Project

General

Profile

Download (15.8 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 = "";
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

    
92
    public CdmServerInfo(String name, String server, int port) {
93
        this.name = name;
94
        this.server = server;
95
        this.port = port;
96
        instances = new ArrayList<CdmInstanceInfo>();
97

    
98
    }
99

    
100

    
101
    public CdmInstanceInfo addInstance(String name, String basePath) {
102
        String _basePath = basePath;
103
        if(isLocalhostMgd()) {
104
            _basePath = "";
105
        }
106
        CdmInstanceInfo cii = new CdmInstanceInfo(name, _basePath);
107
        instances.add(cii);
108
        return cii;
109

    
110
    }
111

    
112
    public boolean isLocalhost() {
113
        return name.startsWith(SERVER_LOCALHOST);
114
    }
115

    
116
    public boolean isLocalhostMgd() {
117
        return NAME_LOCALHOST_MGD.equals(name);
118
    }
119

    
120
    public String getCdmlibServicesVersion() {
121
        return cdmlibServicesVersion;
122
    }
123

    
124
    public String getCdmlibLastModified() {
125
        return cdmlibServicesLastModified;
126
    }
127

    
128
    public void refreshInstances() throws CDMServerException {
129
        instances.clear();
130
        if(isLocalhostMgd()) {
131
            addInstancesFromDataSourcesConfig();
132
        } else {
133
            addInstancesViaHttp();
134
        }
135
        Collections.sort(instances, new Comparator<CdmInstanceInfo>() {
136
            @Override
137
            public int compare(CdmInstanceInfo cii1, CdmInstanceInfo cii2)
138
            {
139
                return cii1.getName().toString().compareTo(cii2.getName().toString());
140
            }
141
        });
142
    }
143

    
144
    public void updateInfo() throws CDMServerException {
145
        String url = "http://" + server + ":" + String.valueOf(port) + "/" + CDMSERVER_PREFIX + "/info.jsp";
146
        String responseBody = getResponse(url);
147
        if(responseBody != null) {
148
            try {
149
                JSONObject info = new JSONObject(responseBody);
150
                cdmlibServicesVersion =  info.getString("cdmlibServicesVersion");
151
                cdmlibServicesLastModified = info.getString("cdmlibServicesLastModified");
152
            } catch (JSONException e) {
153
                throw new CDMServerException(e);
154
            }
155
        }
156
    }
157

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

    
185
    private String getResponse(String url) throws CDMServerException {
186
        HttpClient client = new DefaultHttpClient();
187
        HttpParams params = client.getParams();
188

    
189
        HttpConnectionParams.setConnectionTimeout(params, 5000);
190
        HttpConnectionParams.setSoTimeout(params, 5000);
191

    
192
        HttpGet httpGet = new HttpGet(url);
193

    
194
        logger.info("Executing request " + httpGet.getRequestLine());
195

    
196
        // Create a custom response handler
197
        ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
198

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

    
211
        };
212
        String responseBody = null;
213
        try {
214
            responseBody = client.execute(httpGet, responseHandler);
215
        } catch (ClientProtocolException e) {
216
            throw new CDMServerException(e);
217
        } catch (IOException e) {
218
            throw new CDMServerException(e);
219
        }
220
        return responseBody;
221
    }
222

    
223
    public void addInstancesFromDataSourcesConfig() {
224
        for(ICdmDataSource dataSource : CdmPersistentDataSource.getAllDataSources()){
225
            String datasourceNCName = CDMServerUtils.xmlNCNamefrom(dataSource.getName());
226
            logger.info("Adding local instance " + dataSource.getName() + " as " + datasourceNCName);
227
            addInstance(datasourceNCName, datasourceNCName);
228
        }
229
    }
230

    
231
    public String toString(String instanceName, int port) {
232
        return server + ":" + String.valueOf(port) + "/" + instanceName;
233
    }
234

    
235
    public CdmInstanceInfo getInstanceFromName(String instanceName) {
236
        if(instanceName == null) {
237
            return null;
238
        }
239

    
240
        for(CdmInstanceInfo instance : instances) {
241
            if(instance.getName() != null && instance.getName().equals(instanceName)) {
242
                return instance;
243
            }
244
        }
245
        return null;
246
    }
