From 58f412ad18c1daf622e54ed36db6014f4e04f3f7 Mon Sep 17 00:00:00 2001 From: herbert Date: Wed, 11 Dec 2019 15:06:19 +0100 Subject: Add data-provider data-provider and change to avoid heap overflow Issue-ID: SDNC-994 Signed-off-by: herbert Change-Id: Ifcc6ce1198442e4b48fc08ba71108cfd5b5ca8aa --- sdnr/wt/common/pom.xml | 3 +- .../ccsdk/features/sdnr/wt/common/HtAssert.java | 35 + .../ccsdk/features/sdnr/wt/common/Resources.java | 25 +- .../sdnr/wt/common/ResourcesFromDeviceManager.java | 340 ++++++ .../wt/common/configuration/subtypes/Section.java | 26 +- .../http/BaseHTTPClientFromDevicemanager.java | 327 ++++++ .../http/BaseHTTPResponseFromDevicemanager.java | 38 + .../features/sdnr/wt/common/util/Environment.java | 46 + .../features/sdnr/wt/common/util/FileWatchdog.java | 129 +++ .../features/sdnr/wt/common/test/TestDbClient.java | 71 -- .../sdnr/wt/common/test/TestDbRequests.java | 412 ------- sdnr/wt/data-provider/database/pom.xml | 169 +++ .../netconf/util/InternalConnectionStatus.java | 37 + .../wt/base/netconf/util/NetconfTimeStamp.java | 206 ++++ .../sdnr/wt/database/EsDataObjectReaderWriter.java | 339 ++++++ .../wt/database/EsDataObjectReaderWriter2.java | 360 ++++++ .../features/sdnr/wt/database/config/EsConfig.java | 164 +++ .../sdnr/wt/yangtools/YangToolsCloner.java | 217 ++++ .../sdnr/wt/yangtools/YangToolsCloner2.java | 178 +++ .../sdnr/wt/yangtools/YangToolsMapper.java | 226 ++++ .../sdnr/wt/yangtools/YangToolsMapper2.java | 263 +++++ .../database/src/main/resources/es-init.sh | 121 +- .../wt/dataprovider/database/test/TestConfig.java | 59 + .../database/test/TestNetconfNodeBuilder.java | 56 + .../dataprovider/database/test/TestNuMappings.java | 57 + .../database/src/test/resources/log4j2.xml | 17 + .../src/test/resources/simplelogger.properties | 6 + sdnr/wt/data-provider/feature/pom.xml | 49 + sdnr/wt/data-provider/installer/pom.xml | 137 +++ .../src/assembly/assemble_mvnrepo_zip.xml | 49 + sdnr/wt/data-provider/model/pom.xml | 80 ++ .../dataprovider/model/ArchiveCleanProvider.java | 39 + .../sdnr/wt/dataprovider/model/DataProvider.java | 95 ++ .../wt/dataprovider/model/IEntityDataProvider.java | 26 + .../model/src/main/yang/dataprovider.yang | 1207 ++++++++++++++++++++ sdnr/wt/data-provider/pom.xml | 52 + sdnr/wt/data-provider/provider/copyright | 17 + sdnr/wt/data-provider/provider/pom.xml | 187 +++ .../wt/dataprovider/data/DataObjectAcessor.java | 58 + .../wt/dataprovider/data/DataObjectAcessorPm.java | 161 +++ .../dataprovider/data/DataObjectAcessorStatus.java | 72 ++ .../data/ElasticSearchDataProvider.java | 439 +++++++ .../wt/dataprovider/data/FaultEntityManager.java | 91 ++ .../dataprovider/data/HtDatabaseEventsService.java | 388 +++++++ .../sdnr/wt/dataprovider/data/QueryByFilter.java | 342 ++++++ .../sdnr/wt/dataprovider/data/QueryResult.java | 52 + .../wt/dataprovider/data/YangFileProvider.java | 206 ++++ .../sdnr/wt/dataprovider/data/YangFilename.java | 63 + .../wt/dataprovider/http/AboutHttpServlet.java | 224 ++++ .../wt/dataprovider/http/GetYangSchemaRequest.java | 57 + .../wt/dataprovider/http/ReadyHttpServlet.java | 42 + .../dataprovider/http/YangSchemaHttpServlet.java | 103 ++ .../wt/dataprovider/impl/DataProviderImpl.java | 95 ++ .../dataprovider/impl/DataProviderServiceImpl.java | 335 ++++++ .../provider/src/main/resources/about/README.md | 2 + .../provider/src/main/resources/about/test.bmp | Bin 0 -> 14454 bytes .../org/opendaylight/blueprint/impl-blueprint.xml | 68 ++ .../sdnr/wt/dataprovider/test/TestAbout.java | 98 ++ .../wt/dataprovider/test/TestFilterConversion.java | 22 + .../wt/dataprovider/test/TestTimestampFilter.java | 137 +++ .../wt/dataprovider/test/TestYangProvider.java | 195 ++++ .../provider/src/test/resources/log4j.properties | 12 + .../provider/src/test/resources/log4j2.xml | 17 + .../src/test/resources/simplelogger.properties | 6 + 64 files changed, 8580 insertions(+), 570 deletions(-) create mode 100644 sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/HtAssert.java create mode 100644 sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/ResourcesFromDeviceManager.java create mode 100644 sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/http/BaseHTTPClientFromDevicemanager.java create mode 100644 sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/http/BaseHTTPResponseFromDevicemanager.java create mode 100644 sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/util/Environment.java create mode 100644 sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/util/FileWatchdog.java delete mode 100644 sdnr/wt/common/src/test/java/org/onap/ccsdk/features/sdnr/wt/common/test/TestDbClient.java delete mode 100644 sdnr/wt/common/src/test/java/org/onap/ccsdk/features/sdnr/wt/common/test/TestDbRequests.java create mode 100644 sdnr/wt/data-provider/database/pom.xml create mode 100644 sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/base/netconf/util/InternalConnectionStatus.java create mode 100644 sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/base/netconf/util/NetconfTimeStamp.java create mode 100644 sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/database/EsDataObjectReaderWriter.java create mode 100644 sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/database/EsDataObjectReaderWriter2.java create mode 100644 sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/database/config/EsConfig.java create mode 100644 sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/yangtools/YangToolsCloner.java create mode 100644 sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/yangtools/YangToolsCloner2.java create mode 100644 sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/yangtools/YangToolsMapper.java create mode 100644 sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/yangtools/YangToolsMapper2.java create mode 100644 sdnr/wt/data-provider/database/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/test/TestConfig.java create mode 100644 sdnr/wt/data-provider/database/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/test/TestNetconfNodeBuilder.java create mode 100644 sdnr/wt/data-provider/database/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/test/TestNuMappings.java create mode 100644 sdnr/wt/data-provider/database/src/test/resources/log4j2.xml create mode 100644 sdnr/wt/data-provider/database/src/test/resources/simplelogger.properties create mode 100644 sdnr/wt/data-provider/feature/pom.xml create mode 100755 sdnr/wt/data-provider/installer/pom.xml create mode 100644 sdnr/wt/data-provider/installer/src/assembly/assemble_mvnrepo_zip.xml create mode 100644 sdnr/wt/data-provider/model/pom.xml create mode 100644 sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/ArchiveCleanProvider.java create mode 100644 sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/DataProvider.java create mode 100644 sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/IEntityDataProvider.java create mode 100644 sdnr/wt/data-provider/model/src/main/yang/dataprovider.yang create mode 100755 sdnr/wt/data-provider/pom.xml create mode 100644 sdnr/wt/data-provider/provider/copyright create mode 100644 sdnr/wt/data-provider/provider/pom.xml create mode 100644 sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessor.java create mode 100644 sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessorPm.java create mode 100644 sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessorStatus.java create mode 100644 sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/ElasticSearchDataProvider.java create mode 100644 sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/FaultEntityManager.java create mode 100644 sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/HtDatabaseEventsService.java create mode 100644 sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryByFilter.java create mode 100644 sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryResult.java create mode 100644 sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/YangFileProvider.java create mode 100644 sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/YangFilename.java create mode 100644 sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/AboutHttpServlet.java create mode 100644 sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/GetYangSchemaRequest.java create mode 100644 sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/ReadyHttpServlet.java create mode 100644 sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/YangSchemaHttpServlet.java create mode 100644 sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderImpl.java create mode 100644 sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderServiceImpl.java create mode 100644 sdnr/wt/data-provider/provider/src/main/resources/about/README.md create mode 100644 sdnr/wt/data-provider/provider/src/main/resources/about/test.bmp create mode 100644 sdnr/wt/data-provider/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml create mode 100644 sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestAbout.java create mode 100644 sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestFilterConversion.java create mode 100644 sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestTimestampFilter.java create mode 100644 sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestYangProvider.java create mode 100644 sdnr/wt/data-provider/provider/src/test/resources/log4j.properties create mode 100644 sdnr/wt/data-provider/provider/src/test/resources/log4j2.xml create mode 100644 sdnr/wt/data-provider/provider/src/test/resources/simplelogger.properties diff --git a/sdnr/wt/common/pom.xml b/sdnr/wt/common/pom.xml index d77d2949f..2254b78f1 100644 --- a/sdnr/wt/common/pom.xml +++ b/sdnr/wt/common/pom.xml @@ -120,8 +120,9 @@ com.github.alexcojocaru elasticsearch-maven-plugin - 6.14 + 6.16 + true testCluster 9500 ${databaseport} diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/HtAssert.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/HtAssert.java new file mode 100644 index 000000000..873b5c947 --- /dev/null +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/HtAssert.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.common; + +public class HtAssert { + + + public static class HtNullable { + } + + public static void nonnull(Object ... oList) { + for (Object o : oList) { + if (o == null) { + throw new IllegalArgumentException("Null not allowed here."); + } + } + }; + +} diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/Resources.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/Resources.java index 3597f2e57..fe608a503 100644 --- a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/Resources.java +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/Resources.java @@ -20,22 +20,15 @@ package org.onap.ccsdk.features.sdnr.wt.common; import java.io.BufferedReader; import java.io.File; import java.io.FileFilter; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; import java.util.Enumeration; import java.util.List; - -import org.json.JSONException; -import org.json.JSONObject; import org.osgi.framework.Bundle; import org.osgi.framework.FrameworkUtil; import org.slf4j.Logger; @@ -48,7 +41,7 @@ public class Resources { private static final String RESSOURCEROOT = "src/main/resources"; private static URL getFileURL(Class cls,String resFile) { - Bundle b = FrameworkUtil.getBundle(cls); + Bundle b = FrameworkUtil.getBundle(cls); URL u = null; LOG.debug("try to get file {}", resFile); if (b == null) { @@ -83,7 +76,7 @@ public class Resources { private static String readFile(final InputStream s) throws IOException { // read file - final String LR = "\n"; + final String LR = "\n"; BufferedReader in = new BufferedReader(new InputStreamReader(s)); StringBuilder sb = new StringBuilder(); String inputLine; @@ -97,7 +90,7 @@ public class Resources { private static List getFileURLs(Bundle b,String folder, final String filter, final boolean recursive) throws IOException { - + List list = new ArrayList<>(); if (b == null) { FileFilter ff = pathname -> { @@ -185,7 +178,7 @@ public class Resources { // return list; // } public static String getFileContent( Class cls, String resFile) { - LOG.debug("loading file {} from res", resFile); + LOG.debug("loading file {} from res", resFile); URL u = getFileURL(cls,resFile); String s=null; if (u == null) { @@ -199,7 +192,7 @@ public class Resources { } return s; - } + } // public static JSONObject getJSONFile(Class cls,String resFile) { // LOG.debug("loading json file {} from res", resFile); // JSONObject o = null; @@ -269,11 +262,11 @@ public class Resources { // Collection urlCollection = new ArrayList<>(); // URL url = getUrlForRessource(cls,folder); // if(url==null) { -// return Collections.enumeration(urlCollection); +// return Collections.enumeration(urlCollection); // } // String path = url.getPath(); // File[] files = new File(path).listFiles(); -// +// // if (files != null) { // for (File f : files) { // try { @@ -290,7 +283,7 @@ public class Resources { // } // // return Collections.enumeration(urlCollection); -// +// // } public static URL getUrlForRessource(Class cls,String fileOrDirectory) { @@ -298,7 +291,7 @@ public class Resources { ClassLoader loader = cls.getClassLoader(); URL url = loader.getResource(fileOrDirectory); if(url==null && fileOrDirectory.startsWith("/")) { - url = loader.getResource(fileOrDirectory.substring(1)); + url = loader.getResource(fileOrDirectory.substring(1)); } return url; } diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/ResourcesFromDeviceManager.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/ResourcesFromDeviceManager.java new file mode 100644 index 000000000..32a21a801 --- /dev/null +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/ResourcesFromDeviceManager.java @@ -0,0 +1,340 @@ +/******************************************************************************* + * ============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.common; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileFilter; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; + +import org.json.JSONException; +import org.json.JSONObject; +import org.osgi.framework.Bundle; +import org.osgi.framework.FrameworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ResourcesFromDeviceManager { + + private static final Logger LOG = LoggerFactory.getLogger(ResourcesFromDeviceManager.class); + + private static final String RESSOURCEROOT = "src/main/resources"; + + private static URL getFileURL(String resFile) { + Bundle b = FrameworkUtil.getBundle(ResourcesFromDeviceManager.class); + URL u = null; + LOG.debug("try to get file {}", resFile); + if (b == null) { + LOG.info("Load resource as file: {}", resFile); + u = getUrlForRessource(resFile); + } else { + LOG.info("Load resource from bundle: {}", resFile); + u = b.getEntry(resFile); + } + return u; + } + + private static File getFile(String resFile) { + Bundle b = FrameworkUtil.getBundle(ResourcesFromDeviceManager.class); + File f = null; + LOG.debug("try to get file {}", resFile); + if (b == null) { + LOG.warn("cannot load bundle resources"); + f = new File(RESSOURCEROOT + resFile); + } else { + try { + f = new File(b.getEntry(resFile).toURI()); + } catch (URISyntaxException e) { + LOG.warn("Con not load file: {}",e.getMessage()); + } + } + return f; + } + + private static String readFile(final URL u) throws IOException { + return readFile(u.openStream()); + } + + private static String readFile(final InputStream s) throws IOException { + // read file + BufferedReader in = new BufferedReader(new InputStreamReader(s)); + StringBuilder sb = new StringBuilder(); + String inputLine; + while ((inputLine = in.readLine()) != null) { + sb.append(inputLine); + } + in.close(); + s.close(); + return sb.toString(); + } + + public static List getFileURLs(String folder, final String filter, final boolean recursive) + throws IOException { + Bundle b = FrameworkUtil.getBundle(ResourcesFromDeviceManager.class); + List list = new ArrayList<>(); + if (b == null) { + FileFilter ff = pathname -> { + if (pathname.isFile()) { + return pathname.getName().contains(filter); + } else { + return true; + } + }; + File ffolder = getFile(folder); + if (ffolder != null && ffolder.isDirectory()) { + File[] files = ffolder.listFiles(ff); + if (files != null && files.length > 0) { + for (File f : files) { + if (f.isFile()) { + list.add(f.toURI().toURL()); + } else if (f.isDirectory() && recursive) { + getFileURLsRecursive(f, ff, list); + } + } + } + } + } else { + getResourceURLsTreeRecurse(b, filter, b.getEntryPaths(folder), recursive, list); + } + return list; + } + + private static void getFileURLsRecursive(File root, FileFilter ff, List list) throws MalformedURLException { + if (root != null && root.isDirectory()) { + File[] files = root.listFiles(ff); + if (files != null && files.length > 0) { + for (File f : files) { + if (f.isFile()) { + list.add(f.toURI().toURL()); + } else if (f.isDirectory()) { + getFileURLsRecursive(f, ff, list); + } + } + } + } + + } + + private static void getResourceURLsTreeRecurse(Bundle b, String filter, Enumeration resource, + boolean recursive, List outp) throws IOException { + while (resource.hasMoreElements()) { + String name = resource.nextElement(); + Enumeration list = b.getEntryPaths(name); + if (list != null) { + if (recursive) { + getResourceURLsTreeRecurse(b, filter, list, recursive, outp); + } + } else { + // Read + if (name.contains(filter)) { + LOG.debug("add {} to list", name); + outp.add(b.getEntry(name)); + } else { + LOG.debug("filtered out {}", name); + } + } + } + } + + public static List getJSONFiles(String folder, boolean recursive) { + List list = new ArrayList<>(); + List urls; + try { + urls = getFileURLs(folder, ".json", recursive); + LOG.debug("found {} files", urls.size()); + } catch (IOException e1) { + urls = new ArrayList<>(); + LOG.warn("failed to get urls from resfolder {} : {}", folder, e1.getMessage()); + } + for (URL u : urls) { + LOG.debug("try to parse " + u.toString()); + try { + JSONObject o = new JSONObject(readFile(u)); + list.add(o); + } catch (JSONException | IOException e) { + LOG.warn("problem reading/parsing file {} : {}", u, e.getMessage()); + } + } + return list; + } + + public static JSONObject getJSONFile(String resFile) { + LOG.debug("loading json file {} from res", resFile); + URL u = getFileURL(resFile); + if (u == null) { + LOG.warn("cannot find resfile: {}", resFile); + return null; + } + JSONObject o = null; + try { + // parse to jsonobject + o = new JSONObject(readFile(u)); + } catch (Exception e) { + LOG.warn("problem reading/parsing file: {}", e.getMessage()); + } + return o; + } + + /** + * Used for reading plugins from resource files /elasticsearch/plugins/head + * /etc/elasticsearch-plugins /elasticsearch/plugins + * + * @param resFolder resource folder pointing to the related files + * @param dstFolder destination + * @param rootDirToRemove part from full path to remove + * @return true if files could be extracted + */ + public static boolean copyFolderInto(String resFolder, String dstFolder, String rootDirToRemove) { + + Enumeration urls = null; + Bundle b = FrameworkUtil.getBundle(ResourcesFromDeviceManager.class); + if (b == null) { + LOG.info("Running in file text."); + urls = getResourceFolderFiles(resFolder); + } else { + urls = b.findEntries(resFolder, "*", true); + } + + boolean success = true; + URL srcUrl; + String srcFilename; + String dstFilename; + while (urls.hasMoreElements()) { + srcUrl = urls.nextElement(); + srcFilename = srcUrl.getFile(); + + if (srcFilename.endsWith("/")) { + LOG.debug("Skip directory: {}", srcFilename); + continue; + } + + LOG.debug("try to copy res {} to {}", srcFilename, dstFolder); + if (rootDirToRemove != null) { + srcFilename = + srcFilename.substring(srcFilename.indexOf(rootDirToRemove) + rootDirToRemove.length() + 1); + LOG.debug("dstfilename trimmed to {}", srcFilename); + } + dstFilename = dstFolder + "/" + srcFilename; + try { + if (!extractFileTo(srcUrl, new File(dstFilename))) { + success = false; + } + } catch (Exception e) { + LOG.warn("problem copying res {} to {}: {}", srcFilename, dstFilename, e.getMessage()); + } + } + + return success; + + } + + private static Enumeration getResourceFolderFiles(String folder) { + LOG.debug("Get resource: {}", folder); + URL url = getUrlForRessource(folder); + String path = url.getPath(); + File[] files = new File(path).listFiles(); + Collection urlCollection = new ArrayList<>(); + + if (files != null) { + for (File f : files) { + try { + if (f.isDirectory()) { + urlCollection.addAll(Collections.list(getResourceFolderFiles(folder + "/" + f.getName()))); + } else { + urlCollection.add(f.toURI().toURL()); + } + } catch (MalformedURLException e) { + LOG.error("Can not read ressources", e); + break; + } + } + } + + Enumeration urls = Collections.enumeration(urlCollection); + return urls; + } + + private static URL getUrlForRessource(String fileOrDirectory) { + //ClassLoader loader = Thread.currentThread().getContextClassLoader(); + ClassLoader loader = ResourcesFromDeviceManager.class.getClassLoader(); + URL url = loader.getResource(fileOrDirectory); + if(url==null && fileOrDirectory.startsWith("/")) { + url = loader.getResource(fileOrDirectory.substring(1)); + } + return url; + } + + public static boolean extractFileTo(String resFile, File oFile) { + if (oFile == null) { + return false; + } + LOG.debug("try to copy {} from res to {}", resFile, oFile.getAbsolutePath()); + URL u = getFileURL(resFile); + if (u == null) { + LOG.warn("cannot find resfile: {}", resFile); + return false; + } + return extractFileTo(u, oFile); + } + + public static boolean extractFileTo(URL u, File oFile) { + + if (oFile.isDirectory()) { + oFile.mkdirs(); + return true; + } else { + oFile.getParentFile().mkdirs(); + } + + if (!oFile.exists()) { + try { + oFile.createNewFile(); + } catch (IOException e) { + LOG.warn("problem creating file {}: {}", oFile.getAbsoluteFile(), e.getMessage()); + } + } + try (InputStream in = u.openStream(); OutputStream outStream = new FileOutputStream(oFile);) { + + int theInt; + while ((theInt = in.read()) >= 0) { + outStream.write(theInt); + } + in.close(); + outStream.flush(); + outStream.close(); + LOG.debug("file written successfully"); + } catch (IOException e) { + LOG.error("problem writing file: {}", e.getMessage()); + return false; + } + return true; + } + +} diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/configuration/subtypes/Section.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/configuration/subtypes/Section.java index a0e21be01..094da6389 100644 --- a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/configuration/subtypes/Section.java +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/configuration/subtypes/Section.java @@ -50,7 +50,7 @@ public class Section { } public String getProperty(String key) { - return this.getProperty(key, null); + return this.getProperty(key, ""); } public String getProperty(String key, String defValue) { @@ -61,7 +61,7 @@ public class Section { } public String getName() { - return name; + return name; } public void setProperty(String key, String value) { @@ -70,7 +70,7 @@ public class Section { key = key.substring(1); } if (this.values.containsKey(key)) { - this.values.get(key).setValue(value).setIsUncommented(isuncommented); + this.values.get(key).setValue(value).setIsUncommented(isuncommented); } else { this.values.put(key, new SectionValue(value,isuncommented)); } @@ -128,7 +128,7 @@ public class Section { lines.add("[" + this.name + "]"); } for (Entry entry : this.values.entrySet()) { - SectionValue sectionValue = entry.getValue(); + SectionValue sectionValue = entry.getValue(); if (sectionValue.getComments().size() > 0) { for (String comment : sectionValue.getComments()) { lines.add(comment); @@ -173,11 +173,11 @@ public class Section { public Optional getLong(String key) { String v = this.getProperty(key); - try { - return Optional.of(Long.parseLong(v)); - } catch (NumberFormatException e) { - } - return Optional.empty(); + try { + return Optional.of(Long.parseLong(v)); + } catch (NumberFormatException e) { + } + return Optional.empty(); } public boolean hasValues() { @@ -188,9 +188,9 @@ public class Section { return this.values.containsKey(key); } - @Override - public String toString() { - return "Section [name=" + name + ", rawLines=" + rawLines + ", values=" + values + "]"; - } + @Override + public String toString() { + return "Section [name=" + name + ", rawLines=" + rawLines + ", values=" + values + "]"; + } } diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/http/BaseHTTPClientFromDevicemanager.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/http/BaseHTTPClientFromDevicemanager.java new file mode 100644 index 000000000..e330fb42a --- /dev/null +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/http/BaseHTTPClientFromDevicemanager.java @@ -0,0 +1,327 @@ +/******************************************************************************* + * ============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.common.http; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.security.KeyFactory; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.security.interfaces.RSAPrivateKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.util.Base64; +import java.util.Map; + +import javax.annotation.Nonnull; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.xml.bind.DatatypeConverter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BaseHTTPClientFromDevicemanager { + + private static Logger LOG = LoggerFactory.getLogger(BaseHTTPClientFromDevicemanager.class); + private static final int SSLCERT_NONE = -1; + private static final int SSLCERT_PCKS = 0; + private static final int SSLCERT_PEM = 1; + private static final int BUFSIZE = 1024; + private static final Charset CHARSET = StandardCharsets.UTF_8; + private static final String SSLCONTEXT = "TLSv1.2"; + private static final int DEFAULT_HTTP_TIMEOUT_MS = 30000; // in ms + + private final boolean trustAll; + private final String baseUrl; + + private int timeout = DEFAULT_HTTP_TIMEOUT_MS; + private SSLContext sc = null; + + public BaseHTTPClientFromDevicemanager(String base) { + this(base, false); + } + + public BaseHTTPClientFromDevicemanager(String base, boolean trustAllCerts) { + this(base, trustAllCerts, null, null, SSLCERT_NONE); + } + + public BaseHTTPClientFromDevicemanager(String base, boolean trustAllCerts, String certFilename, String passphrase, int sslCertType) { + this.baseUrl = base; + this.trustAll = trustAllCerts; + try { + sc = setupSsl(trustAll, certFilename, passphrase, sslCertType); + } catch (KeyManagementException | NoSuchAlgorithmException | UnrecoverableKeyException | CertificateException + | KeyStoreException | IOException | InvalidKeySpecException e) { + LOG.warn("problem ssl setup: " + e.getMessage()); + } + } + + protected @Nonnull BaseHTTPResponseFromDevicemanager sendRequest(String uri, String method, String body, Map headers) + throws IOException { + return this.sendRequest(uri, method, body != null ? body.getBytes(CHARSET) : null, headers); + } + + protected @Nonnull BaseHTTPResponseFromDevicemanager sendRequest(String uri, String method, byte[] body, Map headers) + throws IOException { + if (uri == null) { + uri = ""; + } + String surl = this.baseUrl; + if (!surl.endsWith("/") && uri.length() > 0) { + surl += "/"; + } + if (uri.startsWith("/")) { + uri = uri.substring(1); + } + surl += uri; + LOG.debug("try to send request with url=" + this.baseUrl + uri + " as method=" + method); + LOG.trace("body:" + (body == null ? "null" : new String(body, CHARSET))); + URL url = new URL(surl); + URLConnection http = url.openConnection(); + http.setConnectTimeout(this.timeout); + if (surl.toString().startsWith("https")) { + if (sc != null) { + ((HttpsURLConnection) http).setSSLSocketFactory(sc.getSocketFactory()); + if (trustAll) { + LOG.debug("trusting all certs"); + HostnameVerifier allHostsValid = (hostname, session) -> true; + ((HttpsURLConnection) http).setHostnameVerifier(allHostsValid); + } + } else // Should never happen + { + LOG.warn("No SSL context available"); + return new BaseHTTPResponseFromDevicemanager(-1, ""); + } + } + ((HttpURLConnection) http).setRequestMethod(method); + http.setDoOutput(true); + if (headers != null && headers.size() > 0) { + for (String key : headers.keySet()) { + http.setRequestProperty(key, headers.get(key)); + LOG.trace("set http header " + key + ": " + headers.get(key)); + } + } + byte[] buffer = new byte[BUFSIZE]; + int len = 0, lensum = 0; + // send request + // Send the message to destination + if (!method.equals("GET") && body != null && body.length > 0) { + try (OutputStream output = http.getOutputStream()) { + output.write(body); + } + } + // Receive answer + int responseCode = ((HttpURLConnection) http).getResponseCode(); + String sresponse = ""; + InputStream response = null; + try { + if (responseCode >= 200 && responseCode < 300) { + response = http.getInputStream(); + } else { + response = ((HttpURLConnection) http).getErrorStream(); + if (response == null) { + response = http.getInputStream(); + } + } + if (response != null) { + while (true) { + len = response.read(buffer, 0, BUFSIZE); + if (len <= 0) { + break; + } + lensum += len; + sresponse += new String(buffer, 0, len, CHARSET); + } + } else { + LOG.debug("response is null"); + } + } catch (Exception e) { + LOG.debug("No response. ", e); + } finally { + if (response != null) { + response.close(); + } + } + LOG.debug("ResponseCode: " + responseCode); + LOG.trace("Response (len:{}): {}", String.valueOf(lensum), sresponse); + return new BaseHTTPResponseFromDevicemanager(responseCode, sresponse); + } + + public static SSLContext setupSsl(boolean trustall) + throws NoSuchAlgorithmException, KeyManagementException, CertificateException, FileNotFoundException, + IOException, UnrecoverableKeyException, KeyStoreException, InvalidKeySpecException { + + return setupSsl(trustall, null, null, SSLCERT_NONE); + } + + /** + * @param keyFilename filename for key file + * @param certFilename filename for cert file + * @throws NoSuchAlgorithmException + * @throws KeyManagementException + * @throws IOException + * @throws FileNotFoundException + * @throws CertificateException + * @throws KeyStoreException + * @throws UnrecoverableKeyException + * @throws InvalidKeySpecException + */ + /** + * Setup of SSLContext + * + * @param trustall true to switch of certificate verification + * @param certFilename filename for certificate file + * @param passPhrase for certificate + * @param certType of certificate + * @return SSL Context according to parameters + * @throws NoSuchAlgorithmException according name + * @throws KeyManagementException according name + * @throws CertificateException according name + * @throws FileNotFoundException according name + * @throws IOException according name + * @throws UnrecoverableKeyException according name + * @throws KeyStoreException according name + * @throws InvalidKeySpecException according name + */ + public static SSLContext setupSsl(boolean trustall, String certFilename, String passPhrase, int certType) + throws NoSuchAlgorithmException, KeyManagementException, CertificateException, FileNotFoundException, + IOException, UnrecoverableKeyException, KeyStoreException, InvalidKeySpecException { + + SSLContext sc = SSLContext.getInstance(SSLCONTEXT); + TrustManager[] trustCerts = null; + if (trustall) { + trustCerts = new TrustManager[] {new javax.net.ssl.X509TrustManager() { + @Override + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + + @Override + public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {} + + @Override + public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {} + }}; + + } + KeyManager[] kms = null; + if (certFilename != null && passPhrase != null && !certFilename.isEmpty() && !passPhrase.isEmpty()) { + if (certType == SSLCERT_PCKS) { + LOG.debug("try to load pcks file " + certFilename + " with passphrase=" + passPhrase); + KeyStore keyStore = KeyStore.getInstance("PKCS12"); + FileInputStream fileInputStream = new FileInputStream(certFilename); + keyStore.load(fileInputStream, passPhrase.toCharArray()); + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(keyStore, passPhrase.toCharArray()); + kms = kmf.getKeyManagers(); + fileInputStream.close(); + LOG.debug("successful"); + + } else if (certType == SSLCERT_PEM) { + LOG.debug("try to load pem files cert=" + certFilename + " key=" + passPhrase); + File fCert = new File(certFilename); + File fKey = new File(passPhrase); + KeyStore keyStore = KeyStore.getInstance("JKS"); + keyStore.load(null); + byte[] certBytes = parseDERFromPEM(Files.readAllBytes(fCert.toPath()), "-----BEGIN CERTIFICATE-----", + "-----END CERTIFICATE-----"); + byte[] keyBytes = parseDERFromPEM(Files.readAllBytes(fKey.toPath()), "-----BEGIN PRIVATE KEY-----", + "-----END PRIVATE KEY-----"); + + X509Certificate cert = generateCertificateFromDER(certBytes); + RSAPrivateKey key = generatePrivateKeyFromDER(keyBytes); + keyStore.setCertificateEntry("cert-alias", cert); + keyStore.setKeyEntry("key-alias", key, "changeit".toCharArray(), new Certificate[] {cert}); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(keyStore, "changeit".toCharArray()); + kms = kmf.getKeyManagers(); + LOG.debug("successful"); + } + } + // Init the SSLContext with a TrustManager[] and SecureRandom() + sc.init(kms, trustCerts, new java.security.SecureRandom()); + return sc; + } + + protected static byte[] parseDERFromPEM(byte[] pem, String beginDelimiter, String endDelimiter) { + String data = new String(pem); + String[] tokens = data.split(beginDelimiter); + tokens = tokens[1].split(endDelimiter); + return DatatypeConverter.parseBase64Binary(tokens[0]); + } + + protected static RSAPrivateKey generatePrivateKeyFromDER(byte[] keyBytes) + throws InvalidKeySpecException, NoSuchAlgorithmException { + PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); + + KeyFactory factory = KeyFactory.getInstance("RSA"); + + return (RSAPrivateKey) factory.generatePrivate(spec); + } + + protected static X509Certificate generateCertificateFromDER(byte[] certBytes) throws CertificateException { + CertificateFactory factory = CertificateFactory.getInstance("X.509"); + + return (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(certBytes)); + } + + public static String getAuthorizationHeaderValue(String username, String password) { + return "Basic " + new String(Base64.getEncoder().encode((username + ":" + password).getBytes())); + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + public static int getSslCertPcks() { + return SSLCERT_PCKS; + } + + public static int getSslCertNone() { + return SSLCERT_NONE; + } + + public static int getSslCertPEM() { + return SSLCERT_PEM; + } + +} diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/http/BaseHTTPResponseFromDevicemanager.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/http/BaseHTTPResponseFromDevicemanager.java new file mode 100644 index 000000000..0fd0a6459 --- /dev/null +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/http/BaseHTTPResponseFromDevicemanager.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.common.http; + +public class BaseHTTPResponseFromDevicemanager { + + public static final int CODE404 = 404; + public static final int CODE200 = 200; + public static final BaseHTTPResponseFromDevicemanager UNKNOWN = new BaseHTTPResponseFromDevicemanager(-1, ""); + public final int code; + public final String body; + + public BaseHTTPResponseFromDevicemanager(int code,String body) + { + this.code=code; + this.body=body; + } + + @Override + public String toString() { + return "BaseHTTPResponse [code=" + code + ", body=" + body + "]"; + } +} diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/util/Environment.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/util/Environment.java new file mode 100644 index 000000000..1ac55ad15 --- /dev/null +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/util/Environment.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.common.util; + +import java.net.Inet4Address; +import java.net.UnknownHostException; +import java.util.Map; + +public class Environment { + + public static String getVar(String v) + { + if(v.equals("$HOSTNAME")) + { + String s=null; + try { + s = Inet4Address.getLocalHost().getHostName(); + } catch (UnknownHostException e) { + + } + if(s!=null && s.length()>0) + return s; + } + Map env = System.getenv(); + for (String envName : env.keySet()) { + if(envName!=null && envName.equals(v)) + return env.get(envName); + } + return null; + } +} diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/util/FileWatchdog.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/util/FileWatchdog.java new file mode 100644 index 000000000..55fe83300 --- /dev/null +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/util/FileWatchdog.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * ============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========================================================================== + ******************************************************************************/ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You 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. + */ + +package org.onap.ccsdk.features.sdnr.wt.common.util; + +import java.io.File; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Check every now and then that a certain file has not changed. If it has, then call the + * {@link #doOnChange} method. + * + * @author JunHo Yoon + * @since 3.1.1 + */ +public abstract class FileWatchdog extends Thread { + private static final Logger LOGGER = LoggerFactory.getLogger(FileWatchdog.class); + /** + * The default delay between every file modification check, set to 60 seconds. + */ + public static final long DEFAULT_DELAY = 60000; + /** + * The name of the file to observe for changes. + */ + private final String filename; + + /** + * The delay to observe between every check. By default set {@link #DEFAULT_DELAY}. + */ + private long delay = DEFAULT_DELAY; + + private final File file; + private long lastModified = 0; + private boolean warnedAlready = false; + + protected FileWatchdog(String filename) { + this.filename = filename; + file = new File(filename); + setDaemon(true); + checkAndConfigure(); + } + + /** + * Set the delay to observe between each check of the file changes. + * + * @param delay the frequency of file watch. + */ + public void setDelay(long delay) { + this.delay = delay; + } + + /** + * abstract method to be run when the file is changed. + */ + protected abstract void doOnChange(); + + protected void checkAndConfigure() { + boolean fileExists; + try { + fileExists = file.exists(); + } catch (SecurityException e) { + LOGGER.warn("Was not allowed to read check file existence, file:[{}].",filename); + this.interrupt(); // there is no point in continuing + return; + } + + if (fileExists) { + long l = file.lastModified(); // this can also throw a + if (lastModified == 0) { + lastModified = l; // is very unlikely. + } + if (l > lastModified) { // however, if we reached this point this + lastModified = l; // is very unlikely. + doOnChange(); + warnedAlready = false; + } + } else { + if (!warnedAlready) { + LOGGER.debug("[{}] does not exist.", filename); + warnedAlready = true; + } + } + } + + @Override + public void run() { + while (!isInterrupted()) { + checkAndConfigure(); + try { + Thread.sleep(delay); + } catch (InterruptedException e) { + LOGGER.debug("Interrupted sleep. {}", e.getMessage()); + Thread.currentThread().interrupt(); + } + } + LOGGER.debug("Stoppen file watchdog for file {}", filename); + } +} diff --git a/sdnr/wt/common/src/test/java/org/onap/ccsdk/features/sdnr/wt/common/test/TestDbClient.java b/sdnr/wt/common/src/test/java/org/onap/ccsdk/features/sdnr/wt/common/test/TestDbClient.java deleted file mode 100644 index 0d46b4d20..000000000 --- a/sdnr/wt/common/src/test/java/org/onap/ccsdk/features/sdnr/wt/common/test/TestDbClient.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * ============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.common.test; - -import static org.junit.Assert.*; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; -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.config.HostInfo; -import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilders; - -public class TestDbClient { - - private static HtDatabaseClient dbClient; - private static HostInfo[] hosts = new HostInfo[] { new HostInfo("localhost", Integer - .valueOf(System.getProperty("databaseport") != null ? System.getProperty("databaseport") : "49200")) }; - - @BeforeClass - public static void init() { - - dbClient = new HtDatabaseClient(hosts); - dbClient.waitForYellowStatus(20000); - - } - @Test - public void testCRUD() { - final String IDX = "test23-knmoinsd"; - final String ID = "abcddd"; - final String JSON = "{\"data\":{\"inner\":\"more\"}}"; - final String JSON2 = "{\"data\":{\"inner\":\"more2\"}}"; - //Create - String esId=dbClient.doWriteRaw(IDX, ID, JSON); - assertEquals("inserted id is wrong",ID,esId); - //Read - SearchResult result = dbClient.doReadByQueryJsonData(IDX, QueryBuilders.matchQuery("_id", ID)); - assertEquals("amount of results is wrong",1,result.getTotal()); - assertEquals("data not valid", JSON,result.getHits().get(0).getSourceAsString()); - //Update - esId= dbClient.doUpdateOrCreate(IDX, ID, JSON2); - assertEquals("update response not successfull",ID,esId); - //Verify - result = dbClient.doReadByQueryJsonData( IDX, QueryBuilders.matchQuery("_id", ID)); - assertEquals("amount of results is wrong",1,result.getTotal()); - assertEquals("data not valid", JSON2,result.getHits().get(0).getSourceAsString()); - //Delete - boolean del=dbClient.doRemove(IDX, ID); - assertTrue("item not deleted",del); - //Verify - result = dbClient.doReadByQueryJsonData(IDX, QueryBuilders.matchQuery("_id", ID)); - assertEquals("amount of results is wrong",0,result.getTotal()); - } - -} diff --git a/sdnr/wt/common/src/test/java/org/onap/ccsdk/features/sdnr/wt/common/test/TestDbRequests.java b/sdnr/wt/common/src/test/java/org/onap/ccsdk/features/sdnr/wt/common/test/TestDbRequests.java deleted file mode 100644 index 36bbebefd..000000000 --- a/sdnr/wt/common/src/test/java/org/onap/ccsdk/features/sdnr/wt/common/test/TestDbRequests.java +++ /dev/null @@ -1,412 +0,0 @@ -/******************************************************************************* - * ============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.common.test; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; -import org.onap.ccsdk.features.sdnr.wt.common.database.config.HostInfo; -import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilders; -import org.onap.ccsdk.features.sdnr.wt.common.database.requests.ClusterHealthRequest; -import org.onap.ccsdk.features.sdnr.wt.common.database.requests.CreateIndexRequest; -import org.onap.ccsdk.features.sdnr.wt.common.database.requests.DeleteByQueryRequest; -import org.onap.ccsdk.features.sdnr.wt.common.database.requests.DeleteIndexRequest; -import org.onap.ccsdk.features.sdnr.wt.common.database.requests.DeleteRequest; -import org.onap.ccsdk.features.sdnr.wt.common.database.requests.GetRequest; -import org.onap.ccsdk.features.sdnr.wt.common.database.requests.IndexRequest; -import org.onap.ccsdk.features.sdnr.wt.common.database.requests.NodeStatsRequest; -import org.onap.ccsdk.features.sdnr.wt.common.database.requests.RefreshIndexRequest; -import org.onap.ccsdk.features.sdnr.wt.common.database.requests.SearchRequest; -import org.onap.ccsdk.features.sdnr.wt.common.database.requests.UpdateByQueryRequest; -import org.onap.ccsdk.features.sdnr.wt.common.database.requests.UpdateRequest; -import org.onap.ccsdk.features.sdnr.wt.common.database.responses.ClusterHealthResponse; -import org.onap.ccsdk.features.sdnr.wt.common.database.responses.CreateIndexResponse; -import org.onap.ccsdk.features.sdnr.wt.common.database.responses.DeleteByQueryResponse; -import org.onap.ccsdk.features.sdnr.wt.common.database.responses.DeleteIndexResponse; -import org.onap.ccsdk.features.sdnr.wt.common.database.responses.DeleteResponse; -import org.onap.ccsdk.features.sdnr.wt.common.database.responses.GetResponse; -import org.onap.ccsdk.features.sdnr.wt.common.database.responses.IndexResponse; -import org.onap.ccsdk.features.sdnr.wt.common.database.responses.NodeStatsResponse; -import org.onap.ccsdk.features.sdnr.wt.common.database.responses.SearchResponse; -import org.onap.ccsdk.features.sdnr.wt.common.database.responses.UpdateByQueryResponse; -import org.onap.ccsdk.features.sdnr.wt.common.database.responses.UpdateResponse; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -import org.json.JSONException; -import org.json.JSONObject; - -public class TestDbRequests { - - private static HtDatabaseClient dbClient; - private static HostInfo[] hosts = new HostInfo[] { new HostInfo("localhost", Integer - .valueOf(System.getProperty("databaseport") != null ? System.getProperty("databaseport") : "49200")) }; - - @BeforeClass - public static void init() { - - dbClient = new HtDatabaseClient(hosts); - - } - @AfterClass - public static void deinit() { - if(dbClient!=null) { - dbClient.close(); - } - } - @Test - public void testHealth() { - - ClusterHealthResponse response = null; - ClusterHealthRequest request = new ClusterHealthRequest(); - request.timeout(10); - try { - response = dbClient.health(request); - } catch (UnsupportedOperationException | IOException | JSONException e) { - fail(e.getMessage()); - } - assertNotNull("response is null", response); - assertTrue(response.isStatusMinimal(ClusterHealthResponse.HEALTHSTATUS_YELLOW)); - } - - @Test - public void testCount() { - - } - - @Test - public void testCreateAndDeleteIndex() { - final String IDX = "testcidx1"; - CreateIndexRequest request = new CreateIndexRequest(IDX); - CreateIndexResponse response = null; - try { - response = dbClient.createIndex(request); - } catch (IOException e) { - fail(e.getMessage()); - } - assertNotNull(response); - - assertTrue("index not existing", dbClient.isExistsIndex(IDX)); - - DeleteIndexRequest request2 = new DeleteIndexRequest(IDX); - - DeleteIndexResponse response2 = null; - try { - response2 = dbClient.deleteIndex(request2); - } catch (IOException e) { - fail(e.getMessage()); - } - assertNotNull(response2); - assertFalse("index still existing", dbClient.isExistsIndex(IDX)); - this.deleteIndex(IDX); - } - - @Test - public void testInsertAndDelete() { - final String IDX = "test23-knmoinsd"; - final String ID = "abcddd"; - final String JSON = "{\"data\":{\"inner\":\"more\"}}"; - this.insert(IDX, ID, JSON); - // delete data - DeleteRequest request2 = new DeleteRequest(IDX, IDX, ID); - DeleteResponse response2 = null; - try { - response2 = dbClient.delete(request2); - } catch (IOException e) { - fail(e.getMessage()); - } - assertNotNull(response2); - assertTrue(response2.isDeleted()); - try { - dbClient.refreshIndex(new RefreshIndexRequest(IDX)); - } catch (IOException e) { - fail(e.getMessage()); - } - // verify data deleted - GetRequest request4 = new GetRequest(IDX, IDX, ID); - GetResponse response4 = null; - try { - response4 = dbClient.get(request4); - } catch (IOException e1) { - fail(e1.getMessage()); - } - assertNotNull(response4); - assertFalse("data still existing", response4.isExists()); - this.deleteIndex(IDX); - } - - @Test - public void testInsertAndDeleteByQuery() { - final String IDX = "test34-knmoinsd"; - final String ID = "abcdddseae"; - final String JSON = "{\"data\":{\"inner\":\"more\"}}"; - this.insert(IDX, ID, JSON); - - // delete data - DeleteByQueryRequest request2 = new DeleteByQueryRequest(IDX); - request2.source(QueryBuilders.matchQuery("_id", ID)); - DeleteByQueryResponse response2 = null; - try { - response2 = dbClient.deleteByQuery(request2); - } catch (IOException e) { - fail(e.getMessage()); - } - assertNotNull(response2); - assertTrue(response2.isResponseSucceeded()); - try { - dbClient.refreshIndex(new RefreshIndexRequest(IDX)); - } catch (IOException e) { - fail(e.getMessage()); - } - // verify data deleted - GetRequest request4 = new GetRequest(IDX, IDX, ID); - GetResponse response4 = null; - try { - response4 = dbClient.get(request4); - } catch (IOException e1) { - fail(e1.getMessage()); - } - assertNotNull(response4); - assertFalse("data still existing", response4.isExists()); - this.deleteIndex(IDX); - } - - private void insert(String IDX, String ID, String JSON) { - - // create data - IndexRequest request = new IndexRequest(IDX, IDX, ID); - request.source(JSON); - IndexResponse response = null; - try { - response = dbClient.index(request); - } catch (IOException e) { - fail(e.getMessage()); - } - assertNotNull(response); - if (ID != null) { - assertEquals("id not correct", ID, response.getId()); - } else { - ID = response.getId(); - } - // do db refresh - try { - dbClient.refreshIndex(new RefreshIndexRequest(IDX)); - } catch (IOException e) { - fail(e.getMessage()); - } - // verify data exists - GetRequest request3 = new GetRequest(IDX, IDX, ID); - GetResponse response3 = null; - try { - response3 = dbClient.get(request3); - } catch (IOException e1) { - fail(e1.getMessage()); - } - assertNotNull(response3); - JSONAssert.assertEquals("could not verify update", JSON, response3.getSourceAsBytesRef(), true); - } - - @Test - public void testSearch() { - final String IDX = "test44-moinsd"; - final String ID = "abe"; - final String JSON = "{\"data\":{\"inner\":\"more\"}}"; - final String ID2 = "abe2"; - final String JSON2 = "{\"data\":{\"inner\":\"more2\"}}"; - final String ID3 = "abe3"; - final String JSON3 = "{\"data\":{\"inner\":\"more3\"}}"; - this.insert(IDX, ID, JSON); - this.insert(IDX, ID2, JSON2); - this.insert(IDX, ID3, JSON3); - SearchRequest request = new SearchRequest(IDX, IDX); - request.setQuery(QueryBuilders.matchAllQuery()); - SearchResponse response = null; - try { - response = dbClient.search(request); - } catch (IOException e) { - fail(e.getMessage()); - } - assertNotNull(response); - assertEquals("not all items found", 3, response.getHits().length); - assertEquals("incorrect index",IDX,response.getHits()[0].getIndex()); - assertEquals("incorrect type",IDX,response.getHits()[0].getType()); - this.deleteIndex(IDX); - } - - @Test - public void testUpdate() { - final String IDX = "test4534-moinsd"; - final String ID = "assbe"; - final String JSON = "{\"data\":{\"inner\":\"more\"}}"; - final String JSON2 = "{\"data\":{\"inner\":\"more2\"},\"data2\":\"value2\",\"data3\":true}"; - - this.insert(IDX, ID, JSON); - UpdateRequest request = new UpdateRequest(IDX, IDX, ID); - UpdateResponse response = null; - try { - request.source(new JSONObject(JSON2)); - response = dbClient.update(request); - } catch (JSONException | IOException e) { - fail(e.getMessage()); - } - assertNotNull(response); - assertTrue(response.succeeded()); - // refresh index - try { - dbClient.refreshIndex(new RefreshIndexRequest(IDX)); - } catch (IOException e) { - fail(e.getMessage()); - } - // verify update - GetRequest request3 = new GetRequest(IDX, IDX, ID); - GetResponse response3 = null; - try { - response3 = dbClient.get(request3); - } catch (IOException e1) { - fail(e1.getMessage()); - } - assertNotNull(response3); - JSONAssert.assertEquals("could not verify update", JSON2, response3.getSourceAsBytesRef(), true); - this.deleteIndex(IDX); - } - - @Test - public void testUpdateByQuery() { - final String IDX = "test224534-moinsd"; - final String ID = "asssabe"; - final String JSON = "{\"data\":{\"inner\":\"more\"}}"; - final String JSON2 = "{\"data\":{\"inner\":\"more2\"},\"data2\":\"value2\",\"data3\":true}"; - - this.insert(IDX, ID, JSON); - UpdateByQueryRequest request = new UpdateByQueryRequest(IDX, IDX); - UpdateByQueryResponse response = null; - try { - request.source(ID, new JSONObject(JSON2)); - response = dbClient.update(request); - } catch (JSONException | IOException e) { - fail(e.getMessage()); - } - assertNotNull(response); - assertTrue(response.isUpdated()); - // refresh index - try { - dbClient.refreshIndex(new RefreshIndexRequest(IDX)); - } catch (IOException e) { - fail(e.getMessage()); - } - // verify update - GetRequest request3 = new GetRequest(IDX, IDX, ID); - GetResponse response3 = null; - try { - response3 = dbClient.get(request3); - } catch (IOException e1) { - fail(e1.getMessage()); - } - assertNotNull(response3); - JSONAssert.assertEquals("could not verify update", JSON2, response3.getSourceAsBytesRef(), true); - this.deleteIndex(IDX); - } - - @Test - public void testAggregations() { - final String IDX = "test3227533677-moisnsd"; - final String JSON = "{ \"node-id\":\"sim1\",\"severity\":\"critical\"}"; - final String JSON2 = "{ \"node-id\":\"sim2\",\"severity\":\"critical\"}"; - final String JSON3 = "{ \"node-id\":\"sim3\",\"severity\":\"minor\"}"; - final String JSON4 = "{ \"node-id\":\"sim4\",\"severity\":\"warning\"}"; - final String JSON5 = "{ \"node-id\":\"sim5\",\"severity\":\"major\"}"; - final String MAPPINGS = "{\""+IDX+"\":{\"properties\":{\"node-id\": {\"type\": \"keyword\"},\"severity\": {\"type\": \"keyword\"}}}}"; - //create index with mapping keyword - CreateIndexRequest irequest = new CreateIndexRequest(IDX); - irequest.mappings(new JSONObject(MAPPINGS)); - CreateIndexResponse iresponse = null; - try { - iresponse = dbClient.createIndex(irequest); - } catch (IOException e1) { - fail("unable to create index: "+e1.getMessage()); - } - assertNotNull(iresponse); - assertTrue(iresponse.isAcknowledged()); - // fill index - this.insert(IDX, null, JSON); - this.insert(IDX, null, JSON2); - this.insert(IDX, null, JSON3); - this.insert(IDX, null, JSON4); - this.insert(IDX, null, JSON5); - // refresh index - try { - dbClient.refreshIndex(new RefreshIndexRequest(IDX)); - } catch (IOException e) { - fail(e.getMessage()); - } - - SearchRequest request = new SearchRequest(IDX, IDX); - request.setQuery(QueryBuilders.matchAllQuery().aggregations("severity").size(0)); - SearchResponse response = null; - try { - response = dbClient.search(request); - } catch (IOException e) { - fail(e.getMessage()); - } - assertNotNull(response); - assertTrue(response.hasAggregations()); - assertEquals("aggregation size not correct", 4, response.getAggregations("severity").size()); - - List items1 = Arrays.asList(response.getAggregations("severity").getKeysAsPagedStringList(2, 0)); - List items2 = Arrays.asList(response.getAggregations("severity").getKeysAsPagedStringList(2, 2)); - assertEquals("pagination does not work", 2,items1.size()); - assertEquals("pagination does not work", 2,items2.size()); - for(String s:items1) { - assertFalse("pagination overlap is not allowed",items2.contains(s)); - } - for(String s:items2) { - assertFalse("pagination overlap is not allowed",items1.contains(s)); - } - - this.deleteIndex(IDX); - } - - @Test - public void testStatistics() { - NodeStatsResponse stats=null; - try { - stats = dbClient.stats(new NodeStatsRequest()); - } catch (IOException e) { - fail(e.getMessage()); - } - assertNotNull(stats); - System.out.println(stats.getNodesInfo()); - System.out.println(stats.getNodeStatistics()); - } - private void deleteIndex(String idx) { - try { - dbClient.deleteIndex( new DeleteIndexRequest(idx)); - } catch (IOException e) { - - } - } - -} diff --git a/sdnr/wt/data-provider/database/pom.xml b/sdnr/wt/data-provider/database/pom.xml new file mode 100644 index 000000000..444cd59bf --- /dev/null +++ b/sdnr/wt/data-provider/database/pom.xml @@ -0,0 +1,169 @@ + + + + 4.0.0 + org.onap.ccsdk.features.sdnr.wt + sdnr-wt-data-provider-database + 0.7.0-SNAPSHOT + ccsdk-features-sdnr-wt :: ${project.artifactId} + bundle + + + org.onap.ccsdk.parent + binding-parent + 1.5.1-SNAPSHOT + + + + + true + 49401 + + + + + Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0 + + + + + + org.mockito + mockito-core + test + + + org.opendaylight.netconf + sal-netconf-connector + provided + + + + + + + + org.osgi + org.osgi.core + provided + + + ${project.groupId} + sdnr-wt-common + ${project.version} + + + ${project.groupId} + sdnr-wt-data-provider-model + ${project.version} + + + + + + + + + + + org.jacoco + jacoco-maven-plugin + + + **/gen/** + **/generated-sources/** + **/yang-gen-sal/** + **/pax/** + + + + + org.codehaus.mojo + exec-maven-plugin + + + generateDTOs + generate-sources + + exec + + + ${skipTests} + ${basedir}/src/main/resources/es-init.sh + + initfile + -f + ${project.build.directory}/EsInit.script + + + + + + + com.github.alexcojocaru + elasticsearch-maven-plugin + 6.16 + + true + testCluster + 9500 + ${databaseport} + 6.4.3 + ${project.build.directory}/EsInit.script + + + + start-elasticsearch + process-test-classes + + runforked + + + + stop-elasticsearch + prepare-package + + stop + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + databaseport + ${databaseport} + + + + + + + diff --git a/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/base/netconf/util/InternalConnectionStatus.java b/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/base/netconf/util/InternalConnectionStatus.java new file mode 100644 index 000000000..81876b75b --- /dev/null +++ b/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/base/netconf/util/InternalConnectionStatus.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * ============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.base.netconf.util; + +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; + +public class InternalConnectionStatus { + public static ConnectionLogStatus statusFromNodeStatus(ConnectionStatus nodeStatus) { + switch(nodeStatus) { + case Connected: + return ConnectionLogStatus.Connected; + case Connecting: + return ConnectionLogStatus.Connecting; + case UnableToConnect: + return ConnectionLogStatus.UnableToConnect; + default: + return ConnectionLogStatus.Undefined; + } + } +} diff --git a/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/base/netconf/util/NetconfTimeStamp.java b/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/base/netconf/util/NetconfTimeStamp.java new file mode 100644 index 000000000..4857da661 --- /dev/null +++ b/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/base/netconf/util/NetconfTimeStamp.java @@ -0,0 +1,206 @@ +/******************************************************************************* + * ============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.base.netconf.util; + +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.Date; + +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 2019/06/17 Redesign to ZonedDateTime because of sync problems. + * + * Function is handling the NETCONF and the format used by database and restconf communication. + * + * Input supported for the formats used in NETCONF messages: + * + * Format1 ISO 8601 2017-01-18T11:44:49.482-05:00 + * + * Format2 NETCONF - pattern from ietf-yang-types "2013-07-15" Pattern: + * "\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[\+\-](\d{2}):(\d{2}))" + * + * Format3 NETCONF DateAndTime CoreModel-CoreFoundationModule-TypeDefinitions vom + * 2016-07-01 Example1: 20170118114449.1Z Example2: 20170118114449.1-0500 Pattern: + * "\d{4}\d{2}\d{2}\d{2}\d{2}\d{2}.\d+?(Z|[\+\-](\d{2})(\d{2}))" typedef DateAndTime { description + * "This primitive type defines the date and time according to the following structure: + * 'yyyyMMddhhmmss.s[Z|{+|-}HHMm]' where: yyyy '0000'..'9999' year MM '01'..'12' month dd '01'..'31' + * day hh '00'..'23' hour mm '00'..'59' minute ss '00'..'59' second s '.0'..'.9' tenth of second + * (set to '.0' if EMS or NE cannot support this granularity) Z 'Z' indicates UTC (rather than local + * time) {+|-} '+' or '-' delta from UTC HH '00'..'23' time zone difference in hours Mm '00'..'59' + * time zone difference in minutes."; type string; } Format4 E/// specific Example1: + * 2017-01-23T13:32:38-05:00 Example2: 2017-01-23T13:32-05:00 + * + * Input formats netconfTime as String according the formats given above + * + * Return format is String in ISO8601 Format for database and presentation. + * + * Example formats: + * 1) ISO8601. Example 2017-01-18T11:44:49.482-05:00 + * 2) Microwave ONF. Examples 20170118114449.1Z, 20170118114449.1-0500 + * 3.1) Ericson. Example: 2017-01-23T13:32:38-05:00 + * 3.2) Ericson. Example: 2017-01-23T13:32-05:00 + * Always 10 Groups, + * 1:Year 2:Month 3:day 4:Hour 5:minute 6:optional sec 7:optional ms 8:optional Z or 9:offset + * signedhour 10:min + * + * Template: + * private static final NetconfTimeStamp NETCONFTIME_CONVERTER = NetconfTimeStamp.getConverter(); + */ + +public class NetconfTimeStamp { + private static final Logger LOG = LoggerFactory.getLogger(NetconfTimeStamp.class); + + private static final NetconfTimeStamp CONVERTER = new NetconfTimeStamp(); + + /** + * Specify the input format expected from netconf, and from specific devices. + */ + private static DateTimeFormatter formatterInput = DateTimeFormatter.ofPattern("" + + "[yyyy-MM-dd'T'HH:mm[:ss][.SSS][.SS][.S][xxx][xx][X][Z]]" + + "[yyyyMMddHHmmss[.SSS][.SS][.S][xxx][xx][X][Z]]" + ).withZone(ZoneOffset.UTC); + + /** + * Specify output format that is used internally + */ + private static DateTimeFormatter formatterOutput = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.S'Z'") + .withZone(ZoneOffset.UTC); + + /** + * Use static access + */ + private NetconfTimeStamp() { + } + + /* + * ------------------------------------ Public function + */ + + /** + * Use this function to get the converter + * @return global converter + */ + public static NetconfTimeStamp getConverter() { + return CONVERTER; + } + + /** + * Get actual timestamp as NETCONF specific type NETCONF/YANG 1.0 Format + * + * @return String with Date in NETCONF/YANG Format Version 1.0. + */ + public String getTimeStampAsNetconfString() { + return ZonedDateTime.now(ZoneOffset.UTC).format(formatterOutput); + } + + /** + * Get actual timestamp as NETCONF specific type NETCONF/YANG 1.0 Format + + * @return String with Date in NETCONF/YANG Format Version 1.0. + */ + public String getTimeStampAsNetconfString(Date date) { + return ZonedDateTime.ofInstant(date.toInstant(),ZoneOffset.UTC).format(formatterOutput); + } + + + + /** + * Get actual timestamp as NETCONF specific type NETCONF/YANG 1.0 Format in GMT + * + * @return DateAndTime Type 1.0. Date in NETCONF/YANG Format Version 1.0. + */ + public DateAndTime getTimeStamp() { + return DateAndTime.getDefaultInstance(getTimeStampAsNetconfString()); + } + + /** + * Get time from date as NETCONF specific type NETCONF/YANG 1.0 Format in GMT + * @param date specifying the date and time + * @return DateAndTime Type 1.0. Date in NETCONF/YANG Format Version 1.0. + */ + public DateAndTime getTimeStamp(Date date) { + return DateAndTime.getDefaultInstance(getTimeStampAsNetconfString(date)); + } + /** + * Get time from date as NETCONF specific type NETCONF/YANG 1.0 Format in GMT + * @param date specifying the date and time + * @return DateAndTime Type 1.0. Date in NETCONF/YANG Format Version 1.0. + */ + public DateAndTime getTimeStamp(String date) { + return DateAndTime.getDefaultInstance(date); + } + + /** + * Return the String with a NETCONF time converted to long + * + * @param netconfTime as String according the formats given above + * @return Epoch milliseconds + * @throws IllegalArgumentException In case of no compliant time format definition for the string + */ + public long getTimeStampFromNetconfAsMilliseconds(String netconfTime) throws IllegalArgumentException { + try { + long utcMillis = doParse(netconfTime).toInstant().toEpochMilli(); + return utcMillis; + } catch (DateTimeParseException e) { + throw new IllegalArgumentException( + "No pattern for NETCONF data string: " + netconfTime + " Msg:" + e.getMessage()); + } + } + + /** + * Deliver String result. + * + * @param netconfTime as String according the formats given above + * @return If successful: String in ISO8601 Format for database and presentation. If "wrong formed + * input" the Input string with the prefix "Maleformed date" is delivered back. + */ + public String getTimeStampFromNetconf(String netconfTime) { + try { + String inputUTC = doParse(netconfTime).format(formatterOutput); + return inputUTC; + } catch (Exception e) { + LOG.info(e.getMessage()); + } + LOG.debug("No pattern for NETCONF data string: {}", netconfTime); + return "Malformed date: " + netconfTime; // Error handling + } + + /*---------------------------------------------------- + * Private functions + */ + + private OffsetDateTime doParse(String netconfTime) { + return OffsetDateTime.parse(netconfTime, formatterInput); + } + + public Date getDateFromNetconf(String netconfTime) { + return Date.from(LocalDateTime.parse(netconfTime, formatterInput).atZone(ZoneOffset.UTC).toInstant()); + } + + public String getTimeStampAsNetconfString(LocalDateTime dt) { + return formatterOutput.format(dt); + } + +} diff --git a/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/database/EsDataObjectReaderWriter.java b/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/database/EsDataObjectReaderWriter.java new file mode 100644 index 000000000..ac676024f --- /dev/null +++ b/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/database/EsDataObjectReaderWriter.java @@ -0,0 +1,339 @@ +/******************************************************************************* + * ============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.database; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.List; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import org.onap.ccsdk.features.sdnr.wt.common.database.DatabaseClient; +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.onap.ccsdk.features.sdnr.wt.yangtools.YangToolsMapper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Entity; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonProcessingException; + +/** + * Class to rw yang-tool generated objects into elasticsearch database. For "ES _id" exchange the esIdAddAtributteName is used. + * This attribute mast be of type String and contains for read and write operations the object id. + * The function can be used without id handling. + * If id handling is required the parameter needs to be specified by class definition in yang and setting the name by using setAttributeName() + * + * @param Yang tools generated class object. + */ +public class EsDataObjectReaderWriter { + + private final Logger LOG = LoggerFactory.getLogger(EsDataObjectReaderWriter.class); + + /** Typename for elastic search data schema **/ + private String dataTypeName; + + /** Elasticsearch Database client to be used **/ + private DatabaseClient db; + + /** Mapper with configuration to use opendaylight yang-tools builder pattern for object creation **/ + private YangToolsMapper yangtoolsMapper; + + /** Class of T as attribute to allow JSON to Class object mapping **/ + private Class clazz; + + /** Field is used to write id. If null no id handling **/ + private @Nullable Field field; + + /** Attribute that is used as id field for the database object **/ + private @Nullable String esIdAddAtributteName; + + /** Interface to be used for write operations. Rule for write: T extends S and **/ + private Class writeInterfaceClazz; // == "S" + + /** + * Elasticsearch database read and write for specific class, defined by opendaylight yang-tools. + * + * @param db Database access client + * @param dataTypeName typename in database schema + * @param clazz class of type to be handled + * @throws ClassNotFoundException + */ + public EsDataObjectReaderWriter(DatabaseClient db, Entity dataTypeName, Class clazz) throws ClassNotFoundException { + this(db, dataTypeName.getName(), clazz); + } + public EsDataObjectReaderWriter(DatabaseClient db, String dataTypeName, Class clazz) throws ClassNotFoundException { + LOG.info("Create {} for datatype {} class {}", this.getClass().getName(), dataTypeName, clazz.getName()); + + this.esIdAddAtributteName = null; + this.field = null; + this.writeInterfaceClazz = clazz; + this.db = db; + this.dataTypeName = dataTypeName; + this.yangtoolsMapper = new YangToolsMapper(); + //this.yangtoolsMapper.assertBuilderClass(clazz); + this.clazz = clazz; +// +// if (! db.isExistsIndex(dataTypeName)) { +// throw new IllegalArgumentException("Index "+dataTypeName+" not existing."); +// } + } + + public String getDataTypeName() { + return dataTypeName; + } + public Class getClazz() { + return clazz; + } + /** + * Simlar to {@link #setEsIdAttributeName()}, but adapts the parameter to yangtools attribute naming schema + * @param esIdAttributeName is converted to UnderscoreCamelCase + * @return this for further operations. + */ + public EsDataObjectReaderWriter setEsIdAttributeNameCamelized(String esIdAttributeName) { + return setEsIdAttributeName(YangToolsMapper.toCamelCaseAttributeName(esIdAttributeName)); + } + + /** + * Attribute name of class that is containing the object id + * @param esIdAttributeName of the implementation class for the yangtools interface. + * Expected attribute name format is CamelCase with leading underline. @ + * @return this for further operations. + * @throws SecurityException if no access or IllegalArgumentException if wrong type or no attribute with this name. + */ + public EsDataObjectReaderWriter setEsIdAttributeName(String esIdAttributeName) { + LOG.debug("Set attribute '{}'", esIdAttributeName); + this.esIdAddAtributteName = null; // Reset status + this.field = null; + + Field attributeField; + try { + Builder builder = yangtoolsMapper.getBuilder(clazz); + T object = builder.build(); + attributeField = object.getClass().getDeclaredField(esIdAttributeName); + if (attributeField.getType().equals(String.class)) { + attributeField.setAccessible(true); + this.esIdAddAtributteName = esIdAttributeName; //Set new status if everything OK + this.field = attributeField; + } else { + String msg = "Wrong field type " + attributeField.getType().getName() + " of " + esIdAttributeName; + LOG.debug(msg); + throw new IllegalArgumentException(msg); + } + } catch (NoSuchFieldException e) { + // Convert to run-time exception + String msg = "NoSuchFieldException for '" + esIdAttributeName + "' in class " + clazz.getName(); + LOG.debug(msg); + throw new IllegalArgumentException(msg); + } catch (SecurityException e) { + LOG.debug("Access problem "+esIdAttributeName,e); + throw e; + } + return this; + } + + /** + * Specify subclass of T for write operations. + * @param writeInterfaceClazz + */ + public EsDataObjectReaderWriter setWriteInterface( @Nonnull Class writeInterfaceClazz ) { + LOG.debug("Set write interface to {}", writeInterfaceClazz); + if (writeInterfaceClazz == null) + throw new IllegalArgumentException("Null not allowed here."); + + this.writeInterfaceClazz = writeInterfaceClazz; + return this; + } + + /** + * Write child object to database with specific id + * @param object + * @param @Nullable esId use the id or if null generate unique id + * @return String with id or null + */ + public @Nullable String write(S object, @Nullable String esId) { + if (writeInterfaceClazz.isInstance(object)) { + try { + String json = yangtoolsMapper.writeValueAsString(object); + return db.doWriteRaw(dataTypeName, esId, json); + } catch (JsonProcessingException e) { + LOG.error("Write problem: ", e); + } + } else { + LOG.error("Type {} does not provide interface {}", object!=null?object.getClass().getName():"null", + writeInterfaceClazz.getName()); + } + return null; + } + /** + * Update partial child object to database with match/term query + * @param object + * @param esId + * @return String with esId or null + */ + public @Nullable String update(S object, QueryBuilder query) { + if (writeInterfaceClazz.isInstance(object)) { + try { + String json = yangtoolsMapper.writeValueAsString(object); + return db.doUpdate(this.dataTypeName,json,query); + } catch (JsonProcessingException e) { + LOG.error("Update problem: ", e); + } + } else { + LOG.error("Type {} does not provide interface {}", object!=null?object.getClass().getName():"null", + writeInterfaceClazz.getName()); + } + return null; + } + /** + * Write/ update partial child object to database with specific id Write if not + * exists, else update + * @param object + * @param esId + * @return String with esId or null + */ + public @Nullable String update(S object, String esId) { + return this.update(object, esId,null); + } + public @Nullable String update(S object, String esId,List onylForInsert) { + if (writeInterfaceClazz.isInstance(object)) { + try { + String json = yangtoolsMapper.writeValueAsString(object); + return db.doUpdateOrCreate(dataTypeName, esId, json,onylForInsert); + } catch (JsonProcessingException e) { + LOG.error("Update problem: ", e); + } + } else { + LOG.error("Type {} does not provide interface {}", object!=null?object.getClass().getName():"null", + writeInterfaceClazz.getName()); + } + return null; + } + + /** + * Read object from database, by using the id field + * @param object + * @return + */ + public @Nullable T read(String esId) { + @Nullable T res = (T)null; + if (esId != null) { + String json = db.doReadJsonData(dataTypeName, esId); + try { + res = yangtoolsMapper.readValue(json.getBytes(), clazz); + } catch (IOException e) { + LOG.error("Problem: ", e); + } + } + return res; + } + + /** + * Remove object + * @param esId to identify the object. + * @return success + */ + public boolean remove(String esId) { + return db.doRemove(this.dataTypeName, esId); + } + + public int remove(QueryBuilder query) { + return this.db.doRemove(this.dataTypeName, query); + } + /** + * Get all elements of related type + * @return all Elements + */ + public SearchResult doReadAll() { + return doReadAll(null); + } + public SearchResult doReadAll(QueryBuilder query) { + return this.doReadAll(query,false); + } + /** + * Read all existing objects of a type + * @param query for the elements + * @return the list of all objects + */ + + public SearchResult doReadAll(QueryBuilder query, boolean ignoreException) { + + SearchResult res = new SearchResult(); + int idx = 0; //Idx for getAll + int iterateLength = 100; //Step width for iterate + + SearchResult result; + List hits; + do { + if(query!=null) { + LOG.debug("read data in {} with query {}",dataTypeName,query.toJSON()); + result=db.doReadByQueryJsonData( dataTypeName, query,ignoreException); + } + else { + result = db.doReadAllJsonData(dataTypeName,ignoreException); + } + hits=result.getHits(); + LOG.debug("Read: {} elements: {} Failures: {}",dataTypeName,hits.size(), yangtoolsMapper.getMappingFailures()); + + T object; + idx += result.getHits().size(); + for (SearchHit hit : hits) { + object = getT(hit.getSourceAsString()); + LOG.debug("Mapp Object: {}\nSource: '{}'\nResult: '{}'\n Failures: {}", hit.getId(), + hit.getSourceAsString(), object, yangtoolsMapper.getMappingFailures()); + if (object != null) { + setEsId(object, 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(result.getTotal()); + return res; + } + + /* --------------------------------------------- + * Private functions + */ + + private void setEsId(T object, String esId) { + if (field != null) { + try { + field.set(object, esId); + } catch (IllegalArgumentException | IllegalAccessException e) { + LOG.debug("Field set problem.", e); } + } + } + + private @Nullable T getT(String jsonString) { + try { + return yangtoolsMapper.readValue( jsonString, clazz ); + } catch (IOException e) { + LOG.info("Mapping problem", e); + return (T)null; + } + } + +} diff --git a/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/database/EsDataObjectReaderWriter2.java b/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/database/EsDataObjectReaderWriter2.java new file mode 100644 index 000000000..b585b0c60 --- /dev/null +++ b/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/database/EsDataObjectReaderWriter2.java @@ -0,0 +1,360 @@ +/******************************************************************************* + * ============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.database; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.List; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import org.eclipse.jdt.annotation.NonNull; +import org.onap.ccsdk.features.sdnr.wt.common.database.DatabaseClient; +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.onap.ccsdk.features.sdnr.wt.yangtools.YangToolsMapper; +import org.onap.ccsdk.features.sdnr.wt.yangtools.YangToolsMapper2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Entity; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonProcessingException; + +/** + * Class to rw yang-tool generated objects into elasticsearch database. For "ES _id" exchange the esIdAddAtributteName is used. + * This attribute mast be of type String and contains for read and write operations the object id. + * The function can be used without id handling. + * If id handling is required the parameter needs to be specified by class definition in yang and setting the name by using setAttributeName() + * + * Due to using Jackson base interfaces the org.eclipse.jdt.annotation.NonNull needs to be used here to get rid of warnings + * + * @param Yang tools generated class object. + */ +public class EsDataObjectReaderWriter2 { + + private final Logger LOG = LoggerFactory.getLogger(EsDataObjectReaderWriter2.class); + + /** Typename for elastic search data schema **/ + private String dataTypeName; + + /** Elasticsearch Database client to be used **/ + private DatabaseClient db; + + /** Mapper with configuration to use opendaylight yang-tools builder pattern for object creation **/ + private YangToolsMapper2 yangtoolsMapper; + + /** Class of T as attribute to allow JSON to Class object mapping **/ + private Class clazz; + + /** Field is used to write id. If null no id handling **/ + private @Nullable Field field; + + /** Attribute that is used as id field for the database object **/ + private @Nullable String esIdAddAtributteName; + + /** Interface to be used for write operations. Rule for write: T extends S and **/ + private Class writeInterfaceClazz; // == "S" + + /** + * Elasticsearch database read and write for specific class, defined by opendaylight yang-tools. + * + * @param db Database access client + * @param dataTypeName typename in database schema + * @param clazz class of type to be handled + * @throws ClassNotFoundException + */ + public > EsDataObjectReaderWriter2(DatabaseClient db, Entity dataTypeName, @Nonnull Class clazz, @Nullable Class builderClazz) throws ClassNotFoundException { + this(db, dataTypeName.getName(), clazz, builderClazz); + } + public > EsDataObjectReaderWriter2(DatabaseClient db, Entity dataTypeName, @Nonnull Class clazz) throws ClassNotFoundException { + this(db, dataTypeName.getName(), clazz, null); + } + public > EsDataObjectReaderWriter2(DatabaseClient db, String dataTypeName, @Nonnull Class clazz, @Nullable Class builderClazz) throws ClassNotFoundException { + LOG.info("Create {} for datatype {} class {}", this.getClass().getName(), dataTypeName, clazz.getName()); + + this.esIdAddAtributteName = null; + this.field = null; + this.writeInterfaceClazz = clazz; + this.db = db; + this.dataTypeName = dataTypeName; + this.yangtoolsMapper = new YangToolsMapper2<>(clazz, builderClazz); + this.clazz = clazz; + } + + /** + * Simlar to {@link #setEsIdAttributeName()}, but adapts the parameter to yangtools attribute naming schema + * @param esIdAttributeName is converted to UnderscoreCamelCase + * @return this for further operations. + */ + public EsDataObjectReaderWriter2 setEsIdAttributeNameCamelized(String esIdAttributeName) { + return setEsIdAttributeName(YangToolsMapper.toCamelCaseAttributeName(esIdAttributeName)); + } + + /** + * Attribute name of class that is containing the object id + * @param esIdAttributeName of the implementation class for the yangtools interface. + * Expected attribute name format is CamelCase with leading underline. @ + * @return this for further operations. + * @throws SecurityException if no access or IllegalArgumentException if wrong type or no attribute with this name. + */ + public EsDataObjectReaderWriter2 setEsIdAttributeName(String esIdAttributeName) { + LOG.debug("Set attribute '{}'", esIdAttributeName); + this.esIdAddAtributteName = null; // Reset status + this.field = null; + + Field attributeField; + try { + Builder builder = yangtoolsMapper.getBuilder(clazz); + if (builder == null) { + String msg = "No builder for " + clazz; + LOG.debug(msg); + throw new IllegalArgumentException(msg); + } else { + T object = builder.build(); + attributeField = object.getClass().getDeclaredField(esIdAttributeName); + if (attributeField.getType().equals(String.class)) { + attributeField.setAccessible(true); + this.esIdAddAtributteName = esIdAttributeName; // Set new status if everything OK + this.field = attributeField; + } else { + String msg = "Wrong field type " + attributeField.getType().getName() + " of " + esIdAttributeName; + LOG.debug(msg); + throw new IllegalArgumentException(msg); + } + } + } catch (NoSuchFieldException e) { + // Convert to run-time exception + String msg = "NoSuchFieldException for '" + esIdAttributeName + "' in class " + clazz.getName(); + LOG.debug(msg); + throw new IllegalArgumentException(msg); + } catch (SecurityException e) { + LOG.debug("Access problem "+esIdAttributeName,e); + throw e; + } + return this; + } + + /** + * Specify subclass of T for write operations. + * @param writeInterfaceClazz + */ + public EsDataObjectReaderWriter2 setWriteInterface( @Nonnull Class writeInterfaceClazz ) { + LOG.debug("Set write interface to {}", writeInterfaceClazz); + if (writeInterfaceClazz == null) { + throw new IllegalArgumentException("Null not allowed here."); + } + + this.writeInterfaceClazz = writeInterfaceClazz; + return this; + } + + public interface IdGetter { + String getId(S object); + } + + public void write(List objectList, IdGetter idGetter) { + for (S object : objectList) { + write(object, idGetter.getId(object)); + } + } + + /** + * Write child object to database with specific id + * @param object + * @param @Nullable esId use the id or if null generate unique id + * @return String with id or null + */ + public @Nullable String write(S object, @Nullable String esId) { + if (writeInterfaceClazz.isInstance(object)) { + try { + String json = yangtoolsMapper.writeValueAsString(object); + return db.doWriteRaw(dataTypeName, esId, json); + } catch (JsonProcessingException e) { + LOG.error("Write problem: ", e); + } + } else { + LOG.error("Type {} does not provide interface {}", object!=null?object.getClass().getName():"null", + writeInterfaceClazz.getName()); + } + return null; + } + /** + * Update partial child object to database with match/term query + * @param object + * @param esId + * @return String with esId or null + */ + public @Nullable String update(S object, QueryBuilder query) { + if (writeInterfaceClazz.isInstance(object)) { + try { + String json = yangtoolsMapper.writeValueAsString(object); + return db.doUpdate(this.dataTypeName,json,query); + } catch (JsonProcessingException e) { + LOG.error("Update problem: ", e); + } + } else { + LOG.error("Type {} does not provide interface {}", object!=null?object.getClass().getName():"null", + writeInterfaceClazz.getName()); + } + return null; + } + /** + * Write/ update partial child object to database with specific id Write if not + * exists, else update + * @param object + * @param esId + * @return String with esId or null + */ + public @Nullable String update(S object, String esId) { + return this.updateOrCreate(object, esId,null); + } + /** + * See {@link doUpdateOrCreate(String dataTypeName, String esId, String json, List doNotUpdateField) } + */ + public @Nullable String updateOrCreate(S object, String esId,List onlyForInsert) { + if (writeInterfaceClazz.isInstance(object)) { + try { + String json = yangtoolsMapper.writeValueAsString(object); + return db.doUpdateOrCreate(dataTypeName, esId, json,onlyForInsert); + } catch (JsonProcessingException e) { + LOG.error("Update problem: ", e); + } + } else { + LOG.error("Type {} does not provide interface {}", object!=null?object.getClass().getName():"null", + writeInterfaceClazz.getName()); + } + return null; + } + + /** + * Read object from database, by using the id field + * @param object + * @return + */ + public @Nullable T read(String esId) { + @Nullable + T res = null; + if (esId != null) { + String json = db.doReadJsonData(dataTypeName, esId); + if (json != null) { + try { + res = yangtoolsMapper.readValue(json.getBytes(), clazz); + } catch (IOException e) { + LOG.error("Problem: ", e); + } + } else { + LOG.debug("Can not read from DB id {} type {}", esId, dataTypeName); + } + } + return res; + } + + /** + * Remove object + * @param esId to identify the object. + * @return success + */ + public boolean remove(String esId) { + return db.doRemove(this.dataTypeName, esId); + } + + public int remove(QueryBuilder query) { + return this.db.doRemove(this.dataTypeName, query); + } + /** + * Get all elements of related type + * @return all Elements + */ + public SearchResult doReadAll() { + return doReadAll(null); + } + public SearchResult doReadAll(QueryBuilder query) { + return this.doReadAll(query,false); + } + /** + * Read all existing objects of a type + * @param query for the elements + * @return the list of all objects + */ + + public SearchResult doReadAll(QueryBuilder query, boolean ignoreException) { + + SearchResult res = new SearchResult<>(); + int idx = 0; //Idx for getAll + int iterateLength = 100; //Step width for iterate + + SearchResult result; + List hits; + do { + if(query!=null) { + LOG.debug("read data in {} with query {}",dataTypeName,query.toJSON()); + result=db.doReadByQueryJsonData( dataTypeName, query,ignoreException); + } + else { + result = db.doReadAllJsonData(dataTypeName,ignoreException); + } + hits=result.getHits(); + LOG.debug("Read: {} elements: {} Failures: {}",dataTypeName,hits.size(), yangtoolsMapper.getMappingFailures()); + + T object; + idx += result.getHits().size(); + for (SearchHit hit : hits) { + object = getT(hit.getSourceAsString()); + LOG.debug("Mapp Object: {}\nSource: '{}'\nResult: '{}'\n Failures: {}", hit.getId(), + hit.getSourceAsString(), object, yangtoolsMapper.getMappingFailures()); + if (object != null) { + setEsId(object, 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(result.getTotal()); + return res; + } + + /* --------------------------------------------- + * Private functions + */ + + private void setEsId(T object, String esId) { + if (field != null) { + try { + field.set(object, esId); + } catch (IllegalArgumentException | IllegalAccessException e) { + LOG.debug("Field set problem.", e); } + } + } + + private @Nullable T getT(String jsonString) { + try { + return yangtoolsMapper.readValue( jsonString, clazz ); + } catch (IOException e) { + LOG.info("Mapping problem", e); + return null; + } + } + +} diff --git a/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/database/config/EsConfig.java b/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/database/config/EsConfig.java new file mode 100644 index 000000000..c828f3302 --- /dev/null +++ b/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/database/config/EsConfig.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * ============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.database.config; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +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.common.database.config.HostInfo; +import org.onap.ccsdk.features.sdnr.wt.common.database.config.HostInfo.Protocol; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EsConfig implements Configuration { + + private static final Logger LOG = LoggerFactory.getLogger(EsConfig.class); + + public static final String SECTION_MARKER_ES = "es"; + + private static final String PROPERTY_KEY_DBHOSTS = "esHosts"; + private static final String PROPERTY_KEY_ARCHIVE_LIMIT = "esArchiveLifetimeSeconds"; + private static final String PROPERTY_KEY_CLUSTER = "esCluster"; + private static final String PROPERTY_KEY_ARCHIVE_INTERVAL = "esArchiveCheckIntervalSeconds"; + private static final String PROPERTY_KEY_NODE = "esNode"; + + private static String defaultHostinfo = printHosts(new HostInfo[] { new HostInfo("sdnrdb", 9200, Protocol.HTTP) }); + private static final String DEFAULT_VALUE_CLUSTER = ""; + /** check db data in this interval [in seconds] 0 deactivated */ + private static final String DEFAULT_ARCHIVE_INTERVAL_SEC = "0"; + /** keep data for this time [in seconds] 30 days */ + private static final String DEFAULT_ARCHIVE_LIMIT_SEC = String.valueOf(60L * 60L * 24L * 30L); + private static final String DEFAULT_KEY_NODE = "elasticsearchnode"; + + private final ConfigurationFileRepresentation configuration; + + public EsConfig(ConfigurationFileRepresentation configuration) { + + this.configuration = configuration; + this.configuration.addSection(SECTION_MARKER_ES); + defaults(); + } + + /* + * Setter + */ + + public void setNode(String nodeName) { + configuration.setProperty(SECTION_MARKER_ES, PROPERTY_KEY_NODE, nodeName); + } + + /* + * Getter + */ + + public String getNode() { + return configuration.getProperty(SECTION_MARKER_ES, PROPERTY_KEY_NODE); + } + + public HostInfo[] getHosts() { + String dbHosts = configuration.getProperty(SECTION_MARKER_ES, PROPERTY_KEY_DBHOSTS); + return parseHosts(dbHosts); + } + public void setHosts(HostInfo[] hosts) { + this.configuration.setProperty(SECTION_MARKER_ES, PROPERTY_KEY_DBHOSTS, printHosts(hosts)); + } + public String getCluster() { + return configuration.getProperty(SECTION_MARKER_ES, PROPERTY_KEY_ARCHIVE_INTERVAL); + } + + public void setCluster(String cluster) { + configuration.setProperty(SECTION_MARKER_ES, PROPERTY_KEY_CLUSTER, cluster); + } + + public long getArchiveCheckIntervalSeconds() { + return configuration.getPropertyLong(SECTION_MARKER_ES, PROPERTY_KEY_ARCHIVE_INTERVAL).orElse(0L); + } + + public void setArchiveCheckIntervalSeconds(long seconds) { + configuration.setProperty(SECTION_MARKER_ES, PROPERTY_KEY_ARCHIVE_INTERVAL, seconds); + } + + public long getArchiveLifetimeSeconds() { + return configuration.getPropertyLong(SECTION_MARKER_ES, PROPERTY_KEY_ARCHIVE_LIMIT).orElse(0L); + } + + public void setArchiveLimit(long seconds) { + configuration.setProperty(SECTION_MARKER_ES, PROPERTY_KEY_ARCHIVE_LIMIT, seconds); + } + + @Override + public String getSectionName() { + return SECTION_MARKER_ES; + } + + @Override + public void defaults() { + // Add default if not available + configuration.setPropertyIfNotAvailable(SECTION_MARKER_ES, PROPERTY_KEY_DBHOSTS, defaultHostinfo); + configuration.setPropertyIfNotAvailable(SECTION_MARKER_ES, PROPERTY_KEY_ARCHIVE_LIMIT, + DEFAULT_ARCHIVE_LIMIT_SEC); + configuration.setPropertyIfNotAvailable(SECTION_MARKER_ES, PROPERTY_KEY_CLUSTER, DEFAULT_VALUE_CLUSTER); + configuration.setPropertyIfNotAvailable(SECTION_MARKER_ES, PROPERTY_KEY_ARCHIVE_INTERVAL, + DEFAULT_ARCHIVE_INTERVAL_SEC); + configuration.setPropertyIfNotAvailable(SECTION_MARKER_ES, PROPERTY_KEY_NODE, DEFAULT_KEY_NODE); + } + + /** @TODO Shift to own class **/ + private static String printHosts(HostInfo[] h) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < h.length; i++) { + sb.append(h[i].toUrl()); + if (i != h.length - 1) { + sb.append(","); + } + } + return sb.toString(); + } + + /** @TODO Shift to own class **/ + private static HostInfo[] parseHosts(String string) { + List infos = new ArrayList(); + String[] list = string.split(","); + if (list.length > 0) { + for (String item : list) { + try { + URL url = new URL(item); + infos.add(new HostInfo(url.getHost(), url.getPort(), Protocol.getValueOf(url.getProtocol()))); + } catch (MalformedURLException e) { + LOG.warn("problem parsing url {} : {}", item, e.getMessage()); + } + } + } + HostInfo[] a = new HostInfo[infos.size()]; + return infos.toArray(a); + } + + @Override + public String toString() { + return "EsConfig [getNode()=" + getNode() + ", getHosts()=" + Arrays.toString(getHosts()) + ", getCluster()=" + + getCluster() + ", getArchiveCheckIntervalSeconds()=" + getArchiveCheckIntervalSeconds() + + ", getArchiveLifetimeSeconds()=" + getArchiveLifetimeSeconds() + ", getSectionName()=" + + getSectionName() + "]"; + } + +} diff --git a/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/yangtools/YangToolsCloner.java b/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/yangtools/YangToolsCloner.java new file mode 100644 index 000000000..1ac19ff34 --- /dev/null +++ b/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/yangtools/YangToolsCloner.java @@ -0,0 +1,217 @@ +/******************************************************************************* + * ============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.yangtools; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.Nullable; + +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class YangToolsCloner { + + private static YangToolsMapper yangtoolsMapper = new YangToolsMapper(); + private static final Logger LOG = LoggerFactory.getLogger(YangToolsCloner.class); + public static final int ACCESSOR_FIELD = 0; + public static final int ACCESSOR_METHOD = 1; + + + private final int accessor; + + private YangToolsCloner(int ac) { + this.accessor = ac; + } + public static YangToolsCloner instance() { + return instance(ACCESSOR_METHOD); + } + public static YangToolsCloner instance(int ac) { + return new YangToolsCloner(ac); + } + /** + * + * @param source source object + * @param clazz Class of return object + * @return list of cloned object + * @return + */ + public List cloneList(List source, Class clazz) { + return cloneList(source, clazz, null); + } + + /** + * + * @param source source object + * @param clazz Class of return object + * @attrList filter for attribute Names to clone + * @return list of cloned object + */ + public List cloneList(List source, Class clazz, + @Nullable List attrList) { + if (source == null) { + return null; + } + List list = new ArrayList(); + for (S s : source) { + list.add(clone(s, clazz, attrList)); + } + return list; + } + + /** + * + * @param source source object + * @param clazz Class of return object + * @return cloned object + */ + public T clone(S source, Class clazz) { + return clone(source, clazz, null); + } + /** + * + * @param source source object + * @param clazz Class of return object + * @attrList if empty copy all else list of attribute Names to clone + * @return cloned object + */ + public T clone(S source, Class clazz, + @Nullable List attrList) { + if (source == null) { + return (T)null; + } + Field[] attributeFields; + Field sourceField; + Method m; + Builder builder = yangtoolsMapper.getBuilder(clazz); + T object = builder.build(); + attributeFields = object.getClass().getDeclaredFields(); + for (Field attributeField : attributeFields) { + // check if attr is in inclusion list + if (attrList != null && !attrList.contains(attributeField.getName())) { + continue; + } + // ignore QNAME + if (attributeField.getName().equals("QNAME")) { + continue; + } + + attributeField.setAccessible(true); + try { + if(accessor==ACCESSOR_FIELD) { + sourceField = source.getClass().getDeclaredField(attributeField.getName()); + sourceField.setAccessible(true); + if (attributeField.getType().equals(String.class) && !sourceField.getType().equals(String.class)) { + attributeField.set(object, String.valueOf(sourceField.get(source))); + } else { + attributeField.set(object, sourceField.get(source)); + } + } + else if(accessor==ACCESSOR_METHOD) { + String getter = getter(attributeField.getName()); + System.out.println("getter="+getter); + m = source.getClass().getDeclaredMethod(getter); + m.setAccessible(true); + if (attributeField.getType().equals(String.class) && !m.getReturnType().equals(String.class)) { + attributeField.set(object, String.valueOf(m.invoke(source))); + } else { + attributeField.set(object, m.invoke(source)); + } + } + + } catch (NoSuchMethodException | NoSuchFieldException e) { + // Convert to run-time exception + String msg = "no such field " + attributeField.getName() + " in class " + source.getClass().getName(); + LOG.debug(msg); + // throw new IllegalArgumentException(msg); + } catch (IllegalAccessException|SecurityException e) { + LOG.debug("Access problem " + attributeField.getName(), e); + } catch (IllegalArgumentException e) { + LOG.debug("argument problem " + attributeField.getName(), e); + } catch (InvocationTargetException e) { + LOG.debug("invocation problem " + attributeField.getName(), e); + } + } + + return object; + } + + private static String getter(String name) { + return String.format("%s%s%s","get",name.substring(1, 2).toUpperCase(),name.substring(2)); + } + public > B cloneToBuilder(S source, B builder){ + return cloneToBuilder(source, builder,null); + } + public > B cloneToBuilder(S source, B builder, + @Nullable List attrList) { + Field[] attributeFields; + Field sourceField; + Method m; + attributeFields = builder.getClass().getDeclaredFields(); + for (Field attributeField : attributeFields) { + // check if attr is in inclusion list + if (attrList != null && !attrList.contains(attributeField.getName())) { + continue; + } + // ignore QNAME + if (attributeField.getName().equals("QNAME")) { + continue; + } + + attributeField.setAccessible(true); + try { + if(accessor==ACCESSOR_FIELD) { + sourceField = source.getClass().getDeclaredField(attributeField.getName()); + sourceField.setAccessible(true); + if (attributeField.getType().equals(String.class) && !sourceField.getType().equals(String.class)) { + attributeField.set(builder, String.valueOf(sourceField.get(source))); + } else { + attributeField.set(builder, sourceField.get(source)); + } + } + else if(accessor==ACCESSOR_METHOD) { + m = source.getClass().getDeclaredMethod(getter(attributeField.getName())); + m.setAccessible(true); + if (attributeField.getType().equals(String.class) && !m.getReturnType().equals(String.class)) { + attributeField.set(builder, String.valueOf(m.invoke(source))); + } else { + attributeField.set(builder, m.invoke(source)); + } + } + + } catch (NoSuchMethodException | NoSuchFieldException e) { + // Convert to run-time exception + String msg = "no such field " + attributeField.getName() + " in class " + source.getClass().getName(); + LOG.debug(msg); + // throw new IllegalArgumentException(msg); + } catch (IllegalAccessException|SecurityException e) { + LOG.debug("Access problem " + attributeField.getName(), e); + } catch (IllegalArgumentException e) { + LOG.debug("argument problem " + attributeField.getName(), e); + } catch (InvocationTargetException e) { + LOG.debug("invocation problem " + attributeField.getName(), e); + } + } + return builder; + } +} diff --git a/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/yangtools/YangToolsCloner2.java b/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/yangtools/YangToolsCloner2.java new file mode 100644 index 000000000..37d7aa4ad --- /dev/null +++ b/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/yangtools/YangToolsCloner2.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * ============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.yangtools; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.annotation.Nullable; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class YangToolsCloner2 { + + private static final Logger LOG = LoggerFactory.getLogger(YangToolsCloner2.class); + + public enum Accessor { + ACCESSOR_FIELD, + ACCESSOR_METHOD; + } + + private Accessor accessor; + + public YangToolsCloner2() { + LOG.info("Provide new {}",this.getClass().getName()); + this.accessor = Accessor.ACCESSOR_METHOD; + } + + YangToolsCloner2 setAcessor(Accessor accessor) { + this.accessor = accessor; + return this; + } + + Accessor getAccessor() { + return accessor; + } + + public interface Builder { + T build(); + } + + /** + * + * @param source source object + * @param clazz Class of return object + * @attrList filter for attribute Names to clone + * @return list of cloned object + * @throws Exception + */ + public List cloneList(List source, Builder builder, String ... attrList) throws Exception { + if (source == null) { + return null; + } + List list = new ArrayList(); + for (S s : source) { + list.add(copyAttributes(s, builder.build(), attrList)); + } + return list; + } + + /** + * Copy attributes from source to destination object. + * Copy the references. + * @param source source object + * @param clazz Class of return object + * @attrList attribute Names NOT to clone. + * @return cloned object + * @throws Exception + */ + @SuppressWarnings("null") + public @Nullable T copyAttributes(S source, T destination, String ... attributeArray) throws Exception { + + LOG.debug("copyAttributes source.class {} destination.class {} attributes {}", source, destination, attributeArray.length); + + if (destination == null || source == null) + return null; + + List attributeList = Arrays.asList(attributeArray); + LOG.debug("copyAttributes 2 attributes {}", attributeList); + + Field[] destinationAttributeFields = source.getClass().getDeclaredFields(); + String destinationName; + Class destinationType; + for (Field destinationAttributeField : destinationAttributeFields) { + destinationName = destinationAttributeField.getName(); + destinationType = destinationAttributeField.getType(); + LOG.debug("Field: {}", destinationName); + // check if attr is in exclusion list + if (attributeList.contains(destinationName)) { + continue; + } + // ignore QNAME + if (destinationName.equals("QNAME")) { + continue; + } + + destinationAttributeField.setAccessible(true); + Object sourceData = null; + Class sourceType = null; + Class sourceListType = null; + try { + if (accessor == Accessor.ACCESSOR_FIELD) { + Field sourceField; + sourceField = source.getClass().getDeclaredField(destinationName); + sourceField.setAccessible(true); + sourceType = sourceField.getType(); + sourceData = sourceField.get(source); + sourceListType = getListClass(sourceType, sourceData); + + } else if (accessor == Accessor.ACCESSOR_METHOD) { + Method sourceMethod; + sourceMethod = source.getClass().getDeclaredMethod(getter(destinationName)); + sourceMethod.setAccessible(true); + sourceType = sourceMethod.getReturnType(); + sourceData = sourceMethod.invoke(source); + sourceListType = getListClass(sourceType, sourceData); + } + LOG.info("Handle {} {} {}", destinationName, destinationType, sourceType); + if (destinationType == sourceType) { + destinationAttributeField.set(destination, sourceData); + } else { + throw new Exception( + "Problem to copy attribute " + destinationName + +" Sourceclass:" +sourceType + +" Destinationclass:" + destinationType + +" Method:"+accessor.name()); + } + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException + | NoSuchMethodException | InvocationTargetException e) { + throw e; + } + } + return destination; + + } + + private static String getter(String name) { + if (name == null || name.length() == 0) { + return null; + } else if (name.length() == 1) { + return String.format("%s%s", "get", name.substring(1, 2).toUpperCase()); + } else { // >= 2 + return String.format("%s%s%s", "get", name.substring(1, 2).toUpperCase(), name.substring(2)); + } + } + + private static Class getListClass(Class sourceType, Object sourceData) { + if (sourceData != null && sourceType.equals(List.class)) { + List sourceDataList = (List)sourceData; + if (sourceDataList.size() > 0) { + LOG.info("Is list with type"+sourceDataList.get(0).getClass().getName()); + } else { + LOG.info("Is empty list"); + } + } + return(sourceType); + } + +} diff --git a/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/yangtools/YangToolsMapper.java b/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/yangtools/YangToolsMapper.java new file mode 100644 index 000000000..8306cb7d4 --- /dev/null +++ b/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/yangtools/YangToolsMapper.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * ============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.yangtools; + +import java.io.IOException; +import javax.annotation.Nullable; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder.Value; +import com.fasterxml.jackson.databind.introspect.AnnotatedClass; +import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +/** + * YangToolsMapper is a specific Jackson mapper configuration for opendaylight yangtools serialization or deserialization of DataObject to/from JSON + * TODO ChoiceIn and Credentials deserialization only for LoginPasswordBuilder + */ +public class YangToolsMapper extends ObjectMapper { + + private final Logger LOG = LoggerFactory.getLogger(YangToolsMapper.class); + private static final long serialVersionUID = 1L; + private static BundleContext context; + + public YangToolsMapper() { + super(); + configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + setPropertyNamingStrategy(PropertyNamingStrategy.KEBAB_CASE); + setSerializationInclusion(Include.NON_NULL); + setAnnotationIntrospector(new YangToolsBuilderAnnotationIntrospector()); + SimpleModule dateAndTimeSerializerModule = new SimpleModule(); + dateAndTimeSerializerModule.addSerializer(DateAndTime.class,new CustomDateAndTimeSerializer()); + registerModule(dateAndTimeSerializerModule ); + Bundle bundle = FrameworkUtil.getBundle(YangToolsMapper.class); + context = bundle != null ? bundle.getBundleContext() : null; + } + + @Override + public String writeValueAsString(Object value) throws JsonProcessingException { + // TODO Auto-generated method stub + return super.writeValueAsString(value); + } + /** + * Get Builder object for yang tools interface. + * @param yang-tools base datatype + * @param clazz class with interface. + * @return builder for interface or null if not existing + */ + @SuppressWarnings("unchecked") + public @Nullable Builder getBuilder(Class clazz) { + String builder = clazz.getName() + "Builder"; + try { + Class clazzBuilder = findClass(builder); + return (Builder) clazzBuilder.newInstance(); + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { + LOG.debug("Problem ", e); + return null; + } + } + + /** + * Callback for handling mapping failures. + * @return + */ + public int getMappingFailures() { + return 0; + } + + /** + * Provide mapping of string to attribute names, generated by yang-tools. + * "netconf-id" converted to "_netconfId" + * @param name with attribute name, not null or empty + * @return converted string or null if name was empty or null + */ + public @Nullable static String toCamelCaseAttributeName(final String name) { + if (name == null || name.isEmpty()) + return null; + + final StringBuilder ret = new StringBuilder(name.length()); + if (!name.startsWith("_")) + ret.append('_'); + int start = 0; + for (final String word : name.split("-")) { + if (!word.isEmpty()) { + if (start++ == 0) { + ret.append(Character.toLowerCase(word.charAt(0))); + } else { + ret.append(Character.toUpperCase(word.charAt(0))); + } + ret.append(word.substring(1)); + } + } + return ret.toString(); + } + + /** + * Adapted Builder callbacks + */ + private static class YangToolsBuilderAnnotationIntrospector extends JacksonAnnotationIntrospector { + private static final long serialVersionUID = 1L; + + @Override + public Class findPOJOBuilder(AnnotatedClass ac) { + try { + String builder = null; + if (ac.getRawType().equals(Credentials.class)) { + builder = "org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder"; + //System.out.println(DataContainer.class.isAssignableFrom(ac.getRawType())); + //System.out.println(ChoiceIn.class.isAssignableFrom(ac.getRawType())); + + } + else if(ac.getRawType().equals(DateAndTime.class)) { + builder = DateAndTimeBuilder.class.getName(); + } + + else { + if (ac.getRawType().isInterface()) { + builder = ac.getName()+"Builder"; + } + } + if (builder != null) { + //System.out.println("XX1: "+ac.getRawType()); + //System.out.println("XX2: "+builder); + //Class innerBuilder = Class.forName(builder); + Class innerBuilder = findClass(builder); + //System.out.println("Builder found: "+ innerBuilder); + return innerBuilder; + } + } catch( ClassNotFoundException e ) { + // No problem .. try next + } + return super.findPOJOBuilder(ac); + } + + @Override + public Value findPOJOBuilderConfig(AnnotatedClass ac) { + if (ac.hasAnnotation(JsonPOJOBuilder.class)) { + return super.findPOJOBuilderConfig(ac); + } + return new JsonPOJOBuilder.Value("build", "set"); + } + } + + private static Class findClass(String name) throws ClassNotFoundException { + // Try to find in other bundles + if (context != null) { + //OSGi environment + for (Bundle b : context.getBundles()) { + try { + return b.loadClass(name); + } catch (ClassNotFoundException e) { + // No problem, this bundle doesn't have the class + } + } + throw new ClassNotFoundException("Can not find Class in OSGi context."); + } else { + return Class.forName(name); + } + // not found in any bundle + } + public static class DateAndTimeBuilder{ + + private final String _value; + + public DateAndTimeBuilder(String v) { + this._value= v; + } + + public DateAndTime build() { + return new DateAndTime(_value); + } + + } + public static class CustomDateAndTimeSerializer extends StdSerializer{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + public CustomDateAndTimeSerializer() { + this(null); + } + protected CustomDateAndTimeSerializer(Class t) { + super(t); + } + + @Override + public void serialize(DateAndTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeString(value.getValue()); + } + + } +} diff --git a/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/yangtools/YangToolsMapper2.java b/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/yangtools/YangToolsMapper2.java new file mode 100644 index 000000000..0ee76b074 --- /dev/null +++ b/sdnr/wt/data-provider/database/src/main/java/org/onap/ccsdk/features/sdnr/wt/yangtools/YangToolsMapper2.java @@ -0,0 +1,263 @@ +/******************************************************************************* + * ============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.yangtools; + +import java.io.IOException; +import javax.annotation.Nullable; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder.Value; +import com.fasterxml.jackson.databind.introspect.AnnotatedClass; +import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +/** + * YangToolsMapper is a specific Jackson mapper configuration for opendaylight yangtools serialization or deserialization of DataObject to/from JSON + * TODO ChoiceIn and Credentials deserialization only for LoginPasswordBuilder + */ +public class YangToolsMapper2 extends ObjectMapper { + + private final Logger LOG = LoggerFactory.getLogger(YangToolsMapper2.class); + private static final long serialVersionUID = 1L; + private static String ENTITY = "Entity"; + private static String BUILDER = "Builder"; + + private @Nullable Class clazz; + private @Nullable Class> builderClazz; + + private BundleContext context; + + public > YangToolsMapper2(Class clazz, Class builderClazz) throws ClassNotFoundException { + super(); + configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + setPropertyNamingStrategy(PropertyNamingStrategy.KEBAB_CASE); + setSerializationInclusion(Include.NON_NULL); + setAnnotationIntrospector(new YangToolsBuilderAnnotationIntrospector()); + SimpleModule dateAndTimeSerializerModule = new SimpleModule(); + dateAndTimeSerializerModule.addSerializer(DateAndTime.class, new CustomDateAndTimeSerializer()); + registerModule(dateAndTimeSerializerModule ); + Bundle bundle = FrameworkUtil.getBundle(YangToolsMapper2.class); + + this.clazz = clazz; + this.builderClazz = builderClazz != null ? builderClazz : getBuilderClass(getBuilderClassName(clazz)) ; + context = bundle != null ? bundle.getBundleContext() : null; + } + + public YangToolsMapper2() throws ClassNotFoundException { + this(null, null); + } + + + @Override + public String writeValueAsString(Object value) throws JsonProcessingException { + return super.writeValueAsString(value); + } + /** + * Get Builder object for yang tools interface. + * @param yang-tools base datatype + * @param clazz class with interface. + * @return builder for interface or null if not existing + */ + @SuppressWarnings("unchecked") + public @Nullable Builder getBuilder(Class clazz) { + try { + //Class clazzBuilder = getBuilderClass(getBuilderClassName(clazz)); + return (Builder) builderClazz.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + LOG.debug("Problem ", e); + return null; + } + } + + /** + * Callback for handling mapping failures. + * @return + */ + public int getMappingFailures() { + return 0; + } + + /** + * Provide mapping of string to attribute names, generated by yang-tools. + * "netconf-id" converted to "_netconfId" + * @param name with attribute name, not null or empty + * @return converted string or null if name was empty or null + */ + public @Nullable static String toCamelCaseAttributeName(final String name) { + if (name == null || name.isEmpty()) + return null; + + final StringBuilder ret = new StringBuilder(name.length()); + if (!name.startsWith("_")) + ret.append('_'); + int start = 0; + for (final String word : name.split("-")) { + if (!word.isEmpty()) { + if (start++ == 0) { + ret.append(Character.toLowerCase(word.charAt(0))); + } else { + ret.append(Character.toUpperCase(word.charAt(0))); + } + ret.append(word.substring(1)); + } + } + return ret.toString(); + } + + /** Verify if builder is available + * @throws ClassNotFoundException **/ + public Class assertBuilderClass(Class clazz) throws ClassNotFoundException { + return getBuilderClass(getBuilderClassName(clazz)); + } + + // --- Private functions + + /** + * Create name of builder class + * @param + * @param clazz + * @return builders class name + * @throws ClassNotFoundException + */ + private static String getBuilderClassName(Class clazz) { + return clazz.getName() + BUILDER; +// String clazzName = clazz.getName(); +// if (clazzName.endsWith(ENTITY)) { +// return clazzName.replace(ENTITY, BUILDER); +// } else { +// return clazzName + BUILDER; +// } + } + + /** + * Search builder in context + * @param name + * @return + * @throws ClassNotFoundException + */ + @SuppressWarnings("unchecked") + private > Class getBuilderClass(String name) throws ClassNotFoundException { + // Try to find in other bundles + if (context != null) { + //OSGi environment + for (Bundle b : context.getBundles()) { + try { + return (Class) b.loadClass(name); + } catch (ClassNotFoundException e) { + // No problem, this bundle doesn't have the class + } + } + throw new ClassNotFoundException("Can not find Class in OSGi context."); + } else { + return (Class) Class.forName(name); + } + // not found in any bundle + } + + // --- Classes + + /** + * Adapted Builder callbacks + */ + private class YangToolsBuilderAnnotationIntrospector extends JacksonAnnotationIntrospector { + private static final long serialVersionUID = 1L; + + @Override + public Class findPOJOBuilder(AnnotatedClass ac) { + + if (ac.getRawType().equals(Credentials.class)) { + return org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder.class; + + } else if (ac.getRawType().equals(DateAndTime.class)) { + return DateAndTimeBuilder.class; + + } else if (ac.getRawType().equals(clazz)) { + return builderClazz; + } + + if (ac.getRawType().isInterface()) { + String builder = getBuilderClassName(ac.getRawType()); + try { + Class innerBuilder = getBuilderClass(builder); + return innerBuilder; + } catch (ClassNotFoundException e) { + // No problem .. try next + } + } + return super.findPOJOBuilder(ac); + } + + @Override + public Value findPOJOBuilderConfig(AnnotatedClass ac) { + if (ac.hasAnnotation(JsonPOJOBuilder.class)) { + return super.findPOJOBuilderConfig(ac); + } + return new JsonPOJOBuilder.Value("build", "set"); + } + } + + public static class DateAndTimeBuilder{ + + private final String _value; + + public DateAndTimeBuilder(String v) { + this._value= v; + } + + public DateAndTime build() { + return new DateAndTime(_value); + } + + } + public static class CustomDateAndTimeSerializer extends StdSerializer<@NonNull DateAndTime>{ + + private static final long serialVersionUID = 1L; + + public CustomDateAndTimeSerializer() { + this(null); + } + protected CustomDateAndTimeSerializer(Class t) { + super(t); + } + + @Override + public void serialize(DateAndTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeString(value.getValue()); + } + + } +} diff --git a/sdnr/wt/data-provider/database/src/main/resources/es-init.sh b/sdnr/wt/data-provider/database/src/main/resources/es-init.sh index be7d487f7..0b122c060 100755 --- a/sdnr/wt/data-provider/database/src/main/resources/es-init.sh +++ b/sdnr/wt/data-provider/database/src/main/resources/es-init.sh @@ -37,7 +37,7 @@ INITFILENAME="Init.script" set_definition() { def "connectionlog" '{"node-id": {"type": "keyword"},"timestamp": {"type": "date"},"status": {"type": "keyword"}}' def "maintenancemode" '{"node-id": {"type": "keyword"},"active": {"type": "boolean"}},"date_detection":false}}' - def "faultlog" '{"node-id": {"type": "keyword"},"severity": {"type": "keyword"},"timestamp": {"type": "date"},"problem": {"type": "keyword"},"counter": {"type": "keyword"},"object-id":{"type": "keyword"}}' + def "faultlog" '{"node-id": {"type": "keyword"},"severity": {"type": "keyword"},"timestamp": {"type": "date"},"problem": {"type": "keyword"},"counter": {"type": "keyword"},"object-id":{"type": "keyword"},"source-type":{"type": "keyword"}}' def "faultcurrent" '{"node-id": {"type": "keyword"},"severity": {"type": "keyword"},"timestamp": {"type": "date"},"problem": {"type": "keyword"},"counter": {"type": "keyword"},"object-id":{"type": "keyword"}}' def "eventlog" '{"node-id": {"type": "keyword"},"timestamp": {"type": "date"},"new-value": {"type": "keyword"},"attribute-name": {"type": "keyword"},"counter": {"type": "keyword"},"object-id": {"type": "keyword"}}' def "inventoryequipment" '{"date": {"type": "keyword"},"model-identifier": {"type": "keyword"},"manufacturer-identifier": {"type": "keyword"},"type-name": {"type": "keyword"},"description": {"type": "keyword"},"uuid": {"type": "keyword"},"version": {"type": "keyword"},"parent-uuid": {"type": "keyword"},"contained-holder": {"type": "keyword"},"node-id": {"type": "keyword"},"tree-level": {"type": "long"},"part-type-id": {"type": "keyword"},"serial": {"type": "keyword"}}' @@ -88,11 +88,10 @@ print_response() { body=$(echo $response | sed -E 's/HTTPSTATUS\:[0-9]{3}$//') code=$(echo $response | tr -d '\n' | sed -E 's/.*HTTPSTATUS:([0-9]{3})$/\1/') if [ "$VERBOSE" = "0" -a "$code" -ne "200" ] ; then - echo "Error response $code $body" - exit 2 + echo "Error response $code $body" fi if [ "$VERBOSE" -ge 1 ] ; then - echo "response $code" + echo "response $code" fi if [ "$VERBOSE" -ge 2 ] ; then echo "content: $body" @@ -160,6 +159,11 @@ delete_index_alias() { echo "deleting index $index" url="$index" http_delete_request "$url" + + # Delete alias that was falsely autocreated as index + echo "deleting index $index" + url="$alias" + http_delete_request "$url" } # Write mappings @@ -181,9 +185,9 @@ create_index_alias() { fi url=$index - echo "creating index $index" - if [ -z "$3" ] ; then - http_put_request "$url" "$data" + echo "creating index $index" + if [ -z "$3" ] ; then + http_put_request "$url" "$data" else file_append "$url" "$data" fi @@ -192,7 +196,7 @@ create_index_alias() { url="$index/_alias/$alias" echo "creating alias $alias for $index" if [ -z "$3" ] ; then - http_put_request "$url" + http_put_request "$url" else file_append "$url" "{}" fi @@ -210,7 +214,7 @@ es_wait_yellow() { echo "Error: Max attempts reached." exit 3 fi - attempt_counter=$(($attempt_counter+1)) + attempt_counter=$(($attempt_counter+1)) printf '.' sleep 5 done @@ -222,7 +226,7 @@ es_wait_yellow() { echo "Status $ESSTATUS reached: $RES" else echo "Error: DB Reachable, but status $ESSTATUS not reached" - exit 2 + exit 2 fi else echo "Error: $DBURL not reachable" @@ -234,20 +238,23 @@ es_wait_yellow() { cmd_create() { if [ -n "$WAITYELLOW" ] ; then - es_wait_yellow "$WAITYELLOW" + es_wait_yellow "$WAITYELLOW" fi - for i in "${!ALIAS[@]}"; do - create_index_alias "${ALIAS[$i]}" "${MAPPING[$i]}" - done + for i in "${!ALIAS[@]}"; do + create_index_alias "${ALIAS[$i]}" "${MAPPING[$i]}" + done } cmd_delete() { if [ -n "$WAITYELLOW" ] ; then - es_wait_yellow "$WAITYELLOW" + es_wait_yellow "$WAITYELLOW" fi - for i in "${!ALIAS[@]}"; do - delete_index_alias "${ALIAS[$i]}" - done + for i in "${!ALIAS[@]}"; do + delete_index_alias "${ALIAS[$i]}" + done + for i in "${!ALIAS[@]}"; do + delete_index_alias "${ALIAS[$i]}" + done } cmd_purge() { # http_get_request '_cat/aliases' @@ -262,11 +269,11 @@ cmd_purge() { cmd_initfile() { echo "Create script initfile: $INITFILENAME" if [ -f "$INITFILENAME" ] ; then - rm $INITFILENAME + rm $INITFILENAME fi - for i in "${!ALIAS[@]}"; do - create_index_alias "${ALIAS[$i]}" "${MAPPING[$i]}" file - done + for i in "${!ALIAS[@]}"; do + create_index_alias "${ALIAS[$i]}" "${MAPPING[$i]}" file + done } # Prepare database startup @@ -325,22 +332,22 @@ parse_args() { -f|--file) INITFILENAME="$value" shift - ;; - -x|--verbose) - VERBOSE="${value:-0}" - shift - ;; - -v|--version) - VERSION="${value:--v1}" - shift - ;; - -vx|--versionx) - VERSION="" - ;; - -w|--wait) + ;; + -x|--verbose) + VERBOSE="${value:-0}" + shift + ;; + -v|--version) + VERSION="${value:--v1}" + shift + ;; + -vx|--versionx) + VERSION="" + ;; + -w|--wait) WAITYELLOW="${value:-30s}" - shift - ;; + shift + ;; --cmd) STARTUP_CMD="$value" shift @@ -349,10 +356,10 @@ parse_args() { CLUSTER_ENABLED="$value" shift ;; - --index) - NODE_INDEX="$value" - shift - ;; + --index) + NODE_INDEX="$value" + shift + ;; *) ;; esac; @@ -379,32 +386,32 @@ echo " shards=$SHARDS replicas=$REPLICAS prefix=$PREFIX verbose=$VERBOSE versio case "$TASK" in "create") - getsdnrurl - if [ -z "$DBURL" ] ; then - echo "Error: unable to detect database url." - exit 1 - fi + getsdnrurl + if [ -z "$DBURL" ] ; then + echo "Error: unable to detect database url." + exit 1 + fi cmd_create ;; "delete") - getsdnrurl - if [ -z "$DBURL" ] ; then - echo "Error: unable to detect database url." - exit 1 - fi + getsdnrurl + if [ -z "$DBURL" ] ; then + echo "Error: unable to detect database url." + exit 1 + fi cmd_delete ;; "purge") - getsdnrurl - if [ -z "$DBURL" ] ; then - echo "Error: unable to detect database url." - exit 1 - fi + getsdnrurl + if [ -z "$DBURL" ] ; then + echo "Error: unable to detect database url." + exit 1 + fi cmd_purge ;; "initfile") cmd_initfile - ;; + ;; "startup") cmd_startup ;; diff --git a/sdnr/wt/data-provider/database/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/test/TestConfig.java b/sdnr/wt/data-provider/database/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/test/TestConfig.java new file mode 100644 index 000000000..ecc7edf6a --- /dev/null +++ b/sdnr/wt/data-provider/database/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/test/TestConfig.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.dataprovider.database.test; + +import static org.junit.Assert.*; + +import java.io.File; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; +import org.onap.ccsdk.features.sdnr.wt.database.config.EsConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TestConfig { + + private static final Logger LOG = LoggerFactory.getLogger(TestConfig.class); + + private static final String TESTFILENAME = "testconfig.properties"; + + @After + @Before + public void afterAndBefore() { + File f=new File(TESTFILENAME); + if(f.exists()) { + LOG.info("Remove {}", f.getAbsolutePath()); + f.delete(); + } + } + @Test + public void test() { + ConfigurationFileRepresentation configuration=new ConfigurationFileRepresentation(TESTFILENAME); + + EsConfig esConfig = new EsConfig(configuration); + LOG.info("Defaultconfiguration: {}", esConfig.toString()); + assertEquals("http", esConfig.getHosts()[0].protocol.getValue()); + assertEquals(9200, esConfig.getHosts()[0].port); + assertEquals("sdnrdb", esConfig.getHosts()[0].hostname); + + } + +} diff --git a/sdnr/wt/data-provider/database/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/test/TestNetconfNodeBuilder.java b/sdnr/wt/data-provider/database/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/test/TestNetconfNodeBuilder.java new file mode 100644 index 000000000..9237aaf1f --- /dev/null +++ b/sdnr/wt/data-provider/database/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/test/TestNetconfNodeBuilder.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * ============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.dataprovider.database.test; + +import static org.junit.Assert.*; + +import org.junit.Test; +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.NetconfNodeBuilder; +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.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder; + +public class TestNetconfNodeBuilder { + + @SuppressWarnings("deprecation") + //@Test + public void test() { + + NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder(); + + LoginPasswordBuilder loginPasswordBuilder = new LoginPasswordBuilder(); + loginPasswordBuilder.setUsername("myTestUsername"); + loginPasswordBuilder.setPassword("myTestPassword"); + netconfNodeBuilder.setCredentials(loginPasswordBuilder.build()); + + NetconfNode netconfNode = netconfNodeBuilder.build(); + System.out.println(netconfNode); + + Credentials credentials = netconfNode.getCredentials(); + System.out.println("Class: "+credentials.getClass()+"\nContent: "+credentials); + + if (credentials instanceof LoginPassword) { + LoginPassword loginPassword = (LoginPassword)credentials; + System.out.println("User: "+loginPassword.getUsername()+" Password"+loginPassword.getPassword()); + } else { + System.out.println("Not expected class"); + } + } + +} diff --git a/sdnr/wt/data-provider/database/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/test/TestNuMappings.java b/sdnr/wt/data-provider/database/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/test/TestNuMappings.java new file mode 100644 index 000000000..b7d0620ca --- /dev/null +++ b/sdnr/wt/data-provider/database/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/test/TestNuMappings.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * ============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.dataprovider.database.test; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import java.io.IOException; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.yangtools.YangToolsMapper; +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.SeverityType; + +public class TestNuMappings { + + @Test + public void test33() { + Faultcurrent c = new FaultcurrentBuilder().setSeverity(SeverityType.Critical).build(); + YangToolsMapper mapper = new YangToolsMapper(); + try { + System.out.println(mapper.writeValueAsString(c)+"<=>"+SeverityType.Critical.getName()); + } catch (JsonProcessingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + try { + Faultcurrent f=mapper.readValue( "{\"severity\":\"Critical\"}", Faultcurrent.class); + System.out.println(f); + System.out.println(mapper.writeValueAsString(f)); + } catch (JsonParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (JsonMappingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } +} diff --git a/sdnr/wt/data-provider/database/src/test/resources/log4j2.xml b/sdnr/wt/data-provider/database/src/test/resources/log4j2.xml new file mode 100644 index 000000000..164e93f54 --- /dev/null +++ b/sdnr/wt/data-provider/database/src/test/resources/log4j2.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sdnr/wt/data-provider/database/src/test/resources/simplelogger.properties b/sdnr/wt/data-provider/database/src/test/resources/simplelogger.properties new file mode 100644 index 000000000..a2f1e7e76 --- /dev/null +++ b/sdnr/wt/data-provider/database/src/test/resources/simplelogger.properties @@ -0,0 +1,6 @@ +org.slf4j.simpleLogger.defaultLogLevel=debug +org.slf4j.simpleLogger.showDateTime=true +#org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z +#org.slf4j.simpleLogger.showThreadName=true +org.slf4j.simpleLogger.showLogName=true +org.slf4j.simpleLogger.showShortLogName=false \ No newline at end of file diff --git a/sdnr/wt/data-provider/feature/pom.xml b/sdnr/wt/data-provider/feature/pom.xml new file mode 100644 index 000000000..0bda76f8e --- /dev/null +++ b/sdnr/wt/data-provider/feature/pom.xml @@ -0,0 +1,49 @@ + + + + 4.0.0 + + org.onap.ccsdk.features.sdnr.wt + sdnr-wt-data-provider-feature + 0.7.0-SNAPSHOT + feature + ccsdk-features-sdnr-wt :: ${project.artifactId} :: feature + + + org.onap.ccsdk.parent + single-feature-parent + 1.5.1-SNAPSHOT + + + + + + ${project.groupId} + sdnr-wt-data-provider-provider + ${project.version} + + + diff --git a/sdnr/wt/data-provider/installer/pom.xml b/sdnr/wt/data-provider/installer/pom.xml new file mode 100755 index 000000000..c736041e2 --- /dev/null +++ b/sdnr/wt/data-provider/installer/pom.xml @@ -0,0 +1,137 @@ + + + + 4.0.0 + + + org.onap.ccsdk.parent + odlparent-lite + 1.5.1-SNAPSHOT + + + + org.onap.ccsdk.features.sdnr.wt + sdnr-wt-data-provider-installer + 0.7.0-SNAPSHOT + pom + ccsdk-features-sdnr-wt :: ${project.artifactId} + + + sdnr-wt-data-provider + false + + + + + org.onap.ccsdk.features.sdnr.wt + ${application.name}-feature + ${project.version} + xml + features + + + * + * + + + + + org.onap.ccsdk.features.sdnr.wt + ${application.name}-provider + ${project.version} + + + + + + maven-assembly-plugin + + + maven-repo-zip + + single + + package + + true + stage/${application.name}-${project.version} + + src/assembly/assemble_mvnrepo_zip.xml + + true + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-nested-dependencies + + copy-dependencies + + prepare-package + + true + ${project.build.directory}/assembly/system + false + true + true + true + false + false + + + + + + maven-resources-plugin + 2.6 + + + copy-schemas + + copy-resources + + validate + + ${project.build.directory}/assembly/cache/schema + + + ${basedir}/../provider/src/main/resources/preload.cache.schema + + *.yang + + true + + + + + + + + + diff --git a/sdnr/wt/data-provider/installer/src/assembly/assemble_mvnrepo_zip.xml b/sdnr/wt/data-provider/installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..c4eb9aa25 --- /dev/null +++ b/sdnr/wt/data-provider/installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,49 @@ + + + + + + repo + + zip + + + + false + + + + target/assembly/ + . + + + + + + + + diff --git a/sdnr/wt/data-provider/model/pom.xml b/sdnr/wt/data-provider/model/pom.xml new file mode 100644 index 000000000..454742a60 --- /dev/null +++ b/sdnr/wt/data-provider/model/pom.xml @@ -0,0 +1,80 @@ + + + + 4.0.0 + org.onap.ccsdk.features.sdnr.wt + sdnr-wt-data-provider-model + 0.7.0-SNAPSHOT + ccsdk-features-sdnr-wt :: ${project.artifactId} + bundle + + + org.onap.ccsdk.parent + binding-parent + 1.5.1-SNAPSHOT + + + + + true + + + + + Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0 + + + + + + org.opendaylight.netconf + sal-netconf-connector + provided + + + ${project.groupId} + sdnr-wt-common + ${project.version} + + + + + + org.jacoco + jacoco-maven-plugin + + + **/gen/** + **/generated-sources/** + **/yang-gen-sal/** + **/pax/** + + + + + + diff --git a/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/ArchiveCleanProvider.java b/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/ArchiveCleanProvider.java new file mode 100644 index 000000000..00ec2e60e --- /dev/null +++ b/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/ArchiveCleanProvider.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.dataprovider.model; + +import java.util.Date; + +public interface ArchiveCleanProvider { + + /** + * Remove all index data older, than specified + * @param olderAreOutdated time to specify older elements + * @return number of removed elements + */ + int doIndexClean(Date olderAreOutdated); + + /** + * Get number of elements older then + * @param olderAreOutdated date to compare with and specify older elements + * @return number of elements + */ + public int getNumberOfOldObjects(Date olderAreOutdated); + + +} diff --git a/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/DataProvider.java b/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/DataProvider.java new file mode 100644 index 000000000..fbfd18a2f --- /dev/null +++ b/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/DataProvider.java @@ -0,0 +1,95 @@ +/** + * ============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.dataprovider.model; + +import java.util.Date; +import java.util.List; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ConnectionlogEntity; +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.FaultcurrentEntity; +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.NetworkElementConnectionEntity; + +public interface DataProvider extends ArchiveCleanProvider { + + // -- Connection log + void writeConnectionLog(ConnectionlogEntity event); + + // -- Event log + void writeEventLog(EventlogEntity event); + + void writeFaultLog(FaultlogEntity fault); + + void updateFaultCurrent(FaultcurrentEntity fault); + + /** + * Remove all entries for one node + * + * @param nodeName contains the mountpointname + * @return number of deleted entries + */ + int clearFaultsCurrentOfNode(String nodeName); + + /** + * Remove all entries for one node + * + * @param nodeName contains the mountpointname + * @param objectId of element to be deleted + * @return number of deleted entries + */ + int clearFaultsCurrentOfNodeWithObjectId(String nodeName, String objectId); + + /** + * Deliver list with all mountpoint/node-names in the database. + * + * @return List of all mountpoint/node-names the had active alarms. + */ + List getAllNodesWithCurrentAlarms(); + + /** + * write internal equipment to database + * @param internalEquipment with mandatory fields. + */ + void writeInventory(Inventory internalEquipment); + + /** + * + * @param networkElementConnectionEntitiy to wirte to DB + * @param nodeId Id for this DB element + */ + void updateNetworkConnectionDeviceType(NetworkElementConnectionEntity networkElementConnectionEntitiy, + String nodeId); + + /** + * Update after new mountpoint registration + * @param networkElementConnectionEntitiy data + * @param nodeId of device (mountpoint name) + */ + void updateNetworkConnection22(NetworkElementConnectionEntity networkElementConnectionEntitiy, String nodeId); + + void removeNetworkConnection(String nodeId); + + @Override + int doIndexClean(Date olderAreOutdated); + + @Override + int getNumberOfOldObjects(Date olderAreOutdated); + + List getNetworkElementConnections(); +} diff --git a/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/IEntityDataProvider.java b/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/IEntityDataProvider.java new file mode 100644 index 000000000..c8c940433 --- /dev/null +++ b/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/IEntityDataProvider.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * ============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.dataprovider.model; + +public interface IEntityDataProvider { + + /** Get provider for database read/write operations **/ + public DataProvider getDataProvider(); + + public void setReadyStatus(boolean status); +} diff --git a/sdnr/wt/data-provider/model/src/main/yang/dataprovider.yang b/sdnr/wt/data-provider/model/src/main/yang/dataprovider.yang new file mode 100644 index 000000000..8fa19a990 --- /dev/null +++ b/sdnr/wt/data-provider/model/src/main/yang/dataprovider.yang @@ -0,0 +1,1207 @@ +module data-provider { + + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:data-provider"; + prefix "odluxprovider"; + + import ietf-yang-types { prefix "yang"; revision-date 2013-07-15; } + import netconf-node-topology { prefix "nettop"; revision-date 2015-01-14; } + description + "data-provider api module"; + + revision "2019-08-01" { + description + "Initial revision"; + } + // --- typedef + typedef Entity { + description "Data type and alias for elasticsearch or table name for SQL database."; + type enumeration { + enum connectionlog { + description "logs mountpoint connection state changes"; + } + enum faultcurrent { + description "current faults"; + } + enum eventlog { + description "logs for all notifications e.g. netconf, ves and internal events"; + } + enum faultlog { + description "faultlog information"; + } + enum historicalperformance15min { + description "performance data"; + } + enum historicalperformance24h { + description "performance data"; + } + enum mediator-server { + description "list of mediator servers"; + } + enum networkelement-connection { + description "list of mountpoints for netconf devices (joint required-network-element+mdsal + state"; + } + enum inventoryequipment { + description "list of equipment inventory"; + } + enum maintenancemode { + description "list of maintenance setting"; + } + } + } + typedef SortOrder { + type enumeration { + enum ascending { + } + enum descending { + } + } + description "Entities for odlux clients"; + } + typedef FilterProperty { + type string; + } + + typedef NotificationType { + type enumeration { + enum ProblemNotificationXml { + description ""; + } + enum AttributeValueChangedNotificationXml { + description ""; + } + } + } + + typedef ConnectionLogStatus { + type enumeration { + enum Mounted { + description "Mountpoint created"; + } + enum Unmounted { + description "Mountpoint removed"; + } + enum Connecting { + description "Mountpoint establishing connection"; + } + enum Connected { + description "Mountpoint connection established"; + } + enum UnableToConnect { + description "Mountpoint connection not possible"; + } + enum Disconnected { + description "Required and mountpoint removed"; + } + enum Undefined { + description "Status not available"; + } + } + } + typedef NetworkElementDeviceType { + type enumeration { + enum Wireless { + description "implements microwave-model.yang or air-interface.yang"; + } + enum RAN { + description "implements sth. like o-ran*.yang"; + } + enum ORAN { + description "implements RAN according to o-ran*.yang"; + } + enum RAN3GPP { + description "implements RAN according to _3gpp-ran*.yang"; + } + enum Optical { + description "implements tapi-*.yang or org-openroadm*.yang"; + } + enum Router { + description "implements vlan-interface.yang"; + } + enum NtsManager { + + description "Simulation of device"; + } + enum Nonsupported { + description "Device type known, but not support"; + } + enum Unknown { + description "Device type at this point of time unknown"; + } + } + } + typedef severity-type { + type enumeration { + enum NonAlarmed { + description "problem cleared indication"; + } + enum Warning { + description "problem level"; + } + enum Minor { + description "problem level"; + } + enum Major { + description "problem level"; + } + enum Critical { + description "problem level"; + } + } + description "According to ITU-T M.3160"; + } + typedef source-type { + type enumeration { + enum ves { + description "VES Interface"; + } + enum netconf { + description "NETCONF Interface"; + } + enum controller { + description "SDN Controller"; + } + enum unknown { + description "Unknown source"; + } + } + } + // --- grouping and builder-container + grouping connectionlog-entity { + leaf id { + type string; + description "database id"; + } + leaf node-id { + type string; + description "the node/mountpoint which connection state has changed"; + } + leaf timestamp { + type yang:date-and-time; + description "timestamp when event happened"; + } + leaf status { + type ConnectionLogStatus; + description "new state of the connection of the device"; + } + } + container connectionlog { + description "builder"; + uses connectionlog-entity; + } + grouping object-change-reference { + description "Reference of of object (e.g. Interface pack) owned by a node"; + leaf node-id { + type string; + } + leaf counter { + type int32; + } + leaf timestamp { + type yang:date-and-time; + } + leaf object-id { + type string; + } + } + grouping source-reference { + description "Identify a source"; + leaf source-type { + type source-type; + } + } + grouping fault { + description "Fault event of an object"; + leaf problem { + type string; + } + leaf severity { + type severity-type; + } + } + grouping attribute-change { + description "update change of an attribute"; + leaf attribute-name { + type string; + } + leaf new-value { + type string; + } + } + grouping entity-id { + description "Unique database id of entity"; + leaf id { + type string; + } + } + grouping faultcurrent-entity { + description "Current fault status"; + uses object-change-reference; + uses fault; + uses entity-id; + } + container faultcurrent { + description "builder"; + uses faultcurrent-entity; + } + grouping faultlog-entity { + description "Changed fault indication"; + uses source-reference; + uses object-change-reference; + + uses fault; + uses entity-id; + } + container faultlog { + description "builder"; + uses faultlog-entity; + } + grouping eventlog-entity { + description "One change event of devices"; + uses source-reference; + uses object-change-reference; + uses attribute-change; + uses entity-id; + } + container eventlog { + description "builder"; + uses eventlog-entity; + } + grouping filter { + leaf description { + type string; + description "Filter specific description"; + } + leaf start { + type yang:date-and-time; + description "begin of maintenance-mode"; + } + leaf end { + type yang:date-and-time; + description "end of maintenance-mode"; + } + leaf object-id-ref { + type string; + description "object id to filter on, or empty for all"; + } + leaf problem { + type string; + description "name of the problem to filter or empty for all"; + } + } + grouping maintenance-entity { + description "Maintenance mode for a device. "; + leaf id { + mandatory true; + type string; + description "Key to get/set configuration entry in database. Normally Mountpoint-name + is used as key id of node."; + } + leaf node-id { + mandatory true; + type string; + description ""; + } + leaf active { + type boolean; + description "Configuration to activate or deactivate this entry"; + } + uses filter; + } + container maintenance { + description "builder"; + uses maintenance-entity; + } + grouping mediator-server-entity { + leaf id { + mandatory true; + type string; + } + leaf url { + type string; + } + leaf name { + type string; + } + } + grouping pmdata-base { + leaf node-name { + type string; + } + leaf uuid-interface { + type string; + } + leaf layer-protocol-name { + type string; + } + leaf radio-signal-id { + type string; + } + leaf time-stamp { + type yang:date-and-time; + } + leaf suspect-interval-flag { + type boolean; + } + leaf granularity-period { + type string; + } + leaf scanner-id { + type string; + } + } + grouping pmdata-microwave { + description "Consolidated performance information of all microwave model interface pacs"; + leaf es { + type int32; + units "s"; + default -1; + config false; + description "Number of errored seconds."; + } + leaf ses { + type int32; + units "s"; + default -1; + config false; + description "Number of severely errored seconds."; + } + leaf cses { + type int32; + units "s"; + default -1; + config false; + description "Number of consecutive severely errored seconds."; + } + leaf unavailability { + type int32; + units "s"; + default -1; + config false; + description "Total time of unavailability in seconds."; + } + leaf tx-level-min { + type int8; + units "dBm"; + default 99; + config false; + description "Minimum transmit power. Signed integers are required."; + } + leaf tx-level-max { + type int8; + units "dBm"; + default 99; + config false; + description "Maximum transmit power. Signed integers are required."; + } + leaf tx-level-avg { + type int8; + units "dBm"; + default 99; + config false; + description "Averaged transmit power. Signed integers are required."; + } + leaf rx-level-min { + type int8; + units "dBm"; + default 99; + config false; + description "Minimum receive level. Signed integers are required."; + } + leaf rx-level-max { + type int8; + units "dBm"; + default 99; + config false; + description "Maximum receive level. Signed integers are required."; + } + leaf rx-level-avg { + type int8; + units "dBm"; + default 99; + config false; + description "Averaged receive level. Signed integers are required."; + } + leaf time2-states { + type int32; + units "s"; + default -1; + config false; + description "Sum of all seconds the transmitter operated in e.g. BPSK."; + } + leaf time4-states-s { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf time4-states { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf time8-states { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf time16-states-s { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf time16-states { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf time32-states { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf time64-states { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf time128-states { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf time256-states { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf time512-states { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf time512-states-l { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf time1024-states { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf time1024-states-l { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf time2048-states { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf time2048-states-l { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf time4096-states { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf time4096-states-l { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf time8192-states { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf time8192-states-l { + type int32; + units "s"; + default -1; + config false; + description "none"; + } + leaf snir-min { + type int8; + units "dB"; + default -99; + config false; + description "Minimum signal to (noise+interference) ratio."; + } + leaf snir-max { + type int8; + units "dB"; + default -99; + config false; + description "Maximum signal to (noise+interference) ratio."; + } + leaf snir-avg { + type int8; + units "dB"; + default -99; + config false; + description "Averaged signal to (noise+interference) ratio."; + } + leaf xpd-min { + type int8; + units "dB"; + default -99; + config false; + description "Minimum cross polarization discrimination."; + } + leaf xpd-max { + type int8; + units "dB"; + default -99; + config false; + description "Maximum cross polarization discrimination."; + } + leaf xpd-avg { + type int8; + units "dB"; + default -99; + config false; + description "Averaged cross polarization discrimination."; + } + leaf rf-temp-min { + type int8; + units "C"; + default -99; + config false; + description "Lowest temperature (in degree Celsius) of the radio module inside the outdoor unit."; + } + leaf rf-temp-max { + type int8; + units "C"; + default -99; + config false; + description "Highest temperature (in degree Celsius) of the radio module inside the outdoor unit."; + } + leaf rf-temp-avg { + type int8; + units "C"; + default -99; + config false; + description "Averaged temperature (in degree Celsius) of the radio module inside the outdoor unit."; + } + leaf defect-blocks-sum { + type int16; + units "blocks"; + default -1; + config false; + description "Total number of blocks that were defect after receiving and could not be corrected by the FEC."; + } + leaf time-period { + type int32; + units "s"; + default -1; + config false; + description "Total length of the measurement period."; + } + } + grouping pmdata-ethernet { + description "Consolidated performance information for ethernet."; + leaf tx-ethernet-bytes-max-s { + type int32; + units "Bytes/s"; + default -1; + config false; + description "Counts the number of Bytes of Ethernet traffic (before header compression) transmitted within a second and keeps the highest value within the measurement period. Field to be left blank for all types of TDM containers."; + } + leaf tx-ethernet-bytes-max-m { + type int64; + units "Bytes/min"; + default -1; + config false; + description "Counts the number of Bytes of Ethernet traffic (before header compression) transmitted within a minute and keeps the highest value with in the measurement period. Field to be left blank for all types of TDM containers."; + } + leaf tx-ethernet-bytes-sum { + type int64; + units "Bytes"; + default -1; + config false; + description "Total number of Bytes of Ethernet traffic (before header compression) transmitted (in direction out of the device) during the measurement period. Field to be left blank for all types of TDM containers."; + } + + } + grouping pmdata15m-entity { + uses pmdata-base; + container performance-data { + uses pmdata-microwave; + uses pmdata-ethernet; + } + + } + grouping pmdata24h-entity { + uses pmdata-base; + container performance-data { + uses pmdata-microwave; + uses pmdata-ethernet; + } + } + grouping inventory-entity { + description "One equipment entity in a list of a network element that could be rack, card, backplane, module"; + + leaf id { + description "Unique database id, node-id/uuid"; + mandatory true; + type string; + } + leaf tree-level { + description "Containment level, starting with 0.."; + type uint32; + } + leaf parent-uuid { + description "Unique inventory id of holder"; + type string; + } + leaf node-id { + description "Unique node id of network element"; + type string; + } + leaf uuid { + description "Unique inventory id of this node for this equipement, provided by network element"; + type string; + } + leaf-list contained-holder { + description "List of uuid of contained equipment"; + type string; + } + leaf manufacturer-name { + description "manufactured-thing/manufacturer-properties/manufacturer-name"; + type string; + } + leaf manufacturer-identifier { + description "manufactured-thing/manufacturer-properties/manufacturer-identifier"; + type string; + } + leaf serial { + description "manufactured-thing/equipment-instance/serial"; + type string; + } + leaf date { + description "manufactured-thing/equipment-instance/manufacture-date: Date information provided by manufacturer. No specific format. ()"; + type string; + } + leaf version { + description "manufactured-thing/equipment-type/version"; + type string; + } + leaf description { + description "manufactured-thing/equipment-type/description"; + type string; + } + leaf part-type-id { + description "manufactured-thing/equipment-type/part-type-identifier"; + type string; + } + leaf model-identifier { + description "manufactured-thing/equipment-type/model-identifier"; + type string; + } + leaf type-name { + description "manufactured-thing/equipment-type/type-name"; + type string; + } + } + container inventory { + description "builder"; + uses inventory-entity; + } + grouping node-details-g { + leaf-list available-capabilities { + type string; + } + leaf-list unavailable-capabilities { + type string; + } + } + grouping network-element-connection-entity { + + leaf id { + type string; + description "database id/key. here is equal to node-id"; + } + leaf node-id { + type string; + description "mountpoint name of device in controller"; + } + leaf host { + type string; + description "netconf hostname or ip address of device"; + } + leaf port { + type uint32; + description "netconf port of device"; + } + leaf username { + type string; + description "netconf username"; + } + leaf password { + type string; + description "netconf password. should be removed asap"; + } + leaf core-model-capability { + type string; + description "revision of core-model capability"; + } + leaf device-type { + type NetworkElementDeviceType; + description "categoried type of ne based on implemented yang specs"; + } + leaf is-required { + type boolean; + description "entry exists in db index required-networkelement"; + } + container node-details { + uses node-details-g; + description "holder of available and unavailable capabilities"; + } + leaf status { + type ConnectionLogStatus; + description "current connection status. default Disconnected"; + } + } + container network-element-connection { + description "builder"; + uses network-element-connection-entity; + } + grouping status-entity { + container faults { + leaf criticals { + type uint32; + } + leaf majors { + type uint32; + } + leaf minors { + type uint32; + } + leaf warnings { + type uint32; + } + } + } + container status { + description "builder"; + uses status-entity; + } + grouping entity-input { + list filter { + key property; + leaf property { + type string; + } + leaf filtervalue { + type string; + } + description "List with filter criteria. Not listed means all."; + } + list sortorder { + key property; + leaf property { + type string; + } + leaf sortorder { + type SortOrder; + } + description "List with sort order. Not listed means default"; + } + container pagination { + leaf size { + type uint32 { + range "1..max"; + } + default 20; + description "Number of entries to be delivered"; + } + leaf page { + type uint64 { + range "1..max"; + } + default 1; + description "Number to be used to calculate starting entry to deliver"; + } + } + } + grouping pagination-output-g { + leaf size { + type uint32 { + range "1..max"; + } + default 20; + description "Number of entries to be delivered"; + } + leaf page { + type uint64 { + range "1..max"; + } + default 1; + description "Number to be used to calculate starting entry to deliver"; + } + leaf total { + type uint64 { + range "0..max"; + } + default 0; + description "Number to be used to calculate starting entry to deliver"; + } + } + container pagination-output { + description "builder"; + uses pagination-output-g; + } + // --- rpc + rpc read-faultcurrent-list { + description + "Get list of faultcurrent entries according to filter"; + input { + uses entity-input; + } + output { + container pagination { + uses pagination-output-g; + } + list data { + uses faultcurrent-entity; + } + } + } + rpc read-faultlog-list { + description + "Get list of faultlog entries according to filter"; + input { + uses entity-input; + } + output { + container pagination { + uses pagination-output-g; + } + list data { + uses faultlog-entity; + } + } + } + + rpc read-eventlog-list { + description + "Get list of eventlog entities according to filter"; + input { + uses entity-input; + } + output { + container pagination { + uses pagination-output-g; + } + list data { + uses eventlog-entity; + } + } + } + rpc read-connectionlog-list { + description + "Get list of eventlog entities according to filter"; + input { + uses entity-input; + } + output { + container pagination { + uses pagination-output-g; + } + list data { + uses connectionlog-entity; + } + } + } + rpc read-maintenance-list { + description + "Get list of maintenance entries according to filter"; + input { + uses entity-input; + } + output { + container pagination { + uses pagination-output-g; + } + list data { + uses maintenance-entity; + } + } + } + rpc create-maintenance { + description + "insert new entry of maintenance"; + input { + uses maintenance-entity; + } + output { + uses maintenance-entity; + } + } + rpc update-maintenance { + description + "update existing entity of maintenance"; + input { + uses maintenance-entity; + } + output { + uses maintenance-entity; + } + } + rpc delete-maintenance { + description + "delete entity of maintenance"; + input { + uses maintenance-entity; + } + output { + } + } + + rpc read-mediator-server-list { + description + "Get list of mediator-servers according to filter"; + input { + uses entity-input; + } + output { + container pagination { + uses pagination-output-g; + } + list data { + uses mediator-server-entity; + } + } + } + rpc create-mediator-server { + description + "create new entry of entity mediator-server"; + input { + uses mediator-server-entity; + } + output { + uses mediator-server-entity; + } + } + rpc update-mediator-server { + description + "update entry of entity mediator-server"; + input { + uses mediator-server-entity; + } + output { + uses mediator-server-entity; + } + } + rpc delete-mediator-server { + description + "delete entry of entity mediator-server"; + input { + uses mediator-server-entity; + } + output { + } + } + rpc read-network-element-connection-list { + description + "Get list of networkelement-connections according to filter"; + input { + uses entity-input; + } + output { + container pagination { + uses pagination-output-g; + } + list data { + uses network-element-connection-entity; + } + } + } + rpc create-network-element-connection { + description "create entry in networkelement-connection"; + input { + uses network-element-connection-entity; + } + output { + uses network-element-connection-entity; + } + } + rpc update-network-element-connection { + description "Put an element to ne-entity"; + input { + uses network-element-connection-entity; + } + output { + uses network-element-connection-entity; + } + } + rpc delete-network-element-connection { + description "!ONLY FOR TESTING! Put an element to ne-entity"; + input { + uses network-element-connection-entity; + } + output { + } + } + + rpc read-pmdata-15m-ltp-list { + description + "Get list of ltps for one mountpoint with historical pmdata"; + input { + uses entity-input; + } + output { + container pagination { + uses pagination-output-g; + } + leaf-list data { + type string; + } + } + } + rpc read-pmdata-24h-ltp-list { + description + "Get list of ltps for one mountpoint with historical pmdata"; + input { + uses entity-input; + } + + output { + container pagination { + uses pagination-output-g; + } + leaf-list data { + type string; + } + } + } + rpc read-pmdata-15m-device-list { + description + "Get list of mountpoints with historical pmdata"; + input { + uses entity-input; + } + output { + container pagination { + uses pagination-output-g; + } + leaf-list data { + type string; + } + } + } + rpc read-pmdata-24h-device-list { + description + "Get list of mountpoints with historical pmdata"; + input { + uses entity-input; + } + output { + container pagination { + uses pagination-output-g; + } + leaf-list data { + type string; + } + } + } + + rpc read-pmdata-15m-list { + description + "Get list of entities according to filter"; + input { + uses entity-input; + } + output { + container pagination { + uses pagination-output-g; + } + list data { + uses pmdata15m-entity; + } + } + } + rpc read-pmdata-24h-list { + description + "Get list of historical pmdata according to filter"; + input { + uses entity-input; + } + output { + container pagination { + uses pagination-output-g; + } + list data { + uses pmdata24h-entity; + } + } + } + rpc read-inventory-list { + description + "Get list of inventory according to filter"; + input { + uses entity-input; + } + output { + container pagination { + uses pagination-output-g; + } + list data { + uses inventory-entity; + } + } + } + rpc read-status { + description + "Read status information of controller"; + output { + list data { + uses status-entity; + } + } + } +} + diff --git a/sdnr/wt/data-provider/pom.xml b/sdnr/wt/data-provider/pom.xml new file mode 100755 index 000000000..5b1f483d4 --- /dev/null +++ b/sdnr/wt/data-provider/pom.xml @@ -0,0 +1,52 @@ + + + + 4.0.0 + + org.onap.ccsdk.features.sdnr.wt + sdnr-wt-data-provider-top + 0.7.0-SNAPSHOT + pom + ccsdk-features-sdnr-wt :: ${project.artifactId} + + + org.onap.ccsdk.parent + odlparent-lite + 1.5.1-SNAPSHOT + + + + + sdnr-wt-data-provider + + + + model + database + provider + feature + installer + + + diff --git a/sdnr/wt/data-provider/provider/copyright b/sdnr/wt/data-provider/provider/copyright new file mode 100644 index 000000000..754b6218f --- /dev/null +++ b/sdnr/wt/data-provider/provider/copyright @@ -0,0 +1,17 @@ +/** + * ============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========================================================================== + */ diff --git a/sdnr/wt/data-provider/provider/pom.xml b/sdnr/wt/data-provider/provider/pom.xml new file mode 100644 index 000000000..2c1978ba4 --- /dev/null +++ b/sdnr/wt/data-provider/provider/pom.xml @@ -0,0 +1,187 @@ + + + + 4.0.0 + + org.onap.ccsdk.features.sdnr.wt + sdnr-wt-data-provider-provider + 0.7.0-SNAPSHOT + ccsdk-features-sdnr-wt :: ${project.artifactId} + bundle + + + org.onap.ccsdk.parent + binding-parent + 1.5.1-SNAPSHOT + + + + + true + true + yyyy-MM-dd HH:mm + ${maven.build.timestamp} + 6.4.3 + 7.4.0 + 49402 + Frankfurt + Neon-SR1 + 29.7af5ca8(19/11/19) + + + + + Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0 + + + + + + org.mockito + mockito-core + test + + + ${project.groupId} + sdnr-wt-common + ${project.version} + + + ${project.groupId} + sdnr-wt-data-provider-database + ${project.version} + + + javax.servlet + servlet-api + + + org.osgi + org.osgi.core + provided + + + org.opendaylight.netconf + sal-netconf-connector + provided + + + org.opendaylight.mdsal.binding.model.ietf + rfc6991-ietf-yang-types + provided + + + org.opendaylight.mdsal + yang-binding + provided + + + org.opendaylight.mdsal + mdsal-singleton-common-api + provided + + + org.json + json + provided + + + + + + org.jacoco + jacoco-maven-plugin + + + **/gen/** + **/generated-sources/** + **/yang-gen-sal/** + **/pax/** + + + + + org.codehaus.mojo + exec-maven-plugin + + + generateDTOs + generate-sources + + exec + + + ${skipTests} + ${basedir}/../database/src/main/resources/es-init.sh + + initfile + -f + ${project.build.directory}/EsInit.script + + + + + + + com.github.alexcojocaru + elasticsearch-maven-plugin + 6.16 + + true + testCluster + 9500 + ${databaseport} + 6.4.3 + ${project.build.directory}/EsInit.script + + + + start-elasticsearch + process-test-classes + + runforked + + + + stop-elasticsearch + prepare-package + + stop + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + databaseport + ${databaseport} + + + + + + + + diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessor.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessor.java new file mode 100644 index 000000000..dc90ee9fa --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessor.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * ============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.dataprovider.data; + +import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; +import org.onap.ccsdk.features.sdnr.wt.common.database.SearchResult; +import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilder; +import org.onap.ccsdk.features.sdnr.wt.database.EsDataObjectReaderWriter; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.impl.DataProviderServiceImpl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Entity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EntityInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadFaultcurrentListInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadFaultcurrentListOutputBuilder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DataObjectAcessor extends EsDataObjectReaderWriter { + + private static final Logger LOG = LoggerFactory.getLogger(DataObjectAcessor.class); + + public DataObjectAcessor(HtDatabaseClient dbClient, Entity entity, Class clazz) throws ClassNotFoundException { + this(dbClient, entity, clazz, true); + LOG.info("Create {}", this.getClass().getName()); + } + + public DataObjectAcessor(HtDatabaseClient dbClient, Entity entity, Class clazz, boolean idSupported) throws ClassNotFoundException { + super(dbClient, entity, clazz); + if (idSupported) + setEsIdAttributeName("_id"); + } + + QueryResult getData(EntityInput input) { + long page = QueryByFilter.getPage(input); + long pageSize = QueryByFilter.getPageSize(input); + LOG.info("Request: {}", this.getDataTypeName()); + QueryBuilder query = QueryByFilter.fromFilter(input.getFilter()).from((page - 1) * pageSize).size(pageSize); + QueryByFilter.setSortOrder(query, input.getSortorder()); + SearchResult result = doReadAll(query,query.contains("range")); + return new QueryResult(page, pageSize, result); + } + +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessorPm.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessorPm.java new file mode 100644 index 000000000..a145a9f1b --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessorPm.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * ============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.dataprovider.data; + +import java.io.IOException; + +import org.onap.ccsdk.features.sdnr.wt.common.database.ExtRestClient; +import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; +import org.onap.ccsdk.features.sdnr.wt.common.database.SearchResult; +import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilder; +import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilders; +import org.onap.ccsdk.features.sdnr.wt.common.database.requests.SearchRequest; +import org.onap.ccsdk.features.sdnr.wt.common.database.responses.AggregationEntries; +import org.onap.ccsdk.features.sdnr.wt.common.database.responses.SearchResponse; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Entity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EntityInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SortOrder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.entity.input.Filter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.entity.input.Sortorder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DataObjectAcessorPm extends DataObjectAcessor { + + private final Logger LOG = LoggerFactory.getLogger(DataObjectAcessorPm.class); + + private static final String UUID_KEY = "uuid-interface"; + private static final String NODE_KEY = "node-name"; + private static final String KEY = "node-name"; + + + enum Intervall { + PMDATA15M("historicalperformance15min", "historicalperformance15min"), + PMDATA24H("historicalperformance24h", "historicalperformance24h"); + + String index; + String type; + + Intervall(String index, String type) { + this.index = index; + this.type = type; + } + + public String getIndex() { + return index; + } + + public String getType() { + return type; + } + } + + private ExtRestClient dbClient; + private Intervall mode; + + public DataObjectAcessorPm(HtDatabaseClient dbClient, Intervall mode, Entity entity, Class clazz) throws ClassNotFoundException { + super(dbClient, entity, clazz, false); + this.dbClient = dbClient; + this.mode = mode; + } + + /** + * get aggregated list of ltps for filter NODE_KEY + * @param input + * @return + * @throws IOException + */ + QueryResult getDataLtpList(EntityInput input) throws IOException { + long page = QueryByFilter.getPage(input); + long pageSize = QueryByFilter.getPageSize(input); + Filter nodeFilter = QueryByFilter.getFilter(input.getFilter(), NODE_KEY); + if (nodeFilter != null) { + SearchRequest request = new SearchRequest(mode.getIndex(), mode.getType()); + request.setQuery(QueryBuilders.matchQuery(NODE_KEY, nodeFilter.getFiltervalue()).aggregations(UUID_KEY).size(0)); + try { + SearchResponse response = this.dbClient.search(request); + AggregationEntries aggs = response.getAggregations(UUID_KEY); + String[] uuids = aggs.getKeysAsPagedStringList(pageSize, pageSize * (page - 1)); + long totalSize = aggs.size(); + return new QueryResult(page, pageSize, new SearchResult(uuids, totalSize)); + } catch (IOException e) { + throw new IOException("problem reading ltps for req="+request, e); + } + } else { + String msg = "no nodename in filter found "; + LOG.debug(msg); + throw new IllegalArgumentException(msg); + } + } + +// QueryResult getDataDeviceList(EntityInput input) throws IOException { +// +// long page = QueryByFilter.getPage(input); +// long pageSize = QueryByFilter.getPageSize(input); +// +// SearchRequest request = new SearchRequest(mode.getIndex(), mode.getType()); +// request.setQuery(QueryBuilders.matchAllQuery().aggregations(KEY).size(0)); +//// try { +// SearchResponse response = this.dbClient.search(request); +// AggregationEntries aggs = response.getAggregations(KEY); +// String[] uuids = aggs.getKeysAsPagedStringList(pageSize, pageSize * (page - 1)); +// long totalSize = aggs.size(); +// return new QueryResult(page, pageSize, new SearchResult(uuids, totalSize)); +//// } catch (IOException e) { +//// throw new IOException("problem reading nodes for req="+request, e); +//// } +// } + /** + * get aggregated devices list + * @param input filter should be empty/no filter handled, only sortorder for KEY ('node-name') + * @return + * @throws IOException + */ + QueryResult getDataDeviceList(EntityInput input) throws IOException { + + long page = QueryByFilter.getPage(input); + long pageSize = QueryByFilter.getPageSize(input); + + Sortorder soNode = QueryByFilter.getSortOrder(input.getSortorder(), KEY); + SearchRequest request = new SearchRequest(mode.getIndex(), mode.getType()); + QueryBuilder query = null; + if (soNode != null) { + query = QueryBuilders.matchAllQuery() + .aggregations(KEY, + soNode.getSortorder() == SortOrder.Ascending + ? org.onap.ccsdk.features.sdnr.wt.common.database.queries.SortOrder.ASCENDING + : org.onap.ccsdk.features.sdnr.wt.common.database.queries.SortOrder.DESCENDING) + .size(0); + } else { + query = QueryBuilders.matchAllQuery().aggregations(KEY).size(0); + } + request.setQuery(query); + try { + SearchResponse response = this.dbClient.search(request); + AggregationEntries aggs = response.getAggregations(KEY); + String[] uuids = aggs.getKeysAsPagedStringList(pageSize, pageSize * (page - 1)); + long totalSize = aggs.size(); + return new QueryResult(page, pageSize, new SearchResult(uuids, totalSize)); + } catch (IOException e) { + throw new IOException("problem reading nodes for req=" + request, e); + } + + } + +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessorStatus.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessorStatus.java new file mode 100644 index 000000000..5970d5416 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessorStatus.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * ============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.dataprovider.data; + +import java.io.IOException; + +import org.onap.ccsdk.features.sdnr.wt.common.database.ExtRestClient; +import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; +import org.onap.ccsdk.features.sdnr.wt.common.database.SearchResult; +import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilders; +import org.onap.ccsdk.features.sdnr.wt.common.database.requests.SearchRequest; +import org.onap.ccsdk.features.sdnr.wt.common.database.responses.AggregationEntries; +import org.onap.ccsdk.features.sdnr.wt.common.database.responses.SearchResponse; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Entity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.status.output.Data; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.status.output.DataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.status.entity.FaultsBuilder; + +public class DataObjectAcessorStatus extends DataObjectAcessor { + + final String ESDATATYPE_FAULTCURRENT_SEVERITY_KEY = "severity"; + + private final ExtRestClient dbClient; + private final Entity entity; + + public DataObjectAcessorStatus(HtDatabaseClient dbClient, Entity entity) + throws ClassNotFoundException { + super(dbClient, entity, Data.class, false); + this.dbClient = dbClient; + this.entity = entity; + } + + QueryResult getDataStatus() throws IOException { + SearchRequest request = getNewInstanceOfSearchRequest(entity); + request.setQuery( + QueryBuilders.matchAllQuery().aggregations(ESDATATYPE_FAULTCURRENT_SEVERITY_KEY).size(0)); + SearchResponse response = this.dbClient.search(request); + AggregationEntries aggs = response.getAggregations(ESDATATYPE_FAULTCURRENT_SEVERITY_KEY); + + Data[] data = { new DataBuilder().setFaults(new FaultsBuilder(). + setCriticals(aggs.getOrDefault("Critical",0L)). + setMajors(aggs.getOrDefault("Major", 0L)). + setMinors(aggs.getOrDefault("Minor", 0L)). + setWarnings(aggs.getOrDefault("Warning", 0L)). + build()).build() }; + long toalsize = data.length; + return new QueryResult(1L, 1L, new SearchResult(data, toalsize)); + + } + + + private static SearchRequest getNewInstanceOfSearchRequest(Entity entity) { + return new SearchRequest(entity.getName(), entity.getName()); + } + + +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/ElasticSearchDataProvider.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/ElasticSearchDataProvider.java new file mode 100644 index 000000000..306fe95f4 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/ElasticSearchDataProvider.java @@ -0,0 +1,439 @@ +/******************************************************************************* + * ============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.dataprovider.data; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; +import org.onap.ccsdk.features.sdnr.wt.common.database.config.HostInfo; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.DataObjectAcessorPm.Intervall; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.IEntityDataProvider; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.CreateMaintenanceInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.CreateMaintenanceOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.CreateMediatorServerInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.CreateMediatorServerOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.CreateNetworkElementConnectionOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.DeleteMaintenanceInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.DeleteMaintenanceOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.DeleteMediatorServerInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.DeleteMediatorServerOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.DeleteNetworkElementConnectionInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.DeleteNetworkElementConnectionOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Entity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EntityInput; +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.data.provider.rev190801.MediatorServerEntity; +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.ReadConnectionlogListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadEventlogListInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadEventlogListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadFaultcurrentListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadFaultlogListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadInventoryListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadMaintenanceListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadMediatorServerListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadNetworkElementConnectionListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadPmdata15mDeviceListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadPmdata15mListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadPmdata15mLtpListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadPmdata24hDeviceListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadPmdata24hListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadPmdata24hLtpListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadStatusOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.UpdateMaintenanceInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.UpdateMaintenanceOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.UpdateMediatorServerInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.UpdateMediatorServerOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.UpdateNetworkElementConnectionInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.UpdateNetworkElementConnectionOutputBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ElasticSearchDataProvider implements IEntityDataProvider { + + private static final Logger LOG = LoggerFactory.getLogger(ElasticSearchDataProvider.class); + + private final HtDatabaseClient dbClient; + private final DataObjectAcessor eventRWFaultCurrent; + private final DataObjectAcessor eventRWFaultLog; + private final DataObjectAcessor mediatorserverRW; + private final DataObjectAcessor maintenanceRW; + private final DataObjectAcessor equipmentRW; + private final DataObjectAcessor connnectionlogRW; + private final DataObjectAcessor eventlogRW; + private final DataObjectAcessor networkelementConnectionRW; + private final DataObjectAcessorPm pm15mRW; + private final DataObjectAcessorPm pm24hRW; + + private final DataObjectAcessorStatus readStatus; + private final HtDatabaseEventsService databaseService; + + public ElasticSearchDataProvider(HostInfo[] hosts) throws Exception { + LOG.info("Start {}", this.getClass().getName()); + + this.dbClient = new HtDatabaseClient(hosts); + this.mediatorserverRW = new DataObjectAcessor<>(dbClient, Entity.MediatorServer, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.mediator.server.list.output.Data.class); + this.mediatorserverRW.setWriteInterface(MediatorServerEntity.class); + + this.maintenanceRW = new DataObjectAcessor<>(dbClient, Entity.Maintenancemode, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.maintenance.list.output.Data.class); + this.maintenanceRW.setWriteInterface(MaintenanceEntity.class); + + this.equipmentRW = new DataObjectAcessor<>(dbClient, Entity.Inventoryequipment, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.inventory.list.output.Data.class); + + this.eventRWFaultCurrent = new DataObjectAcessor<>(dbClient, Entity.Faultcurrent, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.faultcurrent.list.output.Data.class); + + this.eventRWFaultLog = new DataObjectAcessor<>(dbClient, Entity.Faultlog, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.faultlog.list.output.Data.class); + + this.connnectionlogRW = new DataObjectAcessor<>(dbClient, Entity.Connectionlog, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.connectionlog.list.output.Data.class); + + this.eventlogRW = new DataObjectAcessor<>(dbClient, Entity.Eventlog, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.eventlog.list.output.Data.class); + + this.networkelementConnectionRW = new DataObjectAcessor<>(dbClient, Entity.NetworkelementConnection, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.network.element.connection.list.output.Data.class); + this.networkelementConnectionRW.setWriteInterface(NetworkElementConnectionEntity.class); + + this.pm15mRW = new DataObjectAcessorPm<>(dbClient, Intervall.PMDATA15M, Entity.Historicalperformance15min, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.pmdata._15m.list.output.Data.class); + + this.pm24hRW = new DataObjectAcessorPm<>(dbClient, Intervall.PMDATA24H, Entity.Historicalperformance24h, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.pmdata._24h.list.output.Data.class); + + this.readStatus = new DataObjectAcessorStatus(dbClient, Entity.Faultcurrent ); + + this.databaseService = new HtDatabaseEventsService(dbClient); + } + + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.faultcurrent.list.output.Data + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.faultcurrent.list.output.PaginationBuilder + //eventRWFaultCurrent + public ReadFaultcurrentListOutputBuilder readFaultCurrentList(EntityInput input) { + + ReadFaultcurrentListOutputBuilder outputBuilder = new ReadFaultcurrentListOutputBuilder(); + + QueryResult result = this.eventRWFaultCurrent + .getData(input); + outputBuilder.setData(result.getResult().getHits()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.faultcurrent.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.faultlog.list.output.Data + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.faultlog.list.output.PaginationBuilder + //eventRWFaultLog + public ReadFaultlogListOutputBuilder readFaultLogList(EntityInput input) { + ReadFaultlogListOutputBuilder outputBuilder = new ReadFaultlogListOutputBuilder(); + QueryResult result = this.eventRWFaultLog + .getData(input); + outputBuilder.setData(result.getResult().getHits()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.faultlog.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.maintenance.list.output.Data + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.maintenance.list.output.PaginationBuilder + //maintenanceRW + public ReadMaintenanceListOutputBuilder readMaintenanceList(EntityInput input) { + ReadMaintenanceListOutputBuilder outputBuilder = new ReadMaintenanceListOutputBuilder(); + QueryResult result = this.maintenanceRW + .getData(input); + outputBuilder.setData(result.getResult().getHits()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.maintenance.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.mediator.server.list.output.Data + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.mediator.server.list.output.Pagination + //mediatorserverRW + public ReadMediatorServerListOutputBuilder readMediatorServerList(EntityInput input) { + + ReadMediatorServerListOutputBuilder outputBuilder = new ReadMediatorServerListOutputBuilder(); + QueryResult result = this.mediatorserverRW + .getData(input); + outputBuilder.setData(result.getResult().getHits()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.mediator.server.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.network.element.connection.list.output.Data + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.network.element.connection.list.output.PaginationBuilder + //networkelementConnectionRW + public ReadNetworkElementConnectionListOutputBuilder readNetworkElementConnectionList( + EntityInput input) { + ReadNetworkElementConnectionListOutputBuilder outputBuilder = new ReadNetworkElementConnectionListOutputBuilder(); + QueryResult result = this.networkelementConnectionRW + .getData(input); + outputBuilder.setData(result.getResult().getHits()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.network.element.connection.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.inventory.list.output.Data + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.inventory.list.output.PaginationBuilder + //equipmentRW + public ReadInventoryListOutputBuilder readInventoryList(EntityInput input) { + ReadInventoryListOutputBuilder outputBuilder = new ReadInventoryListOutputBuilder(); + QueryResult result = this.equipmentRW + .getData(input); + outputBuilder.setData(result.getResult().getHits()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.inventory.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.inventory.list.output.Data + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.inventory.list.output.PaginationBuilder + //connnectionlogRW + public ReadConnectionlogListOutputBuilder readConnectionlogList(EntityInput input) { + ReadConnectionlogListOutputBuilder outputBuilder = new ReadConnectionlogListOutputBuilder(); + QueryResult result = this.connnectionlogRW + .getData(input); + outputBuilder.setData(result.getResult().getHits()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.connectionlog.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.eventlog.list.output.Data + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.eventlog.list.output.PaginationBuilder + //eventlogRW + public ReadEventlogListOutputBuilder readEventlogList(ReadEventlogListInput input) throws IOException { + ReadEventlogListOutputBuilder outputBuilder = new ReadEventlogListOutputBuilder(); + QueryResult result = this.eventlogRW + .getData(input); + outputBuilder.setData(result.getResult().getHits()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.eventlog.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.pmdata._15m.list.output.Data + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.pmdata._15m.list.output.PaginationBuilder + public ReadPmdata15mListOutputBuilder readPmdata15mList(EntityInput input) { + ReadPmdata15mListOutputBuilder outputBuilder = new ReadPmdata15mListOutputBuilder(); + QueryResult result = this.pm15mRW + .getData(input); + outputBuilder.setData(result.getResult().getHits()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.pmdata._15m.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.pmdata._24h.list.output.Data + //org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.pmdata._24h.list.output.Pagination + public ReadPmdata24hListOutputBuilder readPmdata24hList(EntityInput input) { + ReadPmdata24hListOutputBuilder outputBuilder = new ReadPmdata24hListOutputBuilder(); + QueryResult result = this.pm24hRW + .getData(input); + outputBuilder.setData(result.getResult().getHits()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.pmdata._24h.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + public ReadPmdata15mLtpListOutputBuilder readPmdata15mLtpList(EntityInput input) throws IOException { + ReadPmdata15mLtpListOutputBuilder outputBuilder = new ReadPmdata15mLtpListOutputBuilder(); + QueryResult result = pm15mRW.getDataLtpList(input); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.pmdata._15m.ltp.list.output.PaginationBuilder( + result.getPagination()).build()); + outputBuilder.setData(result.getResult().getHits()); + return outputBuilder; + } + + public ReadPmdata15mDeviceListOutputBuilder readPmdata15mDeviceList(EntityInput input) throws IOException { + ReadPmdata15mDeviceListOutputBuilder outputBuilder = new ReadPmdata15mDeviceListOutputBuilder(); + QueryResult result = pm15mRW.getDataDeviceList(input); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.pmdata._15m.device.list.output.PaginationBuilder( + result.getPagination()).build()); + outputBuilder.setData(result.getResult().getHits()); + return outputBuilder; + } + + public ReadPmdata24hLtpListOutputBuilder readPmdata24hLtpList(EntityInput input) throws IOException { + + QueryResult result = pm24hRW.getDataLtpList(input); + + ReadPmdata24hLtpListOutputBuilder outputBuilder = new ReadPmdata24hLtpListOutputBuilder(); + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.pmdata._24h.ltp.list.output.PaginationBuilder(); + outputBuilder.setPagination(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.pmdata._24h.ltp.list.output.PaginationBuilder( + result.getPagination()).build()); + outputBuilder.setData(result.getResult().getHits()); + return outputBuilder; + } + + public ReadPmdata24hDeviceListOutputBuilder readPmdata24hDeviceList(EntityInput input) + throws IOException { + + QueryResult result = pm24hRW.getDataDeviceList(input); + + ReadPmdata24hDeviceListOutputBuilder outputBuilder = new ReadPmdata24hDeviceListOutputBuilder(); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.pmdata._24h.device.list.output.PaginationBuilder( + result.getPagination()).build()); + outputBuilder.setData(result.getResult().getHits()); + return outputBuilder; + } + + public ReadStatusOutputBuilder readStatus() throws IOException { + QueryResult result = readStatus.getDataStatus(); + + ReadStatusOutputBuilder outputBuilder = new ReadStatusOutputBuilder(); + outputBuilder.setData(result.getResult().getHits()); + return outputBuilder; + } + + public boolean waitForYellowDatabaseStatus(long timeout, TimeUnit unit) { + return this.dbClient.waitForYellowStatus(unit.toMillis(timeout)); + } + + public CreateNetworkElementConnectionOutputBuilder createNetworkElementConnection( + NetworkElementConnectionEntity input) throws IOException { + String id = this.networkelementConnectionRW.update(input, input.getNodeId()); + if (id == null) { + throw new IOException("unable to write data to database"); + } + CreateNetworkElementConnectionOutputBuilder builder = new CreateNetworkElementConnectionOutputBuilder(); + builder.setId(id).setNodeId(input.getNodeId()).setHost(input.getHost()).setPort(input.getPort()) + .setUsername(input.getUsername()).setPassword(input.getPassword()).setIsRequired(input.isIsRequired()) + .setCoreModelCapability(input.getCoreModelCapability()).setDeviceType(input.getDeviceType()); + return builder; + } + + public UpdateNetworkElementConnectionOutputBuilder updateNetworkElementConnection( + UpdateNetworkElementConnectionInput input) throws IOException { + String id = this.networkelementConnectionRW.update(input, input.getId()); + if (id == null) { + throw new IOException("unable to update data in database"); + } + UpdateNetworkElementConnectionOutputBuilder builder = new UpdateNetworkElementConnectionOutputBuilder(); + builder.setId(id).setNodeId(input.getNodeId()).setHost(input.getHost()).setPort(input.getPort()) + .setUsername(input.getUsername()).setPassword(input.getPassword()) + .setCoreModelCapability(input.getCoreModelCapability()).setDeviceType(input.getDeviceType()); + return builder; + } + + public DeleteNetworkElementConnectionOutputBuilder deleteNetworkElementConnection(DeleteNetworkElementConnectionInput input) throws IOException { + boolean removed = this.networkelementConnectionRW.remove(input.getId()); + if (!removed) { + throw new IOException("unable to remove data from database"); + } + return new DeleteNetworkElementConnectionOutputBuilder(); + } + + public DeleteMediatorServerOutputBuilder deleteMediatorServer(DeleteMediatorServerInput input) throws IOException { + boolean removed = this.mediatorserverRW.remove(input.getId()); + if (!removed) { + throw new IOException("unable to remove data from database"); + } + return new DeleteMediatorServerOutputBuilder(); + } + + public DeleteMaintenanceOutputBuilder deleteMaintenance(DeleteMaintenanceInput input) throws IOException { + boolean removed = this.maintenanceRW.remove(input.getId()); + if (!removed) { + throw new IOException("unable to remove data from database"); + } + return new DeleteMaintenanceOutputBuilder(); + } + + public UpdateMaintenanceOutputBuilder updateMaintenance(UpdateMaintenanceInput input) throws IOException { + if (input.getId() == null) { + throw new IOException("please give the id for updating entry"); + } + String id = this.maintenanceRW.update(input, input.getId()); + if (id == null) { + throw new IOException("unable to update data in database"); + } + UpdateMaintenanceOutputBuilder builder = new UpdateMaintenanceOutputBuilder(input).setId(id); + return builder; + } + + public UpdateMediatorServerOutputBuilder updateMediatorServer(UpdateMediatorServerInput input) throws IOException { + if (input.getId() == null) { + throw new IOException("please give the id for updating entry"); + } + String id = this.mediatorserverRW.update(input, input.getId()); + if (id == null) { + throw new IOException("unable to update data in database"); + } + UpdateMediatorServerOutputBuilder builder = new UpdateMediatorServerOutputBuilder(); + builder.setId(id).setName(input.getName()).setUrl(input.getUrl()); + return builder; + } + + public CreateMaintenanceOutputBuilder createMaintenance(CreateMaintenanceInput input) throws IOException { + String id = this.maintenanceRW.write(input, input.getNodeId()); + if (id == null) { + throw new IOException("unable to write data to database"); + } + CreateMaintenanceOutputBuilder builder = new CreateMaintenanceOutputBuilder(input).setId(id); + return builder; + } + + public CreateMediatorServerOutputBuilder createMediatorServer(CreateMediatorServerInput input) throws IOException { + String id = this.mediatorserverRW.write(input, null); + + if (id == null) { + throw new IOException("unable to write data to database"); + } + CreateMediatorServerOutputBuilder builder = new CreateMediatorServerOutputBuilder(); + builder.setId(id).setName(input.getName()).setUrl(input.getUrl()); + return builder; + } + + @Override + public DataProvider getDataProvider() { + return this.databaseService; + } + + /** + * no need for implementation + */ + @Override + public void setReadyStatus(boolean status) { + + } + + + +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/FaultEntityManager.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/FaultEntityManager.java new file mode 100644 index 000000000..f26a30de8 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/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.dataprovider.data; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.annotation.Nonnull; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SeverityType; + +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(@Nonnull Fault fault) { + return SeverityType.NonAlarmed.equals(fault.getSeverity()); + } + + /** + * 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/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/HtDatabaseEventsService.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/HtDatabaseEventsService.java new file mode 100644 index 000000000..b08466c8b --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/HtDatabaseEventsService.java @@ -0,0 +1,388 @@ +/******************************************************************************* + * ============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.dataprovider.data; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import javax.annotation.Nonnull; +import org.onap.ccsdk.features.sdnr.wt.base.netconf.util.NetconfTimeStamp; +import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; +import org.onap.ccsdk.features.sdnr.wt.common.database.queries.BoolQueryBuilder; +import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilder; +import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilders; +import org.onap.ccsdk.features.sdnr.wt.common.database.queries.RangeQueryBuilder; +import org.onap.ccsdk.features.sdnr.wt.database.EsDataObjectReaderWriter2; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.ArchiveCleanProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Entity; +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.Inventory; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.InventoryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.InventoryEntity; +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.UpdateNetworkElementConnectionInputBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Event service, writing all events into the database into the appropriate + * index. + * + * @author herbert + */ +public class HtDatabaseEventsService implements ArchiveCleanProvider, DataProvider { + private static final Logger LOG = LoggerFactory.getLogger(HtDatabaseEventsService.class); + + private static final NetconfTimeStamp NETCONFTIME_CONVERTER = NetconfTimeStamp.getConverter(); + + private HtDatabaseClient client; + private EsDataObjectReaderWriter2 eventRWEventLogDevicemanager; + private EsDataObjectReaderWriter2 eventRWEquipment; + private EsDataObjectReaderWriter2 eventRWFaultCurrentDB; + private EsDataObjectReaderWriter2 eventRWFaultLogDB; + private EsDataObjectReaderWriter2 eventRWConnectionLogDB; + private EsDataObjectReaderWriter2 networkelementConnectionDB; + // --- Construct and initialize + + public HtDatabaseEventsService(HtDatabaseClient client) throws Exception { + + LOG.info("Create {} start", HtDatabaseEventsService.class); + + try { + // Create control structure + this.client = client; + + eventRWEventLogDevicemanager = new EsDataObjectReaderWriter2<>(client, Entity.Eventlog, + EventlogEntity.class, EventlogBuilder.class); + + eventRWEquipment = new EsDataObjectReaderWriter2<>(client, Entity.Inventoryequipment, + InventoryEntity.class, InventoryBuilder.class); + + eventRWFaultCurrentDB = new EsDataObjectReaderWriter2<>(client, Entity.Faultcurrent, + FaultcurrentEntity.class, FaultcurrentBuilder.class); + + eventRWFaultLogDB = new EsDataObjectReaderWriter2<>(client, Entity.Faultlog, + FaultlogEntity.class, FaultlogBuilder.class); + + eventRWConnectionLogDB = new EsDataObjectReaderWriter2<>(client, Entity.Connectionlog, + ConnectionlogEntity.class, ConnectionlogBuilder.class); + + networkelementConnectionDB = new EsDataObjectReaderWriter2<>(client, Entity.NetworkelementConnection, + NetworkElementConnectionEntity.class, NetworkElementConnectionBuilder.class) + .setEsIdAttributeName("_id"); + + } catch (Exception e) { + LOG.error("Can not start database client. Exception: {}", e); + throw new Exception("Can not start database client. Exception: {}", e); + } + LOG.info("Create {} finished. DB Service {} started.", HtDatabaseEventsService.class, + client != null ? "sucessfully" : "not"); + } + + // --- Function + + // -- Connection log + @Override + public void writeConnectionLog(ConnectionlogEntity event) { + if (assertIfClientNull(event)) { + return; + } + LOG.debug("Write event: {}", event); + eventRWConnectionLogDB.write(event, null); + + } + // -- Event log + @Override + public void writeEventLog(EventlogEntity event) { + if (assertIfClientNull("No client to write {}", event)) { + return; + } + + LOG.debug("Write event: {}", event.toString()); + eventRWEventLogDevicemanager.write(event, null); + } + + + // -- Fault log + + @Override + public void writeFaultLog(FaultlogEntity fault) { + if (assertIfClientNull(fault)) { + return; + } + + LOG.debug("Write fault to faultlog: {}", fault.toString()); + eventRWFaultLogDB.write(fault,null); + } + + // -- Fault current + + @Override + public void updateFaultCurrent(FaultcurrentEntity fault) { + if (assertIfClientNull(fault)) { + return; + } + + if (FaultEntityManager.isManagedAsCurrentProblem(fault)) { + if (FaultEntityManager.isNoAlarmIndication(fault)) { + LOG.debug("Remove from currentFaults: {}", fault.toString()); + eventRWFaultCurrentDB.remove(FaultEntityManager.genSpecificEsId(fault)); + } else { + LOG.debug("Write to currentFaults: {}", fault.toString()); + eventRWFaultCurrentDB.write(fault, FaultEntityManager.genSpecificEsId(fault)); + } + } else { + LOG.debug("Ingnore for currentFaults: {}", fault.toString()); + } + } + + /** + * Remove all entries for one node + * + * @param nodeName contains the mountpointname + * @return number of deleted entries + */ + @Override + public int clearFaultsCurrentOfNode(String nodeName) { + if (assertIfClientNullForNodeName(nodeName)) { + return -1; + } + + LOG.debug("Remove from currentFaults all faults for node: {}", nodeName); + return eventRWFaultCurrentDB.remove(EsFaultCurrent.getQueryForOneNode(nodeName)); + } + + /** + * Remove all entries for one node + * + * @param nodeName contains the mountpointname + * @param objectId of element to be deleted + * @return number of deleted entries + */ + @Override + public int clearFaultsCurrentOfNodeWithObjectId(String nodeName, String objectId) { + if (assertIfClientNullForNodeName(nodeName)) { + return -1; + } + + LOG.debug("Remove from currentFaults all faults for node/objectId: {}/{}", nodeName, objectId); + return eventRWFaultCurrentDB.remove(EsFaultCurrent.getQueryForOneNodeAndObjectId(nodeName, objectId)); + } + + /** + * Deliver list with all mountpoint/node-names in the database. + * + * @return List of all mountpoint/node-names the had active alarms. + */ + @Override + public @Nonnull List getAllNodesWithCurrentAlarms() { + if (assertIfClientNull("No DB, can not delete for all nodes", null)) { + return new ArrayList<>(); + } + + LOG.debug("Remove from currentFaults faults for all node"); + List nodeNames = new ArrayList<>(); + + for (FaultcurrentEntity fault : eventRWFaultCurrentDB.doReadAll().getHits()) { + String nodeName = fault.getNodeId(); + if (!nodeNames.contains(nodeName)) { + // this.clearFaultsCurrentOfNode(nodeName); -> Function shifted + nodeNames.add(nodeName); + } + } + return nodeNames; + } + + // -- Inventory and equipment current + + /** + * write internal equipment to database + * @param internalEquipment with mandatory fields. + */ + @Override + public void writeInventory(Inventory internalEquipment) { + + if (assertIfClientNullForNodeName(internalEquipment.getNodeId())) { + return; + } + eventRWEquipment.write(internalEquipment, internalEquipment.getNodeId()+"/"+internalEquipment.getUuid()); + } + + + // -- Networkelement + + /** + * + * @param networkElementConnectionEntitiy to wirte to DB + * @param nodeId Id for this DB element + */ + @Override + public void updateNetworkConnectionDeviceType(NetworkElementConnectionEntity networkElementConnectionEntitiy, String nodeId) { + this.networkelementConnectionDB.update(networkElementConnectionEntitiy, nodeId); + } + + /** + * Update after new mountpoint registration + * @param networkElementConnectionEntitiy data + * @param nodeId of device (mountpoint name) + */ + @Override + public void updateNetworkConnection22(NetworkElementConnectionEntity networkElementConnectionEntitiy, String nodeId) { + this.networkelementConnectionDB.updateOrCreate(networkElementConnectionEntitiy, nodeId, Arrays.asList("is-required", "username", "password")); + } + + /* please do not remove */ + // public void cleanNetworkElementConnections() { + // this.networkelementConnectionDB.remove(QueryBuilders.matchQuery("is-required", false)); + // CreateNetworkElementConnectionInput x = new CreateNetworkElementConnectionInputBuilder().setStatus(ConnectionLogStatus.Disconnected).build(); + // this.networkelementConnectionDB.update(x,QueryBuilders.matchAllQuery()); + // } + + @Override + public void removeNetworkConnection(String nodeId) { + Boolean isRequired; + NetworkElementConnectionEntity e = this.networkelementConnectionDB.read(nodeId); + if (e != null && (isRequired = e.isIsRequired()) != null) { + if (isRequired) { + LOG.debug("updating connection status for {} of required ne to disconnected",nodeId); + this.networkelementConnectionDB.update(new UpdateNetworkElementConnectionInputBuilder().setStatus(ConnectionLogStatus.Disconnected).build(), nodeId); + } else { + LOG.debug("remove networkelement-connection for {} entry because of non-required",nodeId); + this.networkelementConnectionDB.remove(nodeId); + } + } + else { + LOG.warn("Unable to update connection-status. dbentry for {} not found in networkelement-connection",nodeId); + } + } + + // -- Multiple areas + + @Override + public int doIndexClean(Date olderAreOutdated) { + + String netconfTimeStamp = NETCONFTIME_CONVERTER.getTimeStampAsNetconfString(olderAreOutdated); + int removed = 0; + + QueryBuilder queryEventBase = EsEventBase.getQueryForTimeStamp(netconfTimeStamp); + removed += eventRWEventLogDevicemanager.remove(queryEventBase); + + QueryBuilder queryFaultLog = EsFaultLogDevicemanager.getQueryForTimeStamp(netconfTimeStamp); + removed += eventRWFaultLogDB.remove(queryFaultLog); + return removed; + } + + @Override + public int getNumberOfOldObjects(Date olderAreOutdated) { + + String netconfTimeStamp = NETCONFTIME_CONVERTER.getTimeStampAsNetconfString(olderAreOutdated); + int numberOfElements = 0; + + QueryBuilder queryEventBase = EsEventBase.getQueryForTimeStamp(netconfTimeStamp); + numberOfElements += eventRWEventLogDevicemanager.doReadAll(queryEventBase).getTotal(); + + QueryBuilder queryFaultLog = EsFaultLogDevicemanager.getQueryForTimeStamp(netconfTimeStamp); + numberOfElements += eventRWFaultLogDB.doReadAll(queryFaultLog).getTotal(); + + return numberOfElements; + } + + // -- Helper + + /** + * Verify status of client + * @param event that is printed with message + * @return true if client is null + */ + private boolean assertIfClientNull(Object event) { + return assertIfClientNull("No DB, can not write: {}", event); + } + + private boolean assertIfClientNullForNodeName(Object object) { + return assertIfClientNull("No DB, can not handle node: {}", object); + } + /** + * Verify status of client + * @param message to print including {} for object printout. + * @return true if client is null + */ + private boolean assertIfClientNull(String message, Object object) { + if (client == null) { + LOG.debug(message, object); + return true; + } + return false; + } + + // ### sub classes + + + private static class EsEventBase { + /** + * Query to get older Elements + * @param netconfTimeStamp to identify older Elements + * @return QueryBuilder for older elements related to timestamp + */ + private static QueryBuilder getQueryForTimeStamp(String netconfTimeStamp) { + return new RangeQueryBuilder("event.timeStamp").lte(netconfTimeStamp); + } + } + private static class EsFaultLogDevicemanager { + /** + * Get older Elements + * @param netconfTimeStamp to identify query elements older than this timestamp. + * @return QueryBuilder for related elements + */ + public static QueryBuilder getQueryForTimeStamp(String netconfTimeStamp) { + return new RangeQueryBuilder("timestamp").lte(netconfTimeStamp); + } + } + public static class EsFaultCurrent { + /** + * @param nodeName name of the node + * @return query builder + */ + public static QueryBuilder getQueryForOneNode( String nodeName) { + return QueryBuilders.matchQuery("node-id", nodeName); + } + + public static QueryBuilder getQueryForOneNodeAndObjectId( String nodeName, String objectId) { + BoolQueryBuilder bq = QueryBuilders.boolQuery(); + bq.must(QueryBuilders.matchQuery("node-id", nodeName)); + bq.must(QueryBuilders.matchQuery("object-id", objectId)); + return bq; + } + } + @Override + public List getNetworkElementConnections() { + return this.networkelementConnectionDB.doReadAll().getHits(); + } + +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryByFilter.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryByFilter.java new file mode 100644 index 000000000..f00ffb546 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryByFilter.java @@ -0,0 +1,342 @@ +/******************************************************************************* + * ============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.dataprovider.data; + +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; + +import org.eclipse.jdt.annotation.Nullable; +import org.onap.ccsdk.features.sdnr.wt.base.netconf.util.NetconfTimeStamp; +import org.onap.ccsdk.features.sdnr.wt.common.database.data.DbFilter; +import org.onap.ccsdk.features.sdnr.wt.common.database.queries.BoolQueryBuilder; +import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilder; +import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilders; +import org.onap.ccsdk.features.sdnr.wt.common.database.queries.RangeQueryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EntityInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SortOrder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.entity.input.Filter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.entity.input.Sortorder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class QueryByFilter { + + private static final Logger LOG = LoggerFactory.getLogger(DataObjectAcessorPm.class); + + private QueryByFilter() { + //Hide + } + + static long getPage(EntityInput input) { + return getPage(input, 1); + } + + @SuppressWarnings("null") + private static long getPage(EntityInput input, long defaultValue) { + return input.getPagination() != null ? input.getPagination().getPage().longValue() : defaultValue; + } + + static long getPageSize(EntityInput input) { + return getPageSize(input, 1); + } + + @SuppressWarnings("null") + private static long getPageSize(EntityInput input, long defaultValue) { + return input.getPagination() != null ? input.getPagination().getSize().longValue() : defaultValue; + } + + + public static QueryBuilder setSortOrder(QueryBuilder query, @Nullable List sortorder) { + return setSortOrder(query, sortorder, ""); + } + + private static QueryBuilder setSortOrder(QueryBuilder query, @Nullable List sortorder, String prefix) { + if (sortorder != null && sortorder.size() > 0) { + for (Sortorder so : sortorder) { + query.sort((prefix != null ? prefix : "") + so.getProperty(), + so.getSortorder() == SortOrder.Ascending + ? org.onap.ccsdk.features.sdnr.wt.common.database.queries.SortOrder.ASCENDING + : org.onap.ccsdk.features.sdnr.wt.common.database.queries.SortOrder.DESCENDING); + } + } + return query; + + } + + + public static Sortorder getSortOrder(@Nullable List list, String prop) { + if (list == null) { + return null; + } + for (Sortorder o : list) { + if (prop.equals(o.getProperty())) { + return o; + } + } + return null; + } + + public static Filter getFilter(@Nullable List list, String prop) { + if (list == null) { + return null; + } + for (Filter f : list) { + if (prop.equals(f.getProperty())) { + return f; + } + } + return null; + } + + public static QueryBuilder fromFilter(@Nullable List filters) { + return fromFilter(filters, ""); + } + + private static String fillTimeStamp(String value) { + int idx=value.lastIndexOf("*"); + final String REPLACE="0000-00-00T00:00:00.0Z"; + String s = value.substring(0,idx)+REPLACE.substring(idx); + if(Integer.parseInt(s.substring(5,7))==0) { + s=s.substring(0,5)+"01-"+s.substring(8); + } + if(Integer.parseInt(s.substring(8,10))==0) { + s=s.substring(0,8)+"01"+s.substring(10); + } + + return s; + } + /** + * convert timestamp with ending placeholder in filter to elasticsearch filter + * e.g. 2017* => gte: 2017-01-01T00:00:00Z, lt:2018-01-01T00:00:00Z + * + * 201* => 2010-01... 2020 .. + * 2018-* => 2018-01... <=> 2019-01 + * + */ + private static @Nullable QueryBuilder fromTimestampSearchFilter(String property,String value) { + if(!value.endsWith("*")) { + return null; + } + int idx=value.lastIndexOf("*"); + String lowerEnd = fillTimeStamp(value); + String upperEnd =null; + NetconfTimeStamp converter = NetconfTimeStamp.getConverter(); + Date dt = null; + try{ + dt=converter.getDateFromNetconf(lowerEnd); + } + catch(Exception e) { + + } + if(dt==null) { + return null; + } +// property.substring(0,idx)+REPLACE.substring(idx+1); + Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + c.setTime(dt); + int tmpvalue; + switch(idx) { + case 1: // (2*) + c.set(Calendar.YEAR,c.get(Calendar.YEAR)+1000); + upperEnd = converter.getTimeStampAsNetconfString(c.getTime()); + break; + case 2: // (20*) + c.set(Calendar.YEAR,c.get(Calendar.YEAR)+100); + upperEnd = converter.getTimeStampAsNetconfString(c.getTime()); + break; + case 3: // (200*) + c.set(Calendar.YEAR,c.get(Calendar.YEAR)+10); + upperEnd = converter.getTimeStampAsNetconfString(c.getTime()); + break; + case 4: // (2000*) + case 5: // (2000-*) + c.set(Calendar.YEAR,c.get(Calendar.YEAR)+1); + upperEnd = converter.getTimeStampAsNetconfString(c.getTime()); + break; + case 6: //switch 10 months (2000-0* or 2000-1*) + tmpvalue = c.get(Calendar.MONTH); + if(tmpvalue<9) { + c.set(Calendar.MONTH,9); + } + else { + c.set(Calendar.YEAR,c.get(Calendar.YEAR)+1); + c.set(Calendar.MONTH,0); + } + upperEnd = converter.getTimeStampAsNetconfString(c.getTime()); + + break; + case 7: //switch one month (2018-01* or 2018-01-*) + case 8: + c.add(Calendar.MONTH, 1); + upperEnd = converter.getTimeStampAsNetconfString(c.getTime()); + break; + case 9: // (2018-01-0*) + tmpvalue = c.get(Calendar.DAY_OF_MONTH); + if(tmpvalue==1) { + c.set(Calendar.DAY_OF_MONTH, 10); + }else if(tmpvalue==10) { + c.set(Calendar.DAY_OF_MONTH, 20); + }else if(tmpvalue==20) { + if(c.getActualMaximum(Calendar.DAY_OF_MONTH)<30) { + c.set(Calendar.DAY_OF_MONTH,1); + c.add(Calendar.MONTH,1); + } + else { + c.set(Calendar.DAY_OF_MONTH,30); + } + }else if(tmpvalue==30) { + c.set(Calendar.DAY_OF_MONTH,1); + c.add(Calendar.MONTH,1); + } + else { + break; + } + upperEnd = converter.getTimeStampAsNetconfString(c.getTime()); + break; + case 10: // (2018-01-01*) + case 11: // (2018-01-01T*) + c.add(Calendar.DAY_OF_MONTH,1); + upperEnd = converter.getTimeStampAsNetconfString(c.getTime()); + break; + case 12: // (2018-01-01T1*) + tmpvalue = c.get(Calendar.HOUR_OF_DAY); + if(tmpvalue==20) { + c.set(Calendar.HOUR_OF_DAY,0); + c.add(Calendar.DAY_OF_MONTH,1); + } + else { + c.add(Calendar.HOUR_OF_DAY,10); + } + upperEnd = converter.getTimeStampAsNetconfString(c.getTime()); + break; + case 13: // (2018-01-01T11*) + case 14: // (2018-01-01T11-*) + c.add(Calendar.HOUR_OF_DAY,1); + upperEnd = converter.getTimeStampAsNetconfString(c.getTime()); + break; + case 15: // (2018-01-01T11-3*) + c.add(Calendar.MINUTE,10); + upperEnd = converter.getTimeStampAsNetconfString(c.getTime()); + break; + case 16: // (2018-01-01T11-32*) + case 17: // (2018-01-01T11-32-*) + c.add(Calendar.MINUTE,1); + upperEnd = converter.getTimeStampAsNetconfString(c.getTime()); + break; + case 18: // (2018-01-01T11-32-1*) + c.add(Calendar.SECOND,10); + upperEnd = converter.getTimeStampAsNetconfString(c.getTime()); + break; + case 19: // (2018-01-01T11-32-11*) + case 20: // (2018-01-01T11-32-11.*) + c.add(Calendar.SECOND,1); + upperEnd = converter.getTimeStampAsNetconfString(c.getTime()); + break; + + default: + break; + } + + if(upperEnd==null) { + return null; + } + return QueryBuilders.rangeQuery(property).gte(lowerEnd).lt(upperEnd); + + } + private static QueryBuilder fromFilter(@Nullable List filters, String prefix) { + if (filters == null || filters.size() == 0) { + return QueryBuilders.matchAllQuery(); + + } else if (filters.size() == 1) { + QueryBuilder query; + String p = filters.get(0).getProperty(); + String v= filters.get(0).getFiltervalue(); + if ("id".equals(p)) { + p = "_id"; + } + else { + // v=v.toLowerCase(); + } + if (DbFilter.hasSearchParams(v)) { + if(p!=null && "timestamp".equals(p.toLowerCase())) { + query = fromTimestampSearchFilter(p,v); + if(query!=null) { + return query; + } + } + return QueryBuilders.regex(p, DbFilter.createDatabaseRegex(v)); + + + } else if (DbFilter.isComparisonValid(v)) { + RangeQueryBuilder q = DbFilter.getRangeQuery((prefix != null ? prefix : "") + p, v); + if (q != null) { + return q; + } + else { + return QueryBuilders.matchQuery((prefix != null ? prefix : "") + p, v); + } + } + else { + return QueryBuilders.matchQuery((prefix != null ? prefix : "") + p, v); + } + } + else { + BoolQueryBuilder query = new BoolQueryBuilder(); + QueryBuilder tmpQuery; + for (Filter fi : filters) { + String p = fi.getProperty(); + String v=fi.getFiltervalue(); + if ("id".equals(p)) { + p = "_id"; + } + else { + // v=v.toLowerCase(); + } + if(DbFilter.hasSearchParams(v)) { + if(p!=null && "timestamp".equals(p.toLowerCase())) { + tmpQuery=fromTimestampSearchFilter(p,v); + if(tmpQuery!=null) { + query.must(tmpQuery); + }else { + query.must(QueryBuilders.regex((prefix != null ? prefix : "") + p,DbFilter.createDatabaseRegex(v))); + } + }else { + query.must(QueryBuilders.regex((prefix != null ? prefix : "") + p,DbFilter.createDatabaseRegex(v))); + } + } + else if (DbFilter.isComparisonValid(v)) { + RangeQueryBuilder q = DbFilter.getRangeQuery((prefix != null ? prefix : "") + p,v); + if(q!=null) { + query.must(q); + } + else { + query.must(QueryBuilders.matchQuery((prefix != null ? prefix : "") + p,v)); + } + } + else { + query.must(QueryBuilders.matchQuery((prefix != null ? prefix : "") + p,v)); + } + } + LOG.trace("Query result. {}", query.toJSON()); + return query; + } + } + +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryResult.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryResult.java new file mode 100644 index 000000000..9cbe9430c --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryResult.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * ============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.dataprovider.data; + +import java.math.BigInteger; + +import org.onap.ccsdk.features.sdnr.wt.common.database.SearchResult; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.PaginationOutputG; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.connectionlog.list.output.PaginationBuilder; + +public class QueryResult { + + private SearchResult result; + private PaginationOutputG pagination; + + public QueryResult(long page, long pageSize, SearchResult result) { + this.result = result; + + PaginationBuilder x = new PaginationBuilder(); + x.setPage(BigInteger.valueOf(page)); + x.setSize(pageSize); + x.setTotal(BigInteger.valueOf(result.getTotal())); + pagination = x.build(); + } + + public SearchResult getResult() { + return result; + } + + PaginationOutputG getPagination() { + return pagination; + } + + + + +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/YangFileProvider.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/YangFileProvider.java new file mode 100644 index 000000000..44240b07f --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/YangFileProvider.java @@ -0,0 +1,206 @@ +/******************************************************************************* + * ============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.dataprovider.data; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Path; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Date; +import java.util.List; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class YangFileProvider { + + private static final Logger LOG = LoggerFactory.getLogger(YangFileProvider.class); + + private static final FilenameFilter yangFilenameFilter = new FilenameFilter() { + + @Override + public boolean accept(File dir, String name) { + return name.toLowerCase().endsWith(".yang"); + } + }; + + private static final int BUFFER_SIZE = 1024; + + private final Path mainSourcePath; + private final List additionalSources; + + public YangFileProvider(String path) { + this.mainSourcePath = new File(path).toPath(); + this.additionalSources = new ArrayList<>(); + } + + public boolean hasFileForModule(String module, String version) { + return this.mainSourcePath.resolve(YangFilename.createFilename(module, version)).toFile().exists(); + } + + public boolean hasFileForModule(String module) { + return this.findYangFiles(module).size() > 0; + } + + private List findYangFiles(String module) { + List list = new ArrayList<>(); + String[] files = this.mainSourcePath.toFile().list(yangFilenameFilter); + YangFilename yangfile; + for (String file : files) { + files = this.mainSourcePath.toFile().list(yangFilenameFilter); + for (String fn : files) { + try { + yangfile = new YangFilename(this.mainSourcePath.resolve(fn).toString()); + if (yangfile.getModule().equals(module)) { + list.add(yangfile); + } + } catch (ParseException e) { + LOG.warn("unable to handle yangfile {}: {}", file, e); + } + } + } + for (Path addPath : this.additionalSources) { + files = addPath.toFile().list(yangFilenameFilter); + for (String file : files) { + try { + yangfile = new YangFilename(addPath.resolve(file).toString()); + if (yangfile.getModule().equals(module)) { + list.add(yangfile); + } + } catch (ParseException e) { + LOG.warn("unable to handle yangfile {}: {}", file, e); + } + } + } + return list; + } + + /** + * get yang file from source with specified version or least newer one if + * version is null then the latest one + * + * @param module + * @param version + * @return + * @throws ParseException + */ + private @Nullable YangFilename getYangFile(@Nonnull String module, @Nullable String version) throws ParseException { + YangFilename f = null; + List list = this.findYangFiles(module); + + list.sort(SortByDateAscComparator.getInstance()); + + // find specific version or nearest oldest + if (version != null) { + Date rev = YangFilename.parseRevision(version); + for (YangFilename item : list) { + if (rev.equals(item.getRevision())) { + f = item; + break; + } + if (item.getRevision().after(rev)) { + f = item; + break; + } + } + } + // get latest + else { + f = list.get(list.size() - 1); + } + return f; + } + + /** + * write filestream directly to output stream easier for http handling + * + * @param module + * @param version + * @param outputStream + * @return + * @throws IOException + * @throws ParseException + */ + public int writeOutput(@Nonnull String module, @Nullable String version, @Nonnull OutputStream outputStream) + throws IOException, ParseException { + YangFilename fn = this.getYangFile(module, version); + if(fn==null) { + return 0; + } + byte[] buffer = new byte[BUFFER_SIZE]; + int bytesRead = -1; + int sumlen = 0; + InputStream inputStream = null ; + try { + inputStream= new FileInputStream(fn.getFilename()); + + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + sumlen += bytesRead; + }} + catch(IOException e) { + LOG.warn("problem sending {}: {}",fn.getFilename(),e); + } + finally { + if(inputStream!=null) { + inputStream.close(); + } + } + return sumlen; + } + + private static class SortByDateAscComparator implements Comparator { + + private static SortByDateAscComparator instance; + + @Override + public int compare(YangFilename o1, YangFilename o2) { + return o1.getRevision().compareTo(o2.getRevision()); + } + + public static Comparator getInstance() { + if (instance == null) { + instance = new SortByDateAscComparator(); + } + return instance; + } + + } + + public YangFilename getFileForModule(String module, String rev) throws ParseException { + return this.getYangFile(module, rev); + } + + public YangFilename getFileForModule(String module) throws ParseException { + return this.getFileForModule(module, null); + } + + public boolean hasFileOrNewerForModule(String module, String version) throws ParseException { + return this.getYangFile(module, version) != null; + } + +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/YangFilename.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/YangFilename.java new file mode 100644 index 000000000..b00eb203f --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/YangFilename.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.dataprovider.data; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class YangFilename { + + private static final String regex = "([^\\/]*)@([0-9]{4}-[0-9]{2}-[0-9]{2}).yang"; + private static final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE); + private final String filename; + private final Matcher matcher; + private Date revision; + private String module; + public static Date parseRevision(String sRevision) throws ParseException { + final SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd"); + return fmt.parse(sRevision); + } + public YangFilename(String fn) throws ParseException { + this.filename = fn; + matcher = pattern.matcher(this.filename); + if(!matcher.find()) { + throw new ParseException("unknown filename format", 0); + } + this.module= matcher.group(1); + this.revision=parseRevision(matcher.group(2)); + + } + public static String createFilename(String module, String rev) { + return String.format("%s@%s.yang", module,rev); + } + public YangFilename(String module, String rev) throws ParseException { + this(createFilename(module, rev)); + } + public String getFilename() { + return this.filename; + } + public Date getRevision() { + return this.revision; + } + public String getModule() { + return this.module; + } +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/AboutHttpServlet.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/AboutHttpServlet.java new file mode 100644 index 000000000..66d21041c --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/AboutHttpServlet.java @@ -0,0 +1,224 @@ +/******************************************************************************* + * ============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.dataprovider.http; + +import java.io.IOException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.onap.ccsdk.features.sdnr.wt.common.Resources; +import org.onap.ccsdk.features.sdnr.wt.common.file.PomFile; +import org.onap.ccsdk.features.sdnr.wt.common.file.PomPropertiesFile; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AboutHttpServlet extends HttpServlet { + + /** + * + */ + private static final long serialVersionUID = 1L; + private static final Logger LOG = LoggerFactory.getLogger(AboutHttpServlet.class); + + private static final String URI_PRE = "/about"; + private static final String RES_BASEPATH = "about/"; + + private static final String PLACEHOLDER_ONAP_RELEASENAME = "{release-name}"; + private static final String PLACEHOLDER_ODL_RELEASENAME = "{odl-version}"; + private static final String PLACEHOLDER_BUILD_TIMESTAMP = "{build-time}"; + private static final String PLACEHOLDER_ODLUX_REVISION = "{odlux-revision}"; + private static final String PLACEHOLDER_PACAKGE_VERSION = "{package-version}"; + private static final String README_FILE = "README.md"; + + private final String groupId="org.onap.ccsdk.features.sdnr.wt"; + private final String artifactId="sdnr-wt-data-provider-provider"; + +// private final ConfigurationFileRepresentation configuration; + //private final ExtRestClient dbClient; + private final Map data; + private final String readmeContent; + + + + public AboutHttpServlet() { +// this.configuration = new ConfigurationFileRepresentation(DataProviderServiceImpl.CONFIGURATIONFILE); +// EsConfig esConfig = new EsConfig(configuration); + //this.dbClient = ExtRestClient.createInstance(esConfig.getHosts()); + this.data = new HashMap<>(); + this.collectStaticData(); + this.readmeContent = this.render(this.getFileContent(README_FILE)); + } + + private void collectStaticData() { + PomPropertiesFile props = this.getPomProperties(); + this.data.put(PLACEHOLDER_ONAP_RELEASENAME, this.getPomProperty("onap.distname")); + this.data.put(PLACEHOLDER_ODL_RELEASENAME, this.getPomProperty("odl.distname") ); + this.data.put(PLACEHOLDER_BUILD_TIMESTAMP, props!=null?props.getBuildDate().toString():""); + this.data.put(PLACEHOLDER_ODLUX_REVISION, this.getPomProperty("odlux.buildno")); + this.data.put(PLACEHOLDER_PACAKGE_VERSION, this.getManifestValue("Bundle-Version")); + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + + String uri = req.getRequestURI().substring(URI_PRE.length()); + LOG.debug("request for {}",uri); + if (uri.length() <= 0 || uri.equals("/")) { + // collect data + this.collectData(); + // render readme + String content = this.render(); + byte[] output = content!=null?content.getBytes():new byte[0]; + // output + resp.setStatus(HttpServletResponse.SC_OK); + resp.setContentLength(output.length); + resp.setContentType("text/plain"); + resp.getOutputStream().write(output); + + } else { + this.doGetFile(uri, resp); + } + } + + private String getFileContent(String filename) { + LOG.debug("try ti get content of {}",filename); + return Resources.getFileContent(AboutHttpServlet.class,RES_BASEPATH + filename); + } + + private void collectData() { + // TODO Auto-generated method stub + + } + + private String getManifestValue(String key) { + URL url = Resources.getUrlForRessource(AboutHttpServlet.class, "/META-INF/MANIFEST.MF"); + if(url==null) { + return null; + } + Manifest manifest; + try { + manifest = new Manifest(url.openStream()); + Attributes attr = manifest.getMainAttributes(); + return attr.getValue(key); + } catch (IOException e) { + LOG.warn("problem reading manifest: {}",e); + } + return null; + + } + private PomPropertiesFile getPomProperties() { + URL url = Resources.getUrlForRessource(AboutHttpServlet.class, "/META-INF/maven/"+groupId+"/"+artifactId+"/pom.properties"); + PomPropertiesFile propfile; + if(url==null) { + return null; + } + try { + propfile = new PomPropertiesFile(url.openStream()); + return propfile; + } catch (Exception e) { + LOG.warn("unable to read inner pom file: {}",e); + } + return null; + } + private String getPomProperty(String key) { + LOG.info("try to get pom property for {}",key); + URL url = Resources.getUrlForRessource(AboutHttpServlet.class,"/META-INF/maven/"+groupId+"/"+artifactId+"/pom.xml"); + if(url==null) { + return null; + } + PomFile pomfile; + try { + pomfile = new PomFile(url.openStream()); + return pomfile.getProperty(key); + } catch (Exception e) { + LOG.warn("unable to read inner pom file: {}",e); + } + return null; + } + private void doGetFile(String uri, HttpServletResponse resp) { + String content = this.getFileContent(uri); + if (content == null) { + try { + resp.sendError(HttpServletResponse.SC_NOT_FOUND); + } catch (IOException e) { + LOG.debug("unable to send error response : {}",e); + } + } else { + byte[] data = content.getBytes(); + resp.setStatus(HttpServletResponse.SC_OK); + resp.setContentType(this.getContentType(uri)); + try { + resp.getOutputStream().write(data); + } catch (IOException e) { + LOG.debug("unable to send data : {}",e); + } + } + + } + + private String getContentType(String filename) { + String ext = filename.substring(filename.lastIndexOf(".")+1).toLowerCase(); + switch (ext) { + case "jpg": + case "jpeg": + case "svg": + case "png": + case "gif": + case "bmp": + return "image/" + ext; + case "json": + return "application/json"; + case "html": + case "htm": + return "text/html"; + case "txt": + case "md": + default: + return "text/plain"; + } + } + + private String render() { + return this.render(null); + } + + private String render(String content) { + if (content == null) { + content = this.readmeContent; + } + if(content==null) { + return null; + } + for (Entry entry : this.data.entrySet()) { + if (entry.getValue() != null && content.contains(entry.getKey())) { + content = content.replace(entry.getKey(), entry.getValue()); + } + } + + return content; + } +} \ No newline at end of file diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/GetYangSchemaRequest.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/GetYangSchemaRequest.java new file mode 100644 index 000000000..db4faedfc --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/GetYangSchemaRequest.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * ============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.dataprovider.http; + +import javax.servlet.http.HttpServletRequest; + +public class GetYangSchemaRequest { + + private static final String URI_PREFIX = "/yang-schema/"; + private final String module; + private final String version; + + public String getModule() { + return this.module; + } + + public String getVersion() { + return this.version; + } + + public boolean hasVersion() { + return this.version != null; + } + + public GetYangSchemaRequest(HttpServletRequest req) throws Exception { + String uri = req.getRequestURI().substring(URI_PREFIX.length()); + + String[] hlp = uri.split("/"); + if (hlp.length < 1) { + throw new Exception("no module request found"); + + } else if (hlp.length == 1) { + this.module = hlp[0]; + this.version = null; + } else { + this.module = hlp[0]; + this.version = hlp[1]; + } + + } + +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/ReadyHttpServlet.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/ReadyHttpServlet.java new file mode 100644 index 000000000..607f552f6 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/ReadyHttpServlet.java @@ -0,0 +1,42 @@ +package org.onap.ccsdk.features.sdnr.wt.dataprovider.http; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ReadyHttpServlet extends HttpServlet { + + /** + * + */ + private static final long serialVersionUID = 1L; + private static final Logger LOG = LoggerFactory.getLogger(ReadyHttpServlet.class); + private boolean status; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + + if(this.isReady()) { + resp.setStatus(HttpServletResponse.SC_OK); + } + else { + + resp.sendError(HttpServletResponse.SC_NOT_FOUND); + } + } + + private boolean isReady() { + return this.status; + } + + public void setStatus(boolean status) { + this.status = status; + LOG.info("status is set to ready: {}",status); + } +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/YangSchemaHttpServlet.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/YangSchemaHttpServlet.java new file mode 100644 index 000000000..94d2793ec --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/YangSchemaHttpServlet.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * ============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.dataprovider.http; + +import java.io.IOException; +import java.text.ParseException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.YangFileProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class YangSchemaHttpServlet extends HttpServlet { + /** + * + */ + private static final long serialVersionUID = 1L; + private static final Logger LOG = LoggerFactory.getLogger(YangSchemaHttpServlet.class); + + private static final String schemaCachePath = "cache/schema/"; + + private final YangFileProvider fileProvider; + + public YangSchemaHttpServlet() { + this.fileProvider = new YangFileProvider(schemaCachePath); + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + + GetYangSchemaRequest request = null; + try { + request = new GetYangSchemaRequest(req); + } catch (Exception e) { + LOG.warn("bad request for yang-schema: {}", e); + } + if (request != null) { + int len; + LOG.debug("request for yang-schema for module {} with version {}", request.getModule(), + request.getVersion()); + if (request.hasVersion()) { + boolean has=false; + try { + has = this.fileProvider.hasFileOrNewerForModule(request.getModule(), request.getVersion()); + } catch (ParseException e1) { + LOG.warn("unable to parse revision: {}" ,e1); + } + if(has) { + + try { + resp.setStatus(HttpServletResponse.SC_OK); + resp.setContentType("text/plain"); + len = this.fileProvider.writeOutput(request.getModule(), request.getVersion(), + resp.getOutputStream()); + resp.setContentLength(len); + + } catch (ParseException e) { + LOG.warn("unable to parse revision: {}", e); + } + } else { + resp.sendError(HttpServletResponse.SC_NOT_FOUND); + } + + } else if (this.fileProvider.hasFileForModule(request.getModule())) { + + try { + resp.setStatus(HttpServletResponse.SC_OK); + resp.setContentType("text/plain"); + len = this.fileProvider.writeOutput(request.getModule(), null, resp.getOutputStream()); + resp.setContentLength(len); + } catch (ParseException e) { + LOG.warn(e.getMessage()); + } + + } else { + resp.sendError(HttpServletResponse.SC_NOT_FOUND); + } + } else { + resp.sendError(HttpServletResponse.SC_BAD_REQUEST); + } + + } + +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderImpl.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderImpl.java new file mode 100644 index 000000000..ba6e99975 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderImpl.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * ============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.dataprovider.impl; + +import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.ReadyHttpServlet; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.IEntityDataProvider; +import org.opendaylight.mdsal.binding.api.RpcProviderService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DataProviderImpl implements IEntityDataProvider, AutoCloseable { + + private static final Logger LOG = LoggerFactory.getLogger(DataProviderImpl.class); + + private static final String APPLICATION_NAME = null; + private RpcProviderService rpcProviderService = null; + private DataProviderServiceImpl rpcApiService; + private ReadyHttpServlet readyServlet; + private HtDatabaseClient dbClient; + + + // Blueprint 1 + public DataProviderImpl() { + LOG.info("Creating provider for {}", APPLICATION_NAME); + } + + public void setRpcProviderService(RpcProviderService rpcProviderService) { + this.rpcProviderService = rpcProviderService; + } + public void setReadyServlet(ReadyHttpServlet readyServlet) { + this.readyServlet = readyServlet; + } + public void init() throws Exception { + + LOG.info("Session Initiated start {}", APPLICATION_NAME); + + // Start RPC Service + this.rpcApiService = new DataProviderServiceImpl(rpcProviderService); + // Get configuration + + LOG.info("Session Initiated end. Initialization done"); + } + + @Override + public void close() throws Exception { + LOG.info("DeviceManagerImpl closing ..."); + + close(dbClient); + close(rpcApiService); + LOG.info("DeviceManagerImpl closing done"); + } + + /** + * Used to close all Services, that should support AutoCloseable Pattern + * + * @param toClose + * @throws Exception + */ + private void close(AutoCloseable... toCloseList) throws Exception { + for (AutoCloseable element : toCloseList) { + if (element != null) { + element.close(); + } + } + } + + @Override + public DataProvider getDataProvider() { + return rpcApiService.getDataProvider(); + } + + @Override + public void setReadyStatus(boolean status) { + if(this.readyServlet!=null) { + this.readyServlet.setStatus(status); + } + } +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderServiceImpl.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderServiceImpl.java new file mode 100644 index 000000000..70b735357 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderServiceImpl.java @@ -0,0 +1,335 @@ +/******************************************************************************* + * ============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.dataprovider.impl; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +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.database.config.EsConfig; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.ElasticSearchDataProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.opendaylight.mdsal.binding.api.RpcProviderService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.CreateMaintenanceInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.CreateMaintenanceOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.CreateMediatorServerInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.CreateMediatorServerOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.CreateNetworkElementConnectionInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.CreateNetworkElementConnectionOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.DataProviderService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.DeleteMaintenanceInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.DeleteMaintenanceOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.DeleteMediatorServerInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.DeleteMediatorServerOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.DeleteNetworkElementConnectionInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.DeleteNetworkElementConnectionOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadConnectionlogListInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadConnectionlogListOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadEventlogListInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadEventlogListOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadFaultcurrentListInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadFaultcurrentListOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadFaultlogListInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadFaultlogListOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadInventoryListInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadInventoryListOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadMaintenanceListInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadMaintenanceListOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadMediatorServerListInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadMediatorServerListOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadNetworkElementConnectionListInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadNetworkElementConnectionListOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadPmdata15mDeviceListInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadPmdata15mDeviceListOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadPmdata15mListInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadPmdata15mListOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadPmdata15mLtpListInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadPmdata15mLtpListOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadPmdata24hDeviceListInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadPmdata24hDeviceListOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadPmdata24hListInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadPmdata24hListOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadPmdata24hLtpListInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadPmdata24hLtpListOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadStatusInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.ReadStatusOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.UpdateMaintenanceInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.UpdateMaintenanceOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.UpdateMediatorServerInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.UpdateMediatorServerOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.UpdateNetworkElementConnectionInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.UpdateNetworkElementConnectionOutput; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.concepts.ObjectRegistration; +import org.opendaylight.yangtools.yang.binding.DataObject; +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 DataProviderServiceImpl implements DataProviderService, AutoCloseable { + + private static final Logger LOG = LoggerFactory.getLogger(DataProviderServiceImpl.class); + public static final String CONFIGURATIONFILE = "etc/dataprovider.properties"; + private static final long DATABASE_TIMEOUT_MS = 120*1000L; + + private final ObjectRegistration<@NonNull DataProviderServiceImpl> rpcReg; + private final ElasticSearchDataProvider dataProvider; + private final ConfigurationFileRepresentation configuration; + + DataProviderServiceImpl(final RpcProviderService rpcProviderService) throws Exception { + this.configuration = new ConfigurationFileRepresentation(CONFIGURATIONFILE); + EsConfig esConfig = new EsConfig(configuration); + this.dataProvider = new ElasticSearchDataProvider(esConfig.getHosts()); + this.dataProvider.waitForYellowDatabaseStatus(DATABASE_TIMEOUT_MS,TimeUnit.MILLISECONDS); + // Register ourselves as the REST API RPC implementation + LOG.info("Register RPC Service " + DataProviderServiceImpl.class.getSimpleName()); + this.rpcReg = rpcProviderService.registerRpcImplementation(DataProviderService.class, this); + } + + /** + * @return the dataProvider + */ + public DataProvider getDataProvider() { + return dataProvider.getDataProvider(); + } + + + + @Override + public void close() throws Exception { + LOG.info("Close RPC Service"); + if (rpcReg != null) { + rpcReg.close(); + } + } + + @Override + public ListenableFuture> readFaultcurrentList(ReadFaultcurrentListInput input) { + LOG.debug("RPC Request: getFaultCurrentEntityList with input {}", input); + RpcResultBuilder result = read(()-> DataProviderServiceImpl.this.dataProvider.readFaultCurrentList(input)); + return result.buildFuture(); + } + @Override + public ListenableFuture> readFaultlogList(ReadFaultlogListInput input) { + LOG.debug("RPC Request: getFaultCurrentEntityList with input {}", input); + RpcResultBuilder result = read(()-> DataProviderServiceImpl.this.dataProvider.readFaultLogList(input)); + return result.buildFuture(); + } + + @Override + public ListenableFuture> readMaintenanceList(ReadMaintenanceListInput input) { + LOG.debug("RPC Request: getMaintenanceEntityList with input {}", input); + RpcResultBuilder result = read(()-> DataProviderServiceImpl.this.dataProvider.readMaintenanceList(input)); + return result.buildFuture(); + } + + @Override + public ListenableFuture> readMediatorServerList( + ReadMediatorServerListInput input) { + LOG.debug("RPC Request: getMediatorServerEntityList with input {}", input); + RpcResultBuilder result = read(()-> DataProviderServiceImpl.this.dataProvider.readMediatorServerList(input)); + return result.buildFuture(); + } + + @Override + public ListenableFuture> readNetworkElementConnectionList( + ReadNetworkElementConnectionListInput input) { + LOG.debug("RPC Request: getNetworkElementConnectionEntityList with input {}", input); + RpcResultBuilder result = read(()-> DataProviderServiceImpl.this.dataProvider.readNetworkElementConnectionList(input)); + return result.buildFuture(); + + } + + @Override + public ListenableFuture> readPmdata15mList(ReadPmdata15mListInput input) { + LOG.debug("RPC Request: getNetworkElementConnectionEntityList with input {}", input); + RpcResultBuilder result = read(()-> DataProviderServiceImpl.this.dataProvider.readPmdata15mList(input)); + return result.buildFuture(); + + } + @Override + public ListenableFuture> readPmdata24hList(ReadPmdata24hListInput input) { + LOG.debug("RPC Request: getNetworkElementConnectionEntityList with input {}", input); + RpcResultBuilder result = read(()-> DataProviderServiceImpl.this.dataProvider.readPmdata24hList(input)); + return result.buildFuture(); + + } + @Override + public ListenableFuture> readStatus(ReadStatusInput input) { + LOG.debug("RPC Request: getStatusEntityList with input {}", input); + RpcResultBuilder result = read(()-> DataProviderServiceImpl.this.dataProvider.readStatus()); + return result.buildFuture(); + + } + + @Override + public ListenableFuture> readInventoryList(ReadInventoryListInput input) { + LOG.debug("RPC Request: getInventoryEntityList with input {}", input); + RpcResultBuilder result = read(()-> DataProviderServiceImpl.this.dataProvider.readInventoryList(input)); + return result.buildFuture(); + } + + @Override + public ListenableFuture> readPmdata15mLtpList(ReadPmdata15mLtpListInput input) { + LOG.debug("RPC Request: readPmdataLtpList with input {}", input); + RpcResultBuilder result = read(()-> DataProviderServiceImpl.this.dataProvider.readPmdata15mLtpList(input)); + return result.buildFuture(); + } + + @Override + public ListenableFuture> readPmdata15mDeviceList(ReadPmdata15mDeviceListInput input) { + LOG.debug("RPC Request: readPmdataDeviceList with input {}", input); + RpcResultBuilder result = read(()-> DataProviderServiceImpl.this.dataProvider.readPmdata15mDeviceList(input)); + return result.buildFuture(); + } + + @Override + public ListenableFuture> readPmdata24hLtpList(ReadPmdata24hLtpListInput input) { + LOG.debug("RPC Request: readPmdataLtpList with input {}", input); + RpcResultBuilder result = read(()-> DataProviderServiceImpl.this.dataProvider.readPmdata24hLtpList(input)); + return result.buildFuture(); + } + + @Override + public ListenableFuture> readPmdata24hDeviceList(ReadPmdata24hDeviceListInput input) { + LOG.debug("RPC Request: readPmdataDeviceList with input {}", input); + RpcResultBuilder result = read(()-> DataProviderServiceImpl.this.dataProvider.readPmdata24hDeviceList(input)); + return result.buildFuture(); + } + + @Override + public ListenableFuture> readConnectionlogList( + ReadConnectionlogListInput input) { + LOG.debug("RPC Request: readConnectionlogList with input {}", input); + RpcResultBuilder result = read(() -> DataProviderServiceImpl.this.dataProvider.readConnectionlogList(input)); + return result.buildFuture(); + } + + @Override + public ListenableFuture> createNetworkElementConnection( + CreateNetworkElementConnectionInput input) { + LOG.debug("RPC Request: createNetworkElementConnection with input {}", input); + RpcResultBuilder result = read(() -> DataProviderServiceImpl.this.dataProvider.createNetworkElementConnection(input)); + return result.buildFuture(); + } + + @Override + public ListenableFuture> updateNetworkElementConnection( + UpdateNetworkElementConnectionInput input) { + LOG.debug("RPC Request: updateNetworkElementConnection with input {}", input); + RpcResultBuilder result = read(() -> DataProviderServiceImpl.this.dataProvider.updateNetworkElementConnection(input)); + return result.buildFuture(); + } + + @Override + public ListenableFuture> deleteNetworkElementConnection( + DeleteNetworkElementConnectionInput input) { + RpcResultBuilder result = read(() -> DataProviderServiceImpl.this.dataProvider.deleteNetworkElementConnection(input)); + return result.buildFuture(); + } + + @Override + public ListenableFuture> deleteMediatorServer( + DeleteMediatorServerInput input) { + LOG.debug("RPC Request: deleteMediatorServer with input {}", input); + RpcResultBuilder result = read(() -> DataProviderServiceImpl.this.dataProvider.deleteMediatorServer(input)); + return result.buildFuture(); + } + + @Override + public ListenableFuture> createMediatorServer( + CreateMediatorServerInput input) { + LOG.debug("RPC Request: createMediatorServer with input {}", input); + RpcResultBuilder result = read(() -> DataProviderServiceImpl.this.dataProvider.createMediatorServer(input)); + return result.buildFuture(); + } + + @Override + public ListenableFuture> createMaintenance(CreateMaintenanceInput input) { + LOG.debug("RPC Request: createMaintenance with input {}", input); + RpcResultBuilder result = read(() -> DataProviderServiceImpl.this.dataProvider.createMaintenance(input)); + return result.buildFuture(); + } + + @Override + public ListenableFuture> deleteMaintenance(DeleteMaintenanceInput input) { + LOG.debug("RPC Request: deleteMaintenance with input {}", input); + RpcResultBuilder result = read(() -> DataProviderServiceImpl.this.dataProvider.deleteMaintenance(input)); + return result.buildFuture(); + } + + @Override + public ListenableFuture> updateMediatorServer( + UpdateMediatorServerInput input) { + LOG.debug("RPC Request: updateMediatorServer with input {}", input); + RpcResultBuilder result = read(() -> DataProviderServiceImpl.this.dataProvider.updateMediatorServer(input)); + return result.buildFuture(); + } + + @Override + public ListenableFuture> updateMaintenance(UpdateMaintenanceInput input) { + LOG.debug("RPC Request: updateMaintenance with input {}", input); + RpcResultBuilder result = read(() -> DataProviderServiceImpl.this.dataProvider.updateMaintenance(input)); + return result.buildFuture(); + } + + @Override + public ListenableFuture> readEventlogList(ReadEventlogListInput input) { + LOG.debug("RPC Request: readEventlogList with input {}", input); + RpcResultBuilder result = read(() -> DataProviderServiceImpl.this.dataProvider.readEventlogList(input)); + return result.buildFuture(); + } + + // -- private classes and functions + + private static String assembleExceptionMessage(Exception e) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + + StringBuffer buf = new StringBuffer(); + buf.append("Exception: "); + buf.append(sw.toString()); + return buf.toString(); + } + + private interface GetEntityInput { + Builder get() throws IOException; + } + + private static RpcResultBuilder read(GetEntityInput inputgetter ) { + RpcResultBuilder result; + try { + Builder outputBuilder = inputgetter.get(); + result = RpcResultBuilder.success(outputBuilder); + } catch (Exception e) { + LOG.info("Exception", e); + result = RpcResultBuilder.failed(); + result.withError(ErrorType.APPLICATION, assembleExceptionMessage(e)); + } + return result; + } + +} diff --git a/sdnr/wt/data-provider/provider/src/main/resources/about/README.md b/sdnr/wt/data-provider/provider/src/main/resources/about/README.md new file mode 100644 index 000000000..9c45d8354 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/resources/about/README.md @@ -0,0 +1,2 @@ +# About +ONAP SDN-R | ONF Wireless for ONAP {release-name} ({odl-version}) - Build: {build-time} {odlux-revision} {package-version} \ No newline at end of file diff --git a/sdnr/wt/data-provider/provider/src/main/resources/about/test.bmp b/sdnr/wt/data-provider/provider/src/main/resources/about/test.bmp new file mode 100644 index 000000000..d049ea5bc Binary files /dev/null and b/sdnr/wt/data-provider/provider/src/main/resources/about/test.bmp differ diff --git a/sdnr/wt/data-provider/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml b/sdnr/wt/data-provider/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml new file mode 100644 index 000000000..bc2e3f9cf --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestAbout.java b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestAbout.java new file mode 100644 index 000000000..e87ef9d9b --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestAbout.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * ============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.dataprovider.test; + +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.AboutHttpServlet; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.StringWriter; + +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class TestAbout { + + @Test + public void testReadmeRequest() throws IOException, ServletException { + AboutHelperServlet servlet =new AboutHelperServlet(); + HttpServletRequest request = mock(HttpServletRequest.class); + HttpServletResponse response = mock(HttpServletResponse.class); + when(request.getRequestURI()).thenReturn("/about"); + StringWriter out = new StringWriter(); + ServletOutputStream printOut = new ServletOutputStream() { + + @Override + public void write(int arg0) throws IOException { + out.write(arg0); + } + }; + when(response.getOutputStream()).thenReturn(printOut); + servlet.doGet(request,response); + verify(response).setStatus(200); + verify(response).setContentType("text/plain"); + System.out.println(out.getBuffer().toString()); + assertTrue(out.getBuffer().length()>0); + } + + @Test + public void testReadmeResourceRequest() throws IOException, ServletException { + AboutHelperServlet servlet =new AboutHelperServlet(); + HttpServletRequest request = mock(HttpServletRequest.class); + HttpServletResponse response = mock(HttpServletResponse.class); + when(request.getRequestURI()).thenReturn("/about/test.bmp"); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ServletOutputStream printOut = new ServletOutputStream() { + + @Override + public void write(int arg0) throws IOException { + out.write(arg0); + } + }; + when(response.getOutputStream()).thenReturn(printOut); + servlet.doGet(request,response); + verify(response).setStatus(200); + verify(response).setContentType("image/bmp"); + assertTrue(out.size()>0); + } + + + private class AboutHelperServlet extends AboutHttpServlet{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + super.doGet(req, resp); + } + + } +} diff --git a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestFilterConversion.java b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestFilterConversion.java new file mode 100644 index 000000000..51fe76d92 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestFilterConversion.java @@ -0,0 +1,22 @@ +package org.onap.ccsdk.features.sdnr.wt.dataprovider.test; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilder; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.QueryByFilter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.entity.input.Filter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.entity.input.FilterBuilder; + +public class TestFilterConversion { + + private static final String PROPERTY = "node-id"; + + @Test + public void testQuestionMark() { + List filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY).setFiltervalue("si?ba").build()); + QueryBuilder query = QueryByFilter.fromFilter(filters ); + System.out.println(query.toJSON()); + } +} diff --git a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestTimestampFilter.java b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestTimestampFilter.java new file mode 100644 index 000000000..c32149ba5 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestTimestampFilter.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.dataprovider.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.json.JSONObject; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilder; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.QueryByFilter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.entity.input.Filter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.entity.input.FilterBuilder; + +public class TestTimestampFilter { + + + + @Test + public void testTimestampRange() { + final String PROPERTY_TIMESTAMP = "timestamp"; + List filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2017*").build()); + QueryBuilder query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2017-01-01T00:00:00.0Z", "2018-01-01T00:00:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2000-01-01T00:00:00.0Z", "3000-01-01T00:00:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("20*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2000-01-01T00:00:00.0Z", "2100-01-01T00:00:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("205*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2050-01-01T00:00:00.0Z", "2060-01-01T00:00:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2050*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2050-01-01T00:00:00.0Z", "2051-01-01T00:00:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2050-*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2050-01-01T00:00:00.0Z", "2051-01-01T00:00:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2050-1*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2050-10-01T00:00:00.0Z", "2051-01-01T00:00:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2050-10*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2050-10-01T00:00:00.0Z", "2050-11-01T00:00:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2050-10-*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2050-10-01T00:00:00.0Z", "2050-11-01T00:00:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2050-10-0*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2050-10-01T00:00:00.0Z", "2050-10-10T00:00:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2050-10-02*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2050-10-02T00:00:00.0Z", "2050-10-03T00:00:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2050-10-14*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2050-10-14T00:00:00.0Z", "2050-10-15T00:00:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2050-10-14T*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2050-10-14T00:00:00.0Z", "2050-10-15T00:00:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2050-10-14T1*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2050-10-14T10:00:00.0Z", "2050-10-14T20:00:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2050-10-14T12*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2050-10-14T12:00:00.0Z", "2050-10-14T13:00:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2050-10-14T12:*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2050-10-14T12:00:00.0Z", "2050-10-14T13:00:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2050-10-14T12:4*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2050-10-14T12:40:00.0Z", "2050-10-14T12:50:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2050-10-14T12:42*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2050-10-14T12:42:00.0Z", "2050-10-14T12:43:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2050-10-14T12:42:*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2050-10-14T12:42:00.0Z", "2050-10-14T12:43:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2050-10-14T12:42:5*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2050-10-14T12:42:50.0Z", "2050-10-14T12:43:00.0Z"); + + filters = Arrays.asList(new FilterBuilder().setProperty(PROPERTY_TIMESTAMP).setFiltervalue("2050-10-14T12:42:56*").build()); + query= QueryByFilter.fromFilter(filters ); + assertRange(query.getInner(), PROPERTY_TIMESTAMP, "2050-10-14T12:42:56.0Z", "2050-10-14T12:42:57.0Z"); + } + private void assertRange(JSONObject rangeQuery,String property,String lower,String upper) { + System.out.println("==test for "+rangeQuery.toString()); + assertTrue(rangeQuery.has("range")); + assertTrue(rangeQuery.getJSONObject("range").has(property)); + JSONObject o=rangeQuery.getJSONObject("range").getJSONObject(property); + assertNotNull(o); + assertTrue(o.has("lt")); + assertEquals(upper, o.getString("lt")); + assertTrue(o.has("gte")); + assertEquals(lower, o.getString("gte")); + System.out.println("succeeded"); + } +} diff --git a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestYangProvider.java b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestYangProvider.java new file mode 100644 index 000000000..c911100ef --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestYangProvider.java @@ -0,0 +1,195 @@ +/******************************************************************************* + * ============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.dataprovider.test; + +import static org.junit.Assert.*; + +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.FileAttribute; +import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.PosixFilePermissions; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Comparator; +import java.util.EnumSet; +import java.util.Set; + +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.YangFileProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.YangFilename; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.YangSchemaHttpServlet; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class TestYangProvider { + + private static final String TESTPATH = "cache/schema/"; + + + @BeforeClass + public static void init() { + Set perms; + FileAttribute attr; + perms = EnumSet.noneOf(PosixFilePermission.class); + + perms.add(PosixFilePermission.OWNER_READ); + perms.add(PosixFilePermission.OWNER_WRITE); + perms.add(PosixFilePermission.OWNER_EXECUTE); + + attr = PosixFilePermissions.asFileAttribute(perms); + try { + Files.createDirectories(new File(TESTPATH).toPath(),attr); + new File(TESTPATH+new YangFilename("module1","2010-01-01").getFilename()).createNewFile(); + new File(TESTPATH+new YangFilename("module2","2010-01-01").getFilename()).createNewFile(); + new File(TESTPATH+new YangFilename("module2","2010-04-01").getFilename()).createNewFile(); + new File(TESTPATH+new YangFilename("module3","2010-01-01").getFilename()).createNewFile(); + new File(TESTPATH+new YangFilename("module4","2010-05-01").getFilename()).createNewFile(); + new File(TESTPATH+new YangFilename("module5","2010-01-11").getFilename()).createNewFile(); + new File(TESTPATH+new YangFilename("module6","2010-01-01").getFilename()).createNewFile(); + } catch (IOException | ParseException e) { + + } + } + @AfterClass + public static void deinit() { + try { + Files.walk(new File("cache").toPath()) + .sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); + } catch (IOException e) { + System.err.println(e); + } + } + @Test + public void testExisting() { + YangFileProvider provider= new YangFileProvider(TESTPATH); + assertTrue(provider.hasFileForModule("module1","2010-01-01")); + assertTrue(provider.hasFileForModule("module2")); + assertTrue(provider.hasFileForModule("module3")); + assertFalse(provider.hasFileForModule("module5","2010-01-01")); + } + @Test + public void testRevision() throws ParseException { + SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd"); + YangFileProvider provider= new YangFileProvider(TESTPATH); + YangFilename f1 = provider.getFileForModule("module1","2010-01-01"); + assertEquals("module1",f1.getModule()); + assertEquals(sdf.parse("2010-01-01"),f1.getRevision()); + YangFilename f2 = provider.getFileForModule("module2"); + assertEquals("module2",f2.getModule()); + assertEquals(sdf.parse("2010-04-01"),f2.getRevision()); + f2 = provider.getFileForModule("module2","2010-02-01"); + assertEquals("module2",f2.getModule()); + assertEquals(sdf.parse("2010-04-01"),f2.getRevision()); + YangFilename f3 = provider.getFileForModule("module3"); + assertEquals("module3",f3.getModule()); + assertEquals(sdf.parse("2010-01-01"),f3.getRevision()); + f3 = provider.getFileForModule("module3","2010-04-01"); + assertNull(f3); + } + @Test + public void testServlet() throws IOException, ServletException { + HelpYangSchemaHttpServlet servlet = new HelpYangSchemaHttpServlet(); + HttpServletRequest req = mock(HttpServletRequest.class); + HttpServletResponse resp = mock(HttpServletResponse.class); + + when(req.getRequestURI()).thenReturn("/yang-schema/module1"); + StringWriter out = new StringWriter(); + ServletOutputStream printOut = new ServletOutputStream() { + + @Override + public void write(int arg0) throws IOException { + out.write(arg0); + } + }; + when(resp.getOutputStream()).thenReturn(printOut); + servlet.doGet(req,resp); + verify(resp).setStatus(200); + verify(resp).setContentType("text/plain"); + + } + @Test + public void testServletBad() throws IOException, ServletException { + HelpYangSchemaHttpServlet servlet = new HelpYangSchemaHttpServlet(); + HttpServletRequest req = mock(HttpServletRequest.class); + HttpServletResponse resp = mock(HttpServletResponse.class); + + when(req.getRequestURI()).thenReturn("/yang-schema/module1/2020-01-01"); + StringWriter out = new StringWriter(); + ServletOutputStream printOut = new ServletOutputStream() { + + @Override + public void write(int arg0) throws IOException { + out.write(arg0); + } + }; + when(resp.getOutputStream()).thenReturn(printOut); + servlet.doGet(req,resp); + verify(resp).sendError(HttpServletResponse.SC_NOT_FOUND); + + } + @Test + public void testServletNear() throws IOException, ServletException { + HelpYangSchemaHttpServlet servlet = new HelpYangSchemaHttpServlet(); + HttpServletRequest req = mock(HttpServletRequest.class); + HttpServletResponse resp = mock(HttpServletResponse.class); + + when(req.getRequestURI()).thenReturn("/yang-schema/module2/2010-03-01"); + StringWriter out = new StringWriter(); + ServletOutputStream printOut = new ServletOutputStream() { + + @Override + public void write(int arg0) throws IOException { + out.write(arg0); + } + }; + when(resp.getOutputStream()).thenReturn(printOut); + servlet.doGet(req,resp); + verify(resp).setStatus(200); + verify(resp).setContentType("text/plain"); + + } + private static class HelpYangSchemaHttpServlet extends YangSchemaHttpServlet{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + super.doGet(req, resp); + } + } + + +} diff --git a/sdnr/wt/data-provider/provider/src/test/resources/log4j.properties b/sdnr/wt/data-provider/provider/src/test/resources/log4j.properties new file mode 100644 index 000000000..142663bd2 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/test/resources/log4j.properties @@ -0,0 +1,12 @@ +log4j.rootLogger=INFO, out + +log4j.logger.org.apache.camel.impl.converter=WARN +log4j.logger.org.apache.camel.management=WARN +log4j.logger.org.apache.camel.impl.DefaultPackageScanClassResolver=WARN +log4j.logger.org.springframework=ERROR + +# CONSOLE appender not used by default +log4j.appender.out=org.apache.log4j.ConsoleAppender +log4j.appender.out.layout=org.apache.log4j.PatternLayout +log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n + diff --git a/sdnr/wt/data-provider/provider/src/test/resources/log4j2.xml b/sdnr/wt/data-provider/provider/src/test/resources/log4j2.xml new file mode 100644 index 000000000..164e93f54 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/test/resources/log4j2.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sdnr/wt/data-provider/provider/src/test/resources/simplelogger.properties b/sdnr/wt/data-provider/provider/src/test/resources/simplelogger.properties new file mode 100644 index 000000000..a2f1e7e76 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/test/resources/simplelogger.properties @@ -0,0 +1,6 @@ +org.slf4j.simpleLogger.defaultLogLevel=debug +org.slf4j.simpleLogger.showDateTime=true +#org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z +#org.slf4j.simpleLogger.showThreadName=true +org.slf4j.simpleLogger.showLogName=true +org.slf4j.simpleLogger.showShortLogName=false \ No newline at end of file -- cgit 1.2.3-korg