9b7d1159e1b01b5c7a266ce9d8a57edbd054e7e8
[ccsdk/features.git] /
1 /*******************************************************************************
2  * ============LICENSE_START========================================================================
3  * ONAP : ccsdk feature sdnr wt
4  * =================================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
6  * =================================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License.
16  * ============LICENSE_END==========================================================================
17  ******************************************************************************/
18 package org.onap.ccsdk.features.sdnr.wt.devicemanager.base.database;
19
20 import java.io.IOException;
21 import java.net.InetAddress;
22 import java.net.UnknownHostException;
23 import java.nio.charset.StandardCharsets;
24 import java.nio.file.Files;
25 import java.nio.file.Paths;
26 import java.util.HashSet;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Set;
30 import javax.annotation.Nonnull;
31 import javax.annotation.Nullable;
32 import org.elasticsearch.ElasticsearchException;
33 import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
34 import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse;
35 import org.elasticsearch.action.admin.indices.alias.IndicesAliasesResponse;
36 import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
37 import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
38 import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequestBuilder;
39 import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
40 import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
41 import org.elasticsearch.action.delete.DeleteResponse;
42 import org.elasticsearch.action.get.GetResponse;
43 import org.elasticsearch.action.index.IndexRequestBuilder;
44 import org.elasticsearch.action.index.IndexResponse;
45 import org.elasticsearch.action.search.SearchResponse;
46 import org.elasticsearch.client.Client;
47 import org.elasticsearch.client.transport.TransportClient;
48 import org.elasticsearch.cluster.node.DiscoveryNode;
49 import org.elasticsearch.common.bytes.BytesReference;
50 import org.elasticsearch.common.settings.Settings;
51 import org.elasticsearch.common.transport.InetSocketTransportAddress;
52 import org.elasticsearch.common.unit.TimeValue;
53 import org.elasticsearch.index.query.QueryBuilder;
54 import org.elasticsearch.index.query.QueryBuilders;
55 import org.elasticsearch.search.SearchHit;
56 import org.json.JSONObject;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59
60 /**
61  * @author Herbert
62  *
63  */
64 public class HtDatabaseClientAbstract implements HtDataBase, AutoCloseable {
65
66     private final Logger log = LoggerFactory.getLogger(HtDatabaseClientAbstract.class);
67
68     private static int DELAYSECONDS = 10;
69     private final Client client;
70     private String esIndexAlias;
71
72     /**
73      * Full database initialization.
74      *
75      * @param esIndex Database index
76      * @param esNodeserverName Servername or Server-IP that hosts the node.
77      * @param esClusterName Name of the cluster
78      * @param esNodeName Name of the node within the cluster to connect to.
79      * @throws UnknownHostException Servername not known.
80      */
81     public HtDatabaseClientAbstract(String esIndex, String esNodeserverName, String esClusterName, String esNodeName)
82             throws UnknownHostException {
83
84         this.esIndexAlias = esIndex;
85
86         Settings settings =
87                 Settings.settingsBuilder().put("cluster.name", esClusterName).put("node.name", esNodeName).build();
88         this.client = getClient(esNodeserverName, settings);
89
90     }
91
92     /**
93      * Do not use the hostname, but use the IP for getting the client
94      *
95      * @param esIndex index to be used by the client
96      * @param esClusterName name of the ES cluster
97      * @param esNodeName name of the node
98      * @throws UnknownHostException if hostname not known
99      */
100     public HtDatabaseClientAbstract(String esIndex, String esClusterName, String esNodeName)
101             throws UnknownHostException {
102
103         this.esIndexAlias = esIndex;
104         Settings settings =
105                 Settings.settingsBuilder().put("cluster.name", esClusterName).put("node.name", esNodeName).build();
106         this.client = getClient(null, settings);
107     }
108
109
110     /**
111      * Simple database initialization. Query all ES configuration information from cluster node.
112      *
113      * @param esIndex Database index
114      * @param esNodeserverHostName Servername or Server-IP that hosts the node.
115      * @throws UnknownHostException Servername not known.
116      */
117
118     public HtDatabaseClientAbstract(String esIndex, String esNodeserverHostName) throws UnknownHostException {
119
120         this.esIndexAlias = esIndex;
121
122         Settings settings = Settings.settingsBuilder().put("client.transport.ignore_cluster_name", true)
123                 .put("client.transport.sniff", true).build();
124         this.client = getClient(esNodeserverHostName, settings);
125     }
126
127     /**
128      * Simple database initialization. Query all ES configuration information from cluster node.
129      *
130      * @param esIndex Database index
131      * @param database database node descriptor
132      */
133     public HtDatabaseClientAbstract(String esIndex, @Nonnull HtDatabaseNode database) {
134
135         this.esIndexAlias = esIndex;
136         this.client = database.getClient();
137     }
138
139
140     /*----------------------------------
141      * some constructing functions, used by public constructors
142      */
143     /**
144      *
145      * @param esNodeserverName
146      * @param settings
147      * @return
148      * @throws UnknownHostException
149      */
150     private final TransportClient getClient(@Nullable String esNodeserverName, Settings settings)
151             throws UnknownHostException {
152
153         TransportClient newClient = TransportClient.builder().settings(settings).build();
154
155         if (esNodeserverName != null) {
156             InetAddress nodeIp = InetAddress.getByName(esNodeserverName);
157             newClient.addTransportAddress(new InetSocketTransportAddress(nodeIp, 9300));
158         }
159
160         setup(newClient);
161         return newClient;
162     }
163
164     private void setup(TransportClient newClient) {
165         NodesInfoResponse nodeInfos = newClient.admin().cluster().prepareNodesInfo().get();
166         String clusterName = nodeInfos.getClusterName().value();
167
168         // ------ Debug/ Info
169         StringBuffer logInfo = new StringBuffer();
170         logInfo.append("Create ES Client an localhost for Cluster '");
171         logInfo.append(clusterName);
172         logInfo.append("' for index '");
173         logInfo.append(esIndexAlias);
174         logInfo.append("' Nodelist: ");
175         for (DiscoveryNode node : newClient.connectedNodes()) {
176             logInfo.append("(");
177             logInfo.append(node.toString());
178             logInfo.append(") ");
179         }
180         log.info(logInfo.toString());
181         // ------ Debug/ Info
182
183         log.info("Starting Database service. Short wait.");
184
185         ClusterHealthResponse nodeStatus = newClient.admin().cluster().prepareHealth().setWaitForGreenStatus()
186                 // .setWaitForYellowStatus()
187                 .setTimeout(TimeValue.timeValueSeconds(DELAYSECONDS)).get();
188         log.debug("Elasticsearch client started with status {}", nodeStatus.toString());
189
190
191         List<DiscoveryNode> nodeList = newClient.connectedNodes();
192
193         if (nodeList.isEmpty()) {
194             log.info("ES Client created for nodes: <empty node list>");
195         } else {
196             int t = 0;
197             for (DiscoveryNode dn : nodeList) {
198                 log.info("ES Client created for node#{}: {}", t, dn.getName());
199             }
200         }
201
202         Runtime.getRuntime().addShutdownHook(new Thread() {
203             @Override
204             public void run() {
205                 log.info("Shutdown node " + HtDatabaseClientAbstract.class.getSimpleName());
206             }
207         });
208
209         log.info("Database service started.");
210
211     }
212
213
214     /*----------------------------------
215      * Getter / Setter
216      */
217
218     @Override
219     public String getNetworkIndex() {
220         return esIndexAlias;
221     }
222
223     @Override
224     public void setNetworkIndex(String es_index) {
225         this.esIndexAlias = es_index;
226     }
227
228     @Override
229     public Client getClient() {
230         return client;
231     }
232
233     /*----------------------------------
234      * Functions
235      */
236
237     /**
238      * Close function
239      */
240     @Override
241     public void close() {
242         client.close();
243     }
244
245     /**
246      * Create an ES index. Delete an existing index.
247      */
248     public void doDeleteIndex() {
249         log.info("Remove index {}", esIndexAlias);
250
251         if (esIndexAlias == null) {
252             throw new IllegalArgumentException("Missing Index");
253         }
254
255         try {
256
257             // Delete index
258             IndicesExistsResponse res = client.admin().indices().prepareExists(esIndexAlias).execute().actionGet();
259
260             if (res.isExists()) {
261                 log.info("Delete Index start: {}", esIndexAlias);
262                 DeleteIndexRequestBuilder delIdx = client.admin().indices().prepareDelete(esIndexAlias);
263                 delIdx.execute().actionGet();
264                 log.info("Delete Index done.");
265             }
266
267         } catch (ElasticsearchException e) {
268             log.warn(e.getDetailedMessage());
269         }
270     }
271
272     /**
273      * Verify if index already created
274      *
275      * @return boolean accordingly
276      */
277     public boolean isExistsIndex() {
278
279         if (esIndexAlias == null) {
280             throw new IllegalArgumentException("Missing Index");
281         }
282
283         log.debug("Check status of ES index: {}", esIndexAlias);
284
285         final IndicesExistsResponse indexStatus =
286                 client.admin().indices().prepareExists(esIndexAlias).execute().actionGet();
287
288         return indexStatus.isExists();
289
290     }
291
292
293     /**
294      * Create and write the mapping and setting of the index
295      *
296      * @param jsonIndexMappingSetting with mapping and setting definition Object or null for no
297      *        configuration
298      */
299     public void doCreateIndexWithMapping(JSONObject jsonIndexMappingSetting) {
300
301         if (esIndexAlias == null) {
302             throw new IllegalArgumentException("Missing Index");
303         }
304
305         try {
306             // Create index with mapping and setting
307             String esIndexName = esIndexAlias + "_v1";
308             log.debug("Create not existing ES index: {} with alias:{}", esIndexName, esIndexAlias);
309
310             doCreateIndexWithMappingsAndSettings(esIndexName, jsonIndexMappingSetting);
311
312             // Set Alias
313             log.debug("Set alias {} to index {}", esIndexAlias, esIndexName);
314             IndicesAliasesResponse setAliasResponse =
315                     client.admin().indices().prepareAliases().addAlias(esIndexName, esIndexAlias).execute().actionGet();
316             log.debug("CreateIndex response {}", setAliasResponse);
317
318         } catch (ElasticsearchException e) {
319             log.warn("ElasticsearchException: {}", e.getDetailedMessage());
320         }
321     }
322
323
324     /**
325      * Assign each mapping in the mappings section as separate mapping entry
326      *
327      * @param createIndexRequestBuilder builder for command to ES
328      * @param jsonIndexMappingSetting json with mapping information
329      */
330     private void doCreateIndexWithMappingsAndSettings(String esIndexName, JSONObject jsonIndexMappingSetting) {
331
332         CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(esIndexName);
333         if (createIndexRequestBuilder == null) {
334             throw new HtDatabaseClientException("No client. Can not create index.", esIndexAlias);
335         }
336
337         if (jsonIndexMappingSetting != null) {
338             try {
339                 doAddMappings(createIndexRequestBuilder, jsonIndexMappingSetting);
340                 doAddSetting(createIndexRequestBuilder, jsonIndexMappingSetting);
341                 log.debug(" doCreateIndexWithMapping");
342             } catch (RuntimeException e) {
343                 log.info("Exception during adding mappings or settings to CreateIndexRequestBuilder. ", e);
344             }
345         }
346
347         CreateIndexResponse createResponse = createIndexRequestBuilder.execute().actionGet();
348         log.debug("CreateIndex response {}", createResponse);
349     }
350
351     /**
352      * Add one or more mappings to command
353      *
354      * @param createIndexRequestBuilder to add parameters
355      * @param jsonIndexMappingSetting contains mapping and setting information
356      */
357     private void doAddMappings(CreateIndexRequestBuilder createIndexRequestBuilder,
358             JSONObject jsonIndexMappingSetting) {
359
360         // If there are json information .. verify if they contain mappings
361         JSONObject jsonMapping = jsonIndexMappingSetting.optJSONObject("mappings");
362
363         // Handle optional mappings if requested
364         if (jsonMapping != null) {
365             log.debug("Set mapping for index {} {}", esIndexAlias, jsonMapping);
366
367             // For any reason the function below was not working without iterator
368             Set<String> keys = getStringKeySet(jsonMapping);
369             if (log.isDebugEnabled()) {
370                 log.debug("Found length: {} keys: {}", jsonMapping.length(), keys.size());
371             }
372
373             for (String docType : keys) {
374                 JSONObject jsonObject = jsonMapping.getJSONObject(docType);
375                 if (jsonObject != null) {
376                     String jsonObjectString = jsonObject.toString();
377                     log.debug("Doctype:{} mapping:{}", docType, jsonObjectString);
378                     createIndexRequestBuilder.addMapping(docType, jsonObjectString);
379                     log.debug("Mapping created Doctype:{}", docType);
380                 } else {
381                     log.debug("No jsonObject for docType {}", docType);
382                 }
383             }
384         } else {
385             log.debug("No mapping requested for index {}", esIndexAlias);
386         }
387     }
388
389     /**
390      * Add one setting to command
391      *
392      * @param createIndexRequestBuilder to add parameters
393      * @param jsonIndexMappingSetting contains mapping and setting information
394      */
395     private void doAddSetting(CreateIndexRequestBuilder createIndexRequestBuilder, JSONObject jsonIndexMappingSetting) {
396         // Handle optional settings if requested
397         log.debug("Handle settings");
398         JSONObject jsonSettings = jsonIndexMappingSetting.optJSONObject("settings");
399         if (jsonSettings != null) {
400             log.debug("Set setting for index {} {}", esIndexAlias, jsonSettings);
401             createIndexRequestBuilder.setSettings(Settings.settingsBuilder().loadFromSource(jsonSettings.toString()));
402         } else {
403             log.debug("No settings requested for index {}", esIndexAlias);
404         }
405     }
406
407     /**
408      * Create Index with alias according to definition, but no mapping
409      */
410     public void doCreateIndex() {
411         doCreateIndexWithMapping(null);
412     }
413
414     /**
415      * Write a JSON mapping definition for a document from a file to ES Hint: A later change of the
416      * mapping is not possible.
417      *
418      * @param jsonString String with mapping definition in JSON Format
419      */
420
421     public void doWriteMappingJson(String jsonString) {
422
423         if (esIndexAlias == null) {
424             throw new IllegalArgumentException("Missing Index");
425         }
426         if (jsonString == null) {
427             String s = "Mapping string parameter is null";
428             log.warn(s);
429             throw new IllegalArgumentException(s);
430         }
431
432         try {
433             // MAPPING GOES HERE
434             log.debug("Check status of ES index: {}", esIndexAlias);
435
436             final IndicesExistsResponse indexStatus =
437                     client.admin().indices().prepareExists(esIndexAlias).execute().actionGet();
438
439             if (indexStatus.isExists()) {
440                 log.debug("ES index exists: {}", esIndexAlias);
441                 // A change of mapping is not working. This here works only for new datatypes
442
443                 PutMappingResponse res = client.admin().indices().preparePutMapping(esIndexAlias).setSource(jsonString)
444                         .execute().actionGet();
445                 if (log.isDebugEnabled()) {
446                     log.debug("Result: {}", res);
447                 }
448
449             } else {
450                 log.debug("Create not existing ES index: {}", esIndexAlias);
451
452                 CreateIndexRequestBuilder createIndexRequestBuilder =
453                         client.admin().indices().prepareCreate(esIndexAlias);
454                 createIndexRequestBuilder.addMapping(jsonString).execute().actionGet();
455             }
456
457         } catch (ElasticsearchException e) {
458             log.warn(e.getDetailedMessage());
459         }
460     }
461
462     /**
463      * Write a Json mapping definition for a document from a file to ES
464      *
465      * @param fileName Filename with json definition.
466      */
467     public void doWriteMappingFromFile(String fileName) {
468
469
470         log.info("Write mapping from File: {}", fileName);
471
472         if (esIndexAlias == null) {
473             throw new IllegalArgumentException("Missing Index");
474         }
475
476         if (fileName == null) {
477             log.warn("No mapping for {} specified in parameter file.", esIndexAlias);
478             return;
479         }
480
481         String content = null;
482
483         try {
484             content = new String(Files.readAllBytes(Paths.get(fileName)), StandardCharsets.UTF_8);
485         } catch (IOException e1) {
486             log.warn("Problem with file {}: {}", fileName, e1.getMessage());
487         }
488
489         doWriteMappingJson(content);
490
491     }
492
493     /**
494      * Write list with json objects from json files
495      *
496      * @param docTypeAndFileName List with 2 String Array. String[0] Contains the dataType name
497      *        String[1] Contains the filename
498      */
499     public void doWriteJsonFiles(List<String[]> docTypeAndFileName) {
500
501         if (docTypeAndFileName != null) {
502             log.debug("Write number of JSONFiles: {}", docTypeAndFileName.size());
503             int t = 1;
504             for (String[] s : docTypeAndFileName) {
505                 if (s.length == 2) {
506                     writeJsonObjectsFromFile(s[0], s[1]);
507                 } else {
508                     log.warn("Wrong parameters number. Entry: {}", t);
509                 }
510                 t++;
511             }
512         }
513     }
514
515     /**
516      * Write one object into Database
517      *
518      * @param esId Database index
519      * @param dataTypeName Name of datatype
520      * @param json String in JSON format.
521      * @return esId of the object
522      */
523     @Override
524     public String doWriteJsonString(String dataTypeName, IsEsObject esId, String json) {
525         return doWriteByteArray(dataTypeName, esId, json.getBytes());
526     }
527
528     /**
529      * Write one object into Database
530      *
531      * @param esId Database index
532      * @param dataTypeName Name of datatype
533      * @param json String in JSON format.
534      * @return esId of the object
535      */
536
537     @Override
538     public String doWriteByteArray(String dataTypeName, IsEsObject esId, byte[] json) {
539         return doWriteRaw(dataTypeName, esId.getEsId(), json);
540     }
541
542     /**
543      * Write one object into Database
544      *
545      * @param dataTypeName Name of datatype
546      * @param id id of the object or null
547      * @param json Object as json
548      * @return esId of the Object
549      */
550     public String doWriteJsonObject(String dataTypeName, String id, JSONObject json) {
551         return doWriteRaw(dataTypeName, id, json.toString().getBytes());
552     }
553
554     /**
555      * Write one object into Database
556      *
557      * @param esId Database index or null
558      * @param dataTypeName Name of datatype
559      * @param json String in JSON format.
560      * @return esId of the object
561      */
562
563     public String doWriteRaw(String dataTypeName, String esId, byte[] json) {
564
565         if (esIndexAlias == null) {
566             throw new IllegalArgumentException("Missing Index");
567         }
568
569         IndexRequestBuilder request = esId == null || esId.isEmpty() ? client.prepareIndex(esIndexAlias, dataTypeName)
570                 : client.prepareIndex(esIndexAlias, dataTypeName, esId);
571
572         IndexResponse response = null;
573         try {
574             response = request.setSource(json).execute().actionGet();
575         } catch (ElasticsearchException e) {
576             log.warn("ES Exception {} Json: {}", e.getMessage(), new String(json));
577         }
578
579         if (response == null) {
580             String jsonString = new String(json);
581             log.warn("Response null during write: {} {}", esId, jsonString);
582             return null;
583         } else {
584             return response.getId();
585         }
586     }
587
588     /**
589      * Write JSON Data. First level contains datatype, next level id Example "datatype" : { "id" : { } }
590      * @param json Object
591      */
592     public void doWriteJSONObject(JSONObject json) {
593
594         Set<String> docTypes = getStringKeySet(json);
595         log.debug("Found number of keys: {} keys: {}", json.length(), docTypes.size());
596         for (String docType : docTypes) {
597             JSONObject objects = json.optJSONObject(docType);
598             if (objects == null) {
599                 log.debug("Skip json {} with class {}", docType, json.get(docType).getClass());
600             } else {
601                 doWriteJsonObjectsWithIds(docType, objects);
602             }
603         }
604     }
605
606     /**
607      * Write object and Id of object for a doctype
608      * @param docType of the objects
609      * @param objects a bunch of objects with ids as object name
610      */
611     private void doWriteJsonObjectsWithIds(String docType, JSONObject objects) {
612         Set<String> ids = getStringKeySet(objects);
613         log.debug("write doctype {} with elements {}", docType, ids.size());
614         for (String id : ids) {
615             JSONObject jsonIdObject = objects.optJSONObject(id);
616             if (jsonIdObject == null) {
617                 log.debug("Skip jsonsub {} with class {}", id, objects.get(id).getClass());
618             } else {
619                 if (log.isTraceEnabled()) {
620                     log.trace("Jsonsub object of id {} '{}'", id, jsonIdObject);
621                 }
622                 this.doWriteRaw(docType, id, jsonIdObject.toString().getBytes());
623             }
624         }
625     }
626
627     /**
628      * Remove Object from database
629      */
630     @Override
631     public boolean doRemove(String dataTypeName, IsEsObject esId) {
632
633         if (esIndexAlias == null) {
634             throw new IllegalArgumentException("Missing Index");
635         }
636
637         DeleteResponse response =
638                 client.prepareDelete(esIndexAlias, dataTypeName, esId.getEsId()).execute().actionGet();
639
640         return response.isFound();
641     }
642
643     /**
644      * Read Json Object from database
645      */
646     @Override
647     public @Nullable BytesReference doReadJsonData(String dataTypeName, IsEsObject esId) {
648
649         if (esId.getEsId() == null) {
650             throw new IllegalArgumentException("Read access to object without database Id");
651         }
652
653         return doReadJsonData(dataTypeName, esId.getEsId());
654     }
655
656     /**
657      * Read Json Object from database
658      */
659     @Override
660     public @Nullable BytesReference doReadJsonData(String dataTypeName, String esId) {
661
662         log.debug("NetworkIndex read: {}", esIndexAlias);
663
664         GetResponse response = client.prepareGet(esIndexAlias, dataTypeName, esId)
665                 // .setOperationThreaded(false)
666                 .execute().actionGet();
667
668         return response.isExists() ? response.getSourceAsBytesRef() : null;
669     }
670
671
672     @Override
673     public SearchHit[] doReadByQueryJsonData(int start, int length, String dataTypeName, QueryBuilder qb) {
674
675         log.debug("NetworkIndex query and read: {}", esIndexAlias);
676
677         SearchResponse response1 = client.prepareSearch(esIndexAlias).setTypes(dataTypeName).setQuery(qb).setFrom(start)
678                 .setSize(length).execute().actionGet();
679
680         return response1.getHits().hits();
681     }
682
683
684     @Override
685     public SearchHit[] doReadAllJsonData(int start, int length, String dataTypeName) {
686         // Use query
687         QueryBuilder qb = QueryBuilders.matchAllQuery();
688         return doReadByQueryJsonData(start, length, dataTypeName, qb);
689     }
690
691     /**
692      * Write Json datetype that is specified by file to ES
693      *
694      * @param dataType ES Datatype name
695      * @param fileName file name
696      */
697     public void writeJsonObjectsFromFile(String dataType, String fileName) {
698
699         log.debug("Start: Index: '{}' ' datatype: '{}'  File: '{}'", esIndexAlias, dataType, fileName);
700
701         String content = null;
702
703         try {
704             content = new String(Files.readAllBytes(Paths.get(fileName)), StandardCharsets.UTF_8);
705         } catch (IOException e1) {
706             log.warn("Can not read file: {}", e1.getMessage());
707         }
708
709         if (content != null && content.charAt(0) == 0xfeff) {
710             content = content.substring(1);
711             log.debug("Delete first char {} {}", dataType, fileName);
712         }
713
714         if (content != null) {
715             IndexResponse response = null;
716             try {
717                 response = client.prepareIndex(esIndexAlias, dataType).setSource(content).execute().actionGet();
718             } catch (ElasticsearchException e) {
719                 log.error("ElasticsearchException during write:  for {} from {} from {}", e.getMessage(), dataType, fileName);
720             } catch (Exception e) {
721                 log.error("Exception during write:  for {} from {} from {}", e.getMessage(), dataType, fileName);
722             }
723
724             if (response != null) {
725                 if (!response.isCreated()) {
726                     String responseAsString = response.toString();
727                     log.warn("Jackson Response not created: {} {} {}", dataType, fileName, responseAsString);
728                 } else {
729                     log.debug("Created: {}", response.getId());
730                 }
731             } else {
732                 log.warn("Jackson Response null after write {} {}", dataType, fileName);
733             }
734         }
735
736     }
737
738     @Override
739     public void closeDb() {
740         if (client != null) {
741             client.close();
742         }
743     }
744
745
746     // For any reason the function json.keySet() was not working in Oxygen => replaced by iterator
747     public static @Nonnull Set<String> getStringKeySet(JSONObject json) {
748         Set<String> keys = new HashSet<>();
749         Iterator<?> iterator = json.keys();
750         while (iterator.hasNext()) {
751             keys.add((String) iterator.next());
752         }
753         return keys;
754     }
755
756
757     private static class HtDatabaseClientException extends RuntimeException {
758
759         private static final long serialVersionUID = 1L;
760
761         public HtDatabaseClientException(String string, String esIndexAlias) {
762             super(string + " Effected index: " + "esIndexAlias");
763         }
764     }
765
766 }