Added initial support for alarm expression data

Updated mock auth filter to return proper errors when missing auth data
This commit is contained in:
Jonathan Halterman 2014-04-30 10:50:21 -07:00
parent b727f9655c
commit 31babd37ac
7 changed files with 91 additions and 25 deletions

View File

@ -15,7 +15,7 @@
<properties>
<computedVersion>${project.version}-${timestamp}-${buildNumber}</computedVersion>
<computedName>${project.artifactId}-${computedVersion}</computedName>
<mon.common.version>1.0.0.40</mon.common.version>
<mon.common.version>1.0.0.42</mon.common.version>
<dropwizard.version>0.7.0</dropwizard.version>
<skipITs>true</skipITs>

View File

@ -5,6 +5,7 @@ import io.dropwizard.jdbi.bundles.DBIExceptionsBundle;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@ -16,6 +17,7 @@ import javax.ws.rs.ext.ExceptionMapper;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.hp.csbu.cc.middleware.TokenAuth;
import com.hpcloud.messaging.kafka.KafkaHealthCheck;
import com.hpcloud.mon.bundle.SwaggerBundle;
@ -37,6 +39,7 @@ import com.hpcloud.mon.resource.exception.JsonMappingExceptionManager;
import com.hpcloud.mon.resource.exception.JsonProcessingExceptionMapper;
import com.hpcloud.mon.resource.exception.ResourceNotFoundExceptionMapper;
import com.hpcloud.mon.resource.exception.ThrowableExceptionMapper;
import com.hpcloud.mon.resource.serialization.SubAlarmExpressionSerializer;
import com.hpcloud.util.Injector;
/**
@ -92,11 +95,17 @@ public class MonApiApplication extends Application<MonApiConfiguration> {
PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
environment.getObjectMapper().enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
environment.getObjectMapper().disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
SimpleModule module = new SimpleModule("SerializationModule");
module.addSerializer(new SubAlarmExpressionSerializer());
environment.getObjectMapper().registerModule(module);
/** Configure health checks */
environment.healthChecks().register("kafka", new KafkaHealthCheck(config.kafka));
/** Configure auth filters */
environment.servlets()
.addFilter("pre-auth", new PreAuthenticationFilter())
.addMappingForUrlPatterns(null, true, "/*");
if (config.middleware.enabled) {
Map<String, String> authInitParams = new HashMap<String, String>();
authInitParams.put("ServiceIds", config.middleware.serviceIds);
@ -116,20 +125,17 @@ public class MonApiApplication extends Application<MonApiConfiguration> {
authInitParams.put("ConnRetryTimes", config.middleware.connRetryTimes);
authInitParams.put("ConnRetryInterval", config.middleware.connRetryInterval);
environment.servlets()
.addFilter("pre-auth", new PreAuthenticationFilter())
.addMappingForUrlPatterns(null, true, "/*");
Dynamic filter = environment.servlets().addFilter("token-auth", new TokenAuth());
filter.addMappingForUrlPatterns(null, true, "/*");
filter.setInitParameters(authInitParams);
environment.servlets()
.addFilter("post-auth", new PostAuthenticationFilter(config.middleware.rolesToMatch))
.addMappingForUrlPatterns(null, true, "/*");
} else {
environment.servlets()
.addFilter("mock-auth", new MockAuthenticationFilter())
.addMappingForUrlPatterns(null, true, "/*");
}
environment.servlets()
.addFilter("post-auth", new PostAuthenticationFilter(Collections.<String>singletonList("")))
.addMappingForUrlPatterns(null, true, "/*");
/** Configure swagger */
SwaggerBundle.configure(config);

View File

@ -1,5 +1,11 @@
package com.hpcloud.mon.domain.model.alarm;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import com.hpcloud.mon.common.model.alarm.AlarmExpression;
import com.hpcloud.mon.common.model.alarm.AlarmState;
import com.hpcloud.mon.domain.common.AbstractEntity;
import com.hpcloud.mon.domain.model.common.Link;
@ -7,10 +13,6 @@ import com.hpcloud.mon.domain.model.common.Linked;
import com.wordnik.swagger.annotations.ApiModel;
import com.wordnik.swagger.annotations.ApiModelProperty;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
@ApiModel(value = "An alarm is a devops's best friend")
@XmlRootElement(name = "Alarm")
public class Alarm extends AbstractEntity implements Linked {
@ -18,6 +20,7 @@ public class Alarm extends AbstractEntity implements Linked {
private String name;
private String description = "";
private String expression;
private Object expressionData;
private AlarmState state;
private boolean actionsEnabled;
private List<String> alarmActions;
@ -104,6 +107,10 @@ public class Alarm extends AbstractEntity implements Linked {
return expression;
}
public Object getExpressionData() {
return expressionData;
}
public String getId() {
return id;
}
@ -162,6 +169,11 @@ public class Alarm extends AbstractEntity implements Linked {
public void setExpression(String expression) {
this.expression = expression;
setExpressionData(AlarmExpression.of(expression).getExpressionTree());
}
public void setExpressionData(Object expressionData) {
this.expressionData = expressionData;
}
@XmlElement(name = "id")

View File

@ -1,5 +1,7 @@
package com.hpcloud.mon.infrastructure.middleware;
import java.util.List;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotEmpty;
@ -29,5 +31,5 @@ public class MiddlewareConfiguration {
@NotEmpty @JsonProperty public String connPoolMinIdleTime;
@NotEmpty @JsonProperty public String connRetryTimes;
@NotEmpty @JsonProperty public String connRetryInterval;
@NotNull @JsonProperty public String[] rolesToMatch;
@NotNull @JsonProperty public List<String> rolesToMatch;
}

View File

@ -21,7 +21,6 @@ import javax.servlet.http.HttpServletRequestWrapper;
*/
public class MockAuthenticationFilter implements Filter {
private static final String X_AUTH_TOKEN_HEADER = "X-Auth-Token";
private static final String X_TENANT_ID_HEADER = "X-Tenant-Id";
@Override
public void destroy() {
@ -35,14 +34,31 @@ public class MockAuthenticationFilter implements Filter {
chain.doFilter(wrapper, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* Returns an HttpServletRequestWrapper that serves tenant id headers from request attributes.
*/
private HttpServletRequestWrapper requestWrapperFor(final HttpServletRequest request) {
return new HttpServletRequestWrapper(request) {
@Override
public Object getAttribute(String name) {
if (name.equalsIgnoreCase(PostAuthenticationFilter.X_TENANT_ID_HEADER)) {
String tenantId = request.getHeader(PostAuthenticationFilter.X_TENANT_ID_HEADER);
return tenantId == null ? request.getHeader(X_AUTH_TOKEN_HEADER) : tenantId;
}
if (name.equalsIgnoreCase(PostAuthenticationFilter.X_IDENTITY_STATUS_ATTRIBUTE))
return PostAuthenticationFilter.CONFIRMED_STATUS;
if (name.equalsIgnoreCase(PostAuthenticationFilter.X_ROLES_ATTRIBUTE))
return "";
return super.getAttribute(name);
}
@Override
public String getHeader(String name) {
if (name.equalsIgnoreCase(X_TENANT_ID_HEADER))
if (name.equalsIgnoreCase(PostAuthenticationFilter.X_TENANT_ID_HEADER))
return request.getHeader(X_AUTH_TOKEN_HEADER);
return super.getHeader(name);
}
@ -50,13 +66,13 @@ public class MockAuthenticationFilter implements Filter {
@Override
public Enumeration<String> getHeaderNames() {
List<String> names = Collections.list(super.getHeaderNames());
names.add(X_TENANT_ID_HEADER);
names.add(PostAuthenticationFilter.X_TENANT_ID_HEADER);
return Collections.enumeration(names);
}
@Override
public Enumeration<String> getHeaders(String name) {
if (name.equalsIgnoreCase(X_TENANT_ID_HEADER)) {
if (name.equalsIgnoreCase(PostAuthenticationFilter.X_TENANT_ID_HEADER)) {
String authToken = request.getHeader(X_AUTH_TOKEN_HEADER);
return authToken == null ? Collections.<String>emptyEnumeration()
: Collections.enumeration(Collections.singleton(authToken));
@ -65,8 +81,4 @@ public class MockAuthenticationFilter implements Filter {
}
};
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}

View File

@ -30,15 +30,15 @@ import com.hpcloud.mon.infrastructure.servlet.PreAuthenticationFilter.ErrorCaptu
* @author Michael Sun
*/
public class PostAuthenticationFilter implements Filter {
private static final String CONFIRMED_STATUS = "CONFIRMED";
private static final String X_ROLES_ATTRIBUTE = "X-ROLES";
private static final String X_IDENTITY_STATUS_ATTRIBUTE = "X-IDENTITY-STATUS";
static final String CONFIRMED_STATUS = "CONFIRMED";
static final String X_ROLES_ATTRIBUTE = "X-ROLES";
static final String X_IDENTITY_STATUS_ATTRIBUTE = "X-IDENTITY-STATUS";
private static final String X_TENANT_ID_ATTRIBUTE = "X-TENANT-ID";
private static final String X_TENANT_ID_HEADER = "X-Tenant-Id";
static final String X_TENANT_ID_HEADER = "X-Tenant-Id";
private final List<String> rolesToMatch = new ArrayList<String>();
public PostAuthenticationFilter(String[] rolesToMatch) {
public PostAuthenticationFilter(List<String> rolesToMatch) {
for (String role : rolesToMatch)
this.rolesToMatch.add(role.toLowerCase());
}

View File

@ -0,0 +1,34 @@
package com.hpcloud.mon.resource.serialization;
import java.io.IOException;
import java.util.Collections;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.hpcloud.mon.common.model.alarm.AlarmSubExpression;
public class SubAlarmExpressionSerializer extends JsonSerializer<AlarmSubExpression> {
@Override
public void serialize(AlarmSubExpression value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeStringField("function", value.getFunction().name());
jgen.writeStringField("metric_name", value.getMetricDefinition().name);
jgen.writeObjectField(
"dimensions",
value.getMetricDefinition().dimensions == null ? Collections.emptyMap()
: value.getMetricDefinition().dimensions);
jgen.writeStringField("operator", value.getOperator().name());
jgen.writeNumberField("threshold", value.getThreshold());
jgen.writeNumberField("period", value.getPeriod());
jgen.writeNumberField("periods", value.getPeriods());
jgen.writeEndObject();
}
@Override
public Class<AlarmSubExpression> handledType() {
return AlarmSubExpression.class;
}
}