/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2014, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package mil.nga.giat.data.elasticsearch;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.TimeZone;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.google.common.collect.ImmutableMap;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.feature.NameImpl;
import org.geotools.temporal.object.DefaultInstant;
import org.geotools.temporal.object.DefaultPeriod;
import org.geotools.temporal.object.DefaultPosition;
import org.junit.After;
import org.junit.Before;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.temporal.Instant;
import org.opengis.temporal.Period;
public class ElasticTestSupport {
protected static final Logger LOGGER = org.geotools.util.logging.Logging
.getLogger(ElasticTestSupport.class);
private static final String TEST_FILE = "wifiAccessPoint.json";
private static final String ACTIVE_MAPPINGS_FILE = "active_mappings.json";
private static final String INACTIVE_MAPPINGS_FILE = "inactive_mappings.json";
private static final Pattern STATUS_PATTERN = Pattern.compile(".*\"status_s\"\\s*:\\s*\"(.*?)\".*");
private static final Pattern ID_PATTERN = Pattern.compile(".*\"id\"\\s*:\\s*\"(\\d+)\".*");
private static final int numShards = 1;
private static final int numReplicas = 0;
private static final boolean SCROLL_ENABLED = false;
private static final long SCROLL_SIZE = 20;
private static final ObjectMapper mapper = new ObjectMapper();
private static final ObjectReader mapReader = mapper.readerWithView(Map.class).forType(HashMap.class);
protected static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-dd-MM HH:mm:ss");
protected static final int PORT = 9200;
protected String layerName = "active";
protected int SOURCE_SRID = 4326;
protected String indexName;
protected int activeNumShards;
protected ElasticFeatureSource featureSource;
protected static ElasticDataStore dataStore;
protected ElasticLayerConfiguration config;
protected List<ElasticAttribute> attributes;
protected RestElasticClient client;
@Before
public void beforeTest() throws Exception {
indexName = "gt_integ_test_" + System.nanoTime();
client = new RestElasticClient(RestClient.builder(new HttpHost("localhost", PORT, "http")).build());
Map<String,Serializable> params = createConnectionParams();
ElasticDataStoreFactory factory = new ElasticDataStoreFactory();
dataStore = (ElasticDataStore) factory.createDataStore(params);
createIndices();
}
@After
public void afterTest() throws Exception {
client.performRequest("DELETE", "/" + indexName, null);
dataStore.dispose();
client.close();
}
protected void createIndices() throws IOException {
// create index and add mappings
Map<String,Object> settings = new HashMap<>();
settings.put("settings", ImmutableMap.of("number_of_shards", numShards, "number_of_replicas", numReplicas));
Map<String,Object> mappings = new HashMap<>();
settings.put("mappings", mappings);
try (Scanner s = new Scanner(ClassLoader.getSystemResourceAsStream(ACTIVE_MAPPINGS_FILE))) {
s.useDelimiter("\\A");
Map<String,Object> source = mapReader.readValue(s.next());
mappings.put("active", source);
}
try (Scanner s = new Scanner(ClassLoader.getSystemResourceAsStream(INACTIVE_MAPPINGS_FILE))) {
s.useDelimiter("\\A");
Map<String,Object> source = mapReader.readValue(s.next());
mappings.put("not-active", source);
}
client.performRequest("PUT", "/" + indexName, settings);
// index documents
try (InputStream inputStream = ClassLoader.getSystemResourceAsStream(TEST_FILE); Scanner scanner = new Scanner(inputStream)) {
String eol = System.lineSeparator();
scanner.useDelimiter(eol);
while (scanner.hasNext()) {
final String line = scanner.next();
if (!line.startsWith("#")) {
final Matcher idMatcher = ID_PATTERN.matcher(line);
final String id;
if (idMatcher.matches()) {
id = idMatcher.group(1);
} else {
id = null;
}
final String layerName;
final Matcher statusMatcher = STATUS_PATTERN.matcher(line);
if (statusMatcher.matches()) {
layerName = statusMatcher.group(1);
} else {
layerName = null;
}
Map<String,Object> source = mapReader.readValue(line);
client.performRequest("POST", "/" + indexName + "/" + layerName + "/" + id, source);
}
}
client.performRequest("POST", "/" + indexName + "/_refresh", null);
}
}
protected Map<String,Serializable> createConnectionParams() {
Map<String,Serializable> params = new HashMap<>();
params.put(ElasticDataStoreFactory.HOSTPORT.key, PORT);
params.put(ElasticDataStoreFactory.INDEX_NAME.key, indexName);
params.put(ElasticDataStoreFactory.SCROLL_ENABLED.key, SCROLL_ENABLED);
params.put(ElasticDataStoreFactory.SCROLL_SIZE.key, SCROLL_SIZE);
return params;
}
protected void init() throws Exception {
DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
init(this.layerName);
}
protected void init(String layerName) throws Exception {
init(layerName, "geo");
}
protected void init(String layerName, String geometryField) throws Exception {
this.layerName = layerName;
attributes = dataStore.getElasticAttributes(new NameImpl(this.layerName));
config = new ElasticLayerConfiguration(layerName);
List<ElasticAttribute> layerAttributes = new ArrayList<>();
for (ElasticAttribute attribute : attributes) {
attribute.setUse(true);
if (geometryField.equals(attribute.getName())) {
ElasticAttribute copy = new ElasticAttribute(attribute);
copy.setDefaultGeometry(true);
layerAttributes.add(copy);
} else {
layerAttributes.add(attribute);
}
}
config.getAttributes().clear();
config.getAttributes().addAll(layerAttributes);
dataStore.setLayerConfiguration(config);
featureSource = (ElasticFeatureSource) dataStore.getFeatureSource(this.layerName);
}
protected Date date(String date) throws ParseException {
return DATE_FORMAT.parse(date);
}
protected Instant instant(String d) throws ParseException {
return new DefaultInstant(new DefaultPosition(date(d)));
}
protected Period period(String d1, String d2) throws ParseException {
return new DefaultPeriod(instant(d1), instant(d2));
}
protected List<SimpleFeature> readFeatures(SimpleFeatureIterator iterator) {
final List<SimpleFeature> features = new ArrayList<>();
try {
while (iterator.hasNext()) {
features.add(iterator.next());
}
} finally {
iterator.close();
}
return features;
}
}