add new devicemanager
[ccsdk/features.git] / sdnr / wt / devicemanager / provider / src / main / java / org / onap / ccsdk / features / sdnr / wt / devicemanager / base / onfcore / ONFCoreNetworkElement12Microwave.java
diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/base/onfcore/ONFCoreNetworkElement12Microwave.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/base/onfcore/ONFCoreNetworkElement12Microwave.java
new file mode 100644 (file)
index 0000000..89f803a
--- /dev/null
@@ -0,0 +1,516 @@
+/*******************************************************************************
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ ******************************************************************************/
+package org.onap.ccsdk.features.sdnr.wt.devicemanager.base.onfcore;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider;
+import org.onap.ccsdk.features.sdnr.wt.devicemanager.base.onfcore.container.AllPm;
+import org.onap.ccsdk.features.sdnr.wt.devicemanager.base.onfcore.container.ONFLayerProtocolName;
+import org.onap.ccsdk.features.sdnr.wt.devicemanager.base.onfcore.wrapperc.OnfMicrowaveModel;
+import org.onap.ccsdk.features.sdnr.wt.devicemanager.dcaeconnector.impl.DcaeForwarderInternal;
+import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.handler.NetconfEventListenerHandler12;
+import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.util.InternalDateAndTime;
+import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.util.InternalSeverity;
+import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.AttributeValueChangedNotificationXml;
+import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.ProblemNotificationXml;
+import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.WebSocketServiceClientInternal;
+import org.onap.ccsdk.features.sdnr.wt.devicemanager.performancemanager.impl.database.types.EsHistoricalPerformance15Minutes;
+import org.onap.ccsdk.features.sdnr.wt.devicemanager.performancemanager.impl.database.types.EsHistoricalPerformance24Hours;
+import org.onap.ccsdk.features.sdnr.wt.devicemanager.toggleAlarmFilter.NotificationDelayService;
+import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities;
+import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.INetconfAcessor;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.MountPoint;
+import org.opendaylight.mdsal.binding.api.NotificationService;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.core.model.rev170320.UniversalId;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.core.model.rev170320.extension.g.Extension;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.core.model.rev170320.logical.termination.point.g.Lp;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.g._874._1.model.rev170320.GranularityPeriodType;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.g._874._1.model.rev170320.OtnHistoryDataG;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.onf.core.model.conditional.packages.rev170402.NetworkElementPac;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.onf.core.model.conditional.packages.rev170402.network.element.pac.NetworkElementCurrentProblems;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.NetworkElementDeviceType;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Get information over NETCONF device according to ONF Coremodel. Read networkelement and
+ * conditional packages.
+ *
+ * Get conditional packages from Networkelement Possible interfaces are: MWPS, LTP(MWPS-TTP),
+ * MWAirInterfacePac, MicrowaveModel-ObjectClasses-AirInterface ETH-CTP,LTP(Client),
+ * MW_EthernetContainer_Pac MWS, LTP(MWS-CTP-xD), MWAirInterfaceDiversityPac,
+ * MicrowaveModel-ObjectClasses-AirInterfaceDiversity MWS, LTP(MWS-TTP),
+ * ,MicrowaveModel-ObjectClasses-HybridMwStructure MWS, LTP(MWS-TTP),
+ * ,MicrowaveModel-ObjectClasses-PureEthernetStructure
+ *
+ * @author herbert
+ *
+ */
+public class ONFCoreNetworkElement12Microwave extends ONFCoreNetworkElement12Base
+        implements ONFCoreNetworkElementCallback, NotificationActor<AttributeValueChangedNotificationXml> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ONFCoreNetworkElement12Microwave.class);
+
+    /*-----------------------------------------------------------------------------
+     * Class members
+     */
+    private final @NonNull NetconfEventListenerHandler12 microwaveEventListener;
+    private final @NonNull OnfMicrowaveModel microwaveModel;
+    private final NotificationWorker<AttributeValueChangedNotificationXml> notificationQueue;
+
+    private ListenerRegistration<NotificationListener> listenerRegistrationresult = null;
+
+    /*-----------------------------------------------------------------------------
+     * Construction
+     */
+
+    /**
+     * Constructor
+     *
+     * @param mountPointNodeName as String
+     * @param capabilities of the specific network element
+     * @param netconfNodeDataBroker for the network element specific data
+     * @param webSocketService to forward event notifications
+     * @param databaseService to access the database
+     * @param dcaeProvider to forward problem / change notifications
+     */
+    ONFCoreNetworkElement12Microwave(INetconfAcessor acessor, String mountPointNodeName, Capabilities capabilities,
+            DataBroker netconfNodeDataBroker, WebSocketServiceClientInternal webSocketService,
+            DataProvider databaseService, DcaeForwarderInternal aotsDcaeForwarder,
+            NotificationDelayService<ProblemNotificationXml> notificationDelayService,
+            OnfMicrowaveModel onfMicrowaveModel) {
+
+        super(acessor, mountPointNodeName, netconfNodeDataBroker, capabilities);
+
+        this.microwaveModel = onfMicrowaveModel;
+        this.microwaveModel.setCoreData(this);
+
+        // Create MicrowaveService here
+        this.microwaveEventListener = new NetconfEventListenerHandler12(mountPointNodeName, webSocketService,
+                databaseService, aotsDcaeForwarder, notificationDelayService, this);
+        this.microwaveModel.setOnfMicrowaveModelListener(microwaveEventListener);
+
+        this.notificationQueue = new NotificationWorker<>(1, 100, this);
+
+        // ->Below shifted to super class
+        // this.isNetworkElementCurrentProblemsSupporting12 =
+        // capabilities.isSupportingNamespaceAndRevision(NetworkElementPac.QNAME);
+        // LOG.debug("support necurrent-problem-list=" + this.isNetworkElementCurrentProblemsSupporting12);
+        // LOG.info("Create NE instance {}", InstanceList.QNAME.getLocalName());
+
+    }
+
+    /*-----------------------------------------------------------------------------
+     * Functions
+     */
+
+    /**
+     * DeviceMonitor Prepare check by updating NE state and reading all interfaces.
+     */
+    @Override
+    public void prepareCheck() {
+        synchronized (dmLock) {
+            boolean change = readNetworkElementAndInterfaces();
+            if (change) {
+                int problems = microwaveEventListener.removeAllCurrentProblemsOfNode();
+                List<ProblemNotificationXml> resultList = readAllCurrentProblemsOfNode();
+                microwaveEventListener.initCurrentProblemStatus(resultList);
+                LOG.info("Resync mountpoint {} for device {}. Removed {}. Current problems: {}", getMountPointNodeName(),
+                        getUuId(), problems, resultList.size());
+            }
+        }
+    }
+
+    // public boolean checkIfConnectionToMediatorIsOk() -> Shifted to super class
+    // public boolean checkIfConnectionToNeIsOk() -> Shifted to super class
+
+    /*-----------------------------------------------------------------------------
+     * Synchronization
+     */
+
+    // public void initSynchronizationExtension() -> Shifted to super class
+    // private InstanceList readPTPClockInstances() -> Shifted to super class
+
+    /*-----------------------------------------------------------------------------
+     * Services for NE/Device synchronization
+     */
+
+    /**
+     * Handling of specific Notifications from NE, indicating changes and need for synchronization.
+     *
+     * <attribute-value-changed-notification xmlns="urn:onf:params:xml:ns:yang:microwave-model">
+     * <attribute-name>/equipment-pac/equipment-current-problems</attribute-name>
+     * <object-id-ref>CARD-1.1.1.0</object-id-ref> <new-value></new-value>
+     * </attribute-value-changed-notification>
+     * <attribute-value-changed-notification xmlns="urn:onf:params:xml:ns:yang:microwave-model">
+     * <attribute-name>/network-element/extension[value-name="top-level-equipment"]/value</attribute-name>
+     * <object-id-ref>Hybrid-Z</object-id-ref>
+     * <new-value>SHELF-1.1.0.0,IDU-1.55.0.0,ODU-1.56.0.0,IDU-1.65.0.0</new-value>
+     * </attribute-value-changed-notification>
+     */
+
+
+    @Override
+    public void notificationFromNeListener(AttributeValueChangedNotificationXml notificationXml) {
+        notificationQueue.put(notificationXml);
+    }
+
+    @Override
+    public void notificationActor(AttributeValueChangedNotificationXml notificationXml) {
+
+        LOG.debug("Enter change notification listener");
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Notification: {}", notificationXml);
+        }
+        if (notificationXml.getAttributeName().equals("/equipment-pac/equipment-current-problems")) {
+            syncEquipmentPac(notificationXml.getObjectId());
+        } else if (notificationXml.getAttributeName()
+                .equals("/network-element/extension[value-name=\"top-level-equipment\"]/value")) {
+            initialReadFromNetworkElement();
+        }
+        LOG.debug("Leave change notification listener");
+    }
+
+    /**
+     * Synchronize problems for a specific equipment-pac
+     *
+     * @param uuidString of the equipment-pac
+     */
+    private synchronized void syncEquipmentPac(String uuidString) {
+
+        int problems = microwaveEventListener.removeObjectsCurrentProblemsOfNode(uuidString);
+        LOG.debug("Removed {} problems for uuid {}", problems, uuidString);
+
+        List<ProblemNotificationXml> resultList = equipment.addProblemsofNodeObject(uuidString);
+        microwaveEventListener.initCurrentProblemStatus(resultList);
+        LOG.debug("Added {} problems for uuid {}", resultList.size(), uuidString);
+
+    }
+
+
+    /*-----------------------------------------------------------------------------
+     * Problem/Fault related functions
+     */
+
+    /**
+     * Read during startup all relevant structure and status parameters from device
+     */
+    @Override
+    public synchronized void initialReadFromNetworkElement() {
+        // optionalNe.getLtp().get(0).getLp();
+        LOG.debug("Get info about {}", getMountPointNodeName());
+
+        int problems = microwaveEventListener.removeAllCurrentProblemsOfNode();
+        LOG.debug("Removed all {} problems from database at registration", problems);
+
+        // Step 2.1: access data broker within this mount point
+        LOG.debug("DBRead start");
+
+        // Step 2.2: read ne from data store
+        readNetworkElementAndInterfaces();
+        equipment.readNetworkElementEquipment();
+
+        // Step 2.3: read the existing faults and add to DB
+        List<ProblemNotificationXml> resultList = readAllCurrentProblemsOfNode();
+        equipment.addProblemsofNode(resultList);
+
+        microwaveEventListener.initCurrentProblemStatus(resultList);
+
+        microwaveEventListener.writeEquipment(equipment);
+
+        LOG.info("Found info at {} for device {} number of problems: {}", getMountPointNodeName(), getUuId(),
+                resultList.size());
+    }
+
+    /**
+     * LOG the newly added problems of the interface pac
+     *
+     * @param idxStart
+     * @param uuid
+     * @param resultList
+     */
+    private void debugResultList(String uuid, List<ProblemNotificationXml> resultList, int idxStart) {
+        if (LOG.isDebugEnabled()) {
+            StringBuffer sb = new StringBuffer();
+            int idx = 0;
+            for (int t = idxStart; t < resultList.size(); t++) {
+                sb.append(idx++);
+                sb.append(":{");
+                sb.append(resultList.get(t));
+                sb.append('}');
+            }
+            LOG.debug("Found problems {} {}", uuid, sb.toString());
+        }
+    }
+
+    /**
+     * Read current problems of AirInterfaces and EthernetContainer according to NE status into DB
+     *
+     * @return List with all problems
+     */
+    @Override
+    protected List<ProblemNotificationXml> readAllCurrentProblemsOfNode() {
+
+        // Step 2.3: read the existing faults and add to DB
+        List<ProblemNotificationXml> resultList = new ArrayList<>();
+        int idxStart; // Start index for debug messages
+        UniversalId uuid;
+
+        synchronized (getPmLock()) {
+            for (Lp lp : getInterfaceList()) {
+
+                idxStart = resultList.size();
+                uuid = lp.getUuid();
+                Class<?> lpClass = getLpExtension(lp);
+
+                ONFLayerProtocolName lpName = ONFLayerProtocolName.valueOf(lp.getLayerProtocolName());
+
+                microwaveModel.readTheFaultsOfMicrowaveModel(lpName, lpClass, uuid, resultList);
+
+                debugResultList(uuid.getValue(), resultList, idxStart);
+
+            }
+        }
+
+        // Step 2.4: Read other problems from mountpoint
+        if (isNetworkElementCurrentProblemsSupporting12) {
+            idxStart = resultList.size();
+            readNetworkElementCurrentProblems12(resultList);
+            debugResultList("CurrentProblems12", resultList, idxStart);
+        }
+
+        return resultList;
+
+    }
+
+    /**
+     * Get from LayerProtocolExtensions the related generated ONF Interface PAC class which represents it.
+     *
+     * @param lp logical termination point
+     * @return Class of InterfacePac
+     */
+    @Nullable
+    private Class<?> getLpExtension(@Nullable Lp lp) {
+
+        String capability = EMPTY;
+        String revision = EMPTY;
+        String conditionalPackage = EMPTY;
+        Class<?> res = null;
+
+        if (lp != null) {
+            for (Extension e : getExtensionList(lp)) {
+                if (e.getValueName().contentEquals("capability")) {
+                    capability = e.getValue();
+                    int idx = capability.indexOf("?");
+                    if (idx != -1) {
+                        capability = capability.substring(0, idx);
+                    }
+                }
+                if (e.getValueName().contentEquals("revision")) {
+                    revision = e.getValue();
+                }
+                if (e.getValueName().contentEquals("conditional-package")) {
+                    conditionalPackage = e.getValue();
+                }
+            }
+        }
+        // QName qName =
+        // org.opendaylight.yangtools.yang.common.QName.create("urn:onf:params:xml:ns:yang:microwave-model",
+        // "2017-03-24", "mw-air-interface-pac").intern();
+        LOG.info("LpExtension capability={} revision={} conditionalPackage={}", capability, revision,
+                conditionalPackage);
+        if (!capability.isEmpty() && !revision.isEmpty() && !conditionalPackage.isEmpty()) {
+            try {
+                QName qName = QName.create(capability, revision, conditionalPackage);
+                res = this.microwaveModel.getClassForLtpExtension(qName);
+            } catch (IllegalArgumentException e) {
+                LOG.debug("Can not create QName from ({}{}{}): {}", capability, revision, conditionalPackage,
+                        e.getMessage());
+            }
+        }
+        return res;
+    }
+
+    /**
+     * Read element from class that could be not available
+     *
+     * @param ltp layer termination point
+     * @return List with extension parameters or empty list
+     */
+    @NonNull
+    private static List<Extension> getExtensionList(@Nullable Lp ltp) {
+        if (ltp != null && ltp.getExtension() != null) {
+            return ltp.getExtension();
+        } else {
+            return EMPTYLTPEXTENSIONLIST;
+        }
+    }
+
+    @NonNull
+    private List<? extends OtnHistoryDataG> readTheHistoricalPerformanceData(Lp lp) {
+        ONFLayerProtocolName lpName = ONFLayerProtocolName.valueOf(lp.getLayerProtocolName());
+
+        return this.microwaveModel.readTheHistoricalPerformanceData(lpName, lp);
+    }
+
+    @Override
+    public AllPm getHistoricalPM() {
+
+        synchronized (getPmLock()) {
+            if (pmLp != null) {
+                LOG.debug("Enter query PM");
+                AllPm allPm = new AllPm();
+                Lp lp = pmLp;
+
+                List<? extends OtnHistoryDataG> resultList = readTheHistoricalPerformanceData(lp);
+                LOG.debug("Got records: {}", resultList.size());
+                // org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.g._874._1.model.rev170320.GranularityPeriodType
+                GranularityPeriodType granularityPeriod;
+                for (OtnHistoryDataG perf : resultList) {
+
+                    granularityPeriod = perf.getGranularityPeriod();
+                    if (granularityPeriod == null) {
+                        granularityPeriod = GranularityPeriodType.Unknown;
+                    }
+
+                    switch (granularityPeriod) {
+                        case Period15Min: {
+                            EsHistoricalPerformance15Minutes pm =
+                                    new EsHistoricalPerformance15Minutes(getMountPointNodeName(), lp)
+                                            .setHistoricalRecord15Minutes(perf);
+                            allPm.add(pm);
+                        }
+                            break;
+
+                        case Period24Hours: {
+                            EsHistoricalPerformance24Hours pm =
+                                    new EsHistoricalPerformance24Hours(getMountPointNodeName(), lp)
+                                            .setHistoricalRecord24Hours(perf);
+                            LOG.debug("Write 24h write to DB");
+                            allPm.add(pm);
+                        }
+                            break;
+
+                        default:
+                            LOG.warn("Unknown granularity {}", perf.getGranularityPeriod());
+                            break;
+
+                    }
+                }
+                LOG.debug("Deliver normalized records: {}", allPm.size());
+                return allPm;
+            } else {
+                LOG.debug("Deliver empty, no LTP");
+                return AllPm.getEmpty();
+            }
+        }
+    }
+
+
+    /**
+     * Remove all entries from list
+     */
+    @Override
+    public int removeAllCurrentProblemsOfNode() {
+        return microwaveEventListener.removeAllCurrentProblemsOfNode();
+    }
+
+    /**
+     * Register the listener
+     */
+    @Override
+    public void doRegisterEventListener(MountPoint mountPoint) {
+        LOG.info("End registration listener for Mountpoint {}", mountPoint.getIdentifier().toString());
+        final Optional<NotificationService> optionalNotificationService =
+                mountPoint.getService(NotificationService.class);
+        final NotificationService notificationService = optionalNotificationService.get();
+        // notificationService.registerNotificationListener(microwaveEventListener);
+        listenerRegistrationresult =
+                notificationService.registerNotificationListener(microwaveModel.getNotificationListener());
+        LOG.info("End registration listener for Mountpoint {} Listener: {} Result: {}",
+                mountPoint.getIdentifier().toString(), optionalNotificationService, listenerRegistrationresult);
+    }
+
+    /*------------------------------------------------------------
+     * private function to access database
+     */
+
+    /*-----------------------------------------------------------------------------
+     * Reading problems for the networkElement V1.2
+     */
+
+    private List<ProblemNotificationXml> readNetworkElementCurrentProblems12(List<ProblemNotificationXml> resultList) {
+
+        LOG.info("DBRead Get {} NetworkElementCurrentProblems12", getMountPointNodeName());
+
+        InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.onf.core.model.conditional.packages.rev170402.NetworkElementPac> networkElementCurrentProblemsIID =
+                InstanceIdentifier.builder(
+                        org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.onf.core.model.conditional.packages.rev170402.NetworkElementPac.class)
+                        .build();
+
+        // Step 2.3: read to the config data store
+        NetworkElementPac problemPac;
+        NetworkElementCurrentProblems problems;
+        try {
+            problemPac = getGenericTransactionUtils().readData(getNetconfNodeDataBroker(), LogicalDatastoreType.OPERATIONAL,
+                    networkElementCurrentProblemsIID);
+            problems = problemPac.getNetworkElementCurrentProblems();
+            if (problems == null) {
+                LOG.debug("DBRead no NetworkElementCurrentProblems12");
+            } else {
+                for (org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.onf.core.model.conditional.packages.rev170402.network.element.current.problems.g.CurrentProblemList problem : problems.nonnullCurrentProblemList()) {
+                    resultList.add(new ProblemNotificationXml(getMountPointNodeName(), problem.getObjectReference(),
+                            problem.getProblemName(), InternalSeverity.valueOf(problem.getProblemSeverity()),
+                            problem.getSequenceNumber(),
+                            InternalDateAndTime.valueOf(problem.getTimeStamp())));
+                }
+            }
+        } catch (Exception e) {
+            StringWriter sw = new StringWriter();
+            PrintWriter pw = new PrintWriter(sw);
+            e.printStackTrace(pw);
+            LOG.warn("DBRead {} NetworkElementCurrentProblems12 not supported. Message '{}' ", getMountPointNodeName(), pw.toString());
+        }
+        return resultList;
+
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (listenerRegistrationresult != null) {
+            listenerRegistrationresult.close();
+        }
+    }
+
+    @Override
+    public NetworkElementDeviceType getDeviceType() {
+        return NetworkElementDeviceType.Wireless;
+    }
+}