diff options
author | 2020-07-15 15:44:23 +0200 | |
---|---|---|
committer | 2020-07-15 19:05:46 +0200 | |
commit | 25b3759a0907d06e0d8e391f751c6fcf067087f5 (patch) | |
tree | f9cd6de6e685216c44f4c44cc7f220f3f23f22c5 /sdnr/wt/data-provider/provider/src/main/java/org | |
parent | 002ad417b90882524276d1b9cfe377c6f6293a4c (diff) |
SDN-R data-provider with ES7
Extend to ES 7.x and DB setup
Issue-ID: SDNC-1288
Signed-off-by: highstreetherbert <herbert.eiselt@highstreet-technologies.com>
Change-Id: Id7778322b793bfa7472a14a90bc0d1fd953c8c73
Signed-off-by: highstreetherbert <herbert.eiselt@highstreet-technologies.com>
Diffstat (limited to 'sdnr/wt/data-provider/provider/src/main/java/org')
26 files changed, 1674 insertions, 655 deletions
diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessor.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessor.java index 3fe2a62af..c3c63a963 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessor.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessor.java @@ -24,38 +24,35 @@ package org.onap.ccsdk.features.sdnr.wt.dataprovider.data; import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; import org.onap.ccsdk.features.sdnr.wt.common.database.SearchResult; import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilder; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.EsDataObjectReaderWriter; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.EsDataObjectReaderWriter2; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Entity; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EntityInput; import org.opendaylight.yangtools.yang.binding.DataObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class DataObjectAcessor<T extends DataObject> extends EsDataObjectReaderWriter<T> { +public class DataObjectAcessor<T extends DataObject> extends EsDataObjectReaderWriter2<T> { private static final Logger LOG = LoggerFactory.getLogger(DataObjectAcessor.class); - public DataObjectAcessor(HtDatabaseClient dbClient, Entity entity, Class<T> clazz) throws ClassNotFoundException { - this(dbClient, entity, clazz, true); + DataObjectAcessor(HtDatabaseClient dbClient, Entity entity, Class<T> clazz) throws ClassNotFoundException { + super(dbClient, entity, clazz); LOG.info("Create {}", this.getClass().getName()); } - public DataObjectAcessor(HtDatabaseClient dbClient, Entity entity, Class<T> clazz, boolean idSupported) - throws ClassNotFoundException { - super(dbClient, entity, clazz); - if (idSupported) { - setEsIdAttributeName("_id"); - } - } + public QueryResult<T> getData(EntityInput input) { - QueryResult<T> getData(EntityInput input) { - long page = QueryByFilter.getPage(input); - long pageSize = QueryByFilter.getPageSize(input); - LOG.info("Request: {}", this.getDataTypeName()); - QueryBuilder query = QueryByFilter.fromFilter(input.getFilter()).from((page - 1) * pageSize).size(pageSize); - QueryByFilter.setSortOrder(query, input.getSortorder()); - SearchResult<T> result = doReadAll(query, query.contains("range")); - return new QueryResult<>(page, pageSize, result); + QueryByFilter queryByFilter = new QueryByFilter(input); + QueryBuilder queryBuilder = queryByFilter.getQueryBuilderByFilter(); + // Exception handling during user input for invalid filter input. + // This wrong filter by user is allowed an results into empty data. + boolean ignoreException = queryBuilder.contains("range"); + + LOG.info("Request: {} filter {} ignoreException{}:", this.getDataTypeName(), queryByFilter, ignoreException); + + SearchResult<T> result = doReadAll(queryBuilder, ignoreException); + return new QueryResult<>(queryByFilter, result); } + } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessorPm.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessorPm.java index 8eb51b6aa..83017366d 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessorPm.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessorPm.java @@ -26,16 +26,11 @@ import java.io.IOException; import org.onap.ccsdk.features.sdnr.wt.common.database.ExtRestClient; import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; import org.onap.ccsdk.features.sdnr.wt.common.database.SearchResult; -import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilder; -import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilders; import org.onap.ccsdk.features.sdnr.wt.common.database.requests.SearchRequest; import org.onap.ccsdk.features.sdnr.wt.common.database.responses.AggregationEntries; import org.onap.ccsdk.features.sdnr.wt.common.database.responses.SearchResponse; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Entity; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EntityInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SortOrder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.entity.input.Filter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.entity.input.Sortorder; import org.opendaylight.yangtools.yang.binding.DataObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,7 +44,7 @@ public class DataObjectAcessorPm<T extends DataObject> extends DataObjectAcessor private static final String KEY = "node-name"; - enum Intervall { + public enum Intervall { PMDATA15M("historicalperformance15min", "historicalperformance15min"), PMDATA24H("historicalperformance24h", "historicalperformance24h"); @@ -75,7 +70,8 @@ public class DataObjectAcessorPm<T extends DataObject> extends DataObjectAcessor public DataObjectAcessorPm(HtDatabaseClient dbClient, Intervall mode, Entity entity, Class<T> clazz) throws ClassNotFoundException { - super(dbClient, entity, clazz, false); + super(dbClient, entity, clazz); + LOG.info("DataObjectAcessorPm"); this.dbClient = dbClient; this.mode = mode; } @@ -87,47 +83,24 @@ public class DataObjectAcessorPm<T extends DataObject> extends DataObjectAcessor * @return * @throws IOException */ - QueryResult<String> getDataLtpList(EntityInput input) throws IOException { - long page = QueryByFilter.getPage(input); - long pageSize = QueryByFilter.getPageSize(input); - Filter nodeFilter = QueryByFilter.getFilter(input.getFilter(), NODE_KEY); - if (nodeFilter != null) { - SearchRequest request = new SearchRequest(mode.getIndex(), mode.getType()); - request.setQuery( - QueryBuilders.matchQuery(NODE_KEY, nodeFilter.getFiltervalue()).aggregations(UUID_KEY).size(0)); - try { - SearchResponse response = this.dbClient.search(request); - AggregationEntries aggs = response.getAggregations(UUID_KEY); - String[] uuids = aggs.getKeysAsPagedStringList(pageSize, pageSize * (page - 1)); - long totalSize = aggs.size(); - return new QueryResult<String>(page, pageSize, new SearchResult<String>(uuids, totalSize)); - } catch (IOException e) { - throw new IOException("problem reading ltps for req=" + request, e); - } - } else { - String msg = "no nodename in filter found "; - LOG.debug(msg); - throw new IllegalArgumentException(msg); + public QueryResult<String> getDataLtpList(EntityInput input) throws IOException { + + QueryByFilter queryByFilter = new QueryByFilter(input); + SearchRequest request = + queryByFilter.getSearchRequestByFilter(NODE_KEY, UUID_KEY, mode.getIndex(), mode.getType()); + try { + SearchResponse response = this.dbClient.search(request); + AggregationEntries aggs = response.getAggregations(UUID_KEY); + String[] uuids = + aggs.getKeysAsPagedStringList(queryByFilter.getPageSize(), queryByFilter.getPageStartIndex()); + long totalSize = aggs.size(); + return new QueryResult<String>(queryByFilter.getPage(), queryByFilter.getPageSize(), + new SearchResult<String>(uuids, totalSize)); + } catch (IOException e) { + throw new IOException("problem reading ltps for req=" + request, e); } } - // QueryResult<String> getDataDeviceList(EntityInput input) throws IOException { - // - // long page = QueryByFilter.getPage(input); - // long pageSize = QueryByFilter.getPageSize(input); - // - // SearchRequest request = new SearchRequest(mode.getIndex(), mode.getType()); - // request.setQuery(QueryBuilders.matchAllQuery().aggregations(KEY).size(0)); - //// try { - // SearchResponse response = this.dbClient.search(request); - // AggregationEntries aggs = response.getAggregations(KEY); - // String[] uuids = aggs.getKeysAsPagedStringList(pageSize, pageSize * (page - 1)); - // long totalSize = aggs.size(); - // return new QueryResult<String>(page, pageSize, new SearchResult<String>(uuids, totalSize)); - //// } catch (IOException e) { - //// throw new IOException("problem reading nodes for req="+request, e); - //// } - // } /** * get aggregated devices list * @@ -135,31 +108,19 @@ public class DataObjectAcessorPm<T extends DataObject> extends DataObjectAcessor * @return * @throws IOException */ - QueryResult<String> getDataDeviceList(EntityInput input) throws IOException { - - long page = QueryByFilter.getPage(input); - long pageSize = QueryByFilter.getPageSize(input); - - Sortorder soNode = QueryByFilter.getSortOrder(input.getSortorder(), KEY); - SearchRequest request = new SearchRequest(mode.getIndex(), mode.getType()); - QueryBuilder query = null; - if (soNode != null) { - query = QueryBuilders.matchAllQuery() - .aggregations(KEY, - soNode.getSortorder() == SortOrder.Ascending - ? org.onap.ccsdk.features.sdnr.wt.common.database.queries.SortOrder.ASCENDING - : org.onap.ccsdk.features.sdnr.wt.common.database.queries.SortOrder.DESCENDING) - .size(0); - } else { - query = QueryBuilders.matchAllQuery().aggregations(KEY).size(0); - } - request.setQuery(query); + public QueryResult<String> getDataDeviceList(EntityInput input) throws IOException { + + QueryByFilter queryByFilter = new QueryByFilter(input); + SearchRequest request = + queryByFilter.getSearchRequestBySortOrder(NODE_KEY, UUID_KEY, mode.getIndex(), mode.getType()); try { SearchResponse response = this.dbClient.search(request); AggregationEntries aggs = response.getAggregations(KEY); - String[] uuids = aggs.getKeysAsPagedStringList(pageSize, pageSize * (page - 1)); + String[] uuids = + aggs.getKeysAsPagedStringList(queryByFilter.getPageSize(), queryByFilter.getPageStartIndex()); long totalSize = aggs.size(); - return new QueryResult<String>(page, pageSize, new SearchResult<String>(uuids, totalSize)); + return new QueryResult<String>(queryByFilter.getPage(), queryByFilter.getPageSize(), + new SearchResult<String>(uuids, totalSize)); } catch (IOException e) { throw new IOException("problem reading nodes for req=" + request, e); } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessorStatus.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessorStatus.java index 4dd52f43a..1fa6de37d 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessorStatus.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessorStatus.java @@ -43,12 +43,12 @@ public class DataObjectAcessorStatus extends DataObjectAcessor<Data> { private final Entity entity; public DataObjectAcessorStatus(HtDatabaseClient dbClient, Entity entity) throws ClassNotFoundException { - super(dbClient, entity, Data.class, false); + super(dbClient, entity, Data.class); this.dbClient = dbClient; this.entity = entity; } - QueryResult<Data> getDataStatus() throws IOException { + public QueryResult<Data> getDataStatus() throws IOException { SearchRequest request = getNewInstanceOfSearchRequest(entity); request.setQuery(QueryBuilders.matchAllQuery().aggregations(ESDATATYPE_FAULTCURRENT_SEVERITY_KEY).size(0)); SearchResponse response = this.dbClient.search(request); diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataTreeChildObject.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessorWithId.java index a92265a84..10dd7792c 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataTreeChildObject.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataObjectAcessorWithId.java @@ -21,26 +21,21 @@ */ package org.onap.ccsdk.features.sdnr.wt.dataprovider.data; -import java.util.Map; +import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Entity; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -/** - * @author Michael Dürre - * - */ -public class DataTreeChildObject { +public class DataObjectAcessorWithId<T extends DataObject> extends DataObjectAcessor<T> { - private final String label; - private final String ownSeverity; - private final String childrenSeveritySummary; - private final boolean isMatch; - private final Map<String, DataTreeChildObject> children; + private static final Logger LOG = LoggerFactory.getLogger(DataObjectAcessorWithId.class); - public DataTreeChildObject(String label, boolean isMatch, Map<String, DataTreeChildObject> children, - String ownSeverity, String childrenSeveritySummary) { - this.label = label; - this.isMatch = isMatch; - this.children = children; - this.ownSeverity = ownSeverity; - this.childrenSeveritySummary = childrenSeveritySummary; + public DataObjectAcessorWithId(HtDatabaseClient dbClient, Entity entity, Class<T> clazz) + throws ClassNotFoundException { + super(dbClient, entity, clazz); + setEsIdAttributeName("_id"); + LOG.info("Create {}", this.getClass().getName()); } + } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataTreeObject.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataTreeObject.java deleted file mode 100644 index 4333dccb4..000000000 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/DataTreeObject.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * ============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.data; - -import java.util.HashMap; - -/** - * @author Michael Dürre - * - */ -public class DataTreeObject extends HashMap<String, DataTreeChildObject> { - -} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/ElasticSearchDataProvider.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/ElasticSearchDataProvider.java index 76d47e3e0..30e617ab6 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/ElasticSearchDataProvider.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/ElasticSearchDataProvider.java @@ -77,17 +77,15 @@ public class ElasticSearchDataProvider /*extends BaseStatusProvider /* implement 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 static final boolean DEFAULT_TRUSTALLCERTS = false; - private final HtDatabaseClient dbClient; - private final DataObjectAcessor<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.faultcurrent.list.output.Data> eventRWFaultCurrent; - private final DataObjectAcessor<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.faultlog.list.output.Data> eventRWFaultLog; - private final DataObjectAcessor<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.mediator.server.list.output.Data> mediatorserverRW; - private final DataObjectAcessor<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.maintenance.list.output.Data> maintenanceRW; - private final DataObjectAcessor<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.inventory.list.output.Data> equipmentRW; - private final DataObjectAcessor<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.connectionlog.list.output.Data> connnectionlogRW; - private final DataObjectAcessor<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.eventlog.list.output.Data> eventlogRW; - private final DataObjectAcessor<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.network.element.connection.list.output.Data> networkelementConnectionRW; + private final DataObjectAcessorWithId<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.faultcurrent.list.output.Data> eventRWFaultCurrent; + private final DataObjectAcessorWithId<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.faultlog.list.output.Data> eventRWFaultLog; + private final DataObjectAcessorWithId<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.mediator.server.list.output.Data> mediatorserverRW; + private final DataObjectAcessorWithId<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.maintenance.list.output.Data> maintenanceRW; + private final DataObjectAcessorWithId<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.inventory.list.output.Data> equipmentRW; + private final DataObjectAcessorWithId<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.connectionlog.list.output.Data> connnectionlogRW; + private final DataObjectAcessorWithId<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.eventlog.list.output.Data> eventlogRW; + private final DataObjectAcessorWithId<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.network.element.connection.list.output.Data> networkelementConnectionRW; private final DataObjectAcessorPm<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.pmdata._15m.list.output.Data> pm15mRW; private final DataObjectAcessorPm<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.pmdata._24h.list.output.Data> pm24hRW; @@ -100,7 +98,7 @@ public class ElasticSearchDataProvider /*extends BaseStatusProvider /* implement } public ElasticSearchDataProvider(HostInfo[] hosts) throws Exception { - this(hosts, null, null, DEFAULT_TRUSTALLCERTS); + this(hosts, null, null, HtDatabaseClient.TRUSTALL_DEFAULT); } public ElasticSearchDataProvider(HostInfo[] hosts, String authUsername, String authPassword, boolean trustAllCerts) @@ -108,31 +106,32 @@ public class ElasticSearchDataProvider /*extends BaseStatusProvider /* implement super(); LOG.info("Start {}", this.getClass().getName()); + this.dbClient = HtDatabaseClient.getClient(hosts, authUsername, authPassword, trustAllCerts); - this.mediatorserverRW = new DataObjectAcessor<>(dbClient, Entity.MediatorServer, + this.mediatorserverRW = new DataObjectAcessorWithId<>(dbClient, Entity.MediatorServer, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.mediator.server.list.output.Data.class); this.mediatorserverRW.setWriteInterface(MediatorServerEntity.class); - this.maintenanceRW = new DataObjectAcessor<>(dbClient, Entity.Maintenancemode, + this.maintenanceRW = new DataObjectAcessorWithId<>(dbClient, Entity.Maintenancemode, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.maintenance.list.output.Data.class); this.maintenanceRW.setWriteInterface(MaintenanceEntity.class); - this.equipmentRW = new DataObjectAcessor<>(dbClient, Entity.Inventoryequipment, + this.equipmentRW = new DataObjectAcessorWithId<>(dbClient, Entity.Inventoryequipment, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.inventory.list.output.Data.class); - this.eventRWFaultCurrent = new DataObjectAcessor<>(dbClient, Entity.Faultcurrent, + this.eventRWFaultCurrent = new DataObjectAcessorWithId<>(dbClient, Entity.Faultcurrent, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.faultcurrent.list.output.Data.class); - this.eventRWFaultLog = new DataObjectAcessor<>(dbClient, Entity.Faultlog, + this.eventRWFaultLog = new DataObjectAcessorWithId<>(dbClient, Entity.Faultlog, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.faultlog.list.output.Data.class); - this.connnectionlogRW = new DataObjectAcessor<>(dbClient, Entity.Connectionlog, + this.connnectionlogRW = new DataObjectAcessorWithId<>(dbClient, Entity.Connectionlog, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.connectionlog.list.output.Data.class); - this.eventlogRW = new DataObjectAcessor<>(dbClient, Entity.Eventlog, + this.eventlogRW = new DataObjectAcessorWithId<>(dbClient, Entity.Eventlog, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.eventlog.list.output.Data.class); - this.networkelementConnectionRW = new DataObjectAcessor<>(dbClient, Entity.NetworkelementConnection, + this.networkelementConnectionRW = new DataObjectAcessorWithId<>(dbClient, Entity.NetworkelementConnection, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.read.network.element.connection.list.output.Data.class); this.networkelementConnectionRW.setWriteInterface(NetworkElementConnectionEntity.class); diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/HtDatabaseEventsService.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/HtDatabaseEventsService.java index d255cadcd..4efbf6e28 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/HtDatabaseEventsService.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/HtDatabaseEventsService.java @@ -27,6 +27,7 @@ import java.util.Date; import java.util.List; import javax.annotation.Nonnull; + import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; @@ -113,7 +114,7 @@ public class HtDatabaseEventsService implements ArchiveCleanProvider, DataProvid ConnectionlogEntity.class, ConnectionlogBuilder.class); networkelementConnectionDB = new EsDataObjectReaderWriter2<>(client, Entity.NetworkelementConnection, - NetworkElementConnectionEntity.class, NetworkElementConnectionBuilder.class) + NetworkElementConnectionEntity.class, NetworkElementConnectionBuilder.class, true) .setEsIdAttributeName("_id"); pmData15mDB = new EsDataObjectReaderWriter2<>(client, Entity.Historicalperformance15min, PmdataEntity.class, @@ -271,15 +272,64 @@ public class HtDatabaseEventsService implements ArchiveCleanProvider, DataProvid // -- Networkelement + + /** + * join base with parameters of toJoin (only non null values) + * + * @param base base object + * @param toJoin object with new property values + * @return new joined object + */ + @SuppressWarnings("unused") + private NetworkElementConnectionEntity joinNe(NetworkElementConnectionEntity base, + NetworkElementConnectionEntity toJoin) { + if (base == null) { + return toJoin; + } + NetworkElementConnectionBuilder builder = new NetworkElementConnectionBuilder(base); + if (toJoin != null) { + if (toJoin.isIsRequired() != null) { + builder.setIsRequired(toJoin.isIsRequired()); + } + if (toJoin.getCoreModelCapability() != null) { + builder.setCoreModelCapability(toJoin.getCoreModelCapability()); + } + if (toJoin.getDeviceType() != null) { + builder.setDeviceType(toJoin.getDeviceType()); + } + if (toJoin.getHost() != null) { + builder.setHost(toJoin.getHost()); + } + if (toJoin.getNodeDetails() != null) { + builder.setNodeDetails(toJoin.getNodeDetails()); + } + if (toJoin.getPassword() != null) { + builder.setPassword(toJoin.getPassword()); + } + if (toJoin.getPort() != null) { + builder.setPort(toJoin.getPort()); + } + if (toJoin.getStatus() != null) { + builder.setStatus(toJoin.getStatus()); + } + if (toJoin.getUsername() != null) { + builder.setUsername(toJoin.getUsername()); + } + } + return builder.build(); + } + /** * * @param networkElementConnectionEntitiy to wirte to DB * @param nodeId Id for this DB element */ @Override - public void updateNetworkConnectionDeviceType(NetworkElementConnectionEntity networkElementConnectionEntitiy, + public boolean updateNetworkConnectionDeviceType(NetworkElementConnectionEntity networkElementConnectionEntitiy, String nodeId) { - this.networkelementConnectionDB.update(networkElementConnectionEntitiy, nodeId); + return this.networkelementConnectionDB.update(networkElementConnectionEntitiy, nodeId) != null; + // NetworkElementConnectionEntity e = this.networkelementConnectionDB.read(nodeId); + // this.networkelementConnectionDB.write(this.joinNe(e, networkElementConnectionEntitiy), nodeId); } /** @@ -289,10 +339,14 @@ public class HtDatabaseEventsService implements ArchiveCleanProvider, DataProvid * @param nodeId of device (mountpoint name) */ @Override - public void updateNetworkConnection22(NetworkElementConnectionEntity networkElementConnectionEntitiy, + public boolean updateNetworkConnection22(NetworkElementConnectionEntity networkElementConnectionEntitiy, String nodeId) { - this.networkelementConnectionDB.updateOrCreate(networkElementConnectionEntitiy, nodeId, - Arrays.asList("is-required", "username", "password")); + LOG.info("update networkelement-connection for {} with data {}", nodeId, networkElementConnectionEntitiy); + return this.networkelementConnectionDB.updateOrCreate(networkElementConnectionEntitiy, nodeId, + Arrays.asList("is-required", "username", "password")) != null; + // NetworkElementConnectionEntity e = this.networkelementConnectionDB.read(nodeId); + // this.networkelementConnectionDB.write(this.joinNe(e, networkElementConnectionEntitiy), nodeId); + } /* please do not remove */ diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/HtDatabaseMaintenanceService.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/HtDatabaseMaintenanceService.java index a675f6876..3e9a93902 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/HtDatabaseMaintenanceService.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/HtDatabaseMaintenanceService.java @@ -46,15 +46,15 @@ public class HtDatabaseMaintenanceService implements HtDatabaseMaintenance { private final EsDataObjectReaderWriter2<MaintenanceEntity> maintenanceRW; private final EsDataObjectReaderWriter2<NetworkElementConnectionEntity> requiredNeRW; - HtDatabaseMaintenanceService(@NonNull HtDatabaseClient client) throws ClassNotFoundException { + public HtDatabaseMaintenanceService(@NonNull HtDatabaseClient client) throws ClassNotFoundException { HtAssert.nonnull(client); // Create control structure maintenanceRW = new EsDataObjectReaderWriter2<>(client, Entity.Maintenancemode, MaintenanceEntity.class, - MaintenanceBuilder.class).setEsIdAttributeName("_id"); + MaintenanceBuilder.class, true).setEsIdAttributeName("_id"); requiredNeRW = new EsDataObjectReaderWriter2<>(client, Entity.NetworkelementConnection, - NetworkElementConnectionEntity.class, NetworkElementConnectionBuilder.class) + NetworkElementConnectionEntity.class, NetworkElementConnectionBuilder.class, true) .setEsIdAttributeName("_id"); } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/MediatorServerDataProvider.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/MediatorServerDataProvider.java index 258104db4..c229006ff 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/MediatorServerDataProvider.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/MediatorServerDataProvider.java @@ -40,7 +40,7 @@ public class MediatorServerDataProvider implements AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(MediatorServerDataProvider.class); private final HtDatabaseClient dbClient; - private final DataObjectAcessor<Data> mediatorserverRW; + private final DataObjectAcessorWithId<Data> mediatorserverRW; private final int REFRESH_INTERVAL = 60; private final Map<String, Data> entries; private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); @@ -55,7 +55,7 @@ public class MediatorServerDataProvider implements AutoCloseable { LOG.info("Start {}", this.getClass().getName()); this.entries = new HashMap<>(); this.dbClient = HtDatabaseClient.getClient(hosts, authUsername, authPassword); - this.mediatorserverRW = new DataObjectAcessor<>(dbClient, Entity.MediatorServer, Data.class); + this.mediatorserverRW = new DataObjectAcessorWithId<>(dbClient, Entity.MediatorServer, Data.class); this.scheduler.scheduleAtFixedRate(onTick, this.REFRESH_INTERVAL, this.REFRESH_INTERVAL, TimeUnit.SECONDS); } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryByFilter.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryByFilter.java index b6a502071..4e7bee9d0 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryByFilter.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryByFilter.java @@ -21,6 +21,8 @@ */ package org.onap.ccsdk.features.sdnr.wt.dataprovider.data; +import java.math.BigInteger; +import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; @@ -33,11 +35,13 @@ 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.common.database.requests.SearchRequest; 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.rev190801.EntityInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SortOrder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.entity.input.Filter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.entity.input.Pagination; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.entity.input.Sortorder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,48 +51,130 @@ public class QueryByFilter { private static final Logger LOG = LoggerFactory.getLogger(DataObjectAcessorPm.class); private static final List<String> timestampValueNames = Arrays.asList("timestamp", "start", "end"); - private QueryByFilter() { - //Hide + 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 QueryByFilter(EntityInput input) { + page = -1; + pageSize = -1; + if (input != null) { + @Nullable + Pagination pagination = input.getPagination(); + if (pagination != null) { + BigInteger pageOrNull = pagination.getPage(); + if (pageOrNull != null) { + page = pageOrNull.longValue(); + } + Long pageSizeOrNull = pagination.getSize(); + if (pageSizeOrNull != null) { + pageSize = pageSizeOrNull; + } + } + } + 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 = input.getFilter(); + if (filterList == null) + filterList = emptyFilterList; + sortOrder = input.getSortorder(); + if (sortOrder == null) + sortOrder = emptySortOrderList; + + } + + public QueryBuilder getQueryBuilderByFilter() { + return getQueryBuilderByFilter(""); } - static long getPage(EntityInput input) { - return getPage(input, 1); + public QueryBuilder getQueryBuilderByFilter(String prefix) { + QueryBuilder queryBuilder = fromFilter(filterList, prefix).from(fromPage).size(pageSize); + setSortOrder(queryBuilder, sortOrder, prefix); + return queryBuilder; } - @SuppressWarnings("null") - private static long getPage(EntityInput input, long defaultValue) { - return input.getPagination() != null ? input.getPagination().getPage().longValue() : defaultValue; + public SearchRequest getSearchRequestByFilter(String nodeKey, String uuidKey, String index, String dataType) { + Filter nodeFilter = getFilter(filterList, nodeKey); + if (nodeFilter != null) { + SearchRequest request = new SearchRequest(index, dataType); + request.setQuery( + QueryBuilders.matchQuery(nodeKey, nodeFilter.getFiltervalue()).aggregations(uuidKey).size(0)); + return request; + } else { + String msg = "no nodename in filter found "; + LOG.debug(msg); + throw new IllegalArgumentException(msg); + } } - static long getPageSize(EntityInput input) { - return getPageSize(input, 1); + public SearchRequest getSearchRequestBySortOrder(String nodeKey, String uuidKey, String index, String dataType) { + Sortorder soNode = getSortOrder(sortOrder, nodeKey); + SearchRequest request = new SearchRequest(index, dataType); + QueryBuilder query = null; + if (soNode != null) { + query = QueryBuilders.matchAllQuery().aggregations(nodeKey, convert(soNode.getSortorder())).size(0); + } else { + query = QueryBuilders.matchAllQuery().aggregations(nodeKey).size(0); + } + request.setQuery(query); + return request; } - @SuppressWarnings("null") - private static long getPageSize(EntityInput input, long defaultValue) { - return input.getPagination() != null ? input.getPagination().getSize().longValue() : defaultValue; + public long getPage() { + return page; } + public long getPageSize() { + return pageSize; + } + + public long getPageStartIndex() { + return fromPage; + } - public static QueryBuilder setSortOrder(QueryBuilder query, @Nullable List<Sortorder> sortorder) { - return setSortOrder(query, sortorder, ""); + @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((prefix != null ? prefix : "") + so.getProperty(), - so.getSortorder() == SortOrder.Ascending - ? org.onap.ccsdk.features.sdnr.wt.common.database.queries.SortOrder.ASCENDING - : org.onap.ccsdk.features.sdnr.wt.common.database.queries.SortOrder.DESCENDING); + 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; + }; - public static Sortorder getSortOrder(@Nullable List<Sortorder> list, String prop) { + private static Sortorder getSortOrder(@Nullable List<Sortorder> list, String prop) { if (list == null) { return null; } @@ -100,7 +186,7 @@ public class QueryByFilter { return null; } - public static Filter getFilter(@Nullable List<Filter> list, String prop) { + private static Filter getFilter(@Nullable List<Filter> list, String prop) { if (list == null) { return null; } @@ -112,10 +198,6 @@ public class QueryByFilter { return null; } - public static QueryBuilder fromFilter(@Nullable List<Filter> filters) { - return fromFilter(filters, ""); - } - private static String fillTimeStamp(String value) { int idx = value.lastIndexOf("*"); final String REPLACE = "0000-00-00T00:00:00.0Z"; @@ -176,7 +258,7 @@ public class QueryByFilter { 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*) + case 6: // switch 10 months (2000-0* or 2000-1*) tmpvalue = c.get(Calendar.MONTH); if (tmpvalue < 9) { c.set(Calendar.MONTH, 9); @@ -187,7 +269,7 @@ public class QueryByFilter { upperEnd = converter.getTimeStampAsNetconfString(c.getTime()); break; - case 7: //switch one month (2018-01* or 2018-01-*) + case 7: // switch one month (2018-01* or 2018-01-*) case 8: c.add(Calendar.MONTH, 1); upperEnd = converter.getTimeStampAsNetconfString(c.getTime()); @@ -287,14 +369,14 @@ public class QueryByFilter { } else if (DbFilter.isComparisonValid(v)) { - RangeQueryBuilder q = DbFilter.getRangeQuery((prefix != null ? prefix : "") + p, v); + RangeQueryBuilder q = DbFilter.getRangeQuery(handlePrefix(prefix, p), v); if (q != null) { return q; } else { - return QueryBuilders.matchQuery((prefix != null ? prefix : "") + p, v); + return QueryBuilders.matchQuery(handlePrefix(prefix, p), v); } } else { - return QueryBuilders.matchQuery((prefix != null ? prefix : "") + p, v); + return QueryBuilders.matchQuery(handlePrefix(prefix, p), v); } } else { BoolQueryBuilder query = new BoolQueryBuilder(); @@ -313,22 +395,20 @@ public class QueryByFilter { if (tmpQuery != null) { query.must(tmpQuery); } else { - query.must(QueryBuilders.regex((prefix != null ? prefix : "") + p, - DbFilter.createDatabaseRegex(v))); + query.must(QueryBuilders.regex(handlePrefix(prefix, p), DbFilter.createDatabaseRegex(v))); } } else { - query.must(QueryBuilders.regex((prefix != null ? prefix : "") + p, - DbFilter.createDatabaseRegex(v))); + query.must(QueryBuilders.regex(handlePrefix(prefix, p), DbFilter.createDatabaseRegex(v))); } } else if (DbFilter.isComparisonValid(v)) { - RangeQueryBuilder q = DbFilter.getRangeQuery((prefix != null ? prefix : "") + p, v); + RangeQueryBuilder q = DbFilter.getRangeQuery(handlePrefix(prefix, p), v); if (q != null) { query.must(q); } else { - query.must(QueryBuilders.matchQuery((prefix != null ? prefix : "") + p, v)); + query.must(QueryBuilders.matchQuery(handlePrefix(prefix, p), v)); } } else { - query.must(QueryBuilders.matchQuery((prefix != null ? prefix : "") + p, v)); + query.must(QueryBuilders.matchQuery(handlePrefix(prefix, p), v)); } } LOG.trace("Query result. {}", query.toJSON()); @@ -336,4 +416,8 @@ public class QueryByFilter { } } + private static String handlePrefix(String prefix, String p) { + return (prefix != null ? prefix : "") + p; + } + } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryByFilterStatic.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryByFilterStatic.java new file mode 100644 index 000000000..4abe65856 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryByFilterStatic.java @@ -0,0 +1,336 @@ +/* + * ============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.data; + +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.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.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EntityInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SortOrder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.entity.input.Filter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.entity.input.Sortorder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class QueryByFilterStatic { + + private static final Logger LOG = LoggerFactory.getLogger(DataObjectAcessorPm.class); + private static final List<String> timestampValueNames = Arrays.asList("timestamp", "start", "end"); + + private QueryByFilterStatic() { + //Hide + } + + static long getPage(EntityInput input) { + return getPage(input, 1); + } + + private static long getPage(EntityInput input, long defaultValue) { + return input.getPagination() != null ? input.getPagination().getPage().longValue() : defaultValue; + } + + static long getPageSize(EntityInput input) { + return getPageSize(input, 1); + } + + private static long getPageSize(EntityInput input, long defaultValue) { + return input.getPagination() != null ? input.getPagination().getSize().longValue() : defaultValue; + } + + + public static QueryBuilder setSortOrder(QueryBuilder query, @Nullable List<Sortorder> sortorder) { + return setSortOrder(query, sortorder, ""); + } + + private static QueryBuilder setSortOrder(QueryBuilder query, @Nullable List<Sortorder> sortorder, String prefix) { + if (sortorder != null && sortorder.size() > 0) { + for (Sortorder so : sortorder) { + query.sort((prefix != null ? prefix : "") + so.getProperty(), + so.getSortorder() == SortOrder.Ascending + ? org.onap.ccsdk.features.sdnr.wt.common.database.queries.SortOrder.ASCENDING + : org.onap.ccsdk.features.sdnr.wt.common.database.queries.SortOrder.DESCENDING); + } + } + return query; + + } + + + public static Sortorder getSortOrder(@Nullable List<Sortorder> list, String prop) { + if (list == null) { + return null; + } + for (Sortorder o : list) { + if (prop.equals(o.getProperty())) { + return o; + } + } + return null; + } + + public static Filter getFilter(@Nullable List<Filter> list, String prop) { + if (list == null) { + return null; + } + for (Filter f : list) { + if (prop.equals(f.getProperty())) { + return f; + } + } + return null; + } + + public static QueryBuilder fromFilter(@Nullable List<Filter> filters) { + return fromFilter(filters, ""); + } + + private static String fillTimeStamp(String value) { + int idx = value.lastIndexOf("*"); + final String REPLACE = "0000-00-00T00:00:00.0Z"; + String s = value.substring(0, idx) + REPLACE.substring(idx); + if (Integer.parseInt(s.substring(5, 7)) == 0) { + s = s.substring(0, 5) + "01-" + s.substring(8); + } + if (Integer.parseInt(s.substring(8, 10)) == 0) { + s = s.substring(0, 8) + "01" + s.substring(10); + } + + return s; + } + + /** + * convert timestamp with ending placeholder in filter to elasticsearch filter e.g. 2017* => gte: + * 2017-01-01T00:00:00Z, lt:2018-01-01T00:00:00Z + * + * 201* => 2010-01... 2020 .. 2018-* => 2018-01... <=> 2019-01 + * + */ + private static @Nullable QueryBuilder fromTimestampSearchFilter(String property, String value) { + if (!value.endsWith("*")) { + return null; + } + int idx = value.lastIndexOf("*"); + String lowerEnd = fillTimeStamp(value); + String upperEnd = null; + NetconfTimeStamp converter = 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((prefix != null ? prefix : "") + p, v); + if (q != null) { + return q; + } else { + return QueryBuilders.matchQuery((prefix != null ? prefix : "") + p, v); + } + } else { + return QueryBuilders.matchQuery((prefix != null ? prefix : "") + p, v); + } + } else { + BoolQueryBuilder query = new BoolQueryBuilder(); + QueryBuilder tmpQuery; + for (Filter fi : filters) { + String p = fi.getProperty(); + String v = fi.getFiltervalue(); + if ("id".equals(p)) { + p = "_id"; + } else { + // v=v.toLowerCase(); + } + if (DbFilter.hasSearchParams(v)) { + if (p != null && timestampValueNames.contains(p.toLowerCase())) { + tmpQuery = fromTimestampSearchFilter(p, v); + if (tmpQuery != null) { + query.must(tmpQuery); + } else { + query.must(QueryBuilders.regex((prefix != null ? prefix : "") + p, + DbFilter.createDatabaseRegex(v))); + } + } else { + query.must(QueryBuilders.regex((prefix != null ? prefix : "") + p, + DbFilter.createDatabaseRegex(v))); + } + } else if (DbFilter.isComparisonValid(v)) { + RangeQueryBuilder q = DbFilter.getRangeQuery((prefix != null ? prefix : "") + p, v); + if (q != null) { + query.must(q); + } else { + query.must(QueryBuilders.matchQuery((prefix != null ? prefix : "") + p, v)); + } + } else { + query.must(QueryBuilders.matchQuery((prefix != null ? prefix : "") + p, v)); + } + } + LOG.trace("Query result. {}", query.toJSON()); + return query; + } + } + +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryResult.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryResult.java index 61e524192..7570523cd 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryResult.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/QueryResult.java @@ -42,11 +42,22 @@ public class QueryResult<T> { pagination = x.build(); } + public QueryResult(QueryByFilter queryByFilter, SearchResult<T> result) { + this.result = result; + + PaginationBuilder x = new PaginationBuilder(); + x.setPage(BigInteger.valueOf(queryByFilter.getPage())); + x.setSize(queryByFilter.getPageSize()); + x.setTotal(BigInteger.valueOf(result.getTotal())); + pagination = x.build(); + } + + public SearchResult<T> getResult() { return result; } - PaginationOutputG getPagination() { + public PaginationOutputG getPagination() { return pagination; } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/EsDataObjectReaderWriter.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/EsDataObjectReaderWriter.java deleted file mode 100644 index c0518c664..000000000 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/EsDataObjectReaderWriter.java +++ /dev/null @@ -1,357 +0,0 @@ -/* - * ============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; - -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.List; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import org.onap.ccsdk.features.sdnr.wt.common.database.DatabaseClient; -import org.onap.ccsdk.features.sdnr.wt.common.database.SearchHit; -import org.onap.ccsdk.features.sdnr.wt.common.database.SearchResult; -import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilder; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.YangToolsMapper; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Entity; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.core.JsonProcessingException; - -/** - * Class to rw yang-tool generated objects into elasticsearch database. For "ES _id" exchange the esIdAddAtributteName - * is used. This attribute mast be of type String and contains for read and write operations the object id. The function - * can be used without id handling. If id handling is required the parameter needs to be specified by class definition - * in yang and setting the name by using setAttributeName() - * - * @param <T> Yang tools generated class object. - */ -public class EsDataObjectReaderWriter<T extends DataObject> { - - private final Logger LOG = LoggerFactory.getLogger(EsDataObjectReaderWriter.class); - - /** Typename for elastic search data schema **/ - private String dataTypeName; - - /** Elasticsearch Database client to be used **/ - private DatabaseClient db; - - /** Mapper with configuration to use opendaylight yang-tools builder pattern for object creation **/ - private YangToolsMapper yangtoolsMapper; - - /** Class of T as attribute to allow JSON to Class object mapping **/ - private Class<T> clazz; - - /** Field is used to write id. If null no id handling **/ - private @Nullable Field field; - - /** Attribute that is used as id field for the database object **/ - private @Nullable String esIdAddAtributteName; - - /** Interface to be used for write operations. Rule for write: T extends S and **/ - private Class<? extends DataObject> writeInterfaceClazz; // == "S" - - /** - * Elasticsearch database read and write for specific class, defined by opendaylight yang-tools. - * - * @param db Database access client - * @param dataTypeName typename in database schema - * @param clazz class of type to be handled - * @throws ClassNotFoundException - */ - public EsDataObjectReaderWriter(DatabaseClient db, Entity dataTypeName, Class<T> clazz) - throws ClassNotFoundException { - this(db, dataTypeName.getName(), clazz); - } - - public EsDataObjectReaderWriter(DatabaseClient db, String dataTypeName, Class<T> clazz) - throws ClassNotFoundException { - LOG.info("Create {} for datatype {} class {}", this.getClass().getName(), dataTypeName, clazz.getName()); - - this.esIdAddAtributteName = null; - this.field = null; - this.writeInterfaceClazz = clazz; - this.db = db; - this.dataTypeName = dataTypeName; - this.yangtoolsMapper = new YangToolsMapper(); - //this.yangtoolsMapper.assertBuilderClass(clazz); - this.clazz = clazz; - // - // if (! db.isExistsIndex(dataTypeName)) { - // throw new IllegalArgumentException("Index "+dataTypeName+" not existing."); - // } - } - - public String getDataTypeName() { - return dataTypeName; - } - - public Class<T> getClazz() { - return clazz; - } - - /** - * Simlar to {@link #setEsIdAttributeName()}, but adapts the parameter to yangtools attribute naming schema - * - * @param esIdAttributeName is converted to UnderscoreCamelCase - * @return this for further operations. - */ - public EsDataObjectReaderWriter<T> setEsIdAttributeNameCamelized(String esIdAttributeName) { - return setEsIdAttributeName(YangToolsMapper.toCamelCaseAttributeName(esIdAttributeName)); - } - - /** - * Attribute name of class that is containing the object id - * - * @param esIdAttributeName of the implementation class for the yangtools interface. Expected attribute name format - * is CamelCase with leading underline. @ - * @return this for further operations. - * @throws SecurityException if no access or IllegalArgumentException if wrong type or no attribute with this name. - */ - public EsDataObjectReaderWriter<T> setEsIdAttributeName(String esIdAttributeName) { - LOG.debug("Set attribute '{}'", esIdAttributeName); - this.esIdAddAtributteName = null; // Reset status - this.field = null; - - Field attributeField; - try { - Builder<T> builder = yangtoolsMapper.getBuilder(clazz); - T object = builder.build(); - attributeField = object.getClass().getDeclaredField(esIdAttributeName); - if (attributeField.getType().equals(String.class)) { - attributeField.setAccessible(true); - this.esIdAddAtributteName = esIdAttributeName; //Set new status if everything OK - this.field = attributeField; - } else { - String msg = "Wrong field type " + attributeField.getType().getName() + " of " + esIdAttributeName; - LOG.debug(msg); - throw new IllegalArgumentException(msg); - } - } catch (NoSuchFieldException e) { - // Convert to run-time exception - String msg = "NoSuchFieldException for '" + esIdAttributeName + "' in class " + clazz.getName(); - LOG.debug(msg); - throw new IllegalArgumentException(msg); - } catch (SecurityException e) { - LOG.debug("Access problem " + esIdAttributeName, e); - throw e; - } - return this; - } - - /** - * Specify subclass of T for write operations. - * - * @param writeInterfaceClazz - */ - public EsDataObjectReaderWriter<T> setWriteInterface(@Nonnull 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; - } - - /** - * Write child object to database with specific id - * - * @param object - * @param @Nullable esId use the id or if null generate unique id - * @return String with id or null - */ - public @Nullable <S extends DataObject> String write(S object, @Nullable String esId) { - if (writeInterfaceClazz.isInstance(object)) { - try { - String json = yangtoolsMapper.writeValueAsString(object); - return db.doWriteRaw(dataTypeName, esId, json); - } catch (JsonProcessingException e) { - LOG.error("Write problem: ", e); - } - } else { - LOG.error("Type {} does not provide interface {}", object != null ? object.getClass().getName() : "null", - writeInterfaceClazz.getName()); - } - return null; - } - - /** - * Update partial child object to database with match/term query - * - * @param object - * @param esId - * @return String with esId or null - */ - public @Nullable <S extends DataObject> boolean update(S object, QueryBuilder query) { - if (writeInterfaceClazz.isInstance(object)) { - try { - String json = yangtoolsMapper.writeValueAsString(object); - return db.doUpdate(this.dataTypeName, json, query); - } catch (JsonProcessingException e) { - LOG.error("Update problem: ", e); - } - } else { - LOG.error("Type {} does not provide interface {}", object != null ? object.getClass().getName() : "null", - writeInterfaceClazz.getName()); - } - return false; - } - - /** - * Write/ update partial child object to database with specific id Write if not exists, else update - * - * @param object - * @param esId - * @return String with esId or null - */ - public @Nullable <S extends DataObject> String update(S object, String esId) { - return this.update(object, esId, null); - } - - public @Nullable <S extends DataObject> String update(S object, String esId, List<String> onylForInsert) { - if (writeInterfaceClazz.isInstance(object)) { - try { - String json = yangtoolsMapper.writeValueAsString(object); - return db.doUpdateOrCreate(dataTypeName, esId, json, onylForInsert); - } catch (JsonProcessingException e) { - LOG.error("Update problem: ", e); - } - } else { - LOG.error("Type {} does not provide interface {}", object != null ? object.getClass().getName() : "null", - writeInterfaceClazz.getName()); - } - return null; - } - - /** - * Read object from database, by using the id field - * - * @param object - * @return - */ - public @Nullable T read(String esId) { - @Nullable - T res = (T) null; - if (esId != null) { - String json = db.doReadJsonData(dataTypeName, esId); - try { - res = yangtoolsMapper.readValue(json.getBytes(), clazz); - } catch (IOException e) { - LOG.error("Problem: ", e); - } - } - return res; - } - - /** - * Remove object - * - * @param esId to identify the object. - * @return success - */ - public boolean remove(String esId) { - return db.doRemove(this.dataTypeName, esId); - } - - public int remove(QueryBuilder query) { - return this.db.doRemove(this.dataTypeName, query); - } - - /** - * Get all elements of related type - * - * @return all Elements - */ - public SearchResult<T> doReadAll() { - return doReadAll(null); - } - - public SearchResult<T> doReadAll(QueryBuilder query) { - return this.doReadAll(query, false); - } - - /** - * Read all existing objects of a type - * - * @param query for the elements - * @return the list of all objects - */ - - public SearchResult<T> doReadAll(QueryBuilder query, boolean ignoreException) { - - SearchResult<T> res = new SearchResult<T>(); - SearchResult<SearchHit> result; - List<SearchHit> hits; - if (query != null) { - LOG.debug("read data in {} with query {}", dataTypeName, query.toJSON()); - result = db.doReadByQueryJsonData(dataTypeName, query, ignoreException); - } else { - result = db.doReadAllJsonData(dataTypeName, ignoreException); - } - hits = result.getHits(); - LOG.debug("Read: {} elements: {} Failures: {}", dataTypeName, hits.size(), - yangtoolsMapper.getMappingFailures()); - - T object; - for (SearchHit hit : hits) { - object = getT(hit.getSourceAsString()); - LOG.debug("Mapp Object: {}\nSource: '{}'\nResult: '{}'\n Failures: {}", hit.getId(), - hit.getSourceAsString(), object, yangtoolsMapper.getMappingFailures()); - if (object != null) { - setEsId(object, hit.getId()); - res.add(object); - } else { - LOG.warn("Mapp result null Object: {}\n Source: '{}'\n : '", hit.getId(), hit.getSourceAsString()); - } - } - res.setTotal(result.getTotal()); - return res; - } - - /* --------------------------------------------- - * Private functions - */ - - private void setEsId(T object, String esId) { - if (field != null) { - try { - field.set(object, esId); - } catch (IllegalArgumentException | IllegalAccessException e) { - LOG.debug("Field set problem.", e); - } - } - } - - private @Nullable T getT(String jsonString) { - try { - return yangtoolsMapper.readValue(jsonString, clazz); - } catch (IOException e) { - LOG.info("Mapping problem", e); - return (T) null; - } - } - -} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/EsDataObjectReaderWriter2.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/EsDataObjectReaderWriter2.java index e0f6e4aea..658826986 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/EsDataObjectReaderWriter2.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/EsDataObjectReaderWriter2.java @@ -21,13 +21,12 @@ */ package org.onap.ccsdk.features.sdnr.wt.dataprovider.database; +import com.fasterxml.jackson.core.JsonProcessingException; import java.io.IOException; import java.lang.reflect.Field; import java.util.List; - import javax.annotation.Nonnull; import javax.annotation.Nullable; - import org.eclipse.jdt.annotation.NonNull; import org.onap.ccsdk.features.sdnr.wt.common.database.DatabaseClient; import org.onap.ccsdk.features.sdnr.wt.common.database.SearchHit; @@ -41,8 +40,6 @@ import org.opendaylight.yangtools.yang.binding.DataObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.fasterxml.jackson.core.JsonProcessingException; - /** * Class to rw yang-tool generated objects into elasticsearch database. For "ES _id" exchange the esIdAddAtributteName * is used. This attribute mast be of type String and contains for read and write operations the object id. The function @@ -78,28 +75,23 @@ public class EsDataObjectReaderWriter2<T extends DataObject> { /** Interface to be used for write operations. Rule for write: T extends S and **/ private Class<? extends DataObject> writeInterfaceClazz; // == "S" + /** Flag true to sync this attribute during write always, what is slow and false do not sync */ + private final boolean syncAfterWrite; /** * Elasticsearch database read and write for specific class, defined by opendaylight yang-tools. * + * @param <X> + * @param <B> * @param db Database access client * @param dataTypeName typename in database schema * @param clazz class of type to be handled + * @param builderClazz class to build related object if builder pattern should be used. + * @param syncAfterWrite * @throws ClassNotFoundException */ public <X extends T, @NonNull B extends Builder<X>> EsDataObjectReaderWriter2(DatabaseClient db, - Entity dataTypeName, @Nonnull Class<T> clazz, @Nullable Class<B> builderClazz) - throws ClassNotFoundException { - this(db, dataTypeName.getName(), clazz, builderClazz); - } - - public <X extends T, @NonNull B extends Builder<X>> EsDataObjectReaderWriter2(DatabaseClient db, - Entity dataTypeName, @Nonnull Class<T> clazz) throws ClassNotFoundException { - this(db, dataTypeName.getName(), clazz, null); - } - - public <X extends T, @NonNull B extends Builder<X>> EsDataObjectReaderWriter2(DatabaseClient db, - String dataTypeName, @Nonnull Class<T> clazz, @Nullable Class<B> builderClazz) + String dataTypeName, @Nonnull Class<T> clazz, @Nullable Class<B> builderClazz, boolean syncAfterWrite) throws ClassNotFoundException { LOG.info("Create {} for datatype {} class {}", this.getClass().getName(), dataTypeName, clazz.getName()); @@ -110,11 +102,43 @@ public class EsDataObjectReaderWriter2<T extends DataObject> { this.dataTypeName = dataTypeName; this.yangtoolsMapper = new YangToolsMapper2<>(clazz, builderClazz); this.clazz = clazz; + this.syncAfterWrite = syncAfterWrite; + } + + public <X extends T, @NonNull B extends Builder<X>> EsDataObjectReaderWriter2(DatabaseClient db, + Entity dataTypeName, @Nonnull Class<T> clazz, @Nullable Class<B> builderClazz) + throws ClassNotFoundException { + this(db, dataTypeName.getName(), clazz, builderClazz, false); + } + + public <X extends T, @NonNull B extends Builder<X>> EsDataObjectReaderWriter2(DatabaseClient db, + Entity dataTypeName, @Nonnull Class<T> clazz, @Nullable Class<B> builderClazz, boolean syncAfterWrite) + throws ClassNotFoundException { + this(db, dataTypeName.getName(), clazz, builderClazz, syncAfterWrite); + } + + public EsDataObjectReaderWriter2(DatabaseClient db, Entity dataTypeName, @Nonnull Class<T> clazz, + boolean syncAfterWrite) throws ClassNotFoundException { + this(db, dataTypeName.getName(), clazz, null, syncAfterWrite); + } + + public EsDataObjectReaderWriter2(DatabaseClient db, Entity dataTypeName, Class<T> clazz) + throws ClassNotFoundException { + this(db, dataTypeName.getName(), clazz, null, false); + } + + /** + * Get Datatype name + * + * @return string with dataTypeName + */ + public String getDataTypeName() { + return dataTypeName; } /** * Simlar to {@link #setEsIdAttributeName()}, but adapts the parameter to yangtools attribute naming schema - * + * * @param esIdAttributeName is converted to UnderscoreCamelCase * @return this for further operations. */ @@ -124,7 +148,7 @@ public class EsDataObjectReaderWriter2<T extends DataObject> { /** * Attribute name of class that is containing the object id - * + * * @param esIdAttributeName of the implementation class for the yangtools interface. Expected attribute name format * is CamelCase with leading underline. @ * @return this for further operations. @@ -137,7 +161,7 @@ public class EsDataObjectReaderWriter2<T extends DataObject> { Field attributeField; try { - Builder<T> builder = yangtoolsMapper.getBuilder(clazz); + Builder<? extends T> builder = yangtoolsMapper.getBuilder(clazz); if (builder == null) { String msg = "No builder for " + clazz; LOG.debug(msg); @@ -169,7 +193,7 @@ public class EsDataObjectReaderWriter2<T extends DataObject> { /** * Specify subclass of T for write operations. - * + * * @param writeInterfaceClazz */ public EsDataObjectReaderWriter2<T> setWriteInterface(@Nonnull Class<? extends DataObject> writeInterfaceClazz) { @@ -194,7 +218,7 @@ public class EsDataObjectReaderWriter2<T extends DataObject> { /** * Write child object to database with specific id - * + * * @param object to be written * @param esId use the id or if null generate unique id * @return String with id or null @@ -203,7 +227,7 @@ public class EsDataObjectReaderWriter2<T extends DataObject> { if (object != null && writeInterfaceClazz.isInstance(object)) { try { String json = yangtoolsMapper.writeValueAsString(object); - return db.doWriteRaw(dataTypeName, esId, json); + return db.doWriteRaw(dataTypeName, esId, json, this.syncAfterWrite); } catch (JsonProcessingException e) { LOG.error("Write problem: ", e); } @@ -216,7 +240,7 @@ public class EsDataObjectReaderWriter2<T extends DataObject> { /** * Update partial child object to database with match/term query - * + * * @param <S> of object * @param object to write * @param query for write of specific attributes @@ -239,7 +263,7 @@ public class EsDataObjectReaderWriter2<T extends DataObject> { /** * Write/ update partial child object to database with specific id Write if not exists, else update - * + * * @param object * @param esId * @return String with esId or null @@ -268,7 +292,7 @@ public class EsDataObjectReaderWriter2<T extends DataObject> { /** * Read object from database, by using the id field - * + * * @param object * @return */ @@ -292,7 +316,7 @@ public class EsDataObjectReaderWriter2<T extends DataObject> { /** * Remove object - * + * * @param esId to identify the object. * @return success */ @@ -306,7 +330,7 @@ public class EsDataObjectReaderWriter2<T extends DataObject> { /** * Get all elements of related type - * + * * @return all Elements */ public SearchResult<T> doReadAll() { @@ -319,46 +343,39 @@ public class EsDataObjectReaderWriter2<T extends DataObject> { /** * Read all existing objects of a type - * + * * @param query for the elements * @return the list of all objects */ public SearchResult<T> doReadAll(QueryBuilder query, boolean ignoreException) { - SearchResult<T> res = new SearchResult<>(); - int idx = 0; //Idx for getAll - int iterateLength = 100; //Step width for iterate + SearchResult<T> res = new SearchResult<T>(); SearchResult<SearchHit> result; List<SearchHit> hits; - do { - if (query != null) { - LOG.debug("read data in {} with query {}", dataTypeName, query.toJSON()); - result = db.doReadByQueryJsonData(dataTypeName, query, ignoreException); + if (query != null) { + LOG.debug("read data in {} with query {}", dataTypeName, query.toJSON()); + result = db.doReadByQueryJsonData(dataTypeName, query, ignoreException); + } else { + result = db.doReadAllJsonData(dataTypeName, ignoreException); + } + hits = result.getHits(); + LOG.debug("Read: {} elements: {} Failures: {}", dataTypeName, hits.size(), + yangtoolsMapper.getMappingFailures()); + + T object; + for (SearchHit hit : hits) { + object = getT(hit.getSourceAsString()); + LOG.debug("Mapp Object: {}\nSource: '{}'\nResult: '{}'\n Failures: {}", hit.getId(), + hit.getSourceAsString(), object, yangtoolsMapper.getMappingFailures()); + if (object != null) { + setEsId(object, hit.getId()); + res.add(object); } else { - result = db.doReadAllJsonData(dataTypeName, ignoreException); - } - hits = result.getHits(); - LOG.debug("Read: {} elements: {} Failures: {}", dataTypeName, hits.size(), - yangtoolsMapper.getMappingFailures()); - - T object; - idx += result.getHits().size(); - for (SearchHit hit : hits) { - object = getT(hit.getSourceAsString()); - LOG.debug("Mapp Object: {}\nSource: '{}'\nResult: '{}'\n Failures: {}", hit.getId(), - hit.getSourceAsString(), object, yangtoolsMapper.getMappingFailures()); - if (object != null) { - setEsId(object, hit.getId()); - res.add(object); - } else { - LOG.warn("Mapp result null Object: {}\n Source: '{}'\n : '", hit.getId(), hit.getSourceAsString()); - } + LOG.warn("Mapp result null Object: {}\n Source: '{}'\n : '", hit.getId(), hit.getSourceAsString()); } - - } while (hits.size() == iterateLength); // Do it until end indicated, because less hits than iterateLength - // allows. + } res.setTotal(result.getTotal()); return res; } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/AboutHttpServlet.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/AboutHttpServlet.java index 120684298..fdac1c10a 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/AboutHttpServlet.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/AboutHttpServlet.java @@ -23,7 +23,9 @@ package org.onap.ccsdk.features.sdnr.wt.dataprovider.http; import java.io.IOException; import java.net.URL; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.jar.Attributes; @@ -35,11 +37,14 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +//import org.apache.karaf.bundle.core.BundleInfo; +//import org.apache.karaf.bundle.core.BundleService; import org.onap.ccsdk.features.sdnr.wt.common.Resources; import org.onap.ccsdk.features.sdnr.wt.common.file.PomFile; import org.onap.ccsdk.features.sdnr.wt.common.file.PomPropertiesFile; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.ODLVersionLUT; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.SystemInfo; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,6 +74,7 @@ public class AboutHttpServlet extends HttpServlet { private static final String PLACEHOLDER_MDSAL_VERSION = "{mdsal-version}"; private static final String PLACEHOLDER_YANGTOOLS_VERSION = "{yangtools-version}"; private static final String PLACEHOLDER_KARAF_INFO = "{karaf-info}"; + private static final String PLACEHOLDER_DEVICEMANAGER_TABLE = "{devicemanagers}"; private static final String README_FILE = "README.md"; private final String groupId = "org.onap.ccsdk.features.sdnr.wt"; @@ -76,14 +82,22 @@ public class AboutHttpServlet extends HttpServlet { private final Map<String, String> data; private final String readmeContent; + // private BundleService bundleService; + public AboutHttpServlet() { this.data = new HashMap<>(); this.collectStaticData(); this.readmeContent = this.render(this.getResourceFileContent(README_FILE)); + //BundleContext context = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); + } + // public void setBundleService(BundleService bundleService) { + // this.bundleService = bundleService; + // } + /** * collect static versioning data */ @@ -96,7 +110,7 @@ public class AboutHttpServlet extends HttpServlet { this.data.put(PLACEHOLDER_ODLUX_REVISION, this.getPomProperty("odlux.buildno")); this.data.put(PLACEHOLDER_PACAKGE_VERSION, this.getManifestValue("Bundle-Version")); this.data.put(PLACEHOLDER_CCSDK_VERSION, ccsdkVersion); - this.data.put(PLACEHOLDER_ONAP_RELEASEVERSION, "1.8.1-SNAPSHOT"); + this.data.put(PLACEHOLDER_ONAP_RELEASEVERSION, "2.0.0-SNAPSHOT"); this.data.put(PLACEHOLDER_MDSAL_VERSION, SystemInfo.getMdSalVersion(UNKNOWN)); this.data.put(PLACEHOLDER_YANGTOOLS_VERSION, SystemInfo.getYangToolsVersion(UNKNOWN)); this.data.put(PLACEHOLDER_PACKAGE_GITHASH, this.getGitHash(UNKNOWN)); @@ -170,6 +184,7 @@ public class AboutHttpServlet extends HttpServlet { LOG.info("collecting dynamic data"); try { this.data.put(PLACEHOLDER_KARAF_INFO, SystemInfo.get()); + this.data.put(PLACEHOLDER_DEVICEMANAGER_TABLE, this.getDevicemanagerBundles()); } catch (Exception e) { LOG.warn("problem collecting system data: {}", e); } @@ -264,6 +279,28 @@ public class AboutHttpServlet extends HttpServlet { return null; } + private String getDevicemanagerBundles() { + // if(this.bundleService==null) { + // LOG.debug("no bundle service available"); + // return ""; + // } + // + // List<String> ids = new ArrayList<String>(); + // List<Bundle> bundles = bundleService.selectBundles("0", ids , true); + // if(bundles==null || bundles.size()<=0) { + // LOG.debug("no bundles found"); + // return ""; + // } + // LOG.debug("found {} bundles",bundles.size()); + // MarkdownTable table = new MarkdownTable(); + // for(Bundle bundle:bundles) { + // BundleInfo info = this.bundleService.getInfo(bundle); + // table.addRow(new String[] {String.valueOf(info.getBundleId()),info.getVersion(),info.getName(),info.getState().toString()}); + // } + // return table.toMarkDown(); + return ""; + } + /** * get file by uri from resources and write out to response stream * diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeChildObject.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeChildObject.java new file mode 100644 index 000000000..e34988b4b --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeChildObject.java @@ -0,0 +1,192 @@ +/* + * ============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.http; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.json.JSONObject; + +public class DataTreeChildObject { + + private final String label; + private final String ownSeverity; + private final String childrenSeveritySummary; + private final boolean isMatch; + private final Map<String, DataTreeChildObject> children; + private final Map<String, Object> properties; + + public boolean isMatch() { + return this.isMatch; + } + + public DataTreeChildObject(String label, boolean isMatch, Map<String, DataTreeChildObject> children, + String ownSeverity, String childrenSeveritySummary) { + this.label = label; + this.isMatch = isMatch; + this.children = children; + this.ownSeverity = ownSeverity; + this.childrenSeveritySummary = childrenSeveritySummary; + this.properties = new HashMap<>(); + } + + public DataTreeChildObject setProperty(String key, Object value) { + this.properties.put(key, value); + return this; + } + + public Object getProperty(String key, Object defaultValue) { + return this.properties.getOrDefault(key, defaultValue); + } + + /** + * @param string + * @param b + */ + public DataTreeChildObject(String label, boolean isMatch) { + this(label, isMatch, new HashMap<>(), null, null); + } + + /** + * @param treeLevel + * @param id + * @param data + * @param childKey + * @param parentKey + * @return + */ + public boolean putChild(long treeLevel, String id, DataTreeChildObject data, String parentKey, String childKey) { + Object itemValue; + Object itemValueToMatch = data.getProperty(parentKey, null); + if (itemValueToMatch == null) { + return false; + } + if (treeLevel > 0) { + if (this.children != null) { + for (DataTreeChildObject child : this.children.values()) { + if (child.putChild(treeLevel - 1, id, data, parentKey, childKey)) { + return true; + } + } + } + } else { + // if(this.children!=null) { + // for(DataTreeChildObject child:this.children.values()) { + // itemValue=(String) child.getProperty(childKey, null); + // if(itemValue!=null && itemValue.equals(itemValueToMatch)) { + // child.children.put(id, data); + // return true; + // } + // } + // } + itemValue = this.getProperty(childKey, null); + if (itemValue != null && itemValue.equals(itemValueToMatch)) { + this.children.put(id, data); + } + } + return false; + } + + /** + * @param treeLevel + * @param id + * @param data + * @param parentKey + * @param childKey + * @return + */ + public boolean putChildIfNotExists(long treeLevel, String id, DataTreeChildObject data, String parentKey, + String childKey) { + Object itemValue; + Object itemValueToMatch = data.getProperty(parentKey, null); + if (itemValueToMatch == null) { + return false; + } + if (treeLevel > 0) { + if (this.children != null) { + for (DataTreeChildObject child : this.children.values()) { + if (child.putChildIfNotExists(treeLevel - 1, id, data, parentKey, childKey)) { + return true; + } + } + } + } else { + itemValue = this.getProperty(childKey, null); + if (itemValue != null && itemValue.equals(itemValueToMatch)) { + if (!this.children.containsKey(id)) { + this.children.put(id, data); + } + } + } + return false; + } + + /** + * @return + */ + public JSONObject toJSONObject() { + JSONObject o = new JSONObject(); + o.put("label", this.label); + o.put("isMatch", this.isMatch); + JSONObject c = new JSONObject(); + if (this.children != null) { + for (Entry<String, DataTreeChildObject> entry : this.children.entrySet()) { + c.put(entry.getKey(), entry.getValue().toJSONObject()); + } + } + o.put("children", c); + // o.put("ownSeverity", null); + // o.put("childrenSeveritySummary", null); + return o; + } + + public boolean hasChildMatching() { + boolean match = false; + for (DataTreeChildObject child : this.children.values()) { + match = match || child.hasChildMatching() || this.isMatch; + if (match) { + break; + } + } + return match; + } + + /** + * + */ + public void removeUnmatchedPaths() { + List<String> toRemove = new ArrayList<>(); + for (Entry<String, DataTreeChildObject> entry : this.children.entrySet()) { + if (!(entry.getValue().hasChildMatching() || entry.getValue().isMatch)) { + toRemove.add(entry.getKey()); + } else { + entry.getValue().removeUnmatchedPaths(); + } + } + for (String key : toRemove) { + this.children.remove(key); + } + } +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeHttpServlet.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeHttpServlet.java index 490f3cac8..245ac1cf6 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeHttpServlet.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeHttpServlet.java @@ -21,14 +21,29 @@ */ package org.onap.ccsdk.features.sdnr.wt.dataprovider.http; +import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.json.JSONObject; import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.impl.DataTreeProviderImpl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Entity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author Michael Dürre @@ -36,24 +51,190 @@ import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; */ public class DataTreeHttpServlet extends HttpServlet { + public enum FilterMode { + Strict, //show only filtered items and their parents + Lazy //show root items (and all their children) which have matches inside + } + /** - * @param rawClient + * */ - public void setDatabaseClient(HtDatabaseClient rawClient) { + private static final long serialVersionUID = 1L; + private final DataTreeProviderImpl dataTreeProvider; + private static final Logger LOG = LoggerFactory.getLogger(DataTreeHttpServlet.class); + public DataTreeHttpServlet() { + super(); + this.dataTreeProvider = new DataTreeProviderImpl(); + } + + /** + * @param client + */ + public void setDatabaseClient(HtDatabaseClient client) { + this.dataTreeProvider.setDatabaseClient(client); } + public static String readPayload(HttpServletRequest request) throws IOException { + + String body = null; + StringBuilder stringBuilder = new StringBuilder(); + BufferedReader bufferedReader = null; + + try { + InputStream inputStream = request.getInputStream(); + if (inputStream != null) { + bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + char[] charBuffer = new char[128]; + int bytesRead = -1; + while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { + stringBuilder.append(charBuffer, 0, bytesRead); + } + } else { + stringBuilder.append(""); + } + } catch (IOException ex) { + throw ex; + } finally { + if (bufferedReader != null) { + try { + bufferedReader.close(); + } catch (IOException ex) { + throw ex; + } + } + } + + body = stringBuilder.toString(); + return body; + } + @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { final String uri = req.getRequestURI(); + LOG.debug("GET request for {}", uri); + final EntityWithTree e = getEntity(uri); + if (e != null) { + LOG.info("GET request for {} to e={} with tree={}", uri, e.entity, e.tree); + switch (e.entity) { + case Inventoryequipment: + DataTreeObject o = this.dataTreeProvider.readInventoryTree(e.tree, null, FilterMode.Lazy); + this.doJsonResponse(resp, o); + break; + default: + this.notAvailble(resp); + break; + } + } else { + LOG.debug("unable to find entity for uri {}", uri); + } } - private void readInventoryTree(String filter) { + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + final String uri = req.getRequestURI(); + String filter = null; + FilterMode mode = FilterMode.Lazy; + try { + final String body = readPayload(req); + JSONObject data = new JSONObject(body); + if (data.has("query")) { + filter = data.getString("query"); + } + if (data.has("mode")) { + mode = data.getString("mode").equals("lazy") ? FilterMode.Lazy : FilterMode.Strict; + } + + } catch (Exception e) { + LOG.warn("problem reading payload: {}", e); + } + LOG.debug("POST request for {}", uri); + final EntityWithTree e = getEntity(uri); + if (e != null) { + switch (e.entity) { + case Inventoryequipment: + DataTreeObject o = this.dataTreeProvider.readInventoryTree(e.tree, filter, mode); + this.doJsonResponse(resp, o); + break; + default: + this.notAvailble(resp); + break; + } + } + } + + /** + * @param resp + */ + private void notAvailble(HttpServletResponse resp) { + try { + resp.sendError(HttpServletResponse.SC_NOT_FOUND); + } catch (IOException e) { + + } } - private void doJsonResponse(HttpServletResponse resp, Object data) { + public static EntityWithTree getEntity(String uri) { + final String regex = "^\\/tree\\/read-(.*)-tree\\/?(.*)$"; + final Pattern pattern = Pattern.compile(regex); + final Matcher matcher = pattern.matcher(uri); + Entity e = null; + if (matcher.find() && matcher.groupCount() > 0) { + try { + e = Entity.forName(matcher.group(1)).get(); + return new EntityWithTree(e, matcher.groupCount() > 1 ? matcher.group(2) : null); + } catch (Exception e2) { + LOG.warn("unable to parse {} into entity: {}", matcher.group(2), e2); + } + } + return null; + + } + + private void doJsonResponse(HttpServletResponse resp, DataTreeObject data) { + resp.setHeader("Content-Type", "application/json"); + try { + resp.getWriter().write(data.toJSON()); + } catch (IOException e) { + LOG.warn("problem sending response: {}", e); + } + } + + public static class EntityWithTree { + public final Entity entity; + public final List<String> tree; + + @Override + public String toString() { + return "EntityWithTree [entity=" + entity + ", tree=" + tree + "]"; + } + public EntityWithTree(Entity e, String tree) { + this.entity = e; + if (tree != null) { + if (tree.startsWith("/")) { + tree = tree.substring(1); + } + if (tree.endsWith("/")) { + tree = tree.substring(0, tree.length() - 1); + } + String[] tmp = tree.split("\\/"); + this.tree = new ArrayList<>(); + for (int i = 0; i < tmp.length; i++) { + try { + String s = URLDecoder.decode(tmp[i], "utf-8"); + if (s != null && s.length() > 0) { + this.tree.add(s); + } + } catch (UnsupportedEncodingException e1) { + LOG.warn("problem urldecode {}: {}", tmp[i], e); + } + } + } else { + this.tree = null; + } + } } } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeObject.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeObject.java new file mode 100644 index 000000000..d6c8bd7bb --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeObject.java @@ -0,0 +1,140 @@ +/* + * ============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.http; + +import java.util.HashMap; + +import org.json.JSONObject; + +public class DataTreeObject extends HashMap<String, DataTreeChildObject> { + + private static final long serialVersionUID = 1L; + private final String parentKey; + private final String childKey; + + public DataTreeObject createTreeByPath(String[] pathFilter) { + + if (pathFilter != null && pathFilter.length > 0) { + for (String key : this.keySet()) { + if (key.equals(pathFilter[0])) { + DataTreeChildObject o = this.getChildElemByPath(this.get(key), slice(pathFilter, 1)); + DataTreeObject r = new DataTreeObject(this.parentKey, this.childKey); + r.put(key, o); + return r; + } + } + } + + return null; + + } + + private DataTreeChildObject getChildElemByPath(DataTreeChildObject source, String[] pathFilter) { + + if (pathFilter != null && pathFilter.length > 0) { + // for(String key:source..keySet()) { + // if(key.equals(pathFilter[0])){ + // DataTreeChildObject o= this.getChildElemByPath(this.get(key),slice(pathFilter,1)); + // } + // } + } + + return null; + } + + public DataTreeObject(String parentKey, String childKey) { + this.parentKey = parentKey; + this.childKey = childKey; + } + + /** + * @param treeLevel + * @param id + * @param data + */ + public void put(long treeLevel, String id, DataTreeChildObject data) { + for (DataTreeChildObject entry : this.values()) { + if (entry.putChild(treeLevel, id, data, this.parentKey, this.childKey)) { + break; + } + } + + } + + /** + * + */ + public String toJSON() { + JSONObject o = new JSONObject(); + for (Entry<String, DataTreeChildObject> entry : this.entrySet()) { + o.put(entry.getKey(), entry.getValue().toJSONObject()); + } + return o.toString(); + } + + /** + * + */ + public void removeUnmatchedPaths() { + for (DataTreeChildObject entry : this.values()) { + entry.removeUnmatchedPaths(); + } + + } + + /** + * @param treeLevel + * @param id + * @param setProperty + */ + public void putIfNotExists(long treeLevel, String id, DataTreeChildObject data) { + for (DataTreeChildObject entry : this.values()) { + if (entry.putChildIfNotExists(treeLevel, id, data, this.parentKey, this.childKey)) { + break; + } + } + } + + /** + * @param id + * @param data + */ + public void putIfNotExists(String id, DataTreeChildObject data) { + if (!this.containsKey(id)) { + this.put(id, data); + } + } + + /** + * @param source + * @param i + * @return + */ + public static String[] slice(String[] source, int start) { + String[] r = new String[source.length - start]; + for (int i = 0; i < r.length; i++) { + r[i] = source[i + start]; + } + return r; + + } +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/MarkdownTable.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/MarkdownTable.java new file mode 100644 index 000000000..52eda0cd8 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/MarkdownTable.java @@ -0,0 +1,75 @@ +/* + * ============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.http; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Michael Dürre + * + */ +public class MarkdownTable { + + private String[] columns; + private final List<String[]> rows; + + public MarkdownTable() { + this.rows = new ArrayList<>(); + } + + public void setHeader(String[] cols) { + this.columns = cols; + } + + public void addRow(String[] values) { + this.rows.add(values); + } + + public String toMarkDown() { + StringBuilder sb = new StringBuilder(); + final int cols = + this.columns != null ? this.columns.length : this.rows.size() > 0 ? this.rows.get(0).length : 0; + if (cols > 0) { + sb.append("|"); + for (int i = 0; i < cols; i++) { + sb.append(String.format(" %s |", this.columns != null ? this.columns[i] : "")); + } + sb.append("\n"); + sb.append("|"); + for (int i = 0; i < cols; i++) { + sb.append(" --- |"); + } + sb.append("\n"); + sb.append("|"); + for (String[] row : this.rows) { + for (int i = 0; i < cols; i++) { + sb.append(String.format(" %s |", row[i])); + } + sb.append("\n"); + } + + + } + return sb.toString(); + } +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/ODLVersionLUT.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/ODLVersionLUT.java index 8027fb2c5..3ea3e3d02 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/ODLVersionLUT.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/ODLVersionLUT.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.dataprovider.data; +package org.onap.ccsdk.features.sdnr.wt.dataprovider.http; public class ODLVersionLUT { @@ -27,8 +27,8 @@ public class ODLVersionLUT { if (onapCCSDKVersion == null) { return def; } - if (onapCCSDKVersion.startsWith("1.6.")) { - return "ONAP Guillin"; + if (onapCCSDKVersion.startsWith("2.0.")) { + return "ONAP Guilin"; } if (onapCCSDKVersion.startsWith("1.5.")) { return "ONAP Frankfurt"; @@ -39,6 +39,9 @@ public class ODLVersionLUT { if (onapCCSDKVersion.startsWith("1.3.")) { return "ONAP El Alto"; } + if (onapCCSDKVersion.startsWith("1.2.")) { + return "ONAP Guilin"; + } return def; } @@ -47,8 +50,8 @@ public class ODLVersionLUT { if (onapCCSDKVersion == null) { return def; } - if (onapCCSDKVersion.startsWith("1.6.")) { - return "sodium-SRX (0.11.X)"; + if (onapCCSDKVersion.startsWith("2.")) { + return "sodium-SR3 (0.11.3)"; } if (onapCCSDKVersion.startsWith("1.5.")) { return "neon-SR1 (0.10.1)"; @@ -59,6 +62,9 @@ public class ODLVersionLUT { if (onapCCSDKVersion.startsWith("1.3.")) { return "fluorine-SR2 (0.9.2)"; } + if (onapCCSDKVersion.startsWith("1.2.")) { + return "sodium-SR3 (0.11.3)"; + } return def; } } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/SystemInfo.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/SystemInfo.java index 9b8806ab8..12b03ffe6 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/SystemInfo.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/SystemInfo.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.dataprovider.data; +package org.onap.ccsdk.features.sdnr.wt.dataprovider.http; import java.io.File; import java.io.IOException; diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/YangSchemaHttpServlet.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/YangSchemaHttpServlet.java index 075f4f766..48862a6a5 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/YangSchemaHttpServlet.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/YangSchemaHttpServlet.java @@ -28,7 +28,6 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.YangFileProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderImpl.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderImpl.java index 286af7aa3..f9e0fcbc2 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderImpl.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderImpl.java @@ -46,6 +46,7 @@ public class DataProviderImpl implements IEntityDataProvider, AutoCloseable { private MsServlet mediatorServerServlet; private DataProviderServiceImpl rpcApiService; private AboutHttpServlet aboutServlet; + private DataTreeHttpServlet treeServlet; private HtDatabaseClient dbClient; // Blueprint 1 @@ -66,12 +67,17 @@ public class DataProviderImpl implements IEntityDataProvider, AutoCloseable { this.aboutServlet = aboutServlet; } + public void setTreeServlet(DataTreeHttpServlet treeServlet) { + this.treeServlet = treeServlet; + } + public void init() throws Exception { LOG.info("Session Initiated start {}", APPLICATION_NAME); // Start RPC Service this.rpcApiService = new DataProviderServiceImpl(rpcProviderService, this.mediatorServerServlet); + this.treeServlet.setDatabaseClient(this.rpcApiService.getRawClient()); LOG.info("Session Initiated end. Initialization done"); } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataTreeProviderImpl.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataTreeProviderImpl.java new file mode 100644 index 000000000..2af354bcc --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataTreeProviderImpl.java @@ -0,0 +1,321 @@ +/* + * ============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.impl; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +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.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.SortOrder; +import org.onap.ccsdk.features.sdnr.wt.common.database.requests.Search7Request; +import org.onap.ccsdk.features.sdnr.wt.common.database.requests.SearchRequest; +import org.onap.ccsdk.features.sdnr.wt.common.database.responses.AggregationEntries; +import org.onap.ccsdk.features.sdnr.wt.common.database.responses.SearchResponse; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.DataTreeChildObject; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.DataTreeHttpServlet.FilterMode; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.DataTreeObject; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.Entity; + +/** + * @author Michael Dürre + * + */ +public class DataTreeProviderImpl { + + private static final long MAXSIZE_PERSEARCH = 10; + private HtDatabaseClient dbClient; + final String INVENTORY_PROPERTY_TREELEVEL = "tree-level"; + final String INVENTORY_PROPERTY_NODEID = "node-id"; + final String INVENTORY_PROPERTY_UUID = "uuid"; + final String INVENTORY_PROPERTY_PARENTUUID = "parent-uuid"; + final String INVENTORY_PROPERTY_FOR_LABEL_CHILD = "uuid"; + final String INVENTORY_PROPERTY_FOR_LABEL = "uuid"; + + private List<SearchHit> search(Entity e, String filter, String propTreeLevel) throws IOException { + return this.search(e, filter, null, null, null, null, null, null, propTreeLevel); + } + + private List<SearchHit> search(Entity e, String filter, String nodeKey, String nodeId, String parentKey, + String parentValue, String childKey, String childValue, String propTreeLevel) throws IOException { + QueryBuilder query = + filter == null ? QueryBuilders.matchAllQuery() : QueryBuilders.searchAllFieldsQuery(filter); + if ((nodeId != null && nodeKey != null) || (parentKey != null && parentValue != null)) { + BoolQueryBuilder bquery = new BoolQueryBuilder(); + if (filter != null) { + bquery.must(query); + } + if (nodeId != null) { + bquery.must(QueryBuilders.matchQuery(nodeKey, nodeId)); + } + // if (parentKey != null && parentValue != null) { + // bquery.must(QueryBuilders.matchQuery(parentKey, parentValue)); + // } + // if (childKey != null && childValue != null) { + // bquery.must(QueryBuilders.matchQuery(childKey, childValue)); + // } + query = bquery; + + } + return this.search(e, query, propTreeLevel); + } + + private List<SearchHit> search(Entity e, QueryBuilder query, String propTreeLevel) throws IOException { + List<SearchHit> list = new ArrayList<SearchHit>(); + query.sort(propTreeLevel, SortOrder.ASCENDING); + SearchRequest request = new Search7Request(Entity.Inventoryequipment.getName()); + query.size(MAXSIZE_PERSEARCH); + request.setQuery(query); + SearchResponse response = this.dbClient.search(request); + SearchHit[] matches = response.getHits(); + for (SearchHit hit : matches) { + list.add(hit); + } + if (response.getTotal() > MAXSIZE_PERSEARCH) { + long todo = response.getTotal(); + long from = MAXSIZE_PERSEARCH; + while (todo > from) { + request.setQuery(query.from(from)); + from += MAXSIZE_PERSEARCH; + //merge into list + response = this.dbClient.search(request); + matches = response.getHits(); + for (SearchHit hit : matches) { + list.add(hit); + } + } + } + return list; + } + + /** + * @param iNVENTORY_PROPERTY_NODEID2 + * @return + * @throws IOException + */ + private AggregationEntries searchAggregated(Entity e, String key) throws IOException { + QueryBuilder query = QueryBuilders.matchAllQuery().aggregations(key).size(MAXSIZE_PERSEARCH); + SearchRequest request = new Search7Request(e.getName()); + request.setQuery(query); + SearchResponse response = this.dbClient.search(request); + return response.getAggregations(key); + } + + /** + * + * @param tree + * @param filter + * @param + * @return + * @throws IOException + */ + public DataTreeObject readInventoryTree(List<String> tree, String filter, FilterMode mode) throws IOException { + + //root nodes will be node-information -> below inventory + if (tree == null || tree.size() <= 0) { + return this.readInventoryTreeWithNode(filter, mode); + } + //root node will be inventory on tree-level if sliced treePath + else { + return this.readInventoryTreeForNode(tree.get(0), tree.subList(0, tree.size() - 1), filter, mode); + } + + } + + /** + * @param string + * @param slice + * @param filter + * @param mode + * @return + */ + private DataTreeObject readInventoryTreeForNode(String nodeId, List<String> list, String filter, FilterMode mode) + throws IOException { + DataTreeObject tree = new DataTreeObject(INVENTORY_PROPERTY_PARENTUUID, INVENTORY_PROPERTY_UUID); + final String parentUuid = list.size() > 1 ? list.get(list.size() - 2) : null; + final String uuid = list.size() > 0 ? list.get(list.size() - 1) : null; + List<SearchHit> matches = this.search(Entity.Inventoryequipment, filter, INVENTORY_PROPERTY_NODEID, nodeId, + INVENTORY_PROPERTY_PARENTUUID, parentUuid, INVENTORY_PROPERTY_UUID, uuid, INVENTORY_PROPERTY_TREELEVEL); + + //tree.a(subtreePath); + List<SearchHit> others = this.search(Entity.Inventoryequipment, (String) null, INVENTORY_PROPERTY_TREELEVEL); + if (matches.size() > 0) { + int treeLevelToStart = (list == null || list.size() <= 0) ? 0 : list.size() - 1; + //build tree + JSONObject hitData; + //fill root elems + for (SearchHit hit : matches) { + hitData = hit.getSource(); + if (hitData.getLong("tree-level") == treeLevelToStart) { + tree.put(hit.getId(), + new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL), true) + .setProperty(INVENTORY_PROPERTY_UUID, hitData.getString(INVENTORY_PROPERTY_UUID)) + .setProperty(INVENTORY_PROPERTY_PARENTUUID, + hitData.getString(INVENTORY_PROPERTY_PARENTUUID))); + } + } + for (SearchHit hit : others) { + hitData = hit.getSource(); + if (hitData.getLong("tree-level") == treeLevelToStart) { + tree.putIfNotExists(hit.getId(), + new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL), false) + .setProperty(INVENTORY_PROPERTY_UUID, hitData.getString(INVENTORY_PROPERTY_UUID)) + .setProperty(INVENTORY_PROPERTY_PARENTUUID, + hitData.getString(INVENTORY_PROPERTY_PARENTUUID))); + } + } + //fill child elems + for (SearchHit hit : matches) { + hitData = hit.getSource(); + if (hitData.getLong("tree-level") > treeLevelToStart) { + tree.put(hitData.getLong("tree-level") - treeLevelToStart - 1, hit.getId(), + new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL), true) + .setProperty(INVENTORY_PROPERTY_UUID, hitData.getString(INVENTORY_PROPERTY_UUID)) + .setProperty(INVENTORY_PROPERTY_PARENTUUID, + hitData.getString(INVENTORY_PROPERTY_PARENTUUID))); + } + } + for (SearchHit hit : others) { + hitData = hit.getSource(); + if (hitData.getLong("tree-level") > treeLevelToStart) { + tree.putIfNotExists(hitData.getLong("tree-level") - treeLevelToStart - 1, hit.getId(), + new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL), false) + .setProperty(INVENTORY_PROPERTY_UUID, hitData.getString(INVENTORY_PROPERTY_UUID)) + .setProperty(INVENTORY_PROPERTY_PARENTUUID, + hitData.getString(INVENTORY_PROPERTY_PARENTUUID))); + } + } + } + return tree; + } + + /** + * node will be root elements inventory information below from level-1 + * + * @param filter + * @param mode + * @return + * @throws IOException + */ + private DataTreeObject readInventoryTreeWithNode(String filter, FilterMode mode) throws IOException { + DataTreeObject tree = new DataTreeObject(INVENTORY_PROPERTY_PARENTUUID, INVENTORY_PROPERTY_UUID); + + List<SearchHit> matches = this.search(Entity.Inventoryequipment, filter, INVENTORY_PROPERTY_TREELEVEL); + List<SearchHit> others = null; + if (matches.size() > 0) { + if (filter != null) { + //find all parents up to tree-level 0 + String nodeId = ""; + List<String> alreadyInList = new ArrayList<>(); + BoolQueryBuilder query2 = QueryBuilders.boolQuery(); + for (SearchHit hit : matches) { + nodeId = hit.getSource().getString(INVENTORY_PROPERTY_NODEID); + if (alreadyInList.contains(nodeId)) { + continue; + } + query2.should(QueryBuilders.matchQuery(INVENTORY_PROPERTY_NODEID, nodeId)); + alreadyInList.add(nodeId); + tree.put(nodeId, + new DataTreeChildObject(nodeId, false).setProperty(INVENTORY_PROPERTY_UUID, nodeId)); + + } + others = this.search(Entity.Inventoryequipment, query2, INVENTORY_PROPERTY_TREELEVEL); + } else { + AggregationEntries nodes = this.searchAggregated(Entity.Inventoryequipment, INVENTORY_PROPERTY_NODEID); + for (String node : nodes.keySet()) { + tree.put(node, new DataTreeChildObject(node, false).setProperty(INVENTORY_PROPERTY_UUID, node)); + } + } + + //build tree + JSONObject hitData; + //fill root elems + for (SearchHit hit : matches) { + hitData = hit.getSource(); + if (hitData.getLong("tree-level") == 0) { + tree.put(0, hit.getId(), + new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL), true) + .setProperty(INVENTORY_PROPERTY_UUID, hitData.getString(INVENTORY_PROPERTY_UUID)) + .setProperty(INVENTORY_PROPERTY_PARENTUUID, + hitData.getString(INVENTORY_PROPERTY_NODEID))); + } + } + if (others != null) { + for (SearchHit hit : others) { + hitData = hit.getSource(); + if (hitData.getLong("tree-level") == 0) { + tree.putIfNotExists(0, hit.getId(), + new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL), false) + .setProperty(INVENTORY_PROPERTY_UUID, + hitData.getString(INVENTORY_PROPERTY_UUID)) + .setProperty(INVENTORY_PROPERTY_PARENTUUID, + hitData.getString(INVENTORY_PROPERTY_NODEID))); + } + } + } + //fill child elements + for (SearchHit hit : matches) { + hitData = hit.getSource(); + long treeLevel = hitData.getLong("tree-level"); + if (treeLevel > 0) { + tree.put(treeLevel, hit.getId(), + new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL_CHILD), true) + .setProperty(INVENTORY_PROPERTY_UUID, hitData.getString(INVENTORY_PROPERTY_UUID)) + .setProperty(INVENTORY_PROPERTY_PARENTUUID, + hitData.getString(INVENTORY_PROPERTY_PARENTUUID))); + } + } + if (others != null) { + for (SearchHit hit : others) { + hitData = hit.getSource(); + long treeLevel = hitData.getLong("tree-level"); + if (hitData.getLong("tree-level") > 0) { + tree.putIfNotExists(treeLevel, hit.getId(), + new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL_CHILD), false) + .setProperty(INVENTORY_PROPERTY_UUID, + hitData.getString(INVENTORY_PROPERTY_UUID)) + .setProperty(INVENTORY_PROPERTY_PARENTUUID, + hitData.getString(INVENTORY_PROPERTY_PARENTUUID))); + } + } + } + if (mode == FilterMode.Strict) { + tree.removeUnmatchedPaths(); + } + } + return tree; + } + + + + /** + * @param client + */ + public void setDatabaseClient(HtDatabaseClient client) { + this.dbClient = client; + + } +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/EsConfig.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/EsConfig.java index 001437771..44751ffd0 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/EsConfig.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/EsConfig.java @@ -26,7 +26,6 @@ import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.List; - import org.onap.ccsdk.features.sdnr.wt.common.configuration.Configuration; import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; import org.onap.ccsdk.features.sdnr.wt.common.configuration.filechange.IConfigChangedListener; @@ -52,13 +51,12 @@ public class EsConfig implements Configuration, IEsConfig { private static final String PROPERTY_KEY_AUTH_PASSWORD = "esAuthPassword"; - private static String defaultHostinfo = "${SDNRDBURL}";//printHosts(new HostInfo[] { new HostInfo("sdnrdb", 9200, Protocol.HTTP) }); + private static String defaultHostinfo = "${SDNRDBURL}"; private static final String DEFAULT_VALUE_CLUSTER = ""; /** check db data in this interval [in seconds] 0 deactivated */ private static final String DEFAULT_ARCHIVE_INTERVAL_SEC = "0"; /** keep data for this time [in seconds] 30 days */ private static final String DEFAULT_ARCHIVE_LIMIT_SEC = String.valueOf(60L * 60L * 24L * 30L); - //private static final String DEFAULT_KEY_NODE = "elasticsearchnode"; private static final String DEFAULT_VALUE_NODE = "elasticsearchnode"; private static final String DEFAULT_VALUE_DBUSERNAME = "${SDNRDBUSERNAME}"; private static final String DEFAULT_VALUE_DBPASSWORD = "${SDNRDBPASSWORD}"; diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/YangToolsMapper2.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/YangToolsMapper2.java index ce67c39dd..814bfd745 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/YangToolsMapper2.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/YangToolsMapper2.java @@ -59,16 +59,25 @@ public class YangToolsMapper2<T extends DataObject> extends ObjectMapper { private final Logger LOG = LoggerFactory.getLogger(YangToolsMapper2.class); private static final long serialVersionUID = 1L; - private static String ENTITY = "Entity"; private static String BUILDER = "Builder"; - private @Nullable Class<T> clazz; - private @Nullable Class<? extends Builder<? extends T>> builderClazz; + private @Nullable final Class<T> clazz; + private @Nullable final Class<? extends Builder<? extends T>> builderClazz; private BundleContext context; - public <X extends T, B extends Builder<X>> YangToolsMapper2(Class<T> clazz, Class<B> builderClazz) - throws ClassNotFoundException { + /** + * Generic Object creation of yangtools java class builder pattern. + * + * @param <X> Class of DataObject + * @param <B> Builder for the class. + * @param clazz specifies class to be mapped + * @param builderClazz is the builder for class with name pattern "clazzBuilder".<br> + * If null the clazz is expected to support normal jackson build pattern. + * @throws ClassNotFoundException if builderClazz not available in bundle + */ + public <X extends T, B extends Builder<X>> YangToolsMapper2(@NonNull Class<T> clazz, + @Nullable Class<B> builderClazz) throws ClassNotFoundException { super(); configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); setPropertyNamingStrategy(PropertyNamingStrategy.KEBAB_CASE); @@ -84,11 +93,6 @@ public class YangToolsMapper2<T extends DataObject> extends ObjectMapper { context = bundle != null ? bundle.getBundleContext() : null; } - public YangToolsMapper2() throws ClassNotFoundException { - this(null, null); - } - - @Override public String writeValueAsString(Object value) throws JsonProcessingException { return super.writeValueAsString(value); @@ -101,11 +105,12 @@ public class YangToolsMapper2<T extends DataObject> extends ObjectMapper { * @param clazz class with interface. * @return builder for interface or null if not existing */ - @SuppressWarnings("unchecked") - public @Nullable <T extends DataObject> Builder<T> getBuilder(Class<T> clazz) { + public @Nullable Builder<? extends T> getBuilder(Class<T> clazz) { try { - //Class<?> clazzBuilder = getBuilderClass(getBuilderClassName(clazz)); - return (Builder<T>) builderClazz.newInstance(); + if (builderClazz != null) + return (Builder<? extends T>) builderClazz.newInstance(); + else + return null; } catch (InstantiationException | IllegalAccessException e) { LOG.debug("Problem ", e); return null; @@ -169,12 +174,6 @@ public class YangToolsMapper2<T extends DataObject> extends ObjectMapper { */ private static String getBuilderClassName(Class<?> clazz) { return clazz.getName() + BUILDER; - // String clazzName = clazz.getName(); - // if (clazzName.endsWith(ENTITY)) { - // return clazzName.replace(ENTITY, BUILDER); - // } else { - // return clazzName + BUILDER; - // } } /** |