-// $Id$
/**
* Copyright (C) 2015 EDIT
* European Distributed Institute of Taxonomy
*/
package eu.etaxonomy.taxeditor.remoting.source;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
+import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import eu.etaxonomy.cdm.api.application.CdmApplicationState;
+import eu.etaxonomy.cdm.common.CdmUtils;
import eu.etaxonomy.cdm.config.CdmSourceException;
+import eu.etaxonomy.cdm.database.CdmPersistentDataSource;
+import eu.etaxonomy.cdm.database.ICdmDataSource;
+import eu.etaxonomy.cdm.model.metadata.CdmMetaData;
import eu.etaxonomy.taxeditor.remoting.server.CDMServerException;
+import eu.etaxonomy.taxeditor.remoting.server.CDMServerUtils;
/**
* @author cmathew
public class CdmServerInfo {
public static final Logger logger = Logger.getLogger(CdmServerInfo.class);
- private final static String CDMSERVER_PREFIX = "cdmserver";
- private final static String NAME_PRODUCTION = "edit-production";
- private final static String SERVER_PRODUCTION = "dev.e-taxonomy.eu";
-
- private final static String NAME_INTEGRATION = "edit-integration";
- private final static String SERVER_INTEGRATION = "int.e-taxonomy.eu";
+ private final static String CDMSERVER_PREFIX = "cdmserver/";
+ private final static String NAME_PRODUCTION = "cybertaxonomy.org";
+ private final static String SERVER_PRODUCTION = "api.cybertaxonomy.org";
- private final static String NAME_TEST = "edit-test";
- private final static String SERVER_TEST = "test.e-taxonomy.eu";
+ private final static String NAME_DEMO_1 = "edit-WS I";
+ private final static String SERVER_DEMO_1 = "160.45.63.230";
- private final static String SERVER_LOCALHOST = "localhost";
+ public final static String SERVER_LOCALHOST = "localhost";
private final static String NAME_LOCALHOST = "localhost";
- private final static String NAME_LOCALHOST_MGD = "localhost mgd.";
+ public final static String NAME_LOCALHOST_MGD = "localhost mgd.";
private final static String NAME_LOCALHOST_DEV = "localhost-dev";
private final static String NAME_INSTANCE_LOCALHOST_DEV = "local-dev";
private final static String SERVER_LOCALHOST_DEV = "localhost";
- private final static int PORT_LOCALHOST_DEV = 8080;
private final static String BASEPATH_LOCALHOST_DEV = "";
+ public final static int NULL_PORT = -1;
+ public final static String NULL_PORT_STRING = "N/A";
+
+ private static final String CDM_REMOTE_SERVERS_CONFIG_FILE = "cdm_remote_servers.json";
+
+
private final String name;
private final String server;
- private final int port;
+ private int port;
private final List<CdmInstanceInfo> instances;
+ private String cdmlibServicesVersion = "";
+ private String cdmlibServicesLastModified = "";
- public CdmServerInfo(String name, String server, int port) {
- this.name = name;
- this.server = server;
- this.port = port;
+ private String prefix = "";
+
+ private boolean ignoreCdmLibVersion = false;
+
+
+ public CdmServerInfo(CdmServerInfoConfig parameterObject) {
+ this.name = parameterObject.getName();
+ this.server = parameterObject.getServer();
+ this.port = parameterObject.getPort();
+ this.prefix = parameterObject.getPrefix();
+ this.ignoreCdmLibVersion = parameterObject.isIgnoreCdmLibVersion();
instances = new ArrayList<CdmInstanceInfo>();
}
public CdmInstanceInfo addInstance(String name, String basePath) {
- CdmInstanceInfo cii = new CdmInstanceInfo(name, basePath);
+ String _basePath = basePath;
+ if(isLocalhostMgd()) {
+ _basePath = "";
+ }
+ CdmInstanceInfo cii = new CdmInstanceInfo(name, _basePath);
instances.add(cii);
return cii;
}
public boolean isLocalhost() {
- return name.startsWith(SERVER_LOCALHOST_DEV);
+ return name.startsWith(SERVER_LOCALHOST);
+ }
+
+ public boolean isLocalhostMgd() {
+ return NAME_LOCALHOST_MGD.equals(name);
+ }
+
+ public String getCdmlibServicesVersion() {
+ return cdmlibServicesVersion;
}
+
+ public String getCdmlibLastModified() {
+ return cdmlibServicesLastModified;
+ }
+
public void refreshInstances() throws CDMServerException {
instances.clear();
- String url = "http://" + server + ":" + String.valueOf(port) + "/" + CDMSERVER_PREFIX + "/instances.jsp";
+ if(isLocalhostMgd()) {
+ addInstancesFromDataSourcesConfig();
+ } else {
+ addInstancesViaHttp();
+ }
+ Collections.sort(instances, new Comparator<CdmInstanceInfo>() {
+ @Override
+ public int compare(CdmInstanceInfo cii1, CdmInstanceInfo cii2)
+ {
+ return cii1.getName().toString().compareTo(cii2.getName().toString());
+ }
+ });
+ }
+ public void updateInfo() throws CDMServerException {
+ String url = "http://" + server + ":" + String.valueOf(port) + "/" + prefix + "info.jsp";
+ String responseBody = getResponse(url);
+ if(responseBody != null) {
+ try {
+ JSONObject info = new JSONObject(responseBody);
+ cdmlibServicesVersion = info.getString("cdmlibServicesVersion");
+ cdmlibServicesLastModified = info.getString("cdmlibServicesLastModified");
+ } catch (JSONException e) {
+ throw new CDMServerException(e);
+ }
+ }
+ }
+
+ public void addInstancesViaHttp() throws CDMServerException {
+ updateInfo();
+ String url = "http://" + server + ":" + String.valueOf(port) + "/" + prefix + "instances.jsp";
+ String responseBody = getResponse(url);
+ if(responseBody != null) {
+ try {
+ JSONArray array = new JSONArray(responseBody);
+ for(int i=0;i<array.length();i++) {
+ JSONObject instance = (JSONObject)array.get(i);
+ if(instance != null) {
+ JSONObject conf = (JSONObject)instance.get("configuration");
+ if(conf != null) {
+ String instanceName = conf.getString("instanceName");
+ // we need to remove the first (char) forward slash from
+ // the base path
+ String basePath = conf.getString("basePath").substring(1);
+ addInstance(instanceName, basePath);
+ logger.info("Added instance with name : " + instanceName + ", basePath : " + basePath);
+ }
+ }
+ }
+ } catch (JSONException e) {
+ throw new CDMServerException(e);
+ }
+ }
+ }
+
+ private String getResponse(String url) throws CDMServerException {
HttpClient client = new DefaultHttpClient();
+ HttpParams params = client.getParams();
+
+ HttpConnectionParams.setConnectionTimeout(params, 5000);
+ HttpConnectionParams.setSoTimeout(params, 5000);
+
HttpGet httpGet = new HttpGet(url);
logger.info("Executing request " + httpGet.getRequestLine());
} catch (IOException e) {
throw new CDMServerException(e);
}
+ return responseBody;
+ }
-
- if(responseBody != null) {
- try {
- JSONArray array = new JSONArray(responseBody);
- for(int i=0;i<array.length();i++) {
- JSONObject instance = (JSONObject)array.get(i);
- if(instance != null) {
- JSONObject conf = (JSONObject)instance.get("configuration");
- if(conf != null) {
- String instanceName = conf.getString("instanceName");
- // we need to remove the first (char) forward slash from
- // the base path
- String basePath = conf.getString("basePath").substring(1);
- addInstance(instanceName, basePath);
- logger.info("Added instance with name : " + instanceName + ", basePath : " + basePath);
- }
- }
- }
- } catch (JSONException e) {
- throw new CDMServerException(e);
- }
+ public void addInstancesFromDataSourcesConfig() {
+ for(ICdmDataSource dataSource : CdmPersistentDataSource.getAllDataSources()){
+ String datasourceNCName = CDMServerUtils.xmlNCNamefrom(dataSource.getName());
+ logger.info("Adding local instance " + dataSource.getName() + " as " + datasourceNCName);
+ addInstance(datasourceNCName, datasourceNCName);
}
-
}
public String toString(String instanceName, int port) {
return CdmRemoteSource.NewInstance(name,
server,
port,
- instance.getBasePath(),
- null);
+ instance.getBasePath()
+ );
}
return null;
}
- public boolean pingServer(){
+ public boolean pingServer() {
+ if(isLocalhostMgd()) {
+ return true;
+ }
try {
Socket s = new Socket(server, port);
logger.info("[CDM-Server] Available @ " + server + ":" + port );
+ updateInfo();
return true;
} catch (IOException ioe) {
+ } catch (CDMServerException e) {
+
}
return false;
}
return false;
}
+ public int compareDbSchemaVersion(CdmInstanceInfo instance, int port) throws CDMServerException {
+
+ ICdmRemoteSource crs = getCdmRemoteSource(instance, port);
+ String dbSchemaVersion;
+ try {
+ dbSchemaVersion = crs.getDbSchemaVersion();
+ } catch (CdmSourceException e) {
+ throw new CDMServerException(e);
+ }
+
+
+ if(dbSchemaVersion != null) {
+ return CdmMetaData.compareVersion(dbSchemaVersion, CdmMetaData.getDbSchemaVersion(), 3, null);
+ } else {
+ throw new CDMServerException("Cannot determine editor db. schema version");
+ }
+ }
+
+ public int compareCdmlibServicesVersion() throws CdmSourceException {
+
+ String serverVersion = cdmlibServicesVersion;
+ String serverCdmlibLastModified = cdmlibServicesLastModified;
+ if(ignoreCdmLibVersion) {
+ return 0;
+ } else {
+ return compareCdmlibServicesVersion(serverVersion, serverCdmlibLastModified);
+ }
+ }
+
+
+ /**
+ * @param serverVersion
+ * @param editorVersion
+ * @throws CdmSourceException
+ */
+ public static int compareCdmlibServicesVersion(String serverVersion, String serverCdmlibLastModified) throws CdmSourceException {
+
+ String editorVersion = CdmApplicationState.getCdmlibVersion();
+ String editorCdmlibLastModified = CdmApplicationState.getCdmlibLastModified();
+
+ int result = 0;
+ if(StringUtils.isBlank(serverVersion) || StringUtils.isBlank(editorVersion)) {
+ throw new CdmSourceException("cdmlib-services server or editor version is empty");
+ }
+
+ String[] serverVersionSplit = serverVersion.split("\\.");
+ String[] editorVersionSplit = editorVersion.split("\\.");
+
+ if(serverVersionSplit.length < 3 || editorVersionSplit.length < 3 || serverVersionSplit.length > 4 || editorVersionSplit.length > 4) {
+ throw new CdmSourceException("cdmlib-services server or editor version is invalid");
+ }
+
+ Integer serverVersionPart;
+ Integer editorVersionPart;
+
+ for(int i=0 ; i<3 ; i++) {
+ serverVersionPart = Integer.valueOf(serverVersionSplit[i]);
+ editorVersionPart = Integer.valueOf(editorVersionSplit[i]);
+
+ int partCompare = serverVersionPart.compareTo(editorVersionPart);
+ if (partCompare != 0){
+ return partCompare;
+ }
+ }
+ // at this point major, minor and patch versions are matching
+
+ if(StringUtils.isBlank(serverCdmlibLastModified) || StringUtils.isBlank(editorCdmlibLastModified)) {
+ throw new CdmSourceException("cdmlib-services server or editor version is empty");
+ }
+
+ String cdmServerIgnoreVersion = System.getProperty("cdm.server.version.lm.ignore");
+ if(StringUtils.isBlank(cdmServerIgnoreVersion) || !cdmServerIgnoreVersion.equals("true")) {
+ Long serverLastModified = Long.valueOf(serverCdmlibLastModified);
+ Long editorLastModified = Long.valueOf(editorCdmlibLastModified);
+ return serverLastModified.compareTo(editorLastModified);
+ }
+
+ return result;
+ }
+
+
+
public static List<CdmServerInfo> getCdmServers() {
- List<CdmServerInfo> cdmServerInfoList = new ArrayList<CdmServerInfo>();
- cdmServerInfoList.add(new CdmServerInfo(NAME_PRODUCTION, SERVER_PRODUCTION, 80));
- cdmServerInfoList.add(new CdmServerInfo(NAME_INTEGRATION, SERVER_INTEGRATION, 80));
- cdmServerInfoList.add(new CdmServerInfo(NAME_TEST, SERVER_TEST, 80));
- cdmServerInfoList.add(new CdmServerInfo(NAME_LOCALHOST, SERVER_LOCALHOST, 8080));
- cdmServerInfoList.add(new CdmServerInfo(NAME_LOCALHOST_MGD, SERVER_LOCALHOST,8080));
- return cdmServerInfoList;
+ List<CdmServerInfoConfig> configList = loadFromConfigFile(new File(CdmUtils.perUserCdmFolder, CDM_REMOTE_SERVERS_CONFIG_FILE));
+ List<CdmServerInfo> serverInfoList = new ArrayList<CdmServerInfo>(configList.size());
+ for(CdmServerInfoConfig config : configList) {
+ serverInfoList.add(new CdmServerInfo(config));
+ }
+ // The local host managed server must not be in the config file
+ CdmServerInfoConfig localHostManagedConfig = new CdmServerInfoConfig(NAME_LOCALHOST_MGD, SERVER_LOCALHOST, NULL_PORT, CDMSERVER_PREFIX, false);
+ serverInfoList.add(new CdmServerInfo(localHostManagedConfig));
+ return serverInfoList;
+ }
+
+
+ /**
+ * @param file
+ * @throws IOException
+ * @throws FileNotFoundException
+ * @throws JsonMappingException
+ * @throws JsonParseException
+ */
+ private static List<CdmServerInfoConfig> loadFromConfigFile(File file) {
+
+ List<CdmServerInfoConfig> serverList = null;
+
+ ObjectMapper mapper = new ObjectMapper();
+
+ if(!file.exists()) {
+ logger.info("The remote server config file '" + file.getAbsolutePath() +
+ "' does not yet exist, it will be created based on the defaults.");
+ try {
+ serverList = createDefaultServerConfigList();
+ mapper.writerWithDefaultPrettyPrinter().writeValue(new FileOutputStream(file), serverList);
+
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ try {
+ serverList = mapper.readValue(new FileInputStream(file), new TypeReference<List<CdmServerInfoConfig>>(){});
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ return serverList;
+
+
+ }
+
+
+ /**
+ *
+ */
+ private static List<CdmServerInfoConfig> createDefaultServerConfigList() {
+
+ List<CdmServerInfoConfig> serverInfoList = new ArrayList<CdmServerInfoConfig>();
+ serverInfoList.add(new CdmServerInfoConfig(NAME_PRODUCTION, SERVER_PRODUCTION, 80, "", false));
+ serverInfoList.add(new CdmServerInfoConfig(NAME_DEMO_1, SERVER_DEMO_1, 80, CDMSERVER_PREFIX, false));
+ serverInfoList.add(new CdmServerInfoConfig(NAME_LOCALHOST, SERVER_LOCALHOST, 8080, CDMSERVER_PREFIX, true));
+ return serverInfoList;
}
public String getName() {
return port;
}
+ public void setPort(int port) {
+ this.port = port;
+ }
public List<CdmInstanceInfo> getInstances() throws CDMServerException {
if(instances.isEmpty()) {
CdmInstanceInfo devInstance = null;
if(value != null && !value.isEmpty()) {
int devPort = Integer.valueOf(value);
- CdmServerInfo devCii = new CdmServerInfo(NAME_LOCALHOST_DEV, SERVER_LOCALHOST_DEV, devPort);
+ CdmServerInfo devCii = new CdmServerInfo(new CdmServerInfoConfig(NAME_LOCALHOST_DEV, SERVER_LOCALHOST_DEV, devPort, "", false));
try {
devInstance = devCii.addInstance(NAME_INSTANCE_LOCALHOST_DEV, BASEPATH_LOCALHOST_DEV);
available = devCii.pingInstance(devInstance, devPort);
public class CdmInstanceInfo {
private final String name;
+
+ /**
+ * The full path of the instance including the the prefix (if any).
+ * E.g. for an EDIT instance this would be something like "cdmserver/remoting"
+ * For a managed local server this would simply be ""
+ */
private final String basePath;