Merge "fix connection state machine"
[ccsdk/features.git] / sdnr / wt / data-provider / provider / src / main / java / org / onap / ccsdk / features / sdnr / wt / dataprovider / data / HtDatabaseEventsService.java
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : ccsdk features
4  * ================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property.
6  * All rights reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  *
21  */
22 package org.onap.ccsdk.features.sdnr.wt.dataprovider.data;
23
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Date;
27 import java.util.List;
28
29 import javax.annotation.Nonnull;
30 import org.eclipse.jdt.annotation.NonNull;
31 import org.eclipse.jdt.annotation.Nullable;
32 import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient;
33 import org.onap.ccsdk.features.sdnr.wt.common.database.queries.BoolQueryBuilder;
34 import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilder;
35 import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilders;
36 import org.onap.ccsdk.features.sdnr.wt.common.database.queries.RangeQueryBuilder;
37 import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.EsDataObjectReaderWriter2;
38 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.ArchiveCleanProvider;
39 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider;
40 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.NetconfTimeStamp;
41 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ConnectionLogStatus;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ConnectionlogBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ConnectionlogEntity;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Entity;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EventlogBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EventlogEntity;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.FaultcurrentBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.FaultcurrentEntity;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.FaultlogBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.FaultlogEntity;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.GranularityPeriodType;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Inventory;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.InventoryBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.InventoryEntity;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.NetworkElementConnectionBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.NetworkElementConnectionEntity;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.PmdataEntity;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.PmdataEntityBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.UpdateNetworkElementConnectionInputBuilder;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
64
65 /**
66  * Event service, writing all events into the database into the appropriate
67  * index.
68  *
69  * @author herbert
70  */
71 public class HtDatabaseEventsService implements ArchiveCleanProvider, DataProvider {
72     private static final Logger LOG = LoggerFactory.getLogger(HtDatabaseEventsService.class);
73
74     private static final NetconfTimeStamp NETCONFTIME_CONVERTER = NetconfTimeStampImpl.getConverter();
75
76     private HtDatabaseClient client;
77     private EsDataObjectReaderWriter2<EventlogEntity> eventRWEventLogDevicemanager;
78     private EsDataObjectReaderWriter2<InventoryEntity> eventRWEquipment;
79     private EsDataObjectReaderWriter2<FaultcurrentEntity> eventRWFaultCurrentDB;
80     private EsDataObjectReaderWriter2<FaultlogEntity> eventRWFaultLogDB;
81     private EsDataObjectReaderWriter2<ConnectionlogEntity> eventRWConnectionLogDB;
82     private final EsDataObjectReaderWriter2<NetworkElementConnectionEntity> networkelementConnectionDB;
83     private final EsDataObjectReaderWriter2<PmdataEntity> pmData15mDB;
84     private final EsDataObjectReaderWriter2<PmdataEntity> pmData24hDB;
85
86     @SuppressWarnings("unused")
87     private final ElasticSearchDataProvider dataProvider;
88     // --- Construct and initialize
89
90
91     public HtDatabaseEventsService(HtDatabaseClient client, ElasticSearchDataProvider elasticSearchDataProvider) throws Exception {
92
93         LOG.info("Create {} start", HtDatabaseEventsService.class);
94         this.dataProvider = elasticSearchDataProvider;
95
96         try {
97             // Create control structure
98             this.client = client;
99
100             eventRWEventLogDevicemanager = new EsDataObjectReaderWriter2<>(client, Entity.Eventlog,
101                     EventlogEntity.class, EventlogBuilder.class);
102
103             eventRWEquipment = new EsDataObjectReaderWriter2<>(client, Entity.Inventoryequipment,
104                     InventoryEntity.class, InventoryBuilder.class);
105
106             eventRWFaultCurrentDB = new EsDataObjectReaderWriter2<>(client, Entity.Faultcurrent,
107                     FaultcurrentEntity.class, FaultcurrentBuilder.class);
108
109             eventRWFaultLogDB = new EsDataObjectReaderWriter2<>(client, Entity.Faultlog,
110                     FaultlogEntity.class, FaultlogBuilder.class);
111
112             eventRWConnectionLogDB = new EsDataObjectReaderWriter2<>(client, Entity.Connectionlog,
113                     ConnectionlogEntity.class, ConnectionlogBuilder.class);
114
115             networkelementConnectionDB = new EsDataObjectReaderWriter2<>(client, Entity.NetworkelementConnection,
116                     NetworkElementConnectionEntity.class, NetworkElementConnectionBuilder.class)
117                     .setEsIdAttributeName("_id");
118
119             pmData15mDB = new EsDataObjectReaderWriter2<>(client, Entity.Historicalperformance15min,
120                     PmdataEntity.class, PmdataEntityBuilder.class);
121
122             pmData24hDB = new EsDataObjectReaderWriter2<>(client, Entity.Historicalperformance24h,
123                     PmdataEntity.class, PmdataEntityBuilder.class);
124
125         } catch (Exception e) {
126             LOG.error("Can not start database client. Exception: {}", e);
127             throw new Exception("Can not start database client. Exception: {}", e);
128         }
129         LOG.info("Create {} finished. DB Service {} started.", HtDatabaseEventsService.class,
130                 client != null ? "sucessfully" : "not");
131     }
132
133     // --- Function
134
135     // -- Connection log
136     @Override
137     public void writeConnectionLog(ConnectionlogEntity event) {
138         if (assertIfClientNull(event)) {
139             return;
140         }
141         LOG.debug("Write event: {}", event);
142         eventRWConnectionLogDB.write(event, null);
143
144     }
145     // -- Event log
146     @Override
147     public void writeEventLog(EventlogEntity event) {
148         if (assertIfClientNull("No client to write {}", event)) {
149             return;
150         }
151
152         LOG.debug("Write event: {}", event.toString());
153         eventRWEventLogDevicemanager.write(event, null);
154     }
155
156
157     // -- Fault log
158
159     @Override
160     public void writeFaultLog(FaultlogEntity fault) {
161         if (assertIfClientNull(fault)) {
162             return;
163         }
164
165         LOG.debug("Write fault to faultlog: {}", fault.toString());
166         eventRWFaultLogDB.write(fault,null);
167     }
168
169     // -- Fault current
170
171     @Override
172     public void updateFaultCurrent(FaultcurrentEntity fault) {
173         if (assertIfClientNull(fault)) {
174             return;
175         }
176
177         if (FaultEntityManager.isManagedAsCurrentProblem(fault)) {
178             if (FaultEntityManager.isNoAlarmIndication(fault)) {
179                 LOG.debug("Remove from currentFaults: {}", fault.toString());
180                 eventRWFaultCurrentDB.remove(FaultEntityManager.genSpecificEsId(fault));
181             } else {
182                 LOG.debug("Write to currentFaults: {}", fault.toString());
183                 eventRWFaultCurrentDB.write(fault, FaultEntityManager.genSpecificEsId(fault));
184             }
185         } else {
186             LOG.debug("Ingnore for currentFaults: {}", fault.toString());
187         }
188     }
189
190     /**
191      * Remove all entries for one node
192      *
193      * @param nodeName contains the mountpointname
194      * @return number of deleted entries
195      */
196     @Override
197     public int clearFaultsCurrentOfNode(String nodeName) {
198         if (assertIfClientNullForNodeName(nodeName)) {
199             return -1;
200         }
201
202         LOG.debug("Remove from currentFaults all faults for node: {}", nodeName);
203         return eventRWFaultCurrentDB.remove(EsFaultCurrent.getQueryForOneNode(nodeName));
204     }
205
206     /**
207      * Remove all entries for one node
208      *
209      * @param nodeName contains the mountpointname
210      * @param objectId of element to be deleted
211      * @return number of deleted entries
212      */
213     @Override
214     public int clearFaultsCurrentOfNodeWithObjectId(String nodeName, String objectId) {
215         if (assertIfClientNullForNodeName(nodeName)) {
216             return -1;
217         }
218
219         LOG.debug("Remove from currentFaults all faults for node/objectId: {}/{}", nodeName, objectId);
220         return eventRWFaultCurrentDB.remove(EsFaultCurrent.getQueryForOneNodeAndObjectId(nodeName, objectId));
221     }
222
223     /**
224      * Deliver list with all mountpoint/node-names in the database.
225      *
226      * @return List of all mountpoint/node-names the had active alarms.
227      */
228     @Override
229     public @Nonnull List<String> getAllNodesWithCurrentAlarms() {
230         if (assertIfClientNull("No DB, can not delete for all nodes", null)) {
231             return new ArrayList<>();
232         }
233
234         LOG.debug("Remove from currentFaults faults for all node");
235         List<String> nodeNames = new ArrayList<>();
236
237         for (FaultcurrentEntity fault : eventRWFaultCurrentDB.doReadAll().getHits()) {
238             String nodeName = fault.getNodeId();
239             if (!nodeNames.contains(nodeName)) {
240                 // this.clearFaultsCurrentOfNode(nodeName); -> Function shifted
241                 nodeNames.add(nodeName);
242             }
243         }
244         return nodeNames;
245     }
246
247     // -- Inventory and equipment current
248
249     /**
250      * write internal equipment to database
251      * @param internalEquipment with mandatory fields.
252      */
253     @Override
254     public void writeInventory(Inventory internalEquipment) {
255
256         if (assertIfClientNullForNodeName(internalEquipment.getNodeId())) {
257             return;
258         }
259         if(internalEquipment.getManufacturerIdentifier()==null) {
260                 internalEquipment = new InventoryBuilder(internalEquipment).setManufacturerIdentifier("").build();
261         }
262         if(internalEquipment.getDate()==null) {
263                 internalEquipment = new InventoryBuilder(internalEquipment).setDate("").build();
264         }
265         
266         eventRWEquipment.write(internalEquipment, internalEquipment.getNodeId()+"/"+internalEquipment.getUuid());
267     }
268
269
270     // -- Networkelement
271
272     /**
273      *
274      * @param networkElementConnectionEntitiy to wirte to DB
275      * @param nodeId Id for this DB element
276      */
277     @Override
278     public void updateNetworkConnectionDeviceType(NetworkElementConnectionEntity networkElementConnectionEntitiy, String nodeId) {
279         this.networkelementConnectionDB.update(networkElementConnectionEntitiy, nodeId);
280     }
281
282     /**
283      * Update after new mountpoint registration
284      * @param networkElementConnectionEntitiy data
285      * @param nodeId of device (mountpoint name)
286      */
287     @Override
288     public void updateNetworkConnection22(NetworkElementConnectionEntity networkElementConnectionEntitiy, String nodeId) {
289         this.networkelementConnectionDB.updateOrCreate(networkElementConnectionEntitiy, nodeId, Arrays.asList("is-required", "username", "password"));
290     }
291
292     /* please do not remove */
293     //    public void cleanNetworkElementConnections() {
294     //        this.networkelementConnectionDB.remove(QueryBuilders.matchQuery("is-required", false));
295     //        CreateNetworkElementConnectionInput x = new CreateNetworkElementConnectionInputBuilder().setStatus(ConnectionLogStatus.Disconnected).build();
296     //        this.networkelementConnectionDB.update(x,QueryBuilders.matchAllQuery());
297     //    }
298
299     @Override
300     public void removeNetworkConnection(String nodeId) {
301         Boolean isRequired;
302         NetworkElementConnectionEntity e = this.networkelementConnectionDB.read(nodeId);
303         if (e != null && (isRequired = e.isIsRequired()) != null) {
304             if (isRequired) {
305                 LOG.debug("updating connection status for {} of required ne to disconnected",nodeId);
306                 this.networkelementConnectionDB.update(new UpdateNetworkElementConnectionInputBuilder().setStatus(ConnectionLogStatus.Disconnected).build(), nodeId);
307             } else {
308                 LOG.debug("remove networkelement-connection for {} entry because of non-required",nodeId);
309                 this.networkelementConnectionDB.remove(nodeId);
310             }
311         }
312         else {
313             LOG.warn("Unable to update connection-status. dbentry for {} not found in networkelement-connection",nodeId);
314         }
315     }
316
317     // -- Multiple areas
318
319     @Override
320     public int doIndexClean(Date olderAreOutdated) {
321
322         String netconfTimeStamp = NETCONFTIME_CONVERTER.getTimeStampAsNetconfString(olderAreOutdated);
323         int removed = 0;
324
325         QueryBuilder queryEventBase = EsEventBase.getQueryForTimeStamp(netconfTimeStamp);
326         removed += eventRWEventLogDevicemanager.remove(queryEventBase);
327
328         QueryBuilder queryFaultLog = EsFaultLogDevicemanager.getQueryForTimeStamp(netconfTimeStamp);
329         removed += eventRWFaultLogDB.remove(queryFaultLog);
330         return removed;
331     }
332
333     @Override
334     public int getNumberOfOldObjects(Date olderAreOutdated) {
335
336         String netconfTimeStamp = NETCONFTIME_CONVERTER.getTimeStampAsNetconfString(olderAreOutdated);
337         int numberOfElements = 0;
338
339         QueryBuilder queryEventBase = EsEventBase.getQueryForTimeStamp(netconfTimeStamp);
340         numberOfElements += eventRWEventLogDevicemanager.doReadAll(queryEventBase).getTotal();
341
342         QueryBuilder queryFaultLog = EsFaultLogDevicemanager.getQueryForTimeStamp(netconfTimeStamp);
343         numberOfElements += eventRWFaultLogDB.doReadAll(queryFaultLog).getTotal();
344
345         return numberOfElements;
346     }
347
348     // -- Helper
349
350     /**
351      * Verify status of client
352      * @param event that is printed with message
353      * @return true if client is null
354      */
355     private boolean assertIfClientNull(Object event) {
356         return assertIfClientNull("No DB, can not write: {}", event);
357     }
358
359     private boolean assertIfClientNullForNodeName(Object object) {
360         return assertIfClientNull("No DB, can not handle node: {}", object);
361     }
362     /**
363      * Verify status of client
364      * @param message to print including {} for object printout.
365      * @return true if client is null
366      */
367     private boolean assertIfClientNull(String message, Object object) {
368         if (client == null) {
369             LOG.debug(message, object);
370             return true;
371         }
372         return false;
373     }
374
375     // ### sub classes
376
377
378     private static class EsEventBase {
379         /**
380          * Query to get older Elements
381          * @param netconfTimeStamp to identify older Elements
382          * @return QueryBuilder for older elements related to timestamp
383          */
384         private static QueryBuilder getQueryForTimeStamp(String netconfTimeStamp) {
385             return new RangeQueryBuilder("timestamp").lte(netconfTimeStamp);
386         }
387     }
388     private static class EsFaultLogDevicemanager {
389         /**
390          * Get older Elements
391          * @param netconfTimeStamp to identify query elements older than this timestamp.
392          * @return QueryBuilder for related elements
393          */
394         public static QueryBuilder getQueryForTimeStamp(String netconfTimeStamp) {
395             return new RangeQueryBuilder("timestamp").lte(netconfTimeStamp);
396         }
397      }
398     public static class EsFaultCurrent  {
399         /**
400          * @param nodeName name of the node
401          * @return query builder
402          */
403         public static QueryBuilder getQueryForOneNode( String nodeName) {
404             return QueryBuilders.matchQuery("node-id", nodeName);
405         }
406
407         public static QueryBuilder getQueryForOneNodeAndObjectId( String nodeName, String objectId) {
408             BoolQueryBuilder bq = QueryBuilders.boolQuery();
409             bq.must(QueryBuilders.matchQuery("node-id", nodeName));
410             bq.must(QueryBuilders.matchQuery("object-id", objectId));
411             return bq;
412         }
413     }
414     @Override
415     public List<NetworkElementConnectionEntity> getNetworkElementConnections() {
416         return this.networkelementConnectionDB.doReadAll().getHits();
417     }
418
419     @Override
420     public void doWritePerformanceData(List<PmdataEntity> list) {
421
422         list.forEach(elem -> {
423             GranularityPeriodType granularityPeriod = nnGetGranularityPeriodType(elem.getGranularityPeriod());
424             //_id": "Sim12600/LP-MWPS-TTP-01/2017-07-04T15:15:00.0+00:00"
425             StringBuffer id = new StringBuffer();
426             DateAndTime date = elem.getTimeStamp();
427             id.append(elem.getNodeName());
428             id.append("/");
429             id.append(elem.getUuidInterface());
430             id.append("/");
431             id.append(date != null ? date.getValue() : "null");
432
433             switch (granularityPeriod) {
434             case Period15Min:
435                 pmData15mDB.write(elem, id.toString());
436                 break;
437             case Period24Hours:
438                 pmData24hDB.write(elem, id.toString());
439                 break;
440             case Unknown:
441             default:
442                 LOG.debug("Unknown granularity {} id {}", granularityPeriod, id);
443                 break;
444             }
445         } );
446
447     }
448
449     @NonNull GranularityPeriodType nnGetGranularityPeriodType(@Nullable GranularityPeriodType granularityPeriod) {
450         return granularityPeriod != null ? granularityPeriod : GranularityPeriodType.Unknown;
451     }
452
453         @Override
454         public HtDatabaseClient getRawClient() {
455                 return this.client;
456         }
457
458 }