Project

General

Profile

Download (16.2 KB) Statistics
| Branch: | Tag: | Revision:
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
import eu.etaxonomy.taxeditor.remoting.server.CDMServerUtils;
42

    
43
/**
44
 * @author cmathew
45
 * @date 20 Jan 2015
46
 *
47
 */
48
public class CdmServerInfo {
49
    public static final Logger logger = Logger.getLogger(CdmServerInfo.class);
50

    
51
    private final static String CDMSERVER_PREFIX = "cdmserver/";
52
    private final static String NAME_PRODUCTION = "cybertaxonomy.org";
53
    private final static String SERVER_PRODUCTION = "api.cybertaxonomy.org";
54

    
55
    private final static String NAME_INTEGRATION = "edit-integration";
56
    private final static String SERVER_INTEGRATION = "int.e-taxonomy.eu";
57

    
58
    private final static String NAME_DEMO_1 = "edit-WS I";
59
    private final static String SERVER_DEMO_1 = "160.45.63.230";
60

    
61
    private final static String NAME_DEMO_2 = "edit-WS II";
62
    private final static String SERVER_DEMO_2 = "160.45.63.231";
63

    
64
    private final static String NAME_TEST = "edit-test";
65
    private final static String SERVER_TEST = "test.e-taxonomy.eu";
66

    
67
    public final static String SERVER_LOCALHOST = "localhost";
68
    private final static String NAME_LOCALHOST = "localhost";
69
    public final static String NAME_LOCALHOST_MGD = "localhost mgd.";
70

    
71
    private final static String NAME_LOCALHOST_DEV = "localhost-dev";
72
    private final static String NAME_INSTANCE_LOCALHOST_DEV = "local-dev";
73
    private final static String SERVER_LOCALHOST_DEV = "localhost";
74
    private final static int PORT_LOCALHOST_DEV = 8080;
75
    private final static String BASEPATH_LOCALHOST_DEV = "";
76

    
77
    public final static int NULL_PORT = -1;
78
    public final static String NULL_PORT_STRING = "N/A";
79

    
80

    
81
    private final String name;
82
    private final String server;
83
    private int port;
84
    private final List<CdmInstanceInfo> instances;
85

    
86
    private static List<CdmServerInfo> cdmServerInfoList;
87

    
88
    private String cdmlibServicesVersion = "";
89
    private String cdmlibServicesLastModified = "";
90

    
91
    private String prefix = "";
92

    
93
    private boolean ignoreCdmLibVersion = false;
94

    
95

    
96
    public CdmServerInfo(String name, String server, int port, String prefix, boolean ignoreCdmLibVersion) {
97
        this.name = name;
98
        this.server = server;
99
        this.port = port;
100
        this.prefix = prefix;
101
        this.ignoreCdmLibVersion = ignoreCdmLibVersion;
102
        instances = new ArrayList<CdmInstanceInfo>();
103

    
104
    }
105

    
106

    
107
    public CdmInstanceInfo addInstance(String name, String basePath) {
108
        String _basePath = basePath;
109
        if(isLocalhostMgd()) {
110
            _basePath = "";
111
        }
112
        CdmInstanceInfo cii = new CdmInstanceInfo(name, _basePath);
113
        instances.add(cii);
114
        return cii;
115

    
116
    }
117

    
118
    public boolean isLocalhost() {
119
        return name.startsWith(SERVER_LOCALHOST);
120
    }
121

    
122
    public boolean isLocalhostMgd() {
123
        return NAME_LOCALHOST_MGD.equals(name);
124
    }
125

    
126
    public String getCdmlibServicesVersion() {
127
        return cdmlibServicesVersion;
128
    }
129

    
130
    public String getCdmlibLastModified() {
131
        return cdmlibServicesLastModified;
132
    }
133

    
134
    public void refreshInstances() throws CDMServerException {
135
        instances.clear();
136
        if(isLocalhostMgd()) {
137
            addInstancesFromDataSourcesConfig();
138
        } else {
139
            addInstancesViaHttp();
140
        }
141
        Collections.sort(instances, new Comparator<CdmInstanceInfo>() {
142
            @Override
143
            public int compare(CdmInstanceInfo cii1, CdmInstanceInfo cii2)
144
            {
145
                return cii1.getName().toString().compareTo(cii2.getName().toString());
146
            }
147
        });
148
    }
149

    
150
    public void updateInfo() throws CDMServerException {
151
        String url = "http://" + server + ":" + String.valueOf(port) + "/" + prefix + "info.jsp";
152
        String responseBody = getResponse(url);
153
        if(responseBody != null) {
154
            try {
155
                JSONObject info = new JSONObject(responseBody);
156
                cdmlibServicesVersion =  info.getString("cdmlibServicesVersion");
157
                cdmlibServicesLastModified = info.getString("cdmlibServicesLastModified");
158
            } catch (JSONException e) {
159
                throw new CDMServerException(e);
160
            }
161
        }
162
    }
163

    
164
    public void addInstancesViaHttp() throws CDMServerException {
165
        updateInfo();
166
        String url = "http://" + server + ":" + String.valueOf(port) + "/" + prefix + "instances.jsp";
167
        String responseBody = getResponse(url);
168
        if(responseBody != null) {
169
            try {
170
                JSONArray array = new JSONArray(responseBody);
171
                for(int i=0;i<array.length();i++) {
172
                    JSONObject instance = (JSONObject)array.get(i);
173
                    if(instance != null) {
174
                        JSONObject conf = (JSONObject)instance.get("configuration");
175
                        if(conf != null) {
176
                            String instanceName = conf.getString("instanceName");
177
                            // we need to remove the first (char) forward slash from
178
                            // the base path
179
                            String basePath = conf.getString("basePath").substring(1);
180
                            addInstance(instanceName, basePath);
181
                            logger.info("Added instance with name : " + instanceName + ", basePath : " + basePath);
182
                        }
183
                    }
184
                }
185
            } catch (JSONException e) {
186
                throw new CDMServerException(e);
187
            }
188
        }
189
    }
190

    
191
    private String getResponse(String url) throws CDMServerException {
192
        HttpClient client = new DefaultHttpClient();
193
        HttpParams params = client.getParams();
194

    
195
        HttpConnectionParams.setConnectionTimeout(params, 5000);
196
        HttpConnectionParams.setSoTimeout(params, 5000);
197

    
198
        HttpGet httpGet = new HttpGet(url);
199

    
200
        logger.info("Executing request " + httpGet.getRequestLine());
201

    
202
        // Create a custom response handler
203
        ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
204

    
205
            @Override
206
            public String handleResponse(
207
                    final HttpResponse response) throws ClientProtocolException, IOException {
208
                int status = response.getStatusLine().getStatusCode();
209
                if (status >= 200 && status < 300) {
210
                    HttpEntity entity = response.getEntity();
211
                    return entity != null ? EntityUtils.toString(entity) : null;
212
                } else {
213
                    throw new ClientProtocolException("Unexpected response status: " + status);
214
                }
215
            }
216

    
217
        };
218
        String responseBody = null;
219
        try {
220
            responseBody = client.execute(httpGet, responseHandler);
221
        } catch (ClientProtocolException e) {
222
            throw new CDMServerException(e);
223
        } catch (IOException e) {
224
            throw new CDMServerException(e);
225
        }
226
        return responseBody;
227
    }
