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
+
+
+
+
+
+ ./
+ true
+
+
+
+ /${artifactId}
+
+
+
+ /${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
+
+
+
+
+ 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());
+ }
+ }
+}