diff options
author | 2023-01-19 16:45:58 +0000 | |
---|---|---|
committer | 2023-01-31 11:26:22 +0000 | |
commit | 0fa2fabeec18763bab060d85f5123bceff8ee34c (patch) | |
tree | 3fc7b6bcd8344b8841b397a85beb01a20f9f34b0 /cps-service/src/main/java | |
parent | 3d878b0674cd61e64501dfe6564b8921e76056bb (diff) |
Introduce Instrumentation
- Add instrumentation related dependency
- Added Timed Instrumentation
- CPS-Service Crud methods
- CPS Yang parsing
- NCMP Registration methods
- NCMP Events handling
- Remove manual Gauge for YanResources Cache
as (better!) instrumentation is already built into the 3PP
- Sorted dependecies alphabetically (as we used to enforce, to prevent duplicates)
- Added ## P E R F O R M A N C E T E S T R E S U L T S ### mini report
- (unrelated) test improvement (because of bug that turned out to be invalid)
Reviewers: Sourabh,Priyank, Luke
Issue-ID: CPS-1457
Signed-off-by: ToineSiebelink <toine.siebelink@est.tech>
Change-Id: I34b20bece2f59488b022b8effa9470704c57be4d
Diffstat (limited to 'cps-service/src/main/java')
7 files changed, 179 insertions, 17 deletions
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java index 38fa92a09..53fab2916 100755 --- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java +++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation + * Copyright (C) 2021-2023 Nordix Foundation * Modifications Copyright (C) 2020-2022 Bell Canada. * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2022 TechMahindra Ltd. @@ -28,6 +28,7 @@ import static org.onap.cps.notification.Operation.CREATE; import static org.onap.cps.notification.Operation.DELETE; import static org.onap.cps.notification.Operation.UPDATE; +import io.micrometer.core.annotation.Timed; import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.Collection; @@ -48,7 +49,7 @@ import org.onap.cps.spi.model.DataNode; import org.onap.cps.spi.model.DataNodeBuilder; import org.onap.cps.spi.utils.CpsValidator; import org.onap.cps.utils.ContentType; -import org.onap.cps.utils.YangUtils; +import org.onap.cps.utils.TimedYangParser; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.springframework.stereotype.Service; @@ -66,6 +67,7 @@ public class CpsDataServiceImpl implements CpsDataService { private final YangTextSchemaSourceSetCache yangTextSchemaSourceSetCache; private final NotificationService notificationService; private final CpsValidator cpsValidator; + private final TimedYangParser timedYangParser; @Override public void saveData(final String dataspaceName, final String anchorName, final String nodeData, @@ -74,6 +76,8 @@ public class CpsDataServiceImpl implements CpsDataService { } @Override + @Timed(value = "cps.data.service.datanode.root.save", + description = "Time taken to save a root data node") public void saveData(final String dataspaceName, final String anchorName, final String nodeData, final OffsetDateTime observedTimestamp, final ContentType contentType) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); @@ -90,6 +94,8 @@ public class CpsDataServiceImpl implements CpsDataService { } @Override + @Timed(value = "cps.data.service.datanode.child.save", + description = "Time taken to save a child data node") public void saveData(final String dataspaceName, final String anchorName, final String parentNodeXpath, final String nodeData, final OffsetDateTime observedTimestamp, final ContentType contentType) { @@ -101,6 +107,8 @@ public class CpsDataServiceImpl implements CpsDataService { } @Override + @Timed(value = "cps.data.service.list.element.save", + description = "Time taken to save a list element") public void saveListElements(final String dataspaceName, final String anchorName, final String parentNodeXpath, final String jsonData, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); @@ -112,6 +120,8 @@ public class CpsDataServiceImpl implements CpsDataService { } @Override + @Timed(value = "cps.data.service.list.element.batch.save", + description = "Time taken to save a batch of list elements") public void saveListElementsBatch(final String dataspaceName, final String anchorName, final String parentNodeXpath, final Collection<String> jsonDataList, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); @@ -123,6 +133,8 @@ public class CpsDataServiceImpl implements CpsDataService { } @Override + @Timed(value = "cps.data.service.datanode.get", + description = "Time taken to get a data node") public DataNode getDataNode(final String dataspaceName, final String anchorName, final String xpath, final FetchDescendantsOption fetchDescendantsOption) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); @@ -130,6 +142,8 @@ public class CpsDataServiceImpl implements CpsDataService { } @Override + @Timed(value = "cps.data.service.datanode.batch.get", + description = "Time taken to get a batch of data nodes") public Collection<DataNode> getDataNodes(final String dataspaceName, final String anchorName, final Collection<String> xpaths, final FetchDescendantsOption fetchDescendantsOption) { @@ -138,6 +152,8 @@ public class CpsDataServiceImpl implements CpsDataService { } @Override + @Timed(value = "cps.data.service.datanode.leaves.update", + description = "Time taken to get a batch of data nodes") public void updateNodeLeaves(final String dataspaceName, final String anchorName, final String parentNodeXpath, final String jsonData, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); @@ -148,6 +164,8 @@ public class CpsDataServiceImpl implements CpsDataService { } @Override + @Timed(value = "cps.data.service.datanode.leaves.descendants.leaves.update", + description = "Time taken to update data node leaves and existing descendants leaves") public void updateNodeLeavesAndExistingDescendantLeaves(final String dataspaceName, final String anchorName, final String parentNodeXpath, final String dataNodeUpdatesAsJson, @@ -184,6 +202,8 @@ public class CpsDataServiceImpl implements CpsDataService { } @Override + @Timed(value = "cps.data.service.datanode.descendants.update", + description = "Time taken to update a data node and descendants") public void updateDataNodeAndDescendants(final String dataspaceName, final String anchorName, final String parentNodeXpath, final String jsonData, final OffsetDateTime observedTimestamp) { @@ -196,6 +216,8 @@ public class CpsDataServiceImpl implements CpsDataService { } @Override + @Timed(value = "cps.data.service.datanode.descendants.batch.update", + description = "Time taken to update a batch of data nodes and descendants") public void updateDataNodesAndDescendants(final String dataspaceName, final String anchorName, final Map<String, String> nodesJsonData, final OffsetDateTime observedTimestamp) { @@ -208,6 +230,8 @@ public class CpsDataServiceImpl implements CpsDataService { } @Override + @Timed(value = "cps.data.service.list.update", + description = "Time taken to update a list") public void replaceListContent(final String dataspaceName, final String anchorName, final String parentNodeXpath, final String jsonData, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); @@ -217,6 +241,8 @@ public class CpsDataServiceImpl implements CpsDataService { } @Override + @Timed(value = "cps.data.service.list.batch.update", + description = "Time taken to update a batch of lists") public void replaceListContent(final String dataspaceName, final String anchorName, final String parentNodeXpath, final Collection<DataNode> dataNodes, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); @@ -225,6 +251,8 @@ public class CpsDataServiceImpl implements CpsDataService { } @Override + @Timed(value = "cps.data.service.datanode.delete", + description = "Time taken to delete a datanode") public void deleteDataNode(final String dataspaceName, final String anchorName, final String dataNodeXpath, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); @@ -233,6 +261,8 @@ public class CpsDataServiceImpl implements CpsDataService { } @Override + @Timed(value = "cps.data.service.datanode.batch.delete", + description = "Time taken to delete a batch of datanodes") public void deleteDataNodes(final String dataspaceName, final String anchorName, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); @@ -241,6 +271,8 @@ public class CpsDataServiceImpl implements CpsDataService { } @Override + @Timed(value = "cps.data.service.list.delete", + description = "Time taken to delete a list or list element") public void deleteListOrListElement(final String dataspaceName, final String anchorName, final String listNodeXpath, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); @@ -256,11 +288,12 @@ public class CpsDataServiceImpl implements CpsDataService { final SchemaContext schemaContext = getSchemaContext(dataspaceName, anchor.getSchemaSetName()); if (ROOT_NODE_XPATH.equals(parentNodeXpath)) { - final ContainerNode containerNode = YangUtils.parseData(contentType, nodeData, schemaContext); + final ContainerNode containerNode = timedYangParser.parseData(contentType, nodeData, schemaContext); return new DataNodeBuilder().withContainerNode(containerNode).build(); } - final ContainerNode containerNode = YangUtils.parseData(contentType, nodeData, schemaContext, parentNodeXpath); + final ContainerNode containerNode = + timedYangParser.parseData(contentType, nodeData, schemaContext, parentNodeXpath); return new DataNodeBuilder() .withParentNodeXpath(parentNodeXpath) @@ -283,8 +316,9 @@ public class CpsDataServiceImpl implements CpsDataService { final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName); final SchemaContext schemaContext = getSchemaContext(dataspaceName, anchor.getSchemaSetName()); + if (ROOT_NODE_XPATH.equals(parentNodeXpath)) { - final ContainerNode containerNode = YangUtils.parseData(contentType, nodeData, schemaContext); + final ContainerNode containerNode = timedYangParser.parseData(contentType, nodeData, schemaContext); final Collection<DataNode> dataNodes = new DataNodeBuilder() .withContainerNode(containerNode) .buildCollection(); @@ -293,7 +327,8 @@ public class CpsDataServiceImpl implements CpsDataService { } return dataNodes; } - final ContainerNode containerNode = YangUtils.parseData(contentType, nodeData, schemaContext, parentNodeXpath); + final ContainerNode containerNode = + timedYangParser.parseData(contentType, nodeData, schemaContext, parentNodeXpath); final Collection<DataNode> dataNodes = new DataNodeBuilder() .withParentNodeXpath(parentNodeXpath) .withContainerNode(containerNode) @@ -302,7 +337,6 @@ public class CpsDataServiceImpl implements CpsDataService { throw new DataValidationException("Invalid data.", "No data nodes provided"); } return dataNodes; - } private Collection<Collection<DataNode>> buildDataNodes(final String dataspaceName, final String anchorName, diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java index a04dd2af5..ccd0fcc28 100644 --- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java +++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2020-2022 Nordix Foundation + * Copyright (C) 2020-2023 Nordix Foundation * Modifications Copyright (C) 2020-2021 Pantheon.tech * Modifications Copyright (C) 2022 Bell Canada * Modifications Copyright (C) 2022 TechMahindra Ltd @@ -23,6 +23,7 @@ package org.onap.cps.api.impl; +import io.micrometer.core.annotation.Timed; import java.util.Collection; import java.util.Map; import lombok.RequiredArgsConstructor; @@ -36,8 +37,8 @@ import org.onap.cps.spi.model.ModuleDefinition; import org.onap.cps.spi.model.ModuleReference; import org.onap.cps.spi.model.SchemaSet; import org.onap.cps.spi.utils.CpsValidator; +import org.onap.cps.yang.TimedYangTextSchemaSourceSetBuilder; import org.onap.cps.yang.YangTextSchemaSourceSet; -import org.onap.cps.yang.YangTextSchemaSourceSetBuilder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -49,13 +50,16 @@ public class CpsModuleServiceImpl implements CpsModuleService { private final YangTextSchemaSourceSetCache yangTextSchemaSourceSetCache; private final CpsAdminService cpsAdminService; private final CpsValidator cpsValidator; + private final TimedYangTextSchemaSourceSetBuilder timedYangTextSchemaSourceSetBuilder; @Override + @Timed(value = "cps.module.service.schemaset.create", + description = "Time taken to create (and store) a schemaset") public void createSchemaSet(final String dataspaceName, final String schemaSetName, final Map<String, String> yangResourcesNameToContentMap) { cpsValidator.validateNameCharacters(dataspaceName, schemaSetName); - final var yangTextSchemaSourceSet - = YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap); + final YangTextSchemaSourceSet yangTextSchemaSourceSet = + timedYangTextSchemaSourceSetBuilder.getYangTextSchemaSourceSet(yangResourcesNameToContentMap); cpsModulePersistenceService.storeSchemaSet(dataspaceName, schemaSetName, yangResourcesNameToContentMap); yangTextSchemaSourceSetCache.updateCache(dataspaceName, schemaSetName, yangTextSchemaSourceSet); } diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/YangTextSchemaSourceSetCache.java b/cps-service/src/main/java/org/onap/cps/api/impl/YangTextSchemaSourceSetCache.java index 0f620b0dd..4fdae5a30 100644 --- a/cps-service/src/main/java/org/onap/cps/api/impl/YangTextSchemaSourceSetCache.java +++ b/cps-service/src/main/java/org/onap/cps/api/impl/YangTextSchemaSourceSetCache.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2022 Bell Canada - * Modifications Copyright (C) 2022 Nordix Foundation + * Modifications Copyright (C) 2022-2023 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,9 @@ package org.onap.cps.api.impl; import com.google.errorprone.annotations.CanIgnoreReturnValue; +import io.micrometer.core.instrument.Metrics; import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import lombok.RequiredArgsConstructor; import org.onap.cps.spi.CpsModulePersistenceService; import org.onap.cps.spi.utils.CpsValidator; @@ -46,6 +48,9 @@ public class YangTextSchemaSourceSetCache { private final CpsModulePersistenceService cpsModulePersistenceService; private final CpsValidator cpsValidator; + private final AtomicInteger yangSchemaCacheCounter = Metrics.gauge("cps.yangschema.cache.gauge", + new AtomicInteger(0)); + /** * Cache YangTextSchemaSourceSet. * @@ -74,10 +79,10 @@ public class YangTextSchemaSourceSetCache { public YangTextSchemaSourceSet updateCache(final String dataspaceName, final String schemaSetName, final YangTextSchemaSourceSet yangTextSchemaSourceSet) { cpsValidator.validateNameCharacters(dataspaceName, schemaSetName); + yangSchemaCacheCounter.incrementAndGet(); return yangTextSchemaSourceSet; } - /** * Remove the cached value for the given dataspace and schema-set. * @@ -87,6 +92,7 @@ public class YangTextSchemaSourceSetCache { @CacheEvict(key = "#p0.concat('-').concat(#p1)") public void removeFromCache(final String dataspaceName, final String schemaSetName) { cpsValidator.validateNameCharacters(dataspaceName, schemaSetName); + yangSchemaCacheCounter.decrementAndGet(); // Spring provides implementation for removing object from cache } diff --git a/cps-service/src/main/java/org/onap/cps/utils/TimedYangParser.java b/cps-service/src/main/java/org/onap/cps/utils/TimedYangParser.java new file mode 100644 index 000000000..4640593dc --- /dev/null +++ b/cps-service/src/main/java/org/onap/cps/utils/TimedYangParser.java @@ -0,0 +1,61 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2023 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.utils; + +import io.micrometer.core.annotation.Timed; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.springframework.stereotype.Service; + +@Service +public class TimedYangParser { + + /** + * Parses data into Collection of NormalizedNode according to given schema context. + * + * @param nodeData data string + * @param schemaContext schema context describing associated data model + * @return the NormalizedNode object + */ + @Timed(value = "cps.utils.yangparser.nodedata.parse", + description = "Time taken to parse node data without a parent") + public ContainerNode parseData(final ContentType contentType, + final String nodeData, + final SchemaContext schemaContext) { + return YangUtils.parseData(contentType, nodeData, schemaContext); + } + + /** + * Parses data into NormalizedNode according to given schema context. + * + * @param nodeData data string + * @param schemaContext schema context describing associated data model + * @return the NormalizedNode object + */ + @Timed(value = "cps.utils.yangparser.nodedata.with.parent.parse", + description = "Time taken to parse node data with a parent") + public ContainerNode parseData(final ContentType contentType, + final String nodeData, + final SchemaContext schemaContext, + final String parentNodeXpath) { + return YangUtils.parseData(contentType, nodeData, schemaContext, parentNodeXpath); + } +} diff --git a/cps-service/src/main/java/org/onap/cps/utils/YangUtils.java b/cps-service/src/main/java/org/onap/cps/utils/YangUtils.java index c0dfe5205..7da402415 100644 --- a/cps-service/src/main/java/org/onap/cps/utils/YangUtils.java +++ b/cps-service/src/main/java/org/onap/cps/utils/YangUtils.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2020-2022 Nordix Foundation + * Copyright (C) 2020-2023 Nordix Foundation * Modifications Copyright (C) 2021 Bell Canada. * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2022 TechMahindra Ltd. @@ -87,7 +87,7 @@ public class YangUtils { * @param schemaContext schema context describing associated data model * @return the NormalizedNode object */ - public static ContainerNode parseData(final ContentType contentType, + static ContainerNode parseData(final ContentType contentType, final String nodeData, final SchemaContext schemaContext) { if (contentType == ContentType.JSON) { @@ -103,7 +103,7 @@ public class YangUtils { * @param schemaContext schema context describing associated data model * @return the NormalizedNode object */ - public static ContainerNode parseData(final ContentType contentType, + static ContainerNode parseData(final ContentType contentType, final String nodeData, final SchemaContext schemaContext, final String parentNodeXpath) { diff --git a/cps-service/src/main/java/org/onap/cps/yang/TimedYangTextSchemaSourceSetBuilder.java b/cps-service/src/main/java/org/onap/cps/yang/TimedYangTextSchemaSourceSetBuilder.java new file mode 100644 index 000000000..013faff0c --- /dev/null +++ b/cps-service/src/main/java/org/onap/cps/yang/TimedYangTextSchemaSourceSetBuilder.java @@ -0,0 +1,37 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2023 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.yang; + +import io.micrometer.core.annotation.Timed; +import java.util.Map; +import org.springframework.stereotype.Service; + +@Service +public class TimedYangTextSchemaSourceSetBuilder { + + @Timed(value = "cps.yangtextschemasourceset.build", + description = "Time taken to build a yang text schema source set") + public YangTextSchemaSourceSet getYangTextSchemaSourceSet( + final Map<String, String> yangResourcesNameToContentMap) { + return YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap); + } + +} diff --git a/cps-service/src/main/java/org/onap/cps/yang/YangTextSchemaSourceSetBuilder.java b/cps-service/src/main/java/org/onap/cps/yang/YangTextSchemaSourceSetBuilder.java index e0f24f315..deb5b0575 100644 --- a/cps-service/src/main/java/org/onap/cps/yang/YangTextSchemaSourceSetBuilder.java +++ b/cps-service/src/main/java/org/onap/cps/yang/YangTextSchemaSourceSetBuilder.java @@ -1,7 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2020 Pantheon.tech - * Modifications Copyright (C) 2022 Nordix Foundation. + * Modifications Copyright (C) 2022-2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableMap; +import io.micrometer.core.annotation.Timed; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; @@ -58,16 +59,35 @@ public final class YangTextSchemaSourceSetBuilder { private final ImmutableMap.Builder<String, String> yangModelMap = new ImmutableMap.Builder<>(); + /** + * Add Yang resource context. + * + * @param yangResourceNameToContent the resource content + * @return this builder + */ public YangTextSchemaSourceSetBuilder putAll(final Map<String, String> yangResourceNameToContent) { this.yangModelMap.putAll(yangResourceNameToContent); return this; } + /** + * Build a YangTextSchemaSourceSet. + * + * @return the YangTextSchemaSourceSet + */ public YangTextSchemaSourceSet build() { final var schemaContext = generateSchemaContext(yangModelMap.build()); return new YangTextSchemaSourceSetImpl(schemaContext); } + /** + * Add yangResourceNameToContent and build a YangTextSchemaSourceSet. + * + * @param yangResourceNameToContent the resource content + * @return the YangTextSchemaSourceSet + */ + + @Timed(value = "cps.yang.schemasourceset.build", description = "Time taken to build a ODL yang Model") public static YangTextSchemaSourceSet of(final Map<String, String> yangResourceNameToContent) { return new YangTextSchemaSourceSetBuilder().putAll(yangResourceNameToContent).build(); } |