228

    
229
    public void addInstancesFromDataSourcesConfig() {
230
        for(ICdmDataSource dataSource : CdmPersistentDataSource.getAllDataSources()){
231
            String datasourceNCName = CDMServerUtils.xmlNCNamefrom(dataSource.getName());
232
            logger.info("Adding local instance " + dataSource.getName() + " as " + datasourceNCName);
233
            addInstance(datasourceNCName, datasourceNCName);
234
        }
235
    }
236

    
237
    public String toString(String instanceName, int port) {
238
        return server + ":" + String.valueOf(port) + "/" + instanceName;
239
    }
240

    
241
    public CdmInstanceInfo getInstanceFromName(String instanceName) {
242
        if(instanceName == null) {
243
            return null;
244
        }
245

    
246
        for(CdmInstanceInfo instance : instances) {
247
            if(instance.getName() != null && instance.getName().equals(instanceName)) {
248
                return instance;
249
            }
250
        }
251
        return null;
252
    }
253

    
254
    public CdmRemoteSource getCdmRemoteSource(CdmInstanceInfo instance, int port) {
255
        if(instance != null) {
256
            return CdmRemoteSource.NewInstance(name,
257
                    server,
258
                    port,
259
                    instance.getBasePath(),
260
                    null);
261
        }
262
        return null;
263
    }
