diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..79174f7 --- /dev/null +++ b/.classpath @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..38b0c3b --- /dev/null +++ b/.project @@ -0,0 +1,23 @@ + + + social-data-search-client + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..f9fe345 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/test/java=UTF-8 +encoding/=UTF-8 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..ec4300d --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/distro/INSTALL b/distro/INSTALL new file mode 100644 index 0000000..139597f --- /dev/null +++ b/distro/INSTALL @@ -0,0 +1,2 @@ + + diff --git a/distro/LICENSE b/distro/LICENSE new file mode 100644 index 0000000..cdb5851 --- /dev/null +++ b/distro/LICENSE @@ -0,0 +1,7 @@ +gCube System - License +------------------------------------------------------------ + +The gCube/gCore software is licensed as Free Open Source software conveying to the EUPL (http://ec.europa.eu/idabc/eupl). +The software and documentation is provided by its authors/distributors "as is" and no expressed or +implied warranty is given for its use, quality or fitness for a particular case. + diff --git a/distro/MAINTAINERS b/distro/MAINTAINERS new file mode 100644 index 0000000..21f820d --- /dev/null +++ b/distro/MAINTAINERS @@ -0,0 +1,6 @@ +Mantainers +------- + +* Costantino Perciante (costantino.perciante@isti.cnr.it), CNR Pisa, + Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo". + diff --git a/distro/README b/distro/README new file mode 100644 index 0000000..6e854c2 --- /dev/null +++ b/distro/README @@ -0,0 +1,35 @@ +The gCube System - Social Library +------------------------------------------------------------ + +This work is partially funded by the European Commission in the +context of the iMarine project (www.i-marine.eu), under the 1st call of FP7 IST priority. + +Authors +------- +Costantino Perciante +* +Version and Release Date +------------------------ +Feb 2016 + + +Description +----------- +Social Data Search Client + +Download information +-------------------- +Source code is available from SVN: +https://svn.d4science.research-infrastructures.eu/gcube/trunk/socialnetworking/social-data-search-client + +Binaries can be downloaded from: +http://software.d4science.research-infrastructures.eu/ + +Documentation +------------- +Documentation is available on-line from the Projects Documentation Wiki: + +Licensing +--------- + +This software is licensed under the terms you may find in the file named "LICENSE" in this directory. diff --git a/distro/changelog.xml b/distro/changelog.xml new file mode 100644 index 0000000..c7cb5a9 --- /dev/null +++ b/distro/changelog.xml @@ -0,0 +1,6 @@ + + + First Release + + diff --git a/distro/descriptor.xml b/distro/descriptor.xml new file mode 100644 index 0000000..c468f13 --- /dev/null +++ b/distro/descriptor.xml @@ -0,0 +1,48 @@ + + servicearchive + + tar.gz + + / + + + ${distroDirectory} + / + true + + README + LICENSE + INSTALL + MAINTAINERS + changelog.xml + + 755 + true + + + target/apidocs + /${artifactId}/doc/api + true + 755 + + + + + ${distroDirectory}/profile.xml + ./ + true + + + target/${build.finalName}.jar + /${artifactId} + + + ${distroDirectory}/svnpath.txt + /${artifactId} + true + + + \ No newline at end of file diff --git a/distro/profile.xml b/distro/profile.xml new file mode 100644 index 0000000..f7f1ffa --- /dev/null +++ b/distro/profile.xml @@ -0,0 +1,25 @@ + + + + Library + + gCube Social Networking Library + Portal + ${artifactId} + 1.0.0 + + + ${artifactId} + ${version} + + ${groupId} + ${artifactId} + ${version} + + + ${build.finalName}.jar + + + + + diff --git a/distro/svnpath.txt b/distro/svnpath.txt new file mode 100644 index 0000000..edacb04 --- /dev/null +++ b/distro/svnpath.txt @@ -0,0 +1 @@ +${scm.url} \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..358e1a2 --- /dev/null +++ b/pom.xml @@ -0,0 +1,233 @@ + + 4.0.0 + + + maven-parent + org.gcube.tools + 1.0.0 + + + + org.gcube.socialnetworking + social-data-search-client + 1.0.0-SNAPSHOT + jar + + Social Data Search Client + + This library extends the functionalities of the elastic-search client in order to perform full-text search + on a previously created elasticsearch index that contains posts/comments present in the Social gcube Cassandra cluster. + + + + scm:https://svn.d4science.research-infrastructures.eu/gcube/trunk/${serviceClass}/${project.artifactId} + scm:https://svn.d4science.research-infrastructures.eu/gcube/trunk/${serviceClass}/${project.artifactId} + https://svn.d4science.research-infrastructures.eu/gcube/trunk/${serviceClass}/${project.artifactId} + + + + 2.2.0 + 18.0 + social-networking + distro + 1.7 + 1.7 + + UTF-8 + UTF-8 + + + + + org.gcube.distribution + maven-portal-bom + LATEST + pom + import + + + + + + + junit + junit + 4.8 + + + org.elasticsearch + elasticsearch + ${elasticSearchVersion} + + + org.gcube.common.portal + portal-manager + + + org.gcube.portal + custom-portal-handler + provided + + + org.gcube.applicationsupportlayer + aslcore + provided + + + org.gcube.applicationsupportlayer + aslsocial + provided + + + org.gcube.portal + social-networking-library + provided + + + org.gcube.portal + notifications-common-library + provided + + + org.gcube.common + home-library + provided + + + org.gcube.dvos + usermanagement-core + + + com.sun.mail + javax.mail + provided + + + org.gcube.resources.discovery + ic-client + + + com.netflix.astyanax + astyanax + + + org.gcube.core + common-encryption + provided + + + com.google.guava + guava + ${guavaVersion} + + + com.ning + compress-lzf + 1.0.3 + + + org.slf4j + slf4j-log4j12 + + + org.slf4j + slf4j-api + + + + + + + src/main/java + + **/*.* + + + + + + maven-compiler-plugin + + 1.7 + 1.7 + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + test-jar + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + true + + + + org.apache.maven.plugins + maven-resources-plugin + 2.5 + + + copy-profile + install + + copy-resources + + + target + + + ${distroDirectory} + true + + profile.xml + + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.2 + + + ${distroDirectory}/descriptor.xml + + + + fully.qualified.MainClass + + + + + + + + + servicearchive + install + + single + + + + + + + diff --git a/src/main/java/org/gcube/socialnetworking/social_data_search_client/ElasticSearchClientImpl.java b/src/main/java/org/gcube/socialnetworking/social_data_search_client/ElasticSearchClientImpl.java new file mode 100644 index 0000000..c0a165b --- /dev/null +++ b/src/main/java/org/gcube/socialnetworking/social_data_search_client/ElasticSearchClientImpl.java @@ -0,0 +1,146 @@ +package org.gcube.socialnetworking.social_data_search_client; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; + +import org.codehaus.jackson.map.ObjectMapper; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.client.transport.TransportClient; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.transport.InetSocketTransportAddress; +import org.elasticsearch.index.query.MultiMatchQueryBuilder; +import org.elasticsearch.index.query.MultiMatchQueryBuilder.Type; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.search.SearchHit; +import org.gcube.portal.databook.shared.EnhancedFeed; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * The elasticsearch client for gcube portlets. + * @author Costantino Perciante at ISTI-CNR + * (costantino.perciante@isti.cnr.it) + * + */ +public class ElasticSearchClientImpl implements ElasticSearchClientInterface{ + + //logger + public static final Logger _log = LoggerFactory.getLogger(ElasticSearchClientImpl.class); + + // the elasticsearch client + private TransportClient client; + + // the cluster name: it must be the same among all cluster's nodes + private String clusterName; + + // list of hosts to contact + private List hostsToContact; + + // private port number + private List portNumbers; + + /** + * Build an elasticsearch client to be queried. + * @param scope the scope in the infrastructure + * @throws Exception + */ + public ElasticSearchClientImpl(String scope) throws Exception { + + // retrieve ElasticSearch Endpoint and set hosts/port number + ElasticSearchRunningCluster elasticCluster = new ElasticSearchRunningCluster(scope); + + // save info + clusterName = elasticCluster.getClusterName(); + hostsToContact = elasticCluster.getHosts(); + portNumbers = elasticCluster.getPorts(); + + _log.debug("Creating elasticsearch client for hosts = " + hostsToContact + ", port = " + portNumbers + " and " + + " cluster's name = " + clusterName); + + + // set cluster's name to check and the sniff property to true. + // Cluster's name: each node must have this name. + // Sniff property: allows the client to recover cluster's structure. + // Look at https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/transport-client.html + Settings settings = Settings.settingsBuilder() + .put("cluster.name", this.clusterName) + .put("client.transport.sniff", true) + .build(); + + // build the client + client = TransportClient.builder().settings(settings).build(); + + // add the nodes to contact + for (int i = 0; i < hostsToContact.size(); i++){ + try { + + client.addTransportAddress( + new InetSocketTransportAddress( + InetAddress.getByName(hostsToContact.get(i)), portNumbers.get(i)) + ); + + } catch (UnknownHostException e) { + + _log.debug("Error while adding " + hostsToContact.get(i) + ":" + portNumbers.get(i) + " as host to be contacted."); + + } + } + + + _log.debug("Connection to ElasticSearch cluster done."); + } + + @Override + public List searchInEnhancedFeeds(String query, String vreID, int hits, boolean isPhraseSearch){ + List toReturn = new ArrayList<>(); + + MultiMatchQueryBuilder mq = QueryBuilders.multiMatchQuery( + query, + IndexFields.EF_FEED_TEXT + "^2", // weight of 2 for feed's description + IndexFields.EF_ATTACHMENT_NAME, + IndexFields.EF_PREVIEW_DESCRIPTION, + IndexFields.EF_COMMENT_TEXT). + type(Type.MOST_FIELDS); + + SearchResponse response = client.prepareSearch(IndexFields.INDEX_NAME) + .setTypes(vreID == null ? IndexFields.EF_FEEDS_TABLE : IndexFields.EF_FEEDS_TABLE + vreID) + .setQuery(mq) + .setFrom(0).setSize(hits).setExplain(true) + .addHighlightedField(IndexFields.EF_FEED_TEXT) + .addHighlightedField(IndexFields.EF_ATTACHMENT_NAME) + .addHighlightedField(IndexFields.EF_PREVIEW_DESCRIPTION) + .addHighlightedField(IndexFields.EF_COMMENT_TEXT) + .setHighlighterPreTags("") + .setHighlighterPostTags("") + .execute() + .actionGet(); + + _log.debug("The search took " + response.getTookInMillis() + " ms"); + + SearchHit[] results = response.getHits().getHits(); + + _log.debug("Number of hits is " + results.length); + + ObjectMapper mapper = new ObjectMapper(); + + for (SearchHit hit : results) { + //JSON from String to Object + EnhancedFeed enhFeed; + try { + + _log.debug(hit.getSourceAsString()); + enhFeed = mapper.readValue(hit.getSourceAsString(), EnhancedFeed.class); + + // add to the return set + toReturn.add(enhFeed); + } catch (IOException e) { + _log.error(e.toString()); + } + } + return toReturn; + } +} diff --git a/src/main/java/org/gcube/socialnetworking/social_data_search_client/ElasticSearchClientInterface.java b/src/main/java/org/gcube/socialnetworking/social_data_search_client/ElasticSearchClientInterface.java new file mode 100644 index 0000000..b89fea4 --- /dev/null +++ b/src/main/java/org/gcube/socialnetworking/social_data_search_client/ElasticSearchClientInterface.java @@ -0,0 +1,19 @@ +package org.gcube.socialnetworking.social_data_search_client; + +import java.util.List; + +import org.gcube.portal.databook.shared.EnhancedFeed; + +public interface ElasticSearchClientInterface { + + /** + * Given a query, the method find matching enhanced feeds into the elasticsearch index. + * @param query the query to match + * @param vreID specify if you want to lookup enhanced feeds only in a certain vre + * @param hits the maximum number of hits to return + * @param isPhraseSearch if you want to exactly match a phrase + * @return A list if matching enhanced feeds or nothing + */ + public List searchInEnhancedFeeds(String query, String vreID, int hits, boolean isPhraseSearch); + +} diff --git a/src/main/java/org/gcube/socialnetworking/social_data_search_client/ElasticSearchRunningCluster.java b/src/main/java/org/gcube/socialnetworking/social_data_search_client/ElasticSearchRunningCluster.java new file mode 100644 index 0000000..348306a --- /dev/null +++ b/src/main/java/org/gcube/socialnetworking/social_data_search_client/ElasticSearchRunningCluster.java @@ -0,0 +1,133 @@ +package org.gcube.socialnetworking.social_data_search_client; + +import static org.gcube.resources.discovery.icclient.ICFactory.clientFor; +import static org.gcube.resources.discovery.icclient.ICFactory.queryFor; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.gcube.common.portal.PortalContext; +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.resources.discovery.client.api.DiscoveryClient; +import org.gcube.resources.discovery.client.queries.api.SimpleQuery; +import org.gcube.socialnetworking.social_data_search_client.ex.NoElasticSearchRuntimeResourceException; +import org.gcube.socialnetworking.social_data_search_client.ex.ServiceEndPointException; +import org.gcube.socialnetworking.social_data_search_client.ex.TooManyRunningClustersException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Retrieve elasticsearch's running instance information in the infrastructure. + * @author Costantino Perciante at ISTI-CNR + * (costantino.perciante@isti.cnr.it) + * + */ +public class ElasticSearchRunningCluster { + + //logger + private static final Logger _log = LoggerFactory.getLogger(ElasticSearchRunningCluster.class); + + //properties + private final static String RUNTIME_RESOURCE_NAME = "SocialPortalDataIndex"; + private final static String PLATFORM_NAME = "ElasticSearch"; + + // retrieved data + private List hosts = new ArrayList(); + private List ports = new ArrayList(); + private String clusterName; + + public ElasticSearchRunningCluster(String infrastructure) throws Exception{ + + try { + + List resources = getConfigurationFromIS(infrastructure); + + if (resources.size() > 1) { + _log.error("Too many Runtime Resource having name " + RUNTIME_RESOURCE_NAME +" in this scope"); + throw new TooManyRunningClustersException("There exist more than 1 Runtime Resource in this scope having name " + + RUNTIME_RESOURCE_NAME + " and Platform " + PLATFORM_NAME + ". Only one allowed per infrasrtucture."); + } + else if (resources.size() == 0){ + _log.error("There is no Runtime Resource having name " + RUNTIME_RESOURCE_NAME +" and Platform " + PLATFORM_NAME + " in this scope."); + throw new NoElasticSearchRuntimeResourceException(); + } + else { + + try{ + + _log.debug(resources.toString()); + for (ServiceEndpoint res : resources) { + + Iterator accessPointIterator = res.profile().accessPoints().iterator(); + + while (accessPointIterator.hasNext()) { + ServiceEndpoint.AccessPoint accessPoint = (ServiceEndpoint.AccessPoint) accessPointIterator + .next(); + + // add this host + hosts.add(accessPoint.address().split(":")[0]); + + // save the port + int port = Integer.parseInt(accessPoint.address().split(":")[1]); + ports.add(port); + + // save the name of the cluster (this should be unique) + clusterName = accessPoint.name(); + + } + } + }catch(Exception e ){ + + _log.error(e.toString()); + throw new ServiceEndPointException(); + } + } + } catch (Exception e) { + _log.error(e.toString()); + throw e; + } + + } + + /** + * Retrieve endpoints information from IS + * @return list of endpoints for elasticsearch + * @throws Exception + */ + private List getConfigurationFromIS(String infrastructure) throws Exception{ + + PortalContext context = PortalContext.getConfiguration(); + String scope = "/"; + if(infrastructure != null && !infrastructure.isEmpty()) + scope += infrastructure; + else + scope += context.getInfrastructureName(); + + String currScope = ScopeProvider.instance.get(); + ScopeProvider.instance.set(scope); + SimpleQuery query = queryFor(ServiceEndpoint.class); + query.addCondition("$resource/Profile/Name/text() eq '"+ RUNTIME_RESOURCE_NAME +"'"); + query.addCondition("$resource/Profile/Platform/Name/text() eq '"+ PLATFORM_NAME +"'"); + DiscoveryClient client = clientFor(ServiceEndpoint.class); + List toReturn = client.submit(query); + ScopeProvider.instance.set(currScope); + return toReturn; + + } + + public List getHosts() { + return hosts; + } + + public List getPorts() { + return ports; + } + + public String getClusterName() { + return clusterName; + } + +} diff --git a/src/main/java/org/gcube/socialnetworking/social_data_search_client/IndexFields.java b/src/main/java/org/gcube/socialnetworking/social_data_search_client/IndexFields.java new file mode 100644 index 0000000..de6922e --- /dev/null +++ b/src/main/java/org/gcube/socialnetworking/social_data_search_client/IndexFields.java @@ -0,0 +1,37 @@ +package org.gcube.socialnetworking.social_data_search_client; + +/** + * The fields used to build up the index. + * @author Costantino Perciante at ISTI-CNR + * (costantino.perciante@isti.cnr.it) + * + */ +public class IndexFields { + + // name of the index + public static final String INDEX_NAME = "social"; + + // table for comments + public static final String COMMENT_TABLE = "comments"; + + // table for feeds + public static final String FEED_TABLE = "feeds"; + + // table for enhanced feeds + public static final String EF_FEEDS_TABLE = "enhanced_feeds"; + + // comment table's fields + public static final String COMMENT_TEXT = "description"; + public static final String COMMENT_PARENT_ID = "parent_id"; + + // feed table's fields + public static final String FEED_TEXT = "description"; + public static final String FEED_TYPE = "type"; + public static final String FEED_VRE_ID = "vre_id"; + + // enhanced feeds' fields + public static final String EF_ATTACHMENT_NAME = "attachments.name"; + public static final String EF_FEED_TEXT = "feed.description"; + public static final String EF_COMMENT_TEXT = "comments.text"; + public static final String EF_PREVIEW_DESCRIPTION = "feed.linkTitle"; +} diff --git a/src/main/java/org/gcube/socialnetworking/social_data_search_client/ex/NoElasticSearchRuntimeResourceException.java b/src/main/java/org/gcube/socialnetworking/social_data_search_client/ex/NoElasticSearchRuntimeResourceException.java new file mode 100644 index 0000000..6f650d5 --- /dev/null +++ b/src/main/java/org/gcube/socialnetworking/social_data_search_client/ex/NoElasticSearchRuntimeResourceException.java @@ -0,0 +1,24 @@ +package org.gcube.socialnetworking.social_data_search_client.ex; + +/** + * No elasticsearch cluster in the infrastructure found exception. + * @author Costantino Perciante at ISTI-CNR + * (costantino.perciante@isti.cnr.it) + * + */ +public class NoElasticSearchRuntimeResourceException extends Exception { + + private static final long serialVersionUID = -40748130477807648L; + + private static final String DEFAULT_MESSAGE = "No ElasticSearch cluster instance for this scope!"; + + public NoElasticSearchRuntimeResourceException(){ + super(DEFAULT_MESSAGE); + } + + public NoElasticSearchRuntimeResourceException(String message) { + super(message); + } + + +} diff --git a/src/main/java/org/gcube/socialnetworking/social_data_search_client/ex/ServiceEndPointException.java b/src/main/java/org/gcube/socialnetworking/social_data_search_client/ex/ServiceEndPointException.java new file mode 100644 index 0000000..783faf7 --- /dev/null +++ b/src/main/java/org/gcube/socialnetworking/social_data_search_client/ex/ServiceEndPointException.java @@ -0,0 +1,22 @@ +package org.gcube.socialnetworking.social_data_search_client.ex; + +/** + * Exception thrown when it is not possible retrieve information from the ServiceEndpoint + * related to ElasticSearch + * @author Costantino Perciante at ISTI-CNR + * (costantino.perciante@isti.cnr.it) + * + */ +public class ServiceEndPointException extends Exception { + + private static final long serialVersionUID = 5378333924429281681L; + + private static final String DEFAULT_MESSAGE = "Unable to retrieve information from ElasticSearch endpoint!"; + + public ServiceEndPointException(){ + super(DEFAULT_MESSAGE); + } + public ServiceEndPointException(String string) { + super(string); + } +} diff --git a/src/main/java/org/gcube/socialnetworking/social_data_search_client/ex/TooManyRunningClustersException.java b/src/main/java/org/gcube/socialnetworking/social_data_search_client/ex/TooManyRunningClustersException.java new file mode 100644 index 0000000..34129ea --- /dev/null +++ b/src/main/java/org/gcube/socialnetworking/social_data_search_client/ex/TooManyRunningClustersException.java @@ -0,0 +1,23 @@ +package org.gcube.socialnetworking.social_data_search_client.ex; + +/** + * Too many clusters in this scope exception. + * @author Costantino Perciante at ISTI-CNR + * (costantino.perciante@isti.cnr.it) + * + */ +public class TooManyRunningClustersException extends Exception { + + private static final long serialVersionUID = -4112724774153676227L; + + private static final String DEFAULT_MESSAGE = "Too many ElasticSearch cluster instances for this scope!"; + + public TooManyRunningClustersException(){ + super(DEFAULT_MESSAGE); + } + + public TooManyRunningClustersException(String message) { + super(message); + } + +} diff --git a/src/test/java/org/gcube/socialnetworking/social_data_search_client/Tests.java b/src/test/java/org/gcube/socialnetworking/social_data_search_client/Tests.java new file mode 100644 index 0000000..b1b98ea --- /dev/null +++ b/src/test/java/org/gcube/socialnetworking/social_data_search_client/Tests.java @@ -0,0 +1,27 @@ +package org.gcube.socialnetworking.social_data_search_client; + +import java.util.ArrayList; +import java.util.List; + +import org.gcube.portal.databook.shared.EnhancedFeed; +import org.junit.Test; +/** + * Unit test for simple App. + */ +public class Tests +{ + @Test + public void query() throws Exception{ + + List hosts = new ArrayList(); + hosts.add("localhost"); + ElasticSearchClientImpl el = new ElasticSearchClientImpl("gcube"); + + // try to query + List enFeeds = el.searchInEnhancedFeeds("argentina slow Screen Shot 2016-01-26 at 12.39.30.png", "/gcube/devsec/devVRE", 10, false); + + for (EnhancedFeed enFeed : enFeeds) { + System.err.println("Result is " + enFeed.toString()); + } + } +}