Project

General

Profile

Download (15.6 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

    
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 = "";
51
    private final static String NAME_PRODUCTION = "cybertaxonomy.org";
52
    private final static String SERVER_PRODUCTION = "api.cybertaxonomy.org";
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
}
(5-5/6)