From 98aeaac496ac868a97ce9096c1c51ce9a133992a Mon Sep 17 00:00:00 2001 From: Jakub Dominik Date: Thu, 14 Oct 2021 15:12:55 +0200 Subject: Extend SDNC persistent service to store CM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extend SDNC persistent service to store received CM events into Elasticsearch and MariaDB Issue-ID: CCSDK-3497 Signed-off-by: Jakub Dominik Change-Id: I39983e59ef6512ad6c3864d47aebe1d615897146 Signed-off-by: Michael DÜrre --- .../database/DatabaseDataProvider.java | 8 + .../dataprovider/database/sqldb/SqlDBConfig.java | 10 +- .../database/sqldb/data/HtUserdataManagerBase.java | 126 +++++++++++++ .../database/sqldb/data/HtUserdataManagerImpl.java | 142 +++----------- .../database/sqldb/data/SqlDBDataProvider.java | 43 ++++- .../dataprovider/database/sqldb/data/Userdata.java | 135 ++++++++++++++ .../database/sqldb/data/UserdataBuilder.java | 207 +++++++++++++++++++++ .../sqldb/data/entity/DatabaseIdGenerator.java | 8 +- .../sqldb/data/entity/HtDatabaseEventsService.java | 14 ++ .../sqldb/database/SqlDBReaderWriterUserdata.java | 37 ++++ .../database/sqldb/query/SelectQuery.java | 36 +++- .../sqldb/query/filters/DBKeyValuePair.java | 11 +- .../sqldb/query/filters/RangeSqlDBFilter.java | 12 +- .../wt/dataprovider/dblib/test/TestConfig.java | 133 +++++++++++++ .../dblib/test/TestMariaDataProvider.java | 49 +++++ .../wt/dataprovider/dblib/test/TestObjectIds.java | 7 + .../dataprovider/dblib/test/TestQuerySyntax.java | 39 ++++ .../dblib/test/util/MariaDBTestBase.java | 4 + 18 files changed, 892 insertions(+), 129 deletions(-) create mode 100644 sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/HtUserdataManagerBase.java create mode 100644 sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/Userdata.java create mode 100644 sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/UserdataBuilder.java create mode 100644 sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriterUserdata.java create mode 100644 sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestConfig.java (limited to 'sdnr/wt/data-provider/dblib') diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/DatabaseDataProvider.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/DatabaseDataProvider.java index 9d4beb71b..20b86e661 100644 --- a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/DatabaseDataProvider.java +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/DatabaseDataProvider.java @@ -5,6 +5,8 @@ * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. * All rights reserved. * ================================================================================ + * Update Copyright (C) 2021 Samsung Electronics 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 @@ -27,6 +29,7 @@ import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtDatabaseMaintenance; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtDatabaseMediatorserver; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtUserdataManager; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMaintenanceInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMaintenanceOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMediatorServerInput; @@ -40,6 +43,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.pro import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteNetworkElementConnectionOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EntityInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.NetworkElementConnectionEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadCmlogListOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadConnectionlogListOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadEventlogListOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadFaultcurrentListOutputBuilder; @@ -72,6 +76,8 @@ public interface DatabaseDataProvider { ReadFaultlogListOutputBuilder readFaultLogList(EntityInput input); + ReadCmlogListOutputBuilder readCMLogList(EntityInput input); + ReadMaintenanceListOutputBuilder readMaintenanceList(EntityInput input); ReadMediatorServerListOutputBuilder readMediatorServerList(EntityInput input); @@ -129,4 +135,6 @@ public interface DatabaseDataProvider { HtDatabaseMediatorserver getHtDatabaseMediatorServer(); + HtUserdataManager getUserManager(); + } diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/SqlDBConfig.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/SqlDBConfig.java index 8c7e7b1cb..ecf5f4e4a 100644 --- a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/SqlDBConfig.java +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/SqlDBConfig.java @@ -39,8 +39,8 @@ public class SqlDBConfig implements Configuration { private static final String DEFAULT_VALUE_DBURL = "${SDNRDBURL}"; private static final String DEFAULT_VALUE_DBUSERNAME = "${SDNRDBUSERNAME}"; private static final String DEFAULT_VALUE_DBPASSWORD = "${SDNRDBPASSWORD}"; - private static final String DEFAULT_VALUE_CONTROLLERID = DatabaseIdGenerator.getControllerId(); - private static final String DEFAULT_VALUE_DBSUFFIX = "-v6"; + private static final String DEFAULT_VALUE_CONTROLLERID = "${SDNRCONTROLLERID}"; + private static final String DEFAULT_VALUE_DBSUFFIX = "-v7"; private final ConfigurationFileRepresentation configuration; @@ -99,6 +99,12 @@ public class SqlDBConfig implements Configuration { DEFAULT_VALUE_CONTROLLERID); configuration.setPropertyIfNotAvailable(SECTION_MARKER_MARIADB, PROPERTY_KEY_DBSUFFIX, DEFAULT_VALUE_DBSUFFIX); + String v = this.configuration.getProperty(SECTION_MARKER_MARIADB, PROPERTY_KEY_CONTROLLERID); + // if is set to "null" then it is valid, otherwise if not set or env is empty generate one + if (!"null".equals(v) && (v == null || v.isEmpty())) { + this.setControllerId(DatabaseIdGenerator.getControllerId()); + } + } diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/HtUserdataManagerBase.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/HtUserdataManagerBase.java new file mode 100644 index 000000000..60f28d95c --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/HtUserdataManagerBase.java @@ -0,0 +1,126 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 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.sqldb.data; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import org.json.JSONException; +import org.json.JSONObject; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtUserdataManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class HtUserdataManagerBase implements HtUserdataManager { + + private static final Logger LOG = LoggerFactory.getLogger(HtUserdataManagerBase.class); + + private static final String USERDATA_DEFAULTS_FILENAME = "etc/userdata-defaults.json"; + private static final JSONObject USERDATA_DEFAULTS_CONTENT = loadDefaults(); + + protected static JSONObject loadDefaults() { + File f = new File(USERDATA_DEFAULTS_FILENAME); + String content; + JSONObject o = null; + if (f.exists()) { + try { + content = Files.readString(f.toPath()); + o = new JSONObject(content); + } catch (IOException e) { + LOG.warn("problem loading defaults: ", e); + } catch (JSONException e) { + LOG.warn("problem parsing defaults: ", e); + } + } + return o; + } + + protected abstract String readUserdata(String username, String defaultValue); + + @Override + public String getUserdata(String username) { + String json = this.readUserdata(username, "{}"); + if (USERDATA_DEFAULTS_CONTENT != null) { + JSONObject merge = mergeData(new JSONObject(json), USERDATA_DEFAULTS_CONTENT); + json = merge.toString(); + } + return json; + } + + @Override + public String getUserdata(String username, String key) { + JSONObject o = new JSONObject(this.getUserdata(username)); + return o.has(key) ? o.get(key).toString() : "{}"; + } + + @Override + public boolean setUserdata(String username, String key, String data) { + JSONObject o = new JSONObject(); + o.put(key, new JSONObject(data)); + return this.setUserdata(username, o.toString()); + } + + @Override + public boolean removeUserdata(String username, String key) { + JSONObject o = new JSONObject(this.getUserdata(username)); + if (o.has(key)) { + o.remove(key); + return this.setUserdata(username, o.toString()); + } + return true; + } + + protected static JSONObject mergeData(JSONObject o, String key, JSONObject subObject) { + if (!o.has(key)) { + o.put(key, subObject); + } else { + JSONObject tmp = new JSONObject(); + tmp.put(key, subObject); + o = mergeData(tmp, o); + } + return o; + } + + protected static JSONObject mergeData(JSONObject source, JSONObject target) throws JSONException { + String[] keys = JSONObject.getNames(source); + if (keys == null) { + return target; + } + for (String key : keys) { + Object value = source.get(key); + if (!target.has(key)) { + // new value for "key": + target.put(key, value); + } else { + // existing value for "key" - recursively deep merge: + if (value instanceof JSONObject) { + JSONObject valueJson = (JSONObject) value; + mergeData(valueJson, target.getJSONObject(key)); + } else { + target.put(key, value); + } + } + } + return target; + } + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/HtUserdataManagerImpl.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/HtUserdataManagerImpl.java index 9dd1adb50..79d963751 100644 --- a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/HtUserdataManagerImpl.java +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/HtUserdataManagerImpl.java @@ -21,130 +21,48 @@ */ package org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import org.json.JSONException; -import org.json.JSONObject; -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.queries.QueryBuilders; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtUserdataManager; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Entity; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class HtUserdataManagerImpl implements HtUserdataManager { - - private static final Logger LOG = LoggerFactory.getLogger(HtUserdataManagerImpl.class); - - private static final String USERDATA_DEFAULTS_FILENAME = "etc/userdata-defaults.json"; - private static final JSONObject USERDATA_DEFAULTS_CONTENT = loadDefaults(); - - private static JSONObject loadDefaults() { - File f = new File(USERDATA_DEFAULTS_FILENAME); - String content; - JSONObject o = null; - if (f.exists()) { - try { - content = Files.readString(f.toPath()); - o = new JSONObject(content); - } catch (IOException e) { - LOG.warn("problem loading defaults: ", e); - } catch (JSONException e) { - LOG.warn("problem parsing defaults: ", e); - } - } - return o; - } - - - private final HtDatabaseClient dbClient; - - public HtUserdataManagerImpl(HtDatabaseClient rawClient) { - this.dbClient = rawClient; - } - - @Override - public String getUserdata(String username) { - SearchResult result = this.dbClient.doReadByQueryJsonData(Entity.Userdata.getName(), - QueryBuilders.matchQuery("_id", username)); - String json = result.getHits().size() > 0 ? result.getHits().get(0).getSourceAsString() : "{}"; - if (USERDATA_DEFAULTS_CONTENT != null) { - JSONObject merge = mergeData(new JSONObject(json), USERDATA_DEFAULTS_CONTENT); - json = merge.toString(); - } - return json; - } - - @Override - public String getUserdata(String username, String key) { - JSONObject o = new JSONObject(this.getUserdata(username)); - return o.has(key) ? o.get(key).toString() : "{}"; +import java.util.Arrays; +import java.util.List; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.rpctypehelper.QueryResult; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBReaderWriterUserdata; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EntityInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadFaultcurrentListInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.entity.input.FilterBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.entity.input.PaginationBuilder; +import org.opendaylight.yangtools.yang.common.Uint32; +import org.opendaylight.yangtools.yang.common.Uint64; + +public class HtUserdataManagerImpl extends HtUserdataManagerBase { + + private final SqlDBReaderWriterUserdata rw; + + public HtUserdataManagerImpl(SqlDBReaderWriterUserdata rw) { + this.rw = rw; } @Override public boolean setUserdata(String username, String data) { - JSONObject o = new JSONObject(this.getUserdata(username)); - JSONObject merge = mergeData(o, new JSONObject(data)); - return this.dbClient.doWriteRaw(Entity.Userdata.getName(), username, merge.toString()) != null; - } - - @Override - public boolean setUserdata(String username, String key, String data) { - JSONObject o = new JSONObject(this.getUserdata(username)); - o = mergeData(o, key, new JSONObject(data)); - return this.dbClient.doWriteRaw(Entity.Userdata.getName(), username, o.toString()) != null; + return this.rw.write(new UserdataBuilder().setId(username).setValue(data).build(), username) != null; } @Override public boolean removeUserdata(String username) { - return this.dbClient.doRemove(Entity.Userdata.getName(), username); + return this.rw.remove(username) > 0; } @Override - public boolean removeUserdata(String username, String key) { - JSONObject o = new JSONObject(this.getUserdata(username)); - if (o.has(key)) { - o.remove(key); - return this.setUserdata(username, o.toString()); - } - return true; - } - - private static JSONObject mergeData(JSONObject o, String key, JSONObject subObject) { - if (!o.has(key)) { - o.put(key, subObject); - } else { - JSONObject tmp = new JSONObject(); - tmp.put(key, subObject); - o = mergeData(tmp, o); - } - return o; - } - - private static JSONObject mergeData(JSONObject source, JSONObject target) throws JSONException { - String[] keys = JSONObject.getNames(source); - if (keys == null) { - return target; - } - for (String key : keys) { - Object value = source.get(key); - if (!target.has(key)) { - // new value for "key": - target.put(key, value); - } else { - // existing value for "key" - recursively deep merge: - if (value instanceof JSONObject) { - JSONObject valueJson = (JSONObject) value; - mergeData(valueJson, target.getJSONObject(key)); - } else { - target.put(key, value); - } - } + protected String readUserdata(String username, String defaultValue) { + EntityInput input = new ReadFaultcurrentListInputBuilder() + .setFilter(Arrays.asList(new FilterBuilder().setProperty("id").setFiltervalue(username).build())) + .setPagination(new PaginationBuilder().setPage(Uint64.valueOf(1)).setSize(Uint32.valueOf(1)).build()) + .build(); + QueryResult result = this.rw.getData(input); + if (result != null) { + List data = result.getResult(); + Userdata user = (data != null && !data.isEmpty()) ? data.get(0) : null; + return user == null ? defaultValue : user.getValue(); } - return target; + return defaultValue; } } diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlDBDataProvider.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlDBDataProvider.java index 4165c85a0..b6df73b89 100644 --- a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlDBDataProvider.java +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlDBDataProvider.java @@ -5,6 +5,8 @@ * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. * All rights reserved. * ================================================================================ + * Update Copyright (C) 2021 Samsung Electronics 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 @@ -33,11 +35,13 @@ import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.entity.H import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.entity.HtDatabaseMaintenanceService; import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.rpctypehelper.QueryResult; import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBReaderWriter; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBReaderWriterUserdata; import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBStatusReader; import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.DeleteQuery; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtDatabaseMaintenance; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtDatabaseMediatorserver; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtUserdataManager; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMaintenanceInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMaintenanceOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMediatorServerInput; @@ -54,6 +58,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.pro import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.MaintenanceEntity; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.MediatorServerEntity; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.NetworkElementConnectionEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadCmlogListOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadConnectionlogListOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadEventlogListOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadFaultcurrentListOutputBuilder; @@ -95,6 +100,8 @@ public class SqlDBDataProvider extends HtDatabaseEventsService implements Databa private final SqlDBReaderWriter mediatorserverRW; private final SqlDBReaderWriter maintenanceRW; private final SqlDBStatusReader readStatus; + private final HtUserdataManager usermanager; + public SqlDBReaderWriter getMaintenanceReaderWriter() { return this.maintenanceRW; @@ -107,6 +114,7 @@ public class SqlDBDataProvider extends HtDatabaseEventsService implements Databa public SqlDBDataProvider(SqlDBConfig config) { this(config, true); } + public SqlDBDataProvider(SqlDBConfig config, boolean initControllerId) { super(config); @@ -128,7 +136,9 @@ public class SqlDBDataProvider extends HtDatabaseEventsService implements Databa } }; this.dbMaintenanceService = new HtDatabaseMaintenanceService(this); - if(initControllerId) { + this.usermanager = new HtUserdataManagerImpl(new SqlDBReaderWriterUserdata(this.dbClient, + Entity.Userdata, config.getDbSuffix(), this.dbClient.getDatabaseName(), this.controllerId)); + if (initControllerId) { try { this.setControllerId(); } catch (SQLException e) { @@ -168,6 +178,19 @@ public class SqlDBDataProvider extends HtDatabaseEventsService implements Databa return outputBuilder; } + @Override + public ReadCmlogListOutputBuilder readCMLogList(EntityInput input) { + ReadCmlogListOutputBuilder outputBuilder = new ReadCmlogListOutputBuilder(); + QueryResult + result = + this.eventRWCMLog.getData(input); + outputBuilder.setData(result.getResult()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.cmlog.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + @Override public ReadMaintenanceListOutputBuilder readMaintenanceList(EntityInput input) { ReadMaintenanceListOutputBuilder outputBuilder = new ReadMaintenanceListOutputBuilder(); @@ -480,18 +503,17 @@ public class SqlDBDataProvider extends HtDatabaseEventsService implements Databa return true; } LOG.info("set controllerId {}", this.controllerId); - String query = String.format("SELECT * FROM `%s` WHERE `id`='%s';", this.controllerTableName, - this.controllerId); + String query = + String.format("SELECT * FROM `%s` WHERE `id`='%s';", this.controllerTableName, this.controllerId); LOG.trace(query); ResultSet data = this.dbClient.read(query); - if (!data.next()) { - query = String.format("INSERT INTO `%s` (`id`,`desc`) VALUES ('%s','%s')", - this.controllerTableName, this.controllerId, ""); + if (data == null || !data.next()) { + query = String.format("INSERT INTO `%s` (`id`,`desc`) VALUES ('%s','%s')", this.controllerTableName, + this.controllerId, ""); LOG.trace(query); return this.dbClient.write(query); - } - else { + } else { LOG.trace("controllerId already set"); } return true; @@ -505,5 +527,10 @@ public class SqlDBDataProvider extends HtDatabaseEventsService implements Databa return this.controllerId; } + @Override + public HtUserdataManager getUserManager() { + return this.usermanager; + } + } diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/Userdata.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/Userdata.java new file mode 100644 index 000000000..658b112bd --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/Userdata.java @@ -0,0 +1,135 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 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.sqldb.data; + +import com.google.common.base.MoreObjects; +import java.util.Objects; +import javax.annotation.processing.Generated; +import org.opendaylight.yangtools.yang.binding.Augmentable; +import org.opendaylight.yangtools.yang.binding.CodeHelpers; +import org.opendaylight.yangtools.yang.binding.DataObject; + +/** + * + *

+ * This class represents the following YANG schema fragment defined in module data-provider + * + *

+ * container userdata {
+ *   leaf id {
+ *     type string;
+ *   }
+ *   leaf value {
+ *     type string;
+ *   }
+ * }
+ * 
+ * + * The schema path to identify an instance is data-provider/userdata + * + *

+ * To create instances of this class use {@link UserdataBuilder}. + * + * @see UserdataBuilder + * + */ +@Generated("mdsal-binding-generator") +public interface Userdata extends Augmentable, DataObject { + + /** + * Default implementation of {@link Object#hashCode()} contract for this interface. Implementations of this + * interface are encouraged to defer to this method to get consistent hashing results across all implementations. + * + * @param obj Object for which to generate hashCode() result. + * @return Hash code value of data modeled by this interface. + * @throws NullPointerException if {@code obj} is null + */ + static int bindingHashCode(final Userdata obj) { + final int prime = 31; + int result = 1; + result = prime * result + Objects.hashCode(obj.getId()); + result = prime * result + Objects.hashCode(obj.getValue()); + result = prime * result + obj.augmentations().hashCode(); + return result; + } + + /** + * Default implementation of {@link Object#equals(Object)} contract for this interface. Implementations of this + * interface are encouraged to defer to this method to get consistent equality results across all implementations. + * + * @param thisObj Object acting as the receiver of equals invocation + * @param obj Object acting as argument to equals invocation + * @return True if thisObj and obj are considered equal + * @throws NullPointerException if {@code thisObj} is null + */ + static boolean bindingEquals(final Userdata thisObj, final Object obj) { + if (thisObj == obj) { + return true; + } + final Userdata other = CodeHelpers.checkCast(Userdata.class, obj); + if (other == null) { + return false; + } + if (!Objects.equals(thisObj.getId(), other.getId())) { + return false; + } + if (!Objects.equals(thisObj.getValue(), other.getValue())) { + return false; + } + return thisObj.augmentations().equals(other.augmentations()); + } + + /** + * Default implementation of {@link Object#toString()} contract for this interface. Implementations of this + * interface are encouraged to defer to this method to get consistent string representations across all + * implementations. + * + * @param obj Object for which to generate toString() result. + * @return {@link String} value of data modeled by this interface. + * @throws NullPointerException if {@code obj} is null + */ + static String bindingToString(final Userdata obj) { + final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper("Userdata"); + CodeHelpers.appendValue(helper, "id", obj.getId()); + CodeHelpers.appendValue(helper, "value", obj.getValue()); + CodeHelpers.appendValue(helper, "augmentation", obj.augmentations().values()); + return helper.toString(); + } + + /** + * Return id, or {@code null} if it is not present. + * + * @return {@code java.lang.String} id, or {@code null} if it is not present. + * + */ + String getId(); + + /** + * Return value, or {@code null} if it is not present. + * + * @return {@code java.lang.String} value, or {@code null} if it is not present. + * + */ + String getValue(); + +} + diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/UserdataBuilder.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/UserdataBuilder.java new file mode 100644 index 000000000..bb1268cc9 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/UserdataBuilder.java @@ -0,0 +1,207 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 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.sqldb.data; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import javax.annotation.processing.Generated; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.AbstractAugmentable; +import org.opendaylight.yangtools.yang.binding.Augmentation; +import org.opendaylight.yangtools.yang.binding.DataObject; + +/** + * Class that builds {@link UserdataBuilder} instances. Overall design of the class is that of a + * fluent interface, where method chaining is used. + * + *

+ * In general, this class is supposed to be used like this template: + * + *

+ *   
+ *     UserdataBuilder createTarget(int fooXyzzy, int barBaz) {
+ *         return new UserdataBuilderBuilder()
+ *             .setFoo(new FooBuilder().setXyzzy(fooXyzzy).build())
+ *             .setBar(new BarBuilder().setBaz(barBaz).build())
+ *             .build();
+ *     }
+ *   
+ * 
+ * + *

+ * This pattern is supported by the immutable nature of UserdataBuilder, as instances can be freely passed around + * without worrying about synchronization issues. + * + *

+ * As a side note: method chaining results in: + *

    + *
  • very efficient Java bytecode, as the method invocation result, in this case the Builder reference, is on the + * stack, so further method invocations just need to fill method arguments for the next method invocation, which is + * terminated by {@link #build()}, which is then returned from the method
  • + *
  • better understanding by humans, as the scope of mutable state (the builder) is kept to a minimum and is very + * localized
  • + *
  • better optimization oportunities, as the object scope is minimized in terms of invocation (rather than method) + * stack, making escape analysis a lot easier. Given enough + * compiler (JIT/AOT) prowess, the cost of th builder object can be completely eliminated
  • + *
+ * + * @see UserdataBuilder + * @see Builder + * + */ +@Generated("mdsal-binding-generator") +public class UserdataBuilder implements Builder { + + private String _id; + private String _value; + + + Map>, Augmentation> augmentation = Collections.emptyMap(); + + public UserdataBuilder() {} + + + + public UserdataBuilder(Userdata base) { + Map>, Augmentation> aug = base.augmentations(); + if (!aug.isEmpty()) { + this.augmentation = new HashMap<>(aug); + } + this._id = base.getId(); + this._value = base.getValue(); + } + + + public String getId() { + return _id; + } + + public String getValue() { + return _value; + } + + @SuppressWarnings({"unchecked", "checkstyle:methodTypeParameterName"}) + public > E$$ augmentation(Class augmentationType) { + return (E$$) augmentation.get(Objects.requireNonNull(augmentationType)); + } + + + public UserdataBuilder setId(final String value) { + this._id = value; + return this; + } + + public UserdataBuilder setValue(final String value) { + this._value = value; + return this; + } + + /** + * Add an augmentation to this builder's product. + * + * @param augmentation augmentation to be added + * @return this builder + * @throws NullPointerException if {@code augmentation} is null + */ + public UserdataBuilder addAugmentation(Augmentation augmentation) { + Class> augmentationType = augmentation.implementedInterface(); + if (!(this.augmentation instanceof HashMap)) { + this.augmentation = new HashMap<>(); + } + + this.augmentation.put(augmentationType, augmentation); + return this; + } + + /** + * Remove an augmentation from this builder's product. If this builder does not track such an augmentation type, + * this method does nothing. + * + * @param augmentationType augmentation type to be removed + * @return this builder + */ + public UserdataBuilder removeAugmentation(Class> augmentationType) { + if (this.augmentation instanceof HashMap) { + this.augmentation.remove(augmentationType); + } + return this; + } + + @Override + public Userdata build() { + return new UserdataImpl(this); + } + + private static final class UserdataImpl extends AbstractAugmentable implements Userdata { + + private final String _id; + private final String _value; + + UserdataImpl(UserdataBuilder base) { + super(base.augmentation); + this._id = base.getId(); + this._value = base.getValue(); + } + + @Override + public String getId() { + return _id; + } + + @Override + public String getValue() { + return _value; + } + + private int hash = 0; + private volatile boolean hashValid = false; + + @Override + public int hashCode() { + if (hashValid) { + return hash; + } + + final int result = Userdata.bindingHashCode(this); + hash = result; + hashValid = true; + return result; + } + + @Override + public boolean equals(Object obj) { + return Userdata.bindingEquals(this, obj); + } + + @Override + public String toString() { + return Userdata.bindingToString(this); + } + + @Override + public Class implementedInterface() { + return Userdata.class; + } + } +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/DatabaseIdGenerator.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/DatabaseIdGenerator.java index 2b07dfae2..6244894e5 100644 --- a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/DatabaseIdGenerator.java +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/DatabaseIdGenerator.java @@ -60,7 +60,7 @@ public class DatabaseIdGenerator { return UUID.randomUUID().toString(); } - public static String getFaultcurrentId(String nodeId, String objectId, String problemName) { + public static String extractUuid(String objectId) { String uuId; Matcher matcher = FAULTPATTERN.matcher(objectId); @@ -69,6 +69,12 @@ public class DatabaseIdGenerator { } else { uuId = objectId; } + return uuId; + } + + public static String getFaultcurrentId(String nodeId, String objectId, String problemName) { + String uuId = extractUuid(objectId); + return String.format(FORMAT_FAULTDATA_ID, nodeId, uuId, problemName); } diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/HtDatabaseEventsService.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/HtDatabaseEventsService.java index 84786b0cd..88aaa583d 100644 --- a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/HtDatabaseEventsService.java +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/HtDatabaseEventsService.java @@ -5,6 +5,8 @@ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. * All rights reserved. * ================================================================================ + * Update Copyright (C) 2021 Samsung Electronics 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 @@ -37,6 +39,7 @@ import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlD import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.NetconfTimeStamp; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CmlogEntity; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ConnectionlogEntity; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Entity; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogEntity; @@ -73,6 +76,7 @@ public class HtDatabaseEventsService implements DataProvider { protected final SqlDBReaderWriter networkelementConnectionRW; protected final SqlDBReaderWriterPm pm15mRW; protected final SqlDBReaderWriterPm pm24hRW; + protected final SqlDBReaderWriter eventRWCMLog; protected final String controllerTableName; public HtDatabaseEventsService(SqlDBConfig config) { @@ -117,6 +121,10 @@ public class HtDatabaseEventsService implements DataProvider { org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.pmdata._24h.list.output.Data.class, this.dbClient.getDatabaseName(), this.controllerId); + this.eventRWCMLog = new SqlDBReaderWriter<>(dbClient, Entity.Cmlog, config.getDbSuffix(), + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.cmlog.list.output.Data.class, + this.dbClient.getDatabaseName(), this.controllerId); + } @Override @@ -135,6 +143,11 @@ public class HtDatabaseEventsService implements DataProvider { this.eventRWFaultLog.write(fault, fault.getId()); } + @Override + public void writeCMLog(CmlogEntity cm) { + this.eventRWCMLog.write(cm, cm.getId()); + } + @Override public void updateFaultCurrent(FaultcurrentEntity fault) { final String id = fault.getId() != null ? fault.getId() : DatabaseIdGenerator.getFaultcurrentId(fault); @@ -220,6 +233,7 @@ public class HtDatabaseEventsService implements DataProvider { removed += this.eventlogRW.remove(filter); removed += this.eventRWFaultLog.remove(filter); + removed += this.eventRWCMLog.remove(filter); return removed; } diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriterUserdata.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriterUserdata.java new file mode 100644 index 000000000..2c849ac67 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriterUserdata.java @@ -0,0 +1,37 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 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.sqldb.database; + +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.SqlDBClient; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.Userdata; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Entity; + +public class SqlDBReaderWriterUserdata extends SqlDBReaderWriter { + + public SqlDBReaderWriterUserdata(SqlDBClient dbService, Entity e, String dbSuffix, String dbName, + String controllerId) { + super(dbService, e, dbSuffix, Userdata.class, dbName, controllerId); + } + + + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/SelectQuery.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/SelectQuery.java index 6afcae077..2b3f9f3fa 100644 --- a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/SelectQuery.java +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/SelectQuery.java @@ -25,6 +25,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import org.eclipse.jdt.annotation.Nullable; import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBMapper; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EntityInput; @@ -35,9 +36,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.pro import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.entity.input.Pagination; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.entity.input.Sortorder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.entity.input.SortorderKey; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class SelectQuery implements SqlQuery { + private static final Logger LOG = LoggerFactory.getLogger(SelectQuery.class); + private static final long DEFAULT_PAGESIZE = 20; private static final long DEFAULT_PAGE = 1; private final String tableName; @@ -78,7 +83,7 @@ public class SelectQuery implements SqlQuery { Map filter = input != null ? input.getFilter() : null; if (filter != null && filter.size() > 0) { for (Filter f : filter.values()) { - this.addFilter(f.getProperty(), f.getFiltervalue()); + this.addFilter(f); } } if (controllerId != null) { @@ -101,8 +106,35 @@ public class SelectQuery implements SqlQuery { } public void addFilter(String property, String filtervalue) { - this.filters.add(new FilterBuilder().setProperty(property).setFiltervalue(filtervalue).build()); + this.addFilter(new FilterBuilder().setProperty(property).setFiltervalue(filtervalue).build()); + } + private static Filter cleanFilter(Filter filter) { + if (filter.getFiltervalue() != null + && (filter.getFiltervalues() == null || filter.getFiltervalues().isEmpty())) { + return "*".equals(filter.getFiltervalue()) ? null : filter; + } else { + List list = new ArrayList<>(filter.getFiltervalues()); + if (filter.getFiltervalue() != null && !filter.getFiltervalue().isEmpty()) { + list.add(filter.getFiltervalue()); + } + if (list.size() == 1 && "*".equals(list.get(0))) { + return null; + } ; + return new FilterBuilder().setProperty(filter.getProperty()).setFiltervalue(filter.getFiltervalue()) + .setFiltervalues( + filter.getFiltervalues().stream().filter(e -> !"*".equals(e)).collect(Collectors.toList())) + .build(); + } + } + + public void addFilter(Filter filter) { + Filter tmp = cleanFilter(filter); + if (tmp == null) { + LOG.debug("ignore unneccessary filter for {}", filter); + } else { + this.filters.add(tmp); + } } public void addSortOrder(String col, String order) { diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/DBKeyValuePair.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/DBKeyValuePair.java index 1dd9516e6..70b683a1a 100644 --- a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/DBKeyValuePair.java +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/DBKeyValuePair.java @@ -52,8 +52,15 @@ public class DBKeyValuePair implements SqlDBFilter { @Override public String getFilterExpression() { - if (isNumericValue(this.value)) { - return String.format("`%s`=%d", this.key, this.value); + // remove isNumericValue and add cast to remove sonar issue + if (this.getValue() instanceof Long) { + return String.format("`%s`=%d", this.key, (Long)this.value); + } else if (this.getValue() instanceof Integer) { + return String.format("`%s`=%d", this.key, (Integer)this.value); + } else if (this.getValue() instanceof Byte) { + return String.format("`%s`=%d", this.key, (Byte)this.value); + } else if (this.getValue() instanceof BigInteger) { + return String.format("`%s`=%d", this.key, (BigInteger)this.value); } else { return String.format("`%s`='%s'", this.key, this.value); } diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/RangeSqlDBFilter.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/RangeSqlDBFilter.java index c4a5d8abc..83cd94964 100644 --- a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/RangeSqlDBFilter.java +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/RangeSqlDBFilter.java @@ -21,6 +21,7 @@ */ package org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.filters; +import java.math.BigInteger; import org.eclipse.jdt.annotation.Nullable; public class RangeSqlDBFilter extends DBKeyValuePair implements SqlDBFilter { @@ -34,8 +35,15 @@ public class RangeSqlDBFilter extends DBKeyValuePair implements SqlDBFil @Override public String getFilterExpression() { - if (isNumericValue(this.getValue())) { - return String.format("`%s`%s%d", this.getKey(), this.comparator, this.getValue()); + // remove isNumericValue and add cast to remove sonar issue + if (this.getValue() instanceof Long) { + return String.format("`%s`%s%d", this.getKey(), this.comparator, (Long)this.getValue()); + } else if (this.getValue() instanceof Integer) { + return String.format("`%s`%s%d", this.getKey(), this.comparator, (Integer)this.getValue()); + } else if (this.getValue() instanceof Byte) { + return String.format("`%s`%s%d", this.getKey(), this.comparator, (Byte)this.getValue()); + } else if (this.getValue() instanceof BigInteger) { + return String.format("`%s`%s%d", this.getKey(), this.comparator, (BigInteger)this.getValue()); } else { return String.format("`%s`%s'%s'", this.getKey(), this.comparator, this.getValue()); } diff --git a/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestConfig.java b/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestConfig.java new file mode 100644 index 000000000..676be4178 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestConfig.java @@ -0,0 +1,133 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 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.dblib.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import com.google.common.io.Files; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +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.common.configuration.subtypes.Section; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.subtypes.Section.EnvGetter; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.SqlDBConfig; + +public class TestConfig { + + + private static final String TEST_CONFIG1 = "test.properties"; + private static final String TEST_CONFIG2 = "test2.properties"; + private static final String TEST_CONFIG3 = "test3.properties"; + protected static final String SDNR_CONTROLLERID_ENV_VALUE = "903f3091-24f6-11ec-9cc3-0242ac130003"; + private static final String CONTENT_CONTROLLER_NULL = "dbType=${SDNRDBTYPE}\n" + + "\n" + + "[mariadb]\n" + + "url=${SDNRDBURL}\n" + + "username=${SDNRDBUSERNAME}\n" + + "password=${SDNRDBPASSWORD}\n" + + "controllerId=null\n" + + "suffix=-v6"; + + @Test + public void testEnvControllerId() { + + ConfigurationFileRepresentation cfg = new ConfigurationFileRepresentation(TEST_CONFIG1); + Section.setEnvGetter(new EnvGetter() { + + @Override + public String getenv(String substring) { + if("SDNRCONTROLLERID".equals(substring)) { + return SDNR_CONTROLLERID_ENV_VALUE; + } + return ""; + } + }); + SqlDBConfig config = new SqlDBConfig(cfg); + assertEquals(SDNR_CONTROLLERID_ENV_VALUE, config.getControllerId()); + } + + @Test + public void testGeneratedControllerId() { + ConfigurationFileRepresentation cfg = new ConfigurationFileRepresentation(TEST_CONFIG2); + Section.setEnvGetter(new EnvGetter() { + + @Override + public String getenv(String substring) { + return ""; + } + }); + SqlDBConfig config = new SqlDBConfig(cfg); + final String controllerId = config.getControllerId(); + assertNotNull(controllerId); + assertFalse(controllerId.isBlank()); + final String controllerId2 = config.getControllerId(); + assertEquals(controllerId, controllerId2); + } + + @Test + public void testNullControllerId() throws IOException { + Files.asCharSink(new File(TEST_CONFIG3), StandardCharsets.UTF_8).write(CONTENT_CONTROLLER_NULL); + ConfigurationFileRepresentation cfg = new ConfigurationFileRepresentation(TEST_CONFIG3); + Section.setEnvGetter(new EnvGetter() { + + @Override + public String getenv(String substring) { + return ""; + } + }); + SqlDBConfig config = new SqlDBConfig(cfg); + final String controllerId = config.getControllerId(); + assertNull(controllerId); + final String controllerId2 = config.getControllerId(); + assertNull(controllerId2); + } + + @Before + @After + public void after() throws InterruptedException, IOException { + + delete(new File(TEST_CONFIG1)); + delete(new File(TEST_CONFIG2)); + delete(new File(TEST_CONFIG3)); + + } + + private static void delete(File f) throws IOException { + if (f.isDirectory()) { + for (File c : f.listFiles()) { + delete(c); + } + } + if (f.exists()) { + if (!f.delete()) { + throw new FileNotFoundException("Failed to delete file: " + f); + } + } + } +} diff --git a/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestMariaDataProvider.java b/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestMariaDataProvider.java index da7450089..b4e0584b0 100644 --- a/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestMariaDataProvider.java +++ b/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestMariaDataProvider.java @@ -5,6 +5,8 @@ * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. * All rights reserved. * ================================================================================ + * Update Copyright (C) 2021 Samsung Electronics 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 @@ -43,6 +45,10 @@ import org.onap.ccsdk.features.sdnr.wt.dataprovider.dblib.test.util.MariaDBTestB import org.onap.ccsdk.features.sdnr.wt.yang.mapper.YangToolsMapper; import org.opendaylight.netconf.shaded.sshd.common.util.io.IoUtils; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CmNotificationType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CmSourceIndicator; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CmlogBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CmlogEntity; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ConnectionLogStatus; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ConnectionlogBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ConnectionlogEntity; @@ -70,6 +76,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.pro import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.NetworkElementConnectionEntity; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.NetworkElementDeviceType; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.PmdataEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadCmlogListOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadConnectionlogListOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadEventlogListOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadFaultcurrentListInputBuilder; @@ -113,6 +120,7 @@ public class TestMariaDataProvider { private static final String URI1 = "http://localhost:8181"; private static final String URI2 = "http://localhost:8181"; private static final String URI3 = "http://localhost:8181"; + private static final String PATH = "https://samsung.com/3GPP/simulation/network-function/ves"; private static MariaDBTestBase testBase; private static SqlDBDataProvider dbProvider; private static SqlDBClient dbClient; @@ -198,6 +206,47 @@ public class TestMariaDataProvider { assertEquals(2, faultlogs.getData().size()); } + @Test + public void testCMlog() { + ReadCmlogListOutputBuilder cmlogs = dbProvider.readCMLogList(createInput(1, 20)); + assertEquals(0, cmlogs.getData().size()); + + CmlogEntity cm1 = new CmlogBuilder() + .setNodeId(NODEID2) + .setCounter(1) + .setTimestamp(DateAndTime.getDefaultInstance(TIME1)) + .setObjectId("obj") + .setNotificationType(CmNotificationType.NotifyMOIChanges) + .setNotificationId("1") + .setSourceIndicator(CmSourceIndicator.MANAGEMENTOPERATION) + .setPath(PATH) + .setValue("pnf-registration: true") + .build(); + CmlogEntity cm2 = new CmlogBuilder() + .setNodeId(NODEID2) + .setCounter(2) + .setTimestamp(DateAndTime.getDefaultInstance(TIME2)) + .setObjectId("obj") + .setNotificationType(CmNotificationType.NotifyMOIChanges) + .setNotificationId("2") + .setSourceIndicator(CmSourceIndicator.UNKNOWN) + .setPath(PATH) + .setValue("pnf-registration: false") + .build(); + + dbProvider.writeCMLog(cm1); + dbProvider.writeCMLog(cm2); + cmlogs = dbProvider.readCMLogList(createInput("node-id", NODEID2, 1, 20)); + assertEquals(2, cmlogs.getData().size()); + + List cmLogEntityList = List.of(cm1, cm2); + assertEquals("node2",cmLogEntityList.get(0).getNodeId()); + assertEquals("obj",cmLogEntityList.get(0).getObjectId()); + assertEquals(CmNotificationType.NotifyMOIChanges,cmLogEntityList.get(0).getNotificationType()); + assertEquals("2",cmLogEntityList.get(1).getNotificationId()); + + } + @Test public void testConnectionlog() { try { diff --git a/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestObjectIds.java b/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestObjectIds.java index 7a37345f2..2316e444a 100644 --- a/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestObjectIds.java +++ b/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestObjectIds.java @@ -22,6 +22,8 @@ package org.onap.ccsdk.features.sdnr.wt.dataprovider.dblib.test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + import org.junit.Test; import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.entity.DatabaseIdGenerator; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl; @@ -49,6 +51,11 @@ public class TestObjectIds { @Test public void testGenerator() { + assertEquals(FAULTCURRENTID1, DatabaseIdGenerator.getFaultcurrentId(NODEID1, "toto[layerProtocol="+OBJECTID1+"]", PROBLEMNAME1)); + assertEquals(FAULTCURRENTID1, DatabaseIdGenerator.getFaultcurrentId(NODEID1, "[layerProtocol="+OBJECTID1+"]", PROBLEMNAME1)); + assertEquals(FAULTCURRENTID1, DatabaseIdGenerator.getFaultcurrentId(NODEID1, "[layerPtoto[layerProtocol="+OBJECTID1+"]", PROBLEMNAME1)); + assertNotEquals(FAULTCURRENTID1, DatabaseIdGenerator.getFaultcurrentId(NODEID1, "[layerProtocol="+OBJECTID1+"]aaa", PROBLEMNAME1)); + assertEquals(FAULTCURRENTID1, DatabaseIdGenerator.getFaultcurrentId(NODEID1, OBJECTID1, PROBLEMNAME1)); assertEquals(INVENTORY_ID1, DatabaseIdGenerator .getInventoryId(new InventoryBuilder().setNodeId(NODEID1).setUuid(EQUIPMENT_UUID1).build())); diff --git a/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestQuerySyntax.java b/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestQuerySyntax.java index 758b72f9c..24347c7db 100644 --- a/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestQuerySyntax.java +++ b/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestQuerySyntax.java @@ -21,16 +21,22 @@ */ package org.onap.ccsdk.features.sdnr.wt.dataprovider.dblib.test; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; import org.junit.Test; import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.SelectQuery; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EntityInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadEventlogListInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadGuiCutThroughEntryInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.entity.input.Filter; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.entity.input.FilterBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.entity.input.FilterKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.entity.input.PaginationBuilder; +import org.opendaylight.yangtools.yang.common.Uint32; +import org.opendaylight.yangtools.yang.common.Uint64; public class TestQuerySyntax { @@ -154,4 +160,37 @@ public class TestQuerySyntax { final String sql = query.toSql(); assertTrue(sql.contains("`timestamp`<='2022-01-01 00:00:00.000'")); } + + @Test + public void testSelectForFilterValues() { + EntityInput input = new ReadGuiCutThroughEntryInputBuilder() + .setFilter(Arrays.asList( + new FilterBuilder().setProperty("id").setFiltervalues(Arrays.asList("das", "das2")).build())) + .setPagination(new PaginationBuilder().setSize(Uint32.valueOf(20)).setPage(Uint64.valueOf(1)).build()) + .build(); + SelectQuery query = new SelectQuery(TABLENAME1, input, CONTROLLERID); + System.out.println(query.toSql()); + } + @Test + public void testSelectForFilterValues2() { + EntityInput input = new ReadGuiCutThroughEntryInputBuilder() + .setFilter(Arrays.asList( + new FilterBuilder().setProperty("id").setFiltervalue("*").build())) + .setPagination(new PaginationBuilder().setSize(Uint32.valueOf(20)).setPage(Uint64.valueOf(1)).build()) + .build(); + SelectQuery query = new SelectQuery(TABLENAME1, input, CONTROLLERID); + System.out.println(query.toSql()); + assertFalse(query.toSql().contains("RLIKE")); + } + @Test + public void testSelectForFilterValues3() { + EntityInput input = new ReadGuiCutThroughEntryInputBuilder() + .setFilter(Arrays.asList( + new FilterBuilder().setProperty("id").setFiltervalues(Arrays.asList("*","abc")).build())) + .setPagination(new PaginationBuilder().setSize(Uint32.valueOf(20)).setPage(Uint64.valueOf(1)).build()) + .build(); + SelectQuery query = new SelectQuery(TABLENAME1, input, CONTROLLERID); + System.out.println(query.toSql()); + assertFalse(query.toSql().contains("RLIKE")); + } } diff --git a/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/util/MariaDBTestBase.java b/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/util/MariaDBTestBase.java index b065519f8..3360d3ed8 100644 --- a/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/util/MariaDBTestBase.java +++ b/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/util/MariaDBTestBase.java @@ -5,6 +5,8 @@ * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. * All rights reserved. * ================================================================================ + * Update Copyright (C) 2021 Samsung Electronics 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 @@ -34,6 +36,7 @@ import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.SqlDBConfig; import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.SqlDBDataProvider; import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBMapper; import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBMapper.UnableToMapClassException; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CmlogEntity; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ConnectionlogEntity; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Entity; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogEntity; @@ -163,6 +166,7 @@ public class MariaDBTestBase { createTable(dbService, FaultcurrentEntity.class, Entity.Faultcurrent, false); createTable(dbService, FaultlogEntity.class, Entity.Faultlog, true); createTable(dbService, GuicutthroughEntity.class, Entity.Guicutthrough, false); + createTable(dbService, CmlogEntity.class, Entity.Cmlog, true); createTable(dbService, Pmdata15mEntity.class, Entity.Historicalperformance15min, false); createTable(dbService, Pmdata24hEntity.class, Entity.Historicalperformance24h, false); createTable(dbService, InventoryEntity.class, Entity.Inventoryequipment, false); -- cgit 1.2.3-korg