--- /dev/null
+/*******************************************************************************
+ * ============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;
+ }
+}