247

    
248
    public CdmRemoteSource getCdmRemoteSource(CdmInstanceInfo instance, int port) {
249
        if(instance != null) {
250
            return CdmRemoteSource.NewInstance(name,
251
                    server,
252
                    port,
253
                    instance.getBasePath(),
254
                    null);
255
        }
256
        return null;
257
    }
258

    
259
    public boolean pingServer() {
260
        if(isLocalhostMgd()) {
261
            return true;
262
        }
263
        try {
264
            Socket s = new Socket(server, port);
265
            logger.info("[CDM-Server] Available @ " + server + ":" + port );
266
            updateInfo();
267
            return true;
268
        } catch (IOException ioe) {
269

    
270
        } catch (CDMServerException e) {
271

    
272
        }
273
        return false;
274
    }
275

    
276
    public boolean pingInstance(CdmInstanceInfo instance, int port) throws CDMServerException  {
277

    
278
        ICdmRemoteSource crs = getCdmRemoteSource(instance, port);
279
        try {
280
            if(crs != null && crs.checkConnection()) {
281
                logger.info("[CDM-Server] Running @ " + server + ":" + port + " for instance " + instance);
282
                return true;
283
            }
284
        } catch (CdmSourceException e) {
285
            throw new CDMServerException(e);
286
        }
287

    
288
        return false;
289
    }
290

    
291
    public int compareDbSchemaVersion(CdmInstanceInfo instance, int port) throws CDMServerException {
292

    
293
        ICdmRemoteSource crs = getCdmRemoteSource(instance, port);
294
        String dbSchemaVersion;
295
        try {
296
            dbSchemaVersion = crs.getDbSchemaVersion();
297
        } catch (CdmSourceException e) {
298
            throw new CDMServerException(e);
299
        }
300

    
301

    
302
        if(dbSchemaVersion != null) {
303
            return CdmMetaData.compareVersion(dbSchemaVersion, CdmMetaData.getDbSchemaVersion(), 3, null);
304
        } else {
305
            throw new CDMServerException("Cannot determine editor db. schema version");
306
        }
307
    }
308

    
309
    public int compareCdmlibServicesVersion() throws CdmSourceException {
310

    
311
        String serverVersion = cdmlibServicesVersion;
312
        String serverCdmlibLastModified = cdmlibServicesLastModified;
313

    
314
        return compareCdmlibServicesVersion(serverVersion, serverCdmlibLastModified);
315
    }
316

    
317

    
318
    /**
319
     * @param serverVersion
320
     * @param editorVersion
321
     * @throws CdmSourceException
322
     */
323
    public static int compareCdmlibServicesVersion(String serverVersion, String serverCdmlibLastModified) throws CdmSourceException {
324

    
325
        String editorVersion = CdmApplicationState.getCdmlibVersion();
326
        String editorCdmlibLastModified = CdmApplicationState.getCdmlibLastModified();
327

    
328
        int result = 0;
329
        if(StringUtils.isBlank(serverVersion) || StringUtils.isBlank(editorVersion)) {
330
            throw new CdmSourceException("cdmlib-services server or editor version is empty");
331
        }
332

    
333
        String[] serverVersionSplit = serverVersion.split("\\.");
334
        String[] editorVersionSplit = editorVersion.split("\\.");
335

    
336
        if(serverVersionSplit.length < 3 || editorVersionSplit.length < 3 || serverVersionSplit.length > 4 || editorVersionSplit.length > 4) {
337
            throw new CdmSourceException("cdmlib-services server or editor version is invalid");
338
        }
339

    
340
        Integer serverVersionPart;
341
        Integer editorVersionPart;
342

    
343
        for(int i=0 ; i<3 ; i++) {
344
            serverVersionPart = Integer.valueOf(serverVersionSplit[i]);
345
            editorVersionPart = Integer.valueOf(editorVersionSplit[i]);
346

    
347
            int partCompare = serverVersionPart.compareTo(editorVersionPart);
348
            if (partCompare != 0){
349
                return partCompare;
350
            }
351
        }
352
        // at this point major, minor and patch versions are matching
353

    
354
        if(StringUtils.isBlank(serverCdmlibLastModified) || StringUtils.isBlank(editorCdmlibLastModified)) {
355
            throw new CdmSourceException("cdmlib-services server or editor version is empty");
356
        }
357

    
358
        String cdmServerIgnoreVersion = System.getProperty("cdm.server.version.lm.ignore");
359
        if(StringUtils.isBlank(cdmServerIgnoreVersion) || !cdmServerIgnoreVersion.equals("true")) {
360
            Long serverLastModified = Long.valueOf(serverCdmlibLastModified);
361
            Long editorLastModified = Long.valueOf(editorCdmlibLastModified);
362
            return serverLastModified.compareTo(editorLastModified);
363
        }
364

    
365
        return 0;
366
    }
