diff options
author | herbert <herbert.eiselt@highstreet-technologies.com> | 2020-01-30 12:08:35 +0100 |
---|---|---|
committer | Herbert Eiselt <herbert.eiselt@highstreet-technologies.com> | 2020-02-01 12:42:06 +0000 |
commit | 149a57edf72762c7e0eb4062851c06356e6a75ab (patch) | |
tree | 0f6bf0087a2a82c637bb249ab09561f58202b969 /sdnr/wt/devicemanager/provider/src/main/java | |
parent | 8fb01420d6e5b5c3284da57292e28ce40874aaf4 (diff) |
SDN-R add updated devicemanager
add updated devicemanager and specific devicemanagers
Issue-ID: SDNC-1039
Signed-off-by: herbert <herbert.eiselt@highstreet-technologies.com>
Change-Id: I16f4c8d78da95ab12dbb50e50dfb561a85e8d6a2
Signed-off-by: herbert <herbert.eiselt@highstreet-technologies.com>
Diffstat (limited to 'sdnr/wt/devicemanager/provider/src/main/java')
73 files changed, 8575 insertions, 0 deletions
diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/aaiconnector/impl/AaiProviderClient.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/aaiconnector/impl/AaiProviderClient.java new file mode 100644 index 000000000..450f3c4d3 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/aaiconnector/impl/AaiProviderClient.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * ============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.aaiconnector.impl; + +import java.util.List; +import java.util.Optional; +import javax.annotation.Nonnull; +import org.onap.ccsdk.features.sdnr.wt.common.HtAssert; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.filechange.IConfigChangedListener; +import org.onap.ccsdk.features.sdnr.wt.common.http.BaseHTTPResponse; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.aaiconnector.impl.config.AaiConfig; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.DeviceManagerImpl; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.InventoryProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.AaiService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.InventoryInformationDcae; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AaiProviderClient implements AaiService, AutoCloseable { + + private static Logger LOG = LoggerFactory.getLogger(AaiProviderClient.class); + @SuppressWarnings("unused") // @TODO Remove code + private static boolean reloadConfigFlag; + private static final IConfigChangedListener configChangedListener = () -> reloadConfigFlag = true; + + private final AaiConfig config; + private final DeviceManagerImpl deviceManager; + private final ConfigurationFileRepresentation htconfig; + + + public AaiProviderClient(@Nonnull ConfigurationFileRepresentation cfg, DeviceManagerImpl devMgr) { + HtAssert.nonnull(cfg); + this.config = new AaiConfig(cfg); + LOG.debug("AaiProviderClient configuration setting: {}", this.config); + this.htconfig = cfg; + this.htconfig.registerConfigChangedListener(configChangedListener); + this.deviceManager = devMgr; + + } + + public AaiConfig getConfig() { + return this.config; + } + + public void onDeviceRegistered(String mountPointName) { + if (this.config.isOff()) { + return; + } + NetworkElement ne = this.deviceManager != null ? this.deviceManager.getNeByMountpoint(mountPointName) : null; + Optional<InventoryProvider> oip = ne != null ? ne.getService(InventoryProvider.class) : Optional.empty(); + this.onDeviceRegistered(mountPointName, + oip.isPresent() ? oip.get().getInventoryInformation("MWPS") : InventoryInformationDcae.getDefault()); + } + + public void onDeviceRegistered(String mountPointName, InventoryInformationDcae i) { + if (this.config.isOff()) { + return; + } + new Thread(new AaiCreateRequestRunnable(mountPointName, i.getType(), i.getModel(), i.getVendor(), + i.getDeviceIpv4(), i.getInterfaceUuidList())).start(); + } + + public void onDeviceUnregistered(String mountPointName) { + if (this.config.isOff()) { + return; + } + if (this.config.doDeleteOnMountPointRemoved()) { + new Thread(new AaiDeleteRequestRunnable(mountPointName)).start(); + } else { + LOG.debug("prevent deleting device {} by config", mountPointName); + } + } + + @Override + public void close() throws Exception { + this.htconfig.unregisterConfigChangedListener(configChangedListener); + } + + private class AaiCreateRequestRunnable implements Runnable { + + private static final int RESPCODE_NOTFOUND = BaseHTTPResponse.CODE404; + private static final int RESPCODE_FOUND = BaseHTTPResponse.CODE200; + private final AaiWebApiClient mClient; + private final String pnfId; + private final String type; + private final String model; + private final String vendor; + private final String oamIp; + private final List<String> ifaces; + private final int timeout; + + public AaiCreateRequestRunnable(String pnfId, String type, String model, String vendor, String oamIp, + List<String> ifaces) { + this.pnfId = pnfId; + this.type = type; + this.model = model; + this.vendor = vendor; + this.oamIp = oamIp; + this.ifaces = ifaces; + this.timeout = AaiProviderClient.this.config.getConnectionTimeout(); + this.mClient = new AaiWebApiClient(AaiProviderClient.this.config.getBaseUrl(), + AaiProviderClient.this.config.getHeaders(), AaiProviderClient.this.config.getTrustAll(), + AaiProviderClient.this.config.getPcks12CertificateFilename(), + AaiProviderClient.this.config.getPcks12CertificatePassphrase()); + } + + @Override + public void run() { + LOG.debug("check if pnfid {} exists", pnfId); + this.mClient.setTimeout(timeout); + int responseCode = this.mClient.pnfCheckIfExists(pnfId); + if (responseCode == RESPCODE_NOTFOUND) { + LOG.debug("do pnfCreate for {}", pnfId); + this.mClient.pnfCreate(pnfId, type, model, vendor, oamIp, ifaces); + } else if (responseCode == RESPCODE_FOUND) { + LOG.debug("pnfid {} found, nothing to do", pnfId); + } else { + LOG.warn("unhandled response code: {}", responseCode); + } + } + }; + + private class AaiDeleteRequestRunnable implements Runnable { + + private final AaiWebApiClient mClient; + private final String pnfId; + private final int timeout; + + + public AaiDeleteRequestRunnable(String pnfId) { + this.pnfId = pnfId; + this.timeout = AaiProviderClient.this.config.getConnectionTimeout(); + this.mClient = new AaiWebApiClient(AaiProviderClient.this.config.getBaseUrl(), + AaiProviderClient.this.config.getHeaders(), AaiProviderClient.this.config.getTrustAll(), + AaiProviderClient.this.config.getPcks12CertificateFilename(), + AaiProviderClient.this.config.getPcks12CertificatePassphrase()); + } + + @Override + public void run() { + this.mClient.setTimeout(this.timeout); + this.mClient.pnfDelete(pnfId); + } + }; + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/aaiconnector/impl/AaiWebApiClient.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/aaiconnector/impl/AaiWebApiClient.java new file mode 100644 index 000000000..ce58c0371 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/aaiconnector/impl/AaiWebApiClient.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * ============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.aaiconnector.impl; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.onap.ccsdk.features.sdnr.wt.common.http.BaseHTTPClient; +import org.onap.ccsdk.features.sdnr.wt.common.http.BaseHTTPResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AaiWebApiClient extends BaseHTTPClient { + + private static Logger LOG = LoggerFactory.getLogger(AaiWebApiClient.class); + private static final String PNF_JSON_INTERFACE_TEMPLATE = " {\n" + + " \"interface-name\": \"@interface@\",\n" + " \"speed-value\": \"300\",\n" + + " \"speed-units\": \"MBit/s\",\n" + + " \"port-description\": \"Air Interface (MWPS)\",\n" + + " \"equipment-identifier\": \"@pnfId@-@interface@\",\n" + + " \"interface-role\": \"Wireless\",\n" + + " \"interface-type\": \"Air Interface (MWPS)\",\n" + + " \"resource-version\": \"@model@\",\n" + " \"relationship-list\": [\n" + + " {\n" + + " \"related-to\": \"A keyword provided by A&AI to indicate type of node.\",\n" + + " \"related-link\": \"URL to the object in A&AI.\",\n" + + " \"relationship-data\": [\n" + " {\n" + + " \"relationship-key\": \"A keyword provided by A&AI to indicate an attribute.\",\n" + + " \"relationship-value\": \"Value of the attribute\"\n" + + " }\n" + " ],\n" + + " \"related-to-property\": [\n" + " {\n" + + " \"property-key\": \"Key part of a key/value pair\",\n" + + " \"property-value\": \"Value part of a key/value pair\"\n" + + " }\n" + " ]\n" + " }\n" + " ]\n" + + " }\n"; + private static final String PNF_JSON_TEMPLATE = "{\n" + " \"pnf-name\": \"@pnfId@\",\n" + + " \"pnf-id\": \"@pnfId@\",\n" + " \"equip-type\": \"@type@\",\n" + + " \"equip-model\": \"@model@\",\n" + " \"equip-vendor\": \"@vendor@\",\n" + + " \"ipaddress-v4-oam\": \"@oamIp@\",\n" + " \"in-maint\": false,\n" + + " \"prov-status\":\"PROV\",\n" + " \"p-interfaces\": @interface-list@\n" + "}\n" + ""; + private static final String PNF_URI = "network/pnfs/pnf/"; + private static final String EMPTY_MESSAGE = ""; + + private final Map<String, String> headerMap; + + + public AaiWebApiClient(String baseUrl, Map<String, String> headers, boolean trustAllCerts) { + this(baseUrl, headers, trustAllCerts, null, null); + } + + public AaiWebApiClient(String baseUrl, Map<String, String> headers, boolean trustAllCerts, String certFilename, + String passphrase) { + super(baseUrl, trustAllCerts, certFilename, passphrase, BaseHTTPClient.getSslCertPcks()); + + this.headerMap = new HashMap<>(); + this.headerMap.putAll(headers); + this.headerMap.put("Content-Type", "application/json"); + this.headerMap.put("Accept", "application/json"); + } + + /** + * Create and specify defition parametrs of pnf + * @param pnfId name + * @param type type + * @param model model + * @param vendor vendor + * @param oamIp ip + * @param ifaces interfaces + * @return true if http response code was 200 or false if not. + */ + public boolean pnfCreate(String pnfId, String type, String model, String vendor, String oamIp, + List<String> ifaces) { + LOG.debug("registering {} (type={}, model={}, vendor={},ip={})", pnfId, type, model, vendor, oamIp); + String message = getPnfTemplateFilled(pnfId, type, model, vendor, oamIp, ifaces); + return pnfRequest(pnfId, "PUT", message) == 200; + } + + /** + * Unregister + * @param pnfId name + * @return true if http response code was 200 or false if not. + */ + public boolean pnfDelete(String pnfId) { + LOG.debug("unregistering {}", pnfId); + return pnfRequest(pnfId, "DELETE", EMPTY_MESSAGE) == 200; + } + + /** + * Send registration request + * @param pnfId name + * @return error accoring to http response code or -1 + */ + public int pnfCheckIfExists(String pnfId) { + LOG.debug("check for {}", pnfId); + return pnfRequest(pnfId, "GET", EMPTY_MESSAGE); + } + + /* + * Private classes + */ + + private int pnfRequest(String pnfId, String method, String message) { + BaseHTTPResponse response; + try { + String uri = PNF_URI + URLParamEncoder.encode(pnfId); + response = this.sendRequest(uri, method, message, headerMap); + LOG.debug("finished with responsecode {}", response.code); + return response.code; + } catch (IOException e) { + LOG.warn("problem registering {} : {}", pnfId, e.getMessage()); + return -1; + } + } + + + private static String getPnfTemplateFilled(String pnfId, String type, String model, String vendor, String oamIp, + List<String> ifaces) { + return PNF_JSON_TEMPLATE.replace("@pnfId@", pnfId).replace("@type@", type).replace("@model@", model) + .replace("@vendor@", vendor).replace("@oamIp@", oamIp) + .replace("@interface-list@", getPnfTemplateInterfaceList(pnfId, ifaces, model)); + } + + private static String getPnfTemplateInterfaceList(String pnfId, List<String> ifaces, String model) { + StringBuffer s = new StringBuffer(); + s.append("["); + if (ifaces != null) { + for (int i = 0; i < ifaces.size(); i++) { + if (i > 0) { + s.append(","); + } + s.append(PNF_JSON_INTERFACE_TEMPLATE.replace("@interface@", ifaces.get(i))); + } + } + s.append("]"); + + return s.toString().replace("@pnfId@", pnfId).replace("@model@", model); + } + + + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/aaiconnector/impl/URLParamEncoder.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/aaiconnector/impl/URLParamEncoder.java new file mode 100644 index 000000000..2e8b44fd7 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/aaiconnector/impl/URLParamEncoder.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * ============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.aaiconnector.impl; + +class URLParamEncoder { + + public static String encode(String input) { + StringBuilder resultStr = new StringBuilder(); + for (char ch : input.toCharArray()) { + if (isUnsafe(ch)) { + resultStr.append('%'); + resultStr.append(toHex(ch / 16)); + resultStr.append(toHex(ch % 16)); + } else { + resultStr.append(ch); + } + } + return resultStr.toString(); + } + + private static char toHex(int ch) { + return (char) (ch < 10 ? '0' + ch : 'A' + ch - 10); + } + + private static boolean isUnsafe(char ch) { + if (ch > 128 || ch < 0) { + return true; + } + return " %$&+,/:;=?@<>#%".indexOf(ch) >= 0; + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/aaiconnector/impl/config/AaiClientPropertiesFile.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/aaiconnector/impl/config/AaiClientPropertiesFile.java new file mode 100644 index 000000000..671aea5c2 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/aaiconnector/impl/config/AaiClientPropertiesFile.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * ============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.aaiconnector.impl.config; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Properties; + +public class AaiClientPropertiesFile { + + private final File mFile; + private String mPCKS12CertFilename; + private String mPCKS12Passphrase; + private boolean mTrustInsecureSSL; + private String mApplicationIdentifier; + private String mRemoteUrl; + private int mConnectionTimeout; + private int mReadTimeout; + + public String getFilename() { + return this.mFile.getAbsolutePath(); + } + + public String getPCKS12CertFilename() { + return this.mPCKS12CertFilename; + } + + public String getPCKS12Passphrase() { + return this.mPCKS12Passphrase; + } + + public boolean trustInsecureSSL() { + return this.mTrustInsecureSSL; + } + + public String getApplicationIdentifier() { + return this.mApplicationIdentifier; + } + + public String getRemoteUrl() { + return this.mRemoteUrl; + } + + public int getConnectionTimeout() { + return this.mConnectionTimeout; + } + + public int getReadTimeout() { + return this.mReadTimeout; + } + + public boolean exists() { + return this.mFile.exists(); + } + + public AaiClientPropertiesFile(String filename) { + this.mFile = new File(filename); + } + + public void load() throws IOException, NumberFormatException { + Properties defaultProps = new Properties(); + FileInputStream in = new FileInputStream(this.mFile); + defaultProps.load(in); + this.mPCKS12CertFilename = defaultProps.getProperty("org.onap.ccsdk.sli.adaptors.aai.ssl.key", null); + this.mPCKS12Passphrase = defaultProps.getProperty("org.onap.ccsdk.sli.adaptors.aai.ssl.key.psswd", null); + this.mTrustInsecureSSL = defaultProps + .getProperty("org.onap.ccsdk.sli.adaptors.aai.host.certificate.ignore", "false").equals("true"); + this.mApplicationIdentifier = defaultProps.getProperty("org.onap.ccsdk.sli.adaptors.aai.application", null); + this.mRemoteUrl = defaultProps.getProperty("org.onap.ccsdk.sli.adaptors.aai.uri", null); + this.mConnectionTimeout = Integer.parseInt(defaultProps.getProperty("connection.timeout", "60000")); + this.mReadTimeout = Integer.parseInt(defaultProps.getProperty("read.timeout", "60000")); + in.close(); + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/aaiconnector/impl/config/AaiConfig.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/aaiconnector/impl/config/AaiConfig.java new file mode 100644 index 000000000..d30ee9d67 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/aaiconnector/impl/config/AaiConfig.java @@ -0,0 +1,267 @@ +/******************************************************************************* + * ============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.aaiconnector.impl.config; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Properties; +import org.json.JSONArray; +import org.onap.ccsdk.features.sdnr.wt.common.HtAssert; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.Configuration; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AaiConfig implements Configuration { + + private static Logger LOG = LoggerFactory.getLogger(AaiConfig.class); + + private static final String SECTION_MARKER_AAI = "aai"; + + private enum Config { + AAIPROP_FILE("aaiPropertiesFile", "null"), + BASEURL("aaiUrl", "off", "org.onap.ccsdk.sli.adaptors.aai.uri"), + USERCREDENTIALS("aaiUserCredentials",""), + HEADERS("aaiHeaders","[\"X-TransactionId: 9999\"]"), + DELETEONMOUNTPOINTREMOVED("aaiDeleteOnMountpointRemove",false), + TRUSTALLCERTS("aaiTrustAllCerts",false, "org.onap.ccsdk.sli.adaptors.aai.host.certificate.ignore"), + APIVERSION("aaiApiVersion", "aai/v13"), + PCKS12CERTFILENAME("aaiPcks12ClientCertFile","", "org.onap.ccsdk.sli.adaptors.aai.ssl.key"), + PCKS12PASSPHRASE("aaiPcks12ClientCertPassphrase","", "org.onap.ccsdk.sli.adaptors.aai.ssl.key.psswd"), + CONNECTIONTIMEOUT("aaiClientConnectionTimeout",String.valueOf(DEFAULT_VALUE_CONNECTION_TIMEOUT), "connection.timeout"), //in ms; + APPLICATIONID("aaiApplicationId","SDNR", "org.onap.ccsdk.sli.adaptors.aai.application"), + HTTPREADTIMEOUT("aaiReadTimeout", "60000", "read.timeout"); + + private String propertyKey; + private String propertyValue; + private Optional<String> propertyKeySecondFile; + + Config(String propertyKey, Object propertyValue) { + this.propertyKey = propertyKey; + this.propertyValue = propertyValue.toString(); + this.propertyKeySecondFile = Optional.empty(); + } + + Config(String propertyKey, Object propertyValue, String propertyKeySecondFile) { + this(propertyKey, propertyValue); + this.propertyKeySecondFile = Optional.of(propertyKeySecondFile); + } + } + + private static final long DEFAULT_VALUE_CONNECTION_TIMEOUT = 30000; //in ms + private static final String HEADER_KEY_APPLICATION = "X-FromAppId"; + + private final ConfigurationFileRepresentation configuration; + + public AaiConfig(ConfigurationFileRepresentation configuration) { + HtAssert.nonnull(configuration); + this.configuration = configuration; + this.configuration.addSection(SECTION_MARKER_AAI); + defaults(); + } + + /* + * Getter + */ + + public boolean doDeleteOnMountPointRemoved() { + return configuration.getPropertyBoolean(SECTION_MARKER_AAI, Config.DELETEONMOUNTPOINTREMOVED.propertyKey); + } + + public boolean getTrustAll() { + return configuration.getPropertyBoolean(SECTION_MARKER_AAI, Config.TRUSTALLCERTS.propertyKey); + } + + public String getPcks12CertificateFilename() { + return configuration.getProperty(SECTION_MARKER_AAI, Config.PCKS12CERTFILENAME.propertyKey); + } + + public String getPcks12CertificatePassphrase() { + return configuration.getProperty(SECTION_MARKER_AAI, Config.PCKS12PASSPHRASE.propertyKey); + } + + public int getConnectionTimeout() { + long res = configuration.getPropertyLong(SECTION_MARKER_AAI, Config.PCKS12PASSPHRASE.propertyKey).orElse(DEFAULT_VALUE_CONNECTION_TIMEOUT); + return (int)res; + } + + public boolean isOff() { + return configuration.getProperty(SECTION_MARKER_AAI, Config.BASEURL.propertyKey).equalsIgnoreCase("off"); + } + + public String getBaseUri() { + String res = configuration.getProperty(SECTION_MARKER_AAI, Config.APIVERSION.propertyKey); + if (!res.startsWith("/")) { + res = "/" + res; + } + return res; + } + + public String getBaseUrl() { + if (isOff()) { + return ""; + } else { + String url = configuration.getProperty(SECTION_MARKER_AAI, Config.BASEURL.propertyKey); + if (!url.endsWith("/")) { + url += "/"; + } + String apiVersion = configuration.getProperty(SECTION_MARKER_AAI, Config.APIVERSION.propertyKey); + if (apiVersion.startsWith("/")) { + apiVersion = apiVersion.substring(1); + } + return url + apiVersion; + } + } + + public Map<String, String> getHeaders() { + + Map<String,String> headers = _parseHeadersMap(configuration.getProperty(SECTION_MARKER_AAI, Config.HEADERS.propertyKey)); + headers.put(HEADER_KEY_APPLICATION, configuration.getProperty(SECTION_MARKER_AAI, Config.APPLICATIONID.propertyKey)); + + String credentials = configuration.getProperty(SECTION_MARKER_AAI, Config.USERCREDENTIALS.propertyKey); + if (!nullorempty(credentials)) { + String credentialParts[] = credentials.split(":"); + if (credentialParts.length == 2) { + // 0:username 1:password + String s = headers.getOrDefault("Authorization", null); + if (nullorempty(s) && !nullorempty(credentialParts[0]) && !nullorempty(credentialParts[1])) { + headers.put("Authorization", + "Basic " + new String(Base64.getEncoder().encode(credentials.getBytes()))); + } + } + } + return headers; + } + + @Override + public String getSectionName() { + return SECTION_MARKER_AAI; + } + + @Override + public void defaults() { + for (Config conf : Config.values()) { + configuration.setPropertyIfNotAvailable(SECTION_MARKER_AAI, conf.propertyKey, conf.propertyValue); + } + // If file is available, the content is assigned to related parameters. + getAaiPropertiesFile(); + } + + @Override + public String toString() { + return "AaiConfig [doDeleteOnMountPointRemoved()=" + doDeleteOnMountPointRemoved() + ", getTrustAll()=" + + getTrustAll() + ", getPcks12CertificateFilename()=" + getPcks12CertificateFilename() + + ", getPcks12CertificatePassphrase()=" + getPcks12CertificatePassphrase() + ", getConnectionTimeout()=" + + getConnectionTimeout() + ", isOff()=" + isOff() + ", getBaseUri()=" + getBaseUri() + ", getBaseUrl()=" + + getBaseUrl() + ", getHeaders()=" + getHeaders() + ", getSectionName()=" + getSectionName() + "]"; + } + + /* + * Private + */ + + private boolean nullorempty(String s) { + return s == null || s.isEmpty(); + } + + /** + * Convert headers to configuration string. + * @param headers + * @return + */ + @SuppressWarnings("unused") + private static String _printHeadersMap(Map<String, String> headers) { + String r = "["; + if (headers != null) { + int i = 0; + for (Entry<String, String> entry : headers.entrySet()) { + if (i > 0) { + r += ","; + } + r += "\"" + entry.getKey() + ":" + entry.getValue() + "\""; + i++; + } + } + r += "]"; + return r; + } + + private static Map<String, String> _parseHeadersMap(String s) { + + LOG.info("Parse: '{}'",s); + Map<String, String> r = new HashMap<>(); + if (s != null) { + s = s.trim(); + if (!s.isEmpty()) { + JSONArray a; + try { + a = new JSONArray(s); + if (a.length() > 0) { + for (int i = 0; i < a.length(); i++) { + String item = a.getString(i); + String[] hlp = item.split(":"); + if (hlp.length > 1) { + r.put(hlp[0], hlp[1]); + } + } + } + } catch (Exception e) { + LOG.debug("Unparsable '{}'", s); + } + } + } + return r; + } + + /** + * Read file if available and assign to configuration + */ + private void getAaiPropertiesFile() { + String aaiPropertiesFileName = configuration.getProperty(SECTION_MARKER_AAI, Config.AAIPROP_FILE.propertyKey); + File f = new File(aaiPropertiesFileName); + if (f.exists()) { + try { + FileInputStream in = new FileInputStream(f); + Properties defaultProps = new Properties(); + defaultProps.load(in); + + for (Config conf : Config.values()) { + if (conf.propertyKeySecondFile.isPresent()) { + String config = defaultProps.getProperty("org.onap.ccsdk.sli.adaptors.aai.ssl.key", conf.propertyValue); + LOG.debug("Property file assign {} = {} ",conf.propertyKey, config ); + configuration.setPropertyIfNotAvailable( + SECTION_MARKER_AAI, + conf.propertyKey, + config); + } + } + + in.close(); + } catch (IOException e) { + LOG.warn("Problem during file read {} {}", f.getAbsoluteFile(), e); + } + } + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/archiveservice/ArchiveCleanService.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/archiveservice/ArchiveCleanService.java new file mode 100644 index 000000000..a43502dfc --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/archiveservice/ArchiveCleanService.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * ============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.archiveservice; + +import java.util.Date; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jdt.annotation.NonNull; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.filechange.IConfigChangedListener; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.ArchiveCleanProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.IEsConfig; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService; +import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; + +public class ArchiveCleanService implements AutoCloseable, IConfigChangedListener, Runnable,ClusterSingletonService { + + private static final Logger LOG = LoggerFactory.getLogger(ArchiveCleanService.class); + private static final ServiceGroupIdentifier IDENT = ServiceGroupIdentifier.create("ElasticSearchArchiveCleanService"); + + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + private final ArchiveCleanProvider[] indexCleanList; + private final Runnable doClean; + + private final IEsConfig esConfig; + private Future<?> taskReference; + private boolean isMaster; + + public ArchiveCleanService(IEsConfig config, ArchiveCleanProvider... indexCleanList) { + this.esConfig = config; + this.esConfig.registerConfigChangedListener(this); + + this.indexCleanList = indexCleanList; + this.doClean = this; + this.taskReference = null; + + this.reinit(); + } + + private void reinit() { + + if (taskReference != null) { + taskReference.cancel(false); + } + if(this.isMaster) { + if (this.esConfig.getArchiveCheckIntervalSeconds() > 0) { + LOG.info("DBCleanService is turned on for entries older than {} seconds", + this.esConfig.getArchiveLifetimeSeconds()); + taskReference = this.scheduler.scheduleAtFixedRate(doClean, 0, + this.esConfig.getArchiveCheckIntervalSeconds(), TimeUnit.SECONDS); + } else { + LOG.info("DBCleanService is turned off"); + } + } + else { + LOG.info("service is inactive on this node. active on another node."); + } + } + + public Date getDateForOldElements() { + return new Date(System.currentTimeMillis() - esConfig.getArchiveLifetimeSeconds() * 1000); + } + + public int countOldEntries() { + int cnt = 0; + Date olderAreOutdated = getDateForOldElements(); + for (ArchiveCleanProvider indexCleanElement : indexCleanList) { + if (indexCleanElement != null) { + indexCleanElement.getNumberOfOldObjects(olderAreOutdated); + } + } + return cnt; + } + + @Override + public void run() { + + try { + int removed = 0; + Date olderElementToBeRemoved = getDateForOldElements(); + LOG.trace("cleaning logs from entries older than {}", olderElementToBeRemoved); + + for (ArchiveCleanProvider indexCleanElement : indexCleanList) { + if (indexCleanElement != null) { + removed += indexCleanElement.doIndexClean(olderElementToBeRemoved); + } + } + if (removed > 0) { + LOG.trace("Removed elements: {}",removed); + } + } catch (Exception e) { + LOG.warn("problem executing dbclean", e); + } + } + + @Override + public void onConfigChanged() { + LOG.info("Not yet implemented. config changed. reninit timer"); + }; + + @Override + public void close() throws Exception { + this.esConfig.unregisterConfigChangedListener(this); + this.scheduler.shutdown(); + } + + @Override + public String toString() { + return "ArchivCleanService [ArchiveCheckIntervalSeconds=" + esConfig.getArchiveCheckIntervalSeconds() + + "ArchiveLifetimeSeconds=" + esConfig.getArchiveLifetimeSeconds() + "]"; + } + + @SuppressWarnings("null") + @Override + public @NonNull ServiceGroupIdentifier getIdentifier() { + return IDENT; + } + + @Override + public void instantiateServiceInstance() { + LOG.info("We take Leadership"); + this.isMaster=true; + this.reinit(); + } + + @Override + public ListenableFuture<? extends Object> closeServiceInstance() { + LOG.info("We lost Leadership"); + this.isMaster=false; + this.reinit(); + return Futures.immediateFuture(null); + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/datamanager/DeviceManagerDatabaseNotificationService.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/datamanager/DeviceManagerDatabaseNotificationService.java new file mode 100644 index 000000000..e65a42720 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/datamanager/DeviceManagerDatabaseNotificationService.java @@ -0,0 +1,168 @@ +/******************************************************************************* + * ============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.datamanager; + +import java.util.List; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.onap.ccsdk.features.sdnr.wt.common.HtAssert; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.AttributeValueChangedNotificationXml; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.ObjectCreationNotificationXml; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.ObjectDeletionNotificationXml; +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.service.EquipmentService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.FaultService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.EquipmentData; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.EventlogNotificationBuilder; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.FaultData; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.FaultNotificationBuilder2; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EventlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Faultcurrent; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.FaultcurrentBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.FaultlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Inventory; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SeverityType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SourceType; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; + +/** + * @author herbert + * + */ +public class DeviceManagerDatabaseNotificationService implements NotificationService, EquipmentService, FaultService { + + private final DataProvider databaseService; + private final WebSocketServiceClientInternal webSocketService; + + /** + * @param databaseService to access database + * @param webSocketService to send notifications + */ + public DeviceManagerDatabaseNotificationService(DataProvider databaseService, + WebSocketServiceClientInternal webSocketService) { + super(); + HtAssert.nonnull(databaseService); + HtAssert.nonnull(webSocketService); + + this.databaseService = databaseService; + this.webSocketService = webSocketService; + } + + @Override + public void eventNotification(@NonNull EventlogEntity eventNotification) { + String nodeId = eventNotification.getNodeId(); + if (nodeId == null) { + nodeId = "EmptyNodeId"; + } + databaseService.writeEventLog(eventNotification); + webSocketService.sendViaWebsockets(nodeId, new AttributeValueChangedNotificationXml(eventNotification)); + } + + @Override + public void changeNotification(NodeId nodeId, @Nullable Integer counter, @Nullable DateAndTime timeStamp, + @Nullable String objectId, @Nullable String attributeName, @Nullable String newValue) { + EventlogEntity eventlogEntity = new EventlogNotificationBuilder(nodeId, counter, timeStamp, objectId, attributeName, newValue).build(); + databaseService.writeEventLog(eventlogEntity); + webSocketService.sendViaWebsockets(nodeId.getValue(), new AttributeValueChangedNotificationXml(eventlogEntity)); + } + + @Override + public void creationNotification(NodeId nodeId, @Nullable Integer counter, @Nullable DateAndTime timeStamp, + @Nullable String objectId) { + EventlogEntity eventlogEntity = new EventlogNotificationBuilder(nodeId, counter, timeStamp, objectId, "creation", null).build(); + databaseService.writeEventLog(eventlogEntity); + webSocketService.sendViaWebsockets(nodeId.getValue(), new ObjectCreationNotificationXml(eventlogEntity)); + } + + + @Override + public void deletionNotification(NodeId nodeId, @Nullable Integer counter, @Nullable DateAndTime timeStamp, + @Nullable String objectId) { + EventlogEntity eventlogEntity = new EventlogNotificationBuilder(nodeId, counter, timeStamp, objectId, "deletion", null).build(); + databaseService.writeEventLog(eventlogEntity); + webSocketService.sendViaWebsockets(nodeId.getValue(), new ObjectDeletionNotificationXml(eventlogEntity)); + } + + @Override + public void writeEquipment(@NonNull EquipmentData equipment) { + //equipment.getList().forEach(card -> databaseService.writeInventory(card)); + HtAssert.nonnull(equipment); + List<Inventory> list = equipment.getList(); + HtAssert.nonnull(list); + for (Inventory card : list) { + databaseService.writeInventory(card); + } + } + + @Override + public void faultNotification(@NonNull FaultlogEntity faultNotification) { + databaseService.writeFaultLog(faultNotification); + databaseService.updateFaultCurrent(getFaultCurrent(faultNotification)); + + ProblemNotificationXml notificationXml = new ProblemNotificationXml(faultNotification); + String nodeName = faultNotification.getNodeId(); + // ToggleAlarmFilter functionality +// if (delayFilter.processNotification(notificationXml.getSeverity() == InternalSeverity.NonAlarmed, notificationXml.getProblem(), notificationXml)) +// { +// dcaeForwarder.sendProblemNotificationUsingMaintenanceFilter(nodeName, notificationXml); +// } + // end of ToggleAlarmFilter + + this.webSocketService.sendViaWebsockets(nodeName, notificationXml); + } + + @Override + public void faultNotification(@NonNull NodeId nodeId, @Nullable Integer counter, @Nullable DateAndTime timeStamp, + @Nullable String objectId, @Nullable String problem, @Nullable SeverityType severity) { + FaultNotificationBuilder2 bFaultlog = new FaultNotificationBuilder2(nodeId, counter, timeStamp, objectId, problem, severity, SourceType.Netconf); + faultNotification(bFaultlog.build()); + + } + + @Override + public int removeAllCurrentProblemsOfNode(@NonNull NodeId nodeId) { + int deleted = databaseService.clearFaultsCurrentOfNode(nodeId.getValue()); + return deleted; + } + + @Override + public void initCurrentProblemStatus(@NonNull NodeId nodeId, FaultData resultList) { + resultList.getProblemList().forEach(problem -> { + FaultcurrentBuilder bFaultcurrent = new FaultcurrentBuilder(); + bFaultcurrent.fieldsFrom(problem); + databaseService.updateFaultCurrent(bFaultcurrent.build()); + }); + } + + @Override + public int removeObjectsCurrentProblemsOfNode(@NonNull NodeId nodeId, String objectId) { + int deleted = databaseService.clearFaultsCurrentOfNodeWithObjectId(nodeId.getValue(), objectId); + return deleted; + } + + private Faultcurrent getFaultCurrent(@NonNull FaultlogEntity problem) { + FaultcurrentBuilder bFaultcurrent = new FaultcurrentBuilder(); + bFaultcurrent.fieldsFrom(problem); + return bFaultcurrent.build(); + + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeForwarderImpl.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeForwarderImpl.java new file mode 100644 index 000000000..850101222 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeForwarderImpl.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * ============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.dcaeconnector.impl; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.onap.ccsdk.features.sdnr.wt.common.HtAssert; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.ProviderClient; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.ProblemNotificationXml; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.MaintenanceService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DcaeForwarderImpl implements DcaeForwarderInternal, AutoCloseable { + + private static final Logger LOG = LoggerFactory.getLogger(DcaeForwarderImpl.class); + + private final @Nullable ProviderClient aotsmClient; + private final ProviderClient dcaeProvider; + private final MaintenanceService maintenanceService; + + public DcaeForwarderImpl(@Nullable ProviderClient aotsmClient, @Nullable ProviderClient dcaeProvider, + @NonNull MaintenanceService maintenanceService) { + super(); + + HtAssert.nonnull(maintenanceService); + this.aotsmClient = aotsmClient; + this.dcaeProvider = dcaeProvider; + this.maintenanceService = maintenanceService; + } + + @Override + @SuppressWarnings("null") + public void sendProblemNotificationUsingMaintenanceFilter(String nodeId, ProblemNotificationXml notificationXml) { + if (!this.maintenanceService.isONFObjectInMaintenance(nodeId, notificationXml.getObjectId(), + notificationXml.getProblem())) { + if (dcaeProvider != null) { + this.dcaeProvider.sendProblemNotification(nodeId, notificationXml); + } + if (this.aotsmClient != null) { + this.aotsmClient.sendProblemNotification(nodeId, notificationXml); + } + } else { + LOG.debug("Notification will not be sent to external services. Device " + nodeId + + " is in maintenance mode"); + } + } + + @Override + public void sendProblemNotification(String nodeId, ProblemNotificationXml notificationXml) { + //to prevent push alarms on reconnect + //=> only pushed alarms are forwared to dcae + //dcaeProvider.sendProblemNotification(nodeName, notificationXml); + if(aotsmClient!=null) { + aotsmClient.sendProblemNotification(nodeId, notificationXml); + } + + } + + @Override + public void close() throws Exception { + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeForwarderInternal.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeForwarderInternal.java new file mode 100644 index 000000000..6d92da081 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeForwarderInternal.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * ============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.dcaeconnector.impl; + +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.ProblemNotificationXml; + +/** + * @author herbert + * + */ +public interface DcaeForwarderInternal { + + /** + * @param oWNKEYNAME + * @param notificationXml + */ + void sendProblemNotificationUsingMaintenanceFilter(String oWNKEYNAME, ProblemNotificationXml notificationXml); + + /** + * @param nodeName + * @param notificationXml + */ + void sendProblemNotification(String nodeName, ProblemNotificationXml notificationXml); + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeMessages.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeMessages.java new file mode 100644 index 000000000..2816acb60 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeMessages.java @@ -0,0 +1,349 @@ +/******************************************************************************* + * ============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========================================================================== + ******************************************************************************/ +/** + ecompProvider.sendProblemNotification(ownKeyName, notificationXml); + * ECOMP Messages are generated an send to destination + * + * @author herbert + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.dcaeconnector.impl; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.Optional; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import org.eclipse.jdt.annotation.Nullable; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.NetconfTimeStamp; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.DeviceManagerImpl; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.util.InternalSeverity; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.ProblemNotificationXml; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.InventoryProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.InventoryInformationDcae; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DcaeMessages { + + private static final Logger LOG = LoggerFactory.getLogger(DcaeSenderImpl.class); + + private static final String DCAE_NORMAL = "NORMAL"; + private static final String DCAE_MINOR = "MINOR"; + private static final String DCAE_WARNING = "WARNING"; + private static final String DCAE_CRITICAL = "CRITICAL"; + private static final String DCAE_MAJOR = "MAJOR"; + + private static final String eventNamePrefix = "fault_Microwave_Radio_Alarms"; + private static final String eventType = "Microwave_Radio_Alarms"; + private static final String eventSourceType = "Microwave_Radio"; + + private static final String charset = "UTF-8"; + + private static final HostnameVerifier allHostsValid = (hostname, session) -> true; + + private static final String CONTENT_TYPE_APPJSON = "application/json"; + + private static final NetconfTimeStamp NETCONFTIME_CONVERTER = NetconfTimeStampImpl.getConverter(); + + //Configurable parameters + private final DcaeSender dcaeSender; + private final int heartbeatIntervallSeconds; + private final String entityName; + private final DeviceManagerImpl deviceManager; + + //Variables + private int heartbeatsequence = 0; + + public DcaeMessages(DcaeSender ecompSender, String entityName, Integer heartbeatIntervallSeconds, DeviceManagerImpl deviceManager) { + this.dcaeSender = ecompSender; + this.entityName = entityName; + this.deviceManager = deviceManager; + this.heartbeatIntervallSeconds = heartbeatIntervallSeconds; + } + + /** + * Create a heartbeat message. + * @return Result string with answer from server + */ + public String postHeartBeat() { + String epochTimeMicrosecondsString = getEpochTimeMicroseconds(); + String body = assembleHeartbeatFromTemplate(null, + epochTimeMicrosecondsString, + heartbeatsequence++, + NETCONFTIME_CONVERTER.getTimeStampAsNetconfString()).toString(); + return dcaeSender.sendDcaePost( body); + } + + /** + * ONF 1.2 Problem Notification + * @param mountPointName self-explaining + * @param notification Notification input + * @return String with answer + */ + + public String postNotification(String mountPointName, ProblemNotificationXml notification) { + + String problemName = notification.getProblem(); + String sequence = notification.getCounter(); + String objId = notification.getObjectId(); + String severity = convert( notification.getSeverity()); + String timeStamp = convert( notification.getTimeStamp() ); + + String body = assembleEventNotificationFromTemplate(null, + timeStamp, sequence, + mountPointName, objId, problemName, severity, notification.getTimeStamp() ).toString(); + + return dcaeSender.sendDcaePost( body); + } + + /** + * Setup a connection to URL with authorisation header + * @param url e.g. "https://plan.fritz.box:9092/ux/#" or " + * @param basicAuth authorisation header like "Basic SGVyYmVydDpIZXJiZXJ0" + * @param insertContentHeader + * @return Null in case of error or the URLConnection + * @throws IOException + * @throws MalformedURLException + */ + static @Nullable HttpURLConnection openConnection( URL url, String basicAuth, boolean insertContentHeader, @Nullable SSLContext sc) throws MalformedURLException, IOException { + + //Prepare the connection + HttpURLConnection newHttpConnection = null; + { + URLConnection newConnection = url.openConnection(); + if (newConnection instanceof HttpURLConnection) { + LOG.debug("Setup connection to {} ", url.toString()); + + newHttpConnection = (HttpURLConnection)newConnection; + + newHttpConnection.setDoOutput(true); // Triggers POST. + newHttpConnection.setRequestProperty("Accept-Charset", charset); + if (basicAuth != null) { + newHttpConnection.setRequestProperty("Authorization", basicAuth); + } + if (insertContentHeader) { + newHttpConnection.setRequestProperty("Content-Type", CONTENT_TYPE_APPJSON); + } + + if (newHttpConnection instanceof HttpsURLConnection) { + LOG.debug("SSL connection setup with trust all."); + HttpsURLConnection newHttpsConnection = (HttpsURLConnection)newHttpConnection; + if (sc != null) { + newHttpsConnection.setSSLSocketFactory(sc.getSocketFactory()); + } else { + LOG.warn("No SSL Contect available"); + } + newHttpsConnection.setHostnameVerifier(allHostsValid); + } + } else { + LOG.warn("URL not a HTTP protocol: {}", url); + } + } + return newHttpConnection; + } + + /* ----------------- + * Private function for message creation and with templates + */ + + /** + * Get actual microseconds + * @return String + */ + private String getEpochTimeMicroseconds() { + long microseconds = System.nanoTime() / 1000; + return String.valueOf(microseconds); + } + + /** + * Assemble heartbeat message + * @param sb StringBuffer to be used or null to allocate + * @param epochTimeMicrosecondsString Text with time stamp + * @param sequence integer sequence number + * @param eventTimeValueNetconfFormatString like this: 2018-05-14T05:32:17.292Z + * @return StringBuffer with result + */ + private StringBuffer assembleHeartbeatFromTemplate( + StringBuffer sb, + String epochTimeMicrosecondsString, + int sequence, + String eventTimeValueNetconfFormatString) { + + if (sb == null) { + sb = new StringBuffer(); + } + sb.append("{\n" + + " \"event\": {\n" + + " \"commonEventHeader\": {\n" + + " \"domain\": \"heartbeat\",\n" + + " \"eventId\": \"testpattern-ab305d54-85b4-a31b-7db2-fb6b9e546015\",\n" + + " \"eventName\": \"heartbeat_Controller\",\n" + + " \"eventType\": \"Controller\",\n" + + " \"priority\": \"Low\",\n" + + " \"reportingEntityId\": \"\",\n" + + " \"reportingEntityName\": \""+entityName+"\",\n" + + " \"sequence\": "+String.valueOf(sequence)+",\n" + + " \"sourceId\": \"\",\n" + + " \"sourceName\": \""+entityName+"\",\n" + + " \"startEpochMicrosec\": "+epochTimeMicrosecondsString+",\n" + + " \"lastEpochMicrosec\": "+epochTimeMicrosecondsString+",\n" + + " \"version\": 3.0\n" + + " },\n" + + " \"heartbeatFields\": {\n" + + " \"additionalFields\": [\n" + + " {\n" + + " \"name\": \"eventTime\",\n" + + " \"value\": \""+eventTimeValueNetconfFormatString+"\"\n" + + " }\n" + + " ],\n" + + " \"heartbeatFieldsVersion\": 1.0,\n" + + " \"heartbeatInterval\": "+heartbeatIntervallSeconds+"\n" + + " }\n" + + " }\n" + + "}\n" + ); + + return sb; + } + + /** + * Assemble notification message + * @param sb StringBuffer to be used or null to allocate + * @param epochTimeMicrosecondsString Text with time stamp + * @param sequence integer sequence number + * @param mountpointName + * @param objId + * @param problemName + * @param severity + * @return StringBuffer with result + */ + + private StringBuffer assembleEventNotificationFromTemplate(StringBuffer sb, + String epochTimeMicrosecondsString, String sequence, + String mountpointName, String objId, String problemName, String severity, String eventTimeValueNetconfFormatString + ) { + + if (sb == null) { + sb = new StringBuffer(); + } + + NetworkElement optionalNe = deviceManager != null ? deviceManager.getNeByMountpoint(mountpointName) : null; + InventoryInformationDcae neInventory = InventoryInformationDcae.getDefault(); + if (optionalNe != null) { + Optional<InventoryProvider> inventoryProvider = optionalNe.getService(InventoryProvider.class); + if (inventoryProvider.isPresent()) { + neInventory = inventoryProvider.get().getInventoryInformation(); + } + } + + sb.append("{\n" + + " \"event\": {\n" + + " \"commonEventHeader\": {\n" + + " \"domain\": \"fault\",\n" + + " \"eventId\": \""+mountpointName+"_"+objId+"_"+problemName+"\",\n" + + " \"eventName\": \""+eventNamePrefix+"_"+problemName+"\",\n" + + " \"eventType\": \""+eventType+"\",\n" + + " \"sequence\": "+sequence+",\n" + + " \"priority\": \"High\",\n" + + " \"reportingEntityId\": \"\",\n" + + " \"reportingEntityName\": \""+entityName+"\",\n" + + " \"sourceId\": \"\",\n" + + " \"sourceName\": \""+mountpointName+"\",\n" + + " \"startEpochMicrosec\": "+epochTimeMicrosecondsString+",\n" + + " \"lastEpochMicrosec\": "+epochTimeMicrosecondsString+",\n" + + " \"version\": 3.0\n" + + " },\n" + + " \"faultFields\": {\n" + + " \"alarmAdditionalInformation\": [\n" + + " {\n" + + " \"name\": \"eventTime\",\n" + + " \"value\": \""+eventTimeValueNetconfFormatString+"\"\n" + + " },\n" + + " {\n" + + " \"name\": \"equipType\",\n" + + " \"value\": \""+neInventory.getType()+"\"\n" + + " },\n" + + " {\n" + + " \"name\": \"vendor\",\n" + + " \"value\": \""+neInventory.getVendor()+"\"\n" + + " },\n" + + " {\n" + + " \"name\": \"model\",\n" + + " \"value\": \""+neInventory.getModel()+"\"\n" + + " }\n" + + " ],\n" + + " \"faultFieldsVersion\":2.0,\n" + + " \"eventSourceType\": \""+eventSourceType+"\",\n" + + " \"alarmCondition\": \""+problemName+"\",\n" + + " \"alarmInterfaceA\": \""+objId+"\",\n" + + " \"specificProblem\": \""+problemName+"\",\n" + + " \"eventSeverity\": \""+severity+"\",\n" + + " \"vfStatus\": \"Active\"\n" + + " }\n" + + " }\n" + + "}\n" + ); + + return sb; + } + + /* ----------------- + * Convert internal type formats into the Ecomp format + */ + + private String convert(InternalSeverity severity ) { + switch( severity ) { + case NonAlarmed: + break; + case Warning: + return DCAE_WARNING; + case Minor: + return DCAE_MINOR; + case Major: + return DCAE_MAJOR; + case Critical: + return DCAE_CRITICAL; + } + return DCAE_NORMAL; + } + + + /** + * Time has to be converted into milliseconds + * @param timeAsString time as string + * @return as string + */ + private String convert(String timeAsString) { + + long microseconds = -1; + try { + microseconds = NETCONFTIME_CONVERTER.getTimeStampFromNetconfAsMilliseconds(timeAsString) * 1000; + } catch (IllegalArgumentException e) { + LOG.info("Can not convert timeAsString", e); + } + return String.valueOf(microseconds); + } + + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeProviderClient.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeProviderClient.java new file mode 100644 index 000000000..6993a14e9 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeProviderClient.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * ============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.dcaeconnector.impl; + +import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.filechange.IConfigChangedListener; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.dcaeconnector.impl.config.DcaeConfig; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.DeviceManagerImpl; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.ProviderClient; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.ProblemNotificationXml; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class DcaeProviderClient implements AutoCloseable, ProviderClient { + + private static final Logger LOG = LoggerFactory.getLogger(DcaeProviderClient.class); + + private final ConfigurationFileRepresentation htConfig; + private final IConfigChangedListener configChangedListener; + + private final Object lock = new Object(); + private DcaeProviderWorker worker; + private DcaeConfig config; + + public DcaeProviderClient(ConfigurationFileRepresentation cfg, String entityName, DeviceManagerImpl deviceManager) { + LOG.info("Create"); + this.htConfig=cfg; + this.config = new DcaeConfig(cfg); + worker = new DcaeProviderWorker(config, entityName, deviceManager); + this.configChangedListener = () -> { + LOG.info("Configuration change. Worker exchanged"); + synchronized(lock) { + worker.close(); + worker = new DcaeProviderWorker(this.config, entityName, deviceManager); + } + }; + this.htConfig.registerConfigChangedListener(configChangedListener ); + + } + + @Override + public void sendProblemNotification(String mountPointName, ProblemNotificationXml notification) { + synchronized(lock) { + worker.sendProblemNotification(mountPointName, notification); + } + } + + @Override + public void sendProblemNotification(String mountPointName, ProblemNotificationXml notification, boolean neDeviceAlarm) { + sendProblemNotification(mountPointName, notification); + } + + @Override + public void close() { + this.htConfig.unregisterConfigChangedListener(configChangedListener); + synchronized(lock) { + worker.close(); + } + } + + /* --------------------------------------------------------- + * Private + */ + +} + + + diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeProviderTask.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeProviderTask.java new file mode 100644 index 000000000..2a169db01 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeProviderTask.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * ============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========================================================================== + ******************************************************************************/ +/** + * Event provider to ECOMP for heartbeat message + * + * @author herbert + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.dcaeconnector.impl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class DcaeProviderTask implements Runnable { + + private static final Logger LOG = LoggerFactory.getLogger(DcaeProviderTask.class); + + private int t = 0; + private final DcaeMessages dcaeMessages; + + DcaeProviderTask(DcaeMessages dcaeMessages) { + LOG.info("Create eventprovider task"); + this.dcaeMessages = dcaeMessages; + } + + private void sendHeartbeat() { + dcaeMessages.postHeartBeat(); + } + + @Override + public void run() { + LOG.debug("DCAE provider heartbeat tick start {}", t++); + sendHeartbeat(); + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeProviderWorker.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeProviderWorker.java new file mode 100644 index 000000000..6293843e8 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeProviderWorker.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * ============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.dcaeconnector.impl; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.onap.ccsdk.features.sdnr.wt.devicemanager.dcaeconnector.impl.config.DcaeConfig; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.DeviceManagerImpl; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.ProblemNotificationXml; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class DcaeProviderWorker implements AutoCloseable { + + private static final Logger LOG = LoggerFactory.getLogger(DcaeProviderWorker.class); + + private static final int MIN_HEARTBEAT_TIME_SECONDS = 30; + + private final ScheduledExecutorService scheduler; + private final DcaeSenderImpl dcaepClient; + private final DcaeMessages dcaeMessages; + private final ScheduledFuture<?> taskReference; + + public DcaeProviderWorker(DcaeConfig configuration, String entityName, DeviceManagerImpl deviceManager) { + + //Start services + LOG.info("Configuration: "+configuration); + int heartbeatSeconds = configuration.getTimerPeriodSeconds(); + if ( heartbeatSeconds < MIN_HEARTBEAT_TIME_SECONDS ) { + heartbeatSeconds = MIN_HEARTBEAT_TIME_SECONDS; + LOG.info("Adjust heartbeat intervall to minimum of { } seconds.",heartbeatSeconds); + } + + dcaepClient = new DcaeSenderImpl(configuration.getEventReveicerUrl(), configuration.getUserCredentials()); + dcaeMessages = new DcaeMessages(dcaepClient, entityName, heartbeatSeconds, deviceManager); + + //Activate task + LOG.info("Create Fault manager client Task"); + this.scheduler = Executors.newSingleThreadScheduledExecutor(); + Runnable task = new DcaeProviderTask(dcaeMessages); + + LOG.info("Fault task created with "+heartbeatSeconds+" Seconds"); + this.taskReference = this.scheduler.scheduleAtFixedRate(task, 0, heartbeatSeconds, TimeUnit.SECONDS); + LOG.info("Fault task scheduled"); + } + + public void sendProblemNotification(String mountPointName, ProblemNotificationXml notification) { + LOG.debug("Notification answer: {}", dcaeMessages.postNotification(mountPointName, notification)); + } + + @Override + public void close() { + this.taskReference.cancel(false); + try { + this.scheduler.shutdown(); + this.scheduler.awaitTermination(5, TimeUnit.SECONDS); + } catch (InterruptedException | SecurityException e) { + LOG.debug("Schedler shutdown interrupted with exception: ",e); + if (e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } + } + } + + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeSender.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeSender.java new file mode 100644 index 000000000..5ebc37d51 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeSender.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * ============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.dcaeconnector.impl; + +/** + * @author herbert + * + */ +public interface DcaeSender { + + public String sendDcaePost(String body); + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeSenderImpl.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeSenderImpl.java new file mode 100644 index 000000000..31f7b4e03 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/DcaeSenderImpl.java @@ -0,0 +1,236 @@ +/******************************************************************************* + * ============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========================================================================== + ******************************************************************************/ +/** + * Client for ECOMP notification server + * + * Reference: @link + * http://stackoverflow.com/questions/13022717/java-and-https-url-connection-without-downloading-certificate + * + * @author herbert + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.dcaeconnector.impl; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.Reader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.security.spec.InvalidKeySpecException; +import java.util.Base64; +import javax.net.ssl.SSLContext; +import org.onap.ccsdk.features.sdnr.wt.common.http.BaseHTTPClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DcaeSenderImpl implements DcaeSender { + + private static final Logger LOG = LoggerFactory.getLogger(DcaeSenderImpl.class); + private static final String EMPTY = ""; + private static final String charset = "UTF-8"; + + private final String urlString; + private final String basicAuth; + + private SSLContext sc = null; + private URL url = null; + private HttpURLConnection connection = null; + + public DcaeSenderImpl(String url, String userCredentials) { + + LOG.info("DcaeSenderImpl setup start with {} {}", url, userCredentials); + + this.urlString = url; + this.basicAuth = "Basic " + new String(Base64.getEncoder().encode(userCredentials.getBytes())); + + if (urlString != null && !urlString.equals("off")) { + try { + this.url = new URL(url); + sc = BaseHTTPClient.setupSsl(true); + } catch (KeyManagementException | NoSuchAlgorithmException | UnrecoverableKeyException + | CertificateException | KeyStoreException | InvalidKeySpecException | IOException e) { + LOG.warn("SSL setup failed: {}", e.getMessage()); + } + } + LOG.info("DcaeSenderImpl setup ends"); + } + + /** + * Send message to ECOMP Server + * + * @param body for POST message + */ + @Override + public String sendDcaePost(String body) { + + if (url != null) { + try { + connection = DcaeMessages.openConnection(url, basicAuth, true, sc); + if (connection != null) { + return processPost(connection, body); + } else { + LOG.warn("No SSL context available"); + } + } catch (IOException e) { + LOG.warn("Dcae post failed {}", e.getMessage()); + } + } + return EMPTY; + } + + /** + * Connect to Server and expect answer. + * + * @return with answer body + */ + public String testConnectServer() { + + if (url != null) { + try { + connection = DcaeMessages.openConnection(url, null, false, sc); + if (connection != null) { + return receiveInitialAnswer(connection); + } + } catch (IOException e) { + LOG.warn("Dcae post failed {}", e.getMessage()); + } + } + return EMPTY; + } + + /** + * Show status in readable form for testing + * + * @return String with result + */ + public String getStatusAsString() { + StringBuffer sb = new StringBuffer(); + + sb.append("URL: " + url.getPath() + " " + url.getPort() + " Host: " + url.getHost()); + sb.append("\n"); + if (connection != null) { + sb.append("Connection setup: "); + sb.append(connection.getClass().getName()); + sb.append(" "); + } else { + sb.append("Connection setup: No connection (server problem or switched off)"); + } + return sb.toString(); + + } + + + /*------------------------------------------------------------------------------ + * Private functions + */ + + + /** + * Send Post and wait for answer + * + * @param connection + * @param body + * @return + * @throws IOException + */ + private static String processPost(HttpURLConnection connection, String body) throws IOException { + + LOG.debug("Post message: {}", connection.getURL().toString()); + if (LOG.isTraceEnabled()) { + LOG.trace("Body: {} ", body); + } + + // Send the message to destination + try (OutputStream output = connection.getOutputStream()) { + output.write(body.getBytes(charset)); + } + + // Receive answer + InputStream response = null; + BufferedReader rd = null; + StringBuilder result = new StringBuilder(); + + try { + int responseCode = connection.getResponseCode(); + LOG.debug("Response code: {}", String.valueOf(responseCode)); + + if (responseCode >= 200 && responseCode < 300) { + response = connection.getInputStream(); + } else { + response = connection.getErrorStream(); + if (response == null) { + response = connection.getInputStream(); + } + } + if (response != null) { + rd = new BufferedReader(new InputStreamReader(response)); + String line; + while ((line = rd.readLine()) != null) { + result.append(line); + } + } + } catch (IOException e) { + LOG.debug("No response received: {}", e.getMessage()); + } finally { + if (response != null) { + response.close(); + } + if (rd != null) { + rd.close(); + } + } + + LOG.trace("Result: {} ", result); + return result.toString(); + } + + /** + * Read initial answer from Server after connect + * + * @param connection that was opened + * @return String with answer message + * @throws IOException + */ + private static String receiveInitialAnswer(URLConnection iConnection) throws IOException { + + + final StringBuffer response = new StringBuffer(); + + if (iConnection != null) { + + final Reader reader = new InputStreamReader(iConnection.getInputStream()); + final BufferedReader br = new BufferedReader(reader); + String line = ""; + while ((line = br.readLine()) != null) { + response.append(line); + response.append("\n"); + } + br.close(); + } + + return response.toString(); + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/config/DcaeConfig.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/config/DcaeConfig.java new file mode 100644 index 000000000..2e4d73acb --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/dcaeconnector/impl/config/DcaeConfig.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * ============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.dcaeconnector.impl.config; + +import org.onap.ccsdk.features.sdnr.wt.common.configuration.Configuration; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; + +public class DcaeConfig implements Configuration { + + private static final String SECTION_MARKER_DCAE = "dcae"; + + private static final String PROPERTY_KEY_EVENTRECEIVERURL = "dcaeUrl"; + private static final String PROPERTY_KEY_USERCREDENTIALS = "dcaeUserCredentials"; + private static final String PROPERTY_KEY_TIMERPERIOD = "dcaeHeartbeatPeriodSeconds"; + + private static final String DEFAULT_VALUE_EVENTRECEIVERURL = "off"; + private static final String DEFAULT_VALUE_USERCREDENTIALS = "admin:admin"; + private static final long DEFAULT_VALUE_TIMERPERIOD = 120; + + private final ConfigurationFileRepresentation configuration; + + public DcaeConfig(ConfigurationFileRepresentation configuration) { + this.configuration = configuration; + this.configuration.addSection(SECTION_MARKER_DCAE); + defaults(); + } + + /* *********************** + * Getter + */ + + public String getEventReveicerUrl() { + return configuration.getProperty(SECTION_MARKER_DCAE, PROPERTY_KEY_EVENTRECEIVERURL); + } + + public String getUserCredentials() { + return configuration.getProperty(SECTION_MARKER_DCAE, PROPERTY_KEY_USERCREDENTIALS); + } + + public Integer getTimerPeriodSeconds() { + long res = configuration.getPropertyLong(SECTION_MARKER_DCAE, PROPERTY_KEY_TIMERPERIOD).orElse(DEFAULT_VALUE_TIMERPERIOD); + return (int)res; + } + + + @Override + public String getSectionName() { + return SECTION_MARKER_DCAE; + } + + @Override + public void defaults() { + this.configuration.setPropertyIfNotAvailable(SECTION_MARKER_DCAE, PROPERTY_KEY_EVENTRECEIVERURL, DEFAULT_VALUE_EVENTRECEIVERURL); + this.configuration.setPropertyIfNotAvailable(SECTION_MARKER_DCAE, PROPERTY_KEY_USERCREDENTIALS, DEFAULT_VALUE_USERCREDENTIALS); + this.configuration.setPropertyIfNotAvailable(SECTION_MARKER_DCAE, PROPERTY_KEY_TIMERPERIOD, DEFAULT_VALUE_TIMERPERIOD); + } + + @Override + public String toString() { + return "DcaeConfig [getEventReveicerUrl()=" + getEventReveicerUrl() + ", getUserCredentials()=" + + getUserCredentials() + ", getTimerPeriodSeconds()=" + getTimerPeriodSeconds() + ", getSectionName()=" + + getSectionName() + "]"; + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/Checker.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/Checker.java new file mode 100644 index 000000000..1091c41eb --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/Checker.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * ============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========================================================================== + ******************************************************************************/ +/** + * (c) highstreet technologies GmbH + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.devicemonitor.impl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Steps to Monitor the connection to a network element during state connected + */ +abstract class Checker { + + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(Checker.class); + + /** + * Check action. + * @return true if reachable, false if not + */ + abstract boolean isReachableOnce(); + + /** + * Procedure to check the connection of one mountpoint + * @return true if reachable, false if not + */ + boolean isConnected() { + return isReachableOnce(); + } +} + diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/DeviceMonitor.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/DeviceMonitor.java new file mode 100644 index 000000000..86af7a275 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/DeviceMonitor.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * ============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.devicemonitor.impl; + +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.DeviceMonitoredNe; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; + +public interface DeviceMonitor extends AutoCloseable { + + /** + * Referesh database by raising all alarms again. + */ + void refreshAlarmsInDb(); + + /** + * removeMountpointIndication deregisters a mountpoint for registration services + * @param mountPointNodeName to deregister + */ + void removeMountpointIndication(String mountPointNodeName); + + /** + * Notify of device state change to "disconnected" + * Mount point supervision + * @param mountPointNodeName to deregister + */ + void deviceDisconnectIndication(String mountPointNodeName); + + /** + * Notify of device state changes to "connected" + * @param mountPointNodeName name of mount point + * @param ne to monitor + */ + void deviceConnectMasterIndication(String mountPointNodeName, DeviceMonitoredNe ne); + + /** + * Notify of device state changes to "connected" + * @param mountPointNodeName name of mount point + * @param ne to monitor + */ + void deviceConnectMasterIndication(String mountPointNodeName, NetworkElement ne); + + /** + * Notify of device state changes to "connected" for slave nodes + * @param mountPointNodeName name of mount point + */ + void deviceConnectSlaveIndication(String mountPointNodeName); + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/DeviceMonitorEmptyImpl.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/DeviceMonitorEmptyImpl.java new file mode 100644 index 000000000..039606781 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/DeviceMonitorEmptyImpl.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * ============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.devicemonitor.impl; + +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.DeviceMonitoredNe; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; + +public class DeviceMonitorEmptyImpl implements DeviceMonitor { + + @Override + public void refreshAlarmsInDb() { + } + + @Override + public void removeMountpointIndication(String mountPointNodeName) { + } + + @Override + public void deviceConnectMasterIndication(String mountPointNodeName, DeviceMonitoredNe ne) { + } + + @Override + public void deviceDisconnectIndication(String mountPointNodeName) { + } + + @Override + public void deviceConnectSlaveIndication(String mountPointNodeName) { + } + + @Override + public void close() throws Exception { + } + + @Override + public void deviceConnectMasterIndication(String mountPointNodeName, NetworkElement ne) { + } + + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/DeviceMonitorImpl.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/DeviceMonitorImpl.java new file mode 100644 index 000000000..11e86e896 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/DeviceMonitorImpl.java @@ -0,0 +1,269 @@ +/******************************************************************************* + * ============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========================================================================== + ******************************************************************************/ +/** + * (c) 2017 highstreet technologies GmbH + */ + +package org.onap.ccsdk.features.sdnr.wt.devicemanager.devicemonitor.impl; + +import java.util.Enumeration; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.filechange.IConfigChangedListener; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.devicemonitor.impl.config.DmConfig; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.handler.ODLEventListenerHandler; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.DeviceMonitoredNe; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Implementation of concept "Active monitoring" of a device.<br> + * <br> + * For each existing mountpoint a task runs with 120s cycle time. Every 120 seconds the check actions are performed. + * The request is handled by the NETCONF layer with a (default)configured time-out of 60 seconds.<br> + * Generated alarms, by the object/node "SDN-Controller" are (enum DeviceMonitorProblems):<br> + * - notConnected(InternalSeverity.Warning)<br> + * - noConnectionMediator(InternalSeverity.Minor)<br> + * - noConnectionNe(InternalSeverity.Critical)<br> + * <br> + * 1. Mountpoint does not exist<br> + * If the mountpoint does not exists there are no related current alarms in the database.<br> + * <br> + * 2. Created mountpoint with state "Connecting" or "UnableToConnect"<br> + * If the Mountpoint is created and connection status is "Connecting" or "UnableToConnect".<br> + * - After about 2..4 Minutes ... raise alarm "notConnected" with severity warning<br> + * <br> + * 3. Created mountpoint with state "Connection"<br> + * There are two monitor activities.<br> + * 3a. Check of Mediator connection by requesting (typical) cached data.<br> + * - After about 60 seconds raise alarm: connection-loss-mediator with severity minor<br> + * - Request from Mediator: network-element<br> + * <br> + * 3b. Check connection to NEby requesting (typical) non-cached data.<br> + * - Only if AirInterface available. The first one is used.<br> + * - Requested are the currentAlarms<br> + * - After about 60 seconds raise alarm: connection-loss-network-element with severity critical<br> + * <br> + * @author herbert + */ + +public class DeviceMonitorImpl implements DeviceMonitor, IConfigChangedListener { + + private static final Logger LOG = LoggerFactory.getLogger(DeviceMonitorImpl.class); + + private final ConcurrentHashMap<String, DeviceMonitorTask> queue; + private final ScheduledExecutorService scheduler; + private final ODLEventListenerHandler odlEventListener; + @SuppressWarnings("unused") + private final DataBroker dataBroker; //Future usage + private final DmConfig dmConfig; + private final DeviceMonitoredNe dummyNe; + + /*------------------------------------------------------------- + * Construction/ destruction of service + */ + + /** + * Basic implementation of devicemonitoring + * @param odlEventListener as destination for problems + */ + public DeviceMonitorImpl(DataBroker dataBroker, ODLEventListenerHandler odlEventListener, ConfigurationFileRepresentation htconfig) { + LOG.info("Construct {}", this.getClass().getSimpleName()); + + this.odlEventListener = odlEventListener; + this.dataBroker = dataBroker; + this.dummyNe = getDummyNe(); + + htconfig.registerConfigChangedListener(this); + this.dmConfig = new DmConfig(htconfig); + setDmConfig(dmConfig); + + this.queue = new ConcurrentHashMap<>(); + this.scheduler = Executors.newScheduledThreadPool(10); + } + + /** + * Stop the service. Stop all running monitoring tasks. + */ + @Override + synchronized public void close() { + LOG.info("Close {}", this.getClass().getSimpleName()); + + Enumeration<String> e = queue.keys(); + while (e.hasMoreElements()) { + deviceDisconnectIndication(e.nextElement()); + } + + scheduler.shutdown(); + } + + @Override + public void onConfigChanged() { + setDmConfig(dmConfig); + } + + private void setDmConfig(DmConfig dmConfig) { + for (DeviceMonitorProblems problem : DeviceMonitorProblems.values()) { + problem.setSeverity(dmConfig.getSeverity(problem)); + } + } + + /*------------------------------------------------------------- + * Start/ stop/ update service for Mountpoint + */ + + /** + * Notify of device state changes to "connected" for slave nodes + * @param mountPointNodeName name of mount point + */ + @Override + synchronized public void deviceConnectSlaveIndication(String mountPointNodeName) { + deviceConnectMasterIndication(mountPointNodeName, (DeviceMonitoredNe)null); + } + + @Override + public void deviceConnectMasterIndication(String mountPointNodeName, NetworkElement networkElement) { + Optional<DeviceMonitoredNe> monitoredNe = networkElement.getService(DeviceMonitoredNe.class); + deviceConnectMasterIndication(mountPointNodeName, monitoredNe.isPresent() ? monitoredNe.get() : dummyNe); + } + + /** + * Notify of device state changes to "connected" + * @param mountPointNodeName name of mount point + * @param ne to monitor + */ + @Override + synchronized public void deviceConnectMasterIndication(String mountPointNodeName, DeviceMonitoredNe ne) { + + LOG.debug("ne changes to connected state {}",mountPointNodeName); + createMonitoringTask(mountPointNodeName); + if (queue.containsKey(mountPointNodeName)) { + DeviceMonitorTask task = queue.get(mountPointNodeName); + task.deviceConnectIndication(ne); + } else { + LOG.warn("Monitoring task not in queue: {} {} {}", mountPointNodeName, mountPointNodeName.hashCode(), queue.size()); + } + } + + /** + * Notify of device state change to "disconnected" + * Mount point supervision + * @param mountPointNodeName to deregister + */ + @Override + synchronized public void deviceDisconnectIndication(String mountPointNodeName) { + + LOG.debug("State changes to not connected state {}",mountPointNodeName); + createMonitoringTask(mountPointNodeName); + if (queue.containsKey(mountPointNodeName)) { + DeviceMonitorTask task = queue.get(mountPointNodeName); + task.deviceDisconnectIndication(); + } else { + LOG.warn("Monitoring task not in queue: {} {} {}", mountPointNodeName, mountPointNodeName.hashCode(), queue.size()); + } + } + + /** + * removeMountpointIndication deregisters a mountpoint for registration services + * @param mountPointNodeName to deregister + */ + @Override + synchronized public void removeMountpointIndication(String mountPointNodeName) { + + if (queue.containsKey(mountPointNodeName)) { + DeviceMonitorTask task = queue.get(mountPointNodeName); + //Remove from here + queue.remove(mountPointNodeName); + //Clear all problems + task.removeMountpointIndication(); + LOG.debug("Task stopped: {}", mountPointNodeName); + } else { + LOG.warn("Task not in queue: {}", mountPointNodeName); + } + } + + /** + * Referesh database by raising all alarms again. + */ + @Override + public void refreshAlarmsInDb() { + synchronized(queue) { + for (DeviceMonitorTask task : queue.values()) { + task.refreshAlarms(); + } + } + } + + /*------------------------------------------------------------- + * Private functions + */ + + /** + * createMountpoint registers a new mountpoint monitoring service + * @param mountPointNodeName name of mountpoint + */ + synchronized private DeviceMonitorTask createMonitoringTask(String mountPointNodeName) { + + DeviceMonitorTask task; + LOG.debug("Register for monitoring {} {}",mountPointNodeName, mountPointNodeName.hashCode()); + + if (queue.containsKey(mountPointNodeName)) { + LOG.info("Monitoring task exists"); + task = queue.get(mountPointNodeName); + } else { + LOG.info("Do start of DeviceMonitor task"); + //Runnable task = new PerformanceManagerTask(queue, databaseService); + task = new DeviceMonitorTask(mountPointNodeName, this.odlEventListener); + queue.put(mountPointNodeName, task); + task.start(scheduler); + } + return task; + } + + + private static DeviceMonitoredNe getDummyNe() { + return new DeviceMonitoredNe() { + + @Override + public void prepareCheck() { + // Do nothing + } + + @Override + public boolean checkIfConnectionToMediatorIsOk() { + return true; + } + + @Override + public boolean checkIfConnectionToNeIsOk() { + return true; + } + + @Override + public Optional<NetconfAccessor> getAcessor() { + return Optional.empty(); + } + }; + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/DeviceMonitorProblems.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/DeviceMonitorProblems.java new file mode 100644 index 000000000..1282a41f8 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/DeviceMonitorProblems.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * ============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========================================================================== + ******************************************************************************/ +/** + * Problems generated by DeviceMonitor + * + * @author herbert + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.devicemonitor.impl; + +import org.eclipse.jdt.annotation.Nullable; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.util.InternalSeverity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public enum DeviceMonitorProblems { + + /** + * Mountpoint is not connected via NETCONF with NE/Mediator = ssh connection + */ + connectionLossOAM(InternalSeverity.Major), + + /** + * Mountpoint is connected via Netconf to Mediator, but mediator is not responding. + * Connection state to NE is unknown. + */ + connectionLossMediator(InternalSeverity.Major), + + /** Mountpoint is connected via Netconf to Mediator. + * This connection is OK, but mediator <-> NE Connection is not OK + */ + connectionLossNeOAM(InternalSeverity.Major); + + private static final Logger LOG = LoggerFactory.getLogger(DeviceMonitorProblems.class); + private InternalSeverity severity; + + DeviceMonitorProblems(@Nullable InternalSeverity severity) { + if (severity != null) { + this.severity = severity; + } + } + + public InternalSeverity getSeverity() { + return severity; + } + + public void setSeverity(InternalSeverity severity) { + LOG.info("Change severity for {} from {} to {}", name(), this.severity, severity); + this.severity=severity; + } + +} + diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/DeviceMonitorTask.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/DeviceMonitorTask.java new file mode 100644 index 000000000..fc7af5a92 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/DeviceMonitorTask.java @@ -0,0 +1,321 @@ +/******************************************************************************* + * ============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========================================================================== + ******************************************************************************/ +/** + * @author herbert + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.devicemonitor.impl; + +import java.util.Collections; +import java.util.EnumSet; +import java.util.Set; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.NetconfTimeStamp; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.handler.ODLEventListenerHandler; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.util.InternalSeverity; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.DeviceMonitoredNe; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DeviceMonitorTask implements Runnable { + + private static final Logger LOG = LoggerFactory.getLogger(DeviceMonitorTask.class); + private static final String LOGMARKER = "DMTick"; + private static final NetconfTimeStamp NETCONFTIME_CONVERTER = NetconfTimeStampImpl.getConverter(); + + private final String mountPointName; + private final ODLEventListenerHandler odlEventListener; + private final Checker checkConnectionToMediator; + private final Checker checkConnectionToNe; + + private int tickCounter; //Added for each tick. Not relevant for internal status + + private ScheduledFuture<?> taskHandle; + private final Object lockNe = new Object(); //USe top lock access to member ne + private @Nullable DeviceMonitoredNe ne; //Indication if in status connect or disconnect + private @NonNull Boolean mountpointConnectingStateSupervision; //Indication of mountpoint supervision + + private final Object lockDisconnectSupervisionTickout = new Object(); + private Integer disconnectSupervisionTickout; //Tickcounter of task ticks for "not connected indication" + private Set<DeviceMonitorProblems> currentProblems; //List with actual problems. Synchronized by itself + + /*------------------------------------------------------------ + * Construction + */ + + /** + * Setup monitoring task + * @param mountPointName to monitor + * @param odlEventListener to forward problems to + */ + public DeviceMonitorTask(String mountPointName, ODLEventListenerHandler odlEventListener) { + LOG.debug("Init task {}", DeviceMonitorTask.class.getSimpleName()); + + //Setup finals + this.mountPointName = mountPointName; + this.odlEventListener = odlEventListener; + this.checkConnectionToMediator = new Checker() { + @Override + boolean isReachableOnce() { + synchronized(lockNe) { + //mountpoint state "Connected" + //If for any reason the mountpoint is Connected, but Notconf messages are not received + return ne == null ? true : ne.checkIfConnectionToMediatorIsOk(); + } + } + }; + this.checkConnectionToNe = new Checker() { + @Override + boolean isReachableOnce() { + synchronized(lockNe) { + //mountpoint state "Connected" + //If netconf mediator (netconf application software for NE) has connection loss to managed device. + //The networkelement object is available, but there is no interfacepack available. + return ne == null ? true : ne.checkIfConnectionToNeIsOk(); + } + } + }; + + //Setup parameters + this.taskHandle = null; + this.tickCounter = 0; + this.ne = null; + this.mountpointConnectingStateSupervision = false; + this.currentProblems = Collections.synchronizedSet(EnumSet.noneOf(DeviceMonitorProblems.class)); + this.disconnectSupervisionTickout = 0; + + int removed = odlEventListener.removeAllCurrentProblemsOfNode(mountPointName); + LOG.debug("{} Init task removed fault entries {}", LOGMARKER, removed); + + } + + /** + * Start for each object an own instance of the thread. + * @param scheduler for all the threads. + */ + public void start(ScheduledExecutorService scheduler) { + LOG.info("{} {} DeviceMonitor task to create", LOGMARKER, tickCounter); + if (taskHandle == null) { + startDisconnectSupervision(); + taskHandle = scheduler.scheduleAtFixedRate(this, 0, 120, TimeUnit.SECONDS); + LOG.info("DeviceMonitor task scheduled"); + } else { + LOG.error("{} {} Task already running.", LOGMARKER, tickCounter); + } + } + + /** + * Call after NE change state to connected. + * Mountpoint exists. Status is Connecting. + * @param neParam that connected + */ + + public void deviceConnectIndication(DeviceMonitoredNe neParam) { + LOG.info("{} {} Connect {} and stop.", LOGMARKER, tickCounter, mountPointName); + clear(DeviceMonitorProblems.connectionLossOAM); + synchronized(lockNe) { + this.ne = neParam; + this.mountpointConnectingStateSupervision = false; + } + stopDisconnectSupervision(); + } + + /** + * If ne is disconnected do the related actions. + * - Mountpoint exists. Status is Connecting or UnableToConnect + */ + + public void deviceDisconnectIndication() { + LOG.info("{} {} Disconnect {} and start.", LOGMARKER, tickCounter, mountPointName); + clear(DeviceMonitorProblems.connectionLossOAM); + synchronized(lockNe) { + this.ne = null; + this.mountpointConnectingStateSupervision = true; + } + startDisconnectSupervision(); + } + + /** + * Do all actions to clean up the log if mountpoint has been deleted. + * - Mountpoint removed + * Prepare cancellation of the task and cancel task + */ + + public void removeMountpointIndication() { + for (DeviceMonitorProblems problem : DeviceMonitorProblems.values()) { + clear(problem); + } + //Cancel the task + if (this.taskHandle != null) { + this.taskHandle.cancel(false); + LOG.info("{} {} DeviceMonitor task canceled for {}", LOGMARKER, tickCounter, mountPointName); + } else { + LOG.error("{} {} Task already stopped", LOGMARKER, tickCounter); + } + } + + /** + * Referesh Alarms + */ + public void refreshAlarms() { + LOG.debug("{} Start refresh of all problems",LOGMARKER); + synchronized(currentProblems) { + for (DeviceMonitorProblems problem : currentProblems) { + LOG.debug("{} Refresh problem {} Raised-status {}",LOGMARKER, problem.name(), currentProblems.contains(problem)); + odlEventListener.onProblemNotification(mountPointName, problem.name(), problem.getSeverity()); + } + } + LOG.debug("{} Finish refresh of all problems",LOGMARKER); + } + + /*------------------------------------------------------------ + * Functions to clear/raise alarm + */ + + /** + * Raise a problem, but only once + * @param problem + */ + private void raise(DeviceMonitorProblems problem) { + LOG.debug("{} Raise problem {} Raised-status {}",LOGMARKER, problem.name(), currentProblems.contains(problem)); + synchronized(currentProblems) { + if (! currentProblems.contains(problem)) { + currentProblems.add(problem); + odlEventListener.onProblemNotification(mountPointName, problem.name(), problem.getSeverity()); + } + } + } + + /** + * Raise a problem, but only once + * @param problem + */ + private void clear(DeviceMonitorProblems problem) { + LOG.debug("{} Clear problem {} Raised-status {}",LOGMARKER, problem.name(), currentProblems.contains(problem)); + synchronized(currentProblems) { + if (currentProblems.contains(problem)) { + currentProblems.remove(problem); + odlEventListener.onProblemNotification(mountPointName, problem.name(), InternalSeverity.NonAlarmed); + } + } + } + + /** + * Process problem notification cascade + * @param isReachable + * @param problem + */ + private void clearRaiseIfConnected(Checker checker, DeviceMonitorProblems problem) { + LOG.debug("{} check start {} problem {} Raised-status {}",LOGMARKER, tickCounter, problem.name(), currentProblems.contains(problem)); + if (checker.isConnected()) { + clear(problem); + } else { + raise(problem); + } + LOG.debug("{} check end {} problem {} Raised-status {}",LOGMARKER, tickCounter, problem.name(), currentProblems.contains(problem)); + } + + /*------------------------------------------------------------ + * Functions to start/stop + */ + + private void startDisconnectSupervision() { + synchronized(lockDisconnectSupervisionTickout) { + this.disconnectSupervisionTickout = 2; + } + } + + private void stopDisconnectSupervision() { + synchronized(lockDisconnectSupervisionTickout) { + this.disconnectSupervisionTickout = 0; + } + } + + private boolean processDisconnectSupervisionAndCheckExceeded() { + synchronized(lockDisconnectSupervisionTickout) { + if (disconnectSupervisionTickout == 0) { + return true; + } else if (disconnectSupervisionTickout > 0) { + disconnectSupervisionTickout--; + } + return false; + } + } + + /*------------------------------------------------------------ + * TASK + */ + + /** + * Task to monitor connectivity to Network Elements. + * Connectivity problems lead to alarm indication. + */ + @Override + public void run() { + + try { + LOG.debug("{} UTCTime {} START mountpoint {} tick {} connecting supervision {} tickout {}", + LOGMARKER, + NETCONFTIME_CONVERTER.getTimeStamp(), + mountPointName, + tickCounter, + mountpointConnectingStateSupervision, + disconnectSupervisionTickout); + + if (mountpointConnectingStateSupervision) { + LOG.debug("{} {} Mountpoint supervision {}", LOGMARKER, tickCounter, mountPointName); + if (processDisconnectSupervisionAndCheckExceeded()) { + raise(DeviceMonitorProblems.connectionLossOAM); + } + + } else { + synchronized (lockNe) { + if (ne != null) { + //checks during "Connected" + clear(DeviceMonitorProblems.connectionLossOAM); //Always cleared never raised + LOG.debug("{} {} Prepare check", LOGMARKER, tickCounter); + ne.prepareCheck(); // Prepare ne check + // Mediator check + LOG.debug("{} {} Mediator check", LOGMARKER, tickCounter); + clearRaiseIfConnected(checkConnectionToMediator, DeviceMonitorProblems.connectionLossMediator); + + // NE check + LOG.debug("{} {} Ne check", LOGMARKER, tickCounter); + clearRaiseIfConnected(checkConnectionToNe, DeviceMonitorProblems.connectionLossNeOAM); + } else { + //Monitor switch off. + LOG.debug("{} {} Monitor switch off state", LOGMARKER, tickCounter); + clear(DeviceMonitorProblems.connectionLossOAM); //Always cleared never raised + clear(DeviceMonitorProblems.connectionLossMediator); //Always cleared never raised + clear(DeviceMonitorProblems.connectionLossNeOAM); //Always cleared never raised + } + } + } + } catch (Exception e) { + //Prevent stopping the task + LOG.warn("{} {} During DeviceMontoring task",LOGMARKER, tickCounter, e); + } + LOG.debug("{} {} END", LOGMARKER, tickCounter++); + + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/config/DmConfig.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/config/DmConfig.java new file mode 100644 index 000000000..215d8272d --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/devicemonitor/impl/config/DmConfig.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * ============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.devicemonitor.impl.config; + +import org.onap.ccsdk.features.sdnr.wt.common.configuration.Configuration; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.devicemonitor.impl.DeviceMonitorProblems; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.util.InternalSeverity; + +/** + * Configuration of devicemonitor, section [devicemonitor] + * SeverityConnectionlossNeOAM=minor + * SeverityConnectionlossOAM=major + * SeverityConnectionlossMediator=critical + */ +public class DmConfig implements Configuration { + + private static final String SECTION_MARKER_TA = "devicemonitor"; + + private static final String PROPERTY_KEY_PREFIX_Severity = "Severity"; + + private final ConfigurationFileRepresentation configuration; + + public DmConfig(ConfigurationFileRepresentation configuration) { + this.configuration = configuration; + this.configuration.addSection(SECTION_MARKER_TA); + defaults(); + } + + public InternalSeverity getSeverity(DeviceMonitorProblems problem) { + String severityString = configuration.getProperty(SECTION_MARKER_TA, getPropertyName(problem)); + InternalSeverity result = InternalSeverity.valueOfString(severityString); + return result != null ? result : InternalSeverity.Major; + } + + @Override + public String getSectionName() { + return SECTION_MARKER_TA; + } + + @Override + public void defaults() { + for (DeviceMonitorProblems problem : DeviceMonitorProblems.values()) { + configuration.setPropertyIfNotAvailable(SECTION_MARKER_TA, getPropertyName(problem), problem.getSeverity().name()); + } + } + + private String getPropertyName(DeviceMonitorProblems problem) { + return PROPERTY_KEY_PREFIX_Severity+problem.name(); + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/housekeeping/ConnectionStatusHousekeepingService.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/housekeeping/ConnectionStatusHousekeepingService.java new file mode 100644 index 000000000..1628fba1b --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/housekeeping/ConnectionStatusHousekeepingService.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * ============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.housekeeping; + +import com.google.common.util.concurrent.FluentFuture; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import org.eclipse.jdt.annotation.NonNull; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.InternalConnectionStatus; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService; +import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ConnectionLogStatus; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.NetworkElementConnectionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.NetworkElementConnectionEntity; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ConnectionStatusHousekeepingService implements ClusterSingletonService,AutoCloseable { + + private static final Logger LOG = LoggerFactory.getLogger(ConnectionStatusHousekeepingService.class); + + private static final long INTERVAL_SECONDS = 30; + private static final InstanceIdentifier<Topology> NETCONF_TOPO_IID = InstanceIdentifier + .create(NetworkTopology.class) + .child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName()))); + private static final ServiceGroupIdentifier IDENT = ServiceGroupIdentifier.create("ConnectionStatusHousekeepingService"); + + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(3); + private final DataBroker dataBroker; + private final DataProvider dataProvider; + private boolean isMaster; + private Future<?> taskReference; + + private final Runnable runner = () -> doClean(); + + public ConnectionStatusHousekeepingService(DataBroker dataBroker, DataProvider dataProvider) { + this.dataBroker = dataBroker; + this.dataProvider = dataProvider; + this.start(); + } + + public void start() { + if (taskReference != null) { + taskReference.cancel(false); + } + if(!isMaster) { + LOG.info("do not start. not the master node"); + return; + } + LOG.info("starting scheduler with interval {}", INTERVAL_SECONDS); + this.taskReference = this.scheduler.scheduleAtFixedRate(runner, INTERVAL_SECONDS, INTERVAL_SECONDS, + TimeUnit.SECONDS); + } + + private void doClean() { + LOG.debug("start housekeeping"); + // get all devices from networkelement-connection index + try { + List<NetworkElementConnectionEntity> list = this.dataProvider.getNetworkElementConnections(); + + ConnectionLogStatus dbStatus; + ConnectionLogStatus mdsalStatus; + String nodeId; + if (list == null || list.size() <= 0) { + LOG.trace("no items in list."); + return; + } + for (NetworkElementConnectionEntity item : list) { + + // compare with MD-SAL + nodeId = item.getNodeId(); + LOG.trace("check status of {}", nodeId); + dbStatus = item.getStatus(); + mdsalStatus = this.getMDSalConnectionStatus(nodeId); + if (mdsalStatus == null) { + LOG.trace("unable to get connection status. jump over"); + continue; + } + // if different then update db + if (dbStatus != mdsalStatus) { + LOG.trace("status is inconsistent db={}, mdsal={}. updating db", dbStatus, mdsalStatus); + if(!item.isIsRequired() && mdsalStatus==ConnectionLogStatus.Disconnected) { + this.dataProvider.removeNetworkConnection(nodeId); + } + else { + this.dataProvider.updateNetworkConnectionDeviceType( + new NetworkElementConnectionBuilder().setStatus(mdsalStatus).build(), nodeId); + } + } else { + LOG.trace("no difference"); + } + + } + } catch (Exception e) { + LOG.warn("problem executing housekeeping task: {}", e); + } + LOG.debug("finish housekeeping"); + } + + private ConnectionLogStatus getMDSalConnectionStatus(String nodeId) { + + @SuppressWarnings("null") + @NonNull InstanceIdentifier<Node> instanceIdentifier = NETCONF_TOPO_IID.child(Node.class, + new NodeKey(new NodeId(nodeId))); + FluentFuture<Optional<Node>> optionalNode = this.dataBroker.newReadOnlyTransaction() + .read(LogicalDatastoreType.OPERATIONAL, instanceIdentifier); + try { + Node node = optionalNode.get(5, TimeUnit.SECONDS).get(); + LOG.debug("node is {}", node); + NetconfNode nNode = node.augmentation(NetconfNode.class); + LOG.debug("nnode is {}", nNode); + if (nNode != null) { + return InternalConnectionStatus.statusFromNodeStatus(nNode.getConnectionStatus()); + } + } catch (NoSuchElementException e) { + return ConnectionLogStatus.Disconnected; + } catch (ExecutionException | InterruptedException | TimeoutException e) { + LOG.warn("unable to get node info: {}", e); + } + + return null; + } + + @Override + public void close() throws Exception { + if (taskReference != null) { + taskReference.cancel(false); + } + this.scheduler.shutdown(); + } + + @SuppressWarnings("null") + @Override + public @NonNull ServiceGroupIdentifier getIdentifier() { + return IDENT; + } + + @Override + public void instantiateServiceInstance() { + LOG.info("We take Leadership"); + this.isMaster=true; + this.start(); + } + + @Override + public ListenableFuture<? extends Object> closeServiceInstance() { + LOG.info("We lost Leadership"); + this.isMaster=false; + this.start(); + return Futures.immediateFuture(null); + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/housekeeping/ResyncNetworkElementHouskeepingService.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/housekeeping/ResyncNetworkElementHouskeepingService.java new file mode 100644 index 000000000..73a3e7c24 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/housekeeping/ResyncNetworkElementHouskeepingService.java @@ -0,0 +1,168 @@ +/******************************************************************************* + * ============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.housekeeping; + +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.devicemonitor.impl.DeviceMonitor; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.DeviceManagerImpl; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.handler.ODLEventListenerHandler; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; +import org.opendaylight.mdsal.binding.api.MountPoint; +import org.opendaylight.mdsal.binding.api.MountPointService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ResyncNetworkElementHouskeepingService implements ResyncNetworkElementsListener { + + private static final Logger LOG = LoggerFactory.getLogger(ResyncNetworkElementHouskeepingService.class); + + private static final InstanceIdentifier<Topology> NETCONF_TOPO_IID = + InstanceIdentifier.create(NetworkTopology.class).child(Topology.class, + new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName()))); + + // Services to use + private final MountPointService mountPointService; + private final ODLEventListenerHandler odlEventListenerHandler; + private final DataProvider databaseClientEvents; + private @Nullable final DeviceMonitor deviceMonitor; + private final DeviceManagerImpl deviceManager; + + /** Thread is started to du the clean up action **/ + private Thread threadDoClearCurrentFaultByNodename; + /** Indicate number of refresh activities for log **/ + private int refreshCounter = 0; + + /** + * @param deviceManager to provide devices information + * @param mountPointService service + * @param odlEventListenerHandler handler for events + * @param databaseClientEvents database to clean + * @param deviceMonitor devicemonitor + */ + public ResyncNetworkElementHouskeepingService( + DeviceManagerImpl deviceManager, + MountPointService mountPointService, ODLEventListenerHandler odlEventListenerHandler, + DataProvider databaseClientEvents, DeviceMonitor deviceMonitor) { + super(); + this.deviceManager = deviceManager; + this.mountPointService = mountPointService; + this.odlEventListenerHandler = odlEventListenerHandler; + this.databaseClientEvents = databaseClientEvents; + this.deviceMonitor = deviceMonitor; + } + + /** + * Async RPC Interface implementation + */ + @Override + public @NonNull List<String> doClearCurrentFaultByNodename(@Nullable List<String> nodeNamesInput) + throws IllegalStateException { + + if (this.databaseClientEvents == null) { + throw new IllegalStateException("dbEvents service not instantiated"); + } + + if (threadDoClearCurrentFaultByNodename != null && threadDoClearCurrentFaultByNodename.isAlive()) { + throw new IllegalStateException("A clear task is already active"); + } else { + + // Create list of mountpoints if input is empty, using the content in ES + if (nodeNamesInput == null || nodeNamesInput.size() <= 0) { + nodeNamesInput = this.databaseClientEvents.getAllNodesWithCurrentAlarms(); + } + + // Filter all mountpoints from input that were found and are known to this Cluster-node instance of + // DeviceManager + final List<String> nodeNamesHandled = new ArrayList<>(); + for (String mountpointName : nodeNamesInput) { + LOG.info("Work with mountpoint {}", mountpointName); + + if (odlEventListenerHandler != null && mountpointName.equals(odlEventListenerHandler.getOwnKeyName())) { + + // SDN Controller related alarms + // -- can not be recreated on all nodes in connected state + // -- would result in a DCAE/AAI Notification + // Conclusion for 1810 Delivery ... not covered by RPC function (See issue #43) + LOG.info("Ignore SDN Controller related alarms for {}", mountpointName); + // this.databaseClientEvents.clearFaultsCurrentOfNode(mountpointName); + // nodeNamesHandled.add(mountpointName); + + } else { + + if (mountPointService != null) { + InstanceIdentifier<Node> instanceIdentifier = + NETCONF_TOPO_IID.child(Node.class, new NodeKey(new NodeId(mountpointName))); + Optional<MountPoint> optionalMountPoint = mountPointService.getMountPoint(instanceIdentifier); + + if (!optionalMountPoint.isPresent()) { + LOG.info("Remove Alarms for unknown mountpoint {}", mountpointName); + this.databaseClientEvents.clearFaultsCurrentOfNode(mountpointName); + nodeNamesHandled.add(mountpointName); + } else { + if (deviceManager.getNeByMountpoint(mountpointName) != null) { + LOG.info("At node known mountpoint {}", mountpointName); + nodeNamesHandled.add(mountpointName); + } else { + LOG.info("At node unknown mountpoint {}", mountpointName); + } + } + } + } + } + + // Force a sync + deviceMonitor.refreshAlarmsInDb(); + + threadDoClearCurrentFaultByNodename = new Thread(() -> { + refreshCounter++; + LOG.info("Start refresh mountpoint task {}", refreshCounter); + // for(String nodeName:nodeNamesOutput) { + for (String nodeName : nodeNamesHandled) { + NetworkElement ne = deviceManager.getNeByMountpoint(nodeName); + if (ne != null) { + LOG.info("Refresh mountpoint {}", nodeName); + ne.warmstart(); + } else { + LOG.info("Unhandled mountpoint {}", nodeName); + } + } + LOG.info("End refresh mountpoint task {}", refreshCounter); + }); + threadDoClearCurrentFaultByNodename.start(); + return nodeNamesHandled; + } + }; + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/housekeeping/ResyncNetworkElementsListener.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/housekeeping/ResyncNetworkElementsListener.java new file mode 100644 index 000000000..751d48cda --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/housekeeping/ResyncNetworkElementsListener.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * ============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.housekeeping; + +import java.util.List; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; + + +public interface ResyncNetworkElementsListener +{ + /** + * Handle API Request and clean up current alarms according to the list of mountpoint id's/devices + * Implement RPC function "clear-current-fault-by-nodename" + * @return List with + * @throws IllegalStateException Illegal state exception + */ + public @NonNull List<String> doClearCurrentFaultByNodename(@Nullable List<String> nodeNamesInput) throws IllegalStateException; + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/DeviceManagerApiServiceImpl.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/DeviceManagerApiServiceImpl.java new file mode 100644 index 000000000..9a2b81cbb --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/DeviceManagerApiServiceImpl.java @@ -0,0 +1,239 @@ +/******************************************************************************* + * ============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.impl; + +import java.util.List; +import org.eclipse.jdt.annotation.Nullable; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.housekeeping.ResyncNetworkElementsListener; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.maintenance.MaintenanceRPCServiceAPI; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.maintenance.impl.MaintenanceServiceImpl; +import org.opendaylight.mdsal.binding.api.RpcProviderService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.ClearCurrentFaultByNodenameInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.ClearCurrentFaultByNodenameOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.ClearCurrentFaultByNodenameOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.DevicemanagerService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.GetMaintenanceModeInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.GetMaintenanceModeOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.GetMaintenanceModeOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.GetRequiredNetworkElementKeysInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.GetRequiredNetworkElementKeysOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.GetRequiredNetworkElementKeysOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.PushAttributeChangeNotificationInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.PushAttributeChangeNotificationOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.PushFaultNotificationInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.PushFaultNotificationOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.SetMaintenanceModeInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.SetMaintenanceModeOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.SetMaintenanceModeOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.ShowRequiredNetworkElementInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.ShowRequiredNetworkElementOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.ShowRequiredNetworkElementOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.TestMaintenanceModeInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.TestMaintenanceModeOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.TestMaintenanceModeOutputBuilder; +import org.opendaylight.yangtools.concepts.ObjectRegistration; +import org.opendaylight.yangtools.yang.common.RpcError.ErrorType; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.util.concurrent.ListenableFuture; + +public class DeviceManagerApiServiceImpl implements DevicemanagerService, AutoCloseable { + + private static final Logger LOG = LoggerFactory.getLogger(DevicemanagerService.class); + + private final ObjectRegistration<DevicemanagerService> rpcReg; + private @Nullable + final MaintenanceRPCServiceAPI maintenanceService; + private @Nullable + final PushNotifications pushNotificationsListener; + private @Nullable + final ResyncNetworkElementsListener resyncCallbackListener; + + DeviceManagerApiServiceImpl(final RpcProviderService rpcProviderRegistry, + MaintenanceServiceImpl maintenanceService, ResyncNetworkElementsListener listener, + PushNotifications pushNotificationsListener) { + this.maintenanceService = maintenanceService; + this.pushNotificationsListener = pushNotificationsListener; + this.resyncCallbackListener = listener; + + // Register ourselves as the REST API RPC implementation + LOG.info("Register RPC Service "+DevicemanagerService.class.getSimpleName()); + this.rpcReg = rpcProviderRegistry.registerRpcImplementation(DevicemanagerService.class, this); + } + + @Override + public void close() throws Exception { + LOG.info("Close RPC Service"); + if (rpcReg != null) { + rpcReg.close(); + } + } + + /*------------------------------- + * Interfaces for MaintenanceService + */ + + @Override + public ListenableFuture<RpcResult<GetRequiredNetworkElementKeysOutput>> getRequiredNetworkElementKeys( + GetRequiredNetworkElementKeysInput input) { + return getRequiredNetworkElementKeys(); + } + + // For casablanca version no input was generated. + public ListenableFuture<RpcResult<GetRequiredNetworkElementKeysOutput>> getRequiredNetworkElementKeys() { + + LOG.info("RPC Request: getRequiredNetworkElementKeys"); + RpcResultBuilder<GetRequiredNetworkElementKeysOutput> result; + try { + GetRequiredNetworkElementKeysOutputBuilder outputBuilder = maintenanceService.getRequiredNetworkElementKeys(); + result = RpcResultBuilder.success(outputBuilder); + } catch (Exception e) { + result = RpcResultBuilder.failed(); + result.withError(ErrorType.APPLICATION, "Exception", e); + } + return result.buildFuture(); + } + + @Override + public ListenableFuture<RpcResult<ShowRequiredNetworkElementOutput>> showRequiredNetworkElement( + ShowRequiredNetworkElementInput input) { + + LOG.info("RPC Request: showRequiredNetworkElement input: {}", input.getMountpointName()); + RpcResultBuilder<ShowRequiredNetworkElementOutput> result; + + try { + ShowRequiredNetworkElementOutputBuilder outputBuilder = maintenanceService.showRequiredNetworkElement(input); + result = RpcResultBuilder.success(outputBuilder); + } catch (Exception e) { + result = RpcResultBuilder.failed(); + result.withError(ErrorType.APPLICATION, "Exception", e); + } + return result.buildFuture(); + } + + @Override + public ListenableFuture<RpcResult<SetMaintenanceModeOutput>> setMaintenanceMode(SetMaintenanceModeInput input) { + + LOG.info("RPC Request: setMaintenanceMode input: {}", input.getNodeId()); + RpcResultBuilder<SetMaintenanceModeOutput> result; + + try { + SetMaintenanceModeOutputBuilder outputBuilder = maintenanceService.setMaintenanceMode(input); + result = RpcResultBuilder.success(outputBuilder); + } catch (Exception e) { + result = RpcResultBuilder.failed(); + result.withError(ErrorType.APPLICATION, "Exception", e); + } + return result.buildFuture(); + + } + + + + @Override + public ListenableFuture<RpcResult<GetMaintenanceModeOutput>> getMaintenanceMode(GetMaintenanceModeInput input) { + + LOG.info("RPC Request: getMaintenanceMode input: {}", input.getMountpointName()); + RpcResultBuilder<GetMaintenanceModeOutput> result; + + try { + GetMaintenanceModeOutputBuilder outputBuilder = maintenanceService.getMaintenanceMode(input); + result = RpcResultBuilder.success(outputBuilder); + } catch (Exception e) { + result = RpcResultBuilder.failed(); + result.withError(ErrorType.APPLICATION, "Exception", e); + } + return result.buildFuture(); + + } + + @Override + public ListenableFuture<RpcResult<TestMaintenanceModeOutput>> testMaintenanceMode(TestMaintenanceModeInput input) { + LOG.info("RPC Request: getMaintenanceMode input: {}", input.getMountpointName()); + RpcResultBuilder<TestMaintenanceModeOutput> result; + + try { + TestMaintenanceModeOutputBuilder outputBuilder = maintenanceService.testMaintenanceMode(input); + result = RpcResultBuilder.success(outputBuilder); + } catch (Exception e) { + result = RpcResultBuilder.failed(); + result.withError(ErrorType.APPLICATION, "Exception", e); + } + return result.buildFuture(); + + } + + + @Override + public ListenableFuture<RpcResult<ClearCurrentFaultByNodenameOutput>> clearCurrentFaultByNodename( + ClearCurrentFaultByNodenameInput input) { + LOG.info("RPC Request: clearNetworkElementAlarms input: {}", input.getNodenames()); + RpcResultBuilder<ClearCurrentFaultByNodenameOutput> result; + try { + if(this.resyncCallbackListener!=null) { + List<String> nodeNames= this.resyncCallbackListener.doClearCurrentFaultByNodename(input.getNodenames()); + ClearCurrentFaultByNodenameOutputBuilder outputBuilder = new ClearCurrentFaultByNodenameOutputBuilder(); + outputBuilder.setNodenames(nodeNames); + result = RpcResultBuilder.success(outputBuilder); + } else { + result = RpcResultBuilder.failed(); + result.withError(ErrorType.APPLICATION, "Startup running" ); + } + } catch(Exception e) { + result = RpcResultBuilder.failed(); + result.withError(ErrorType.APPLICATION, "Exception", e); + } + return result.buildFuture(); + } + + @Override + public ListenableFuture<RpcResult<PushFaultNotificationOutput>> pushFaultNotification( + PushFaultNotificationInput input) { + LOG.info("RPC Received fault notification {}", input); + RpcResultBuilder<PushFaultNotificationOutput> result; + try { + pushNotificationsListener.pushFaultNotification(input); + result = RpcResultBuilder.success(); + } catch (Exception e) { + result = RpcResultBuilder.failed(); + result.withError(ErrorType.APPLICATION, "Exception", e); + } + return result.buildFuture(); + } + + @Override + public ListenableFuture<RpcResult<PushAttributeChangeNotificationOutput>> pushAttributeChangeNotification( + PushAttributeChangeNotificationInput input) { + LOG.info("RPC Received change notification {}", input); + RpcResultBuilder<PushAttributeChangeNotificationOutput> result; + try { + pushNotificationsListener.pushAttributeChangeNotification(input); + result = RpcResultBuilder.success(); + } catch (Exception e) { + result = RpcResultBuilder.failed(); + result.withError(ErrorType.APPLICATION, "Exception", e); + } + return result.buildFuture(); + } + + + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/DeviceManagerImpl.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/DeviceManagerImpl.java new file mode 100644 index 000000000..bf467cf9c --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/DeviceManagerImpl.java @@ -0,0 +1,441 @@ +/******************************************************************************* + * ============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.impl; + +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.IEntityDataProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.IEsConfig; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.aaiconnector.impl.AaiProviderClient; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.archiveservice.ArchiveCleanService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.datamanager.DeviceManagerDatabaseNotificationService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.dcaeconnector.impl.DcaeForwarderImpl; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.dcaeconnector.impl.DcaeForwarderInternal; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.dcaeconnector.impl.DcaeProviderClient; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.devicemonitor.impl.DeviceMonitor; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.devicemonitor.impl.DeviceMonitorImpl; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.housekeeping.ConnectionStatusHousekeepingService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.housekeeping.ResyncNetworkElementHouskeepingService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.handler.ODLEventListenerHandler; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.handler.RpcPushNotificationsHandler; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.listener.NetconfChangeListener; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.WebSocketServiceClientDummyImpl; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.WebSocketServiceClientImpl2; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.WebSocketServiceClientInternal; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.maintenance.impl.MaintenanceServiceImpl; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.factory.FactoryRegistration; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.factory.NetworkElementFactory; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.performancemanager.impl.PerformanceManagerImpl; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.performancemanager.impl.database.service.MicrowaveHistoricalPerformanceWriterService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.AaiService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.EquipmentService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.EventHandlingService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.FaultService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.MaintenanceService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NetconfNetworkElementService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.PerformanceManager; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.toggleAlarmFilter.DevicemanagerNotificationDelayService; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeStateService; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.binding.api.MountPoint; +import org.opendaylight.mdsal.binding.api.MountPointService; +import org.opendaylight.mdsal.binding.api.NotificationPublishService; +import org.opendaylight.mdsal.binding.api.RpcProviderService; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.websocketmanager.rev150105.WebsocketmanagerService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Devicemanager + * - Handles startup and closedown of network element handlers for netconf session + * - Provide common services for network element specific components + */ +public class DeviceManagerImpl implements NetconfNetworkElementService, DeviceManagerServiceProvider, AutoCloseable { + + private static final Logger LOG = LoggerFactory.getLogger(DeviceManagerImpl.class); + private static final String APPLICATION_NAME = "DeviceManager"; + private static final String MYDBKEYNAMEBASE = "SDN-Controller"; + private static final String CONFIGURATIONFILE = "etc/devicemanager.properties"; + public static final long DATABASE_TIMEOUT_MS = 120*1000L; + + @SuppressWarnings("unused") + private static final String STARTUPLOG_FILENAME = "etc/devicemanager.startup.log"; + // private static final String STARTUPLOG_FILENAME2 = "data/cache/devicemanager.startup.log"; + + // MDSAL Services + private DataBroker dataBroker; + private MountPointService mountPointService; + private RpcProviderService rpcProviderRegistry; + @SuppressWarnings("unused") + private NotificationPublishService notificationPublishService; + private ClusterSingletonServiceProvider clusterSingletonServiceProvider; + private WebsocketmanagerService websocketmanagerService; + private IEntityDataProvider iEntityDataProvider; + + // Devicemanager common services for network element handler + private @Nullable WebSocketServiceClientInternal webSocketService; + private ODLEventListenerHandler odlEventListenerHandler; //EventHandlingService + private NetconfChangeListener netconfChangeListener; + private DeviceManagerApiServiceImpl rpcApiService; + private PerformanceManagerImpl performanceManager; + private DcaeProviderClient dcaeProviderClient; + private AaiProviderClient aaiProviderClient; + private DcaeForwarderInternal aotsDcaeForwarder; + private DeviceMonitor deviceMonitor; + private MaintenanceServiceImpl maintenanceService; + private DevicemanagerNotificationDelayService notificationDelayService; + private ResyncNetworkElementHouskeepingService resyncNetworkElementHouskeepingService; + private ArchiveCleanService archiveCleanService; + private ConnectionStatusHousekeepingService housekeepingService; + private NetconfNodeStateService netconfNodeStateService; + private DataProvider dataProvider; + //private HtDatabaseClient htDatabaseClient; + // Handler + private RpcPushNotificationsHandler rpcPushNotificationsHandler; + private DeviceManagerNetconfConnectHandler forTest; + // Attributes + private final Object networkelementLock; + private final ConcurrentHashMap<String, NetworkElement> networkElementRepresentations; + private final List<MyNetworkElementFactory<? extends NetworkElementFactory>> factoryList; + + private DeviceManagerDatabaseNotificationService deviceManagerDatabaseAndNotificationService; + private ClusterSingletonServiceRegistration cssRegistration; + private ClusterSingletonServiceRegistration cssRegistration2; + + + private Boolean devicemanagerInitializationOk; + + // Blueprint 1 + public DeviceManagerImpl() { + LOG.info("Creating provider for {}", APPLICATION_NAME); + this.devicemanagerInitializationOk = false; + this.factoryList = new CopyOnWriteArrayList<>(); + this.networkelementLock = new Object(); + this.networkElementRepresentations = new ConcurrentHashMap<>(); + + this.dataBroker = null; + this.mountPointService = null; + this.rpcProviderRegistry = null; + this.notificationPublishService = null; + this.clusterSingletonServiceProvider = null; + this.websocketmanagerService = null; + this.iEntityDataProvider = null; + + this.webSocketService = null; + } + + public void setDataBroker(DataBroker dataBroker) { + this.dataBroker = dataBroker; + } + + public void setRpcProviderRegistry(RpcProviderService rpcProviderRegistry) { + this.rpcProviderRegistry = rpcProviderRegistry; + } + + public void setNotificationPublishService(NotificationPublishService notificationPublishService) { + this.notificationPublishService = notificationPublishService; + } + + public void setMountPointService(MountPointService mountPointService) { + this.mountPointService = mountPointService; + } + public void setClusterSingletonService(ClusterSingletonServiceProvider clusterSingletonService) { + this.clusterSingletonServiceProvider = clusterSingletonService; + } + public void setNetconfNodeStateService(NetconfNodeStateService netconfNodeStateService) { + this.netconfNodeStateService = netconfNodeStateService; + } + public void setWebsocketmanagerService(WebsocketmanagerService websocketmanagerService) { + this.websocketmanagerService = websocketmanagerService; + } + public void setEntityDataProvider(IEntityDataProvider iEntityDataProvider) { + this.iEntityDataProvider = iEntityDataProvider; + } + + @SuppressWarnings({ "deprecation", "null" }) + public void init() throws Exception { + + LOG.info("Session Initiated start {}", APPLICATION_NAME); + this.iEntityDataProvider.setReadyStatus(false); + + this.dataProvider = iEntityDataProvider.getDataProvider(); // Get configuration + + ConfigurationFileRepresentation config = new ConfigurationFileRepresentation(CONFIGURATIONFILE); + + this.notificationDelayService = new DevicemanagerNotificationDelayService(config); + + //EsConfig dbConfig = new EsConfig(config); + //LOG.debug("esConfig=" + dbConfig.toString()); + // Start database + // TODO Remove this database client + //this.htDatabaseClient = new HtDatabaseClient(dbConfig.getHosts()); + //this.htDatabaseClient.waitForYellowStatus(DATABASE_TIMEOUT_MS); + + // start service for device maintenance service + this.maintenanceService = new MaintenanceServiceImpl(iEntityDataProvider.getHtDatabaseMaintenance()); + + // Websockets + try { + this.webSocketService = new WebSocketServiceClientImpl2(websocketmanagerService); + } catch (Exception e) { + LOG.error("Can not start websocket service. Loading mock class.", e); + this.webSocketService = new WebSocketServiceClientDummyImpl(); + } + + this.deviceManagerDatabaseAndNotificationService = new DeviceManagerDatabaseNotificationService(dataProvider, webSocketService); + + IEsConfig esConfig = iEntityDataProvider.getEsConfig(); + // DCAE + this.dcaeProviderClient = new DcaeProviderClient(config, esConfig.getCluster(), this); + + this.aaiProviderClient = new AaiProviderClient(config, this); + // EM + String myDbKeyNameExtended = MYDBKEYNAMEBASE + "-" + esConfig.getCluster(); + + this.aotsDcaeForwarder = new DcaeForwarderImpl(null, dcaeProviderClient, maintenanceService); + this.rpcPushNotificationsHandler = new RpcPushNotificationsHandler(webSocketService, + dataProvider, aotsDcaeForwarder); + this.odlEventListenerHandler = new ODLEventListenerHandler(myDbKeyNameExtended, webSocketService, + dataProvider, aotsDcaeForwarder); + this.archiveCleanService = new ArchiveCleanService(iEntityDataProvider.getEsConfig(), dataProvider); + this.housekeepingService = new ConnectionStatusHousekeepingService(this.dataBroker, + dataProvider); + this.cssRegistration = this.clusterSingletonServiceProvider + .registerClusterSingletonService(this.archiveCleanService); + this.cssRegistration2 = this.clusterSingletonServiceProvider + .registerClusterSingletonService(this.housekeepingService); + // PM + this.performanceManager = new PerformanceManagerImpl(60, this, new MicrowaveHistoricalPerformanceWriterService(dataProvider), config); + // DM + // DeviceMonitor has to be available before netconfSubscriptionManager is + // configured + LOG.debug("start DeviceMonitor Service"); + this.deviceMonitor = new DeviceMonitorImpl(dataBroker, odlEventListenerHandler, config); + + // ResyncNetworkElementHouskeepingService + this.resyncNetworkElementHouskeepingService = new ResyncNetworkElementHouskeepingService( + this, mountPointService, odlEventListenerHandler, + dataProvider, deviceMonitor); + + // RPC Service for specific services + // Start RPC Service + LOG.debug("start rpc service"); + this.rpcApiService = new DeviceManagerApiServiceImpl(rpcProviderRegistry, maintenanceService, + resyncNetworkElementHouskeepingService, rpcPushNotificationsHandler); + + // netconfSubscriptionManager should be the last one because this is a callback + // service + LOG.debug("start NetconfSubscriptionManager Service"); + // this.netconfSubscriptionManager = new + // NetconfSubscriptionManagerOfDeviceManager(this, dataBroker); + // this.netconfSubscriptionManager.register(); + + //---->>>>>>> OLD OLD OLD + //this.netconfChangeListener = new NetconfChangeListener(this, dataBroker); + //this.netconfChangeListener.register(); + + //---->>>>>>> NEW NEW NEW + this.forTest = new DeviceManagerNetconfConnectHandler(netconfNodeStateService, odlEventListenerHandler, + deviceMonitor, this, factoryList); + + writeToEventLog(APPLICATION_NAME, "startup", "done"); + this.devicemanagerInitializationOk = true; + + LOG.info("Session Initiated end. Initialization done {}", devicemanagerInitializationOk); + this.iEntityDataProvider.setReadyStatus(true); + + } + + @Override + public void close() { + LOG.info("DeviceManagerImpl closing ..."); + close(performanceManager); + close(dcaeProviderClient); + close(aaiProviderClient); + close(deviceMonitor); + //close(htDatabaseClient); + close(netconfChangeListener); + close(maintenanceService); + close(rpcApiService); + close(notificationDelayService); + close(archiveCleanService); + close(housekeepingService); + close(forTest); + close(cssRegistration, cssRegistration2); + LOG.info("DeviceManagerImpl closing done"); + } + + @Override + public @NonNull <L extends NetworkElementFactory> FactoryRegistration<L> registerNetworkElementFactory(@NonNull L factory) { + LOG.info("Factory registration {}", factory.getClass().getName()); + MyNetworkElementFactory<L> myFactory = new MyNetworkElementFactory<>(factory, (a,b,c) -> initDefault(a,b,c)); + factoryList.add(myFactory); + return new FactoryRegistration<L>() { + + @Override + public @NonNull L getInstance() { + return myFactory.getFactory(); + } + + @Override + public void close() { + factoryList.remove(myFactory); + } + + }; + } + + /** + * Execute register command, for network element + * @param mountPointNodeName of new network element + * @param mountPoint of new network element + * @param inNe that needs to register + */ + private void initDefault(String mountPointNodeName, MountPoint mountPoint, NetworkElement inNe) { + // sendUpdateNotification(mountPointNodeName, nNode.getConnectionStatus(), nNode); + + NetworkElement result; + synchronized (networkelementLock) { + result = networkElementRepresentations.put(mountPointNodeName, inNe); + } + if (result != null) { + LOG.warn("NE list was not empty as expected, but contained {} ", result.getNodeId()); + } else { + deviceMonitor.deviceConnectMasterIndication(mountPointNodeName, inNe); + inNe.register(); // Call NE specific initialization + odlEventListenerHandler.connectIndication(mountPointNodeName, inNe.getDeviceType()); + } + } + + @SuppressWarnings("null") + @Override + public @NonNull DataProvider getDataProvider() { + return this.dataProvider; + } + + @SuppressWarnings("null") + @Override + public @NonNull NotificationService getNotificationService() { + return this.deviceManagerDatabaseAndNotificationService; + } + + @SuppressWarnings("null") + @Override + public @NonNull FaultService getFaultService() { + return this.deviceManagerDatabaseAndNotificationService; + } + + @SuppressWarnings("null") + @Override + public @NonNull EquipmentService getEquipmentService() { + return this.deviceManagerDatabaseAndNotificationService; + } + + @SuppressWarnings("null") + @Override + public @NonNull AaiService getAaiService() { + return this.aaiProviderClient; + } + + @SuppressWarnings("null") + @Override + public @NonNull MaintenanceService getMaintenanceService() { + return this.maintenanceService; + } + + @SuppressWarnings("null") + @Override + public @NonNull PerformanceManager getPerformanceManagerService() { + return this.performanceManager; + } + + @SuppressWarnings("null") + @Override + public @NonNull EventHandlingService getEventHandlingService() { + return this.odlEventListenerHandler; + } + // Deviceinitialization + + /** + * Used to close all Services, that should support AutoCloseable Pattern + * @param toClose + */ + private void close(AutoCloseable... toCloseList) { + for (AutoCloseable element : toCloseList) { + if (element != null) { + try { + element.close(); + } catch (Exception e) { + LOG.warn("Problem during close {}", e); + } + } + } + } + + /*------------------------------------------------------------------------------------------- + * Functions + */ + + public ArchiveCleanService getArchiveCleanService() { + return this.archiveCleanService; + } + + public DataProvider getDatabaseClientEvents() { + return dataProvider; + } + + @Override + public DeviceManagerServiceProvider getServiceProvider() { + return this; + } + + /** + * Indication if init() of devicemanager successfully done. + * @return true if init() was sucessfull. False if not done or not successfull. + */ + public boolean isDevicemanagerInitializationOk() { + return this.devicemanagerInitializationOk; + } + + /** + * Get NE object. Used by DCAE Service + * @param mountpoint mount point name + * @return null or NE specific data + */ + public @Nullable NetworkElement getNeByMountpoint(String mountpoint) { + + return networkElementRepresentations.get(mountpoint); + + } + + @Override + public void writeToEventLog(String objectId, String msg, String value) { + this.odlEventListenerHandler.writeEventLog(objectId, msg, value); + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/DeviceManagerNetconfConnectHandler.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/DeviceManagerNetconfConnectHandler.java new file mode 100644 index 000000000..2d949e59a --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/DeviceManagerNetconfConnectHandler.java @@ -0,0 +1,190 @@ +/******************************************************************************* + * ============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.impl; + +import java.util.List; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import org.eclipse.jdt.annotation.NonNull; +import org.onap.ccsdk.features.sdnr.wt.common.HtAssert; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.devicemonitor.impl.DeviceMonitor; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.handler.ODLEventListenerHandler; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.factory.NetworkElementFactory; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeConnectListener; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeStateListener; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeStateService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DeviceManagerNetconfConnectHandler implements NetconfNodeConnectListener, NetconfNodeStateListener { + + private static final Logger LOG = LoggerFactory.getLogger(DeviceManagerNetconfConnectHandler.class); + + private final @NonNull ListenerRegistration<DeviceManagerNetconfConnectHandler> registerNetconfNodeConnectListener; + private final @NonNull ListenerRegistration<NetconfNodeStateListener> registerNetconfNodeStateListener; + + private final @NonNull ODLEventListenerHandler odlEventListenerHandler; + private final @NonNull DeviceMonitor deviceMonitor; + private final @NonNull List<MyNetworkElementFactory<? extends NetworkElementFactory>> factoryList; + private final @NonNull DeviceManagerServiceProvider serviceProvider; + + private final Object networkelementLock; + private final ConcurrentHashMap<String, NetworkElement> networkElementRepresentations; + + public DeviceManagerNetconfConnectHandler(@NonNull NetconfNodeStateService netconfNodeStateService, + @NonNull ODLEventListenerHandler odlEventListenerHandler, @NonNull DeviceMonitor deviceMonitor, + @NonNull DeviceManagerServiceProvider serviceProvider, + @NonNull List<MyNetworkElementFactory<? extends NetworkElementFactory>> factoryList) { + + HtAssert.nonnull(netconfNodeStateService, this.odlEventListenerHandler = odlEventListenerHandler, + this.deviceMonitor = deviceMonitor, this.serviceProvider = serviceProvider, + this.factoryList = factoryList); + + this.networkelementLock = new Object(); + this.networkElementRepresentations = new ConcurrentHashMap<>(); + + this.registerNetconfNodeConnectListener = netconfNodeStateService.registerNetconfNodeConnectListener(this); + this.registerNetconfNodeStateListener = netconfNodeStateService.registerNetconfNodeStateListener(this); + } + + @Override + public void onEnterConnected(@NonNull NetconfAccessor acessor) { + //@NonNull NodeId nNodeId, @NonNull NetconfNode netconfNode, + //@NonNull MountPoint mountPoint, @NonNull DataBroker netconfNodeDataBroker + String mountPointNodeName = acessor.getNodeId().getValue(); + LOG.info("onEnterConnected - starting Event listener on Netconf for mountpoint {}", mountPointNodeName); + + LOG.info("Master mountpoint {}", mountPointNodeName); + + // It is master for mountpoint and all data are available. + // Make sure that specific mountPointNodeName is handled only once. + // be aware that startListenerOnNodeForConnectedState could be called multiple + // times for same mountPointNodeName. + // networkElementRepresentations contains handled NEs at master node. + + synchronized (networkelementLock) { + if (networkElementRepresentations.containsKey(mountPointNodeName)) { + LOG.warn("Mountpoint {} already registered. Leave startup procedure.", mountPointNodeName); + return; + } + } + // update db with connect status + NetconfNode netconfNode = acessor.getNetconfNode(); + sendUpdateNotification(mountPointNodeName, netconfNode.getConnectionStatus(), netconfNode); + + for ( MyNetworkElementFactory<? extends NetworkElementFactory> f : factoryList) { + Optional<NetworkElement> optionalNe = f.getFactory().create(acessor, serviceProvider); + if (optionalNe.isPresent()) { + // sendUpdateNotification(mountPointNodeName, nNode.getConnectionStatus(), nNode); + NetworkElement inNe = optionalNe.get(); + LOG.info("NE Management for {} with {}", mountPointNodeName, inNe.getClass().getName()); + putToNetworkElementRepresentations(mountPointNodeName, inNe); + deviceMonitor.deviceConnectMasterIndication(mountPointNodeName, inNe); + + inNe.register(); + break; // Use the first provided + } + } + } + + @Override + public void onLeaveConnected(@NonNull NodeId nNodeId, @NonNull Optional<NetconfNode> optionalNetconfNode) { + + LOG.info("onLeaveConnected {}", nNodeId); + String mountPointNodeName = nNodeId.getValue(); + + if (optionalNetconfNode.isPresent()) { + NetconfNode nNode = optionalNetconfNode.get(); + ConnectionStatus csts = nNode.getConnectionStatus(); + sendUpdateNotification(mountPointNodeName, csts, nNode); + } + + // Handling if mountpoint exist. connected -> connecting/UnableToConnect + stopListenerOnNodeForConnectedState(mountPointNodeName); + deviceMonitor.deviceDisconnectIndication(mountPointNodeName); + } + + @Override + public void onCreated(NodeId nNodeId, NetconfNode netconfNode) { + LOG.info("onCreated {}", nNodeId); + } + + @Override + public void onStateChange(NodeId nNodeId, NetconfNode netconfNode) { + LOG.info("onStateChange {}", nNodeId); + } + + @Override + public void onRemoved(NodeId nNodeId) { + String mountPointNodeName = nNodeId.getValue(); + LOG.info("mountpointNodeRemoved {}", nNodeId.getValue()); + + stopListenerOnNodeForConnectedState(mountPointNodeName); + deviceMonitor.removeMountpointIndication(mountPointNodeName); + odlEventListenerHandler.deRegistration(mountPointNodeName); //Additional indication for log + } + + @Override + public void close() { + registerNetconfNodeConnectListener.close(); + registerNetconfNodeStateListener.close(); + } + + /*-------------------------------------------- + * Private functions + */ + + /** + * Do all tasks necessary to move from mountpoint state connected -> connecting + * @param mountPointNodeName provided + * @param ne representing the device connected to mountpoint + */ + private void stopListenerOnNodeForConnectedState( String mountPointNodeName) { + NetworkElement ne = networkElementRepresentations.remove(mountPointNodeName); + if (ne != null) { + ne.deregister(); + } + } + + private void putToNetworkElementRepresentations(String mountPointNodeName, NetworkElement ne) { + NetworkElement result; + synchronized (networkelementLock) { + result = networkElementRepresentations.put(mountPointNodeName, ne); + } + if (result != null) { + LOG.warn("NE list was not empty as expected, but contained {} ", result.getNodeId()); + } else { + odlEventListenerHandler.connectIndication(mountPointNodeName, ne.getDeviceType()); + } + } + + private void sendUpdateNotification(String mountPointNodeName, ConnectionStatus csts, NetconfNode nNode) { + LOG.info("update ConnectedState for device :: Name : {} ConnectionStatus {}", mountPointNodeName, csts); + odlEventListenerHandler.updateRegistration(mountPointNodeName, ConnectionStatus.class.getSimpleName(), + csts != null ? csts.getName() : "null", nNode); + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/MyNetworkElementFactory.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/MyNetworkElementFactory.java new file mode 100644 index 000000000..e2ce10ded --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/MyNetworkElementFactory.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * ============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.impl; + +import org.eclipse.jdt.annotation.NonNull; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.factory.NetworkElementFactory; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; +import org.opendaylight.mdsal.binding.api.MountPoint; + +/** + * @author herbert + * + */ +class MyNetworkElementFactory<L extends NetworkElementFactory> { + + + @FunctionalInterface + interface Register<X, Y, Z> { + public void register(X mountPointNodeName, Y mountPoint, Z ne); + } + + private final Register<String, MountPoint, NetworkElement> init; + private final @NonNull L factory; + + @SuppressWarnings("null") + MyNetworkElementFactory(@NonNull L factory, Register<String, MountPoint, NetworkElement> init) { + super(); + if (init == null || factory == null) { + throw new IllegalArgumentException("Null not allowed here."); + } + this.init = init; + this.factory = factory; + } + public Register<String, MountPoint, NetworkElement> getInit() { + return init; + } + public @NonNull L getFactory() { + return factory; + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/NetconfNodeService.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/NetconfNodeService.java new file mode 100644 index 000000000..5ce8a0d69 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/NetconfNodeService.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * ============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.impl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; + +public interface NetconfNodeService { + + public enum Action { + CREATE, + REMOVE, + UPDATE + } + + /** + * MountpointChangeHandler, called to indicate change to DeviceManager + * @param action provided + * @param csts provided + * @param nodeId provided + * @param nnode provided + */ + void netconfNodeChangeHandler(Action action, NodeId nodeId, NetconfNode nnode); +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/ProviderClient.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/ProviderClient.java new file mode 100644 index 000000000..922b8a0e0 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/ProviderClient.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * ============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.impl; + +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.ProblemNotificationXml; + +public interface ProviderClient extends AutoCloseable { + + /** + * Send out problem notification, that was created by a device/ or NE + * @param mountPointName related + * @param notification xml description + */ + public void sendProblemNotification(String mountPointName, ProblemNotificationXml notification); + + /** + * Send out problem notification + * @param mountPointName related + * @param notification xml description + * @param neDeviceAlarm true indicates an NE originated alarm, false an sdncontroller generated alarm + */ + public void sendProblemNotification(String mountPointName, ProblemNotificationXml notification, boolean neDeviceAlarm); + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/PushNotifications.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/PushNotifications.java new file mode 100644 index 000000000..2acefc166 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/PushNotifications.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * ============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.impl; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.PushAttributeChangeNotificationInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.PushFaultNotificationInput; + +public interface PushNotifications { + + void pushAttributeChangeNotification(PushAttributeChangeNotificationInput input); + + void pushFaultNotification(PushFaultNotificationInput input); + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/conf/odlAkka/AkkaConfig.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/conf/odlAkka/AkkaConfig.java new file mode 100644 index 000000000..7e54881ed --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/conf/odlAkka/AkkaConfig.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * ============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.impl.conf.odlAkka; + +import java.io.File; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.typesafe.config.Config; +import com.typesafe.config.ConfigFactory; + +public class AkkaConfig { + + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(AkkaConfig.class); + + private static final String DEFAULT_FILENAME = "configuration/initial/akka.conf"; + private final String filename; + private ClusterConfig cluserConfig; + + public ClusterConfig getClusterConfig() { + return this.cluserConfig; + } + + private AkkaConfig(String filename) { + this.filename = filename; + } + + public AkkaConfig() { + this(null); + } + + @Override + public String toString() { + return "AkkaConfig [filename=" + filename + ", cluserConfig=" + cluserConfig + "]"; + } + + private void loadFromFile() throws Exception { + Config cfg = ConfigFactory.parseFile(new File(this.filename)); + this.cluserConfig = new ClusterConfig(cfg.getConfig("odl-cluster-data").getConfig("akka").getConfig("cluster")); + } + + public boolean isCluster() { + return this.cluserConfig != null ? this.cluserConfig.isCluster() : false; + } + + public boolean isClusterAndFirstNode() { + return isSingleNode() || isCluster() && getClusterConfig().getRoleMemberIndex() == 1; + } + + public static AkkaConfig load() throws Exception { + return load(DEFAULT_FILENAME); + } + + public static AkkaConfig load(String filename) throws Exception { + AkkaConfig cfg = new AkkaConfig(filename); + cfg.loadFromFile(); + return cfg; + } + + public boolean isSingleNode() { + return !this.isCluster(); + } + public static AkkaConfig parse(String content) throws Exception { + Config cfg = ConfigFactory.parseString(content); + AkkaConfig c = new AkkaConfig(); + c.cluserConfig=new ClusterConfig(cfg.getConfig("odl-cluster-data").getConfig("akka").getConfig("cluster")); + return c; + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/conf/odlAkka/ClusterConfig.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/conf/odlAkka/ClusterConfig.java new file mode 100644 index 000000000..c6c8c1533 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/conf/odlAkka/ClusterConfig.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * ============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.impl.conf.odlAkka; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.conf.odlGeo.ClusterRoleInfo; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.conf.odlGeo.ClusterRoleInfoCollection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.typesafe.config.Config; + +public class ClusterConfig { + + private static final Logger LOG = LoggerFactory.getLogger(ClusterConfig.class); + + private final List<ClusterNodeInfo> seedNodes; + private final ClusterRoleInfoCollection roles; + private ClusterNodeInfo ismeInfo; + + public static ClusterConfig defaultSingleNodeConfig() + { + ClusterConfig cfg=new ClusterConfig(); + cfg.ismeInfo=ClusterNodeInfo.defaultSingleNodeInfo(); + cfg.seedNodes.add(cfg.ismeInfo); + cfg.roles.add(ClusterRoleInfo.defaultSingleNodeRole()); + return cfg; + } + public ClusterConfig() + { + this.seedNodes = new ArrayList<>(); + this.roles = new ClusterRoleInfoCollection(); + + } + public ClusterConfig(Config o) throws Exception { + { + this.seedNodes = new ArrayList<>(); + this.roles = new ClusterRoleInfoCollection(); + List<String> a = o.getStringList("seed-nodes"); + for (int i = 0; i < a.size(); i++) { + ClusterNodeInfo info = new ClusterNodeInfo(a.get(i)); + this.seedNodes.add(info); + } + a = o.getStringList("roles"); + for (int i = 0; i < a.size(); i++) { + ClusterRoleInfo s = new ClusterRoleInfo(a.get(i)); + this.roles.add(s); + } + int idx = this.roles.get(0).getIndex() - 1; + if (idx >= 0 && idx < this.seedNodes.size()) { + this.ismeInfo = this.seedNodes.get(idx); + } else { + this.ismeInfo = null; + } + } + + } + + public boolean isCluster() { + return this.seedNodes != null ? this.seedNodes.size() > 1 : false; + } + + public boolean isMe(ClusterNodeInfo i) { + return this.ismeInfo != null ? this.ismeInfo.equals(i) : false; + } + + public List<ClusterNodeInfo> getSeedNodes() { + return this.seedNodes; + } + + public String getHostName(String defaultValue) { + if (getRoleMemberIndex() > 0 && getRoleMemberIndex() <= seedNodes.size()) { + return this.seedNodes.get(getRoleMemberIndex()-1).getRemoteAddress(); + } else { + LOG.warn("Seednode not available for roleMemberIndex {}. Using default {}",getRoleMember(), defaultValue); + return defaultValue; + } + } + + public String getDBClusterName(String defaultValue) { + String r = null; + if (this.seedNodes != null && this.seedNodes.size() > 0) { + r = String.format("cluster-%s.%d", this.seedNodes.get(0).getRemoteAddress(), this.seedNodes.get(0).getPort()); + } + if (r == null || r.isEmpty()) { + r = defaultValue; + } + return r; + } + public String getClusterSeedNodeName() { + return this.getClusterSeedNodeName(""); + } + public String getClusterSeedNodeName(String defaultValue) { + int idx=this.getRoleMemberIndex()-1; + String r=null; + if(this.seedNodes!=null && idx>=0 && this.seedNodes.size()>0 && this.seedNodes.size()>idx) + { + r=this.seedNodes.get(idx).getSeedNodeName(); + } + if (r == null || r.isEmpty()) { + r = defaultValue; + } + return r; + } + public int getRoleMemberIndex() { + + ClusterRoleInfo role=this.roles.get("member"); + return role!=null?role.getIndex():0; + } + public ClusterRoleInfo getRoleMember() { + return this.roles.get("member"); + } + + @Override + public String toString() { + return "ClusterConfig [seedNodes=" + seedNodes + ", roles=" + roles + ", ismeInfo=" + ismeInfo + "]"; + } + + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/conf/odlAkka/ClusterNodeInfo.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/conf/odlAkka/ClusterNodeInfo.java new file mode 100644 index 000000000..7bc015fed --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/conf/odlAkka/ClusterNodeInfo.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * ============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.impl.conf.odlAkka; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ClusterNodeInfo { + private final String protocol; + private final String clusterName; + private final String remoteAdr; + private final int port; + private final String seedNodeName; + + public static ClusterNodeInfo defaultSingleNodeInfo() { + return new ClusterNodeInfo("akka.tcp","opendaylight-cluster-data","127.0.0.1",2550); + } + + public ClusterNodeInfo(String s) throws Exception { + final String regex = "([a-z.]*):\\/\\/([a-zA-Z0-9-]*)@([a-zA-Z0-9.-]*):([0-9]*)"; + final Pattern pattern = Pattern.compile(regex); + final Matcher matcher = pattern.matcher(s); + if (!matcher.find()) { + throw new Exception("invalid seedNode format"); + } + this.seedNodeName = matcher.group(); + this.protocol = matcher.group(1); + this.clusterName = matcher.group(2); + this.remoteAdr = matcher.group(3); + this.port = Integer.parseInt(matcher.group(4)); + } + + public ClusterNodeInfo(String protocol, String clustername, String remoteadr, int port) { + this.protocol=protocol; + this.clusterName=clustername; + this.remoteAdr=remoteadr; + this.port=port; + this.seedNodeName=this.protocol+"://"+this.clusterName+"@"+this.remoteAdr+":"+this.port; + } + + public String getProtocol() { + return protocol; + } + + public String getClusterName() { + return clusterName; + } + + public String getRemoteAddress() { + return remoteAdr; + } + public String getSeedNodeName() { + return seedNodeName; + } + + public int getPort() { + return port; + } + + @Override + public String toString() { + return "ClusterNodeInfo [protocol=" + protocol + ", clusterName=" + clusterName + ", remoteAdr=" + remoteAdr + + ", port=" + port + ", seedNodeName=" + seedNodeName + "]"; + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/conf/odlGeo/ClusterRoleInfo.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/conf/odlGeo/ClusterRoleInfo.java new file mode 100644 index 000000000..9a9793b89 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/conf/odlGeo/ClusterRoleInfo.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * ============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.impl.conf.odlGeo; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ClusterRoleInfo { + private final String Role; + private final int Index; + + public ClusterRoleInfo(String s) throws Exception { + final String regex = "([a-zA-Z]*)-([0-9]*)"; + final Pattern pattern = Pattern.compile(regex); + final Matcher matcher = pattern.matcher(s); + if (!matcher.find()) { + throw new Exception("unexpected role format:"+s); + } + this.Role = matcher.group(1); + this.Index = Integer.parseInt(matcher.group(2)); + } + + private ClusterRoleInfo(String role, int idx) { + this.Role=role; + this.Index=idx; + } + + public static ClusterRoleInfo defaultSingleNodeRole() { + return new ClusterRoleInfo("member",1); + } + + public String getRole() { + return Role; + } + public int getIndex() { + return Index; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Index; + result = prime * result + (Role == null ? 0 : Role.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ClusterRoleInfo other = (ClusterRoleInfo) obj; + if (Index != other.Index) { + return false; + } + if (Role == null) { + if (other.Role != null) { + return false; + } + } else if (!Role.equals(other.Role)) { + return false; + } + return true; + } + @Override + public String toString() { + return "ClusterRoleInfo [Role=" + Role + ", Index=" + Index + "]"; + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/conf/odlGeo/ClusterRoleInfoCollection.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/conf/odlGeo/ClusterRoleInfoCollection.java new file mode 100644 index 000000000..089bf33f2 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/conf/odlGeo/ClusterRoleInfoCollection.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * ============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.impl.conf.odlGeo; + +import java.util.ArrayList; + +public class ClusterRoleInfoCollection extends ArrayList<ClusterRoleInfo> { + private static final long serialVersionUID = 1L; + + public ClusterRoleInfo get(String role) { + for (ClusterRoleInfo info : this) { + if (info.getRole().equals(role)) { + return info; + } + } + return null; + } + + public boolean contains(ClusterRoleInfo info) { + if (info == null) { + return false; + } + for (ClusterRoleInfo i : this) { + if (i.equals(info)) { + return true; + } + } + return false; + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/conf/odlGeo/GeoConfig.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/conf/odlGeo/GeoConfig.java new file mode 100644 index 000000000..25e7fe265 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/conf/odlGeo/GeoConfig.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * ============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.impl.conf.odlGeo; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import com.typesafe.config.Config; +import com.typesafe.config.ConfigFactory; + +public class GeoConfig { + + private static final String DEFAULT_FILENAME = "configuration/initial/geo.conf"; + private static final String LUMINA_ROOTNODENAME = "lumina-geo-cluster"; + private final String filename; + private final String rootNodename; + private ClusterRoleInfoCollection primaryRoles; + private ClusterRoleInfoCollection secondayRoles; + private RolesTable rolesTable; + + private GeoConfig() { + this(null); + } + + private GeoConfig(String filename) { + this(filename, LUMINA_ROOTNODENAME); + } + + private GeoConfig(String filename, String rootNodeName) { + this.filename = filename; + this.rootNodename = rootNodeName; + } + + public static boolean fileExists() { + File f = new File(DEFAULT_FILENAME); + return f.exists(); + } + + public static GeoConfig load() throws Exception { + return load(DEFAULT_FILENAME); + } + + public static GeoConfig load(String filename) throws Exception { + GeoConfig cfg = new GeoConfig(filename); + cfg._load(); + return cfg; + } + + private void _load() throws Exception { + this._load(ConfigFactory.parseFile(new File(this.filename))); + } + + private void _load(Config cfg) throws Exception { + this.primaryRoles = new ClusterRoleInfoCollection(); + List<String> a = cfg.getConfig(this.rootNodename).getStringList("primary_roles"); + + for (int i = 0; i < a.size(); i++) { + ClusterRoleInfo s = new ClusterRoleInfo(a.get(i)); + this.primaryRoles.add(s); + } + this.secondayRoles = new ClusterRoleInfoCollection(); + a = cfg.getConfig(this.rootNodename).getStringList("secondary_roles"); + for (int i = 0; i < a.size(); i++) { + ClusterRoleInfo s = new ClusterRoleInfo(a.get(i)); + this.secondayRoles.add(s); + } + this.checkDuplicateRoleEntries(); + this.rolesTable = new RolesTable(cfg.getConfig(this.rootNodename).getConfigList("ip_roles_table")); + } + + private void checkDuplicateRoleEntries() throws Exception { + ClusterRoleInfoCollection duplicateEntries = new ClusterRoleInfoCollection(); + for (ClusterRoleInfo primaryRole : this.primaryRoles) { + if (this.secondayRoles.contains(primaryRole)) { + duplicateEntries.add(primaryRole); + } + } + if (duplicateEntries.size() > 0) { + throw new Exception("duplicate entries found: " + duplicateEntries.toString()); + } + + } + + public static GeoConfig parse(String content) throws Exception { + GeoConfig cfg = new GeoConfig(); + cfg._load(ConfigFactory.parseString(content)); + return cfg; + } + + public ClusterRoleInfoCollection getPrimaryRoles() { + return this.primaryRoles; + } + + public ClusterRoleInfoCollection getSecondaryRoles() { + return this.secondayRoles; + } + + public boolean isPrimary(ClusterRoleInfo roleMember) { + return !this.isSecondary(roleMember); + } + + private boolean isSecondary(ClusterRoleInfo roleMember) { + if (roleMember == null) { + return false; + } + for (ClusterRoleInfo info : this.secondayRoles) { + if (info.equals(roleMember)) { + return true; + } + } + return false; + } + + @Override + public String toString() { + return "GeoConfig [filename=" + filename + ", rootNodename=" + rootNodename + ", primaryRoles=" + primaryRoles + + ", secondayRoles=" + secondayRoles + ", rolesTable=" + rolesTable + "]"; + } + + public static class RolesTableEntry { + private final ClusterRoleInfo role; + private final String ip; + + public RolesTableEntry(Config c) throws Exception { + this.role = new ClusterRoleInfo(c.getString("role")); + this.ip = c.getString("ip"); + } + + @Override + public String toString() { + return "RolesTableEntry [role=" + role + ", ip=" + ip + "]"; + } + } + public static class RolesTable extends ArrayList<RolesTableEntry> { + private static final long serialVersionUID = -9146218864237487506L; + + public RolesTable(List<? extends Config> configList) throws Exception { + for (Config c : configList) { + this.add(new RolesTableEntry(c)); + } + } + + } + + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/database/FaultEntityManager.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/database/FaultEntityManager.java new file mode 100644 index 000000000..5b7057b81 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/database/FaultEntityManager.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * ============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.impl.database; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.util.InternalSeverity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Fault; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.FaultcurrentEntity; + +public class FaultEntityManager { + + private static final Pattern pattern = Pattern.compile(".*\\[layerProtocol=(.*)\\]"); + + /** + * The leading indication for notification or events that are not in the + * currentProblem data of the ONF Coremodel + */ + private static final String NOCURRENTPROBLEMINDICATION = "#"; + + /** + * Specific problems are not moving into current problem list + * @param problemName to be verified + * @return true if problem is current + */ + public static boolean isManagedAsCurrentProblem(String problemName) { + return ! problemName.startsWith(NOCURRENTPROBLEMINDICATION); + } + + public static boolean isManagedAsCurrentProblem(Fault problem) { + return isManagedAsCurrentProblem(problem.getProblem()); + } + + /** + * Specific problems are not moving into current problem list + * @param fault to be verified + * @return true if cleared indication + */ + public static boolean isNoAlarmIndication(Fault fault) { + InternalSeverity severity = InternalSeverity.valueOf(fault.getSeverity()); + return severity.isNoAlarmIndication(); + } + + /** + * Create a specific ES id for the current log. + * @return a string with the generated ES Id + */ + public static String genSpecificEsId(String nodeName, String objectId, String problemName) { + + String uuId; + + Matcher matcher = pattern.matcher(objectId); + if (matcher.matches() && matcher.groupCount() == 1) { + uuId = matcher.group(1); + } else { + uuId = objectId; + } + + StringBuffer strBuf = new StringBuffer(); + strBuf.append(nodeName); + strBuf.append("/"); + strBuf.append(uuId); + strBuf.append("/"); + strBuf.append(problemName); + return strBuf.toString(); + } + + /** + * Create Es id + * @param fault used to create uuid for faultcurrent + * @return String with Id + */ + public static String genSpecificEsId(FaultcurrentEntity fault) { + return genSpecificEsId(fault.getNodeId(), fault.getObjectId(), fault.getProblem()); + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/database/HtDataBaseReaderAndWriter.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/database/HtDataBaseReaderAndWriter.java new file mode 100644 index 000000000..919156b20 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/database/HtDataBaseReaderAndWriter.java @@ -0,0 +1,258 @@ +/******************************************************************************* + * ============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.impl.database; + +import java.util.Collection; +import java.util.List; +import org.eclipse.jdt.annotation.Nullable; +import org.onap.ccsdk.features.sdnr.wt.common.database.DatabaseClient; +import org.onap.ccsdk.features.sdnr.wt.common.database.IsEsObject; +import org.onap.ccsdk.features.sdnr.wt.common.database.SearchHit; +import org.onap.ccsdk.features.sdnr.wt.common.database.SearchResult; +import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Generic class to write lists of model classes to the database. + * + */ +public class HtDataBaseReaderAndWriter<T extends IsEsObject> { + + private static final Logger log = LoggerFactory.getLogger(HtDataBaseReaderAndWriter.class); + + + private final DatabaseClient db; + private final String dataTypeName; + private final HtMapper<T> mapper; + + /** + * Class specific access to database + * @param db ES database descriptor + * @param dataTypeName datatype name + * @param clazz class of datatype + */ + public HtDataBaseReaderAndWriter(DatabaseClient db, String dataTypeName, Class<? extends T> clazz) { + + this.db = db; + this.dataTypeName = dataTypeName; + this.mapper = new HtMapper<>( clazz ); + + } + public boolean isExistsIndex() { + return this.db.isExistsIndex(this.dataTypeName); + } + /** + * @return dataTypeName + */ + public String getDataTypeName() { + return this.dataTypeName; + } + /** + * Remove Object from database + * @param object Object with content + * @return true if remove is done + */ + public boolean doRemove( T object) { + + return db.doRemove(dataTypeName, object ); + + } + + /** + * Remove all data that match the filter + * @param query to specify data to be deleted + * @return number of removed objects + */ + public int doRemoveByQuery(QueryBuilder query) { + + int idx = 0; //Idx for getAll + int iterateLength = 100; //Step width for iterate + + List<SearchHit> hits; + do { + hits = db.doReadByQueryJsonData( dataTypeName, query).getHits(); + log.debug("Found: {} elements: {} Failures: {}",dataTypeName,hits.size(), mapper.getMappingFailures()); + + T object; + idx += hits.size(); + for (SearchHit hit : hits) { + + object = mapper.getObjectFromJson( hit.getSourceAsString() ); + + log.debug("Mapp Object: {}\nSource: '{}'\nResult: '{}'\n Failures: {}", hit.getId(), hit.getSourceAsString(), object, mapper.getMappingFailures()); + if (object != null) { + object.setEsId( hit.getId() ); + doRemove(object); + } else { + log.warn("Mapp result null Object: {}\n Source: '{}'\n : '", hit.getId(), hit.getSourceAsString()); + } + } + } while (hits.size() == iterateLength); //Do it until end indicated, because less hits than iterateLength allows. + + return idx; + } + + /** + * Do the mapping for test purpose + * @param object object for test purpose + * @return json String + */ + public String getJson( T object ) { + String json = mapper.objectToJson(object); + return json; + } + + /** + * Write one object into Database + * @param object Object with content + * @return This object for chained call pattern. + */ + public T doWrite( T object) { + + String json = mapper.objectToJson(object); + return doWrite(object, json); + + } + + /** + * Write one object into Database + * @param object Object with content + * @param json string + * @return This object for chained call pattern. + */ + public T doWrite( T object, String json) { + + log.debug("doWrite {} {}",object.getClass().getSimpleName(), object.getEsId()); + + if (json != null) { + String esId = db.doWriteJsonString(dataTypeName, object, json); + object.setEsId(esId); + log.debug("doWrite done for {} {}",object.getClass().getSimpleName(), object.getEsId()); + return esId == null ? null : object; + } else { + log.warn("Can not map object and write to database. {} {}",object.getClass().getSimpleName(), object); + return null; + } + + } + + + /** + * Write a list of Objects to the database. + * @param list Object list with content + * @return This object for chained call pattern. + */ + public HtDataBaseReaderAndWriter<T> doWrite( Collection<T> list) { + + int writeError = 0; + log.debug("Write to ES database {} Class: {} {} elements",dataTypeName, mapper.getClazz().getSimpleName(), list.size()); + + if (list != null && !list.isEmpty()) { + for( T s : list ) { + if ( doWrite(s) == null ) { + if ( ++writeError > 5 ) { + log.warn("Leave because of to >5 write errors"); + break; + } + } + } + } + + return this; + } + + /** + * Read one object via the object class specific ID + * @param object Object refrenced by idString + * @return The Object if found or null + */ + public @Nullable T doRead( IsEsObject object ) { + T res = mapper.getObjectFromJson( db.doReadJsonData( dataTypeName, object) ); + if (res != null) { + res.setEsId(object.getEsId()); + } + return res; + } + + /** + * Read one object via the object class specific ID + * @param objectEsId Object refrence + * @return The Object if found or null + */ + public @Nullable T doRead( String objectEsId ) { + T res = mapper.getObjectFromJson( db.doReadJsonData( dataTypeName, objectEsId ) ); + if (res != null) { + res.setEsId(objectEsId); + } + return res; + } + /** + * Get all elements of related type + * @return all Elements + */ + public SearchResult<T> doReadAll() { + return doReadAll(null); + } + + /** + * Read all existing objects of a type + * @param query for the elements + * @return the list of all objects + */ + + public SearchResult<T> doReadAll(QueryBuilder query) { + + SearchResult<T> res = new SearchResult<>(); + int idx = 0; //Idx for getAll + int iterateLength = 100; //Step width for iterate + + SearchResult<SearchHit> result; + List<SearchHit> hits; + do { + if(query!=null) { + log.debug("read data in {} with query {}",dataTypeName,query.toJSON()); + result=db.doReadByQueryJsonData( dataTypeName, query); + } + else { + result = db.doReadAllJsonData( dataTypeName); + } + hits=result.getHits(); + log.debug("Read: {} elements: {} Failures: {}",dataTypeName,hits.size(), mapper.getMappingFailures()); + + T object; + idx += result.getHits().size(); + for (SearchHit hit : hits) { + +// object = mapper.getObjectFromJson( hit.getSourceRef() ); + object = mapper.getObjectFromJson( hit.getSourceAsString() ); + + log.debug("Mapp Object: {}\nSource: '{}'\nResult: '{}'\n Failures: {}", hit.getId(), hit.getSourceAsString(), object, mapper.getMappingFailures()); + if (object != null) { + object.setEsId( hit.getId() ); + res.add( object ); + } else { + log.warn("Mapp result null Object: {}\n Source: '{}'\n : '", hit.getId(), hit.getSourceAsString()); + } + } + } while (hits.size() == iterateLength); //Do it until end indicated, because less hits than iterateLength allows. + res.setTotal(idx); + return res; + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/database/HtMapper.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/database/HtMapper.java new file mode 100644 index 000000000..dc2e4d768 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/database/HtMapper.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * ============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.impl.database; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import java.io.IOException; +import org.eclipse.jdt.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Herbert + * + */ +public class HtMapper<T> { + + private static final Logger log = LoggerFactory.getLogger(HtMapper.class); + + private final Class<? extends T> clazz; + + private final JsonMapperBase objectMapperRead; + private final JsonMapperBase objectMapperWrite; + + private int mappingFailures; + + public HtMapper(Class<? extends T> clazz) { + + this.mappingFailures = 0; + this.clazz = clazz; + + this.objectMapperRead = new JsonMapperBase(); + this.objectMapperWrite = this.objectMapperRead; + } + + public Class<? extends T> getClazz() { + return clazz; + } + + public int getMappingFailures() { + return mappingFailures; + } + + public String objectToJson(T object) { + return objectMapperWrite.objectToJson(object); + } + + /** + * Do the mapping from Json to class Block further mapping if there is are to + * many failures + * + * @param json String with Objects JSON representation + * @return The Object + */ + public @Nullable T getObjectFromJson(byte[] json) { + + if (json == null) { + return null; + } else if (mappingFailures < 10) { + try { + T object = objectMapperRead.readValue(json, clazz); + return object; + } catch (JsonParseException e) { + mappingFailures++; + log.warn(e.toString()); + } catch (JsonMappingException e) { + mappingFailures++; + log.warn(e.toString()); + } catch (IOException e) { + mappingFailures++; + log.warn(e.toString()); + } catch (Exception e) { + mappingFailures++; + log.warn(e.toString()); + } + } + log.warn("Problems parsing : {} {}", clazz, json); + return null; + } + + /** + * Do the mapping from Json to class Block further mapping if there is are to + * many failures + * + * @param json String with Objects JSON representation + * @return The Object + */ + public @Nullable T getObjectFromJson(String json) { + + if (json == null) { + return null; + } else if (mappingFailures < 10) { + try { + T object = objectMapperRead.readValue(json, clazz); + return object; + } catch (JsonParseException e) { + mappingFailures++; + log.warn(e.toString()); + } catch (JsonMappingException e) { + mappingFailures++; + log.warn(e.toString()); + } catch (IOException e) { + mappingFailures++; + log.warn(e.toString()); + } catch (Exception e) { + mappingFailures++; + log.warn(e.toString()); + } + } + log.warn("Problems parsing : {} {}", clazz, json); + return null; + } + + public void setSerializationInclusion(Include incl) { + this.objectMapperRead.setSerializationInclusion(incl); + + } + public void resetSerializationInclusion() { + this.objectMapperRead.setSerializationInclusion(Include.USE_DEFAULTS); + + + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/database/JsonMapperBase.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/database/JsonMapperBase.java new file mode 100644 index 000000000..848004b39 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/database/JsonMapperBase.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * ============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.impl.database; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonGenerator.Feature; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +/** + * This class is used to define default for JSON Serialization and Deserialization for the project at a single place + */ +public class JsonMapperBase extends ObjectMapper { + + private static final long serialVersionUID = 1L; + private static final Logger LOG = LoggerFactory.getLogger(JsonMapperBase.class); + + public JsonMapperBase() { + + setVisibility(PropertyAccessor.ALL, Visibility.NONE); + setVisibility(PropertyAccessor.FIELD, Visibility.ANY); + + // Deserialization + configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true); + + // Serialization + configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + getFactory().configure(Feature.ESCAPE_NON_ASCII, true); + } + + public JsonMapperBase(int t) { + + switch(t) { + case 0: + break; + case 1: + setVisibility(PropertyAccessor.ALL, Visibility.NONE); + setVisibility(PropertyAccessor.FIELD, Visibility.DEFAULT); + break; + case 2: + setVisibility(PropertyAccessor.ALL, Visibility.NONE); + setVisibility(PropertyAccessor.FIELD, Visibility.PROTECTED_AND_PUBLIC); + break; + case 3: + setVisibility(PropertyAccessor.ALL, Visibility.NONE); + setVisibility(PropertyAccessor.GETTER, Visibility.ANY); + setVisibility(PropertyAccessor.IS_GETTER, Visibility.ANY); + break; + default: + setVisibility(PropertyAccessor.ALL, Visibility.NONE); + setVisibility(PropertyAccessor.FIELD, Visibility.ANY); + break; + + } + + // Deserialization + configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true); + + // Serialization + configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + getFactory().configure(Feature.ESCAPE_NON_ASCII, true); + } + + + + public String objectToJson( Object object ) { + String res = null; + + try { + + res = writeValueAsString(object); + + } catch (JsonGenerationException e) { + LOG.debug(e.toString()); + } catch (JsonMappingException e) { + LOG.debug(e.toString()); + } catch (IOException e) { + LOG.debug(e.toString()); + } catch (Exception e) { + LOG.debug(e.toString()); + } + + return res; + } + + public String objectListToJson( List<? extends Object> objectList ) { + String res = null; + + try { + + StringWriter stringEmp = new StringWriter(); + writeValue(stringEmp, objectList); + res = stringEmp.toString(); + stringEmp.close(); + + } catch (JsonGenerationException e) { + LOG.debug(e.toString()); + } catch (JsonMappingException e) { + LOG.debug(e.toString()); + } catch (IOException e) { + LOG.debug(e.toString()); + } catch (Exception e) { + LOG.debug(e.toString()); + } + + return res; + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/handler/ODLEventListenerHandler.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/handler/ODLEventListenerHandler.java new file mode 100644 index 000000000..1b31a4e98 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/handler/ODLEventListenerHandler.java @@ -0,0 +1,241 @@ +/******************************************************************************* + * ============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.impl.handler; + +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.NetconfTimeStamp; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.dcaeconnector.impl.DcaeForwarderInternal; +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.util.NetworkElementConnectionEntitiyUtil; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.AttributeValueChangedNotificationXml; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.ObjectCreationNotificationXml; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.ObjectDeletionNotificationXml; +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.service.EventHandlingService; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EventlogBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.NetworkElementConnectionEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.NetworkElementDeviceType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SourceType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Responsible class for documenting changes in the ODL itself. The occurence of such an event is + * documented in the database and to clients. Specific example here is the registration or + * deregistration of a netconf device. This service has an own eventcounter to apply to the ONF + * Coremodel netconf behaviour. + * + * Important: Websocket notification must be the last action. + * + * @author herbert + */ + +public class ODLEventListenerHandler implements EventHandlingService { + + private static final Logger LOG = LoggerFactory.getLogger(ODLEventListenerHandler.class); + + private static final NetconfTimeStamp NETCONFTIME_CONVERTER = NetconfTimeStampImpl.getConverter(); + + private final String ownKeyName; + private final WebSocketServiceClientInternal webSocketService; + private final DataProvider databaseService; + private final DcaeForwarderInternal aotsDcaeForwarder; + + private int eventNumber; + + /*--------------------------------------------------------------- + * Construct + */ + + /** + * Create a Service to document events to clients and within a database + * + * @param ownKeyName The name of this service, that is used in the database as identification key. + * @param webSocketService service to direct messages to clients + * @param databaseService service to write to the database + * @param dcaeForwarder to deliver problems to external service + */ + public ODLEventListenerHandler(String ownKeyName, WebSocketServiceClientInternal webSocketService, + DataProvider databaseService, DcaeForwarderInternal dcaeForwarder) { + super(); + + this.ownKeyName = ownKeyName; + this.webSocketService = webSocketService; + + this.databaseService = databaseService; + this.aotsDcaeForwarder = dcaeForwarder; + + this.eventNumber = 0; + + } + + /*--------------------------------------------------------------- + * Handling of ODL Controller events + */ + + /** + * A registration of a mountpoint occured, that is in connect state + * @param registrationName of device (mountpoint name) + * @param nNode with mountpoint data + */ + @Override + public void registration(String registrationName, NetconfNode nNode) { + + ObjectCreationNotificationXml cNotificationXml = + new ObjectCreationNotificationXml(ownKeyName, popEvntNumber(), + InternalDateAndTime.valueOf(NETCONFTIME_CONVERTER.getTimeStamp()), registrationName); + NetworkElementConnectionEntity e = NetworkElementConnectionEntitiyUtil.getNetworkConnection(registrationName, nNode); + LOG.debug("registration networkelement-connection for {} with status {}", registrationName, e.getStatus()); + + // Write first to prevent missing entries + databaseService.updateNetworkConnection22(e, registrationName); + databaseService.writeConnectionLog(cNotificationXml.getConnectionlogEntity()); + webSocketService.sendViaWebsockets(registrationName, cNotificationXml); + } + + /** + * After registration + * @param mountpointNodeName uuid that is nodeId or mountpointId + * @param deviceType according to assessement + */ + @Override + public void connectIndication(String mountpointNodeName, NetworkElementDeviceType deviceType) { + + // Write first to prevent missing entries + LOG.debug("updating networkelement-connection devicetype for {} with {}",mountpointNodeName, deviceType); + NetworkElementConnectionEntity e = NetworkElementConnectionEntitiyUtil.getNetworkConnectionDeviceTpe(deviceType); + databaseService.updateNetworkConnectionDeviceType(e, mountpointNodeName); + + AttributeValueChangedNotificationXml notificationXml = new AttributeValueChangedNotificationXml(ownKeyName, + popEvntNumber(), InternalDateAndTime.valueOf(NETCONFTIME_CONVERTER.getTimeStamp()), + mountpointNodeName, "deviceType", deviceType.name()); + webSocketService.sendViaWebsockets(mountpointNodeName, notificationXml); + } + + + /** + * A deregistration of a mountpoint occured. + * @param registrationName Name of the event that is used as key in the database. + */ + @Override + public void deRegistration(String registrationName) { + + ObjectDeletionNotificationXml dNotificationXml = + new ObjectDeletionNotificationXml(ownKeyName, popEvntNumber(), + InternalDateAndTime.valueOf(NETCONFTIME_CONVERTER.getTimeStamp()), registrationName); + + // Write first to prevent missing entries + databaseService.removeNetworkConnection(registrationName); + databaseService.writeConnectionLog(dNotificationXml.getConnectionlogEntity()); + webSocketService.sendViaWebsockets(registrationName, dNotificationXml); + + } + + /** + * Mountpoint state changed .. from connected -> connecting or unable-to-connect or vis-e-versa. + * @param registrationName Name of the event that is used as key in the database. + */ + + @Override + public void updateRegistration(String registrationName, String attribute, String attributeNewValue, NetconfNode nNode) { + AttributeValueChangedNotificationXml notificationXml = new AttributeValueChangedNotificationXml(ownKeyName, + popEvntNumber(), InternalDateAndTime.valueOf(NETCONFTIME_CONVERTER.getTimeStamp()), + registrationName, attribute, attributeNewValue); + NetworkElementConnectionEntity e = NetworkElementConnectionEntitiyUtil.getNetworkConnection(registrationName, nNode); + LOG.debug("updating networkelement-connection for {} with status {}", registrationName, e.getStatus()); + + databaseService.updateNetworkConnection22(e, registrationName); + databaseService.writeConnectionLog(notificationXml.getConnectionlogEntity()); + webSocketService.sendViaWebsockets(registrationName, notificationXml); + } + + /** + * At a mountpoint a problem situation is indicated + * + * @param registrationName indicating object within SDN controller, normally the mountpointName + * @param problemName that changed + * @param problemSeverity of the problem according to NETCONF/YANG + */ + + public void onProblemNotification(String registrationName, String problemName, InternalSeverity problemSeverity) { + LOG.debug("Got event of {} {} {}", registrationName, problemName, problemSeverity); + // notification + + ProblemNotificationXml notificationXml = + new ProblemNotificationXml(ownKeyName, registrationName, problemName, problemSeverity, + // popEvntNumberAsString(), InternalDateAndTime.TESTPATTERN ); + popEvntNumber(), InternalDateAndTime.valueOf(NETCONFTIME_CONVERTER.getTimeStamp())); + + databaseService.writeFaultLog(notificationXml.getFaultlog(SourceType.Controller)); + databaseService.updateFaultCurrent(notificationXml.getFaultcurrent()); + + aotsDcaeForwarder.sendProblemNotificationUsingMaintenanceFilter(ownKeyName, notificationXml); + + webSocketService.sendViaWebsockets(registrationName, notificationXml); + } + + @Override + public void writeEventLog(String objectId, String msg, String value) { + + LOG.debug("Got startComplete"); + EventlogBuilder eventlogBuilder = new EventlogBuilder(); + eventlogBuilder.setNodeId(ownKeyName).setTimestamp(new DateAndTime(NETCONFTIME_CONVERTER.getTimeStamp())) + .setObjectId(objectId).setAttributeName(msg).setNewValue(value).setCounter(popEvntNumber()) + .setSourceType(SourceType.Controller); + databaseService.writeEventLog(eventlogBuilder.build()); + + } + + /*--------------------------------------------- + * Handling of ODL Controller events + */ + + /** + * Called on exit to remove everything for a node from the current list. + * + * @param nodeName to remove all problems for + * @return Number of deleted objects + */ + public int removeAllCurrentProblemsOfNode(String nodeName) { + return databaseService.clearFaultsCurrentOfNodeWithObjectId(ownKeyName, nodeName); + } + + /*--------------------------------------------------------------- + * Get/Set + */ + + /** + * @return the ownKeyName + */ + public String getOwnKeyName() { + return ownKeyName; + } + + /*--------------------------------------------------------------- + * Private + */ + private Integer popEvntNumber() { + return eventNumber++; + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/handler/RpcPushNotificationsHandler.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/handler/RpcPushNotificationsHandler.java new file mode 100644 index 000000000..ff559f859 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/handler/RpcPushNotificationsHandler.java @@ -0,0 +1,90 @@ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.handler; +/******************************************************************************* + * ============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========================================================================== + ******************************************************************************/ + +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.dcaeconnector.impl.DcaeForwarderInternal; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.PushNotifications; +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.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EventlogBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EventlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.FaultcurrentBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.FaultcurrentEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.FaultlogBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.FaultlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SourceType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.PushAttributeChangeNotificationInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.PushFaultNotificationInput; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RpcPushNotificationsHandler implements PushNotifications { + + private static final Logger LOG = LoggerFactory.getLogger(RpcPushNotificationsHandler.class); + + private static String OWNKEYNAME = "VES"; + private final WebSocketServiceClientInternal webSocketService; + private final DataProvider databaseService; + private final DcaeForwarderInternal aotsDcaeForwarder; + + public RpcPushNotificationsHandler(WebSocketServiceClientInternal webSocketService, DataProvider databaseService, + DcaeForwarderInternal aotsDcaeForwarder) { + super(); + this.webSocketService = webSocketService; + this.databaseService = databaseService; + this.aotsDcaeForwarder = aotsDcaeForwarder; + } + + @Override + public void pushAttributeChangeNotification(PushAttributeChangeNotificationInput input) { + + LOG.debug("Got attribute change event {}", input); + + EventlogBuilder enventlogBuilder = new EventlogBuilder(); + enventlogBuilder.setSourceType(SourceType.Ves); + enventlogBuilder.fieldsFrom(input); + EventlogEntity eventlogEntity = enventlogBuilder.build(); + databaseService.writeEventLog(eventlogEntity); + webSocketService.sendViaWebsockets(OWNKEYNAME, new AttributeValueChangedNotificationXml(eventlogEntity)); + + } + + @Override + public void pushFaultNotification(PushFaultNotificationInput input) { + + LOG.debug("Got fault event {}", input); + + FaultlogBuilder faultlogBuilder = new FaultlogBuilder(); + faultlogBuilder.setSourceType(SourceType.Ves); + faultlogBuilder.fieldsFrom(input); + FaultlogEntity faultlogEntity = faultlogBuilder.build(); + databaseService.writeFaultLog(faultlogEntity); + + FaultcurrentBuilder faultcurrentBuilder = new FaultcurrentBuilder(); + faultcurrentBuilder.fieldsFrom(input); + FaultcurrentEntity faultcurrentEntity = faultcurrentBuilder.build(); + databaseService.updateFaultCurrent(faultcurrentEntity); + + ProblemNotificationXml notificationXml = new ProblemNotificationXml(faultlogEntity); + aotsDcaeForwarder.sendProblemNotificationUsingMaintenanceFilter(OWNKEYNAME, notificationXml); + webSocketService.sendViaWebsockets(OWNKEYNAME, notificationXml); + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/listener/NetconfChangeListener.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/listener/NetconfChangeListener.java new file mode 100644 index 000000000..2334bd181 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/listener/NetconfChangeListener.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * ============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.impl.listener; + +import java.util.Collection; + +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.NetconfNodeService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.NetconfNodeService.Action; +import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.binding.api.DataObjectModification; +import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType; +import org.opendaylight.mdsal.binding.api.DataTreeIdentifier; +import org.opendaylight.mdsal.binding.api.DataTreeModification; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +// 07.09.18 Switched to DataTreeChangeListener from ClusteredDataTreeChangeListener -> DM Service is +// running at all nodes +// This is not correct +public class NetconfChangeListener implements ClusteredDataTreeChangeListener<Node>, AutoCloseable { + + private static final Logger LOG = LoggerFactory.getLogger(NetconfChangeListener.class); + + private static final InstanceIdentifier<Node> NETCONF_NODE_TOPO_IID = + InstanceIdentifier.create(NetworkTopology.class) + .child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName()))) + .child(Node.class); + // Name of ODL controller NETCONF instance + private static final NodeId CONTROLLER = new NodeId("controller-config"); + + private final NetconfNodeService deviceManagerService; + private final DataBroker dataBroker; + private ListenerRegistration<NetconfChangeListener> dlcReg; + + public NetconfChangeListener(NetconfNodeService deviceManagerService, DataBroker dataBroker) { + this.deviceManagerService = deviceManagerService; + this.dataBroker = dataBroker; + } + + public void register() { + DataTreeIdentifier<Node> treeId = DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL, NETCONF_NODE_TOPO_IID); + + dlcReg = dataBroker.registerDataTreeChangeListener(treeId, this); + } + + @Override + public void close() { + if (dlcReg != null) { + dlcReg.close(); + } + } + /** + * Listener function to select the right node from DataObjectModification + */ + @Override + public void onDataTreeChanged(Collection<DataTreeModification<Node>> changes) { + LOG.debug("OnDataChange, TreeChange, changes:{}", changes.size()); + + for (final DataTreeModification<Node> change : changes) { + final DataObjectModification<Node> root = change.getRootNode(); + final ModificationType modificationType = root.getModificationType(); + if (LOG.isTraceEnabled()) { + LOG.trace("Handle this modificationType:{} path:{} root:{}", modificationType, change.getRootPath(), + root); + } + switch (modificationType) { + case SUBTREE_MODIFIED: + // Change of subtree information + // update(change); OLD + doProcessing(Action.UPDATE, root.getDataAfter()); + break; + case WRITE: + // Create or modify top level node + // Treat an overwrite as an update + boolean update = root.getDataBefore() != null; + if (update) { + // update(change); + doProcessing(Action.UPDATE, root.getDataAfter()); + } else { + // add(change); + doProcessing(Action.CREATE, root.getDataAfter()); + } + break; + case DELETE: + // Node removed + // remove(change); + doProcessing(Action.REMOVE, root.getDataBefore()); + break; + } + } + } + + /* + * ---------------------------------------------------------------- + */ + + /** + * Process event and forward to clients if Node is a NetconfNode + * @param action + * @param node Basis node + */ + private void doProcessing(Action action, Node node) { + + NodeId nodeId = null; + NetconfNode nnode = null; + + try { + if (node != null) { + nodeId = node.key().getNodeId(); //Never null + nnode = node.augmentation(NetconfNode.class); + } + + if (node == null || nnode == null) { + LOG.warn("Unexpected node {}, netconf node {} id {}", node, nnode, nodeId); + } else { + // Do not forward any controller related events to devicemanager + if (nodeId.equals(CONTROLLER)) { + LOG.debug("Stop processing for [{}]", nodeId); + } else { + // Action forwarded to devicehandler + deviceManagerService.netconfNodeChangeHandler(action, nodeId, nnode); + } + } + } catch (NullPointerException e) { + LOG.warn("Unexpected null .. stop processing.", e); + } + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/util/InternalDateAndTime.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/util/InternalDateAndTime.java new file mode 100644 index 000000000..b04a49bca --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/util/InternalDateAndTime.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * ============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.impl.util; + +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.NetconfTimeStamp; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl; + +/** + * Converts time stamps into internal format according to ONF1.2 and ISO 8601. + * @author herbert + * + */ +public class InternalDateAndTime { + + private static final NetconfTimeStamp NETCONFTIME_CONVERTER = NetconfTimeStampImpl.getConverter(); + + private static final InternalDateAndTime TESTPATTERN = new InternalDateAndTime("2017-01-01T00:00:00.0Z"); + private static final String INITIALPATTERN = "0000-00-00T00:00:00.0Z"; + + String internalDateAndTime = INITIALPATTERN; + + /** + * Static builder ONF1.2 + * @param time in ONF1.2 yang format + * @return InternalDateAndTime + */ +// public static InternalDateAndTime valueOf(DateAndTime time) { +// return new InternalDateAndTime(time); +// } + + /** + * Static builder ONF1.0 + * @param time in ONF1.0 yang format + * @return InternalDateAndTime + */ + + public static InternalDateAndTime valueOf(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime time) { + return new InternalDateAndTime(time); + } + + /** + * @return Getter with String representation + */ + public String getValue() { + return internalDateAndTime; + } + + /*---------------------------------------------------------------- + * Private constructors and functions + */ + + /** + * Convert ONF 1.2 DateAndTime to String + * @param time as input + */ +// private InternalDateAndTime(DateAndTime time) { +// internalDateAndTime = NETCONFTIME_CONVERTER.getTimeStampFromNetconf(time.getValue()); +// } + + /** + * Convert ONF 1.2 DateAndTime to String + * @param time as input + */ + private InternalDateAndTime(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime time) { + if (time != null) { + internalDateAndTime = NETCONFTIME_CONVERTER.getTimeStampFromNetconf(time.getValue()); + } else { + internalDateAndTime = INITIALPATTERN; + } + } + + /** + * Setup static TEST + * @param internalDateAndTime + */ + private InternalDateAndTime(String internalDateAndTime) { + this.internalDateAndTime = internalDateAndTime; + } + + /** + * Get a testpattern + * @return testpattern + */ + public static InternalDateAndTime getTestpattern() { + return TESTPATTERN; + } + + + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/util/InternalSeverity.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/util/InternalSeverity.java new file mode 100644 index 000000000..00dc4d570 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/util/InternalSeverity.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * ============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========================================================================== + ******************************************************************************/ +/** + * @author herbert + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.util; + + +import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SeverityType; + +public enum InternalSeverity { + + NonAlarmed, + Warning, + Minor, + Major, + Critical; + + public boolean isNoAlarmIndication() { + return this == NonAlarmed; + } + + public String getValueAsString() { + return this.name(); + } + + @Override + public String toString() { + return this.name(); + } + + public String toNetconfString() { + switch (this) { + case NonAlarmed: + return "non-alarmed"; + case Warning: + return "warning"; + case Minor: + return "minor"; + case Major: + return "major"; + case Critical: + return "critical"; + } + return "not-specified"; + } + + public SeverityType toDataProviderSeverityType() { + switch (this) { + case NonAlarmed: + return SeverityType.NonAlarmed; + case Warning: + return SeverityType.Warning; + case Minor: + return SeverityType.Minor; + case Major: + return SeverityType.Major; + case Critical: + return SeverityType.Critical; + } + return null; //Should never happen + } + +// /** +// * convert ONF 1.2 Severity +// * @param severity as input +// * @return String with related output +// */ +// public static InternalSeverity valueOf(org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.microwave.model.rev170324.SeverityType severity ) { +// switch( severity ) { +// case NonAlarmed: +// return InternalSeverity.NonAlarmed; +// case Warning: +// return InternalSeverity.Warning; +// case Minor: +// return InternalSeverity.Minor; +// case Major: +// return InternalSeverity.Major; +// case Critical: +// return InternalSeverity.Critical; +// } +// return null; +// } +// +// /** +// * convert ONF 1.2.1.1 Severity +// * @param severity as input +// * @return String with related output +// */ +// public static InternalSeverity valueOf(org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.microwave.model.rev180907.SeverityType severity ) { +// switch( severity ) { +// case NonAlarmed: +// return InternalSeverity.NonAlarmed; +// case Warning: +// return InternalSeverity.Warning; +// case Minor: +// return InternalSeverity.Minor; +// case Major: +// return InternalSeverity.Major; +// case Critical: +// return InternalSeverity.Critical; +// } +// return null; +// } +// +// /** +// * convert ONF 1.2.1.1p Severity +// * @param severity as input +// * @return String with related output +// */ +// public static InternalSeverity valueOf(org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.microwave.model.rev181010.SeverityType severity ) { +// switch( severity ) { +// case NonAlarmed: +// return InternalSeverity.NonAlarmed; +// case Warning: +// return InternalSeverity.Warning; +// case Minor: +// return InternalSeverity.Minor; +// case Major: +// return InternalSeverity.Major; +// case Critical: +// return InternalSeverity.Critical; +// } +// return null; +// } + + + + /** + * convert a text string into Severity + * @param severityString with textes: warning minor major critical non[-]alarmed. (Capital or lowercase) + * @return related enum. Unknown oe illegal are converted to NonAlarm + */ + public static @Nullable InternalSeverity valueOfString(String severityString) { + + switch( severityString.toLowerCase().trim() ) { + case "warning": + return InternalSeverity.Warning; + case "minor": + return InternalSeverity.Minor; + case "major": + return InternalSeverity.Major; + case "critical": + return InternalSeverity.Critical; + } + return InternalSeverity.NonAlarmed; + + } + + /** + * Convert to InternalSeverity + * @param severity to be converted + * @return InternalSeverity, null converted to NonAlarmed + */ + public static InternalSeverity valueOf(@org.eclipse.jdt.annotation.Nullable SeverityType severity) { + if (severity != null) { + switch (severity) { + case NonAlarmed: + return InternalSeverity.NonAlarmed; + case Warning: + return InternalSeverity.Warning; + case Minor: + return InternalSeverity.Minor; + case Major: + return InternalSeverity.Major; + case Critical: + return InternalSeverity.Critical; + } + } + return InternalSeverity.NonAlarmed; + } + + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/util/NetconfNotification.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/util/NetconfNotification.java new file mode 100644 index 000000000..95d6b89c4 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/util/NetconfNotification.java @@ -0,0 +1,70 @@ +/** + * ============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.impl.util; + +import java.util.Optional; +import javax.annotation.Nonnull; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.DeviceManagerImpl; +import org.opendaylight.mdsal.binding.api.MountPoint; +import org.opendaylight.mdsal.binding.api.RpcConsumerRegistry; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInput; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInputBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.NotificationsService; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NetconfNotification { + + private static final Logger log = LoggerFactory.getLogger(DeviceManagerImpl.class); + + /** + * Do the stream creation for the device. + * @param nodeId node-id of device + * @param mountpoint information + * @param streamName to register + */ + public static void registerNotificationStream(String nodeId, MountPoint mountpoint, String streamName) { + + final Optional<RpcConsumerRegistry> optionalRpcConsumerService = + mountpoint.getService(RpcConsumerRegistry.class); + if (optionalRpcConsumerService.isPresent()) { + final RpcConsumerRegistry rpcConsumerRegitry = optionalRpcConsumerService.get(); + @Nonnull + final NotificationsService rpcService = rpcConsumerRegitry.getRpcService(NotificationsService.class); + + final CreateSubscriptionInputBuilder createSubscriptionInputBuilder = new CreateSubscriptionInputBuilder(); + createSubscriptionInputBuilder.setStream(new StreamNameType(streamName)); + log.info("Event listener triggering notification stream {} for node {}", streamName, nodeId); + try { + CreateSubscriptionInput createSubscriptionInput = createSubscriptionInputBuilder.build(); + if (createSubscriptionInput == null) { + log.warn("createSubscriptionInput is null for mountpoint {}", nodeId); + } else { + rpcService.createSubscription(createSubscriptionInput); + } + } catch (NullPointerException e) { + log.warn("createSubscription failed"); + } + } else { + log.warn("No RpcConsumerRegistry avaialble."); + } + + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/util/NetworkElementConnectionEntitiyUtil.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/util/NetworkElementConnectionEntitiyUtil.java new file mode 100644 index 000000000..edbc080a5 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/util/NetworkElementConnectionEntitiyUtil.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * ============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.impl.util; + +import javax.annotation.Nonnull; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.InternalConnectionStatus; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPassword; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ConnectionLogStatus; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.NetworkElementConnectionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.NetworkElementConnectionEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.NetworkElementDeviceType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.network.element.connection.entity.NodeDetailsBuilder; +import org.opendaylight.yangtools.yang.common.QName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("deprecation") +public class NetworkElementConnectionEntitiyUtil { + + private static final Logger LOG = LoggerFactory.getLogger(NetworkElementConnectionEntitiyUtil.class); + + private static final QName QNAME_COREMODEL = QName.create("urn:onf:params:xml:ns:yang:core-model", "2017-03-20", "core-model").intern(); + + + /** + * Update devicetype and let all other field empty + * @param deviceType that should be updated + * @return NetworkElementConnectionEntity with related parameter + */ + public static NetworkElementConnectionEntity getNetworkConnectionDeviceTpe(NetworkElementDeviceType deviceType) { + NetworkElementConnectionBuilder eb = new NetworkElementConnectionBuilder(); + eb.setDeviceType(deviceType); + return eb.build(); + } + + /** + * Provide device specific data + * @param nodeId mountpoint id + * @param nNode data + * @return NetworkElementConnectionEntity specific information + */ + public static NetworkElementConnectionEntity getNetworkConnection(String nodeId, @Nonnull NetconfNode nNode) { + + NetworkElementConnectionBuilder eb = new NetworkElementConnectionBuilder(); + // -- basics + eb.setId(nodeId).setNodeId(nodeId).setDeviceType(NetworkElementDeviceType.Unknown).setIsRequired(false); + + // -- connection status + ConnectionLogStatus status = InternalConnectionStatus.statusFromNodeStatus(nNode.getConnectionStatus()); + eb.setStatus(status); + + // -- capabilites + Capabilities availableCapabilities = Capabilities.getAvailableCapabilities(nNode); + Capabilities unAvailableCapabilities = Capabilities.getUnavailableCapabilities(nNode); + + eb.setCoreModelCapability(availableCapabilities.getRevisionForNamespace(QNAME_COREMODEL)); + + NodeDetailsBuilder nodeDetails = new NodeDetailsBuilder() + .setAvailableCapabilities(availableCapabilities.getCapabilities()) + .setUnavailableCapabilities(unAvailableCapabilities.getCapabilities()); + eb.setNodeDetails(nodeDetails.build()); + // -- host information + Host host = nNode.getHost(); + PortNumber portNumber = nNode.getPort(); + if (host != null && portNumber != null) { + eb.setHost(host.stringValue()).setPort(portNumber.getValue().longValue()); + } + + Credentials credentials = nNode.getCredentials(); + if (credentials instanceof LoginPassword) { + LoginPassword loginPassword = (LoginPassword) credentials; + eb.setUsername(loginPassword.getUsername()).setPassword(loginPassword.getPassword()); + } + return eb.build(); + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/AttributeValueChangedNotificationXml.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/AttributeValueChangedNotificationXml.java new file mode 100644 index 000000000..471060c2d --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/AttributeValueChangedNotificationXml.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * ============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.impl.xml; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.util.InternalDateAndTime; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EventlogBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EventlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SourceType; + +@XmlRootElement(name = "AttributeValueChangedNotification") +public class AttributeValueChangedNotificationXml extends MwtNotificationBase implements GetEventType { + + private static String EVENTTYPE = "AttributeValueChangedNotification"; + + @XmlElement(name = "attributeName") + private String attributeName; + + @XmlElement(name = "newValue") + private String newValue; + + public AttributeValueChangedNotificationXml() { + + } + + /** + * Normalized notification + * @param nodeName name of mountpoint + * @param counter of notification + * @param timeStamp from ne + * @param objectIdRef from ne + * @param attributeName from ne + * @param newValue from ne + */ + public AttributeValueChangedNotificationXml(String nodeName, Integer counter, InternalDateAndTime timeStamp, String objectIdRef, + String attributeName, String newValue) { + super(nodeName, counter, timeStamp, objectIdRef); + this.attributeName = attributeName; + this.newValue = newValue; + } + + public AttributeValueChangedNotificationXml(EventlogEntity eventlogEntitiy) { + this(eventlogEntitiy.getNodeId(), eventlogEntitiy.getCounter(), + InternalDateAndTime.valueOf(eventlogEntitiy.getTimestamp()), eventlogEntitiy.getObjectId(), + eventlogEntitiy.getAttributeName(), eventlogEntitiy.getNewValue()); + } + + + public String getAttributeName() { + return attributeName; + } + + public String getNewValue() { + return newValue; + } + + @Override + public String getEventType() { + return EVENTTYPE; + } + + public EventlogEntity getEventlogEntity() { + return new EventlogBuilder().setAttributeName(attributeName).setNewValue(newValue) + .setCounter(Integer.valueOf(this.getCounter())) + .setNodeId(this.getNodeName()).setObjectId(this.getObjectId()) + .setTimestamp(new DateAndTime(this.getTimeStamp())).setSourceType(SourceType.Netconf).build(); + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/GetEventType.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/GetEventType.java new file mode 100644 index 000000000..ba3e23c77 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/GetEventType.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * ============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.impl.xml; + +/** + * @author herbert + * + */ +public interface GetEventType { + public String getEventType(); +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/MwtNotificationBase.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/MwtNotificationBase.java new file mode 100644 index 000000000..156f9226e --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/MwtNotificationBase.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * ============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.impl.xml; + +import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.Nonnull; +import javax.xml.bind.annotation.XmlElement; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.util.InternalDateAndTime; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ConnectionLogStatus; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ConnectionlogBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ConnectionlogEntity; + +public class MwtNotificationBase { + + private static String EMPTY = "empty"; + + private String nodeName; + private String counter; + private String timeStamp; + private @Nonnull String objectId; + + public MwtNotificationBase() { + // For Jaxb + } + + public MwtNotificationBase(String nodeName, Integer counter, InternalDateAndTime timeStamp, String objectId) { + this.nodeName = nodeName; + this.counter = String.valueOf(counter); + this.timeStamp = timeStamp.getValue(); + this.objectId = objectId; + if (this.objectId == null) { + this.objectId = EMPTY; + } + } + + @XmlElement(name = "nodeName") + public String getNodeName() { + return nodeName; + } + + @XmlElement(name = "counter") + public String getCounter() { + return counter; + } + + @XmlElement(name = "timeStamp") + public String getTimeStamp() { + return timeStamp; + } + + @XmlElement(name = "objectId") + public String getObjectId() { + return objectId; + } + + /** + * Provide ConnectionlogEntity type + * @return ConnectionlogEntity + */ + public ConnectionlogEntity getConnectionlogEntity() { + return new ConnectionlogBuilder() + .setNodeId(objectId) + .setStatus(getStatus()) + .setTimestamp(new DateAndTime(timeStamp)) + .build(); + } + + /** + * Provide connection status for mountpoint log. + * TODO Add status disconnected if mountpoint is required, but does not exists. + * @return + */ + private ConnectionLogStatus getStatus() { + + if (this instanceof ObjectCreationNotificationXml) { + return ConnectionLogStatus.Mounted; + + } else if (this instanceof ObjectDeletionNotificationXml) { + return ConnectionLogStatus.Unmounted; + + } else if (this instanceof AttributeValueChangedNotificationXml) { + String pnx = ((AttributeValueChangedNotificationXml)this).getNewValue(); + if (pnx.equals(ConnectionStatus.Connected.getName())) { + return ConnectionLogStatus.Connected; + + } else if (pnx.equals(ConnectionStatus.Connecting.getName())) { + return ConnectionLogStatus.Connecting; + + } else if (pnx.equals(ConnectionStatus.UnableToConnect.getName())) { + return ConnectionLogStatus.UnableToConnect; + } + } + return ConnectionLogStatus.Undefined; + } + + /** + * Type for the Database to document the the same name that is used in the websockets. + * @return String with type name of child class + */ + @JsonProperty("type") + public String getType() { + return this.getClass().getSimpleName(); + } + + @Override + public String toString() { + return "MwtNotificationBase [getType()="+ getType() + ", nodeName=" + nodeName + ", counter=" + counter + ", timeStamp=" + timeStamp + + ", objectId=" + objectId + "]"; + } + + + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/ObjectCreationNotificationXml.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/ObjectCreationNotificationXml.java new file mode 100644 index 000000000..210e17353 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/ObjectCreationNotificationXml.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * ============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.impl.xml; + +import javax.xml.bind.annotation.XmlRootElement; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.util.InternalDateAndTime; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EventlogBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EventlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SourceType; + +@XmlRootElement(name = "ObjectCreationNotification") +public class ObjectCreationNotificationXml extends MwtNotificationBase implements GetEventType { + + private static String EVENTTYPE = "ObjectCreationNotification"; + private static String ACTION = "creation"; + + public ObjectCreationNotificationXml() { + + } + + /** + * Normalized notification + * @param nodeName name of mountpoint or instance that owns the problem + * @param counter of notification + * @param timeStamp from ne + * @param objectIdRef from ne + */ + public ObjectCreationNotificationXml(String nodeName, Integer counter, InternalDateAndTime timeStamp, String objectIdRef) { + super(nodeName, counter, timeStamp, objectIdRef); + } + + public ObjectCreationNotificationXml(EventlogEntity el) { + this(el.getNodeId(), el.getCounter(), InternalDateAndTime.valueOf(el.getTimestamp()), el.getObjectId()); + } + + @Override + public String getEventType() { + return EVENTTYPE; + } + + public EventlogEntity getEventlogEntity() { + return new EventlogBuilder().setAttributeName(ACTION).setNewValue(ACTION) + .setCounter(Integer.valueOf(this.getCounter())) + .setNodeId(this.getNodeName()).setObjectId(this.getObjectId()) + .setTimestamp(new DateAndTime(this.getTimeStamp())).setSourceType(SourceType.Netconf).build(); + } + + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/ObjectDeletionNotificationXml.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/ObjectDeletionNotificationXml.java new file mode 100644 index 000000000..d56ef1520 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/ObjectDeletionNotificationXml.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * ============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.impl.xml; + +import javax.xml.bind.annotation.XmlRootElement; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.util.InternalDateAndTime; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EventlogBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EventlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SourceType; + +@XmlRootElement(name = "ObjectDeletionNotification") +public class ObjectDeletionNotificationXml extends MwtNotificationBase implements GetEventType { + + private static String EVENTTYPE = "ObjectDeletionNotification"; + private static String ACTION = "deletion"; + + public ObjectDeletionNotificationXml() { + + } + + /** + * Normalized notification + * @param nodeName name of mountpoint or instance that owns the problem + * @param counter of notification + * @param timeStamp from ne + * @param objectIdRef from ne + */ + public ObjectDeletionNotificationXml(String nodeName, Integer counter, InternalDateAndTime timeStamp, String objectIdRef) { + super(nodeName, counter, timeStamp, objectIdRef); + } + + public ObjectDeletionNotificationXml(EventlogEntity el) { + this(el.getNodeId(), el.getCounter(), InternalDateAndTime.valueOf(el.getTimestamp()), el.getObjectId()); + } + + @Override + public String getEventType() { + return EVENTTYPE; + } + + public EventlogEntity getEventlogEntity() { + return new EventlogBuilder().setAttributeName(ACTION).setNewValue(ACTION) + .setCounter(Integer.valueOf(this.getCounter())) + .setNodeId(this.getNodeName()).setObjectId(this.getObjectId()) + .setTimestamp(new DateAndTime(this.getTimeStamp())).setSourceType(SourceType.Netconf).build(); + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/ProblemNotificationXml.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/ProblemNotificationXml.java new file mode 100644 index 000000000..dcb299a8e --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/ProblemNotificationXml.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * ============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.impl.xml; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import java.util.List; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.database.FaultEntityManager; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.util.InternalDateAndTime; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.util.InternalSeverity; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Faultcurrent; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.FaultcurrentBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Faultlog; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.FaultlogBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.FaultlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SourceType; +import org.slf4j.Logger; + +@XmlRootElement(name = "ProblemNotification") +public class ProblemNotificationXml extends MwtNotificationBase implements GetEventType { + + private static String EVENTTYPE = "ProblemNotification"; + + @XmlElement(name = "problem") + private String problem; + + @XmlElement(name = "severity") + private InternalSeverity severity; + + public ProblemNotificationXml() { + + } + + /** + * Generic Problem. All the parameters are of type Strings according to YANG + * specification. + * + * @param nodeName Name of mountpoint + * @param uuId Name of Interface Pac + * @param problemNameString Name of the problem + * @param problemSeverityString Severitycode of the problem + * @param counter Counter from device + * @param internaltimeStampString Timestamp according to internal format. + */ + public ProblemNotificationXml(String nodeName, String uuId, String problemNameString, + InternalSeverity problemSeverityString, Integer counter, InternalDateAndTime internaltimeStampString) { + super(nodeName, counter, internaltimeStampString, uuId); + this.problem = problemNameString; + this.severity = problemSeverityString; + } + + public ProblemNotificationXml(FaultlogEntity input) { + this(input.getNodeId(), input.getObjectId(), input.getProblem(), InternalSeverity.valueOf(input.getSeverity()), + input.getCounter(), InternalDateAndTime.valueOf(input.getTimestamp())); + } + + public String getProblem() { + return problem; + } + + public InternalSeverity getSeverity() { + return severity; + } + + public boolean isNotManagedAsCurrentProblem() { + return ! FaultEntityManager.isManagedAsCurrentProblem(getProblem()); + } + + public boolean isNoAlarmIndication() { + return severity.isNoAlarmIndication(); + } + + /** + * Create a specific ES id for the current log. + * @return a string with the generated ES Id + */ + @JsonIgnore + public String genSpecificEsId() { + return FaultEntityManager.genSpecificEsId(getNodeName(), getObjectId(), getProblem()); + } + + @JsonIgnore + public Faultlog getFaultlog(SourceType sourceType) { + return new FaultlogBuilder().setNodeId(getNodeName()).setCounter(Integer.parseInt(getCounter())) + .setObjectId(getObjectId()).setProblem(getProblem()).setSourceType(sourceType) + .setSeverity(getSeverity().toDataProviderSeverityType()).setTimestamp(new DateAndTime(getTimeStamp())) + .build(); + } + + @JsonIgnore + public Faultcurrent getFaultcurrent() { + return new FaultcurrentBuilder().setNodeId(getNodeName()).setCounter(Integer.parseInt(getCounter())) + .setObjectId(genSpecificEsId()).setProblem(getProblem()) + .setSeverity(getSeverity().toDataProviderSeverityType()).setTimestamp(new DateAndTime(getTimeStamp())) + .build(); + } + + @Override + public String toString() { + return "ProblemNotificationXml [problem=" + problem + ", severity=" + severity + ", toString()=" + + super.toString() + "]"; + } + + @Override + public String getEventType() { + return EVENTTYPE; + } + + /** + * LOG the newly added problems of the interface pac + * @param log of logger + * @param uuid as log info + * @param resultList with all problems + * @param idxStart start of listing till end + */ + public static void debugResultList(Logger log, 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()); + } + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/WebSocketServiceClientDummyImpl.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/WebSocketServiceClientDummyImpl.java new file mode 100644 index 000000000..fa6bb1887 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/WebSocketServiceClientDummyImpl.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * ============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.impl.xml; + +import org.eclipse.jdt.annotation.NonNull; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.handler.ODLEventListenerHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * WrapperMock class for web-socket notifications to the web-socket service. + */ +public class WebSocketServiceClientDummyImpl implements WebSocketServiceClientInternal { + + private static final Logger LOG = LoggerFactory.getLogger(ODLEventListenerHandler.class); + + public WebSocketServiceClientDummyImpl() { + } + + @Override + public <T extends MwtNotificationBase & GetEventType> void sendViaWebsockets(@NonNull String nodeName, @NonNull T notificationXml) { + LOG.info("Dummy to send websocket event {} for mountpoint {}", notificationXml.getClass().getSimpleName(), nodeName); + } + + @Override + public void close() throws Exception { + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/WebSocketServiceClientImpl2.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/WebSocketServiceClientImpl2.java new file mode 100644 index 000000000..8c01438ca --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/WebSocketServiceClientImpl2.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * ============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.impl.xml; + +import java.util.concurrent.Future; +import org.eclipse.jdt.annotation.NonNull; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.handler.ODLEventListenerHandler; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EventlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.websocketmanager.rev150105.WebsocketEventInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.websocketmanager.rev150105.WebsocketEventOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.websocketmanager.rev150105.WebsocketmanagerService; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Wrapper for forwarding web-socket notifications to the web-socket service, that is running as + * bundle. + */ +@SuppressWarnings("deprecation") +public class WebSocketServiceClientImpl2 implements WebSocketServiceClientInternal { + + private static final Logger LOG = LoggerFactory.getLogger(ODLEventListenerHandler.class); + + private final WebsocketmanagerService websocketmanagerService; + private final XmlMapper xmlMapper; + + /** + * Implementation of Websocket notification processor. + * @param rpcProviderRegistry to get MDSAL services. + */ + @Deprecated + public WebSocketServiceClientImpl2(@NonNull RpcProviderRegistry rpcProviderRegistry) { + super(); + this.websocketmanagerService = rpcProviderRegistry.getRpcService(WebsocketmanagerService.class); + this.xmlMapper = new XmlMapper(); + } + + /** + * New: Implementation of Websocket notification processor. + * @param websocketmanagerService2 to be used + */ + public WebSocketServiceClientImpl2(WebsocketmanagerService websocketmanagerService2) { + super(); + this.websocketmanagerService = websocketmanagerService2; + this.xmlMapper = new XmlMapper(); + } + + @Override + public <T extends MwtNotificationBase & GetEventType> void sendViaWebsockets(@NonNull String nodeName, @NonNull T notificationXml) { + LOG.info("Send websocket event {} for mountpoint {}", notificationXml.getClass().getSimpleName(), nodeName); + + try { + WebsocketEventInputBuilder wsBuilder = new WebsocketEventInputBuilder(); + wsBuilder.setNodeName(nodeName); + wsBuilder.setEventType(notificationXml.getEventType()); + wsBuilder.setXmlEvent(xmlMapper.getXmlString(notificationXml)); + Future<RpcResult<WebsocketEventOutput>> result = websocketmanagerService.websocketEvent(wsBuilder.build()); + LOG.info("Send websocket result: {}", result.get().getResult().getResponse()); + } catch (Exception e) { + LOG.warn("Can not send websocket event {} for mountpoint {} {}", notificationXml.getClass().getSimpleName(), + nodeName, e.toString()); + } + } + + @Override + public void close() throws Exception { + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/WebSocketServiceClientInternal.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/WebSocketServiceClientInternal.java new file mode 100644 index 000000000..75be0badd --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/WebSocketServiceClientInternal.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * ============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.impl.xml; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * Wrapper for forwarding websocket notifications to the websocket service, that is running as container. + * @author herbert + */ +public interface WebSocketServiceClientInternal extends AutoCloseable { + + public <T extends MwtNotificationBase & GetEventType> void sendViaWebsockets(@NonNull String nodeName, @NonNull T notificationXml); + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/XmlMapper.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/XmlMapper.java new file mode 100644 index 000000000..897795a0e --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/xml/XmlMapper.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * ============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.impl.xml; + +import java.io.StringWriter; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class XmlMapper { + private static final Logger LOG = LoggerFactory.getLogger(XmlMapper.class); + + public String getXmlString(MwtNotificationBase base) { + String xml; + JAXBContext jaxbContext; + try { + jaxbContext = JAXBContext.newInstance(AttributeValueChangedNotificationXml.class, + ObjectCreationNotificationXml.class, ObjectDeletionNotificationXml.class, + ProblemNotificationXml.class); + Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); + jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + + StringWriter stringWriter = new StringWriter(); + jaxbMarshaller.marshal(base, stringWriter); + xml = stringWriter.toString(); + } catch (JAXBException e) { + LOG.warn("Problem in marshalling xml file {}", e); + xml = null; + } + return xml; + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/maintenance/MaintenanceRPCServiceAPI.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/maintenance/MaintenanceRPCServiceAPI.java new file mode 100644 index 000000000..3687625a0 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/maintenance/MaintenanceRPCServiceAPI.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * ============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.maintenance; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.GetMaintenanceModeInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.GetMaintenanceModeOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.GetRequiredNetworkElementKeysOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.SetMaintenanceModeInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.SetMaintenanceModeOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.ShowRequiredNetworkElementInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.ShowRequiredNetworkElementOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.TestMaintenanceModeInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.TestMaintenanceModeOutputBuilder; + +public interface MaintenanceRPCServiceAPI { + + public GetRequiredNetworkElementKeysOutputBuilder getRequiredNetworkElementKeys(); + + public ShowRequiredNetworkElementOutputBuilder showRequiredNetworkElement(ShowRequiredNetworkElementInput input); + + public GetMaintenanceModeOutputBuilder getMaintenanceMode(GetMaintenanceModeInput input); + + public SetMaintenanceModeOutputBuilder setMaintenanceMode(SetMaintenanceModeInput input); + + public TestMaintenanceModeOutputBuilder testMaintenanceMode(TestMaintenanceModeInput input); + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/maintenance/impl/MaintenanceCalculator.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/maintenance/impl/MaintenanceCalculator.java new file mode 100644 index 000000000..8771b4c2f --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/maintenance/impl/MaintenanceCalculator.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * ============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.maintenance.impl; + +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.MaintenanceEntity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MaintenanceCalculator { + + private static final Logger LOG = LoggerFactory.getLogger(MaintenanceCalculator.class); + + private static ZoneId EsMaintenanceFilterTimeZone = ZoneId.of("UTC"); + //private static DateTimeFormatter FORMAT = DateTimeFormatter.ISO_DATE_TIME; // "1986-04-08T12:30:00" + private static DateTimeFormatter FORMAT = DateTimeFormatter.ISO_OFFSET_DATE_TIME; // 2011-12-03T10:15:30+01:00 + private static ZonedDateTime EMPTYDATETIME = ZonedDateTime.ofInstant(Instant.EPOCH, EsMaintenanceFilterTimeZone); + + /** Intended to be used static **/ + private MaintenanceCalculator() { + } + + + + + /** + * Verify maintenance status + * @param maintenance if null false, else according to settings + * @param objectIdRef NETCONF object id + * @param problem name that was provided + * @param now time to verify with + * @return true if in maintenance status + */ + public static boolean isONFObjectInMaintenance(MaintenanceEntity maintenance, String objectIdRef, String problem, + ZonedDateTime now) { + + if (maintenance != null) { + Boolean isActive = maintenance.isActive(); + if (isActive != null && isActive && isInMaintenance(maintenance, objectIdRef, problem, now)) { + return true; + } + + } + return false; + } + + /** Shortcut **/ + public static boolean isONFObjectInMaintenance(MaintenanceEntity maintenance, String objectIdRef, String problem) { + return isONFObjectInMaintenance(maintenance, objectIdRef, problem, getNow()); + } + + + /*--------------------------------------------- + * private static helper functions to verify + */ + + /** + * Get the actual time in the Filter time zone. + * @return actual Time + */ + private static ZonedDateTime getNow() { + return ZonedDateTime.now(EsMaintenanceFilterTimeZone); + } + + + /** + * Verify if the filter is active for an object + * + * @param now point of time to verify + * @return if the object is covered by filter and now within point of time + */ + private static boolean isInMaintenance(MaintenanceEntity maintenance, String objectIdRef, String problem, ZonedDateTime now) { + return appliesToObjectReference(maintenance, objectIdRef, problem) && isInPeriod(maintenance.getStart(), maintenance.getEnd(), now); + } + + /** + * Compare the if probe is within the range of start and end. + * + * @param start of range + * @param end of range + * @param probe time to verify + * @return boolean result true if (start <= probe <= end) + */ + public static boolean isInPeriod(DateAndTime start, DateAndTime end, ZonedDateTime probe) { + ZonedDateTime startZT = valueOf(start.getValue()); + ZonedDateTime endZT = valueOf(end.getValue()); + return startZT.compareTo(endZT) < 0 && startZT.compareTo(probe) <= 0 && endZT.compareTo(probe) >= 0; + } + + /** + * Verify if the definied object is matching to the referenced object + * @param definition definition with parameters + * @param pObjectIdRef If empty considered as true + * @param pProblem if empty considered as true + * @return true if if referenced + */ + private static boolean appliesToObjectReference(@Nonnull MaintenanceEntity definition, @Nonnull String pObjectIdRef, @Nonnull String pProblem) { + boolean res = (pObjectIdRef.isEmpty() || pObjectIdRef.contains(definition.getObjectIdRef())) + && (pProblem.isEmpty() || pProblem.contains(definition.getProblem())); + LOG.debug("Check result applies {}: {} {} against: {}", res, pObjectIdRef, pProblem, definition); + return res; + } + + /** + * Convert String to time value + * @param zoneTimeString with time + * @return ZonedDateTime string + */ + static ZonedDateTime valueOf(String zoneTimeString) { + if (zoneTimeString == null || zoneTimeString.isEmpty()) { + LOG.warn("Null or empty zoneTimeString"); + return EMPTYDATETIME; + } + try { + return ZonedDateTime.parse(zoneTimeString, FORMAT); + } catch (DateTimeParseException e) { + LOG.warn("Can not parse zoneTimeString '{}'",zoneTimeString); + return EMPTYDATETIME; + } + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/maintenance/impl/MaintenanceServiceImpl.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/maintenance/impl/MaintenanceServiceImpl.java new file mode 100644 index 000000000..6f68589f2 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/maintenance/impl/MaintenanceServiceImpl.java @@ -0,0 +1,168 @@ +/******************************************************************************* + * ============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.maintenance.impl; + +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.List; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtDatabaseMaintenance; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.maintenance.MaintenanceRPCServiceAPI; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.MaintenanceService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.MaintenanceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.MaintenanceEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.GetMaintenanceModeInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.GetMaintenanceModeOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.GetRequiredNetworkElementKeysOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.SetMaintenanceModeInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.SetMaintenanceModeOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.ShowRequiredNetworkElementInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.ShowRequiredNetworkElementOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.TestMaintenanceModeInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.TestMaintenanceModeOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.devicemanager.rev190109.show.required.network.element.output.RequiredNetworkElementBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MaintenanceServiceImpl implements MaintenanceService, MaintenanceRPCServiceAPI, AutoCloseable { + + private static final Logger LOG = LoggerFactory.getLogger(MaintenanceServiceImpl.class); + + private final HtDatabaseMaintenance database; + + public MaintenanceServiceImpl(HtDatabaseMaintenance client) throws ClassNotFoundException { + + LOG.info("Create {} start", MaintenanceServiceImpl.class); + database = client; + LOG.info("Create {} finished. DB Service {} started.", MaintenanceServiceImpl.class, client != null ? "sucessfully" : "not" ); + + } + + @Override + public void createIfNotExists(String mountPointNodeName) { + database.createIfNotExists(mountPointNodeName); + } + + @Override + public void deleteIfNotRequired(String mountPointNodeName) { + database.deleteIfNotRequired(mountPointNodeName); + } + + /*------------------------------------------------- + * Interface AutoClosable + */ + + @Override + public void close() throws Exception { + } + + /*------------------------------------------------- + * Interface MaintenanceRPCServiceAPI + */ + + @Override + public GetRequiredNetworkElementKeysOutputBuilder getRequiredNetworkElementKeys() { + List<MaintenanceEntity> all = database.getAll(); + + List<String> mountpointList = new ArrayList<>(); + for (MaintenanceEntity oneOfAll : all) { + mountpointList.add(oneOfAll.getNodeId()); + + } + GetRequiredNetworkElementKeysOutputBuilder outputBuilder = new GetRequiredNetworkElementKeysOutputBuilder(); + outputBuilder.setMountpointNames(mountpointList); + return outputBuilder; + } + + @Override + public ShowRequiredNetworkElementOutputBuilder showRequiredNetworkElement(ShowRequiredNetworkElementInput input) { + ShowRequiredNetworkElementOutputBuilder outputBuilder = new ShowRequiredNetworkElementOutputBuilder(); + MaintenanceEntity maintenanceMode = database.getMaintenance(input.getMountpointName()); + if (maintenanceMode != null) { + RequiredNetworkElementBuilder valueBuilder = new RequiredNetworkElementBuilder(); + + valueBuilder.setMountpointName(maintenanceMode.getNodeId()); + valueBuilder.setStatus(String.valueOf(MaintenanceCalculator.isONFObjectInMaintenance(maintenanceMode, "",""))); + valueBuilder.setDescription("Pretty description here"); + outputBuilder.setRequiredNetworkElement(valueBuilder.build()); + } else { + LOG.warn("No info in database for {}",input.getMountpointName()); + } + return outputBuilder; + } + + @Override + public GetMaintenanceModeOutputBuilder getMaintenanceMode(GetMaintenanceModeInput input) { + + GetMaintenanceModeOutputBuilder outputBuilder; + MaintenanceEntity maintenanceMode = database.getMaintenance(input.getMountpointName()); + if (maintenanceMode != null) { + outputBuilder = new GetMaintenanceModeOutputBuilder(maintenanceMode); + } else { + throw new IllegalArgumentException("No info in database for "+input.getMountpointName()); + } + return outputBuilder; + } + + @Override + public SetMaintenanceModeOutputBuilder setMaintenanceMode(SetMaintenanceModeInput input) { + + SetMaintenanceModeOutputBuilder outputBuilder = new SetMaintenanceModeOutputBuilder(); + MaintenanceBuilder mb = new MaintenanceBuilder(input); + MaintenanceEntity m = mb.build(); + database.setMaintenance(m); + return outputBuilder; + + } + + @Override + public TestMaintenanceModeOutputBuilder testMaintenanceMode(TestMaintenanceModeInput input) { + + StringBuffer resultString = new StringBuffer(); + + MaintenanceEntity maintenanceMode = database.getMaintenance(input.getMountpointName()); + + ZonedDateTime now = MaintenanceCalculator.valueOf(input.getTestDate()); + + resultString.append("In database table: "); + resultString.append(maintenanceMode != null); + resultString.append(" Maintenance active: "); + resultString.append(MaintenanceCalculator.isONFObjectInMaintenance(maintenanceMode, input.getObjectIdRef(), + input.getProblemName(), now)); + resultString.append(" at Timestamp: "); + resultString.append(now); + TestMaintenanceModeOutputBuilder outputBuilder = maintenanceMode != null + ? new TestMaintenanceModeOutputBuilder(maintenanceMode) + : new TestMaintenanceModeOutputBuilder(); + outputBuilder.setResultString(resultString.toString()); + return outputBuilder; + + } + + /*------------------------------------------------- + * Interface MaintenaceService + */ + + @Override + public boolean isONFObjectInMaintenance(String mountpointReference, String objectIdRef, String problem) { + MaintenanceEntity maintenanceMode = database.getMaintenance(mountpointReference); + boolean res = MaintenanceCalculator.isONFObjectInMaintenance(maintenanceMode, objectIdRef, problem); + LOG.debug("inMaintenance={} for mountpoint/id/problem:{} {} {} Definition: {}",res, mountpointReference, objectIdRef, problem, this ); + return res; + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/performancemanager/impl/PerformanceManagerImpl.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/performancemanager/impl/PerformanceManagerImpl.java new file mode 100644 index 000000000..de40fb1c4 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/performancemanager/impl/PerformanceManagerImpl.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * ============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.performancemanager.impl; + +import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.performancemanager.impl.config.PmConfig; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.performancemanager.impl.database.service.MicrowaveHistoricalPerformanceWriterService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NetconfNetworkElementService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.PerformanceManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PerformanceManagerImpl implements PerformanceManager, AutoCloseable { + + private static final Logger LOG = LoggerFactory.getLogger(PerformanceManagerImpl.class); + + private PerformanceManagerTask task; + + public PerformanceManagerImpl(long seconds, NetconfNetworkElementService netconfNetworkElementService, + MicrowaveHistoricalPerformanceWriterService microwaveHistoricalPerformanceWriterService, + ConfigurationFileRepresentation config) { + + LOG.info("Construct {}", PerformanceManagerImpl.class.getSimpleName()); + + this.task = null; + PmConfig configurationPM = new PmConfig(config); + LOG.info("Performance manager configuration: {}", configurationPM); + + if (!configurationPM.isPerformanceManagerEnabled()) { + LOG.info("Don't start performance manager"); + + } else { + LOG.info("{} Seconds", seconds); + LOG.info("Start of PM task"); + task = new PerformanceManagerTask(seconds, microwaveHistoricalPerformanceWriterService, netconfNetworkElementService); + task.start(); + LOG.info("PM task scheduled"); + } + + LOG.info("Construct end {}", PerformanceManagerImpl.class.getSimpleName()); + } + + @Override + public void close() { + LOG.info("Close {}", PerformanceManagerImpl.class.getSimpleName()); + if (task != null) { + task.stop(); + } + } + + @Override + public void registration(String mountPointNodeName, NetworkElement ne) { + LOG.debug("Register {}",mountPointNodeName); + if (task != null) { + task.registration(mountPointNodeName, ne); + } + } + + @Override + public void deRegistration(String mountPointNodeName) { + LOG.debug("Deregister {}",mountPointNodeName); + if (task != null) { + task.deRegistration(mountPointNodeName); + } + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/performancemanager/impl/PerformanceManagerTask.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/performancemanager/impl/PerformanceManagerTask.java new file mode 100644 index 000000000..465d9ccee --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/performancemanager/impl/PerformanceManagerTask.java @@ -0,0 +1,254 @@ +/******************************************************************************* + * ============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.performancemanager.impl; + +import java.util.Iterator; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.PerformanceDataProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.performancemanager.impl.database.service.MicrowaveHistoricalPerformanceWriterService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NetconfNetworkElementService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.PerformanceDataLtp; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PerformanceManagerTask implements Runnable { + + private static final Logger LOG = LoggerFactory.getLogger(PerformanceManagerTask.class); + private static final String LOGMARKER = "PMTick"; + + private int tickCounter = 0; + + private final ConcurrentHashMap<String, PerformanceDataProvider> queue = new ConcurrentHashMap<>(); + private final MicrowaveHistoricalPerformanceWriterService databaseService; + private final ScheduledExecutorService scheduler; + private final long seconds; + + private ScheduledFuture<?> taskHandle = null; + private Iterator<PerformanceDataProvider> neIterator = null; + private PerformanceDataProvider actualNE = null; + private final NetconfNetworkElementService netconfNetworkElementService; + + /** + * Constructor of PM Task + * @param seconds seconds to call PM Task + * @param microwaveHistoricalPerformanceWriterService DB Service to load PM data to + * @param netconfNetworkElementService to write into log + */ + + public PerformanceManagerTask(long seconds, + MicrowaveHistoricalPerformanceWriterService microwaveHistoricalPerformanceWriterService, + NetconfNetworkElementService netconfNetworkElementService) { + + LOG.debug("Init task {}", PerformanceManagerTask.class.getSimpleName()); + this.seconds = seconds; + this.databaseService = microwaveHistoricalPerformanceWriterService; + this.scheduler = Executors.newSingleThreadScheduledExecutor(); + this.netconfNetworkElementService = netconfNetworkElementService; + + } + + /** + * Start PM Task + */ + public void start() { + LOG.info("PM task created"); + taskHandle = this.scheduler.scheduleAtFixedRate(this, 0, seconds, TimeUnit.SECONDS); + LOG.info("PM task scheduled"); + } + + /** + * Stop everything + */ + public void stop() { + LOG.info("Stop {}", PerformanceManagerImpl.class.getSimpleName()); + if (taskHandle != null) { + taskHandle.cancel(true); + try { + scheduler.awaitTermination(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + LOG.debug("Schdule stopped.",e); + // Restore interrupted state... + Thread.currentThread().interrupt(); + } + } + } + + /** + * Add NE/Mountpoint to PM Processig + * @param mountPointNodeName to be added + * @param ne that is connected to the mountpoint + */ + public void registration(String mountPointNodeName, NetworkElement ne) { + + Optional<PerformanceDataProvider> oPmNe = ne.getService(PerformanceDataProvider.class); + if (oPmNe.isPresent()) { + queue.put(mountPointNodeName, oPmNe.get()); + } + } + + /** + * Remove mountpoint/NE from PM process + * @param mountPointNodeName that has to be removed + */ + public void deRegistration(String mountPointNodeName) { + LOG.debug("Deregister {}",mountPointNodeName); + PerformanceDataProvider removedNE = queue.remove(mountPointNodeName); + + if ( removedNE == null) { + LOG.warn("Couldn't delete {}",mountPointNodeName); + } + } + + + /*-------------------------------------------------------------- + * Task to read PM data from NE + */ + + /** + * Task runner to read all performance data from Network Elements. + * Catch exceptions to make sure, that the Task is not stopped. + */ + @Override + public void run() { + + String mountpointName = "No NE"; + if (actualNE != null && actualNE.getAcessor().isPresent()) { + mountpointName = actualNE.getAcessor().get().getNodeId().getValue(); + } + LOG.debug("{} start {} Start with mountpoint {}",LOGMARKER, tickCounter, mountpointName); + + //Proceed to next NE/Interface + getNextInterface(mountpointName); + + LOG.debug("{} {} Next interface to handle {}", LOGMARKER, tickCounter, + actualNE == null ? "No NE/IF" : actualNE.pmStatusToString()); + + if (actualNE != null) { + try { + LOG.debug("{} Start to read PM from NE ({})", LOGMARKER, tickCounter); + Optional<PerformanceDataLtp> allPm = actualNE.getLtpHistoricalPerformanceData(); + if (allPm.isPresent()) { + LOG.debug("{} {} Got PM list. Start write to DB", LOGMARKER, tickCounter); + databaseService.writePM(allPm.get()); + } + LOG.debug("{} {} PM List end.", LOGMARKER, tickCounter); + } catch (Exception e) { + StringBuffer msg = new StringBuffer(); + msg.append(e.getMessage()); + msg.append(" - "); + msg.append(e.getCause().toString()); + msg.append(" - "); + msg.append(actualNE.pmStatusToString()); + String msgString = msg.toString(); + LOG.warn("{} {} PM read/write failed. Write log entry {}", LOGMARKER, tickCounter, msgString); + netconfNetworkElementService.writeToEventLog(mountpointName, "PM Problem", msgString); + } + } + + LOG.debug("{} end {}",LOGMARKER, tickCounter); + tickCounter++; + } + + /** + * Reset queue to start from beginning + */ + private void resetQueue() { + actualNE = null; + neIterator = null; + } + + /** + * Get then next interface in the list. + * First try to find a next on the actual NE. + * If not available search next interface at a NE + * Special Situations to handle: Empty queue, NEs, but no interfaces + */ + private void getNextInterface(String mountpointName) { + boolean started = false; + int loopCounter = 0; + + LOG.debug("{} {} getNextInterface enter. Queue size {} ", LOGMARKER, tickCounter, queue.size()); + + if (actualNE != null && !queue.containsValue(actualNE)) { + LOG.debug("{} {} NE Removed duringprocessing A",LOGMARKER, tickCounter); + resetQueue(); + } + + while (true) { + + if (loopCounter++ >= 1000) { + LOG.error("{} {} Problem in PM iteration. endless condition reached", LOGMARKER, tickCounter); + resetQueue(); + break; + } + + LOG.debug("{} {} Loop ne {}:neiterator {}:Interfaceiterator:{} Loop:{}", + LOGMARKER, + tickCounter, + actualNE == null? "null" : mountpointName, + neIterator == null ? "null" : neIterator.hasNext(), + actualNE == null ? "null" : actualNE.hasNext(), + loopCounter); + + if (actualNE != null && actualNE.hasNext()) { + // Yes, there is an interface, deliver back + LOG.debug("{} {} getNextInterface yes A",LOGMARKER, tickCounter); + actualNE.next(); + break; + + } else { + // No element in neInterfaceInterator .. get next NE and try + if (neIterator != null && neIterator.hasNext()) { + // Set a new NE + LOG.debug("{} {} Next NE A",LOGMARKER, tickCounter); + actualNE = neIterator.next(); + actualNE.resetPMIterator(); + + } else { + // Goto start condition 1) first entry 2) end of queue reached + LOG.debug("{} {} Reset",LOGMARKER, tickCounter); + resetQueue(); + + if (queue.isEmpty()) { + LOG.debug("{} {} no nextInterfac. queue empty",LOGMARKER, tickCounter); + break; + } else if (!started){ + LOG.debug("{} {} getNextInterface start condition. Get interator.",LOGMARKER, tickCounter); + neIterator = queue.values().iterator(); + started = true; + } else { + LOG.debug("{} {} no nextInterface",LOGMARKER, tickCounter); + break; + } + } + } + } //while + + if (actualNE != null && !queue.containsValue(actualNE)) { + LOG.debug("{} {} NE Removed duringprocessing B",LOGMARKER, tickCounter); + resetQueue(); + } + + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/performancemanager/impl/config/PmConfig.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/performancemanager/impl/config/PmConfig.java new file mode 100644 index 000000000..e4d06c6fb --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/performancemanager/impl/config/PmConfig.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * ============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.performancemanager.impl.config; + +import org.onap.ccsdk.features.sdnr.wt.common.configuration.Configuration; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; + +public class PmConfig implements Configuration { + + private static final String SECTION_MARKER_PM = "pm"; + + private static final String PROPERTY_KEY_ENABLED = "pmEnabled"; + private static final String DEFAULT_VALUE_ENABLED = String.valueOf(true); + + + private final ConfigurationFileRepresentation configuration; + + public PmConfig(ConfigurationFileRepresentation configuration) { + this.configuration = configuration; + this.configuration.addSection(SECTION_MARKER_PM); + defaults(); + } + + public boolean isPerformanceManagerEnabled() { + return configuration.getPropertyBoolean(SECTION_MARKER_PM, PROPERTY_KEY_ENABLED); + } + + @Override + public String getSectionName() { + return SECTION_MARKER_PM; + } + + @Override + public void defaults() { + //Add default if not available + configuration.setPropertyIfNotAvailable(SECTION_MARKER_PM, PROPERTY_KEY_ENABLED, DEFAULT_VALUE_ENABLED); + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/performancemanager/impl/database/service/MicrowaveHistoricalPerformanceWriterService.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/performancemanager/impl/database/service/MicrowaveHistoricalPerformanceWriterService.java new file mode 100644 index 000000000..da4387a1a --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/performancemanager/impl/database/service/MicrowaveHistoricalPerformanceWriterService.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * ============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.performancemanager.impl.database.service; + +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.PerformanceDataLtp; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MicrowaveHistoricalPerformanceWriterService { + + private static final Logger LOG = LoggerFactory.getLogger(MicrowaveHistoricalPerformanceWriterService.class); + + private final DataProvider dataProvider; +// private HtDataBaseReaderAndWriter<EsHistoricalPerformance15Minutes> historicalPerformance15mRW; +// private HtDataBaseReaderAndWriter<EsHistoricalPerformance24Hours> historicalPerformance24hRW; +// private HtDataBaseReaderAndWriter<EsHistoricalPerformanceLogEntry> historicalPerformanceLogRW; + + @Deprecated + public MicrowaveHistoricalPerformanceWriterService(DataProvider dataProvider) { + + LOG.info("Create {} start", MicrowaveHistoricalPerformanceWriterService.class); + this.dataProvider = dataProvider; + + LOG.info("Create {} finished. DB Service {} started.", MicrowaveHistoricalPerformanceWriterService.class, + dataProvider != null ? "sucessfully" : "not"); + } + + +// public void writePM(AllPm pm) { +// LOG.debug("Write {} pm records", pm.size()); +// +// LOG.debug("Write 15m write to DB"); +// historicalPerformance15mRW.doWrite(pm.getPm15()); +// LOG.debug("Write 15m done, Write 24h write to DB"); +// historicalPerformance24hRW.doWrite(pm.getPm24()); +// LOG.debug("Write 24h done"); +// } +// + /** + * @param performanceDataLtp + */ + public void writePM(PerformanceDataLtp performanceDataLtp) { + + dataProvider.doWritePerformanceData(performanceDataLtp.getList()); + } + + static public boolean isAvailable(MicrowaveHistoricalPerformanceWriterService s) { + + if (s == null || s.dataProvider == null) { + return false; + } + return true; + } + + + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/toggleAlarmFilter/DevicemanagerNotificationDelayService.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/toggleAlarmFilter/DevicemanagerNotificationDelayService.java new file mode 100644 index 000000000..6bfca6907 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/toggleAlarmFilter/DevicemanagerNotificationDelayService.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * ============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.toggleAlarmFilter; + +import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.xml.ProblemNotificationXml; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerService; + +/** + * Devicemanager service + */ +public class DevicemanagerNotificationDelayService extends NotificationDelayService<ProblemNotificationXml> implements DeviceManagerService { + + public DevicemanagerNotificationDelayService(ConfigurationFileRepresentation htconfig) { + super(htconfig); + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/toggleAlarmFilter/NotificationDelayFilter.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/toggleAlarmFilter/NotificationDelayFilter.java new file mode 100644 index 000000000..92af68bc0 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/toggleAlarmFilter/NotificationDelayFilter.java @@ -0,0 +1,181 @@ +/******************************************************************************* + * ============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.toggleAlarmFilter; + +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NotificationDelayFilter<T> implements AutoCloseable { + + private static final Logger LOG = LoggerFactory.getLogger(NotificationDelayFilter.class); + + private final ConcurrentHashMap <String, NotificationWithServerTimeStamp<T>> problemItems; +// private final HashMap<String, NotificationWithServerTimeStamp<T>> nonProblemItems; + private final NotificationDelayedListener<T> timeoutListener; + + private static long delay; + private static boolean enabled; + + public static void setDelay(long l) { + NotificationDelayFilter.delay = l; + } + + public static long getDelay() { + return NotificationDelayFilter.delay; + } + + public static boolean isEnabled() { + return NotificationDelayFilter.enabled; + } + + public static void setEnabled(boolean enabled) { + NotificationDelayFilter.enabled = enabled; + } + + private final ScheduledExecutorService scheduler; + private final Runnable timerRunner = () -> onTick(); + + private final String nodeName; + + public NotificationDelayFilter(String nodeName, NotificationDelayedListener<T> timeoutListener) { + this.nodeName = nodeName; + this.timeoutListener = timeoutListener; + this.problemItems = new ConcurrentHashMap <>(); + this.scheduler = Executors.newScheduledThreadPool(1); + this.startTimer(); + } + + /** + * If process the notification + * @return true if other processing is required, false if not + */ + public boolean processNotification(boolean cleared, String problemName, T notificationXml) { + // ToggleAlarmFilter functionality + if (NotificationDelayFilter.isEnabled()) { + if (cleared) { + clearAlarmNotification(problemName, notificationXml); + } else { + pushAlarmNotification(problemName, notificationXml); + } + return false; + } else { + return true; + } + // end of ToggleAlarmFilter + } + + /** + * Push notification with a specific severity (everything except non-alarmed) + * @param problemName key + * @param notification related notification + */ + public void pushAlarmNotification(String problemName, T notification) { + synchronized (problemItems) { + + boolean cp = this.problemItems.containsKey(problemName); + if (!cp) { + // no alarm in entries => create entry and push the alarm currently + NotificationWithServerTimeStamp<T> item = new NotificationWithServerTimeStamp<>( + notification); + LOG.debug("add event into list for node " + this.nodeName + " for alarm " + problemName + ": " + + item.toString()); + this.problemItems.put(problemName, item); + if (this.timeoutListener != null) { + this.timeoutListener.onNotificationDelay(notification); + } + } else { + LOG.debug("clear contra event for node " + this.nodeName + " for alarm " + problemName); + this.problemItems.get(problemName).clrContraEvent(); + } + + } + } + + /** + * Push notification with severity non-alarmed + * @param problemName key + * @param notification related notification + */ + public void clearAlarmNotification(String problemName, T notification) { + synchronized (problemItems) { + + boolean cp = this.problemItems.containsKey(problemName); + if (cp) { + LOG.debug("set contra event for alarm " + problemName); + this.problemItems.get(problemName).setContraEvent(notification); + } else { + // not in list => push directly through + if (this.timeoutListener != null) { + this.timeoutListener.onNotificationDelay(notification); + } + } + } + } + + private void startTimer() { + scheduler.scheduleAtFixedRate(timerRunner, 0, 1, TimeUnit.SECONDS); + } + + private void stopTimer() { + scheduler.shutdown(); + } + + /** + * check for clearing item out of the list + */ + private void onTick() { + long now = System.currentTimeMillis(); + try { + + synchronized (problemItems) { + + for (Entry<String, NotificationWithServerTimeStamp<T>> entry : problemItems + .entrySet()) { + NotificationWithServerTimeStamp<T> value = entry.getValue(); + if (value.isStable(now)) { + // send contra Alarm if exists + if (value.getContraAlarmNotification() != null) { + if (this.timeoutListener != null) { + this.timeoutListener.onNotificationDelay(value.getContraAlarmNotification()); + } + } + problemItems.remove(entry.getKey()); + LOG.debug("removing entry for "+this.nodeName+" for alarm " + entry.getKey()); + } else { + LOG.trace("currently state is still unstable for alarm " + entry.getKey()); + } + } + + } + } catch (Exception e) { + //Prevent stopping the task + LOG.warn("Exception during NotificationDelayFilter Task", e); + } + } + + @Override + public void close() throws Exception { + this.stopTimer(); + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/toggleAlarmFilter/NotificationDelayService.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/toggleAlarmFilter/NotificationDelayService.java new file mode 100644 index 000000000..0768ffda8 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/toggleAlarmFilter/NotificationDelayService.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * ============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.toggleAlarmFilter; + +import java.util.HashMap; + +import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.filechange.IConfigChangedListener; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.toggleAlarmFilter.conf.ToggleAlarmConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NotificationDelayService<T> implements DeviceManagerService, AutoCloseable, IConfigChangedListener { + private static final Logger LOG = LoggerFactory.getLogger(NotificationDelayService.class); + + private final HashMap<String, NotificationDelayFilter<T>> filters; + private final ToggleAlarmConfig config; + + public NotificationDelayService(ConfigurationFileRepresentation htconfig) { + this.filters = new HashMap<>(); + htconfig.registerConfigChangedListener(this); + config = new ToggleAlarmConfig(htconfig); + onConfigChanged(); + } + + public NotificationDelayFilter<T> getInstance(String nodeName, NotificationDelayedListener<T> eventListener) { + NotificationDelayFilter<T> filter = filters.getOrDefault(nodeName, null); + + LOG.trace("nodeName={}, filter!=null? {}", nodeName, filter != null); + if (filter == null) { + filter = new NotificationDelayFilter<>(nodeName, eventListener); + this.filters.put(nodeName, filter); + } + return filter; + } + + @Override + public void onConfigChanged() { + NotificationDelayFilter.setDelay(config.getDelay()); + NotificationDelayFilter.setEnabled(config.isEnabled()); + } + + @Override + public void close() throws Exception { + // close all filters + for (NotificationDelayFilter<T> filter : this.filters.values()) { + filter.close(); + } + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/toggleAlarmFilter/NotificationDelayedListener.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/toggleAlarmFilter/NotificationDelayedListener.java new file mode 100644 index 000000000..eab541d13 --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/toggleAlarmFilter/NotificationDelayedListener.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * ============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.toggleAlarmFilter; + +public interface NotificationDelayedListener<T> { + + public void onNotificationDelay(T notification); + +} + diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/toggleAlarmFilter/NotificationWithServerTimeStamp.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/toggleAlarmFilter/NotificationWithServerTimeStamp.java new file mode 100644 index 000000000..1cf32cffc --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/toggleAlarmFilter/NotificationWithServerTimeStamp.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * ============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.toggleAlarmFilter; + +public class NotificationWithServerTimeStamp<T2> { + private final T2 alarmNotification; + private T2 contraAlarmNotification; + private final long timestampStart; + private long timestamp; + + public NotificationWithServerTimeStamp(T2 n) { + this(n, System.currentTimeMillis()); + } + + public NotificationWithServerTimeStamp(T2 n, long ts) { + this.alarmNotification = n; + this.contraAlarmNotification = null; + this.timestamp = ts; + this.timestampStart=ts; + } + + @SuppressWarnings("unused") + public long getStartTime() { + return this.timestampStart; + } + public void refresh() { + this.refresh(System.currentTimeMillis()); + } + + public void refresh(long ts) { + this.timestamp = ts; + } + + public void setContraEvent(T2 notification) { + this.contraAlarmNotification = notification; + this.refresh(); + } + + public void clrContraEvent() { + this.contraAlarmNotification = null; + this.refresh(); + } + + public boolean isStable(long now) { + return this.timestamp + NotificationDelayFilter.getDelay() < now; + } + + @SuppressWarnings("unused") + public T2 getAlarmNotification() { + return this.alarmNotification; + } + + public T2 getContraAlarmNotification() { + return this.contraAlarmNotification; + } + + @Override + public String toString() { + return "NotificationWithServerTimeStamp [alarmNotification=" + alarmNotification + + ", contraAlarmNotification=" + contraAlarmNotification + ", timestampStart=" + timestampStart + + ", timestamp=" + timestamp + "]"; + } +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/toggleAlarmFilter/conf/ToggleAlarmConfig.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/toggleAlarmFilter/conf/ToggleAlarmConfig.java new file mode 100644 index 000000000..e7c6c7a2d --- /dev/null +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/toggleAlarmFilter/conf/ToggleAlarmConfig.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * ============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.toggleAlarmFilter.conf; + +import org.onap.ccsdk.features.sdnr.wt.common.configuration.Configuration; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; + +public class ToggleAlarmConfig implements Configuration { + + private static final String SECTION_MARKER_TA = "toggleAlarmFilter"; + + private static final String PROPERTY_KEY_ENABLED = "taEnabled"; + private static final String PROPERTY_KEY_DELAY = "taDelay"; + + private static final boolean DEFAULT_VALUE_ENABLED = true; + private static final long DEFAULT_VALUE_DELAY = 3000; //in ms + + private final ConfigurationFileRepresentation configuration; + + public ToggleAlarmConfig(ConfigurationFileRepresentation configuration) { + this.configuration = configuration; + this.configuration.addSection(SECTION_MARKER_TA); + defaults(); + } + + public boolean isEnabled() { + return configuration.getPropertyBoolean(SECTION_MARKER_TA, PROPERTY_KEY_ENABLED); + } + public long getDelay() { + return configuration.getPropertyLong(SECTION_MARKER_TA, PROPERTY_KEY_DELAY).orElse(DEFAULT_VALUE_DELAY); + } + + @Override + public String getSectionName() { + return SECTION_MARKER_TA; + } + + @Override + public void defaults() { + //Add default if not available + configuration.setPropertyIfNotAvailable(SECTION_MARKER_TA, PROPERTY_KEY_ENABLED, DEFAULT_VALUE_ENABLED); + configuration.setPropertyIfNotAvailable(SECTION_MARKER_TA, PROPERTY_KEY_DELAY, DEFAULT_VALUE_DELAY); + } +} |