diff options
author | KAPIL SINGAL <ks220y@att.com> | 2021-07-30 01:55:03 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2021-07-30 01:55:03 +0000 |
commit | e4f3ee3ce9264c6ca41928e49c3075d4ca99eb0f (patch) | |
tree | 29a4875163cfec0b0aff3e2c6071a6f286340c6c /sdnr/wt/data-provider/dblib | |
parent | 4d2a4e187187e726e99fa85e32bfbe101567a83f (diff) | |
parent | 016536791b95df23811dabd063010f0561526163 (diff) |
Merge "Support for MariaDB"
Diffstat (limited to 'sdnr/wt/data-provider/dblib')
36 files changed, 6611 insertions, 0 deletions
diff --git a/sdnr/wt/data-provider/dblib/pom.xml b/sdnr/wt/data-provider/dblib/pom.xml new file mode 100644 index 000000000..c4c3d8695 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ ============LICENSE_START======================================================= + ~ ONAP : ccsdk features + ~ ================================================================================ + ~ Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. + ~ All rights reserved. + ~ ================================================================================ + ~ Update Copyright (C) 2020 AT&T 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======================================================= + ~ + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>binding-parent</artifactId> + <version>2.2.0-SNAPSHOT</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.features.sdnr.wt</groupId> + <artifactId>sdnr-wt-data-provider-dblib</artifactId> + <version>1.2.0-SNAPSHOT</version> + <packaging>bundle</packaging> + + <name>ccsdk-features :: ${project.artifactId}</name> + <licenses> + <license> + <name>Apache License, Version 2.0</name> + <url>http://www.apache.org/licenses/LICENSE-2.0</url> + </license> + </licenses> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>sdnr-wt-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>sdnr-wt-yang-utils</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>sdnr-wt-data-provider-model</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-annotations</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.netconf</groupId> + <artifactId>sal-netconf-connector</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.opendaylight.mdsal.binding.model.ietf</groupId> + <artifactId>rfc6991-ietf-yang-types</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>yang-binding</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>mdsal-singleton-common-api</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.json</groupId> + <artifactId>json</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <!-- MariaDB start --> + <dependency> <!-- Not part of ODL karaf standard delivery --> + <groupId>org.apache.tomcat</groupId> + <artifactId>tomcat-jdbc</artifactId> + </dependency> + <dependency> <!-- Not part of ODL karaf standard delivery --> + <groupId>org.mariadb.jdbc</groupId> + <artifactId>mariadb-java-client</artifactId> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + </dependency> + <dependency> + <groupId>ch.vorburger.mariaDB4j</groupId> + <artifactId>mariaDB4j</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <!-- MariaDB end --> + </dependencies> + +</project> 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 new file mode 100644 index 000000000..9d4beb71b --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/DatabaseDataProvider.java @@ -0,0 +1,132 @@ +/* + * ============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; + +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.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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMediatorServerOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateNetworkElementConnectionOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteMaintenanceInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteMaintenanceOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteMediatorServerInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteMediatorServerOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteNetworkElementConnectionInput; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadFaultlogListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadGuiCutThroughEntryOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadInventoryListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadMaintenanceListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadMediatorServerListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadNetworkElementConnectionListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata15mDeviceListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata15mListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata15mLtpListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata24hDeviceListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata24hListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata24hLtpListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadStatusOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateMaintenanceInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateMaintenanceOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateMediatorServerInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateMediatorServerOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateNetworkElementConnectionInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateNetworkElementConnectionOutputBuilder; + + +public interface DatabaseDataProvider { + + HtDatabaseClient getRawClient(); + + ReadFaultcurrentListOutputBuilder readFaultCurrentList(EntityInput input); + + ReadFaultlogListOutputBuilder readFaultLogList(EntityInput input); + + ReadMaintenanceListOutputBuilder readMaintenanceList(EntityInput input); + + ReadMediatorServerListOutputBuilder readMediatorServerList(EntityInput input); + + ReadNetworkElementConnectionListOutputBuilder readNetworkElementConnectionList(EntityInput input); + + ReadInventoryListOutputBuilder readInventoryList(EntityInput input); + + ReadConnectionlogListOutputBuilder readConnectionlogList(EntityInput input); + + ReadEventlogListOutputBuilder readEventlogList(EntityInput input) throws IOException; + + ReadPmdata15mListOutputBuilder readPmdata15mList(EntityInput input); + + ReadPmdata24hListOutputBuilder readPmdata24hList(EntityInput input); + + ReadPmdata15mLtpListOutputBuilder readPmdata15mLtpList(EntityInput input) throws IOException; + + ReadPmdata15mDeviceListOutputBuilder readPmdata15mDeviceList(EntityInput input) throws IOException; + + ReadPmdata24hLtpListOutputBuilder readPmdata24hLtpList(EntityInput input) throws IOException; + + ReadPmdata24hDeviceListOutputBuilder readPmdata24hDeviceList(EntityInput input) throws IOException; + + ReadStatusOutputBuilder readStatus() throws IOException; + + boolean waitForYellowDatabaseStatus(long timeout, TimeUnit unit); + + CreateNetworkElementConnectionOutputBuilder createNetworkElementConnection(NetworkElementConnectionEntity input) + throws IOException; + + UpdateNetworkElementConnectionOutputBuilder updateNetworkElementConnection( + UpdateNetworkElementConnectionInput input) throws IOException; + + DeleteNetworkElementConnectionOutputBuilder deleteNetworkElementConnection( + DeleteNetworkElementConnectionInput input) throws IOException; + + DeleteMediatorServerOutputBuilder deleteMediatorServer(DeleteMediatorServerInput input) throws IOException; + + DeleteMaintenanceOutputBuilder deleteMaintenance(DeleteMaintenanceInput input) throws IOException; + + UpdateMaintenanceOutputBuilder updateMaintenance(UpdateMaintenanceInput input) throws IOException; + + UpdateMediatorServerOutputBuilder updateMediatorServer(UpdateMediatorServerInput input) throws IOException; + + CreateMaintenanceOutputBuilder createMaintenance(CreateMaintenanceInput input) throws IOException; + + CreateMediatorServerOutputBuilder createMediatorServer(CreateMediatorServerInput input) throws IOException; + + ReadGuiCutThroughEntryOutputBuilder readGuiCutThroughEntry(EntityInput input); + + DataProvider getDataProvider(); + + HtDatabaseMaintenance getHtDatabaseMaintenance(); + + HtDatabaseMediatorserver getHtDatabaseMediatorServer(); + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/SqlDBClient.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/SqlDBClient.java new file mode 100644 index 000000000..f16eadd01 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/SqlDBClient.java @@ -0,0 +1,264 @@ +/* + * ============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; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.text.ParseException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.onap.ccsdk.features.sdnr.wt.common.database.Portstatus; +import org.onap.ccsdk.features.sdnr.wt.common.database.data.AliasesEntry; +import org.onap.ccsdk.features.sdnr.wt.common.database.data.AliasesEntryList; +import org.onap.ccsdk.features.sdnr.wt.common.database.data.DatabaseVersion; +import org.onap.ccsdk.features.sdnr.wt.common.database.data.IndicesEntryList; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.SqlDBIndicesEntry; +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.Entity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SqlDBClient { + + private static final Logger LOG = LoggerFactory.getLogger(SqlDBClient.class); + + // matches: + // 1=>type, e.g. mariadb, mysql, ... + // 2=>host + // 3=>port + // 4=>dbname + private static final String DBURL_REGEX = "^jdbc:([^:]+):\\/\\/([^:]+):([0-9]+)\\/(.+)$"; + private static final Pattern DBURL_PATTERN = Pattern.compile(DBURL_REGEX); + private static final String DBVERSION_REGEX = "^([\\d]+\\.[\\d]+\\.[\\d]+)"; + private static final Pattern DBVERSION_PATTERN = Pattern.compile(DBVERSION_REGEX); + private static final String SELECT_VERSION_QUERY = "SELECT @@version as version"; + + private static final String DBNAME_DEFAULT = "sdnrdb"; + private final String dbConnectionString; + private final String dbName; + private final String dbHost; + private final int dbPort; + + /** + * + * @param dbUrl e.g. jdbc:mysql://sdnrdb:3306/sdnrdb + * @param username + * @param password + */ + public SqlDBClient(String dbUrl, String username, String password) throws IllegalArgumentException { + this.dbConnectionString = String.format("%s?user=%s&password=%s", dbUrl, username, password); + final Matcher matcher = DBURL_PATTERN.matcher(dbUrl); + if(!matcher.find()) { + throw new IllegalArgumentException("unable to parse databaseUrl "+dbUrl); + } + this.dbHost = matcher.group(2); + this.dbPort = Integer.parseInt(matcher.group(3)); + this.dbName = matcher.group(4); + } + + public AliasesEntryList readViews() { + return this.readViews(DBNAME_DEFAULT); + } + + public AliasesEntryList readViews(String dbName) { + AliasesEntryList list = new AliasesEntryList(); + final String query = "SELECT v.`TABLE_NAME` AS vn, t.`TABLE_NAME` AS tn\n" + + "FROM `information_schema`.`TABLES` AS v\n" + + "LEFT JOIN `information_schema`.`TABLES` AS t ON t.`TABLE_NAME` LIKE CONCAT(v.`TABLE_NAME`,'%')" + + " AND t.`TABLE_TYPE`='BASE TABLE'\n" + "WHERE v.`TABLE_SCHEMA`='" + dbName + + "' AND v.`TABLE_TYPE`='VIEW'"; + ResultSet data = this.read(query); + try { + while (data.next()) { + list.add(new AliasesEntry(data.getString(2), data.getString(1))); + } + } catch (SQLException e) { + LOG.warn("problem reading views: ", e); + } + return list; + } + + public IndicesEntryList readTables() { + final String query = "SHOW FULL TABLES WHERE `Table_type` = 'BASE TABLE'"; + IndicesEntryList list = new IndicesEntryList(); + ResultSet data = this.read(query); + try { + while (data.next()) { + list.add(new SqlDBIndicesEntry(data.getString(1))); + } + } catch (SQLException e) { + LOG.warn("problem reading tables: ", e); + } + return list; + } + + public void waitForYellowStatus(long timeoutms) { + Portstatus.waitSecondsTillAvailable(timeoutms/1000, this.dbHost, this.dbPort); + } + + public DatabaseVersion readActualVersion() throws SQLException, ParseException { + ResultSet data; + try { + data = this.read(SELECT_VERSION_QUERY); + if (data.next()) { + final String s = data.getString(1); + final Matcher matcher = DBVERSION_PATTERN.matcher(s); + data.afterLast(); + data.close(); + if (matcher.find()) { + return new DatabaseVersion(matcher.group(1)); + } else { + throw new ParseException(String.format("unable to extract version out of string '%s'", s), 0); + } + } + } catch (SQLException e) { + LOG.warn("problem reading tables: ", e); + } + throw new SQLException("unable to read version from database"); + } + + public boolean createTable(Entity entity, Class<?> clazz, String suffix) throws UnableToMapClassException { + String createStatement = SqlDBMapper.createTable(clazz, entity, suffix); + return this.createTable(createStatement); + } + + public boolean createTable(String tableName, String tableMappings) { + final String createStatement = String.format("CREATE TABLE IF NOT EXISTS `%s` (%s)", tableName, tableMappings); + return this.createTable(createStatement); + } + + public boolean createTable(String query) { + try { + Connection connection = this.getConnection(); + PreparedStatement stmt = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS); + stmt.execute(); + connection.close(); + return true; + } catch (SQLException e) { + LOG.warn("problem creating table:", e); + } + return false; + } + + public boolean createView(String tableName, String viewName) throws SQLException { + try { + this.write(String.format("CREATE VIEW IF NOT EXISTS `%s` AS SELECT * FROM `%s`", viewName, tableName)); + return true; + } catch (SQLException e) { + LOG.warn("problem deleting table:", e); + } + return false; + } + + public boolean deleteView(String viewName) throws SQLException { + try { + this.write(String.format("DROP VIEW IF EXISTS `%s`", viewName)); + return true; + } catch (SQLException e) { + LOG.warn("problem deleting view:", e); + } + return false; + } + + public boolean update(String query) throws SQLException { + boolean result = false; + Connection connection = null; + connection = DriverManager.getConnection(this.dbConnectionString); + Statement stmt = connection.createStatement(); + result = stmt.execute(query); + return stmt.getUpdateCount() > 0 ? stmt.getUpdateCount() > 0 : result; + } + + public boolean write(String query) throws SQLException { + Connection connection = this.getConnection(); + PreparedStatement stmt = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS); + boolean result = stmt.execute(); + connection.close(); + return stmt.getUpdateCount() > 0 ? stmt.getUpdateCount() > 0 : result; + } + + public String writeAndReturnId(String query) throws SQLException { + Connection connection = this.getConnection(); + PreparedStatement stmt = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS); + stmt.execute(); + ResultSet generatedKeys = stmt.getGeneratedKeys(); + connection.close(); + if (generatedKeys.next()) { + return String.valueOf(generatedKeys.getLong(1)); + } + return null; + } + + public boolean deleteTable(String tableName) throws SQLException { + try { + this.write(String.format("DROP TABLE IF EXISTS `%s`", tableName)); + return true; + } catch (SQLException e) { + LOG.warn("problem deleting table:", e); + } + return false; + } + + public String getDatabaseName() { + return this.dbName; + } + + public ResultSet read(String query) { + ResultSet data = null; + Connection connection = null; + Statement stmt = null; + try { + connection = DriverManager.getConnection(this.dbConnectionString); + stmt = connection.createStatement(); + data = stmt.executeQuery(query); + } catch (SQLException e) { + LOG.warn("problem reading tables: ", e); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException e) { + LOG.warn("problem closing connection: ", e); + } + } + + return data; + } + + public Connection getConnection() throws SQLException { + return DriverManager.getConnection(this.dbConnectionString); + } + + public boolean delete(String query) throws SQLException { + this.write(query); + return true; + } + + + +} 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 new file mode 100644 index 000000000..8c7e7b1cb --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/SqlDBConfig.java @@ -0,0 +1,112 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 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; + +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.dataprovider.database.sqldb.data.entity.DatabaseIdGenerator; + +public class SqlDBConfig implements Configuration { + + private static final String SECTION_MARKER_MARIADB = "mariadb"; + + private static final String PROPERTY_KEY_DBURL = "url"; + private static final String PROPERTY_KEY_USERNAME = "username"; + private static final String PROPERTY_KEY_PASSWORD = "password"; + private static final String PROPERTY_KEY_CONTROLLERID = "controllerId"; + private static final String PROPERTY_KEY_DBSUFFIX = "suffix"; + + + 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 final ConfigurationFileRepresentation configuration; + + public SqlDBConfig(ConfigurationFileRepresentation configuration) { + + this.configuration = configuration; + this.configuration.addSection(SECTION_MARKER_MARIADB); + defaults(); + } + + + /* + * Getter + */ + + public String getUrl() { + return configuration.getProperty(SECTION_MARKER_MARIADB, PROPERTY_KEY_DBURL); + } + + public void setUrl(String url) { + configuration.setProperty(SECTION_MARKER_MARIADB, PROPERTY_KEY_DBURL, url); + + } + + public String getUsername() { + return this.configuration.getProperty(SECTION_MARKER_MARIADB, PROPERTY_KEY_USERNAME); + } + + public String getPassword() { + return this.configuration.getProperty(SECTION_MARKER_MARIADB, PROPERTY_KEY_PASSWORD); + } + + public String getControllerId() { + String v = this.configuration.getProperty(SECTION_MARKER_MARIADB, PROPERTY_KEY_CONTROLLERID); + return (v == null || v.equals("null") || v.isEmpty()) ? null : v; + } + + public String getDbSuffix() { + return this.configuration.getProperty(SECTION_MARKER_MARIADB, PROPERTY_KEY_DBSUFFIX); + } + + @Override + public String getSectionName() { + return SECTION_MARKER_MARIADB; + } + + @Override + public synchronized void defaults() { + // Add default if not available + configuration.setPropertyIfNotAvailable(SECTION_MARKER_MARIADB, PROPERTY_KEY_DBURL, DEFAULT_VALUE_DBURL); + configuration.setPropertyIfNotAvailable(SECTION_MARKER_MARIADB, PROPERTY_KEY_USERNAME, + DEFAULT_VALUE_DBUSERNAME); + configuration.setPropertyIfNotAvailable(SECTION_MARKER_MARIADB, PROPERTY_KEY_PASSWORD, + DEFAULT_VALUE_DBPASSWORD); + configuration.setPropertyIfNotAvailable(SECTION_MARKER_MARIADB, PROPERTY_KEY_CONTROLLERID, + DEFAULT_VALUE_CONTROLLERID); + configuration.setPropertyIfNotAvailable(SECTION_MARKER_MARIADB, PROPERTY_KEY_DBSUFFIX, DEFAULT_VALUE_DBSUFFIX); + + } + + + public void setControllerId(String id) { + configuration.setProperty(SECTION_MARKER_MARIADB, PROPERTY_KEY_CONTROLLERID, id); + } + + public void setDbSuffix(String suffix) { + configuration.setProperty(SECTION_MARKER_MARIADB, PROPERTY_KEY_DBSUFFIX, suffix); + } +} 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 new file mode 100644 index 000000000..9dd1adb50 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/HtUserdataManagerImpl.java @@ -0,0 +1,150 @@ +/* + * ============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.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<SearchHit> 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() : "{}"; + } + + @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; + } + + @Override + public boolean removeUserdata(String username) { + return this.dbClient.doRemove(Entity.Userdata.getName(), username); + } + + @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); + } + } + } + return target; + } + +} 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 new file mode 100644 index 000000000..94c7dcfc6 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlDBDataProvider.java @@ -0,0 +1,509 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 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.IOException; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.concurrent.TimeUnit; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.DatabaseDataProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.SqlDBClient; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.SqlDBConfig; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.entity.HtDatabaseEventsService; +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.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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMediatorServerOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateNetworkElementConnectionOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteMaintenanceInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteMaintenanceOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteMediatorServerInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteMediatorServerOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteNetworkElementConnectionInput; +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.Entity; +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.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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadFaultlogListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadGuiCutThroughEntryOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadInventoryListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadMaintenanceListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadMediatorServerListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadNetworkElementConnectionListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata15mDeviceListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata15mListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata15mLtpListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata24hDeviceListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata24hListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata24hLtpListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadStatusOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateMaintenanceInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateMaintenanceOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateMediatorServerInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateMediatorServerOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateNetworkElementConnectionInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateNetworkElementConnectionOutputBuilder; +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.read.mediator.server.list.output.Data; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class SqlDBDataProvider extends HtDatabaseEventsService implements DatabaseDataProvider { + + private static final Logger LOG = LoggerFactory.getLogger(SqlDBDataProvider.class); + + private static final String EXCEPTION_UNABLE_TO_WRITE_IN_DATABASE = "unable to write data to database"; + private static final String EXCEPTION_UNABLE_TO_UPDATE_IN_DATABASE = "unable to update data in database"; + private static final String EXCEPTION_UNABLE_TO_REMOVE_FROM_DATABASE = "unable to remove data from database"; + + private final HtDatabaseMediatorserver dbMediatorServerService; + private final HtDatabaseMaintenance dbMaintenanceService; + private final SqlDBReaderWriter<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.mediator.server.list.output.Data> mediatorserverRW; + private final SqlDBReaderWriter<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.maintenance.list.output.Data> maintenanceRW; + private final SqlDBStatusReader readStatus; + + public SqlDBReaderWriter<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.maintenance.list.output.Data> getMaintenanceReaderWriter() { + return this.maintenanceRW; + } + + public SqlDBReaderWriter<Data> getMediatorServerReaderWriter() { + return this.mediatorserverRW; + } + + public SqlDBDataProvider(SqlDBConfig config) { + this(config, true); + } + public SqlDBDataProvider(SqlDBConfig config, boolean initControllerId) { + super(config); + + this.mediatorserverRW = new SqlDBReaderWriter<>(this.dbClient, Entity.MediatorServer, config.getDbSuffix(), + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.mediator.server.list.output.Data.class, + this.dbClient.getDatabaseName(), this.controllerId).setWriteInterface(MediatorServerEntity.class); + + this.maintenanceRW = new SqlDBReaderWriter<>(this.dbClient, Entity.Maintenancemode, config.getDbSuffix(), + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.maintenance.list.output.Data.class, + this.dbClient.getDatabaseName(), this.controllerId).setWriteInterface(MaintenanceEntity.class); + + this.readStatus = new SqlDBStatusReader(this.dbClient, this.controllerId); + + this.dbMediatorServerService = new HtDatabaseMediatorserver() { + + @Override + public List<MediatorServerEntity> getAll() { + return SqlDBDataProvider.this.mediatorserverRW.readAll(MediatorServerEntity.class); + } + }; + this.dbMaintenanceService = new HtDatabaseMaintenanceService(this); + if(initControllerId) { + try { + this.setControllerId(); + } catch (SQLException e) { + LOG.warn("problem setting controllerId: ", e); + } + } + + } + + /*------------------------- + * Provide access to model API + */ + + @Override + public ReadFaultcurrentListOutputBuilder readFaultCurrentList(EntityInput input) { + + ReadFaultcurrentListOutputBuilder outputBuilder = new ReadFaultcurrentListOutputBuilder(); + + QueryResult<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.faultcurrent.list.output.Data> result = + this.eventRWFaultCurrent.getData(input); + outputBuilder.setData(result.getResult()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.faultcurrent.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + @Override + public ReadFaultlogListOutputBuilder readFaultLogList(EntityInput input) { + ReadFaultlogListOutputBuilder outputBuilder = new ReadFaultlogListOutputBuilder(); + QueryResult<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.faultlog.list.output.Data> result = + this.eventRWFaultLog.getData(input); + outputBuilder.setData(result.getResult()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.faultlog.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + @Override + public ReadMaintenanceListOutputBuilder readMaintenanceList(EntityInput input) { + ReadMaintenanceListOutputBuilder outputBuilder = new ReadMaintenanceListOutputBuilder(); + QueryResult<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.maintenance.list.output.Data> result = + this.maintenanceRW.getData(input); + outputBuilder.setData(result.getResult()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.maintenance.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + @Override + public ReadMediatorServerListOutputBuilder readMediatorServerList(EntityInput input) { + + ReadMediatorServerListOutputBuilder outputBuilder = new ReadMediatorServerListOutputBuilder(); + QueryResult<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.mediator.server.list.output.Data> result = + this.mediatorserverRW.getData(input); + outputBuilder.setData(result.getResult()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.mediator.server.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + @Override + public ReadNetworkElementConnectionListOutputBuilder readNetworkElementConnectionList(EntityInput input) { + ReadNetworkElementConnectionListOutputBuilder outputBuilder = + new ReadNetworkElementConnectionListOutputBuilder(); + QueryResult<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.network.element.connection.list.output.Data> result = + this.networkelementConnectionRW.getData(input); + outputBuilder.setData(result.getResult()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.network.element.connection.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + @Override + public ReadInventoryListOutputBuilder readInventoryList(EntityInput input) { + ReadInventoryListOutputBuilder outputBuilder = new ReadInventoryListOutputBuilder(); + QueryResult<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.inventory.list.output.Data> result = + this.equipmentRW.getData(input); + outputBuilder.setData(result.getResult()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.inventory.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + @Override + public ReadConnectionlogListOutputBuilder readConnectionlogList(EntityInput input) { + ReadConnectionlogListOutputBuilder outputBuilder = new ReadConnectionlogListOutputBuilder(); + QueryResult<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.connectionlog.list.output.Data> result = + this.connectionlogRW.getData(input); + outputBuilder.setData(result.getResult()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.connectionlog.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + @Override + public ReadEventlogListOutputBuilder readEventlogList(EntityInput input) throws IOException { + ReadEventlogListOutputBuilder outputBuilder = new ReadEventlogListOutputBuilder(); + QueryResult<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.eventlog.list.output.Data> result = + this.eventlogRW.getData(input); + outputBuilder.setData(result.getResult()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.eventlog.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + @Override + public ReadPmdata15mListOutputBuilder readPmdata15mList(EntityInput input) { + ReadPmdata15mListOutputBuilder outputBuilder = new ReadPmdata15mListOutputBuilder(); + QueryResult<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.pmdata._15m.list.output.Data> result = + this.pm15mRW.getData(input); + LOG.debug("Read data: readPmdata15mList: {}", result); + outputBuilder.setData(result.getResult()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.pmdata._15m.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + @Override + public ReadPmdata24hListOutputBuilder readPmdata24hList(EntityInput input) { + ReadPmdata24hListOutputBuilder outputBuilder = new ReadPmdata24hListOutputBuilder(); + QueryResult<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.pmdata._24h.list.output.Data> result = + this.pm24hRW.getData(input); + outputBuilder.setData(result.getResult()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.pmdata._24h.list.output.PaginationBuilder( + result.getPagination()).build()); + return outputBuilder; + } + + @Override + public ReadPmdata15mLtpListOutputBuilder readPmdata15mLtpList(EntityInput input) throws IOException { + ReadPmdata15mLtpListOutputBuilder outputBuilder = new ReadPmdata15mLtpListOutputBuilder(); + QueryResult<String> result = this.pm15mRW.getDataLtpList(input); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.pmdata._15m.ltp.list.output.PaginationBuilder( + result.getPagination()).build()); + outputBuilder.setData(result.getResult()); + return outputBuilder; + } + + @Override + public ReadPmdata15mDeviceListOutputBuilder readPmdata15mDeviceList(EntityInput input) throws IOException { + ReadPmdata15mDeviceListOutputBuilder outputBuilder = new ReadPmdata15mDeviceListOutputBuilder(); + QueryResult<String> result = this.pm15mRW.getDataDeviceList(input); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.pmdata._15m.device.list.output.PaginationBuilder( + result.getPagination()).build()); + outputBuilder.setData(result.getResult()); + return outputBuilder; + } + + @Override + public ReadPmdata24hLtpListOutputBuilder readPmdata24hLtpList(EntityInput input) throws IOException { + + QueryResult<String> result = this.pm24hRW.getDataLtpList(input); + + ReadPmdata24hLtpListOutputBuilder outputBuilder = new ReadPmdata24hLtpListOutputBuilder(); + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.pmdata._24h.ltp.list.output.PaginationBuilder(); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.pmdata._24h.ltp.list.output.PaginationBuilder( + result.getPagination()).build()); + outputBuilder.setData(result.getResult()); + return outputBuilder; + } + + @Override + public ReadPmdata24hDeviceListOutputBuilder readPmdata24hDeviceList(EntityInput input) throws IOException { + + QueryResult<String> result = pm24hRW.getDataDeviceList(input); + + ReadPmdata24hDeviceListOutputBuilder outputBuilder = new ReadPmdata24hDeviceListOutputBuilder(); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.pmdata._24h.device.list.output.PaginationBuilder( + result.getPagination()).build()); + outputBuilder.setData(result.getResult()); + return outputBuilder; + } + + @Override + public ReadStatusOutputBuilder readStatus() throws IOException { + QueryResult<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.status.output.Data> result = + readStatus.getDataStatus(); + + ReadStatusOutputBuilder outputBuilder = new ReadStatusOutputBuilder(); + outputBuilder.setData(result.getResult()); + return outputBuilder; + } + + @Override + public CreateNetworkElementConnectionOutputBuilder createNetworkElementConnection( + NetworkElementConnectionEntity input) throws IOException { + String id = this.networkelementConnectionRW.write(input, input.getNodeId()); + if (id == null) { + throw new IOException(EXCEPTION_UNABLE_TO_WRITE_IN_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; + } + + @Override + public UpdateNetworkElementConnectionOutputBuilder updateNetworkElementConnection( + UpdateNetworkElementConnectionInput input) throws IOException { + String id = this.networkelementConnectionRW.update(input, input.getId()); + if (id == null) { + throw new IOException(EXCEPTION_UNABLE_TO_UPDATE_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; + } + + @Override + public DeleteNetworkElementConnectionOutputBuilder deleteNetworkElementConnection( + DeleteNetworkElementConnectionInput input) throws IOException { + boolean removed = this.networkelementConnectionRW.remove(input.getId()) > 0; + if (!removed) { + throw new IOException(EXCEPTION_UNABLE_TO_REMOVE_FROM_DATABASE); + } + return new DeleteNetworkElementConnectionOutputBuilder(); + } + + @Override + public DeleteMediatorServerOutputBuilder deleteMediatorServer(DeleteMediatorServerInput input) throws IOException { + boolean removed = this.mediatorserverRW.remove(input.getId()) > 0; + if (!removed) { + throw new IOException(EXCEPTION_UNABLE_TO_REMOVE_FROM_DATABASE); + } + return new DeleteMediatorServerOutputBuilder(); + } + + @Override + public DeleteMaintenanceOutputBuilder deleteMaintenance(DeleteMaintenanceInput input) throws IOException { + boolean removed = this.maintenanceRW.remove(input.getId()) > 0; + if (!removed) { + throw new IOException(EXCEPTION_UNABLE_TO_REMOVE_FROM_DATABASE); + } + return new DeleteMaintenanceOutputBuilder(); + } + + @Override + 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(EXCEPTION_UNABLE_TO_UPDATE_IN_DATABASE); + } + UpdateMaintenanceOutputBuilder builder = new UpdateMaintenanceOutputBuilder(input).setId(id); + return builder; + } + + @Override + 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(EXCEPTION_UNABLE_TO_UPDATE_IN_DATABASE); + } + UpdateMediatorServerOutputBuilder builder = new UpdateMediatorServerOutputBuilder(); + builder.setId(id).setName(input.getName()).setUrl(input.getUrl()); + return builder; + } + + @Override + public CreateMaintenanceOutputBuilder createMaintenance(CreateMaintenanceInput input) throws IOException { + String id = this.maintenanceRW.write(input, input.getNodeId()); + if (id == null) { + throw new IOException(EXCEPTION_UNABLE_TO_WRITE_IN_DATABASE); + } + CreateMaintenanceOutputBuilder builder = new CreateMaintenanceOutputBuilder(input).setId(id); + return builder; + } + + @Override + public CreateMediatorServerOutputBuilder createMediatorServer(CreateMediatorServerInput input) throws IOException { + String id = this.mediatorserverRW.write(input, null); + + if (id == null) { + throw new IOException(EXCEPTION_UNABLE_TO_WRITE_IN_DATABASE); + } + CreateMediatorServerOutputBuilder builder = new CreateMediatorServerOutputBuilder(); + builder.setId(id).setName(input.getName()).setUrl(input.getUrl()); + return builder; + } + + @Override + public ReadGuiCutThroughEntryOutputBuilder readGuiCutThroughEntry(EntityInput input) { + ReadGuiCutThroughEntryOutputBuilder outputBuilder = new ReadGuiCutThroughEntryOutputBuilder(); + QueryResult<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.gui.cut.through.entry.output.Data> result = + this.guicutthroughRW.getData(input); + outputBuilder.setData(result.getResult()); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.gui.cut.through.entry.output.PaginationBuilder() + .build()); + return outputBuilder; + } + + + + @Override + public boolean waitForYellowDatabaseStatus(long timeout, TimeUnit unit) { + return true; + } + + @Override + public DataProvider getDataProvider() { + return this; + } + + @Override + public HtDatabaseMaintenance getHtDatabaseMaintenance() { + return this.dbMaintenanceService; + } + + @Override + public HtDatabaseMediatorserver getHtDatabaseMediatorServer() { + return this.dbMediatorServerService; + } + + public boolean delete(Entity e, List<Filter> filters) throws SQLException { + DeleteQuery query = new DeleteQuery(e, filters); + return this.dbClient.write(query.toSql()); + + } + + public SqlDBClient getDBService() { + return this.dbClient; + } + + public boolean setControllerId() throws SQLException { + if (this.controllerId == null) { + return true; + } + LOG.info("set controllerId {}", this.controllerId); + String query = String.format("SELECT * FROM `%s` WHERE `id`='%s';", this.controllerTableName, + this.controllerId); + LOG.info(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, ""); + LOG.info(query); + return this.dbClient.write(query); + } + else { + LOG.info("controllerId already set"); + } + return true; + } + + public void waitForDatabaseReady(int i, TimeUnit unit) { + this.dbClient.waitForYellowStatus(unit.convert(i, TimeUnit.MILLISECONDS)); + } + + public String getControllerId() { + return this.controllerId; + } + + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlDBIndicesEntry.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlDBIndicesEntry.java new file mode 100644 index 000000000..fdea87c8b --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlDBIndicesEntry.java @@ -0,0 +1,33 @@ +/* + * ============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 org.onap.ccsdk.features.sdnr.wt.common.database.data.IndicesEntry; + +public class SqlDBIndicesEntry extends IndicesEntry{ + + public SqlDBIndicesEntry(String name) { + super(name,"","","",0,0,0,0,"",""); + } + + +} 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 new file mode 100644 index 000000000..5a9e58cef --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/DatabaseIdGenerator.java @@ -0,0 +1,104 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 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.entity; + +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultcurrentEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.InventoryEntity; +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.NetworkElementConnectionEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Pmdata15mEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Pmdata24hEntity; + +/** + * Database id generator for those classes which need manual id generation by object + * implementation for this spec: https://wiki.onap.org/display/DW/SDN-R+Database+for+Instanbul + * @author jack + * + */ +public class DatabaseIdGenerator { + + private static final Pattern FAULTPATTERN = Pattern.compile(".*\\[layerProtocol=(.*)\\]"); + + public static String getMaintenanceId(String nodeId) { + return nodeId; + } + + public static String getMaintenanceId(MaintenanceEntity object) { + return object == null ? null : object.getNodeId(); + } + + public static String getControllerId() { + return UUID.randomUUID().toString(); + } + + public static String getFaultcurrentId(String nodeId, String objectId, String problemName) { + String uuId; + + Matcher matcher = FAULTPATTERN.matcher(objectId); + if (matcher.matches() && matcher.groupCount() == 1) { + uuId = matcher.group(1); + } else { + uuId = objectId; + } + return String.format("%s/%s/%s", nodeId, uuId, problemName); + } + + public static String getFaultcurrentId(FaultcurrentEntity object) { + return object == null ? null : getFaultcurrentId(object.getNodeId(), object.getObjectId(), object.getProblem()); + } + + public static String getNetworkelementConnectionId(String nodeId) { + return nodeId; + } + + public static String getNetworkelementConnectionId(NetworkElementConnectionEntity object) { + return object == null ? null : object.getNodeId(); + } + + public static String getPmData15mId(String nodeId, String uuidInterface, String timestamp) { + return String.format("%s/%s/%s", nodeId, uuidInterface, timestamp); + } + + public static String getPmData15mId(Pmdata15mEntity object) { + return object == null ? null + : getPmData15mId(object.getNodeName(), object.getUuidInterface(), object.getTimeStamp().getValue()); + } + public static String getPmData24hId(String nodeId, String uuidInterface, String timestamp) { + return String.format("%s/%s/%s", nodeId, uuidInterface, timestamp); + } + + public static String getPmData24hId(Pmdata24hEntity object) { + return object == null ? null + : getPmData24hId(object.getNodeName(), object.getUuidInterface(), object.getTimeStamp().getValue()); + } + + public static String getInventoryId(InventoryEntity object) { + return getInventoryId(object.getNodeId(),object.getUuid()); + } + + private static String getInventoryId(String nodeId, String uuid) { + return String.format("%s/%s", nodeId, uuid); + } +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/FaultEntityManager.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/FaultEntityManager.java new file mode 100644 index 000000000..8371b9c2b --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/FaultEntityManager.java @@ -0,0 +1,65 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * 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.sqldb.data.entity; + +import java.util.Date; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Fault; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SeverityType; +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; + +public class FaultEntityManager { + + /** + * 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()); + } + + public static Filter getOlderOrEqualFilter(Date olderAreOutdated) { + return new FilterBuilder().setProperty("timestamp").setFiltervalue("<").build(); + } +} 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 new file mode 100644 index 000000000..84786b0cd --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/HtDatabaseEventsService.java @@ -0,0 +1,269 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * 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.sqldb.data.entity; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import org.mariadb.jdbc.Driver; +import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.SqlDBClient; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.SqlDBConfig; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBMapper; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBReaderWriter; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBReaderWriterFault; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBReaderWriterPm; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultcurrentEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.GranularityPeriodType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Guicutthrough; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory; +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.PmdataEntity; +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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Event service, writing all events into the database into the appropriate index. + * + * @author herbert + */ +public class HtDatabaseEventsService implements DataProvider { + private static final Logger LOG = LoggerFactory.getLogger(HtDatabaseEventsService.class); + + private static final NetconfTimeStamp NETCONFTIME_CONVERTER = NetconfTimeStampImpl.getConverter();; + + protected final SqlDBClient dbClient; + protected final String controllerId; + protected final SqlDBReaderWriter<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.connectionlog.list.output.Data> connectionlogRW; + protected final SqlDBReaderWriter<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.eventlog.list.output.Data> eventlogRW; + protected final SqlDBReaderWriter<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.faultlog.list.output.Data> eventRWFaultLog; + protected final SqlDBReaderWriterFault<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.faultcurrent.list.output.Data> eventRWFaultCurrent; + protected final SqlDBReaderWriter<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.inventory.list.output.Data> equipmentRW; + protected final SqlDBReaderWriter<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.gui.cut.through.entry.output.Data> guicutthroughRW; + protected final SqlDBReaderWriter<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.network.element.connection.list.output.Data> networkelementConnectionRW; + protected final SqlDBReaderWriterPm<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.pmdata._15m.list.output.Data> pm15mRW; + protected final SqlDBReaderWriterPm<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.pmdata._24h.list.output.Data> pm24hRW; + protected final String controllerTableName; + + public HtDatabaseEventsService(SqlDBConfig config) { + LOG.debug("Creating dummy instance of org.mariadb.jdbc.Driver"); + @SuppressWarnings("unused") + Driver dvr = new org.mariadb.jdbc.Driver(); + dvr = null; + this.controllerId = config.getControllerId(); + this.controllerTableName = SqlDBMapper.TABLENAME_CONTROLLER + config.getDbSuffix(); + this.dbClient = new SqlDBClient(config.getUrl(), config.getUsername(), config.getPassword()); + this.connectionlogRW = new SqlDBReaderWriter<>(dbClient, Entity.Connectionlog, config.getDbSuffix(), + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.connectionlog.list.output.Data.class, + this.dbClient.getDatabaseName(), this.controllerId); + this.eventlogRW = new SqlDBReaderWriter<>(dbClient, Entity.Eventlog, config.getDbSuffix(), + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.eventlog.list.output.Data.class, + this.dbClient.getDatabaseName(), this.controllerId); + this.eventRWFaultLog = new SqlDBReaderWriter<>(dbClient, Entity.Faultlog, config.getDbSuffix(), + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.faultlog.list.output.Data.class, + this.dbClient.getDatabaseName(), this.controllerId); + this.eventRWFaultCurrent = new SqlDBReaderWriterFault<>(dbClient, Entity.Faultcurrent, config.getDbSuffix(), + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.faultcurrent.list.output.Data.class, + this.dbClient.getDatabaseName(), this.controllerId); + this.equipmentRW = new SqlDBReaderWriter<>(dbClient, Entity.Inventoryequipment, config.getDbSuffix(), + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.inventory.list.output.Data.class, + this.dbClient.getDatabaseName(), this.controllerId); + this.guicutthroughRW = new SqlDBReaderWriter<>(dbClient, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Entity.Guicutthrough, + config.getDbSuffix(), + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.gui.cut.through.entry.output.Data.class, + this.dbClient.getDatabaseName(), this.controllerId).setWriteInterface(Guicutthrough.class); + this.networkelementConnectionRW = new SqlDBReaderWriter<>(dbClient, Entity.NetworkelementConnection, + config.getDbSuffix(), + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.network.element.connection.list.output.Data.class, + this.dbClient.getDatabaseName(), this.controllerId); + this.networkelementConnectionRW.setWriteInterface(NetworkElementConnectionEntity.class); + + this.pm15mRW = new SqlDBReaderWriterPm<>(dbClient, Entity.Historicalperformance15min, config.getDbSuffix(), + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.pmdata._15m.list.output.Data.class, + this.dbClient.getDatabaseName(), this.controllerId); + + this.pm24hRW = new SqlDBReaderWriterPm<>(dbClient, Entity.Historicalperformance24h, config.getDbSuffix(), + 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); + + } + + @Override + public void writeConnectionLog(ConnectionlogEntity event) { + this.connectionlogRW.write(event, event.getId()); + } + + @Override + public void writeEventLog(EventlogEntity event) { + this.eventlogRW.write(event, event.getId()); + + } + + @Override + public void writeFaultLog(FaultlogEntity fault) { + this.eventRWFaultLog.write(fault, fault.getId()); + } + + @Override + public void updateFaultCurrent(FaultcurrentEntity fault) { + final String id = fault.getId() != null ? fault.getId() : DatabaseIdGenerator.getFaultcurrentId(fault); + if (FaultEntityManager.isManagedAsCurrentProblem(fault)) { + if (FaultEntityManager.isNoAlarmIndication(fault)) { + LOG.debug("Remove from currentFaults: {}", fault.toString()); + this.eventRWFaultCurrent.remove(id); + } else { + LOG.debug("Write to currentFaults: {}", fault.toString()); + this.eventRWFaultCurrent.updateOrInsert(fault, id); + } + } else { + LOG.debug("Ingnore for currentFaults: {}", fault.toString()); + } + } + + @Override + public int clearFaultsCurrentOfNode(String nodeName) { + return this.eventRWFaultCurrent + .remove(Arrays.asList(new FilterBuilder().setProperty("node-id").setFiltervalue(nodeName).build())); + } + + @Override + public int clearFaultsCurrentOfNodeWithObjectId(String nodeName, String objectId) { + return this.eventRWFaultCurrent + .remove(Arrays.asList(new FilterBuilder().setProperty("node-id").setFiltervalue(nodeName).build(), + new FilterBuilder().setProperty("object-id").setFiltervalue(objectId).build())); + } + + @Override + public List<String> getAllNodesWithCurrentAlarms() { + return this.eventRWFaultCurrent.getAllNodes(); + } + + @Override + public void writeInventory(String nodeId, List<Inventory> list) { + for (Inventory internalEquipment : list) { + this.equipmentRW.updateOrInsert(internalEquipment, + internalEquipment.getId() != null ? internalEquipment.getId() + : DatabaseIdGenerator.getInventoryId(internalEquipment)); + } + } + + @Override + public void writeGuiCutThroughData(Guicutthrough gcData, String nodeId) { + this.guicutthroughRW.write(gcData, nodeId); + } + + @Override + public int clearGuiCutThroughEntriesOfNode(String nodeName) { + this.guicutthroughRW.remove(nodeName); + return 0; + } + + @Override + public boolean updateNetworkConnectionDeviceType(NetworkElementConnectionEntity networkElementConnectionEntitiy, + String nodeId) { + return this.networkelementConnectionRW.updateOrInsert(networkElementConnectionEntitiy, nodeId) != null; + } + + @Override + public boolean updateNetworkConnection22(NetworkElementConnectionEntity ne, String nodeId) { + return this.networkelementConnectionRW.updateOrInsert(ne, nodeId) != null; + } + + @Override + public void removeNetworkConnection(String nodeId) { + this.networkelementConnectionRW.remove(nodeId); + + } + + @Override + public int doIndexClean(Date olderAreOutdated) { + String netconfTimeStamp = NETCONFTIME_CONVERTER.getTimeStampAsNetconfString(olderAreOutdated); + List<Filter> filter = new ArrayList<>(); + filter.add(new FilterBuilder().setProperty("timestamp").setFiltervalue(String.format("<%s", netconfTimeStamp)) + .build()); + if (this.controllerId != null) { + filter.add( + new FilterBuilder().setProperty(SqlDBMapper.ODLID_DBCOL).setFiltervalue(this.controllerId).build()); + } + int removed = 0; + + removed += this.eventlogRW.remove(filter); + removed += this.eventRWFaultLog.remove(filter); + return removed; + } + + @Override + public long getNumberOfOldObjects(Date olderAreOutdated) { + List<Filter> filter = Arrays.asList(FaultEntityManager.getOlderOrEqualFilter(olderAreOutdated)); + try { + return this.eventRWFaultLog.count(filter, this.controllerId); + } catch (SQLException e) { + LOG.warn("problem counting faults older than {}: ", olderAreOutdated, e); + } + return 0; + } + + @Override + public List<NetworkElementConnectionEntity> getNetworkElementConnections() { + return this.networkelementConnectionRW.readAll(NetworkElementConnectionEntity.class); + } + + @Override + public void doWritePerformanceData(List<PmdataEntity> list) { + list.stream().forEach((pmData) -> { + GranularityPeriodType granularityPeriod = + pmData.getGranularityPeriod() != null ? pmData.getGranularityPeriod() + : GranularityPeriodType.Unknown; + switch (granularityPeriod) { + case Period15Min: + this.pm15mRW.write(pmData); + break; + case Period24Hours: + this.pm24hRW.write(pmData); + break; + case Unknown: + default: + LOG.debug("Unknown granularity {}", granularityPeriod); + break; + } + }); + + } + + @Override + public HtDatabaseClient getRawClient() { + return null; + } + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/HtDatabaseMaintenanceService.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/HtDatabaseMaintenanceService.java new file mode 100644 index 000000000..dbbb89c47 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/HtDatabaseMaintenanceService.java @@ -0,0 +1,126 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * 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.sqldb.data.entity; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.eclipse.jdt.annotation.Nullable; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.SqlDBDataProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBReaderWriter; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtDatabaseMaintenance; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMaintenanceInputBuilder; +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.DeleteMaintenanceInputBuilder; +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.ReadMaintenanceListInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadMaintenanceListOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadNetworkElementConnectionListInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadNetworkElementConnectionListOutput; +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.read.maintenance.list.output.Data; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class HtDatabaseMaintenanceService implements HtDatabaseMaintenance { + + private static final Logger LOG = LoggerFactory.getLogger(HtDatabaseMaintenanceService.class); + private final SqlDBReaderWriter<Data> maintenanceRw; + private final SqlDBDataProvider dbProvider; + + public HtDatabaseMaintenanceService(SqlDBDataProvider dbProvider) { + this.dbProvider = dbProvider; + this.maintenanceRw = dbProvider.getMaintenanceReaderWriter(); + } + + + @Override + public MaintenanceEntity createIfNotExists(String nodeId) { + + MaintenanceEntity e = this.getMaintenance(nodeId); + if (e == null) { + try { + CreateMaintenanceOutputBuilder createResult = this.dbProvider + .createMaintenance(new CreateMaintenanceInputBuilder().setNodeId(nodeId).build()); + e = createResult.build(); + } catch (IOException e1) { + LOG.warn("problem writing initial maintenance entry for {} : ", nodeId, e); + } + } + return e; + } + + private static Map<FilterKey, Filter> getFilterInput(String key, String value) { + Map<FilterKey, Filter> filterMap = new HashMap<>(); + Filter f = new FilterBuilder().setProperty(key).setFiltervalue(value).build(); + filterMap.put(f.key(), f); + return filterMap; + } + + @Override + public void deleteIfNotRequired(String nodeId) { + ReadNetworkElementConnectionListOutput result = this.dbProvider.readNetworkElementConnectionList( + new ReadNetworkElementConnectionListInputBuilder().setFilter(getFilterInput("node-id", nodeId)).build()) + .build(); + if (result.getData() != null && result.getData().size() > 0) { + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.network.element.connection.list.output.Data entry = + result.getData().get(0); + if (entry.isIsRequired()) { + return; + + } + } + try { + this.dbProvider.deleteMaintenance( + new DeleteMaintenanceInputBuilder().setId(DatabaseIdGenerator.getMaintenanceId(nodeId)).build()); + } catch (IOException e) { + LOG.warn("problem deleting maintenance entry for node {}: ", nodeId, e); + } + } + + @Override + public List<MaintenanceEntity> getAll() { + return this.maintenanceRw.readAll(MaintenanceEntity.class); + } + + @Override + public MaintenanceEntity getMaintenance(@Nullable String nodeId) { + ReadMaintenanceListOutput result = this.dbProvider + .readMaintenanceList( + new ReadMaintenanceListInputBuilder().setFilter(getFilterInput("node-id", nodeId)).build()) + .build(); + + return result.getData() != null ? result.getData().size() > 0 ? result.getData().get(0) : null : null; + } + + @Override + public MaintenanceEntity setMaintenance(MaintenanceEntity m) { + + this.maintenanceRw.updateOrInsert(m, DatabaseIdGenerator.getMaintenanceId(m)); + return this.getMaintenance(m.getNodeId()); + } + + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/rpctypehelper/QueryResult.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/rpctypehelper/QueryResult.java new file mode 100644 index 000000000..ca90e84fb --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/rpctypehelper/QueryResult.java @@ -0,0 +1,60 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * 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.sqldb.data.rpctypehelper; + +import java.util.List; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.PaginationOutputG; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.connectionlog.list.output.PaginationBuilder; +import org.opendaylight.yangtools.yang.common.Uint32; +import org.opendaylight.yangtools.yang.common.Uint64; + +public class QueryResult<T> { + + private List<T> result; + private PaginationOutputG pagination; + + public QueryResult( List<T> result,long page, long pageSize,long total) { + this.result = result; + + PaginationBuilder x = new PaginationBuilder(); + x.setPage(Uint64.valueOf(page)); + x.setSize(Uint32.valueOf(pageSize)); + x.setTotal(Uint64.valueOf(total)); + pagination = x.build(); + } + + public List<T> getResult() { + return result; + } + + public PaginationOutputG getPagination() { + return pagination; + } + + @Override + public String toString() { + return "QueryResult [result=" + result + ", pagination=" + pagination + "]"; + } + + + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/rpctypehelper/SqlDBQueryByFilter.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/rpctypehelper/SqlDBQueryByFilter.java new file mode 100644 index 000000000..4354b1647 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/rpctypehelper/SqlDBQueryByFilter.java @@ -0,0 +1,373 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * 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.sqldb.data.rpctypehelper; + +import java.util.ArrayList; +import java.util.Arrays; +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.common.YangHelper; +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.onap.ccsdk.features.sdnr.wt.dataprovider.model.NetconfTimeStamp; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.YangHelper2; +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.SortOrder; +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.Pagination; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.entity.input.Sortorder; +import org.opendaylight.yangtools.yang.common.Uint32; +import org.opendaylight.yangtools.yang.common.Uint64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SqlDBQueryByFilter { + + private static final Logger LOG = LoggerFactory.getLogger(SqlDBQueryByFilter.class); + private static final List<String> timestampValueNames = Arrays.asList("timestamp", "time-stamp", "start", "end"); + + private static List<Sortorder> emptySortOrderList = new ArrayList<>(); + private static List<Filter> emptyFilterList = new ArrayList<>(); + + // Derived from input + private long page; + private long pageSize; + private long fromPage; + private List<Filter> filterList; + private List<Sortorder> sortOrder; + + /** + * Process input from RPC into Queries to database + * + * @param input Input from RPC, for test it could be null + */ + public SqlDBQueryByFilter(EntityInput input) { + page = -1; + pageSize = -1; + if (input != null) { + @Nullable + Pagination pagination = input.getPagination(); + if (pagination != null) { + @Nullable Uint64 pageOrNull = YangHelper2.getUint64(pagination.getPage()); + if (pageOrNull != null) { + page = pageOrNull.longValue(); + } + @Nullable Uint32 pageSizeOrNull = YangHelper2.getUint32(pagination.getSize()); + if (pageSizeOrNull != null) { + pageSize = pageSizeOrNull.longValue(); + } + } + } + if (page < 0) + page = 1; + if (pageSize < 0) + pageSize = 1; + + fromPage = (page - 1) * pageSize; + if (fromPage < 0 || pageSize > 10000) + throw new IllegalArgumentException("mismatching input parameters. From:" + fromPage + " size:" + pageSize); + + filterList = YangHelper.getList(input.getFilter()); + if (filterList == null) + filterList = emptyFilterList; + sortOrder = YangHelper.getList(input.getSortorder()); + if (sortOrder == null) + sortOrder = emptySortOrderList; + + } + + public QueryBuilder getQueryBuilderByFilter() { + return getQueryBuilderByFilter(""); + } + + public QueryBuilder getQueryBuilderByFilter(String prefix) { + QueryBuilder queryBuilder = fromFilter(filterList, prefix).from(fromPage).size(pageSize); + setSortOrder(queryBuilder, sortOrder, prefix); + return queryBuilder; + } + + public long getPage() { + return page; + } + + public long getPageSize() { + return pageSize; + } + + public long getPageStartIndex() { + return fromPage; + } + + @Override + public String toString() { + return "QueryByFilter [page=" + page + ", pageSize=" + pageSize + ", fromPage=" + fromPage + ", filterList=" + + filterList + ", sortOrder=" + sortOrder + "]"; + } + + /* + * Private and static implementations + */ + private static QueryBuilder setSortOrder(QueryBuilder query, @Nullable List<Sortorder> sortorder, String prefix) { + if (sortorder != null && sortorder.size() > 0) { + for (Sortorder so : sortorder) { + query.sort(handlePrefix(prefix, so.getProperty()), convert(so.getSortorder())); + } + } + return query; + } + + private static org.onap.ccsdk.features.sdnr.wt.common.database.queries.SortOrder convert(SortOrder sortOrder) { + return sortOrder == SortOrder.Ascending + ? org.onap.ccsdk.features.sdnr.wt.common.database.queries.SortOrder.ASCENDING + : org.onap.ccsdk.features.sdnr.wt.common.database.queries.SortOrder.DESCENDING; + }; + + 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 = NetconfTimeStampImpl.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<Filter> 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 && timestampValueNames.contains(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(handlePrefix(prefix, p), v); + if (q != null) { + return q; + } else { + return QueryBuilders.matchQuery(handlePrefix(prefix, p), v); + } + } else { + return QueryBuilders.matchQuery(handlePrefix(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 && timestampValueNames.contains(p.toLowerCase())) { + tmpQuery = fromTimestampSearchFilter(p, v); + if (tmpQuery != null) { + query.must(tmpQuery); + } else { + query.must(QueryBuilders.regex(handlePrefix(prefix, p), DbFilter.createDatabaseRegex(v))); + } + } else { + query.must(QueryBuilders.regex(handlePrefix(prefix, p), DbFilter.createDatabaseRegex(v))); + } + } else if (DbFilter.isComparisonValid(v)) { + RangeQueryBuilder q = DbFilter.getRangeQuery(handlePrefix(prefix, p), v); + if (q != null) { + query.must(q); + } else { + query.must(QueryBuilders.matchQuery(handlePrefix(prefix, p), v)); + } + } else { + query.must(QueryBuilders.matchQuery(handlePrefix(prefix, p), v)); + } + } + LOG.trace("Query result. {}", query.toJSON()); + return query; + } + } + + private static String handlePrefix(String prefix, String p) { + return (prefix != null ? prefix : "") + p; + } + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBMapper.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBMapper.java new file mode 100644 index 000000000..85d3cfe4b --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBMapper.java @@ -0,0 +1,536 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 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 com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.math.BigInteger; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.sql.rowset.CachedRowSet; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.filters.DBKeyValuePair; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.YangToolsMapper; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.YangToolsMapperHelper; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.mapperextensions.YangToolsBuilderAnnotationIntrospector; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.mapperextensions.YangToolsDeserializerModifier; +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.Entity; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.Enumeration; +import org.opendaylight.yangtools.yang.common.Uint16; +import org.opendaylight.yangtools.yang.common.Uint32; +import org.opendaylight.yangtools.yang.common.Uint64; +import org.opendaylight.yangtools.yang.common.Uint8; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SqlDBMapper { + + private static final Logger LOG = LoggerFactory.getLogger(SqlDBMapper.class); + + private static final Map<Class<?>, String> mariaDBTypeMap = initTypeMap(); + private static final String ODLID_DBTYPE = "VARCHAR(40)"; + private static final String STRING_DBTYPE = "VARCHAR(255)"; + private static final String ENUM_DBTYPE = "VARCHAR(100)"; + public static final String ODLID_DBCOL = "controller-id"; + private static List<Class<?>> numericClasses = Arrays.asList(Byte.class, Integer.class, Long.class, + BigInteger.class, Uint8.class, Uint16.class, Uint32.class, Uint64.class); + private static final YangToolsMapper mapper = new YangToolsMapper(); + public static final String TABLENAME_CONTROLLER = "controller"; + private static final String DEFAULTID_DBTYPE = "int(11)"; + + public static String createTableOdl() { + return "CREATE TABLE IF NOT EXISTS " + TABLENAME_CONTROLLER + " (" + "`id` " + ODLID_DBTYPE + " " + + getColumnOptions("id", ODLID_DBTYPE) + "," + "`desc` " + STRING_DBTYPE + " " + + getColumnOptions("description", STRING_DBTYPE) + "," + "primary key(id))"; + } + + public static <T> String createTable(Class<T> clazz, Entity e) throws UnableToMapClassException { + return createTable(clazz, e, "", false); + } + + public static <T> String createTable(Class<T> clazz, Entity e, String suffix) throws UnableToMapClassException { + return createTable(clazz, e, suffix, false); + } + + public static <T> String createTable(Class<T> clazz, Entity e, boolean autoIndex) throws UnableToMapClassException { + return createTable(clazz, e, "", false); + } + + public static <T> String createTable(Class<T> clazz, Entity e, String suffix, boolean autoIndex) + throws UnableToMapClassException { + StringBuilder sb = new StringBuilder(); + sb.append("CREATE TABLE IF NOT EXISTS `" + e.getName() + suffix + "` (\n"); + if (autoIndex) { + sb.append("`id` " + DEFAULTID_DBTYPE + " " + getColumnOptions("id", DEFAULTID_DBTYPE) + ",\n"); + } else { + sb.append("`id` " + STRING_DBTYPE + " " + getColumnOptions("id", STRING_DBTYPE) + ",\n"); + } + sb.append("`" + ODLID_DBCOL + "` " + ODLID_DBTYPE + " " + getColumnOptions(ODLID_DBCOL, ODLID_DBTYPE) + ",\n"); + for (Method method : getFilteredMethods(clazz, true)) { + Class<?> valueType = method.getReturnType(); + String colName = getColumnName(method); + if (colName.equals("id")) { + continue; + } + String dbType = getDBType(valueType); + String options = getColumnOptions(colName, dbType); + sb.append("`" + colName + "` " + dbType + " " + options + ",\n"); + } + sb.append("primary key(id),"); + sb.append("foreign key(`" + ODLID_DBCOL + "`) references " + TABLENAME_CONTROLLER + "(id)"); + + sb.append(");"); + return sb.toString(); + } + + private static String getColumnOptions(String colName, String dbType) { + StringBuilder options = new StringBuilder(); + if (dbType.contains("VARCHAR")) { + options.append("CHARACTER SET utf8 "); + } + if (colName.equals("id") || colName.equals(ODLID_DBCOL)) { + if (dbType.equals(DEFAULTID_DBTYPE)) { + options.append("NOT NULL AUTO_INCREMENT"); + } else { + options.append("NOT NULL"); + } + } + return options.toString(); + } + + public static List<Method> getFilteredMethods(Class<?> clazz, boolean getterOrSetter) { + Method[] methods = clazz.getMethods(); + List<Method> list = new ArrayList<>(); + for (Method method : methods) { + if (getterOrSetter) { + if (!isGetter(method)) { + continue; + } + } else { + if (!isSetter(method)) { + continue; + } + } + if (ignoreMethod(method, methods, getterOrSetter)) { + continue; + } + list.add(method); + } + return list; + } + + + private static Map<Class<?>, String> initTypeMap() { + Map<Class<?>, String> map = new HashMap<>(); + map.put(String.class, STRING_DBTYPE); + map.put(Boolean.class, "BOOLEAN"); + map.put(Byte.class, "TINYINT"); + map.put(Integer.class, "INTEGER"); + map.put(Long.class, "BIGINT"); + map.put(BigInteger.class, "BIGINT"); + map.put(Uint8.class, "SMALLINT"); + map.put(Uint16.class, "INTEGER"); + map.put(Uint32.class, "BIGINT"); + map.put(Uint64.class, "BIGINT"); //???? + map.put(DateAndTime.class, "DATETIME(3)"); + return map; + } + + private static boolean ignoreMethod(Method method, Method[] classMehtods, boolean getterOrSetter) { + final String name = method.getName(); + if (name.equals("getAugmentations") || name.equals("getImplementedInterface") + || name.equals("implementedInterface") || name.equals("getClass")) { + return true; + } + for (Method cm : classMehtods) { + if (!cm.equals(method) && cm.getName().equals(name)) { + //resolve conflict + return !resolveConflict(method, cm, getterOrSetter); + } + //silicon fix + if (method.getReturnType().equals(Boolean.class) && getterOrSetter) { + if (name.startsWith("get") && cm.getName().startsWith("is") + && cm.getName().endsWith(name.substring(3))) { + return true; + } + } + } + return false; + } + + private static boolean resolveConflict(Method m1, Method m2, boolean getterOrSetter) { + Class<?> p1 = getterOrSetter ? m1.getReturnType() : m1.getParameterTypes()[0]; + Class<?> p2 = getterOrSetter ? m2.getReturnType() : m2.getParameterTypes()[0]; + if (YangToolsBuilderAnnotationIntrospector.isAssignable(p1, p2, Map.class, List.class)) { + return p1.isAssignableFrom(List.class); //prefer List setter + } else if (YangToolsBuilderAnnotationIntrospector.isAssignable(p1, p2, Uint64.class, BigInteger.class)) { + return p1.isAssignableFrom(Uint64.class); + } else if (YangToolsBuilderAnnotationIntrospector.isAssignable(p1, p2, Uint32.class, Long.class)) { + return p1.isAssignableFrom(Uint32.class); + } else if (YangToolsBuilderAnnotationIntrospector.isAssignable(p1, p2, Uint16.class, Integer.class)) { + return p1.isAssignableFrom(Uint16.class); + } else if (YangToolsBuilderAnnotationIntrospector.isAssignable(p1, p2, Uint8.class, Short.class)) { + return p1.isAssignableFrom(Uint8.class); + } + return false; + } + + public static String getColumnName(Method method) { + String camelName = (method.getName().startsWith("get") || method.getName().startsWith("set")) + ? method.getName().substring(3) + : method.getName().substring(2); + return convertCamelToKebabCase(camelName); + } + + private static String getDBType(Class<?> valueType) throws UnableToMapClassException { + String type = mariaDBTypeMap.getOrDefault(valueType, null); + if (type == null) { + if (implementsInterface(valueType, DataObject.class) || implementsInterface(valueType, List.class) + || implementsInterface(valueType, Map.class)) { + return "JSON"; + } + if (implementsInterface(valueType, Enumeration.class)) { + return ENUM_DBTYPE; + } + throw new UnableToMapClassException("no mapping for " + valueType.getName() + " found"); + } + return type; + } + + private static boolean implementsInterface(Class<?> valueType, Class<?> iftoImpl) { + return iftoImpl.isAssignableFrom(valueType); + } + + private static boolean isGetter(Method method) { + return method.getName().startsWith("get") || method.getName().startsWith("is") + || method.getName().startsWith("do"); + } + + private static boolean isSetter(Method method) { + return method.getName().startsWith("set"); + } + + /** + * @param input string in Camel Case + * @return String in Kebab case Inspiration from KebabCaseStrategy class of com.fasterxml.jackson.databind with an + * additional condition to handle numbers as well Using QNAME would have been a more fool proof solution, + * however it can lead to performance problems due to usage of Java reflection + */ + private static String convertCamelToKebabCase(String input) { + if (input == null) + return input; // garbage in, garbage out + int length = input.length(); + if (length == 0) { + return input; + } + + StringBuilder result = new StringBuilder(length + (length >> 1)); + + int upperCount = 0; + + for (int i = 0; i < length; ++i) { + char ch = input.charAt(i); + char lc = Character.toLowerCase(ch); + + if (lc == ch) { // lower-case letter means we can get new word + // but need to check for multi-letter upper-case (acronym), where assumption + // is that the last upper-case char is start of a new word + if ((upperCount > 1)) { + // so insert hyphen before the last character now + result.insert(result.length() - 1, '-'); + } else if ((upperCount == 1) && Character.isDigit(ch) && i != length - 1) { + result.append('-'); + } + upperCount = 0; + } else { + // Otherwise starts new word, unless beginning of string + if ((upperCount == 0) && (i > 0)) { + result.append('-'); + } + ++upperCount; + } + result.append(lc); + } + return result.toString(); + } + + public static class UnableToMapClassException extends Exception { + + private static final long serialVersionUID = 1L; + + public UnableToMapClassException(String message) { + super(message); + } + + } + + public static String escape(Object o) { + return escape(o.toString()); + } + + public static String escape(String o) { + return o.replace("'", "\'"); + } + + public static boolean isComplex(Class<?> valueType) { + return DataObject.class.isAssignableFrom(valueType) || List.class.isAssignableFrom(valueType); + } + + public static Object getNumericValue(Object value, Class<?> valueType) { + if (valueType.equals(Byte.class) || valueType.equals(Integer.class) || valueType.equals(Long.class)) { + return value; + } + if (valueType.equals(Uint8.class) || valueType.equals(Uint16.class) || valueType.equals(Uint32.class) + || valueType.equals(Uint64.class)) { + return ((Number) value).longValue(); + } + return value; + } + + public static Object bool2int(Object invoke) { + return Boolean.TRUE.equals(invoke) ? 1 : 0; + } + + public static boolean isBoolean(Class<?> valueType) { + return valueType.equals(Boolean.class); + } + + public static boolean isNumeric(Class<?> valueType) { + return numericClasses.contains(valueType); + + } + + private static boolean isDateTime(Class<?> valueType) { + return valueType.equals(DateAndTime.class); + } + + private static boolean isYangEnum(Class<?> valueType) { + return YangToolsMapperHelper.implementsInterface(valueType, Enumeration.class); + } + + public static <T extends DataObject> List<T> read(CachedRowSet data, Class<T> clazz) + throws JsonMappingException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, + InstantiationException, SecurityException, NoSuchMethodException, JsonProcessingException, SQLException { + return read(data, clazz, null); + } + + public static <T extends DataObject> List<T> read(ResultSet data, Class<T> clazz) + throws JsonMappingException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, + InstantiationException, SecurityException, NoSuchMethodException, JsonProcessingException, SQLException { + return read(data, clazz, null); + } + + @SuppressWarnings("unchecked") + public static <T> List<T> read(CachedRowSet data, Class<T> clazz, String column) throws IllegalAccessException, + IllegalArgumentException, InvocationTargetException, SQLException, InstantiationException, + SecurityException, NoSuchMethodException, JsonMappingException, JsonProcessingException { + + List<T> list = new ArrayList<>(); + while (data.next()) { + if (column == null) { + Builder<T> builder = findPOJOBuilder(clazz); + Class<?> argType; + String col; + for (Method m : getFilteredMethods(builder.getClass(), false)) { + argType = m.getParameterTypes()[0]; + col = getColumnName(m); + m.setAccessible(true); + m.invoke(builder, getValueOrDefault(data, col, argType, null)); + } + list.add(builder.build()); + } else { + Object value = getValueOrDefault(data, column, clazz, null); + if (value != null) { + list.add((T) value); + } + } + } + return list; + } + + @SuppressWarnings("unchecked") + public static <T> List<T> read(ResultSet data, Class<T> clazz, String column) throws IllegalAccessException, + IllegalArgumentException, InvocationTargetException, SQLException, InstantiationException, + SecurityException, NoSuchMethodException, JsonMappingException, JsonProcessingException { + + List<T> list = new ArrayList<>(); + while (data.next()) { + if (column == null) { + Builder<T> builder = findPOJOBuilder(clazz); + Class<?> argType; + String col; + for (Method m : getFilteredMethods(builder.getClass(), false)) { + argType = m.getParameterTypes()[0]; + col = getColumnName(m); + m.setAccessible(true); + m.invoke(builder, getValueOrDefault(data, col, argType, null)); + } + list.add(builder.build()); + } else { + Object value = getValueOrDefault(data, column, clazz, null); + if (value != null) { + list.add((T) value); + } + } + } + return list; + } + + @SuppressWarnings("unchecked") + private static <T> Builder<T> findPOJOBuilder(Class<T> ac) throws InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, SecurityException, NoSuchMethodException { + try { + String builder = null; + + if (ac.isInterface()) { + String clsName = ac.getName(); + if (clsName.endsWith("Entity")) { + clsName = clsName.substring(0, clsName.length() - 6); + } + builder = clsName + "Builder"; + } + if (builder != null) { + Class<?> innerBuilder = YangToolsMapperHelper.findClass(builder); + Class<Builder<T>> builderClass = (Class<Builder<T>>) innerBuilder; + return builderClass.getDeclaredConstructor().newInstance(); + } + } catch (ClassNotFoundException e) { + + } + return null; + } + + private static Object getValueOrDefault(CachedRowSet data, String col, Class<?> dstType, Object defaultValue) + throws SQLException, JsonMappingException, JsonProcessingException { + if (isBoolean(dstType)) { + return data.getBoolean(col); + } else if (isNumeric(dstType)) { + return getNumeric(dstType, data.getLong(col)); + } else if (String.class.equals(dstType)) { + return data.getString(col); + } else if (isYangEnum(dstType)) { + return getYangEnum(data.getString(col), dstType); + } else if (isDateTime(dstType)) { + String v = data.getString(col); + return v == null || v.equals("null") ? null : DateAndTime.getDefaultInstance(v.replace(" ", "T") + "Z"); + } else if (isComplex(dstType)) { + String v = data.getString(col); + + return (v == null || v.toLowerCase().equals("null")) ? null : mapper.readValue(v, dstType); + } + return defaultValue; + } + + private static Object getValueOrDefault(ResultSet data, String col, Class<?> dstType, Object defaultValue) + throws SQLException, JsonMappingException, JsonProcessingException { + if (isBoolean(dstType)) { + return data.getBoolean(col); + } else if (isNumeric(dstType)) { + return getNumeric(dstType, data.getLong(col)); + } else if (String.class.equals(dstType)) { + return data.getString(col); + } else if (isYangEnum(dstType)) { + return getYangEnum(data.getString(col), dstType); + } else if (isDateTime(dstType)) { + String v = data.getString(col); + return v == null || v.equals("null") ? null : DateAndTime.getDefaultInstance(v.replace(" ", "T") + "Z"); + } else if (isComplex(dstType)) { + String v = data.getString(col); + + return (v == null || v.toLowerCase().equals("null")) ? null : mapper.readValue(v, dstType); + } + return defaultValue; + } + + + + private static Object getYangEnum(String value, Class<?> dstType) { + if (value == null || value.equals("null")) { + return null; + } + try { + return YangToolsDeserializerModifier.parseEnum(value, dstType); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException + | SecurityException e) { + LOG.warn("unable to parse enum value '{}' to class {}: ", value, dstType, e); + } + return null; + } + + private static Object getNumeric(Class<?> dstType, long value) { + if (dstType.equals(Uint64.class)) { + return Uint64.valueOf(value); + } else if (dstType.equals(Uint32.class)) { + return Uint32.valueOf(value); + } else if (dstType.equals(Uint16.class)) { + return Uint16.valueOf(value); + } else if (dstType.equals(Uint16.class)) { + return Uint8.valueOf(value); + } else if (dstType.equals(Long.class)) { + return Long.valueOf(value); + } else if (dstType.equals(Integer.class)) { + return Long.valueOf(value).intValue(); + } else if (dstType.equals(Byte.class)) { + return Long.valueOf(value).byteValue(); + } + return null; + } + + public static DBKeyValuePair<String> getEscapedKeyValue(Method m, String col, Object value) + throws JsonProcessingException { + Class<?> valueType = m.getReturnType(); + String svalue = null; + if (isBoolean(valueType)) { + svalue = String.valueOf(bool2int(value)); + } else if (isNumeric(valueType)) { + svalue = String.valueOf(getNumericValue(value, valueType)); + } else if (isDateTime(valueType)) { + svalue = "'" + getDateTimeValue((DateAndTime) value) + "'"; + } else if (isComplex(valueType)) { + svalue = "'" + escape(mapper.writeValueAsString(value)) + "'"; + } else { + svalue = "'" + escape(value) + "'"; + } + return new DBKeyValuePair<String>("`" + col + "`", svalue); + } + + private static String getDateTimeValue(DateAndTime value) { + String s = value.getValue(); + if (s.endsWith("Z")) { + s = s.substring(0, s.length() - 1).replace("T", " "); + } else if (s.contains("+")) { + s = s.substring(0, s.indexOf("+")).replace("T", " "); + } + return s; + } + + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriter.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriter.java new file mode 100644 index 000000000..d033e45f7 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriter.java @@ -0,0 +1,246 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 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 com.fasterxml.jackson.core.JsonProcessingException; +import java.lang.reflect.InvocationTargetException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import org.eclipse.jdt.annotation.Nullable; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.SqlDBClient; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.rpctypehelper.QueryResult; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.DeleteQuery; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.InsertQuery; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.SelectQuery; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.SqlQuery; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.UpdateQuery; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.UpsertQuery; +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.EntityInput; +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.yangtools.yang.binding.DataObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SqlDBReaderWriter<T extends DataObject> { + + private static final Logger LOG = LoggerFactory.getLogger(SqlDBReaderWriter.class); + + protected final Entity entity; + private final Class<T> clazz; + protected final SqlDBClient dbService; + private final String dbName; + protected final String controllerId; + protected final String tableName; + + public SqlDBReaderWriter(SqlDBClient dbService, Entity e, String dbSuffix, Class<T> clazz, String dbName, + String controllerId) { + this.dbService = dbService; + this.entity = e; + this.clazz = clazz; + this.dbName = dbName; + this.tableName = this.entity.getName() + dbSuffix; + this.controllerId = controllerId; + } + + public long count(List<Filter> filter) throws SQLException { + String query; + if (filter == null || filter.isEmpty()) { + query = String.format("SELECT table_rows FROM `information_schema`.`tables` " + + "WHERE `table_schema` = '%s' AND `table_name` = '%s'", this.dbName, this.tableName); + } else { + query = String.format("SELECT COUNT(`id`) FROM `%s` %s", this.tableName, + SqlQuery.getWhereExpression(filter)); + } + ResultSet data = this.dbService.read(query); + long cnt = 0; + if (data.next()) { + cnt = data.getLong(1); + } + return cnt; + } + + public long count(List<Filter> list, String controllerId) throws SQLException { + if (list == null) { + list = new ArrayList<>(); + } + Optional<Filter> cFilter = + list.stream().filter(e -> SqlDBMapper.ODLID_DBCOL.equals(e.getProperty())).findFirst(); + if (!cFilter.isEmpty()) { + list.remove(cFilter.get()); + } + if (controllerId != null) { + list.add(new FilterBuilder().setProperty(SqlDBMapper.ODLID_DBCOL).setFiltervalue(this.controllerId) + .build()); + } + return this.count(list); + } + + public QueryResult<T> getData(EntityInput input) { + SelectQuery query = new SelectQuery(this.tableName, input, this.controllerId); + LOG.info("query={}", query.toSql()); + try { + ResultSet data = this.dbService.read(query.toSql()); + List<T> mappedData = SqlDBMapper.read(data, clazz); + long total = this.count(input.getFilter() != null ? new ArrayList<>(input.getFilter().values()) : null, + this.controllerId); + return new QueryResult<T>(mappedData, query.getPage(), query.getPageSize(), total); + } catch (SQLException | IllegalAccessException | IllegalArgumentException | InvocationTargetException + | InstantiationException | SecurityException | NoSuchMethodException | JsonProcessingException e) { + LOG.warn("problem reading data {}: ", this.entity, e); + } + return null; + } + + + + public <S extends DataObject> String write(S object, String id) { + if (id == null) { + return this.writeWithoutId(object); + } + InsertQuery<S> query = new InsertQuery<S>(this.entity, object, this.controllerId); + query.setId(id); + boolean success = false; + try { + success = this.dbService.write(query.toSql()); + } catch (SQLException e) { + LOG.warn("problem writing data into db: ", e); + } + + return success ? id : null; + } + + private <S extends DataObject> String writeWithoutId(S object) { + + InsertQuery<S> query = new InsertQuery<S>(this.entity, object, this.controllerId); + try { + return this.dbService.writeAndReturnId(query.toSql()); + } catch (SQLException e) { + LOG.warn("problem writing data into db: ", e); + } + return null; + } + + public <S extends DataObject> String update(S object, String id) { + UpdateQuery<S> query = new UpdateQuery<S>(this.entity, object, this.controllerId); + query.setId(id); + String insertedId = null; + try { + Connection connection = this.dbService.getConnection(); + PreparedStatement stmt = connection.prepareStatement(query.toSql()); + stmt.execute(); + + int affectedRows = stmt.getUpdateCount(); + connection.close(); + if (affectedRows > 0) { + insertedId = id; + } + } catch (SQLException e) { + LOG.warn("problem writing data into db: ", e); + } + + return insertedId; + } + + public <S extends DataObject> String updateOrInsert(S object, String id) { + UpsertQuery<S> query = new UpsertQuery<S>(this.entity, object, this.controllerId); + query.setId(id); + String insertedId = null; + LOG.info("query={}", query.toSql()); + try { + Connection connection = this.dbService.getConnection(); + PreparedStatement stmt = connection.prepareStatement(query.toSql()); + stmt.execute(); + + int affectedRows = stmt.getUpdateCount(); + connection.close(); + if (affectedRows > 0) { + insertedId = id; + } + } catch (SQLException e) { + LOG.warn("problem writing data into db: ", e); + } + return insertedId; + } + + public SqlDBReaderWriter<T> setWriteInterface(Class<? extends DataObject> writeInterfaceClazz) { + LOG.debug("Set write interface to {}", writeInterfaceClazz); + if (writeInterfaceClazz == null) { + throw new IllegalArgumentException("Null not allowed here."); + } + + // this.writeInterfaceClazz = writeInterfaceClazz; + return this; + } + + public int remove(List<Filter> filters) { + DeleteQuery query = new DeleteQuery(this.entity, filters); + int affectedRows = 0; + try { + Connection connection = this.dbService.getConnection(); + PreparedStatement stmt = connection.prepareStatement(query.toSql()); + stmt.execute(); + affectedRows = stmt.getUpdateCount(); + connection.close(); + } catch (SQLException e) { + LOG.warn("problem execute delete query: ", e); + } + return affectedRows; + } + + public int remove(@Nullable String id) { + return this.remove(Arrays.asList(new FilterBuilder().setProperty("id").setFiltervalue(id).build())); + } + + public <S extends DataObject> List<S> readAll(Class<S> clazz) { + SelectQuery query = new SelectQuery(this.tableName); + try { + ResultSet data = this.dbService.read(query.toSql()); + List<S> mappedData = SqlDBMapper.read(data, clazz); + return mappedData; + } catch (SQLException | IllegalAccessException | IllegalArgumentException | InvocationTargetException + | InstantiationException | SecurityException | NoSuchMethodException | JsonProcessingException e) { + LOG.warn("problem reading data {}: ", this.entity, e); + } + return null; + } + + public List<String> readAll(String key) { + SelectQuery query = new SelectQuery(this.tableName, key, this.controllerId).groupBy(key); + try { + ResultSet data = this.dbService.read(query.toSql()); + List<String> mappedData = SqlDBMapper.read(data, String.class, key); + return mappedData; + } catch (SQLException | IllegalAccessException | IllegalArgumentException | InvocationTargetException + | InstantiationException | SecurityException | NoSuchMethodException | JsonProcessingException e) { + LOG.warn("problem reading data {}: ", this.entity, e); + } + return null; + } +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriterFault.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriterFault.java new file mode 100644 index 000000000..2d4e26eea --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriterFault.java @@ -0,0 +1,43 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 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 java.util.List; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.SqlDBClient; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Entity; +import org.opendaylight.yangtools.yang.binding.DataObject; + +public class SqlDBReaderWriterFault<T extends DataObject> extends SqlDBReaderWriter<T> { + + private static final String NODE_KEY = "node-id"; + + public SqlDBReaderWriterFault(SqlDBClient dbService, Entity e, String dbSuffix, Class<T> clazz, String dbName, + String controllerId) { + super(dbService, e, dbSuffix, clazz, dbName, controllerId); + } + + public List<String> getAllNodes() { + + return this.readAll(NODE_KEY); + } + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriterPm.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriterPm.java new file mode 100644 index 000000000..f0ce268db --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriterPm.java @@ -0,0 +1,133 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 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 com.fasterxml.jackson.core.JsonProcessingException; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.SqlDBClient; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.rpctypehelper.QueryResult; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.SelectQuery; +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.Entity; +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.PmdataEntity; +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.FilterKey; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SqlDBReaderWriterPm<T extends DataObject> extends SqlDBReaderWriter<T> { + + private final Logger LOG = LoggerFactory.getLogger(SqlDBReaderWriterPm.class); + + private static final String UUID_KEY = "uuid-interface"; + private static final String NODE_KEY = "node-name"; + private static final String KEY = "node-name"; + + private static final FilterKey FILTERKEY = new FilterKey(KEY); + + public SqlDBReaderWriterPm(SqlDBClient dbService, Entity e, String dbSuffix, Class<T> clazz, String dbName, + String controllerId) { + super(dbService, e, dbSuffix, clazz, dbName, controllerId); + } + + /** + * get aggregated list of ltps for filter NODE_KEY + * + * @param input + * @return + * @throws IOException + */ + public QueryResult<String> getDataLtpList(EntityInput input) throws IOException { + + SelectQuery query = new SelectQuery(this.tableName, UUID_KEY, this.controllerId).groupBy(UUID_KEY); + query.setPagination(input.getPagination()); + Map<FilterKey, Filter> filter = input.nonnullFilter(); + if (!filter.containsKey(FILTERKEY)) { + String msg = "no node-name in filter found "; + LOG.debug(msg); + throw new IllegalArgumentException(msg); + } + for (Filter f : filter.values()) { + query.addFilter(f.getProperty(), f.getFiltervalue()); + } + + + try { + ResultSet data = this.dbService.read(query.toSql()); + List<String> mappedData = SqlDBMapper.read(data, String.class, UUID_KEY); + long total = this.count(input.getFilter() != null ? new ArrayList<>(input.getFilter().values()) : null, + this.controllerId); + return new QueryResult<String>(mappedData, query.getPage(), query.getPageSize(), total); + } catch (SQLException | IllegalAccessException | IllegalArgumentException | InvocationTargetException + | InstantiationException | SecurityException | NoSuchMethodException | JsonProcessingException e) { + LOG.warn("problem reading ltp list: ", e); + } + return null; + } + + /** + * get aggregated devices list + * + * @param input filter should be empty/no filter handled, only sortorder for KEY ('node-name') + * @return + * @throws IOException + */ + public QueryResult<String> getDataDeviceList(EntityInput input) throws IOException { + + SelectQuery query = new SelectQuery(this.tableName, NODE_KEY, this.controllerId).groupBy(NODE_KEY); + query.setPagination(input.getPagination()); + Map<FilterKey, Filter> filter = input.getFilter(); + if (filter != null) { + for (Filter f : filter.values()) { + query.addFilter(f.getProperty(), f.getFiltervalue()); + } + } + + try { + ResultSet data = this.dbService.read(query.toSql()); + List<String> mappedData = SqlDBMapper.read(data, String.class, NODE_KEY); + long total = this.count(input.getFilter() != null ? new ArrayList<>(input.getFilter().values()) : null, + this.controllerId); + return new QueryResult<String>(mappedData, query.getPage(), query.getPageSize(), total); + } catch (SQLException | IllegalAccessException | IllegalArgumentException | InvocationTargetException + | InstantiationException | SecurityException | NoSuchMethodException | JsonProcessingException e) { + LOG.warn("problem reading device list: ", e); + } + return null; + } + + public void write(PmdataEntity pmData) { + DateAndTime date = pmData.getTimeStamp(); + final String id = String.format("%s/%s/%s", pmData.getNodeName(), pmData.getUuidInterface(), + date != null ? date.getValue() : "null"); + this.updateOrInsert(pmData, id); + } + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBStatusReader.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBStatusReader.java new file mode 100644 index 000000000..c98ba388d --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBStatusReader.java @@ -0,0 +1,132 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 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 java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Arrays; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.SqlDBClient; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.rpctypehelper.QueryResult; +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.Entity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SeverityType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.status.output.Data; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.status.output.DataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.status.entity.FaultsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.status.entity.NetworkElementConnectionsBuilder; +import org.opendaylight.yangtools.yang.common.Uint32; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SqlDBStatusReader { + + private final Logger LOG = LoggerFactory.getLogger(SqlDBStatusReader.class); + + private final SqlDBClient dbClient; + private final String controllerId; + + public SqlDBStatusReader(SqlDBClient dbClient, String controllerId) { + this.dbClient = dbClient; + this.controllerId = controllerId; + } + + public QueryResult<Data> getDataStatus() { + String selectQuery = createCountQuery("severity", Entity.Faultcurrent, this.controllerId); + long criticalCount = 0; + long majorCount = 0; + long minorCount = 0; + long warningCount = 0; + ResultSet data; + try { + data = this.dbClient.read(selectQuery); + String severity; + while (data.next()) { + severity = data.getString(1); + if (severity != null) { + if (severity.equals(SeverityType.Critical.getName())) { + criticalCount = data.getLong(2); + } else if (severity.equals(SeverityType.Major.getName())) { + majorCount = data.getLong(2); + } else if (severity.equals(SeverityType.Minor.getName())) { + minorCount = data.getLong(2); + } else if (severity.equals(SeverityType.Warning.getName())) { + warningCount = data.getLong(2); + } + + } + } + } catch (SQLException e) { + LOG.warn("problem reading status:", e); + } + DataBuilder builder = new DataBuilder().setFaults( + new FaultsBuilder().setCriticals(Uint32.valueOf(criticalCount)).setMajors(Uint32.valueOf(majorCount)) + .setMinors(Uint32.valueOf(minorCount)).setWarnings(Uint32.valueOf(warningCount)).build()); + selectQuery = createCountQuery("status", Entity.NetworkelementConnection, this.controllerId); + NetworkElementConnectionsBuilder neBuilder = new NetworkElementConnectionsBuilder(); + String state; + long connectedCount = 0, connectingCount = 0, disconnectedCount = 0, mountedCount = 0, unableToConnectCount = 0, + undefinedCount = 0, unmountedCount = 0; + long cnt; + try { + data = this.dbClient.read(selectQuery); + while (data.next()) { + state = data.getString(1); + cnt = data.getLong(2); + if (state != null) { + if (state.equals(ConnectionLogStatus.Connected.getName())) { + connectedCount = cnt; + } else if (state.equals(ConnectionLogStatus.Connecting.getName())) { + connectingCount = cnt; + } else if (state.equals(ConnectionLogStatus.Disconnected.getName())) { + disconnectedCount = cnt; + } else if (state.equals(ConnectionLogStatus.Mounted.getName())) { + mountedCount = cnt; + } else if (state.equals(ConnectionLogStatus.UnableToConnect.getName())) { + unableToConnectCount = cnt; + } else if (state.equals(ConnectionLogStatus.Undefined.getName())) { + undefinedCount = cnt; + } else if (state.equals(ConnectionLogStatus.Unmounted.getName())) { + unmountedCount = cnt; + } + } + } + } catch (SQLException e) { + LOG.warn("problem reading status:", e); + } + neBuilder.setConnected(Uint32.valueOf(connectedCount)).setConnecting(Uint32.valueOf(connectingCount)) + .setDisconnected(Uint32.valueOf(disconnectedCount)).setMounted(Uint32.valueOf(mountedCount)) + .setTotal(Uint32.valueOf(connectedCount + connectingCount + disconnectedCount + mountedCount + + unableToConnectCount + undefinedCount + unmountedCount)) + .setUnableToConnect(Uint32.valueOf(unableToConnectCount)).setUndefined(Uint32.valueOf(undefinedCount)) + .setUnmounted(Uint32.valueOf(unmountedCount)); + builder.setNetworkElementConnections(neBuilder.build()); + return new QueryResult<Data>(Arrays.asList(builder.build()), 1, 1, 1); + } + + private static String createCountQuery(String key, Entity e, String controllerId) { + return String.format("SELECT `%s`, COUNT(`%s`) " + "FROM `%s` " + "%s " + "GROUP BY `%s`;", key, key, + e.getName(), + controllerId != null ? String.format("WHERE `%s`='%s'", SqlDBMapper.ODLID_DBCOL, controllerId) : "", + key); + } + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/CountQuery.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/CountQuery.java new file mode 100644 index 000000000..c499fefb8 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/CountQuery.java @@ -0,0 +1,82 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 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.query; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +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.Entity; +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.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; + +public class CountQuery implements SqlQuery { + + private final Entity entity; + private final List<Filter> filters; + private final String countField; + public CountQuery(Entity e) { + this(e, "*", null); + } + public CountQuery(Entity e, String controllerId) { + this(e, "*", controllerId); + } + public CountQuery(Entity e, String countField, String controllerId) { + this.entity = e; + this.countField = countField; + this.filters = new ArrayList<>(); + if (controllerId != null) { + this.addFilter(SqlDBMapper.ODLID_DBCOL, controllerId); + } + } + + public CountQuery(Entity e, EntityInput input) { + this(e, input, null); + } + + public CountQuery(Entity e, EntityInput input, String controllerId) { + this(e); + Map<FilterKey, Filter> filter = input != null ? input.getFilter() : null; + if (filter != null && filter.size() > 0) { + this.filters.addAll(filters); + } + if (controllerId != null) { + this.addFilter(SqlDBMapper.ODLID_DBCOL, controllerId); + } + } + + public void addFilter(String property, String filtervalue) { + this.filters.add(new FilterBuilder().setProperty(property).setFiltervalue(filtervalue).build()); + + } + + @Override + public String toSql() { + StringBuilder sb = new StringBuilder(); + sb.append(String.format("SELECT COUNT(`%s`) FROM `%s`", this.countField, this.entity.getName())); + sb.append(SqlQuery.getWhereExpression(this.filters)); + return sb.toString(); + } + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/DeleteQuery.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/DeleteQuery.java new file mode 100644 index 000000000..f49c78a29 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/DeleteQuery.java @@ -0,0 +1,44 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 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.query; + +import java.util.List; +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.entity.input.Filter; + +public class DeleteQuery implements SqlQuery { + + + private final Entity entity; + private final List<Filter> filters; + + public DeleteQuery(Entity e, List<Filter> filters) { + this.entity = e; + this.filters = filters; + } + + @Override + public String toSql() { + return String.format("DELETE FROM `%s` %s", this.entity.getName(), SqlQuery.getWhereExpression(this.filters)); + } + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/InsertQuery.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/InsertQuery.java new file mode 100644 index 000000000..108888ad0 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/InsertQuery.java @@ -0,0 +1,111 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 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.query; + +import com.fasterxml.jackson.core.JsonProcessingException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBMapper; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.filters.DBKeyValuePair; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Entity; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class InsertQuery<T extends DataObject> implements SqlQuery { + + private final Logger LOG = LoggerFactory.getLogger(InsertQuery.class); + + protected final Entity entity; + private final String controllerId; + private final T object; + private final boolean ignoreNull; + private String id; + + public InsertQuery(Entity e, T object, String controllerId) { + this.entity = e; + this.controllerId = controllerId; + this.object = object; + this.ignoreNull = true; + this.id = null; + + } + + @Override + public String toSql() { + try { + return this.toSqlWithError(); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException + | JsonProcessingException e) { + LOG.warn("unable to create insert statement for table {} from object {}: ", this.entity, this.object, e); + } + return null; + } + + protected String toSqlWithError() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, + JsonProcessingException { + Class<?> cls = this.object.getClass(); + List<DBKeyValuePair<String>> kvps = new ArrayList<>(); + List<String> cols = new ArrayList<>(); + List<String> args = new ArrayList<>(); + Object value; + String col; + StringBuilder sb = new StringBuilder(); + sb.append("INSERT INTO `" + entity.getName() + "` ("); + for (Method m : SqlDBMapper.getFilteredMethods(cls, true)) { + + m.setAccessible(true); + value = m.invoke(this.object); + col = SqlDBMapper.getColumnName(m); + if (col.equals("id") && this.id != null) { + value = this.id; + } + if (ignoreNull && value == null) { + continue; + } + DBKeyValuePair<String> kvp = SqlDBMapper.getEscapedKeyValue(m,col, value); + cols.add(kvp.getKey()); + args.add(kvp.getValue()); + kvps.add(kvp); + } + if (this.id != null && !cols.contains("`id`")) { + cols.add("`id`"); + args.add("'"+this.id+"'"); + } + args.add("'"+this.controllerId+"'"); + sb.append( String.join(",", cols)); + sb.append(",`" + SqlDBMapper.ODLID_DBCOL + "`) VALUES ("); + sb.append( String.join(",", args)+" )"); + this.appendAdditionalToQuery(sb,kvps); + return sb.toString(); + } + + protected void appendAdditionalToQuery(StringBuilder sb, List<DBKeyValuePair<String>> keyValues) { + + } + + public void setId(String id) { + this.id = id; + } +} 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 new file mode 100644 index 000000000..800150814 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/SelectQuery.java @@ -0,0 +1,166 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 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.query; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SortOrder; +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.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; + +public class SelectQuery implements SqlQuery { + + private static final long DEFAULT_PAGESIZE = 20; + private static final long DEFAULT_PAGE = 1; + private static final List<String> TIMESTAMPPROPERTYNAMES = Arrays.asList("timestamp", "time-stamp", "start", "end"); + private final String tableName; + private final List<Filter> filters; + private final List<String> sortExpressions; + private long page; + private long pageSize; + private final List<String> fields; + private final List<String> groups; + + public SelectQuery(String tableName) { + this(tableName, Arrays.asList("*"), null); + } + + public SelectQuery(String tableName, List<String> fields, String controllerId) { + this.tableName = tableName; + this.fields = fields; + this.filters = new ArrayList<>(); + this.sortExpressions = new ArrayList<>(); + this.groups = new ArrayList<>(); + this.page = DEFAULT_PAGE; + this.pageSize = DEFAULT_PAGESIZE; + if (controllerId != null) { + this.addFilter(SqlDBMapper.ODLID_DBCOL, controllerId); + } + } + + public SelectQuery(String tableName, String field, String controllerId) { + this(tableName, Arrays.asList(field), controllerId); + } + + public SelectQuery(String tableName, EntityInput input) { + this(tableName, input, null); + } + + public SelectQuery(String tableName, EntityInput input, String controllerId) { + this(tableName); + Map<FilterKey, Filter> filter = input != null ? input.getFilter() : null; + if (filter != null && filter.size() > 0) { + for (Filter f : filter.values()) { + this.addFilter(f.getProperty(), f.getFiltervalue()); + } + } + if (controllerId != null) { + this.addFilter(SqlDBMapper.ODLID_DBCOL, controllerId); + } + + Map<SortorderKey, Sortorder> so = input.getSortorder(); + if (so != null && so.size() > 0) { + for (Sortorder s : so.values()) { + this.addSortOrder(s.getProperty(), + s.getSortorder() == SortOrder.Ascending ? "ASC" : "DESC"); + } + } + Pagination pagination = input.getPagination(); + if (pagination != null) { + this.setPagination(pagination.getPage().longValue(), pagination.getSize().longValue()); + } else { + this.setPagination(1, 30); + } + + } + + public void addFilter(String property, String filtervalue) { + this.filters.add(new FilterBuilder().setProperty(property).setFiltervalue(filtervalue).build()); + + } + + public void addSortOrder(String col, String order) { + this.sortExpressions.add(String.format("`%s` %s", col, order)); + } + + public void setPagination(long page, long pageSize) { + this.page = page; + this.pageSize = pageSize; + } + + public void setPagination(@Nullable Pagination pagination) { + long page = DEFAULT_PAGE; + long pageSize = DEFAULT_PAGESIZE; + if(pagination!=null) { + if(pagination.getPage()!=null) { + page = pagination.getPage().longValue(); + } + if(pagination.getSize()!=null) { + pageSize = pagination.getSize().longValue(); + } + } + this.setPagination(page, pageSize); + + } + + @Override + public String toSql() { + StringBuilder sb = new StringBuilder(); + if (this.fields.size() == 1 && this.fields.contains("*")) { + sb.append(String.format("SELECT * FROM `%s`", this.tableName)); + } else { + sb.append(String.format("SELECT `%s` FROM `%s`", String.join("`,`", this.fields), this.tableName)); + } + sb.append(SqlQuery.getWhereExpression(this.filters)); + if (this.groups.size() > 0) { + sb.append(String.format(" GROUP BY `%s`", String.join("`,`", this.groups))); + } + if (this.sortExpressions.size() > 0) { + sb.append(" ORDER BY " + String.join(",", this.sortExpressions)); + } + sb.append(String.format(" LIMIT %d,%d;", (this.page - 1) * this.pageSize, this.pageSize)); + return sb.toString(); + } + + public long getPage() { + return this.page; + } + + public long getPageSize() { + return this.pageSize; + } + + public SelectQuery groupBy(String group) { + this.groups.add(group); + return this; + } + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/SqlQuery.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/SqlQuery.java new file mode 100644 index 000000000..95e360540 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/SqlQuery.java @@ -0,0 +1,351 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 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.query; + +import java.util.ArrayList; +import java.util.Arrays; +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.common.database.data.DbFilter; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.filters.DBFilterKeyValuePair; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.filters.RangeSqlDBFilter; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.filters.RegexSqlDBFilter; +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.entity.input.Filter; + +public interface SqlQuery { + + String toSql(); + + static final List<String> TIMESTAMPPROPERTYNAMES = Arrays.asList("timestamp", "time-stamp", "start", "end"); + static final String MARIADB_TIMESTAMP_REPLACER = "0000-00-00 00:00:00.000"; + static final String NETCONF_TIMESTAMP_REPLACER = "0000-00-00T00:00:00.000Z"; + static final String MARIADB_TIMESTAMP_REPLACER_MIN = "0000-00-00 00:00:00"; + static final int MARIADB_TIMESTAMP_REPLACER_MIN_LENGTH = MARIADB_TIMESTAMP_REPLACER_MIN.length(); + static final int MARIADB_TIMESTAMP_REPLACER_MAX_LENGTH = MARIADB_TIMESTAMP_REPLACER.length(); + + public static String getWhereExpression(List<Filter> filters) { + if (filters == null) { + return ""; + } + StringBuilder sb = new StringBuilder(); + if (filters.size() > 0) { + + sb.append(" WHERE (" + getFilterExpression(filters.get(0)) + ")"); + for (int i = 1; i < filters.size(); i++) { + sb.append(" AND (" + getFilterExpression(filters.get(i)) + ")"); + } + } + return sb.toString(); + } + + public static String getFilterExpression(Filter filter) { + String property = filter.getProperty(); + List<String> values = collectValues(filter.getFiltervalue(), filter.getFiltervalues()); + if (values.size() == 1) { + return getFilterExpression(property, values.get(0)); + } else if (values.size() > 1) { + StringBuilder sb = new StringBuilder(); + sb.append(getFilterExpression(property, values.get(0))); + for (int i = 1; i < values.size(); i++) { + sb.append(" OR "); + sb.append(getFilterExpression(property, values.get(i))); + } + return sb.toString(); + } + return null; + } + + public static String getFilterExpression(String property, String value) { + String filter = null;; + if (DbFilter.hasSearchParams(value)) { + if (TIMESTAMPPROPERTYNAMES.contains(property.toLowerCase())) { + if (DbFilter.isComparisonValid(value)) { + filter = getComparisonFilter(property, value, true); + } else { + filter = fromTimestampSearchFilter(property, value); + } + if (filter != null) { + return filter; + } + } + return new RegexSqlDBFilter(property, value).getFilterExpression(); + } else if (DbFilter.isComparisonValid(value)) { + filter = getComparisonFilter(property, value, TIMESTAMPPROPERTYNAMES.contains(property.toLowerCase())); + if (filter != null) { + return filter; + } + } + return new DBFilterKeyValuePair(property, value).getFilterExpression(); + } + + static List<String> collectValues(String filtervalue, List<String> filtervalues) { + if (filtervalues == null) { + return Arrays.asList(filtervalue); + } + List<String> values = new ArrayList<>(); + if (filtervalue != null) { + values.add(filtervalue); + } + values.addAll(filtervalues); + return values; + } + + private static String getComparisonFilter(String property, String filtervalue, boolean asTimeStamp) { + filtervalue = filtervalue.trim(); + String comparator = null; + Object value; + if (filtervalue.startsWith(">=")) { + comparator = ">="; + filtervalue = filtervalue.substring(2).trim(); + if (asTimeStamp) { + filtervalue = netconfToMariaDBTimestamp(fillTimeStamp( + filtervalue.endsWith("*") ? filtervalue : (filtervalue + "*"), MARIADB_TIMESTAMP_REPLACER)); + } + } else if (filtervalue.startsWith(">")) { + comparator = ">"; + filtervalue = filtervalue.substring(1).trim(); + if (asTimeStamp) { + if (isFullTimestamp(filtervalue)) { + filtervalue = netconfToMariaDBTimestamp(filtervalue); + } else { + comparator = ">="; + filtervalue = netconfToMariaDBTimestamp( + fillTimeStamp(filtervalue.endsWith("*") ? filtervalue : (filtervalue + "*"), + NETCONF_TIMESTAMP_REPLACER, true)); + } + } + } else if (filtervalue.startsWith("<=")) { + comparator = "<="; + filtervalue = filtervalue.substring(2).trim(); + if (asTimeStamp) { + if (isFullTimestamp(filtervalue)) { + filtervalue = netconfToMariaDBTimestamp(filtervalue); + } else { + comparator = "<"; + filtervalue = netconfToMariaDBTimestamp( + fillTimeStamp(filtervalue.endsWith("*") ? filtervalue : (filtervalue + "*"), + NETCONF_TIMESTAMP_REPLACER, true)); + } + } + } else if (filtervalue.startsWith("<")) { + comparator = "<"; + filtervalue = filtervalue.substring(1).trim(); + if (asTimeStamp) { + filtervalue = netconfToMariaDBTimestamp(fillTimeStamp( + filtervalue.endsWith("*") ? filtervalue : (filtervalue + "*"), MARIADB_TIMESTAMP_REPLACER)); + } + } else { + return null; + } + value = filtervalue; + return new RangeSqlDBFilter(property, value, comparator).getFilterExpression(); + } + + static boolean isFullTimestamp(String v) { + return v.length() >= MARIADB_TIMESTAMP_REPLACER_MIN_LENGTH; + } + + /** + * Convert timestamp beginning filter expression like 2017* to a full qualified timestamp like '2017-01-01 + * 00:00:00'. + * + * @param value filter input value + * @return fully qualified timestamp + */ + private static String fillTimeStamp(String value) { + return fillTimeStamp(value, NETCONF_TIMESTAMP_REPLACER); + } + + private static String fillTimeStamp(String value, String replacer) { + return fillTimeStamp(value, replacer, false); + } + + private static String fillTimeStamp(String value, String replacer, boolean useUpperEnd) { + int idx = value.lastIndexOf("*"); + String s = null; + if (idx > replacer.length()) { + s = value.substring(0, replacer.length()); + } else { + s = value.substring(0, idx) + replacer.substring(idx); + } + //if month is zero => set to 1 + if (Integer.parseInt(s.substring(5, 7)) == 0) { + s = s.substring(0, 5) + "01-" + s.substring(8); + } + //if day is zero => set to 1 + if (Integer.parseInt(s.substring(8, 10)) == 0) { + s = s.substring(0, 8) + "01" + s.substring(10); + } + if (useUpperEnd) { + s = getTimestampUpperLimit(s, idx); + } + return s; + } + + /** + * convert timestamp with ending placeholder in filter to elasticsearch filter e.g. 2017* => gte: 2017-01-01 + * 00:00:00, lt:2018-01-01 00:00:00Z + * + * 201* => 2010-01... 2020 .. 2018-* => 2018-01... <=> 2019-01 + * + */ + private static @Nullable String fromTimestampSearchFilter(String property, String value) { + if (!value.endsWith("*")) { + return null; + } + int idx = value.lastIndexOf("*"); + String lowerEnd = fillTimeStamp(value); + String upperEnd = getTimestampUpperLimit(fillTimeStamp(value, "0000-00-00T00:00:00.0Z"), idx); + return RangeSqlDBFilter.between(property, netconfToMariaDBTimestamp(lowerEnd), true, + netconfToMariaDBTimestamp(upperEnd), false); + } + + private static String netconfToMariaDBTimestamp(String ts) { + String v = ts.replace("T", " ").replace("Z", ""); + return v.length() > MARIADB_TIMESTAMP_REPLACER_MAX_LENGTH + ? v.substring(0, MARIADB_TIMESTAMP_REPLACER_MAX_LENGTH) + : v; + } + + private static String getTimestampUpperLimit(String lowerEnd, int idx) { + + String upperEnd = null; + NetconfTimeStamp converter = NetconfTimeStampImpl.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; + } + return upperEnd; + } + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/UpdateQuery.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/UpdateQuery.java new file mode 100644 index 000000000..b47b03042 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/UpdateQuery.java @@ -0,0 +1,111 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 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.query; + +import com.fasterxml.jackson.core.JsonProcessingException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBMapper; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.filters.DBKeyValuePair; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Entity; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class UpdateQuery<T extends DataObject> implements SqlQuery { + + private final Logger LOG = LoggerFactory.getLogger(UpdateQuery.class); + + private final Entity entity; + private final String controllerId; + private final T object; + private final boolean ignoreNull; + private String id; + + public UpdateQuery(Entity e, T object) { + this(e, object, null); + } + + public UpdateQuery(Entity e, T object, String controllerId) { + this.entity = e; + this.controllerId = controllerId; + this.object = object; + this.ignoreNull = true; + this.id = null; + } + + @Override + public String toSql() { + try { + return this.toSqlWithError(); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException + | JsonProcessingException e) { + LOG.warn("unable to create insert statement for table {} from object {}: ", this.entity, this.object, e); + } + return null; + } + + private String toSqlWithError() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, + JsonProcessingException { + Class<?> cls = this.object.getClass(); + Object value; + String col; + StringBuilder sb = new StringBuilder(); + List<String> args = new ArrayList<>(); + sb.append("UPDATE `" + entity.getName() + "` SET "); + List<Method> methods = SqlDBMapper.getFilteredMethods(cls, true); + Method m; + for (int i = 0; i < methods.size(); i++) { + m = methods.get(i); + m.setAccessible(true); + value = m.invoke(this.object); + col = SqlDBMapper.getColumnName(m); + if (col.equals("id")) { + if (this.id == null) { + this.id = String.valueOf(value); + } + continue; + } + if (ignoreNull && value == null) { + continue; + } + DBKeyValuePair<String> kvp = SqlDBMapper.getEscapedKeyValue(m, col, value); + args.add(String.format("%s=%s", kvp.getKey(), kvp.getValue())); + } + sb.append(String.join(",", args)); + sb.append(String.format(" WHERE `id`='%s'", this.id)); + if (this.controllerId != null) { + sb.append(String.format(" AND `%s`='%s'", SqlDBMapper.ODLID_DBCOL, this.controllerId)); + } + + return sb.toString(); + } + + public void setId(String id) { + this.id = id; + } + + + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/UpsertQuery.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/UpsertQuery.java new file mode 100644 index 000000000..e6f1e13cb --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/UpsertQuery.java @@ -0,0 +1,56 @@ +/* + * ============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.query; + +import java.util.List; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.filters.DBKeyValuePair; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Entity; +import org.opendaylight.yangtools.yang.binding.DataObject; + +public class UpsertQuery<T extends DataObject> extends InsertQuery<T> { + + public UpsertQuery(Entity e, T object, String controllerId) { + super(e, object, controllerId); + + } + + @Override + protected void appendAdditionalToQuery(StringBuilder sb, List<DBKeyValuePair<String>> keyValues) { + sb.append(" ON DUPLICATE KEY UPDATE "); + boolean comma = false; + for (DBKeyValuePair<String> kvp : keyValues) { + if(kvp.getKey().equals("`id`")) { + continue; + } + //do not update is-required if entry already exists + if (this.entity == Entity.NetworkelementConnection && kvp.getKey().equals("`is-required`") + && (kvp.getValue().equals("false") || kvp.getValue().equals("0"))) { + continue; + } + if (comma) { + sb.append(","); + } + sb.append(String.format("%s=%s", kvp.getKey(), kvp.getValue())); + comma = true; + } + } +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/DBFilterKeyValuePair.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/DBFilterKeyValuePair.java new file mode 100644 index 000000000..930f16af6 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/DBFilterKeyValuePair.java @@ -0,0 +1,31 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 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.query.filters; + +public class DBFilterKeyValuePair extends DBKeyValuePair<Object> { + + public DBFilterKeyValuePair(String key, Object value) { + super(key, value); + } + + +} 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 new file mode 100644 index 000000000..2474e5227 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/DBKeyValuePair.java @@ -0,0 +1,64 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 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.query.filters; + +import java.math.BigInteger; + +public class DBKeyValuePair<T> implements SqlDBFilter { + + private final String key; + private final T value; + + public DBKeyValuePair(String key, T value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public T getValue() { + return value; + } + + @Override + public String toString() { + return "DBKeyValuePair [key=" + key + ", value=" + value + "]"; + } + + protected boolean isNumericValue(T v) { + if ((v instanceof Long) || (v instanceof Integer) || (v instanceof Byte) || (v instanceof BigInteger)) { + return true; + } + return false; + } + + @Override + public String getFilterExpression() { + if (isNumericValue(this.value)) { + return String.format("`%s`=%d", this.key, 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 new file mode 100644 index 000000000..c4a5d8abc --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/RangeSqlDBFilter.java @@ -0,0 +1,51 @@ +/* + * ============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.query.filters; + +import org.eclipse.jdt.annotation.Nullable; + +public class RangeSqlDBFilter extends DBKeyValuePair<Object> implements SqlDBFilter { + + private final String comparator; + + public RangeSqlDBFilter(String property, Object value, String comparator) { + super(property, value); + this.comparator = comparator; + } + + @Override + public String getFilterExpression() { + if (isNumericValue(this.getValue())) { + return String.format("`%s`%s%d", this.getKey(), this.comparator, this.getValue()); + } else { + return String.format("`%s`%s'%s'", this.getKey(), this.comparator, this.getValue()); + } + } + + public static @Nullable String between(String property, String lowerEnd, boolean incLowerEnd, String upperEnd, + boolean incUpperEnd) { + return String.format("(%s AND %s)", + new RangeSqlDBFilter(property, lowerEnd, incLowerEnd ? ">=" : ">").getFilterExpression(), + new RangeSqlDBFilter(property, upperEnd, incUpperEnd ? "<=" : "<").getFilterExpression()); + } + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/RegexSqlDBFilter.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/RegexSqlDBFilter.java new file mode 100644 index 000000000..4ef1b9a55 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/RegexSqlDBFilter.java @@ -0,0 +1,35 @@ +/* + * ============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.query.filters; + +public class RegexSqlDBFilter extends DBKeyValuePair<String> implements SqlDBFilter{ + + + public RegexSqlDBFilter(String key, String value) { + super(key, value); + } + + @Override + public String getFilterExpression() { + return String.format("`%s` RLIKE '%s'", this.getKey(), this.getValue()); + } +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/SqlDBFilter.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/SqlDBFilter.java new file mode 100644 index 000000000..2997c7040 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/SqlDBFilter.java @@ -0,0 +1,28 @@ +/* + * ============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.query.filters; + +public interface SqlDBFilter { + + public String getFilterExpression(); + +} diff --git a/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestCRUDMariaDB.java b/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestCRUDMariaDB.java new file mode 100644 index 000000000..ad4ab6789 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestCRUDMariaDB.java @@ -0,0 +1,236 @@ +/* + * ============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.assertTrue; +import static org.junit.Assert.fail; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.ParseException; +import java.util.concurrent.TimeUnit; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.common.database.data.AliasesEntryList; +import org.onap.ccsdk.features.sdnr.wt.common.database.data.DatabaseVersion; +import org.onap.ccsdk.features.sdnr.wt.common.database.data.IndicesEntryList; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.SqlDBClient; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.SqlDBDataProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.dblib.test.util.MariaDBTestBase; +import ch.vorburger.exec.ManagedProcessException; + +public class TestCRUDMariaDB { + + + private static final String TABLE1_NAME = "table1"; + private static final String TABLE2_NAME = "table2-v6"; + private static final String TABLE3_NAME = "table3-v6"; + private static final String VIEW2_NAME = "table2"; + private static final String VIEW3_NAME = "table3"; + private static final String TABLE1_MAPPING = "col1 INT PRIMARY KEY, col2 NVARCHAR(30), col3 BOOLEAN"; + private static final String TABLE2_MAPPING = "col1 INT PRIMARY KEY, col2 NVARCHAR(30), col3 BOOLEAN"; + private static final String TABLE3_MAPPING = "col1 INT PRIMARY KEY, col2 NVARCHAR(30), col3 BOOLEAN"; + private static final String DELETE_ALL_FORMAT = "DELETE FROM `%s`"; + private static final String READ_ALL_FORMAT = "SELECT * FROM `%s`"; + private static final String TABLE1_INSERT_ENTRY_FORMAT = + "INSERT INTO `" + TABLE1_NAME + "` (col1, col2, col3) VALUES(%d,'%s',%d);"; + private static final String TABLE1_UPDATE_ENTRY_FORMAT = + "UPDATE `" + TABLE1_NAME + "` SET col2='%s', col3=%d WHERE col1=%d;"; + private static final String TABLE1_DELETE_ENTRY_FORMAT = "DELETE FROM `" + TABLE1_NAME + "` WHERE col1=%d;"; + private static String DBNAME = null; + + private static MariaDBTestBase testBase; + private static SqlDBDataProvider dbProvider; + private static SqlDBClient dbClient; + + @BeforeClass + public static void init() throws Exception { + + testBase = new MariaDBTestBase(); + dbProvider = testBase.getDbProvider(); + dbProvider.waitForDatabaseReady(30, TimeUnit.SECONDS); + dbClient = testBase.createRawClient(); + DBNAME = testBase.getDBName(); + } + + @AfterClass + public static void close() { + try { + testBase.close(); + } catch (ManagedProcessException e) { + e.printStackTrace(); + } + } + + @Test + public void test1() { + ResultSet data; + boolean success; + String id = null; + //create test1Table + success = dbClient.createTable(TABLE1_NAME, TABLE1_MAPPING); + assertTrue("failed to create table", success); + //delete all + try { + success = dbClient.delete(String.format(DELETE_ALL_FORMAT, TABLE1_NAME)); + } catch (SQLException e) { + e.printStackTrace(); + } + assertTrue("failed to clear table", success); + //test empty + data = dbClient.read(String.format(READ_ALL_FORMAT, TABLE1_NAME)); + try { + assertEquals(0, countRows(data)); + } catch (SQLException e) { + e.printStackTrace(); + fail("unable to read size"); + } + //create entry + success = false; + try { + success = dbClient.write(String.format(TABLE1_INSERT_ENTRY_FORMAT, 10, "hello", 0)); + } catch (SQLException e) { + e.printStackTrace(); + } + assertTrue("failed to write data", success); + //verify write + data = dbClient.read(String.format(READ_ALL_FORMAT, TABLE1_NAME)); + try { + assertEquals(1, countRows(data)); + assertTrue(data.next()); + assertEquals(10, data.getInt(1)); + assertEquals("hello", data.getString(2)); + assertEquals(false, data.getBoolean(3)); + } catch (SQLException e) { + e.printStackTrace(); + fail("unable to verify write"); + } + //update entry + success = false; + try { + success = dbClient.update(String.format(TABLE1_UPDATE_ENTRY_FORMAT, "hello2", 1, 10)); + } catch (SQLException e) { + e.printStackTrace(); + } + assertTrue("failed to update data", success); + //verify update + data = dbClient.read(String.format(READ_ALL_FORMAT, TABLE1_NAME)); + try { + assertEquals(1, countRows(data)); + assertTrue(data.next()); + assertEquals(10, data.getInt(1)); + assertEquals("hello2", data.getString(2)); + assertEquals(true, data.getBoolean(3)); + } catch (SQLException e) { + e.printStackTrace(); + fail("unable to verify write"); + } + //delete entry + success = false; + try { + success = dbClient.delete(String.format(TABLE1_DELETE_ENTRY_FORMAT, 10)); + } catch (SQLException e) { + e.printStackTrace(); + } + assertTrue("failed to delete data", success); + //verify delete + data = dbClient.read(String.format(READ_ALL_FORMAT, TABLE1_NAME)); + try { + assertEquals(0, data.getFetchSize()); + } catch (SQLException e) { + e.printStackTrace(); + fail("unable to verify delete. size>0"); + } + } + + @Test + public void testDBVersion() { + DatabaseVersion version = null; + try { + version = dbClient.readActualVersion(); + } catch (SQLException | ParseException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + assertTrue(version.getMajor() >= 10); + } + + @Test + public void testTableStuff() { + + boolean success; + //create Tables/Views + success = dbClient.createTable(TABLE2_NAME, TABLE2_MAPPING); + assertTrue(success); + success = dbClient.createTable(TABLE3_NAME, TABLE3_MAPPING); + assertTrue(success); + try { + success = dbClient.createView(TABLE2_NAME, VIEW2_NAME); + assertTrue(success); + success = dbClient.createView(TABLE3_NAME, VIEW3_NAME); + assertTrue(success); + } catch (SQLException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + //read Tables + IndicesEntryList tables = dbClient.readTables(); + assertTrue(tables.stream().filter(t -> t.getName().equals(TABLE2_NAME)).count() == 1); + assertTrue(tables.stream().filter(t -> t.getName().equals(TABLE3_NAME)).count() == 1); + AliasesEntryList views = dbClient.readViews(DBNAME); + assertTrue(views.stream().filter(t -> t.getIndex().equals(TABLE2_NAME) && t.getAlias().equals(VIEW2_NAME)) + .count() == 1); + assertTrue(views.stream().filter(t -> t.getIndex().equals(TABLE3_NAME) && t.getAlias().equals(VIEW3_NAME)) + .count() == 1); + + //delete Tables/Views + try { + success = dbClient.deleteView(VIEW2_NAME); + assertTrue(success); + success = dbClient.deleteView(VIEW3_NAME); + assertTrue(success); + success = dbClient.deleteTable(TABLE2_NAME); + assertTrue(success); + success = dbClient.deleteTable(TABLE3_NAME); + assertTrue(success); + } catch (SQLException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + //verify + tables = dbClient.readTables(); + assertTrue(tables.stream().filter(t->t.getName().equals(TABLE2_NAME)).count()==0); + assertTrue(tables.stream().filter(t->t.getName().equals(TABLE3_NAME)).count()==0); + views = dbClient.readViews(DBNAME); + assertEquals(0,views.size()); + } + + public static int countRows(ResultSet data) throws SQLException { + int rows = 0; + while (data.next()) { + rows++; + } + data.beforeFirst(); + return rows; + } +} 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 new file mode 100644 index 000000000..da7450089 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestMariaDataProvider.java @@ -0,0 +1,563 @@ +/* + * ============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.fail; +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import org.json.JSONArray; +import org.json.JSONException; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.SqlDBClient; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.SqlDBDataProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.DeleteQuery; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.dblib.test.util.MariaDBTestBase; +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.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; +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.CreateMaintenanceInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMediatorServerInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMediatorServerInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMediatorServerOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteMediatorServerInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteMediatorServerInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteNetworkElementConnectionInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteNetworkElementConnectionInputBuilder; +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.EntityInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultcurrentBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultcurrentEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Guicutthrough; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.GuicutthroughBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.NetworkElementConnectionBuilder; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadFaultcurrentListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadFaultlogListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadGuiCutThroughEntryOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadInventoryListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadMaintenanceListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadMediatorServerListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadNetworkElementConnectionListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata15mDeviceListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata15mListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata15mLtpListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata24hListOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadStatusOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SeverityType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SourceType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateMediatorServerInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateMediatorServerInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateNetworkElementConnectionInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateNetworkElementConnectionInputBuilder; +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; +import ch.vorburger.exec.ManagedProcessException; + +public class TestMariaDataProvider { + + + private static final String NODEID1 = "node1"; + private static final String NODEID2 = "node2"; + private static final String NODEID3 = "node3"; + private static final String PROBLEM1 = "problem1"; + private static final String TIME1 = "2021-05-25T05:12:55.0Z"; + private static final String TIME2 = "2021-05-25T05:12:56.0Z"; + private static final String TIME3 = "2021-05-25T05:12:57.0Z"; + private static final String PROBLEM2 = "problem2"; + 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 MariaDBTestBase testBase; + private static SqlDBDataProvider dbProvider; + private static SqlDBClient dbClient; + private static String CONTROLLERID; + + @BeforeClass + public static void init() throws Exception { + + testBase = new MariaDBTestBase(); + dbProvider = testBase.getDbProvider(); + dbProvider.waitForDatabaseReady(30, TimeUnit.SECONDS); + dbClient = testBase.createRawClient(); + MariaDBTestBase.testCreateTableStructure(dbClient); + dbProvider.setControllerId(); + CONTROLLERID = dbProvider.getControllerId(); + + } + + @AfterClass + public static void close() { + try { + testBase.close(); + } catch (ManagedProcessException e) { + e.printStackTrace(); + } + } + + @Test + public void testFaultcurrent() { + dbProvider.clearFaultsCurrentOfNode(NODEID1); + ReadFaultcurrentListOutputBuilder faultCurrents = + dbProvider.readFaultCurrentList(createInput("node-id", NODEID1, 1, 20)); + assertEquals(0, faultCurrents.getData().size()); + FaultcurrentEntity faultCurrent1 = new FaultcurrentBuilder().setNodeId(NODEID1).setCounter(1).setObjectId("obj") + .setProblem(PROBLEM1).setTimestamp(DateAndTime.getDefaultInstance(TIME1)) + .setSeverity(SeverityType.Major).setId(String.format("%s/%s", NODEID1, PROBLEM1)).build(); + dbProvider.updateFaultCurrent(faultCurrent1); + FaultcurrentEntity faultCurrent2 = new FaultcurrentBuilder().setNodeId(NODEID1).setCounter(1).setObjectId("obj") + .setProblem(PROBLEM2).setTimestamp(DateAndTime.getDefaultInstance(TIME1)) + .setSeverity(SeverityType.Minor).setId(String.format("%s/%s", NODEID1, PROBLEM2)).build(); + dbProvider.updateFaultCurrent(faultCurrent2); + faultCurrents = dbProvider.readFaultCurrentList(createInput("node-id", NODEID1, 1, 20)); + assertEquals(2, faultCurrents.getData().size()); + ReadStatusOutputBuilder status = null; + try { + status = dbProvider.readStatus(); + } catch (IOException e) { + e.printStackTrace(); + fail("failed to read status"); + } + assertEquals(0, status.getData().get(0).getFaults().getCriticals().intValue()); + assertEquals(1, status.getData().get(0).getFaults().getMajors().intValue()); + assertEquals(1, status.getData().get(0).getFaults().getMinors().intValue()); + assertEquals(0, status.getData().get(0).getFaults().getWarnings().intValue()); + + faultCurrent1 = new FaultcurrentBuilder().setNodeId(NODEID1).setCounter(1).setObjectId("obj") + .setProblem(PROBLEM1).setTimestamp(DateAndTime.getDefaultInstance(TIME1)) + .setSeverity(SeverityType.NonAlarmed).setId(String.format("%s/%s", NODEID1, PROBLEM1)).build(); + dbProvider.updateFaultCurrent(faultCurrent1); + faultCurrents = dbProvider.readFaultCurrentList(createInput("node-id", NODEID1, 1, 20)); + assertEquals(1, faultCurrents.getData().size()); + } + + @Test + public void testFaultlog() { + try { + dbClient.delete(new DeleteQuery(Entity.Faultcurrent, null).toSql()); + } catch (SQLException e) { + e.printStackTrace(); + fail("problem clearing faultlog"); + } + ReadFaultlogListOutputBuilder faultlogs = dbProvider.readFaultLogList(createInput(1, 20)); + assertEquals(0, faultlogs.getData().size()); + FaultlogEntity fault1 = new FaultlogBuilder().setCounter(1).setNodeId(NODEID1).setObjectId("obj") + .setProblem(PROBLEM1).setSeverity(SeverityType.Major).setSourceType(SourceType.Netconf) + .setTimestamp(DateAndTime.getDefaultInstance(TIME1)).build(); + dbProvider.writeFaultLog(fault1); + FaultlogEntity fault2 = new FaultlogBuilder().setCounter(2).setNodeId(NODEID1).setObjectId("obj") + .setProblem(PROBLEM2).setSeverity(SeverityType.Major).setSourceType(SourceType.Netconf) + .setTimestamp(DateAndTime.getDefaultInstance(TIME1)).build(); + dbProvider.writeFaultLog(fault2); + faultlogs = dbProvider.readFaultLogList(createInput("node-id", NODEID1, 1, 20)); + assertEquals(2, faultlogs.getData().size()); + } + + @Test + public void testConnectionlog() { + try { + dbClient.delete(new DeleteQuery(Entity.Connectionlog, null).toSql()); + } catch (SQLException e) { + e.printStackTrace(); + fail("problem clearing faultlog"); + } + ReadConnectionlogListOutputBuilder logs = dbProvider.readConnectionlogList(createInput(1, 20)); + assertEquals(0, logs.getData().size()); + ConnectionlogEntity log1 = new ConnectionlogBuilder().setNodeId(NODEID1) + .setTimestamp(DateAndTime.getDefaultInstance(TIME1)).setStatus(ConnectionLogStatus.Mounted).build(); + dbProvider.writeConnectionLog(log1); + ConnectionlogEntity log2 = new ConnectionlogBuilder().setNodeId(NODEID1) + .setTimestamp(DateAndTime.getDefaultInstance(TIME2)).setStatus(ConnectionLogStatus.Connecting).build(); + dbProvider.writeConnectionLog(log2); + ConnectionlogEntity log3 = new ConnectionlogBuilder().setNodeId(NODEID1) + .setTimestamp(DateAndTime.getDefaultInstance(TIME3)).setStatus(ConnectionLogStatus.Connected).build(); + dbProvider.writeConnectionLog(log3); + logs = dbProvider.readConnectionlogList(createInput(1, 20)); + assertEquals(3, logs.getData().size()); + } + + @Test + public void testEventlog() { + try { + dbClient.delete(new DeleteQuery(Entity.Eventlog, null).toSql()); + } catch (SQLException e) { + e.printStackTrace(); + fail("problem clearing faultlog"); + } + ReadEventlogListOutputBuilder logs = null; + try { + logs = dbProvider.readEventlogList(createInput(1, 20)); + } catch (IOException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + assertEquals(0, logs.getData().size()); + EventlogEntity log1 = new EventlogBuilder().setCounter(1).setNodeId(NODEID1).setObjectId("obj") + .setTimestamp(DateAndTime.getDefaultInstance(TIME1)).setAttributeName("attr").setNewValue("new-value") + .setSourceType(SourceType.Netconf).build(); + dbProvider.writeEventLog(log1); + EventlogEntity log2 = new EventlogBuilder().setCounter(1).setNodeId(NODEID1).setObjectId("obj") + .setTimestamp(DateAndTime.getDefaultInstance(TIME2)).setAttributeName("attr").setNewValue("new-value2") + .setSourceType(SourceType.Netconf).build(); + dbProvider.writeEventLog(log2); + EventlogEntity log3 = new EventlogBuilder().setCounter(1).setNodeId(NODEID1).setObjectId("obj") + .setTimestamp(DateAndTime.getDefaultInstance(TIME3)).setAttributeName("attr").setNewValue("new-value3") + .setSourceType(SourceType.Netconf).build(); + dbProvider.writeEventLog(log3); + try { + logs = dbProvider.readEventlogList(createInput(1, 20)); + } catch (IOException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + assertEquals(3, logs.getData().size()); + } + + @Test + public void testGuicutthrough() { + try { + dbClient.delete(new DeleteQuery(Entity.Guicutthrough, null).toSql()); + } catch (SQLException e) { + e.printStackTrace(); + fail("problem clearing faultlog"); + } + Guicutthrough gc1 = new GuicutthroughBuilder().setName(NODEID1).setWeburi(URI1).build(); + dbProvider.writeGuiCutThroughData(gc1, NODEID1); + Guicutthrough gc2 = new GuicutthroughBuilder().setName(NODEID2).setWeburi(URI2).build(); + dbProvider.writeGuiCutThroughData(gc2, NODEID2); + Guicutthrough gc3 = new GuicutthroughBuilder().setName(NODEID3).setWeburi(URI3).build(); + dbProvider.writeGuiCutThroughData(gc3, NODEID3); + ReadGuiCutThroughEntryOutputBuilder data = dbProvider.readGuiCutThroughEntry(createInput(1, 20)); + assertEquals(3, data.getData().size()); + data = dbProvider.readGuiCutThroughEntry(createInput("name", NODEID1, 1, 20)); + assertEquals(1, data.getData().size()); + + } + + @Test + public void testInventory() { + try { + dbClient.delete(new DeleteQuery(Entity.Inventoryequipment, null).toSql()); + } catch (SQLException e) { + e.printStackTrace(); + fail("problem clearing faultlog"); + } + ReadInventoryListOutputBuilder data = dbProvider.readInventoryList(createInput(1, 20)); + assertEquals(0, data.getData().size()); + List<Inventory> list = null; + try { + list = loadListFile("/inventory.json", Inventory.class); + } catch (IOException e) { + e.printStackTrace(); + fail("problem loading inventory data"); + + } + dbProvider.writeInventory(NODEID1, list); + data = dbProvider.readInventoryList(createInput(1, 50)); + assertEquals(22, data.getData().size()); + data = dbProvider.readInventoryList(createInput("tree-level", "0", 1, 50)); + assertEquals(5, data.getData().size()); + } + + @Test + public void testMaintenance() { + try { + dbClient.delete(new DeleteQuery(Entity.Maintenancemode, null).toSql()); + } catch (SQLException e) { + e.printStackTrace(); + fail("problem clearing faultlog"); + } + ReadMaintenanceListOutputBuilder data = dbProvider.readMaintenanceList(createInput(1, 20)); + assertEquals(0, data.getData().size()); + CreateMaintenanceInput maint1 = new CreateMaintenanceInputBuilder().setId(NODEID1).setNodeId(NODEID1) + .setActive(true).setDescription("desc").setObjectIdRef("ref").setProblem("problem") + .setStart(DateAndTime.getDefaultInstance(TIME1)).setEnd(DateAndTime.getDefaultInstance(TIME3)).build(); + CreateMaintenanceInput maint2 = new CreateMaintenanceInputBuilder().setId(NODEID2).setNodeId(NODEID2) + .setActive(true).setDescription("desc").setObjectIdRef("ref").setProblem("problem2") + .setStart(DateAndTime.getDefaultInstance(TIME1)).setEnd(DateAndTime.getDefaultInstance(TIME3)).build(); + CreateMaintenanceInput maint3 = new CreateMaintenanceInputBuilder().setId(NODEID3).setNodeId(NODEID3) + .setActive(true).setDescription("desc").setObjectIdRef("ref").setProblem("problem3") + .setStart(DateAndTime.getDefaultInstance(TIME1)).setEnd(DateAndTime.getDefaultInstance(TIME3)).build(); + try { + dbProvider.createMaintenance(maint1); + dbProvider.createMaintenance(maint2); + dbProvider.createMaintenance(maint3); + } catch (IOException e) { + e.printStackTrace(); + fail("unable to create maintenance data"); + } + data = dbProvider.readMaintenanceList(createInput(1, 20)); + assertEquals(3, data.getData().size()); + + } + + @Test + public void testMediatorserver() { + try { + dbClient.delete(new DeleteQuery(Entity.MediatorServer, null).toSql()); + } catch (SQLException e) { + e.printStackTrace(); + fail("problem clearing mediator server"); + } + ReadMediatorServerListOutputBuilder data = dbProvider.readMediatorServerList(createInput(1, 20)); + assertEquals(0, data.getData().size()); + CreateMediatorServerInput mediator1 = + new CreateMediatorServerInputBuilder().setName("server1").setUrl("http://10.20.30.40:7070").build(); + CreateMediatorServerInput mediator2 = + new CreateMediatorServerInputBuilder().setName("server2").setUrl("http://10.20.30.42:7070").build(); + CreateMediatorServerInput mediator3 = + new CreateMediatorServerInputBuilder().setName("server3").setUrl("http://10.20.30.43:7070").build(); + CreateMediatorServerOutputBuilder output1 = null, output2 = null; + try { + output1 = dbProvider.createMediatorServer(mediator1); + output2 = dbProvider.createMediatorServer(mediator2); + dbProvider.createMediatorServer(mediator3); + } catch (IOException e) { + e.printStackTrace(); + fail("problem creating mediator servers"); + } + data = dbProvider.readMediatorServerList(createInput(1, 20)); + assertEquals(3, data.getData().size()); + UpdateMediatorServerInput update1 = new UpdateMediatorServerInputBuilder().setId(output1.getId()) + .setName("server1").setUrl("http://10.20.30.40:7071").build(); + try { + dbProvider.updateMediatorServer(update1); + } catch (IOException e) { + e.printStackTrace(); + fail("failed to update mediator server"); + } + data = dbProvider.readMediatorServerList(createInput("id", output1.getId(), 1, 20)); + assertEquals(1, data.getData().size()); + assertEquals(output1.getId(), data.getData().get(0).getId()); + assertEquals("server1", data.getData().get(0).getName()); + assertEquals("http://10.20.30.40:7071", data.getData().get(0).getUrl()); + + DeleteMediatorServerInput delete2 = new DeleteMediatorServerInputBuilder().setId(output2.getId()).build(); + try { + dbProvider.deleteMediatorServer(delete2); + } catch (IOException e) { + e.printStackTrace(); + fail("unable to delete mediator server"); + } + data = dbProvider.readMediatorServerList(createInput("id", output2.getId(), 1, 20)); + assertEquals(0, data.getData().size()); + data = dbProvider.readMediatorServerList(createInput(1, 20)); + assertEquals(2, data.getData().size()); + } + + @Test + public void testNeConnection() { + try { + dbClient.delete(new DeleteQuery(Entity.NetworkelementConnection, null).toSql()); + } catch (SQLException e) { + e.printStackTrace(); + fail("problem clearing neconnection"); + } + ReadNetworkElementConnectionListOutputBuilder data = + dbProvider.readNetworkElementConnectionList(createInput(1, 20)); + assertEquals(0, data.getData().size()); + NetworkElementConnectionEntity ne1 = new NetworkElementConnectionBuilder().setNodeId(NODEID1) + .setHost("10.20.30.50").setPort(Uint32.valueOf(8300)).setIsRequired(true).setUsername("user") + .setPassword("passwd").build(); + NetworkElementConnectionEntity ne2 = new NetworkElementConnectionBuilder().setNodeId(NODEID2) + .setHost("10.20.30.55").setPort(Uint32.valueOf(8300)).setIsRequired(false).setUsername("user") + .setPassword("passwd").setStatus(ConnectionLogStatus.Connecting).build(); + try { + dbProvider.createNetworkElementConnection(ne1); + dbProvider.createNetworkElementConnection(ne2); + } catch (IOException e) { + e.printStackTrace(); + fail("problem creating neconnection"); + } + data = dbProvider.readNetworkElementConnectionList(createInput(1, 20)); + assertEquals(2, data.getData().size()); + NetworkElementConnectionEntity update1 = new NetworkElementConnectionBuilder() + .setStatus(ConnectionLogStatus.Connected).setDeviceType(NetworkElementDeviceType.ORAN).build(); + dbProvider.updateNetworkConnectionDeviceType(update1, NODEID1); + data = dbProvider.readNetworkElementConnectionList(createInput("node-id", NODEID1, 1, 20)); + assertEquals(1, data.getData().size()); + assertEquals(NetworkElementDeviceType.ORAN, data.getData().get(0).getDeviceType()); + assertEquals(true, data.getData().get(0).isIsRequired()); + UpdateNetworkElementConnectionInput update2 = new UpdateNetworkElementConnectionInputBuilder().setId(NODEID2) + .setHost("10.20.55.44").setIsRequired(true).build(); + try { + dbProvider.updateNetworkElementConnection(update2); + } catch (IOException e) { + e.printStackTrace(); + fail("failed to update neconnection"); + } + data = dbProvider.readNetworkElementConnectionList(createInput("node-id", NODEID2, 1, 20)); + assertEquals(1, data.getData().size()); + assertEquals("10.20.55.44", data.getData().get(0).getHost()); + assertEquals(true, data.getData().get(0).isIsRequired()); + + ReadStatusOutputBuilder status = null; + try { + status = dbProvider.readStatus(); + } catch (IOException e) { + e.printStackTrace(); + fail("failed to read status"); + } + assertEquals(1, status.getData().get(0).getNetworkElementConnections().getConnected().intValue()); + assertEquals(1, status.getData().get(0).getNetworkElementConnections().getConnecting().intValue()); + assertEquals(0, status.getData().get(0).getNetworkElementConnections().getDisconnected().intValue()); + assertEquals(0, status.getData().get(0).getNetworkElementConnections().getMounted().intValue()); + assertEquals(2, status.getData().get(0).getNetworkElementConnections().getTotal().intValue()); + assertEquals(0, status.getData().get(0).getNetworkElementConnections().getUnableToConnect().intValue()); + assertEquals(0, status.getData().get(0).getNetworkElementConnections().getUndefined().intValue()); + assertEquals(0, status.getData().get(0).getNetworkElementConnections().getUnmounted().intValue()); + + + DeleteNetworkElementConnectionInput delete1 = + new DeleteNetworkElementConnectionInputBuilder().setId(NODEID1).build(); + try { + dbProvider.deleteNetworkElementConnection(delete1); + } catch (IOException e) { + e.printStackTrace(); + fail("failed to delete neconnection"); + } + data = dbProvider.readNetworkElementConnectionList(createInput("node-id", NODEID1, 1, 20)); + assertEquals(0, data.getData().size()); + data = dbProvider.readNetworkElementConnectionList(createInput(1, 20)); + assertEquals(1, data.getData().size()); + } + + @Test + public void testpm15m() { + try { + dbClient.delete(new DeleteQuery(Entity.Historicalperformance15min, null).toSql()); + } catch (SQLException e) { + e.printStackTrace(); + fail("problem clearing pmdata15m"); + } + ReadPmdata15mListOutputBuilder data = dbProvider.readPmdata15mList(createInput(1, 20)); + assertEquals(0, data.getData().size()); + List<PmdataEntity> list = null; + try { + list = loadListFile("/pmdata15m.json", PmdataEntity.class); + } catch (JSONException | IOException e) { + e.printStackTrace(); + fail("failed to load pmdata15m"); + } + dbProvider.doWritePerformanceData(list); + data = dbProvider.readPmdata15mList(createInput(1, 20)); + assertEquals(10, data.getData().size()); + ReadPmdata15mLtpListOutputBuilder ltpdata = null; + try { + ltpdata = dbProvider.readPmdata15mLtpList(createInput("node-name","sim12600",1, 20)); + } catch (IOException e) { + e.printStackTrace(); + fail("failed to read pmdata15m ltp list"); + } + assertEquals(3, ltpdata.getData().size()); + ReadPmdata15mDeviceListOutputBuilder devicedata = null; + try { + devicedata = dbProvider.readPmdata15mDeviceList(createInput(1,20)); + } catch (IOException e) { + e.printStackTrace(); + fail("failed to read pmdata15m devices list"); + } + assertEquals(1, devicedata.getData().size()); + } + + @Ignore + @Test + public void testpm24h() { + try { + dbClient.delete(new DeleteQuery(Entity.Historicalperformance24h, null).toSql()); + } catch (SQLException e) { + e.printStackTrace(); + fail("problem clearing pmdata24h"); + } + ReadPmdata24hListOutputBuilder data = dbProvider.readPmdata24hList(createInput(1, 20)); + assertEquals(0, data.getData().size()); + List<PmdataEntity> list = null; + try { + list = loadListFile("/pmdata24h.json", PmdataEntity.class); + } catch (JSONException | IOException e) { + e.printStackTrace(); + fail("failed to load pmdata24h"); + } + dbProvider.doWritePerformanceData(list); + } + + private static EntityInput createInput(int page, int size) { + return createInput(null, null, page, size); + } + + private static <T> List<T> loadListFile(String filename, Class<T> clazz) throws JSONException, IOException { + List<T> list = new ArrayList<>(); + JSONArray a = new JSONArray(loadFile(filename)); + for (int i = 0; i < a.length(); i++) { + list.add(loadData(a.getJSONObject(i).toString(), clazz)); + } + return list; + } + + private static <T> T loadData(String content, Class<T> clazz) throws IOException { + YangToolsMapper mapper = new YangToolsMapper(); + return mapper.readValue(content, clazz); + } + + private static String loadFile(String filename) throws IOException { + return String.join("\n", IoUtils.readAllLines(TestMariaDataProvider.class.getResourceAsStream(filename))); + } + + private static EntityInput createInput(String filter, String filterValue, int page, int size) { + ReadFaultcurrentListInputBuilder builder = new ReadFaultcurrentListInputBuilder().setPagination( + new PaginationBuilder().setPage(Uint64.valueOf(page)).setSize(Uint32.valueOf(size)).build()); + if (filter != null && filterValue != null) { + Filter f = new FilterBuilder().setProperty(filter).setFiltervalue(filterValue).build(); + Map<FilterKey, Filter> fmap = new HashMap<>(); + fmap.put(f.key(), f); + builder.setFilter(fmap); + } + return builder.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 new file mode 100644 index 000000000..758b72f9c --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestQuerySyntax.java @@ -0,0 +1,157 @@ +/* + * ============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.assertTrue; +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.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; + +public class TestQuerySyntax { + + + private static final String TABLENAME1 = "table1"; + private static final String CONTROLLERID = "controllerid1"; + + @Test + public void testTimestampFilter() { + Map<FilterKey, Filter> filterMap = new HashMap<>(); + Filter filter = new FilterBuilder().setProperty("timestamp").setFiltervalue("2021*").build(); + filterMap.put(filter.key(), filter); + EntityInput input = new ReadEventlogListInputBuilder().setFilter(filterMap).build(); + SelectQuery query = new SelectQuery(TABLENAME1, input, CONTROLLERID); + final String sql = query.toSql(); + assertTrue(sql.contains("`timestamp`>='2021-01-01 00:00:00.000'")); + assertTrue(sql.contains("`timestamp`<'2022-01-01 00:00:00.0'")); + } + + @Test + public void testTimestampFilter2() { + Map<FilterKey, Filter> filterMap = new HashMap<>(); + Filter filter = new FilterBuilder().setProperty("timestamp").setFiltervalue(">2021").build(); + filterMap.put(filter.key(), filter); + EntityInput input = new ReadEventlogListInputBuilder().setFilter(filterMap).build(); + SelectQuery query = new SelectQuery(TABLENAME1, input, CONTROLLERID); + final String sql = query.toSql(); + assertTrue(sql.contains("`timestamp`>='2022-01-01 00:00:00.0'")); + } + + @Test + public void testTimestampFilter3() { + Map<FilterKey, Filter> filterMap = new HashMap<>(); + Filter filter = new FilterBuilder().setProperty("timestamp").setFiltervalue(">=2021").build(); + filterMap.put(filter.key(), filter); + EntityInput input = new ReadEventlogListInputBuilder().setFilter(filterMap).build(); + SelectQuery query = new SelectQuery(TABLENAME1, input, CONTROLLERID); + final String sql = query.toSql(); + assertTrue(sql.contains("`timestamp`>='2021-01-01 00:00:00.000'")); + + } + + @Test + public void testTimestampFilter4() { + Map<FilterKey, Filter> filterMap = new HashMap<>(); + Filter filter = new FilterBuilder().setProperty("timestamp").setFiltervalue("<2021").build(); + filterMap.put(filter.key(), filter); + EntityInput input = new ReadEventlogListInputBuilder().setFilter(filterMap).build(); + SelectQuery query = new SelectQuery(TABLENAME1, input, CONTROLLERID); + final String sql = query.toSql(); + assertTrue(sql.contains("`timestamp`<'2021-01-01 00:00:00.000'")); + } + + @Test + public void testTimestampFilter5() { + Map<FilterKey, Filter> filterMap = new HashMap<>(); + Filter filter = new FilterBuilder().setProperty("timestamp").setFiltervalue("<=2021").build(); + filterMap.put(filter.key(), filter); + EntityInput input = new ReadEventlogListInputBuilder().setFilter(filterMap).build(); + SelectQuery query = new SelectQuery(TABLENAME1, input, CONTROLLERID); + final String sql = query.toSql(); + assertTrue(sql.contains("`timestamp`<'2022-01-01 00:00:00.0'")); + } + + @Test + public void testTimestampFilter6() { + Map<FilterKey, Filter> filterMap = new HashMap<>(); + Filter filter = + new FilterBuilder().setProperty("timestamp").setFiltervalue(">=2022-01-01T00:00:00.000Z").build(); + filterMap.put(filter.key(), filter); + EntityInput input = new ReadEventlogListInputBuilder().setFilter(filterMap).build(); + SelectQuery query = new SelectQuery(TABLENAME1, input, CONTROLLERID); + final String sql = query.toSql(); + assertTrue(sql.contains("`timestamp`>='2022-01-01 00:00:00.000'")); + } + + @Test + public void testTimestampFilter8() { + Map<FilterKey, Filter> filterMap = new HashMap<>(); + Filter filter = + new FilterBuilder().setProperty("timestamp").setFiltervalue(">2022-01-01T00:00:00.000Z").build(); + filterMap.put(filter.key(), filter); + EntityInput input = new ReadEventlogListInputBuilder().setFilter(filterMap).build(); + SelectQuery query = new SelectQuery(TABLENAME1, input, CONTROLLERID); + final String sql = query.toSql(); + assertTrue(sql.contains("`timestamp`>'2022-01-01 00:00:00.000'")); + } + + @Test + public void testTimestampFilter9() { + Map<FilterKey, Filter> filterMap = new HashMap<>(); + Filter filter = + new FilterBuilder().setProperty("timestamp").setFiltervalue("<2022-01-01T00:00:00.000Z").build(); + filterMap.put(filter.key(), filter); + EntityInput input = new ReadEventlogListInputBuilder().setFilter(filterMap).build(); + SelectQuery query = new SelectQuery(TABLENAME1, input, CONTROLLERID); + final String sql = query.toSql(); + assertTrue(sql.contains("`timestamp`<'2022-01-01 00:00:00.000'")); + } + + @Test + public void testTimestampFilter10() { + Map<FilterKey, Filter> filterMap = new HashMap<>(); + Filter filter = + new FilterBuilder().setProperty("timestamp").setFiltervalue("<=2022-01-01T00:00:00.000Z").build(); + filterMap.put(filter.key(), filter); + EntityInput input = new ReadEventlogListInputBuilder().setFilter(filterMap).build(); + SelectQuery query = new SelectQuery(TABLENAME1, input, CONTROLLERID); + final String sql = query.toSql(); + assertTrue(sql.contains("`timestamp`<='2022-01-01 00:00:00.000'")); + } + + @Test + public void testTimestampFilter11() { + Map<FilterKey, Filter> filterMap = new HashMap<>(); + Filter filter = + new FilterBuilder().setProperty("timestamp").setFiltervalue("<=2022-01-01T00:00:00.000222Z").build(); + filterMap.put(filter.key(), filter); + EntityInput input = new ReadEventlogListInputBuilder().setFilter(filterMap).build(); + SelectQuery query = new SelectQuery(TABLENAME1, input, CONTROLLERID); + final String sql = query.toSql(); + assertTrue(sql.contains("`timestamp`<='2022-01-01 00:00:00.000'")); + } +} 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 new file mode 100644 index 000000000..b065519f8 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/util/MariaDBTestBase.java @@ -0,0 +1,192 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 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.util; + +import static org.junit.Assert.fail; +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +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.SqlDBClient; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultcurrentEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.GuicutthroughEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.InventoryEntity; +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.Pmdata15mEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Pmdata24hEntity; +import ch.vorburger.exec.ManagedProcessException; +import ch.vorburger.mariadb4j.DB; +import ch.vorburger.mariadb4j.DBConfigurationBuilder; + +public class MariaDBTestBase { + + private final SqlDBDataProvider dbProvider; + private final DB db; + private SqlDBConfig config; + private static final Map<String, String> envDefaultValues = initEnvDefaultValues(); + private static final String SDNRDBDATABASETEST = "test"; + + public MariaDBTestBase() throws ManagedProcessException { + this(new Random().nextInt(1000) + 50000); + } + + private static String dbUrl(String host, int port, String dbName) { + return String.format("jdbc:mysql://%s:%d/%s", host, port, dbName); + } + + private static Map<String, String> initEnvDefaultValues() { + Map<String, String> defaults = new HashMap<>(); + defaults.put("SDNRDBURL", dbUrl("localhost", 3306, SDNRDBDATABASETEST)); + defaults.put("SDNRDBDATABASE", "test"); + + return defaults; + } + + public MariaDBTestBase(String host, int port) { + this(host, port, SDNRDBDATABASETEST); + } + + public MariaDBTestBase(String host, int port, String dbName) { + EnvGetter env = Section.getEnvGetter(); + envDefaultValues.put("SDNRDBURL", dbUrl(host, port, dbName)); + envDefaultValues.put("SDNRDBUSERNAME", "sdnrdb"); + envDefaultValues.put("SDNRDBPASSWORD", "sdnrdb"); + Section.setEnvGetter((envname) -> { + return envDefaultValues.getOrDefault(envname, env.getenv(envname)); + }); + this.config = new SqlDBConfig(new ConfigurationFileRepresentation("test.properties")); + this.config.setDbSuffix(""); + this.config.setControllerId("test123"); + this.db = null; + this.dbProvider = new SqlDBDataProvider(config, false); + } + + public MariaDBTestBase(int port) throws ManagedProcessException { + EnvGetter env = Section.getEnvGetter(); + envDefaultValues.put("SDNRDBURL", dbUrl("localhost", port, SDNRDBDATABASETEST)); + Section.setEnvGetter((envname) -> { + return envDefaultValues.getOrDefault(envname, env.getenv(envname)); + }); + this.config = new SqlDBConfig(new ConfigurationFileRepresentation("test.properties")); + this.config.setDbSuffix(""); + this.config.setControllerId("test123"); + //start db server + this.db = startDatabase(port); + //create db with name sdnrdb + this.dbProvider = new SqlDBDataProvider(config, false); + } + + public void close() throws ManagedProcessException { + if (db != null) { + this.db.stop(); + } + File f = new File("test.properties"); + if(f.exists()) { + f.delete(); + } + } + + public SqlDBDataProvider getDbProvider() { + return dbProvider; + } + + public DB getDb() { + return db; + } + + private static DB startDatabase(int port) throws ManagedProcessException { + // Start MariaDB4j database + DBConfigurationBuilder dbconfig = DBConfigurationBuilder.newBuilder(); + dbconfig.setPort(port); // 0 => autom. detect free port + DB db = DB.newEmbeddedDB(dbconfig.build()); + db.start(); + return db; + } + + public String getDBUrl() { + return envDefaultValues.get("SDNRDBURL"); + } + + public String getDBUsername() { + return envDefaultValues.getOrDefault("SDNRDBUSERNAME", ""); + } + + public String getDBPassword() { + return envDefaultValues.getOrDefault("SDNRDBPASSWORD", ""); + } + + public SqlDBClient createRawClient() { + return new SqlDBClient(this.config.getUrl(), this.config.getUsername(), this.config.getPassword()); + } + + public String getDBName() { + String url = this.getDBUrl(); + return url.substring(url.lastIndexOf("/") + 1); + } + + public static void testCreateTableStructure(SqlDBClient dbService) { + createTableOdl(dbService); + createTable(dbService, ConnectionlogEntity.class, Entity.Connectionlog, true); + createTable(dbService, EventlogEntity.class, Entity.Eventlog, true); + createTable(dbService, FaultcurrentEntity.class, Entity.Faultcurrent, false); + createTable(dbService, FaultlogEntity.class, Entity.Faultlog, true); + createTable(dbService, GuicutthroughEntity.class, Entity.Guicutthrough, false); + createTable(dbService, Pmdata15mEntity.class, Entity.Historicalperformance15min, false); + createTable(dbService, Pmdata24hEntity.class, Entity.Historicalperformance24h, false); + createTable(dbService, InventoryEntity.class, Entity.Inventoryequipment, false); + createTable(dbService, MaintenanceEntity.class, Entity.Maintenancemode, false); + createTable(dbService, MediatorServerEntity.class, Entity.MediatorServer, true); + createTable(dbService, NetworkElementConnectionEntity.class, Entity.NetworkelementConnection, false); + } + + public static boolean createTableOdl(SqlDBClient dbService) { + String createStatement = null; + createStatement = SqlDBMapper.createTableOdl(); + System.out.println(createStatement); + return dbService.createTable(createStatement); + } + + public static boolean createTable(SqlDBClient dbService, Class<?> cls, Entity entity, boolean autoIndex) { + String createStatement = null; + try { + createStatement = SqlDBMapper.createTable(cls, entity, "", autoIndex); + } catch (UnableToMapClassException e) { + fail(e.getMessage()); + } + System.out.println(createStatement); + return dbService.createTable(createStatement); + } +} + diff --git a/sdnr/wt/data-provider/dblib/src/test/resources/inventory.json b/sdnr/wt/data-provider/dblib/src/test/resources/inventory.json new file mode 100644 index 000000000..9a29325dc --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/test/resources/inventory.json @@ -0,0 +1,381 @@ +[ + { + "description": "WS/p8.module/a2.module#5", + "date": "2013-04-13T00:00:00.0Z", + "version": "a2.module-newest", + "node-id": "sim1", + "uuid": "a2.module-1.1.5.5", + "parent-uuid": "CARD-1.1.5.0", + "contained-holder": [ + "SUBRACK-1.55.0.0" + ], + "tree-level": 2, + "manufacturer-identifier": "ONF-Wireless-Transport", + "serial": "310330015", + "part-type-id": "3EM23141AD01", + "model-identifier": "CRPQABVFAA", + "type-name": "a2.module" + }, + { + "description": "WS/DS1", + "date": "2007-08-27T00:00:00.0Z", + "version": "p1.module", + "node-id": "sim1", + "uuid": "CARD-1.1.7.0", + "parent-uuid": "SHELF-1.1.0.0", + "contained-holder": [], + "tree-level": 1, + "manufacturer-identifier": "CIT", + "serial": "serial-number-s3s", + "part-type-id": "part-number-s3s", + "model-identifier": "model-id-s3s", + "type-name": "p1.module_A" + }, + { + "description": "MWR#55Ch#1/a2.moduletraff", + "date": "2013-04-13T00:00:00.0Z", + "version": "a2.module-newest", + "node-id": "sim1", + "uuid": "a2.module-1.55.1.2", + "parent-uuid": "IDU-1.55.0.0", + "contained-holder": [], + "tree-level": 1, + "manufacturer-identifier": "ONF-Wireless-Transport", + "serial": "310330015", + "part-type-id": "3EM23141AD01", + "model-identifier": "CRPQABVFAA", + "type-name": "a2.module" + }, + { + "description": "MWR#65Ch#1/a2.moduletraff", + "date": "2013-04-13T00:00:00.0Z", + "version": "a2.module-newest", + "node-id": "sim1", + "uuid": "a2.module-1.65.1.2", + "parent-uuid": "IDU-1.65.0.0", + "contained-holder": [], + "tree-level": 1, + "manufacturer-identifier": "ONF-Wireless-Transport", + "serial": "310330008", + "part-type-id": "3EM23141AD01", + "model-identifier": "CRPQABVFAA", + "type-name": "a2.module" + }, + { + "description": "WS-8", + "date": "2017-09-09T00:00:00.0Z", + "version": "a2.module-newest", + "node-id": "sim1", + "uuid": "SHELF-1.1.0.0", + "parent-uuid": "network-element", + "contained-holder": [ + "SLOT-1.1.1.0", + "SLOT-1.1.2.0", + "SLOT-1.1.3.0", + "SLOT-1.1.4.0", + "SLOT-1.1.5.0", + "SLOT-1.1.6.0", + "SLOT-1.1.7.0", + "SLOT-1.1.8.0", + "SLOT-1.1.9.0" + ], + "tree-level": 0, + "manufacturer-identifier": "ONF-Wireless-Transport", + "serial": "Serial1", + "part-type-id": "Partnumber", + "model-identifier": "model-id", + "type-name": "WS-8" + }, + { + "description": "WS/CORE-MAIN/a2.module#5", + "date": "2005-11-09T00:00:00.0Z", + "version": "a2.module-newest", + "node-id": "sim1", + "uuid": "a2.module-1.1.1.5", + "parent-uuid": "CARD-1.1.1.0", + "contained-holder": [ + "SUBRACK-1.15.0.0" + ], + "tree-level": 2, + "manufacturer-identifier": "ONF-Wireless-Transport", + "serial": "0003548168", + "part-type-id": "3FE25774AA01", + "model-identifier": "VAUIAEYAAA", + "type-name": "a2.module" + }, + { + "description": "WS/CORE-MAIN/a2.module#8", + "date": "2010-02-05T00:00:00.0Z", + "version": "a2.module-newest", + "node-id": "sim1", + "uuid": "a2.module-1.1.1.8", + "parent-uuid": "CARD-1.1.1.0", + "contained-holder": [ + "SUBRACK-1.18.0.0" + ], + "tree-level": 2, + "manufacturer-identifier": "ONF-Wireless-Transport", + "serial": "01T441601301", + "part-type-id": "1AB376720002", + "model-identifier": "NGI7AMLMAA", + "type-name": "a2.module" + }, + { + "description": "WS/p8.module/a2.module#5", + "date": "2013-04-13T00:00:00.0Z", + "version": "a2.module-newest", + "node-id": "sim1", + "uuid": "a2.module-1.1.6.5", + "parent-uuid": "CARD-1.1.6.0", + "contained-holder": [ + "SUBRACK-1.65.0.0" + ], + "tree-level": 2, + "manufacturer-identifier": "ONF-Wireless-Transport", + "serial": "310330008", + "part-type-id": "3EM23141AD01", + "model-identifier": "CRPQABVFAA", + "type-name": "a2.module" + }, + { + "description": "MWR-hyper Dir#5.6-Ch#1", + "date": "", + "version": "extrem-hyper", + "node-id": "sim1", + "uuid": "ODU-1.56.0.0", + "parent-uuid": "network-element", + "contained-holder": [ + "PORT-1.56.1.2", + "PORT-1.56.1.3", + "PORT-1.56.1.4" + ], + "tree-level": 0, + "manufacturer-identifier": "", + "serial": "", + "part-type-id": "", + "model-identifier": "", + "type-name": "MWR-hyper" + }, + { + "description": "MWR#56Ch#1/a2.moduletraff", + "date": "2017-09-09T00:00:00.0Z", + "version": "a2.module-newest", + "node-id": "sim1", + "uuid": "a2.module-1.56.1.2", + "parent-uuid": "ODU-1.56.0.0", + "contained-holder": [], + "tree-level": 1, + "manufacturer-identifier": "ONF-Wireless-Transport", + "serial": "Serial1", + "part-type-id": "Partnumber", + "model-identifier": "model-id", + "type-name": "a2.module" + }, + { + "description": "MWR-ng Dir#6.5-Ch#1", + "date": "2014-01-16T00:00:00.0Z", + "version": "MWR-ng", + "node-id": "sim1", + "uuid": "IDU-1.65.0.0", + "parent-uuid": "network-element", + "contained-holder": [ + "PORT-1.65.1.4", + "PORT-1.65.1.2" + ], + "tree-level": 0, + "manufacturer-identifier": "ONF-Wireless-Transport", + "serial": "WAUZZI", + "part-type-id": "3DB76047BAAA02", + "model-identifier": "model-id-s3s", + "type-name": "MWR-ng" + }, + { + "description": "MWR#55Ch#0/RxDiv", + "date": "2014-01-08T00:00:00.0Z", + "version": "2017", + "node-id": "sim1", + "uuid": "CARD-1.65.1.4", + "parent-uuid": "IDU-1.65.0.0", + "contained-holder": [], + "tree-level": 1, + "manufacturer-identifier": "ONF-Wireless-Transport", + "serial": "Serie2017-13", + "part-type-id": "partNo2017-12", + "model-identifier": "model-id-s3s", + "type-name": "RxDiv" + }, + { + "description": "WS/p8.module", + "date": "2013-11-23T00:00:00.0Z", + "version": "234", + "node-id": "sim1", + "uuid": "CARD-1.1.6.0", + "parent-uuid": "SHELF-1.1.0.0", + "contained-holder": [ + "PORT-1.1.6.5", + "PORT-1.1.6.7", + "PORT-1.1.6.6", + "PORT-1.1.6.8" + ], + "tree-level": 1, + "manufacturer-identifier": "SAN", + "serial": "serial-number-124", + "part-type-id": "part-number-12", + "model-identifier": "model-id-12", + "type-name": "p8.module" + }, + { + "description": "WS/DS3", + "date": "2008-10-21T00:00:00.0Z", + "version": "unknown", + "node-id": "sim1", + "uuid": "CARD-1.1.8.0", + "parent-uuid": "SHELF-1.1.0.0", + "contained-holder": [], + "tree-level": 1, + "manufacturer-identifier": "ONF-Wireless-Transport", + "serial": "sd-dsa-eqw", + "part-type-id": "unknown", + "model-identifier": "model-id-s3s", + "type-name": "p4.module" + }, + { + "description": "WS/wind", + "date": "2007-02-19T00:00:00.0Z", + "version": "wind", + "node-id": "sim1", + "uuid": "CARD-1.1.9.0", + "parent-uuid": "SHELF-1.1.0.0", + "contained-holder": [], + "tree-level": 1, + "manufacturer-identifier": "CIT", + "serial": "proto-type", + "part-type-id": "party-yea", + "model-identifier": "model-id-s3s", + "type-name": "wind" + }, + { + "description": "MWR#55Ch#1/RxDiv", + "date": "2014-01-07T00:00:00.0Z", + "version": "2017", + "node-id": "sim1", + "uuid": "CARD-1.55.1.4", + "parent-uuid": "IDU-1.55.0.0", + "contained-holder": [], + "tree-level": 1, + "manufacturer-identifier": "ONF-Wireless-Transport", + "serial": "Serie2017-12", + "part-type-id": "partNo2017-12", + "model-identifier": "model-id-s3s", + "type-name": "RxDiv" + }, + { + "description": "WS/CORE-MAIN/a2.module#7", + "date": "2009-01-19T00:00:00.0Z", + "version": "a2.module-newest", + "node-id": "sim1", + "uuid": "a2.module-1.1.1.7", + "parent-uuid": "CARD-1.1.1.0", + "contained-holder": [ + "SUBRACK-1.17.0.0" + ], + "tree-level": 2, + "manufacturer-identifier": "ONF-Wireless-Transport", + "serial": "91T403003322", + "part-type-id": "1AB187280031", + "model-identifier": "mod2", + "type-name": "a2.module" + }, + { + "description": "MWR-ng Dir#5.5-Ch#1", + "date": "2014-01-15T00:00:00.0Z", + "version": "MWR-ng", + "node-id": "sim1", + "uuid": "IDU-1.55.0.0", + "parent-uuid": "network-element", + "contained-holder": [ + "PORT-1.55.1.2", + "PORT-1.55.1.4" + ], + "tree-level": 0, + "manufacturer-identifier": "ONF-Wireless-Transport", + "serial": "Serie2017-14", + "part-type-id": "3DB76047BAAA02", + "model-identifier": "model-id-s3s", + "type-name": "MWR-ng" + }, + { + "description": "WS/CORE-MAIN", + "date": "2015-08-17T00:00:00.0Z", + "version": "123", + "node-id": "sim1", + "uuid": "CARD-1.1.1.0", + "parent-uuid": "SHELF-1.1.0.0", + "contained-holder": [ + "PORT-1.1.1.6", + "PORT-1.1.1.5", + "PORT-1.1.1.8", + "PORT-1.1.1.7" + ], + "tree-level": 1, + "manufacturer-identifier": "SAN", + "serial": "asdf-asdasd-asd", + "part-type-id": "part-number-2", + "model-identifier": "model-id-2", + "type-name": "latest" + }, + { + "description": "WS/p8.module", + "date": "2013-10-21T00:00:00.0Z", + "version": "234", + "node-id": "sim1", + "uuid": "CARD-1.1.5.0", + "parent-uuid": "SHELF-1.1.0.0", + "contained-holder": [ + "PORT-1.1.5.6", + "PORT-1.1.5.5", + "PORT-1.1.5.8", + "PORT-1.1.5.7" + ], + "tree-level": 1, + "manufacturer-identifier": "SAN", + "serial": "africa", + "part-type-id": "part-number-12", + "model-identifier": "model-id-12", + "type-name": "p8.module" + }, + { + "description": "WS/p8.module/a2.module#6", + "date": "", + "version": "", + "node-id": "sim1", + "uuid": "a2.module-1.1.5.6", + "parent-uuid": "CARD-1.1.5.0", + "contained-holder": [ + "SUBRACK-1.56.0.0" + ], + "tree-level": 2, + "manufacturer-identifier": "", + "serial": "", + "part-type-id": "", + "model-identifier": "", + "type-name": "a2.module" + }, + { + "description": "WS/p8.module/a2.module#6", + "date": "", + "version": "", + "node-id": "sim2", + "uuid": "a2.module-1.1.5.6", + "parent-uuid": "network-element", + "contained-holder": [ + "SUBRACK-1.56.0.0" + ], + "tree-level": 0, + "manufacturer-identifier": "", + "serial": "", + "part-type-id": "", + "model-identifier": "", + "type-name": "a2.module" + } +]
\ No newline at end of file diff --git a/sdnr/wt/data-provider/dblib/src/test/resources/pmdata15m.json b/sdnr/wt/data-provider/dblib/src/test/resources/pmdata15m.json new file mode 100644 index 000000000..88dd87f55 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/test/resources/pmdata15m.json @@ -0,0 +1,532 @@ +[ + { + "uuid-interface": "LP-MWPS-TTP-01", + "performance-data": { + "time-period": 900, + "es": 0, + "ses": 0, + "cses": 0, + "unavailability": 0, + "tx-level-min": 25, + "tx-level-max": 25, + "tx-level-avg": 25, + "rx-level-min": -41, + "rx-level-max": -41, + "rx-level-avg": -41, + "time2-states": -1, + "time4-states-s": 0, + "time4-states": 0, + "time8-states": 0, + "time16-states-s": -1, + "time16-states": 0, + "time32-states": 0, + "time64-states": 0, + "time128-states": 0, + "time256-states": 900, + "time512-states": -1, + "time512-states-l": -1, + "time1024-states": -1, + "time1024-states-l": -1, + "time2048-states": -1, + "time2048-states-l": -1, + "time4096-states": -1, + "time4096-states-l": -1, + "time8192-states": -1, + "time8192-states-l": -1, + "snir-min": -99, + "snir-max": -99, + "snir-avg": -99, + "xpd-min": -99, + "xpd-max": -99, + "xpd-avg": -99, + "rf-temp-min": -99, + "rf-temp-max": -99, + "rf-temp-avg": -99, + "defect-blocks-sum": -1 + }, + "layer-protocol-name": "MWPS", + "radio-signal-id": "Test11", + "suspect-interval-flag": false, + "granularity-period": "Period15Min", + "scanner-id": "PM_RADIO_15M_03", + "time-stamp": "2017-07-04T15:30:00.0+00:00", + "node-name": "sim12600" + }, + { + "uuid-interface": "LP-MWPS-TTP-01", + "performance-data": { + "time-period": 900, + "es": 0, + "ses": 0, + "cses": 0, + "unavailability": 0, + "tx-level-min": 25, + "tx-level-max": 25, + "tx-level-avg": 25, + "rx-level-min": -41, + "rx-level-max": -41, + "rx-level-avg": -41, + "time2-states": -1, + "time4-states-s": 0, + "time4-states": 0, + "time8-states": 0, + "time16-states-s": -1, + "time16-states": 0, + "time32-states": 0, + "time64-states": 0, + "time128-states": 0, + "time256-states": 900, + "time512-states": -1, + "time512-states-l": -1, + "time1024-states": -1, + "time1024-states-l": -1, + "time2048-states": -1, + "time2048-states-l": -1, + "time4096-states": -1, + "time4096-states-l": -1, + "time8192-states": -1, + "time8192-states-l": -1, + "snir-min": -99, + "snir-max": -99, + "snir-avg": -99, + "xpd-min": -99, + "xpd-max": -99, + "xpd-avg": -99, + "rf-temp-min": -99, + "rf-temp-max": -99, + "rf-temp-avg": -99, + "defect-blocks-sum": -1 + }, + "layer-protocol-name": "MWPS", + "radio-signal-id": "Test11", + "suspect-interval-flag": false, + "granularity-period": "Period15Min", + "scanner-id": "PM_RADIO_15M_01", + "time-stamp": "2017-07-04T16:00:00.0+00:00", + "node-name": "sim12600" + }, + { + "uuid-interface": "LP-MWPS-TTP-01", + "performance-data": { + "time-period": 900, + "es": 0, + "ses": 0, + "cses": 0, + "unavailability": 0, + "tx-level-min": 25, + "tx-level-max": 25, + "tx-level-avg": 25, + "rx-level-min": -41, + "rx-level-max": -41, + "rx-level-avg": -41, + "time2-states": -1, + "time4-states-s": 0, + "time4-states": 0, + "time8-states": 0, + "time16-states-s": -1, + "time16-states": 0, + "time32-states": 0, + "time64-states": 0, + "time128-states": 0, + "time256-states": 900, + "time512-states": -1, + "time512-states-l": -1, + "time1024-states": -1, + "time1024-states-l": -1, + "time2048-states": -1, + "time2048-states-l": -1, + "time4096-states": -1, + "time4096-states-l": -1, + "time8192-states": -1, + "time8192-states-l": -1, + "snir-min": -99, + "snir-max": -99, + "snir-avg": -99, + "xpd-min": -99, + "xpd-max": -99, + "xpd-avg": -99, + "rf-temp-min": -99, + "rf-temp-max": -99, + "rf-temp-avg": -99, + "defect-blocks-sum": -1 + }, + "layer-protocol-name": "MWPS", + "radio-signal-id": "Test11", + "suspect-interval-flag": false, + "granularity-period": "Period15Min", + "scanner-id": "PM_RADIO_15M_6", + "time-stamp": "2017-07-04T14:45:00.0+00:00", + "node-name": "sim12600" + }, + { + "uuid-interface": "LP-MWPS-TTP-01", + "performance-data": { + "time-period": 900, + "es": 0, + "ses": 0, + "cses": 0, + "unavailability": 0, + "tx-level-min": 25, + "tx-level-max": 25, + "tx-level-avg": 25, + "rx-level-min": -41, + "rx-level-max": -41, + "rx-level-avg": -41, + "time2-states": -1, + "time4-states-s": 0, + "time4-states": 0, + "time8-states": 0, + "time16-states-s": -1, + "time16-states": 0, + "time32-states": 0, + "time64-states": 0, + "time128-states": 0, + "time256-states": 900, + "time512-states": -1, + "time512-states-l": -1, + "time1024-states": -1, + "time1024-states-l": -1, + "time2048-states": -1, + "time2048-states-l": -1, + "time4096-states": -1, + "time4096-states-l": -1, + "time8192-states": -1, + "time8192-states-l": -1, + "snir-min": -99, + "snir-max": -99, + "snir-avg": -99, + "xpd-min": -99, + "xpd-max": -99, + "xpd-avg": -99, + "rf-temp-min": -99, + "rf-temp-max": -99, + "rf-temp-avg": -99, + "defect-blocks-sum": -1 + }, + "layer-protocol-name": "MWPS", + "radio-signal-id": "Test11", + "suspect-interval-flag": false, + "granularity-period": "Period15Min", + "scanner-id": "PM_RADIO_15M_4", + "time-stamp": "2017-07-04T15:15:00.0+00:00", + "node-name": "sim12600" + }, + { + "uuid-interface": "LP-MWPS-TTP-01", + "performance-data": { + "time-period": 900, + "es": 0, + "ses": 0, + "cses": 0, + "unavailability": 0, + "tx-level-min": 25, + "tx-level-max": 25, + "tx-level-avg": 25, + "rx-level-min": -41, + "rx-level-max": -41, + "rx-level-avg": -41, + "time2-states": -1, + "time4-states-s": 0, + "time4-states": 0, + "time8-states": 0, + "time16-states-s": -1, + "time16-states": 0, + "time32-states": 0, + "time64-states": 0, + "time128-states": 0, + "time256-states": 900, + "time512-states": -1, + "time512-states-l": -1, + "time1024-states": -1, + "time1024-states-l": -1, + "time2048-states": -1, + "time2048-states-l": -1, + "time4096-states": -1, + "time4096-states-l": -1, + "time8192-states": -1, + "time8192-states-l": -1, + "snir-min": -99, + "snir-max": -99, + "snir-avg": -99, + "xpd-min": -99, + "xpd-max": -99, + "xpd-avg": -99, + "rf-temp-min": -99, + "rf-temp-max": -99, + "rf-temp-avg": -99, + "defect-blocks-sum": -1 + }, + "layer-protocol-name": "MWPS", + "radio-signal-id": "Test11", + "suspect-interval-flag": false, + "granularity-period": "Period15Min", + "scanner-id": "PM_RADIO_15M_12", + "time-stamp": "2017-07-04T13:15:00.0+00:00", + "node-name": "sim12600" + }, + { + "uuid-interface": "LP-MWPS-TTP-01", + "performance-data": { + "time-period": 900, + "es": 0, + "ses": 0, + "cses": 0, + "unavailability": 0, + "tx-level-min": 25, + "tx-level-max": 25, + "tx-level-avg": 25, + "rx-level-min": -41, + "rx-level-max": -41, + "rx-level-avg": -41, + "time2-states": -1, + "time4-states-s": 0, + "time4-states": 0, + "time8-states": 0, + "time16-states-s": -1, + "time16-states": 0, + "time32-states": 0, + "time64-states": 0, + "time128-states": 0, + "time256-states": 900, + "time512-states": -1, + "time512-states-l": -1, + "time1024-states": -1, + "time1024-states-l": -1, + "time2048-states": -1, + "time2048-states-l": -1, + "time4096-states": -1, + "time4096-states-l": -1, + "time8192-states": -1, + "time8192-states-l": -1, + "snir-min": -99, + "snir-max": -99, + "snir-avg": -99, + "xpd-min": -99, + "xpd-max": -99, + "xpd-avg": -99, + "rf-temp-min": -99, + "rf-temp-max": -99, + "rf-temp-avg": -99, + "defect-blocks-sum": -1 + }, + "layer-protocol-name": "MWPS", + "radio-signal-id": "Test11", + "suspect-interval-flag": false, + "granularity-period": "Period15Min", + "scanner-id": "PM_RADIO_15M_15", + "time-stamp": "2017-07-04T12:30:00.0+00:00", + "node-name": "sim12600" + }, + { + "uuid-interface": "LP-MWPS-TTP-03", + "performance-data": { + "time-period": 900, + "es": 0, + "ses": 0, + "cses": 0, + "unavailability": 0, + "tx-level-min": 25, + "tx-level-max": 25, + "tx-level-avg": 25, + "rx-level-min": -41, + "rx-level-max": -41, + "rx-level-avg": -41, + "time2-states": -1, + "time4-states-s": 0, + "time4-states": 0, + "time8-states": 0, + "time16-states-s": -1, + "time16-states": 0, + "time32-states": 0, + "time64-states": 0, + "time128-states": 0, + "time256-states": 900, + "time512-states": -1, + "time512-states-l": -1, + "time1024-states": -1, + "time1024-states-l": -1, + "time2048-states": -1, + "time2048-states-l": -1, + "time4096-states": -1, + "time4096-states-l": -1, + "time8192-states": -1, + "time8192-states-l": -1, + "snir-min": -99, + "snir-max": -99, + "snir-avg": -99, + "xpd-min": -99, + "xpd-max": -99, + "xpd-avg": -99, + "rf-temp-min": -99, + "rf-temp-max": -99, + "rf-temp-avg": -99, + "defect-blocks-sum": -1 + }, + "layer-protocol-name": "MWPS", + "radio-signal-id": "Test11", + "suspect-interval-flag": false, + "granularity-period": "Period15Min", + "scanner-id": "PM_RADIO_15M_16", + "time-stamp": "2017-07-04T12:15:00.0+00:00", + "node-name": "sim12600" + }, + { + "uuid-interface": "LP-MWPS-TTP-02", + "performance-data": { + "time-period": 900, + "es": 0, + "ses": 0, + "cses": 0, + "unavailability": 0, + "tx-level-min": 25, + "tx-level-max": 25, + "tx-level-avg": 25, + "rx-level-min": -41, + "rx-level-max": -41, + "rx-level-avg": -41, + "time2-states": -1, + "time4-states-s": 0, + "time4-states": 0, + "time8-states": 0, + "time16-states-s": -1, + "time16-states": 0, + "time32-states": 0, + "time64-states": 0, + "time128-states": 0, + "time256-states": 900, + "time512-states": -1, + "time512-states-l": -1, + "time1024-states": -1, + "time1024-states-l": -1, + "time2048-states": -1, + "time2048-states-l": -1, + "time4096-states": -1, + "time4096-states-l": -1, + "time8192-states": -1, + "time8192-states-l": -1, + "snir-min": -99, + "snir-max": -99, + "snir-avg": -99, + "xpd-min": -99, + "xpd-max": -99, + "xpd-avg": -99, + "rf-temp-min": -99, + "rf-temp-max": -99, + "rf-temp-avg": -99, + "defect-blocks-sum": -1 + }, + "layer-protocol-name": "MWPS", + "radio-signal-id": "Test11", + "suspect-interval-flag": false, + "granularity-period": "Period15Min", + "scanner-id": "PM_RADIO_15M_02", + "time-stamp": "2017-07-04T15:45:00.0+00:00", + "node-name": "sim12600" + }, + { + "uuid-interface": "LP-MWPS-TTP-02", + "performance-data": { + "time-period": 900, + "es": 0, + "ses": 0, + "cses": 0, + "unavailability": 0, + "tx-level-min": 25, + "tx-level-max": 25, + "tx-level-avg": 25, + "rx-level-min": -41, + "rx-level-max": -41, + "rx-level-avg": -41, + "time2-states": -1, + "time4-states-s": 0, + "time4-states": 0, + "time8-states": 0, + "time16-states-s": -1, + "time16-states": 0, + "time32-states": 0, + "time64-states": 0, + "time128-states": 0, + "time256-states": 900, + "time512-states": -1, + "time512-states-l": -1, + "time1024-states": -1, + "time1024-states-l": -1, + "time2048-states": -1, + "time2048-states-l": -1, + "time4096-states": -1, + "time4096-states-l": -1, + "time8192-states": -1, + "time8192-states-l": -1, + "snir-min": -99, + "snir-max": -99, + "snir-avg": -99, + "xpd-min": -99, + "xpd-max": -99, + "xpd-avg": -99, + "rf-temp-min": -99, + "rf-temp-max": -99, + "rf-temp-avg": -99, + "defect-blocks-sum": -1 + }, + "layer-protocol-name": "MWPS", + "radio-signal-id": "Test11", + "suspect-interval-flag": false, + "granularity-period": "Period15Min", + "scanner-id": "PM_RADIO_15M_11", + "time-stamp": "2017-07-04T13:30:00.0+00:00", + "node-name": "sim12600" + }, + { + "uuid-interface": "LP-MWPS-TTP-02", + "performance-data": { + "time-period": 900, + "es": 0, + "ses": 0, + "cses": 0, + "unavailability": 0, + "tx-level-min": 25, + "tx-level-max": 25, + "tx-level-avg": 25, + "rx-level-min": -41, + "rx-level-max": -41, + "rx-level-avg": -41, + "time2-states": -1, + "time4-states-s": 0, + "time4-states": 0, + "time8-states": 0, + "time16-states-s": -1, + "time16-states": 0, + "time32-states": 0, + "time64-states": 0, + "time128-states": 0, + "time256-states": 900, + "time512-states": -1, + "time512-states-l": -1, + "time1024-states": -1, + "time1024-states-l": -1, + "time2048-states": -1, + "time2048-states-l": -1, + "time4096-states": -1, + "time4096-states-l": -1, + "time8192-states": -1, + "time8192-states-l": -1, + "snir-min": -99, + "snir-max": -99, + "snir-avg": -99, + "xpd-min": -99, + "xpd-max": -99, + "xpd-avg": -99, + "rf-temp-min": -99, + "rf-temp-max": -99, + "rf-temp-avg": -99, + "defect-blocks-sum": -1 + }, + "layer-protocol-name": "MWPS", + "radio-signal-id": "Test11", + "suspect-interval-flag": false, + "granularity-period": "Period15Min", + "scanner-id": "PM_RADIO_15M_13", + "time-stamp": "2017-07-04T13:00:00.0+00:00", + "node-name": "sim12600" + } +]
\ No newline at end of file |