367

    
368

    
369

    
370
    public static List<CdmServerInfo> getCdmServers() {
371
        if(cdmServerInfoList == null) {
372
            cdmServerInfoList = new ArrayList<CdmServerInfo>();
373
            cdmServerInfoList.add(new CdmServerInfo(NAME_PRODUCTION, SERVER_PRODUCTION, 80));
374
            //cdmServerInfoList.add(new CdmServerInfo(NAME_INTEGRATION, SERVER_INTEGRATION, 80));
375
            cdmServerInfoList.add(new CdmServerInfo(NAME_DEMO_1, SERVER_DEMO_1, 80));
376
           // cdmServerInfoList.add(new CdmServerInfo(NAME_DEMO_2, SERVER_DEMO_2, 80));
377
           //cdmServerInfoList.add(new CdmServerInfo(NAME_TEST, SERVER_TEST, 80));
378
           // cdmServerInfoList.add(new CdmServerInfo(NAME_LOCALHOST, SERVER_LOCALHOST, 8080));
379
            cdmServerInfoList.add(new CdmServerInfo(NAME_LOCALHOST_MGD, SERVER_LOCALHOST,NULL_PORT));
380
        }
381
        return cdmServerInfoList;
382
    }
383

    
384
    public String getName() {
385
        return name;
386
    }
387

    
388
    public String getServer() {
389
        return server;
390
    }
391

    
392

    
393
    public int getPort() {
394
        return port;
395
    }
396

    
397
    public void setPort(int port) {
398
        this.port = port;
399
    }
400

    
401
    public List<CdmInstanceInfo> getInstances() throws CDMServerException {
402
        if(instances.isEmpty()) {
403
            refreshInstances();
404
        }
405
        return instances;
406
    }
407

    
408
    public static CdmRemoteSource getDevServerRemoteSource() {
409
        String value = System.getProperty("cdm.server.dev.port");
410
        boolean available = false;
411
        CdmInstanceInfo devInstance = null;
412
        if(value != null && !value.isEmpty()) {
413
            int devPort = Integer.valueOf(value);
414
            CdmServerInfo devCii = new CdmServerInfo(NAME_LOCALHOST_DEV, SERVER_LOCALHOST_DEV, devPort);
415
            try {
416
                devInstance = devCii.addInstance(NAME_INSTANCE_LOCALHOST_DEV, BASEPATH_LOCALHOST_DEV);
417
                available = devCii.pingInstance(devInstance, devPort);
418
                if(available) {
419
                    return devCii.getCdmRemoteSource(devInstance, devPort);
420
                }
421
            } catch (Exception e) {
422

    
423
            }
424
        }
425
        return null;
426
    }
427

    
428
    public class CdmInstanceInfo {
429
        private final String name;
430

    
431
        /**
432
         * The full path of the instance including the the prefix (if any).
433
         * E.g. for an EDIT instance this would be something like "cdmserver/remoting"
434
         * For a managed local server this would simply be ""
435
         */
436
        private final String basePath;
437

    
438

    
439
        public CdmInstanceInfo(String name, String basePath) {
440
            this.name = name;
441
            this.basePath = basePath;
442
        }
443

    
444

    
445
        public String getName() {
446
            return name;
447
        }
448

    
449
        public String getBasePath() {
450
            return basePath;
451
        }
452
    }
453
}
(5-5/6)