From 6b8e4f12fc66a64fa5c5498d06891f1f5f1189ac Mon Sep 17 00:00:00 2001 From: Ravi Pendurty Date: Thu, 2 Mar 2023 12:06:07 +0530 Subject: Upgrade parents to 2.5.4-SNAPSHOT Code changes as a result of changes induced by ODL Chlorine SR1 Issue-ID: CCSDK-3856 Signed-off-by: Ravi Pendurty Change-Id: Ic08786f050e58bdb8371c8f8c25fb0db9f258cd4 Signed-off-by: Ravi Pendurty --- .../database/DatabaseDataProvider.java | 141 -------- .../dataprovider/database/sqldb/SqlDBClient.java | 4 +- .../database/sqldb/data/PropertyList.java | 36 ++ .../database/sqldb/data/SqlDBDataProvider.java | 26 +- .../sqldb/data/SqlDbInventoryTreeProvider.java | 89 +++++ .../database/sqldb/data/SqlPropertyInfo.java | 56 ++++ .../database/sqldb/data/UserdataBuilder.java | 5 +- .../sqldb/data/entity/HtDatabaseEventsService.java | 7 +- .../database/sqldb/database/SqlDBMapper.java | 60 ++-- .../database/sqldb/database/SqlDBReader.java | 210 ++++++++++++ .../database/sqldb/database/SqlDBReaderWriter.java | 165 +--------- .../sqldb/database/SqlDBReaderWriterInventory.java | 87 +++++ .../sqldb/database/SqlDBReaderWriterUserdata.java | 4 - .../database/sqldb/query/InsertQuery.java | 2 +- .../database/sqldb/query/SelectQuery.java | 34 +- .../database/sqldb/query/SqlQuery.java | 33 +- .../sqldb/query/filters/DBKeyValuePair.java | 4 +- .../database/sqldb/query/filters/SqlDBFilter.java | 4 + .../sqldb/query/filters/SqlDBSearchFilter.java | 45 +++ .../dblib/test/TestMariaDataProvider.java | 53 ++- .../dblib/src/test/resources/inventory2.json | 364 +++++++++++++++++++++ 21 files changed, 1082 insertions(+), 347 deletions(-) delete mode 100644 sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/DatabaseDataProvider.java create mode 100644 sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/PropertyList.java create mode 100644 sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlDbInventoryTreeProvider.java create mode 100644 sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlPropertyInfo.java create mode 100644 sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReader.java create mode 100644 sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriterInventory.java create mode 100644 sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/SqlDBSearchFilter.java create mode 100644 sdnr/wt/data-provider/dblib/src/test/resources/inventory2.json (limited to 'sdnr/wt/data-provider/dblib/src') 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 deleted file mode 100644 index fbd105aa1..000000000 --- a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/DatabaseDataProvider.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP : ccsdk features - * ================================================================================ - * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. - * All rights reserved. - * ================================================================================ - * Update Copyright (C) 2021 Samsung Electronics Intellectual Property. All rights reserved. - * ================================================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtUserdataManager; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMaintenanceInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMaintenanceOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMediatorServerInput; -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.ReadCmlogListOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadConnectionlogListOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadEventlogListOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadFaultcurrentListOutputBuilder; -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.ReadGuiCutThroughEntryOutput; -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); - - ReadCmlogListOutputBuilder readCMLogList(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(EntityInput input) 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(); - - HtUserdataManager getUserManager(); - -} 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 index b93145cbb..dc1241156 100644 --- 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 @@ -63,7 +63,6 @@ public class SqlDBClient { private static final String SELECT_VERSION_QUERY = "SELECT @@version as version"; private static final String DBNAME_DEFAULT = "sdnrdb"; - private static final int DEFAULT_POOLSIZE = 50; private final String dbConnectionString; private final String dbName; private final String dbHost; @@ -306,7 +305,8 @@ public class SqlDBClient { } public Connection getConnection() throws SQLException { - return DriverManager.getConnection(this.dbConnectionString); + return this.connectionPool.getConnection(); + //return DriverManager.getConnection(this.dbConnectionString); } public boolean delete(String query) throws SQLException { diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/PropertyList.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/PropertyList.java new file mode 100644 index 000000000..d2321fc2b --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/PropertyList.java @@ -0,0 +1,36 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2023 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data; + +import java.util.ArrayList; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBMapper; +import org.opendaylight.yangtools.yang.binding.DataObject; + +@SuppressWarnings("serial") +public class PropertyList extends ArrayList { + + + public PropertyList(Class clazz){ + super(SqlDBMapper.getProperties(clazz)); + } + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlDBDataProvider.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlDBDataProvider.java index cb66fc6fb..d00941d86 100644 --- a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlDBDataProvider.java +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlDBDataProvider.java @@ -28,7 +28,6 @@ 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; @@ -39,9 +38,11 @@ import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlD 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.DatabaseDataProvider; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtDatabaseMaintenance; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtDatabaseMediatorserver; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtUserdataManager; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.InventoryTreeProvider; 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; @@ -64,6 +65,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.pro import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.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.ReadInventoryDeviceListOutputBuilder; 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; @@ -101,6 +103,7 @@ public class SqlDBDataProvider extends HtDatabaseEventsService implements Databa private final SqlDBReaderWriter maintenanceRW; private final SqlDBStatusReader readStatus; private final HtUserdataManager usermanager; + private final InventoryTreeProvider inventoryTreeProvider; public SqlDBReaderWriter getMaintenanceReaderWriter() { @@ -145,6 +148,8 @@ public class SqlDBDataProvider extends HtDatabaseEventsService implements Databa LOG.warn("problem setting controllerId: ", e); } } + this.inventoryTreeProvider = new SqlDbInventoryTreeProvider(this.dbClient, this.getControllerId()); + } @@ -241,6 +246,17 @@ public class SqlDBDataProvider extends HtDatabaseEventsService implements Databa return outputBuilder; } + @Override + public ReadInventoryDeviceListOutputBuilder readInventoryDeviceList(EntityInput input) { + ReadInventoryDeviceListOutputBuilder outputBuilder = new ReadInventoryDeviceListOutputBuilder(); + QueryResult result = this.equipmentRW.getDataDeviceList(input); + outputBuilder.setPagination( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.inventory.device.list.output.PaginationBuilder( + result.getPagination()).build()); + outputBuilder.setData(result.getResultSet()); + return outputBuilder; + } + @Override public ReadConnectionlogListOutputBuilder readConnectionlogList(EntityInput input) { ReadConnectionlogListOutputBuilder outputBuilder = new ReadConnectionlogListOutputBuilder(); @@ -504,7 +520,7 @@ public class SqlDBDataProvider extends HtDatabaseEventsService implements Databa } LOG.info("set controllerId {}", this.controllerId); String query = - String.format("SELECT * FROM `%s` WHERE `id`='%s';", this.controllerTableName, this.controllerId); + String.format("SELECT * FROM `%s` WHERE `id`='%s'", this.controllerTableName, this.controllerId); LOG.trace(query); ResultSet data = this.dbClient.read(query); @@ -515,6 +531,7 @@ public class SqlDBDataProvider extends HtDatabaseEventsService implements Databa try { if(data!=null){data.close();} } catch (SQLException ignore) { } return this.dbClient.write(query); } else { + this.controllerId = data.getString(0); LOG.trace("controllerId already set"); } return true; @@ -533,5 +550,10 @@ public class SqlDBDataProvider extends HtDatabaseEventsService implements Databa return this.usermanager; } + @Override + public InventoryTreeProvider getInventoryTreeProvider() { + return this.inventoryTreeProvider; + } + } diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlDbInventoryTreeProvider.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlDbInventoryTreeProvider.java new file mode 100644 index 000000000..425007016 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlDbInventoryTreeProvider.java @@ -0,0 +1,89 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2023 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.onap.ccsdk.features.sdnr.wt.common.database.queries.SortOrder; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.SqlDBClient; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBReaderWriter; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.BaseInventoryTreeProvider; +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.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.Inventory; +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.ReadInventoryListInputBuilder; +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.Sortorder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.entity.input.SortorderBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.entity.input.SortorderKey; + +public class SqlDbInventoryTreeProvider extends BaseInventoryTreeProvider { + private final SqlDBReaderWriter dbReader; + + public SqlDbInventoryTreeProvider(SqlDBClient dbClient, String controllerId) { + this.dbReader = new SqlDBReaderWriter<>(dbClient, Entity.Inventoryequipment, "", Inventory.class, controllerId); + } + + @Override + protected List getAllNodeIds() { + return this.dbReader.readAll(INVENTORY_PROPERTY_NODEID); + } + + @Override + protected List search(String filter, String sortOrderProperty, SortOrder sortOrder) { + return new ArrayList<>(this.dbReader.searchAll(Inventory.class, null, filter)); + } + + @Override + protected List search(String filter, String nodeId, String parentUuid, String uuid, + String sortOrderProperty, SortOrder sortOrder) { + List filters = new ArrayList<>(); + if (nodeId != null) { + filters.add(new FilterBuilder().setProperty(INVENTORY_PROPERTY_NODEID).setFiltervalue(nodeId).build()); + } + EntityInput input = new ReadInventoryListInputBuilder() + .setFilter(YangHelper2.getListOrMap(FilterKey.class, filters)).build(); + return new ArrayList<>(this.dbReader.searchAll(Inventory.class, input, filter)); + } + + @Override + protected List getItemsForNodes(List nodeIds, String sortOrderProperty, + SortOrder sortOrder) { + Map nodeFilter = new HashMap<>(); + Filter filter = new FilterBuilder().setProperty(INVENTORY_PROPERTY_NODEID) + .setFiltervalues(nodeIds.stream().collect(Collectors.toSet())).build(); + nodeFilter.put(filter.key(), filter); + Map so = new HashMap<>(); + Sortorder soItem = new SortorderBuilder().setProperty(sortOrderProperty) + .setSortorder(YangHelper2.getSortOrder(sortOrder)).build(); + so.put(soItem.key(), soItem); + EntityInput input = new ReadInventoryListInputBuilder().setFilter(nodeFilter).setSortorder(so).build(); + return new ArrayList<>(this.dbReader.readAll(Inventory.class, input)); + } +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlPropertyInfo.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlPropertyInfo.java new file mode 100644 index 000000000..76e5d70fe --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/SqlPropertyInfo.java @@ -0,0 +1,56 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2023 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.lang.reflect.Method; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBMapper; + +public class SqlPropertyInfo { + + private final Class javaType; + private final String name; + private final String sqlType; + + public SqlPropertyInfo(Method method) throws SqlDBMapper.UnableToMapClassException { + this.name = SqlDBMapper.getColumnName(method); + this.javaType = method.getReturnType(); + this.sqlType = SqlDBMapper.getDBType(this.javaType); + } + + public SqlPropertyInfo(String name, Class javaType, String sqlType){ + this.name =name; + this.javaType = javaType; + this.sqlType = sqlType; + } + + public boolean isSqlStringType(){ + return String.class.equals(this.javaType); + } + + public String getName() { + return this.name; + } + + public String getSqlType() { + return sqlType; + } +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/UserdataBuilder.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/UserdataBuilder.java index bb1268cc9..b10aaaa60 100644 --- a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/UserdataBuilder.java +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/UserdataBuilder.java @@ -26,7 +26,6 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; import javax.annotation.processing.Generated; -import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.yang.binding.AbstractAugmentable; import org.opendaylight.yangtools.yang.binding.Augmentation; import org.opendaylight.yangtools.yang.binding.DataObject; @@ -71,7 +70,7 @@ import org.opendaylight.yangtools.yang.binding.DataObject; * */ @Generated("mdsal-binding-generator") -public class UserdataBuilder implements Builder { +public class UserdataBuilder { private String _id; private String _value; @@ -148,7 +147,7 @@ public class UserdataBuilder implements Builder { return this; } - @Override + public Userdata build() { return new UserdataImpl(this); } diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/HtDatabaseEventsService.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/HtDatabaseEventsService.java index 776c91fe5..09baa3775 100644 --- a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/HtDatabaseEventsService.java +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/data/entity/HtDatabaseEventsService.java @@ -35,6 +35,7 @@ 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.SqlDBReaderWriterInventory; 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; @@ -68,12 +69,12 @@ public class HtDatabaseEventsService implements DataProvider { private static final NetconfTimeStamp NETCONFTIME_CONVERTER = NetconfTimeStampImpl.getConverter();; protected final SqlDBClient dbClient; - protected final String controllerId; + protected String controllerId; protected final SqlDBReaderWriter connectionlogRW; protected final SqlDBReaderWriter eventlogRW; protected final SqlDBReaderWriter eventRWFaultLog; protected final SqlDBReaderWriterFault eventRWFaultCurrent; - protected final SqlDBReaderWriter equipmentRW; + protected final SqlDBReaderWriterInventory equipmentRW; protected final SqlDBReaderWriter guicutthroughRW; protected final SqlDBReaderWriter networkelementConnectionRW; protected final SqlDBReaderWriterPm pm15mRW; @@ -101,7 +102,7 @@ public class HtDatabaseEventsService implements DataProvider { 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.controllerId); - this.equipmentRW = new SqlDBReaderWriter<>(dbClient, Entity.Inventoryequipment, config.getDbSuffix(), + this.equipmentRW = new SqlDBReaderWriterInventory<>(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.controllerId); this.guicutthroughRW = new SqlDBReaderWriter<>(dbClient, 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 index 1c24636db..8167c7bbf 100644 --- 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 @@ -34,7 +34,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; - +import java.util.stream.Collectors; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.SqlPropertyInfo; 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; @@ -91,8 +92,7 @@ public class SqlDBMapper { } public static String createTable(Class clazz, Entity e, String suffix, boolean autoIndex, - boolean withControllerId) - throws UnableToMapClassException { + boolean withControllerId) throws UnableToMapClassException { StringBuilder sb = new StringBuilder(); sb.append("CREATE TABLE IF NOT EXISTS `" + e.getName() + suffix + "` (\n"); if (autoIndex) { @@ -101,7 +101,7 @@ public class SqlDBMapper { } else { sb.append("`" + ID_DBCOL + "` " + STRING_DBTYPE + " " + getColumnOptions(ID_DBCOL, STRING_DBTYPE) + ",\n"); } - if(withControllerId) { + if (withControllerId) { sb.append("`" + ODLID_DBCOL + "` " + ODLID_DBTYPE + " " + getColumnOptions(ODLID_DBCOL, ODLID_DBTYPE) + ",\n"); } for (Method method : getFilteredMethods(clazz, true)) { @@ -115,7 +115,7 @@ public class SqlDBMapper { sb.append("`" + colName + "` " + dbType + " " + options + ",\n"); } sb.append("primary key(" + ID_DBCOL + ")"); - if(withControllerId) { + if (withControllerId) { sb.append(",foreign key(`" + ODLID_DBCOL + "`) references " + TABLENAME_CONTROLLER + "(" + ID_DBCOL + ")"); } @@ -138,6 +138,12 @@ public class SqlDBMapper { return options.toString(); } + /** + * + * @param clazz Class to scan for methods for their properties + * @param getterOrSetter true for using only getters, false using setters + * @return + */ public static List getFilteredMethods(Class clazz, boolean getterOrSetter) { Method[] methods = clazz.getMethods(); List list = new ArrayList<>(); @@ -220,7 +226,7 @@ public class SqlDBMapper { return convertCamelToKebabCase(camelName); } - private static String getDBType(Class valueType) throws UnableToMapClassException { + public 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) @@ -292,6 +298,16 @@ public class SqlDBMapper { return result.toString(); } + public static List getProperties(Class clazz) { + return getFilteredMethods(clazz, true).stream().map(e -> { + try { + return new SqlPropertyInfo(e); + } catch (UnableToMapClassException ex) { + throw new RuntimeException(ex); + } + }).collect(Collectors.toList()); + } + public static class UnableToMapClassException extends Exception { private static final long serialVersionUID = 1L; @@ -307,11 +323,12 @@ public class SqlDBMapper { } public static String escape(String o) { - return o.replace("'", "\'"); + return o.replace("'", "\\'"); } public static boolean isComplex(Class valueType) { - return DataObject.class.isAssignableFrom(valueType) || List.class.isAssignableFrom(valueType); + return DataObject.class.isAssignableFrom(valueType) || List.class.isAssignableFrom(valueType) + || Set.class.isAssignableFrom(valueType); } public static Object getNumericValue(Object value, Class valueType) { @@ -353,15 +370,15 @@ public class SqlDBMapper { } @SuppressWarnings("unchecked") - public static List read(ResultSet data, Class clazz, String column) + public static List read(ResultSet data, Class clazz, String column) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, SQLException, InstantiationException, SecurityException, NoSuchMethodException, JsonProcessingException { - if(data==null) { + if (data == null) { return Arrays.asList(); } S builder = findPOJOBuilder(clazz); - if(builder==null && column==null) { - throw new InstantiationException("unable to find builder for class "+clazz.getName()); + if (builder == null && column == null) { + throw new InstantiationException("unable to find builder for class " + clazz.getName()); } List list = new ArrayList<>(); @@ -387,13 +404,14 @@ public class SqlDBMapper { } @SuppressWarnings("unchecked") - private static T callBuild(S builder) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - Method method = builder.getClass().getMethod("build"); - return (T) method.invoke(builder); - } + private static T callBuild(S builder) throws NoSuchMethodException, SecurityException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method method = builder.getClass().getMethod("build"); + return (T) method.invoke(builder); + } - @SuppressWarnings("unchecked") - private static S findPOJOBuilder(Class ac) throws InstantiationException, IllegalAccessException, + @SuppressWarnings("unchecked") + private static S findPOJOBuilder(Class ac) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, NoSuchMethodException { try { String builder = null; @@ -407,7 +425,7 @@ public class SqlDBMapper { } if (builder != null) { Class innerBuilder = YangToolsMapperHelper.findClass(builder); - //Class> builderClass = (Class>) innerBuilder; + // Class> builderClass = (Class>) innerBuilder; return (S) innerBuilder.getDeclaredConstructor().newInstance(); } } catch (ClassNotFoundException e) { @@ -464,9 +482,9 @@ public class SqlDBMapper { } else if (dstType.equals(Long.class)) { return value; } else if (dstType.equals(Integer.class)) { - return (int)value; + return (int) value; } else if (dstType.equals(Byte.class)) { - return (byte)value; + return (byte) value; } return null; } diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReader.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReader.java new file mode 100644 index 000000000..9798d12f8 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReader.java @@ -0,0 +1,210 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2023 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 org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.SqlDBClient; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.PropertyList; +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.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.SqlQuery; +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; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +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 java.util.Optional; + +public class SqlDBReader { + private static final Logger LOG = LoggerFactory.getLogger(SqlDBReader.class); + + protected final Entity entity; + private final Class clazz; + protected final SqlDBClient dbService; + protected final String controllerId; + protected final String tableName; + protected final boolean ignoreControllerId; + protected final PropertyList propertyList; + public SqlDBReader(SqlDBClient dbService, Entity e, String dbSuffix, Class clazz, + String controllerId) { + this(dbService, e, dbSuffix, clazz, controllerId, false); + } + + public SqlDBReader(SqlDBClient dbService, Entity e, String dbSuffix, Class clazz, + String controllerId, boolean ignoreControllerId) { + this.dbService = dbService; + this.entity = e; + this.clazz = clazz; + this.tableName = this.entity.getName() + dbSuffix; + this.controllerId = controllerId; + this.ignoreControllerId = ignoreControllerId; + this.propertyList = new PropertyList(clazz); + } + + public long count(List 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); + query = String.format("SELECT COUNT(`id`) FROM `%s`", this.tableName); + } else { + query = String.format("SELECT COUNT(`id`) FROM `%s` %s", this.tableName, + SqlQuery.getWhereExpression(filter)); + } + ResultSet data = this.dbService.read(query); + if (data == null) { + return 0; + } + long cnt = 0; + if (data.next()) { + cnt = data.getLong(1); + } + try { + data.close(); + } catch (SQLException ignore) { + } + return cnt; + } + + public long count(List list, String controllerId) throws SQLException { + if (list == null) { + list = new ArrayList<>(); + } + Optional 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 getData(EntityInput input) { + SelectQuery query = new SelectQuery(this.tableName, input, this.controllerId); + if (LOG.isTraceEnabled()) { + LOG.trace("query={}", query.toSql()); + } + try { + ResultSet data = this.dbService.read(query.toSql()); + List mappedData = SqlDBMapper.read(data, clazz); + final Map filter = input.getFilter(); + try { + if (data != null) { + data.close(); + } + } catch (SQLException ignore) { + } + long total = this.count(filter != null ? new ArrayList<>(filter.values()) : null, this.controllerId); + return new QueryResult(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 QueryResult.createEmpty(); + } + + public List readAll(Class clazz) { + SelectQuery query = new SelectQuery(this.tableName, this.controllerId); + if (LOG.isTraceEnabled()) { + LOG.trace("query={}", query.toSql()); + } + return this.readAll(clazz, query); + } + + public List readAll(Class clazz, EntityInput input) { + SelectQuery query = new SelectQuery(this.tableName, input, this.controllerId); + return this.readAll(clazz, query); + } + public List searchAll(Class clazz, EntityInput input, String searchTerm) { + SelectQuery query = new SelectQuery(this.tableName, input, this.controllerId); + if(searchTerm!=null && !searchTerm.isEmpty()) { + query.setAllPropertyFilter(searchTerm, this.propertyList); + } + return this.readAll(clazz, query); + } + public List readAll(Class clazz, SelectQuery query) { + try { + ResultSet data = this.dbService.read(query.toSql()); + List mappedData = SqlDBMapper.read(data, clazz); + try { + data.close(); + } catch (SQLException ignore) { + } + return mappedData; + } catch (SQLException | IllegalAccessException | IllegalArgumentException | InvocationTargetException + | InstantiationException | SecurityException | NoSuchMethodException | JsonProcessingException e) { + LOG.warn("problem reading all data{}: ", this.entity, e); + } + return null; + } + + public List readAll(String key) { + SelectQuery query = new SelectQuery(this.tableName, key, this.controllerId).groupBy(key); + if (LOG.isTraceEnabled()) { + LOG.trace("query={}", query.toSql()); + } + try { + ResultSet data = this.dbService.read(query.toSql()); + List mappedData = SqlDBMapper.read(data, String.class, key); + try { + data.close(); + } catch (SQLException ignore) { + } + return mappedData; + } catch (SQLException | IllegalAccessException | IllegalArgumentException | InvocationTargetException + | InstantiationException | SecurityException | NoSuchMethodException | JsonProcessingException e) { + LOG.warn("problem reading all data {} for key: ", this.entity, key, e); + } + return null; + } + + public T read(String id) { + SelectQuery query = + new SelectQuery(this.tableName, this.controllerId).addFilter(SqlDBMapper.ID_DBCOL, id); + if (LOG.isTraceEnabled()) { + LOG.trace("query={}", query.toSql()); + } + T item = null; + try { + ResultSet data = this.dbService.read(query.toSql()); + List mappedData = SqlDBMapper.read(data, clazz); + item = mappedData.size() > 0 ? mappedData.get(0) : null; + } catch (SQLException | IllegalAccessException | IllegalArgumentException | InvocationTargetException + | InstantiationException | SecurityException | NoSuchMethodException | JsonProcessingException e) { + LOG.warn("problem reading data {}: ", this.entity, e); + } + return item; + } +} 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 index 56a986e55..0df2dc5d6 100644 --- 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 @@ -21,128 +21,39 @@ */ 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.Map; -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.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 SqlDBReaderWriter { +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.List; - private static final Logger LOG = LoggerFactory.getLogger(SqlDBReaderWriter.class); +public class SqlDBReaderWriter extends SqlDBReader { - protected final Entity entity; - private final Class clazz; - protected final SqlDBClient dbService; - protected final String controllerId; - protected final String tableName; - private final boolean ignoreControllerId; + private static final Logger LOG = LoggerFactory.getLogger(SqlDBReaderWriter.class); public SqlDBReaderWriter(SqlDBClient dbService, Entity e, String dbSuffix, Class clazz, String controllerId) { - this(dbService, e, dbSuffix, clazz, controllerId, false); + super(dbService, e, dbSuffix, clazz, controllerId); } public SqlDBReaderWriter(SqlDBClient dbService, Entity e, String dbSuffix, Class clazz, String controllerId, boolean ignoreControllerId) { - this.dbService = dbService; - this.entity = e; - this.clazz = clazz; - this.tableName = this.entity.getName() + dbSuffix; - this.controllerId = controllerId; - this.ignoreControllerId = ignoreControllerId; - } - - public long count(List 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); - query = String.format("SELECT COUNT(`id`) FROM `%s`", this.tableName); - } else { - query = String.format("SELECT COUNT(`id`) FROM `%s` %s", this.tableName, - SqlQuery.getWhereExpression(filter)); - } - ResultSet data = this.dbService.read(query); - if(data==null) { - return 0; - } - long cnt = 0; - if (data.next()) { - cnt = data.getLong(1); - } - try { - data.close(); - } catch (SQLException ignore) { - } - return cnt; - } - - public long count(List list, String controllerId) throws SQLException { - if (list == null) { - list = new ArrayList<>(); - } - Optional 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 getData(EntityInput input) { - SelectQuery query = new SelectQuery(this.tableName, input, this.controllerId); - if (LOG.isTraceEnabled()) { - LOG.trace("query={}", query.toSql()); - } - try { - ResultSet data = this.dbService.read(query.toSql()); - List mappedData = SqlDBMapper.read(data, clazz); - final Map filter = input.getFilter(); - try { - if(data!=null) { - data.close(); - } - } catch (SQLException ignore) { - } - long total = this.count(filter != null ? new ArrayList<>(filter.values()) : null, this.controllerId); - return new QueryResult(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 QueryResult.createEmpty(); + super(dbService, e, dbSuffix, clazz, controllerId, ignoreControllerId); } - - public String write(S object, String id) { if (id == null) { return this.writeWithoutId(object); @@ -309,62 +220,4 @@ public class SqlDBReaderWriter { public int remove(@Nullable String id) { return this.remove(Arrays.asList(new FilterBuilder().setProperty("id").setFiltervalue(id).build())); } - - public List readAll(Class clazz) { - SelectQuery query = new SelectQuery(this.tableName); - if (LOG.isTraceEnabled()) { - LOG.trace("query={}", query.toSql()); - } - try { - ResultSet data = this.dbService.read(query.toSql()); - List mappedData = SqlDBMapper.read(data, clazz); - try { - data.close(); - } catch (SQLException ignore) { - } - return mappedData; - } catch (SQLException | IllegalAccessException | IllegalArgumentException | InvocationTargetException - | InstantiationException | SecurityException | NoSuchMethodException | JsonProcessingException e) { - LOG.warn("problem reading all data{}: ", this.entity, e); - } - return null; - } - - public List readAll(String key) { - SelectQuery query = new SelectQuery(this.tableName, key, this.controllerId).groupBy(key); - if (LOG.isTraceEnabled()) { - LOG.trace("query={}", query.toSql()); - } - try { - ResultSet data = this.dbService.read(query.toSql()); - List mappedData = SqlDBMapper.read(data, String.class, key); - try { - data.close(); - } catch (SQLException ignore) { - } - return mappedData; - } catch (SQLException | IllegalAccessException | IllegalArgumentException | InvocationTargetException - | InstantiationException | SecurityException | NoSuchMethodException | JsonProcessingException e) { - LOG.warn("problem reading all data {} for key: ", this.entity, key, e); - } - return null; - } - - public T read(String id) { - SelectQuery query = - new SelectQuery(this.tableName, this.controllerId).addFilter(SqlDBMapper.ID_DBCOL, id); - if (LOG.isTraceEnabled()) { - LOG.trace("query={}", query.toSql()); - } - T item = null; - try { - ResultSet data = this.dbService.read(query.toSql()); - List mappedData = SqlDBMapper.read(data, clazz); - item = mappedData.size()>0? mappedData.get(0): null; - } catch (SQLException | IllegalAccessException | IllegalArgumentException | InvocationTargetException - | InstantiationException | SecurityException | NoSuchMethodException | JsonProcessingException e) { - LOG.warn("problem reading data {}: ", this.entity, e); - } - return item; - } } diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriterInventory.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriterInventory.java new file mode 100644 index 000000000..5ed44cb29 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriterInventory.java @@ -0,0 +1,87 @@ +/* + * ============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.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.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.FilterKey; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SqlDBReaderWriterInventory extends SqlDBReaderWriter { + + private final Logger LOG = LoggerFactory.getLogger(SqlDBReaderWriterInventory.class); + + private static final String KEY = "node-id"; + + private static final FilterKey FILTERKEY = new FilterKey(KEY); + + public SqlDBReaderWriterInventory(SqlDBClient dbService, Entity e, String dbSuffix, Class clazz, + String controllerId) { + super(dbService, e, dbSuffix, clazz, controllerId); + } + + /** + * get aggregated devices list + * + * @param input filter should be empty/no filter handled, only sortorder for KEY ('node-name') + * @return + */ + public QueryResult getDataDeviceList(EntityInput input) { + + SelectQuery query = new SelectQuery(this.tableName, KEY, this.controllerId).groupBy(KEY); + query.setPagination(input.getPagination()); + Map 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 mappedData = SqlDBMapper.read(data, String.class, KEY); + try { data.close(); } catch (SQLException ignore) { } + Map inpFilter = input.getFilter(); + long total = this.count(inpFilter != null ? new ArrayList<>(inpFilter.values()) : null, this.controllerId); + return new QueryResult<>(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; + } + + +} diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriterUserdata.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriterUserdata.java index 258cd160f..398e9501a 100644 --- a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriterUserdata.java +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/database/SqlDBReaderWriterUserdata.java @@ -30,8 +30,4 @@ public class SqlDBReaderWriterUserdata extends SqlDBReaderWriter { public SqlDBReaderWriterUserdata(SqlDBClient dbService, Entity e, String dbSuffix) { super(dbService, e, dbSuffix, Userdata.class, null, true); } - - - - } 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 index f52fbd55a..c505816ef 100644 --- 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 @@ -107,7 +107,7 @@ public class InsertQuery implements SqlQuery { } if (this.id != null && !cols.contains("`id`")) { cols.add("`id`"); - args.add("'" + this.id + "'"); + args.add("'" + SqlDBMapper.escape(this.id) + "'"); } if (!this.ignoreControllerId) { args.add("'" + this.controllerId + "'"); diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/SelectQuery.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/SelectQuery.java index a4df26bae..48165f1bf 100644 --- a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/SelectQuery.java +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/SelectQuery.java @@ -28,7 +28,9 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import org.eclipse.jdt.annotation.Nullable; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.PropertyList; import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBMapper; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.filters.SqlDBSearchFilter; 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; @@ -49,10 +51,12 @@ public class SelectQuery implements SqlQuery { private final String tableName; private final List filters; private final List sortExpressions; + private final String controllerId; private long page; private long pageSize; private final List fields; private final List groups; + private SqlDBSearchFilter allPropertyFilter; public SelectQuery(String tableName) { this(tableName, (String)null); @@ -68,6 +72,8 @@ public class SelectQuery implements SqlQuery { this.groups = new ArrayList<>(); this.page = DEFAULT_PAGE; this.pageSize = DEFAULT_PAGESIZE; + this.controllerId = controllerId; + this.allPropertyFilter = null; if (controllerId != null) { this.addFilter(SqlDBMapper.ODLID_DBCOL, controllerId); } @@ -146,7 +152,9 @@ public class SelectQuery implements SqlQuery { public void addSortOrder(String col, String order) { this.sortExpressions.add(String.format("`%s` %s", col, order)); } - + public void setAllPropertyFilter(String filter, PropertyList propertyList) { + this.allPropertyFilter = new SqlDBSearchFilter(propertyList, filter); + } public void setPagination(long page, long pageSize) { this.page = page; this.pageSize = pageSize; @@ -175,7 +183,7 @@ public class SelectQuery implements SqlQuery { } else { sb.append(String.format("SELECT `%s` FROM `%s`", String.join("`,`", this.fields), this.tableName)); } - sb.append(SqlQuery.getWhereExpression(this.filters)); + sb.append(SqlQuery.getWhereExpression(this.filters, this.controllerId, this.allPropertyFilter)); if (this.groups.size() > 0) { sb.append(String.format(" GROUP BY `%s`", String.join("`,`", this.groups))); } @@ -198,5 +206,27 @@ public class SelectQuery implements SqlQuery { this.groups.add(group); return this; } + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("SelectQuery [tableName="); + builder.append(tableName); + builder.append(", filters="); + builder.append(filters); + builder.append(", sortExpressions="); + builder.append(sortExpressions); + builder.append(", page="); + builder.append(page); + builder.append(", pageSize="); + builder.append(pageSize); + builder.append(", fields="); + builder.append(fields); + builder.append(", groups="); + builder.append(groups); + builder.append("]"); + return builder.toString(); + } + + } 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 index c954faadb..89638cc8b 100644 --- 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 @@ -36,6 +36,7 @@ import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlD 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.database.sqldb.query.filters.SqlDBSearchFilter; 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; @@ -58,26 +59,32 @@ public interface SqlQuery { return getWhereExpression(filters, null); } public static String getWhereExpression(Collection filters, String controllerId) { + return getWhereExpression(filters, controllerId, null); + } + public static String getWhereExpression(Collection filters, String controllerId, SqlDBSearchFilter allPropertyFilter) { if (filters == null && controllerId == null) { return ""; } StringBuilder sb = new StringBuilder(); List filters2 = filters != null - ? filters.stream().filter(e -> !"*".equals(e.getFiltervalue())).map(e -> getFilterExpression(e)) + ? filters.stream().filter(e -> !isFilterEmpty(e)).map(e -> getFilterExpression(e)) .collect(Collectors.toList()) : new ArrayList<>(); - if(controllerId!=null) { + if (controllerId != null) { filters2.add(getFilterExpression(SqlDBMapper.ODLID_DBCOL, controllerId)); } - if (!filters2.isEmpty() ) { + if(allPropertyFilter!=null){ + filters2.add(allPropertyFilter.getFilterExpression(true)); + } + if (!filters2.isEmpty()) { sb.append(" WHERE "); sb.append(StringUtil.join(" AND ", filters2)); } return sb.toString(); } - public static String getFilterExpression(Filter filter) { + private static String getFilterExpression(Filter filter) { String property = filter.getProperty(); List values = collectValues(filter.getFiltervalue(), filter.getFiltervalues()).stream() .filter(e -> !"*".equals(e)).collect(Collectors.toList()); @@ -95,7 +102,7 @@ public interface SqlQuery { return null; } - public static String getFilterExpression(String property, String value) { + private static String getFilterExpression(String property, String value) { String filter = null; if (DbFilter.hasSearchParams(value)) { if (TIMESTAMPPROPERTYNAMES.contains(property.toLowerCase())) { @@ -118,7 +125,7 @@ public interface SqlQuery { return new DBFilterKeyValuePair(property, value).getFilterExpression(); } - static List collectValues(String filtervalue, Set filtervalues) { + private static List collectValues(String filtervalue, Set filtervalues) { if (filtervalues == null) { return Arrays.asList(filtervalue); } @@ -367,4 +374,18 @@ public interface SqlQuery { return upperEnd; } + + private static boolean isFilterEmpty(Filter filter) { + @Nullable Set filtervalues = filter.getFiltervalues(); + @Nullable String filtervalue = filter.getFiltervalue(); + + List allValues = filtervalues == null ? new ArrayList<>() : new ArrayList<>(filtervalues); + if (filtervalue != null) { + allValues.add(filtervalue); + } + + return allValues.isEmpty() || allValues.contains("*"); + } + + } diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/DBKeyValuePair.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/DBKeyValuePair.java index 70b683a1a..7ea393da5 100644 --- a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/DBKeyValuePair.java +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/DBKeyValuePair.java @@ -23,6 +23,8 @@ package org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.filter import java.math.BigInteger; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBMapper; + public class DBKeyValuePair implements SqlDBFilter { private final String key; @@ -62,7 +64,7 @@ public class DBKeyValuePair implements SqlDBFilter { } else if (this.getValue() instanceof BigInteger) { return String.format("`%s`=%d", this.key, (BigInteger)this.value); } else { - return String.format("`%s`='%s'", this.key, this.value); + return String.format("`%s`='%s'", this.key, SqlDBMapper.escape(this.value)); } } } 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 index 2997c7040..3ff2bdbea 100644 --- 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 @@ -25,4 +25,8 @@ public interface SqlDBFilter { public String getFilterExpression(); + default String getFilterExpression(boolean enclose) { + return enclose ? String.format("(%s)", this.getFilterExpression()) : this.getFilterExpression(); + } + } diff --git a/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/SqlDBSearchFilter.java b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/SqlDBSearchFilter.java new file mode 100644 index 000000000..db5f2cb3b --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/sqldb/query/filters/SqlDBSearchFilter.java @@ -0,0 +1,45 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2023 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.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.PropertyList; + +import java.util.List; +import java.util.stream.Collectors; + +public class SqlDBSearchFilter implements SqlDBFilter { + private final PropertyList propertyList; + private final String filter; + + public SqlDBSearchFilter(PropertyList propertyList, String filter) { + this.propertyList = propertyList; + this.filter = filter; + } + + @Override + public String getFilterExpression() { + List tmp = this.propertyList.stream() + .map(e -> new RegexSqlDBFilter(e.getName(), this.filter).getFilterExpression()) + .collect(Collectors.toList()); + return String.join(" OR ", tmp); + } +} diff --git a/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestMariaDataProvider.java b/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestMariaDataProvider.java index 33703042e..5942321cf 100644 --- a/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestMariaDataProvider.java +++ b/sdnr/wt/data-provider/dblib/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/dblib/test/TestMariaDataProvider.java @@ -23,14 +23,13 @@ */ package org.onap.ccsdk.features.sdnr.wt.dataprovider.dblib.test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import ch.vorburger.exec.ManagedProcessException; import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -38,6 +37,10 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.junit.AfterClass; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import org.junit.BeforeClass; import org.junit.Test; import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.SqlDBClient; @@ -80,6 +83,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.pro import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.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.InventoryBuilder; 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.NetworkElementConnectionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.NetworkElementConnectionEntity; @@ -92,6 +96,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.pro import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.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.ReadInventoryDeviceListOutputBuilder; 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; @@ -118,7 +123,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.pro import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.network.element.connection.list.output.Data; import org.opendaylight.yangtools.yang.common.Uint32; import org.opendaylight.yangtools.yang.common.Uint64; -import ch.vorburger.exec.ManagedProcessException; public class TestMariaDataProvider { @@ -390,8 +394,47 @@ public class TestMariaDataProvider { dbProvider.writeInventory(NODEID1, list); data = dbProvider.readInventoryList(createInput(1, 50)); assertEquals(22, data.getData().size()); + ReadInventoryDeviceListOutputBuilder data2 = dbProvider.readInventoryDeviceList(createInput(1, 20)); + assertEquals(2, data2.getData().size()); + assertTrue(data2.getData().contains("sim1") && data2.getData().contains("sim2")); data = dbProvider.readInventoryList(createInput("tree-level", "0", 1, 50)); assertEquals(5, data.getData().size()); + + try { + dbProvider.writeInventory("sim3", loadListFile("/inventory2.json", Inventory.class)); + } catch (IOException e) { + fail("problem loading inventory data2"); + } + data2 = dbProvider.readInventoryDeviceList(createInput(1, 20)); + assertEquals(3, data2.getData().size()); + assertTrue(data2.getData().contains("sim1") && data2.getData().contains("sim2") && + data2.getData().contains("sim3")); + } + + @Test + public void testInventoryWithComplexTypes() { + try { + dbClient.delete(new DeleteQuery(Entity.Inventoryequipment, null).toSql()); + } catch (SQLException e) { + e.printStackTrace(); + fail("problem clearing inventoryequipment"); + } + ReadInventoryListOutputBuilder data = dbProvider.readInventoryList(createInput(1, 20)); + assertEquals(0, data.getData().size()); + try { + Inventory inventory = new InventoryBuilder() + .setContainedHolder(new HashSet<>( + Arrays.asList("STM1-1", "Radio-2A", "LAN-3-SFP", "Radio-1A", "STM1-2", "LAN-4-SFP"))) + .setSerial("14209652001003620").setDescription("INDOOR UNIT ALCPlus2e") + .setTreeLevel(Uint32.valueOf(0)).setNodeId("NTS_ONF14").build(); + dbProvider.writeInventory(NODEID1, new ArrayList(Arrays.asList(inventory))); + } catch (Exception e) { + e.printStackTrace(); + fail("problem loading inventory data"); + + } + data = dbProvider.readInventoryList(createInput(1, 50)); + assertEquals(1, data.getData().size()); } @Test diff --git a/sdnr/wt/data-provider/dblib/src/test/resources/inventory2.json b/sdnr/wt/data-provider/dblib/src/test/resources/inventory2.json new file mode 100644 index 000000000..b13220f28 --- /dev/null +++ b/sdnr/wt/data-provider/dblib/src/test/resources/inventory2.json @@ -0,0 +1,364 @@ +[ + { + "description": "WS/p8.module/a2.module#5", + "date": "2013-04-13T00:00:00.0Z", + "version": "a2.module-newest", + "node-id": "sim3", + "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": "sim3", + "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": "sim3", + "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": "sim3", + "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": "sim3", + "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": "sim3", + "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": "sim3", + "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": "sim3", + "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": "sim3", + "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": "sim3", + "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": "sim3", + "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": "sim3", + "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": "sim3", + "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": "sim3", + "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": "sim3", + "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": "sim3", + "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": "sim3", + "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": "sim3", + "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": "sim3", + "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": "sim3", + "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": "sim3", + "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" + } +] \ No newline at end of file -- cgit 1.2.3-korg