264

    
265
    public boolean pingServer() {
266
        if(isLocalhostMgd()) {
267
            return true;
268
        }
269
        try {
270
            Socket s = new Socket(server, port);
271
            logger.info("[CDM-Server] Available @ " + server + ":" + port );
272
            updateInfo();
273
            return true;
274
        } catch (IOException ioe) {
275

    
276
        } catch (CDMServerException e) {
277

    
278
        }
279
        return false;
280
    }
281

    
282
    public boolean pingInstance(CdmInstanceInfo instance, int port) throws CDMServerException  {
283

    
284
        ICdmRemoteSource crs = getCdmRemoteSource(instance, port);
285
        try {
286
            if(crs != null && crs.checkConnection()) {
287
                logger.info("[CDM-Server] Running @ " + server + ":" + port + " for instance " + instance);
288
                return true;
289
            }
290
        } catch (CdmSourceException e) {
291
            throw new CDMServerException(e);
292
        }
293

    
294
        return false;
295
    }
296

    
297
    public int compareDbSchemaVersion(CdmInstanceInfo instance, int port) throws CDMServerException {
298

    
299
        ICdmRemoteSource crs = getCdmRemoteSource(instance, port);
300
        String dbSchemaVersion;
301
        try {
302
            dbSchemaVersion = crs.getDbSchemaVersion();
303
        } catch (CdmSourceException e) {
304
            throw new CDMServerException(e);
305
        }
306

    
307

    
308
        if(dbSchemaVersion != null) {
309
            return CdmMetaData.compareVersion(dbSchemaVersion, CdmMetaData.getDbSchemaVersion(), 3, null);
310
        } else {
311
            throw new CDMServerException("Cannot determine editor db. schema version");
312
        }
313
    }
314

    
315
    public int compareCdmlibServicesVersion() throws CdmSourceException {
316

    
317
        String serverVersion = cdmlibServicesVersion;
318
        String serverCdmlibLastModified = cdmlibServicesLastModified;
319
        if(ignoreCdmLibVersion) {
320
            return 0;
321
        } else {
322
            return compareCdmlibServicesVersion(serverVersion, serverCdmlibLastModified);
323
        }
324
    }
325

    
326

    
327
    /**
328
     * @param serverVersion
329
     * @param editorVersion
330
     * @throws CdmSourceException
331
     */
332
    public static int compareCdmlibServicesVersion(String serverVersion, String serverCdmlibLastModified) throws CdmSourceException {
333

    
334
        String editorVersion = CdmApplicationState.getCdmlibVersion();
335
        String editorCdmlibLastModified = CdmApplicationState.getCdmlibLastModified();
336

    
337
        int result = 0;
338
        if(StringUtils.isBlank(serverVersion) || StringUtils.isBlank(editorVersion)) {
339
            throw new CdmSourceException("cdmlib-services server or editor version is empty");
340
        }
341

    
342
        String[] serverVersionSplit = serverVersion.split("\\.");
343
        String[] editorVersionSplit = editorVersion.split("\\.");
344

    
345
        if(serverVersionSplit.length < 3 || editorVersionSplit.length < 3 || serverVersionSplit.length > 4 || editorVersionSplit.length > 4) {
346
            throw new CdmSourceException("cdmlib-services server or editor version is invalid");
347
        }
348

    
349
        Integer serverVersionPart;
350
        Integer editorVersionPart;
351

    
352
        for(int i=0 ; i<3 ; i++) {
353
            serverVersionPart = Integer.valueOf(serverVersionSplit[i]);
354
            editorVersionPart = Integer.valueOf(editorVersionSplit[i]);
355

    
356
            int partCompare = serverVersionPart.compareTo(editorVersionPart);
357
            if (partCompare != 0){
358
                return partCompare;
359
            }
360
        }
361
        // at this point major, minor and patch versions are matching
362

    
363
        if(StringUtils.isBlank(serverCdmlibLastModified) || StringUtils.isBlank(editorCdmlibLastModified)) {
364
            throw new CdmSourceException("cdmlib-services server or editor version is empty");
365
        }
366

    
367
        String cdmServerIgnoreVersion = System.getProperty("cdm.server.version.lm.ignore");
368
        if(StringUtils.isBlank(cdmServerIgnoreVersion) || !cdmServerIgnoreVersion.equals("true")) {
369
            Long serverLastModified = Long.valueOf(serverCdmlibLastModified);
370
            Long editorLastModified = Long.valueOf(editorCdmlibLastModified);
371
            return serverLastModified.compareTo(editorLastModified);
372
        }
373

    
374
        return 0;
375
    }
