package com.lordofthejars.nosqlunit.elasticsearch2;
import com.lordofthejars.nosqlunit.elasticsearch2.parser.DataReader;
import com.lordofthejars.nosqlunit.core.FailureHandler;
import com.lordofthejars.nosqlunit.util.DeepEquals;
import org.codehaus.jackson.map.ObjectMapper;
import org.elasticsearch.action.count.CountResponse;
import org.elasticsearch.action.get.GetRequestBuilder;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.client.Client;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class ElasticsearchAssertion {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
private ElasticsearchAssertion() {
super();
}
public static void strictAssertEquals(List<Map<String, Object>> expectedDocuments, Client client) {
checkNumberOfDocuments(expectedDocuments, client);
for (Map<String, Object> document : expectedDocuments) {
final Object object = document.get(DataReader.DOCUMENT_ELEMENT);
if (object instanceof List) {
@SuppressWarnings("unchecked")
final List<Map<String, Object>> properties = (List<Map<String, Object>>) object;
final List<GetRequestBuilder> indexes = new ArrayList<>();
Map<String, Object> expectedDataOfDocument = new HashMap<>();
for (Map<String, Object> property : properties) {
if (property.containsKey(DataReader.INDEX_ELEMENT)) {
indexes.add(prepareGetIndex(property.get(DataReader.INDEX_ELEMENT), client));
} else {
if (property.containsKey(DataReader.DATA_ELEMENT)) {
expectedDataOfDocument = dataOfDocument(property.get(DataReader.DATA_ELEMENT));
}
}
}
checkIndicesWithDocument(indexes, expectedDataOfDocument);
} else {
throw new IllegalArgumentException("Array of Indexes and Data are required.");
}
}
}
private static void checkIndicesWithDocument(List<GetRequestBuilder> indexes,
Map<String, Object> expectedDataOfDocument) {
for (GetRequestBuilder getRequestBuilder : indexes) {
GetResponse dataOfDocumentResponse = getRequestBuilder.execute().actionGet();
checkExistenceOfDocument(getRequestBuilder, dataOfDocumentResponse);
checkDocumentEquality(expectedDataOfDocument, getRequestBuilder, dataOfDocumentResponse);
}
}
private static void checkDocumentEquality(Map<String, Object> expectedDataOfDocument,
GetRequestBuilder getRequestBuilder, GetResponse dataOfDocumentResponse) {
final Map<String, Object> dataOfDocument = new LinkedHashMap<>(dataOfDocumentResponse.getSource());
if (!DeepEquals.deepEquals(dataOfDocument, expectedDataOfDocument)) {
try {
throw FailureHandler.createFailure("Expected document for index: %s - type: %s - id: %s is %s, but %s was found.", getRequestBuilder.request().index(), getRequestBuilder.request().type(),
getRequestBuilder.request().id(), OBJECT_MAPPER.writeValueAsString(expectedDataOfDocument), OBJECT_MAPPER.writeValueAsString(dataOfDocument));
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}
}
private static void checkExistenceOfDocument(GetRequestBuilder getRequestBuilder, GetResponse dataOfDocumentResponse) {
if (!dataOfDocumentResponse.isExists()) {
throw FailureHandler.createFailure(
"Document with index: %s - type: %s - id: %s has not returned any document.",
getRequestBuilder.request().index(), getRequestBuilder.request().type(),
getRequestBuilder.request().id());
}
}
private static void checkNumberOfDocuments(List<Map<String, Object>> expectedDocuments, Client client) {
int expectedNumberOfElements = expectedDocuments.size();
long numberOfInsertedDocuments = numberOfInsertedDocuments(client);
if (expectedNumberOfElements != numberOfInsertedDocuments) {
throw FailureHandler.createFailure("Expected number of documents are %s but %s has been found.",
expectedNumberOfElements, numberOfInsertedDocuments);
}
}
private static GetRequestBuilder prepareGetIndex(Object object, Client client) {
@SuppressWarnings("unchecked")
Map<String, String> indexInformation = (Map<String, String>) object;
GetRequestBuilder prepareGet = client.prepareGet();
if (indexInformation.containsKey(DataReader.INDEX_NAME_ELEMENT)) {
prepareGet.setIndex(indexInformation.get(DataReader.INDEX_NAME_ELEMENT));
}
if (indexInformation.containsKey(DataReader.INDEX_TYPE_ELEMENT)) {
prepareGet.setType(indexInformation.get(DataReader.INDEX_TYPE_ELEMENT));
}
if (indexInformation.containsKey(DataReader.INDEX_ID_ELEMENT)) {
prepareGet.setId(indexInformation.get(DataReader.INDEX_ID_ELEMENT));
}
return prepareGet;
}
@SuppressWarnings("unchecked")
private static Map<String, Object> dataOfDocument(Object object) {
return (Map<String, Object>) object;
}
private static long numberOfInsertedDocuments(Client client) {
final CountResponse numberOfElements = client.prepareCount().execute().actionGet();
return numberOfElements.getCount();
}
}