package com.rackspacecloud.blueflood.inputs.handlers;
import com.rackspacecloud.blueflood.http.HttpIntegrationTestBase;
import com.rackspacecloud.blueflood.outputs.formats.ErrorResponse;
import com.rackspacecloud.blueflood.service.Configuration;
import com.rackspacecloud.blueflood.service.CoreConfig;
import com.rackspacecloud.blueflood.types.Event;
import io.netty.handler.codec.http.HttpResponseStatus;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.junit.Test;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.*;
import static com.rackspacecloud.blueflood.TestUtils.*;
import java.io.IOException;
import java.util.*;
import java.util.regex.Pattern;
/**
* Testing posting annotations to blueflood.
*/
public class HttpHandlerAnnotationIntegrationTest extends HttpIntegrationTestBase {
private final String INVALID_DATA = "Invalid Data: " + ERROR_TITLE;
//A time stamp 2 days ago
private final long baseMillis = System.currentTimeMillis() - 172800000;
@Test
public void testHttpAnnotationsIngestionHappyCase() throws Exception {
final int batchSize = 1;
final String tenant_id = "333333";
String event = createTestEvent(batchSize);
HttpResponse response = postEvent( tenant_id, event );
try {
assertEquals( 200, response.getStatusLine().getStatusCode() );
}
finally {
EntityUtils.consume( response.getEntity() ); // Releases connection apparently
}
//Sleep for a while
Thread.sleep(1200);
Map<String, List<String>> query = new HashMap<String, List<String>>();
query.put(Event.tagsParameterName, Arrays.asList("deployment"));
List<Map<String, Object>> results = eventsSearchIO.search(tenant_id, query);
assertEquals( batchSize, results.size() );
query = new HashMap<String, List<String>>();
query.put(Event.fromParameterName, Arrays.asList(String.valueOf(baseMillis - 86400000)));
query.put(Event.untilParameterName, Arrays.asList(String.valueOf(baseMillis + (86400000*3))));
results = eventsSearchIO.search(tenant_id, query);
assertEquals(batchSize, results.size());
}
@Test
public void testHttpAnnotationsIngestionMultiEvents() throws Exception {
final int batchSize = 5;
final String tenant_id = "333444";
String event = createTestEvent(batchSize);
HttpResponse response = postEvent( tenant_id, event );
ErrorResponse errorResponse = getErrorResponse(response);
assertEquals("Number of errors invalid", 1, errorResponse.getErrors().size());
assertEquals("Invalid error message", "Invalid Data: Only one event is allowed per request", errorResponse.getErrors().get(0).getMessage());
assertEquals("Invalid tenant", tenant_id, errorResponse.getErrors().get(0).getTenantId());
assertEquals("Invalid status", HttpResponseStatus.BAD_REQUEST.code(), response.getStatusLine().getStatusCode());
}
@Test
public void testHttpAnnotationsIngestionDuplicateEvents() throws Exception {
int batchSize = 5; // To create duplicate events
String tenant_id = "444444";
createAndInsertTestEvents(tenant_id, batchSize);
esSetup.client().admin().indices().prepareRefresh().execute().actionGet();
Map<String, List<String>> query = new HashMap<String, List<String>>();
query.put(Event.tagsParameterName, Arrays.asList("deployment"));
List<Map<String, Object>> results = eventsSearchIO.search(tenant_id, query);
assertEquals( batchSize, results.size() );
query = new HashMap<String, List<String>>();
query.put(Event.fromParameterName, Arrays.asList(String.valueOf(baseMillis - 86400000)));
query.put(Event.untilParameterName, Arrays.asList(String.valueOf(baseMillis + (86400000 * 3))));
results = eventsSearchIO.search(tenant_id, query);
assertEquals(batchSize, results.size());
}
@Test
public void testHttpAnnotationIngestionInvalidPastCollectionTime() throws Exception {
long timestamp = System.currentTimeMillis() - TIME_DIFF_MS - Configuration.getInstance().getLongProperty( CoreConfig.BEFORE_CURRENT_COLLECTIONTIME_MS );
final int batchSize = 1;
final String tenant_id = "333333";
String event = createTestEvent( batchSize, timestamp );
HttpResponse response = postEvent(tenant_id, event);
ErrorResponse errorResponse = getErrorResponse(response);
assertEquals("Number of errors invalid", 1, errorResponse.getErrors().size());
assertEquals("Invalid error message", "Out of bounds. Cannot be more than 259200000 milliseconds into the past." +
" Cannot be more than 600000 milliseconds into the future", errorResponse.getErrors().get(0).getMessage());
assertEquals("Invalid tenant", tenant_id, errorResponse.getErrors().get(0).getTenantId());
assertEquals("Invalid status", HttpResponseStatus.BAD_REQUEST.code(), response.getStatusLine().getStatusCode());
}
@Test
public void testHttpAnnotationIngestionInvalidFutureCollectionTime() throws Exception {
long timestamp = System.currentTimeMillis() + TIME_DIFF_MS + Configuration.getInstance().getLongProperty( CoreConfig.AFTER_CURRENT_COLLECTIONTIME_MS );
final int batchSize = 1;
final String tenant_id = "333333";
String event = createTestEvent( batchSize, timestamp );
HttpResponse response = postEvent( tenant_id, event );
ErrorResponse errorResponse = getErrorResponse(response);
assertEquals("Number of errors invalid", 1, errorResponse.getErrors().size());
assertEquals("Invalid error message", "Out of bounds. Cannot be more than 259200000 milliseconds into the past." +
" Cannot be more than 600000 milliseconds into the future", errorResponse.getErrors().get(0).getMessage());
assertEquals("Invalid tenant", tenant_id, errorResponse.getErrors().get(0).getTenantId());
assertEquals("Invalid status", HttpResponseStatus.BAD_REQUEST.code(), response.getStatusLine().getStatusCode());
}
@Test
public void testIngestingInvalidJAnnotationsJSON() throws Exception {
String requestBody = //Invalid JSON with single inverted commas instead of double.
"{'when':346550008," +
"'what':'Dummy Event'," +
"'data':'Dummy Data'," +
"'tags':'deployment'}";
HttpResponse response = postEvent( "456854", requestBody );
String responseString = EntityUtils.toString(response.getEntity());
assertEquals( 400, response.getStatusLine().getStatusCode() );
assertTrue( responseString.contains("Invalid Data:") );
}
@Test
public void testIngestingInvalidAnnotationsData() throws Exception {
String requestBody = //Invalid Data.
"{\"how\":346550008," +
"\"why\":\"Dummy Event\"," +
"\"info\":\"Dummy Data\"," +
"\"tickets\":\"deployment\"}";
HttpResponse response = postEvent( "456854", requestBody );
String responseString = EntityUtils.toString(response.getEntity());
assertEquals( 400, response.getStatusLine().getStatusCode() );
assertTrue(responseString.contains("Invalid Data:"));
}
private void createAndInsertTestEvents(final String tenant, int eventCount) throws Exception {
ArrayList<Map<String, Object>> eventList = new ArrayList<Map<String, Object>>();
for (int i=0; i<eventCount; i++) {
Event event = new Event();
event.setWhat("deployment");
event.setWhen(Calendar.getInstance().getTimeInMillis());
event.setData("deploying prod");
event.setTags("deployment");
eventList.add(event.toMap());
}
eventsSearchIO.insert(tenant, eventList);
}
private ErrorResponse getErrorResponse(HttpResponse response) throws IOException {
return new ObjectMapper().readValue(response.getEntity().getContent(), ErrorResponse.class);
}
}