add production server to server info
[taxeditor.git] / eu.etaxonomy.taxeditor.cdmlib / src / main / java / eu / etaxonomy / taxeditor / remoting / source / CdmServerInfo.java
1 // $Id$
2 /**
3 * Copyright (C) 2015 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10 package eu.etaxonomy.taxeditor.remoting.source;
11
12 import java.io.IOException;
13 import java.net.Socket;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.Comparator;
17 import java.util.List;
18
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.http.HttpEntity;
21 import org.apache.http.HttpResponse;
22 import org.apache.http.client.ClientProtocolException;
23 import org.apache.http.client.HttpClient;
24 import org.apache.http.client.ResponseHandler;
25 import org.apache.http.client.methods.HttpGet;
26 import org.apache.http.impl.client.DefaultHttpClient;
27 import org.apache.http.params.HttpConnectionParams;
28 import org.apache.http.params.HttpParams;
29 import org.apache.http.util.EntityUtils;
30 import org.apache.log4j.Logger;
31 import org.json.JSONArray;
32 import org.json.JSONException;
33 import org.json.JSONObject;
34
35 import eu.etaxonomy.cdm.api.application.CdmApplicationState;
36 import eu.etaxonomy.cdm.config.CdmSourceException;
37 import eu.etaxonomy.cdm.database.CdmPersistentDataSource;
38 import eu.etaxonomy.cdm.database.ICdmDataSource;
39 import eu.etaxonomy.cdm.model.metadata.CdmMetaData;
40 import eu.etaxonomy.taxeditor.remoting.server.CDMServerException;
41
42 /**
43 * @author cmathew
44 * @date 20 Jan 2015
45 *
46 */
47 public class CdmServerInfo {
48 public static final Logger logger = Logger.getLogger(CdmServerInfo.class);
49
50 private final static String CDMSERVER_PREFIX = "cdmserver";
51 private final static String NAME_PRODUCTION = "edit-production";
52 private final static String SERVER_PRODUCTION = "dev.e-taxonomy.eu";
53
54 private final static String NAME_INTEGRATION = "edit-integration";
55 private final static String SERVER_INTEGRATION = "int.e-taxonomy.eu";
56
57 private final static String NAME_DEMO_1 = "edit-WS I";
58 private final static String SERVER_DEMO_1 = "160.45.63.230";
59
60 private final static String NAME_DEMO_2 = "edit-WS II";
61 private final static String SERVER_DEMO_2 = "160.45.63.231";
62
63 private final static String NAME_TEST = "edit-test";
64 private final static String SERVER_TEST = "test.e-taxonomy.eu";
65
66 public final static String SERVER_LOCALHOST = "localhost";
67 private final static String NAME_LOCALHOST = "localhost";
68 public final static String NAME_LOCALHOST_MGD = "localhost mgd.";
69
70 private final static String NAME_LOCALHOST_DEV = "localhost-dev";
71 private final static String NAME_INSTANCE_LOCALHOST_DEV = "local-dev";
72 private final static String SERVER_LOCALHOST_DEV = "localhost";
73 private final static int PORT_LOCALHOST_DEV = 8080;
74 private final static String BASEPATH_LOCALHOST_DEV = "";
75
76 public final static int NULL_PORT = -1;
77 public final static String NULL_PORT_STRING = "N/A";
78
79
80 private final String name;
81 private final String server;
82 private int port;
83 private final List<CdmInstanceInfo> instances;
84
85 private static List<CdmServerInfo> cdmServerInfoList;
86
87 private String cdmlibServicesVersion = "";
88 private String cdmlibServicesLastModified = "";
89
90
91 public CdmServerInfo(String name, String server, int port) {
92 this.name = name;
93 this.server = server;
94 this.port = port;
95 instances = new ArrayList<CdmInstanceInfo>();
96
97 }
98
99
100 public CdmInstanceInfo addInstance(String name, String basePath) {
101 String _basePath = basePath;
102 if(isLocalhostMgd()) {
103 _basePath = "";
104 }
105 CdmInstanceInfo cii = new CdmInstanceInfo(name, _basePath);
106 instances.add(cii);
107 return cii;
108
109 }
110
111 public boolean isLocalhost() {
112 return name.startsWith(SERVER_LOCALHOST);
113 }
114
115 public boolean isLocalhostMgd() {
116 return NAME_LOCALHOST_MGD.equals(name);
117 }
118
119 public String getCdmlibServicesVersion() {
120 return cdmlibServicesVersion;
121 }
122
123 public String getCdmlibLastModified() {
124 return cdmlibServicesLastModified;
125 }
126
127 public void refreshInstances() throws CDMServerException {
128 instances.clear();
129 if(isLocalhostMgd()) {
130 addInstancesFromDataSourcesConfig();
131 } else {
132 addInstancesViaHttp();
133 }
134 Collections.sort(instances, new Comparator<CdmInstanceInfo>() {
135 @Override
136 public int compare(CdmInstanceInfo cii1, CdmInstanceInfo cii2)
137 {
138 return cii1.getName().toString().compareTo(cii2.getName().toString());
139 }
140 });
141 }
142
143 public void updateInfo() throws CDMServerException {
144 String url = "http://" + server + ":" + String.valueOf(port) + "/" + CDMSERVER_PREFIX + "/info.jsp";
145 String responseBody = getResponse(url);
146 if(responseBody != null) {
147 try {
148 JSONObject info = new JSONObject(responseBody);
149 cdmlibServicesVersion = info.getString("cdmlibServicesVersion");
150 cdmlibServicesLastModified = info.getString("cdmlibServicesLastModified");
151 } catch (JSONException e) {
152 throw new CDMServerException(e);
153 }
154 }
155 }
156
157 public void addInstancesViaHttp() throws CDMServerException {
158 updateInfo();
159 String url = "http://" + server + ":" + String.valueOf(port) + "/" + CDMSERVER_PREFIX + "/instances.jsp";
160 String responseBody = getResponse(url);
161 if(responseBody != null) {
162 try {
163 JSONArray array = new JSONArray(responseBody);
164 for(int i=0;i<array.length();i++) {
165 JSONObject instance = (JSONObject)array.get(i);
166 if(instance != null) {
167 JSONObject conf = (JSONObject)instance.get("configuration");
168 if(conf != null) {
169 String instanceName = conf.getString("instanceName");
170 // we need to remove the first (char) forward slash from
171 // the base path
172 String basePath = conf.getString("basePath").substring(1);
173 addInstance(instanceName, basePath);
174 logger.info("Added instance with name : " + instanceName + ", basePath : " + basePath);
175 }
176 }
177 }
178 } catch (JSONException e) {
179 throw new CDMServerException(e);
180 }
181 }
182 }
183
184 private String getResponse(String url) throws CDMServerException {
185 HttpClient client = new DefaultHttpClient();
186 HttpParams params = client.getParams();
187
188 HttpConnectionParams.setConnectionTimeout(params, 5000);
189 HttpConnectionParams.setSoTimeout(params, 5000);
190
191 HttpGet httpGet = new HttpGet(url);
192
193 logger.info("Executing request " + httpGet.getRequestLine());
194
195 // Create a custom response handler
196 ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
197
198 @Override
199 public String handleResponse(
200 final HttpResponse response) throws ClientProtocolException, IOException {
201 int status = response.getStatusLine().getStatusCode();
202 if (status >= 200 && status < 300) {
203 HttpEntity entity = response.getEntity();
204 return entity != null ? EntityUtils.toString(entity) : null;
205 } else {
206 throw new ClientProtocolException("Unexpected response status: " + status);
207 }
208 }
209
210 };
211 String responseBody = null;
212 try {
213 responseBody = client.execute(httpGet, responseHandler);
214 } catch (ClientProtocolException e) {
215 throw new CDMServerException(e);
216 } catch (IOException e) {
217 throw new CDMServerException(e);
218 }
219 return responseBody;
220 }
221
222 public void addInstancesFromDataSourcesConfig() {
223 for(ICdmDataSource dataSource : CdmPersistentDataSource.getAllDataSources()){
224 logger.info("Adding local instance " + dataSource.getName());
225 addInstance(dataSource.getName(), dataSource.getName());
226 }
227 }
228
229 public String toString(String instanceName, int port) {
230 return server + ":" + String.valueOf(port) + "/" + instanceName;
231 }
232
233 public CdmInstanceInfo getInstanceFromName(String instanceName) {
234 if(instanceName == null) {
235 return null;
236 }
237
238 for(CdmInstanceInfo instance : instances) {
239 if(instance.getName() != null && instance.getName().equals(instanceName)) {
240 return instance;
241 }
242 }
243 return null;
244 }
245
246 public CdmRemoteSource getCdmRemoteSource(CdmInstanceInfo instance, int port) {
247 if(instance != null) {
248 return CdmRemoteSource.NewInstance(name,
249 server,
250 port,
251 instance.getBasePath(),
252 null);
253 }
254 return null;
255 }
256
257 public boolean pingServer() {
258 if(isLocalhostMgd()) {
259 return true;
260 }
261 try {
262 Socket s = new Socket(server, port);
263 logger.info("[CDM-Server] Available @ " + server + ":" + port );
264 updateInfo();
265 return true;
266 } catch (IOException ioe) {
267
268 } catch (CDMServerException e) {
269
270 }
271 return false;
272 }
273
274 public boolean pingInstance(CdmInstanceInfo instance, int port) throws CDMServerException {
275
276 ICdmRemoteSource crs = getCdmRemoteSource(instance, port);
277 try {
278 if(crs != null && crs.checkConnection()) {
279 logger.info("[CDM-Server] Running @ " + server + ":" + port + " for instance " + instance);
280 return true;
281 }
282 } catch (CdmSourceException e) {
283 throw new CDMServerException(e);
284 }
285
286 return false;
287 }
288
289 public int compareDbSchemaVersion(CdmInstanceInfo instance, int port) throws CDMServerException {
290
291 ICdmRemoteSource crs = getCdmRemoteSource(instance, port);
292 String dbSchemaVersion;
293 try {
294 dbSchemaVersion = crs.getDbSchemaVersion();
295 } catch (CdmSourceException e) {
296 throw new CDMServerException(e);
297 }
298
299
300 if(dbSchemaVersion != null) {
301 return CdmMetaData.compareVersion(dbSchemaVersion, CdmMetaData.getDbSchemaVersion(), 3, null);
302 } else {
303 throw new CDMServerException("Cannot determine editor db. schema version");
304 }
305 }
306
307 public int compareCdmlibServicesVersion() throws CdmSourceException {
308
309 String serverVersion = cdmlibServicesVersion;
310 String serverCdmlibLastModified = cdmlibServicesLastModified;
311
312 return compareCdmlibServicesVersion(serverVersion, serverCdmlibLastModified);
313 }
314
315
316 /**
317 * @param serverVersion
318 * @param editorVersion
319 * @throws CdmSourceException
320 */
321 public static int compareCdmlibServicesVersion(String serverVersion, String serverCdmlibLastModified) throws CdmSourceException {
322
323 String editorVersion = CdmApplicationState.getCdmlibVersion();
324 String editorCdmlibLastModified = CdmApplicationState.getCdmlibLastModified();
325
326 int result = 0;
327 if(StringUtils.isBlank(serverVersion) || StringUtils.isBlank(editorVersion)) {
328 throw new CdmSourceException("cdmlib-services server or editor version is empty");
329 }
330
331 String[] serverVersionSplit = serverVersion.split("\\.");
332 String[] editorVersionSplit = editorVersion.split("\\.");
333
334 if(serverVersionSplit.length < 3 || editorVersionSplit.length < 3 || serverVersionSplit.length > 4 || editorVersionSplit.length > 4) {
335 throw new CdmSourceException("cdmlib-services server or editor version is invalid");
336 }
337
338 Integer serverVersionPart;
339 Integer editorVersionPart;
340
341 for(int i=0 ; i<3 ; i++) {
342 serverVersionPart = Integer.valueOf(serverVersionSplit[i]);
343 editorVersionPart = Integer.valueOf(editorVersionSplit[i]);
344
345 int partCompare = serverVersionPart.compareTo(editorVersionPart);
346 if (partCompare != 0){
347 return partCompare;
348 }
349 }
350 // at this point major, minor and patch versions are matching
351
352 if(StringUtils.isBlank(serverCdmlibLastModified) || StringUtils.isBlank(editorCdmlibLastModified)) {
353 throw new CdmSourceException("cdmlib-services server or editor version is empty");
354 }
355
356 String cdmServerIgnoreVersion = System.getProperty("cdm.server.version.lm.ignore");
357 if(StringUtils.isBlank(cdmServerIgnoreVersion) || !cdmServerIgnoreVersion.equals("true")) {
358 Long serverLastModified = Long.valueOf(serverCdmlibLastModified);
359 Long editorLastModified = Long.valueOf(editorCdmlibLastModified);
360 return serverLastModified.compareTo(editorLastModified);
361 }
362
363 return 0;
364 }
365
366
367
368 public static List<CdmServerInfo> getCdmServers() {
369 if(cdmServerInfoList == null) {
370 cdmServerInfoList = new ArrayList<CdmServerInfo>();
371 cdmServerInfoList.add(new CdmServerInfo(NAME_PRODUCTION, SERVER_PRODUCTION, 80));
372 //cdmServerInfoList.add(new CdmServerInfo(NAME_INTEGRATION, SERVER_INTEGRATION, 80));
373 cdmServerInfoList.add(new CdmServerInfo(NAME_DEMO_1, SERVER_DEMO_1, 80));
374 // cdmServerInfoList.add(new CdmServerInfo(NAME_DEMO_2, SERVER_DEMO_2, 80));
375 //cdmServerInfoList.add(new CdmServerInfo(NAME_TEST, SERVER_TEST, 80));
376 // cdmServerInfoList.add(new CdmServerInfo(NAME_LOCALHOST, SERVER_LOCALHOST, 8080));
377 cdmServerInfoList.add(new CdmServerInfo(NAME_LOCALHOST_MGD, SERVER_LOCALHOST,NULL_PORT));
378 }
379 return cdmServerInfoList;
380 }
381
382 public String getName() {
383 return name;
384 }
385
386 public String getServer() {
387 return server;
388 }
389
390
391 public int getPort() {
392 return port;
393 }
394
395 public void setPort(int port) {
396 this.port = port;
397 }
398
399 public List<CdmInstanceInfo> getInstances() throws CDMServerException {
400 if(instances.isEmpty()) {
401 refreshInstances();
402 }
403 return instances;
404 }
405
406 public static CdmRemoteSource getDevServerRemoteSource() {
407 String value = System.getProperty("cdm.server.dev.port");
408 boolean available = false;
409 CdmInstanceInfo devInstance = null;
410 if(value != null && !value.isEmpty()) {
411 int devPort = Integer.valueOf(value);
412 CdmServerInfo devCii = new CdmServerInfo(NAME_LOCALHOST_DEV, SERVER_LOCALHOST_DEV, devPort);
413 try {
414 devInstance = devCii.addInstance(NAME_INSTANCE_LOCALHOST_DEV, BASEPATH_LOCALHOST_DEV);
415 available = devCii.pingInstance(devInstance, devPort);
416 if(available) {
417 return devCii.getCdmRemoteSource(devInstance, devPort);
418 }
419 } catch (Exception e) {
420
421 }
422 }
423 return null;
424 }
425
426 public class CdmInstanceInfo {
427 private final String name;
428
429 /**
430 * The full path of the instance including the the prefix (if any).
431 * E.g. for an EDIT instance this would be something like "cdmserver/remoting"
432 * For a managed local server this would simply be ""
433 */
434 private final String basePath;
435
436
437 public CdmInstanceInfo(String name, String basePath) {
438 this.name = name;
439 this.basePath = basePath;
440 }
441
442
443 public String getName() {
444 return name;
445 }
446
447 public String getBasePath() {
448 return basePath;
449 }
450 }
451 }