376

    
377

    
378

    
379
    public static List<CdmServerInfo> getCdmServers() {
380
        if(cdmServerInfoList == null) {
381
           cdmServerInfoList = new ArrayList<CdmServerInfo>();
382
           // cdmServerInfoList.add(new CdmServerInfo(NAME_PRODUCTION, SERVER_PRODUCTION, 80, ""));
383
           //cdmServerInfoList.add(new CdmServerInfo(NAME_INTEGRATION, SERVER_INTEGRATION, 80, CDMSERVER_PREFIX));
384
           cdmServerInfoList.add(new CdmServerInfo(NAME_DEMO_1, SERVER_DEMO_1, 80, CDMSERVER_PREFIX, false));
385
           // cdmServerInfoList.add(new CdmServerInfo(NAME_DEMO_2, SERVER_DEMO_2, 80, CDMSERVER_PREFIX));
386
           cdmServerInfoList.add(new CdmServerInfo(NAME_TEST, SERVER_TEST, 80, CDMSERVER_PREFIX, false));
387
           cdmServerInfoList.add(new CdmServerInfo(NAME_LOCALHOST, SERVER_LOCALHOST, 8080, CDMSERVER_PREFIX, true));
388
           cdmServerInfoList.add(new CdmServerInfo(NAME_LOCALHOST_MGD, SERVER_LOCALHOST, NULL_PORT, CDMSERVER_PREFIX, false));
389
        }
390
        return cdmServerInfoList;
391
    }
392

    
393
    public String getName() {
394
        return name;
395
    }
396

    
397
    public String getServer() {
398
        return server;
399
    }
400

    
401

    
402
    public int getPort() {
403
        return port;
404
    }
405

    
406
    public void setPort(int port) {
407
        this.port = port;
408
    }
409

    
410
    public List<CdmInstanceInfo> getInstances() throws CDMServerException {
411
        if(instances.isEmpty()) {
412
            refreshInstances();
413
        }
414
        return instances;
415
    }
416

    
417
    public static CdmRemoteSource getDevServerRemoteSource() {
418
        String value = System.getProperty("cdm.server.dev.port");
419
        boolean available = false;
420
        CdmInstanceInfo devInstance = null;
421
        if(value != null && !value.isEmpty()) {
422
            int devPort = Integer.valueOf(value);
423
            CdmServerInfo devCii = new CdmServerInfo(NAME_LOCALHOST_DEV, SERVER_LOCALHOST_DEV, devPort, "", false);
424
            try {
425
                devInstance = devCii.addInstance(NAME_INSTANCE_LOCALHOST_DEV, BASEPATH_LOCALHOST_DEV);
426
                available = devCii.pingInstance(devInstance, devPort);
427
                if(available) {
428
                    return devCii.getCdmRemoteSource(devInstance, devPort);
429
                }
430
            } catch (Exception e) {
431

    
432
            }
433
        }
434
        return null;
435
    }
436

    
437
    public class CdmInstanceInfo {
438
        private final String name;
439

    
440
        /**
441
         * The full path of the instance including the the prefix (if any).
442
         * E.g. for an EDIT instance this would be something like "cdmserver/remoting"
443
         * For a managed local server this would simply be ""
444
         */
445
        private final String basePath;
446

    
447

    
448
        public CdmInstanceInfo(String name, String basePath) {
449
            this.name = name;
450
            this.basePath = basePath;
451
        }
452

    
453

    
454
        public String getName() {
455
            return name;
456
        }
457

    
458
        public String getBasePath() {
459
            return basePath;
460
        }
461
    }
462
}
(5-5/6)