diff options
97 files changed, 1607 insertions, 10919 deletions
diff --git a/checkstyle/pom.xml b/checkstyle/pom.xml index 59af7a43db..62c6d5bffa 100644 --- a/checkstyle/pom.xml +++ b/checkstyle/pom.xml @@ -2,7 +2,7 @@ <!-- ============LICENSE_START======================================================= Copyright (C) 2020 Pantheon.tech - Modifications Copyright (C) 2022 Nordix Foundation + Modifications 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. @@ -26,7 +26,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>org.onap.cps</groupId> <artifactId>checkstyle</artifactId> - <version>3.3.0-SNAPSHOT</version> + <version>3.3.1-SNAPSHOT</version> <profiles> <profile> diff --git a/cps-application/pom.xml b/cps-application/pom.xml index 4c46e462a1..5d3fbf8739 100755 --- a/cps-application/pom.xml +++ b/cps-application/pom.xml @@ -3,7 +3,7 @@ ============LICENSE_START======================================================= Copyright (c) 2021 Pantheon.tech. Modifications Copyright (C) 2021 Bell Canada. - Modifications Copyright (C) 2021 Nordix Foundation + Modifications Copyright (C) 2021-2023 Nordix Foundation Modifications Copyright (C) 2022 Deutsche Telekom AG ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,7 +28,7 @@ <parent> <groupId>org.onap.cps</groupId> <artifactId>cps-parent</artifactId> - <version>3.3.0-SNAPSHOT</version> + <version>3.3.1-SNAPSHOT</version> <relativePath>../cps-parent/pom.xml</relativePath> </parent> diff --git a/cps-bom/pom.xml b/cps-bom/pom.xml index c9af839557..9f9c274111 100644 --- a/cps-bom/pom.xml +++ b/cps-bom/pom.xml @@ -2,7 +2,7 @@ <!-- ============LICENSE_START======================================================= Copyright (C) 2020 Pantheon.tech - Modifications Copyright (C) 2021-2022 Nordix Foundation + Modifications Copyright (C) 2021-2023 Nordix Foundation Modifications Copyright (C) 2021 Bell Canada. ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,7 +25,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>org.onap.cps</groupId> <artifactId>cps-bom</artifactId> - <version>3.3.0-SNAPSHOT</version> + <version>3.3.1-SNAPSHOT</version> <packaging>pom</packaging> <description>This artifact contains dependencyManagement declarations of all published CPS components.</description> diff --git a/cps-dependencies/pom.xml b/cps-dependencies/pom.xml index 770a66ad5a..6f8595b693 100755 --- a/cps-dependencies/pom.xml +++ b/cps-dependencies/pom.xml @@ -2,7 +2,7 @@ <!-- ============LICENSE_START======================================================= Copyright (c) 2021 Linux Foundation. - Modifications Copyright (C) 2020-2022 Nordix Foundation + Modifications Copyright (C) 2020-2023 Nordix Foundation Modifications Copyright (C) 2022 Bell Canada. ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,7 +27,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>org.onap.cps</groupId> <artifactId>cps-dependencies</artifactId> - <version>3.3.0-SNAPSHOT</version> + <version>3.3.1-SNAPSHOT</version> <packaging>pom</packaging> <name>${project.groupId}:${project.artifactId}</name> @@ -71,9 +71,14 @@ <dependencyManagement> <dependencies> <dependency> + <groupId>org.springdoc</groupId> + <artifactId>springdoc-openapi-ui</artifactId> + <version>1.6.6</version> + </dependency> + <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> - <version>2.6.14</version> + <version>2.7.6</version> <type>pom</type> <scope>import</scope> </dependency> @@ -107,9 +112,9 @@ <version>2.8.9</version> </dependency> <dependency> - <groupId>com.vladmihalcea</groupId> - <artifactId>hibernate-types-52</artifactId> - <version>2.10.0</version> + <groupId>io.hypersistence</groupId> + <artifactId>hypersistence-utils-hibernate-52</artifactId> + <version>3.3.2</version> </dependency> <dependency> <groupId>org.antlr</groupId> @@ -174,7 +179,7 @@ <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> - <version>4.14.0</version> + <version>4.16.0</version> </dependency> <dependency> <groupId>com.tngtech.archunit</groupId> diff --git a/cps-events/pom.xml b/cps-events/pom.xml index be0f4a73ff..23060f6262 100644 --- a/cps-events/pom.xml +++ b/cps-events/pom.xml @@ -24,7 +24,7 @@ <parent> <groupId>org.onap.cps</groupId> <artifactId>cps-parent</artifactId> - <version>3.3.0-SNAPSHOT</version> + <version>3.3.1-SNAPSHOT</version> <relativePath>../cps-parent/pom.xml</relativePath> </parent> diff --git a/cps-ncmp-events/pom.xml b/cps-ncmp-events/pom.xml index 494e12631e..c2122fbfd5 100644 --- a/cps-ncmp-events/pom.xml +++ b/cps-ncmp-events/pom.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- ============LICENSE_START======================================================= - Copyright (c) 2022 Nordix Foundation. + 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,7 @@ <parent> <groupId>org.onap.cps</groupId> <artifactId>cps-parent</artifactId> - <version>3.3.0-SNAPSHOT</version> + <version>3.3.1-SNAPSHOT</version> <relativePath>../cps-parent/pom.xml</relativePath> </parent> diff --git a/cps-ncmp-rest-stub/pom.xml b/cps-ncmp-rest-stub/pom.xml index af289cbaab..60069f2060 100644 --- a/cps-ncmp-rest-stub/pom.xml +++ b/cps-ncmp-rest-stub/pom.xml @@ -26,7 +26,7 @@ <parent> <groupId>org.onap.cps</groupId> <artifactId>cps-parent</artifactId> - <version>3.3.0-SNAPSHOT</version> + <version>3.3.1-SNAPSHOT</version> <relativePath>../cps-parent/pom.xml</relativePath> </parent> diff --git a/cps-ncmp-rest/pom.xml b/cps-ncmp-rest/pom.xml index ecf66fc2cb..7c5ebeed47 100644 --- a/cps-ncmp-rest/pom.xml +++ b/cps-ncmp-rest/pom.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- ============LICENSE_START======================================================= - Copyright (C) 2021-2022 Nordix Foundation + Copyright (C) 2021-2023 Nordix Foundation Modifications Copyright (C) 2021 Bell Canada ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,7 +27,7 @@ <parent> <groupId>org.onap.cps</groupId> <artifactId>cps-parent</artifactId> - <version>3.3.0-SNAPSHOT</version> + <version>3.3.1-SNAPSHOT</version> <relativePath>../cps-parent/pom.xml</relativePath> </parent> diff --git a/cps-ncmp-service/pom.xml b/cps-ncmp-service/pom.xml index 07ce152a4e..b027a2bd98 100644 --- a/cps-ncmp-service/pom.xml +++ b/cps-ncmp-service/pom.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- ============LICENSE_START======================================================= - Copyright (C) 2021-2022 Nordix Foundation + Copyright (C) 2021-2023 Nordix Foundation Modifications Copyright (C) 2021 Pantheon.tech Modifications Copyright (C) 2022 Bell Canada ================================================================================ @@ -27,7 +27,7 @@ <parent> <groupId>org.onap.cps</groupId> <artifactId>cps-parent</artifactId> - <version>3.3.0-SNAPSHOT</version> + <version>3.3.1-SNAPSHOT</version> <relativePath>../cps-parent/pom.xml</relativePath> </parent> diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java index d3a4f530f1..b3904bd0bb 100755 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java @@ -44,7 +44,7 @@ import lombok.extern.slf4j.Slf4j; import org.onap.cps.api.CpsDataService; import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService; import org.onap.cps.ncmp.api.NetworkCmProxyDataService; -import org.onap.cps.ncmp.api.impl.event.lcm.LcmEventsCmHandleStateHandler; +import org.onap.cps.ncmp.api.impl.events.lcm.LcmEventsCmHandleStateHandler; import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations; import org.onap.cps.ncmp.api.impl.operations.DmiOperations; import org.onap.cps.ncmp.api.impl.utils.CmHandleQueryConditions; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventConsumer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventConsumer.java index bc6624dee6..0ac0fb92de 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventConsumer.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventConsumer.java @@ -22,6 +22,7 @@ package org.onap.cps.ncmp.api.impl.async; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.onap.cps.ncmp.api.impl.events.EventsPublisher; import org.onap.cps.ncmp.event.model.DmiAsyncRequestResponseEvent; import org.onap.cps.ncmp.event.model.NcmpAsyncRequestResponseEvent; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -37,7 +38,7 @@ import org.springframework.stereotype.Component; @ConditionalOnProperty(name = "notification.enabled", havingValue = "true", matchIfMissing = true) public class NcmpAsyncRequestResponseEventConsumer { - private final NcmpAsyncRequestResponseEventProducer ncmpAsyncRequestResponseEventProducer; + private final EventsPublisher<NcmpAsyncRequestResponseEvent> eventsPublisher; private final NcmpAsyncRequestResponseEventMapper ncmpAsyncRequestResponseEventMapper; /** @@ -53,7 +54,7 @@ public class NcmpAsyncRequestResponseEventConsumer { final NcmpAsyncRequestResponseEvent ncmpAsyncRequestResponseEvent = ncmpAsyncRequestResponseEventMapper.toNcmpAsyncEvent(dmiAsyncRequestResponseEvent); - ncmpAsyncRequestResponseEventProducer.sendMessage( + eventsPublisher.publishEvent(ncmpAsyncRequestResponseEvent.getEventTarget(), ncmpAsyncRequestResponseEvent.getEventId(), ncmpAsyncRequestResponseEvent); } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventProducer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventProducer.java deleted file mode 100644 index 8ab6db9045..0000000000 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventProducer.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022 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.ncmp.api.impl.async; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.event.model.NcmpAsyncRequestResponseEvent; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.stereotype.Service; - -@Slf4j -@Service -@RequiredArgsConstructor -public class NcmpAsyncRequestResponseEventProducer { - - private final KafkaTemplate<String, NcmpAsyncRequestResponseEvent> kafkaTemplate; - - - /** - * Sends message to the configured topic with a message key. - * - * @param eventId message key - * @param ncmpAsyncRequestResponseEvent message payload - */ - public void sendMessage(final String eventId, final NcmpAsyncRequestResponseEvent ncmpAsyncRequestResponseEvent) { - kafkaTemplate.send(ncmpAsyncRequestResponseEvent.getEventTarget(), eventId, ncmpAsyncRequestResponseEvent); - } -} diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/EventsPublisher.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/EventsPublisher.java index 60d39db7a2..ec344bbaee 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/EventsPublisher.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/EventsPublisher.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation + * 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. @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.event; +package org.onap.cps.ncmp.api.impl.events; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/notifications/avc/AvcEventConsumer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avc/AvcEventConsumer.java index 58290a7e9d..83ad5e5704 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/notifications/avc/AvcEventConsumer.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avc/AvcEventConsumer.java @@ -18,11 +18,13 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.notifications.avc; +package org.onap.cps.ncmp.api.impl.events.avc; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.onap.cps.ncmp.api.impl.events.EventsPublisher; import org.onap.cps.ncmp.event.model.AvcEvent; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.kafka.annotation.KafkaListener; import org.springframework.stereotype.Component; @@ -36,7 +38,13 @@ import org.springframework.stereotype.Component; @ConditionalOnProperty(name = "notification.enabled", havingValue = "true", matchIfMissing = true) public class AvcEventConsumer { - private final AvcEventProducer avcEventProducer; + + @Value("${app.ncmp.avc.cm-events-topic}") + private String cmEventsTopicName; + + private final EventsPublisher<AvcEvent> eventsPublisher; + private final AvcEventMapper avcEventMapper; + /** * Consume the specified event. @@ -48,6 +56,7 @@ public class AvcEventConsumer { properties = {"spring.json.value.default.type=org.onap.cps.ncmp.event.model.AvcEvent"}) public void consumeAndForward(final AvcEvent avcEvent) { log.debug("Consuming AVC event {} ...", avcEvent); - avcEventProducer.sendMessage(avcEvent); + final AvcEvent outgoingAvcEvent = avcEventMapper.toOutgoingAvcEvent(avcEvent); + eventsPublisher.publishEvent(cmEventsTopicName, outgoingAvcEvent.getEventId(), outgoingAvcEvent); } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/notifications/avc/AvcEventMapper.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avc/AvcEventMapper.java index adbf08fa27..113da0deb9 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/notifications/avc/AvcEventMapper.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avc/AvcEventMapper.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.notifications.avc; +package org.onap.cps.ncmp.api.impl.events.avc; import java.util.UUID; import org.mapstruct.Mapper; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/avc/SubscriptionEventConsumer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventConsumer.java index 2685ce4ca9..7717db67a6 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/avc/SubscriptionEventConsumer.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventConsumer.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.event.avc; +package org.onap.cps.ncmp.api.impl.events.avcsubscription; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/avc/SubscriptionEventForwarder.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarder.java index 635059bfe1..c3624b8005 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/avc/SubscriptionEventForwarder.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarder.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.event.avc; +package org.onap.cps.ncmp.api.impl.events.avcsubscription; import java.util.Collection; import java.util.Collections; @@ -29,7 +29,7 @@ import java.util.Objects; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.api.impl.event.EventsPublisher; +import org.onap.cps.ncmp.api.impl.events.EventsPublisher; import org.onap.cps.ncmp.api.impl.operations.RequiredDmiService; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; import org.onap.cps.ncmp.api.inventory.InventoryPersistence; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/avc/SubscriptionEventMapper.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventMapper.java index 44f9abb08e..3c238dda28 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/avc/SubscriptionEventMapper.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventMapper.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.event.avc; +package org.onap.cps.ncmp.api.impl.events.avcsubscription; import java.util.List; import java.util.stream.Collectors; @@ -33,7 +33,7 @@ public interface SubscriptionEventMapper { @Mapping(source = "event.subscription.clientID", target = "clientId") @Mapping(source = "event.subscription.name", target = "subscriptionName") - @Mapping(source = "event.subscription.isTagged", target = "tagged", qualifiedByName = "mapIsTagged") + @Mapping(source = "event.subscription.isTagged", target = "tagged") @Mapping(source = "event.predicates.targets", target = "predicates.targetCmHandles", qualifiedByName = "mapTargetsToCmHandleTargets") @Mapping(source = "event.predicates.datastore", target = "predicates.datastore") @@ -44,9 +44,4 @@ public interface SubscriptionEventMapper { return targets.stream().map( target -> new YangModelSubscriptionEvent.TargetCmHandle(target.toString())).collect(Collectors.toList()); } - - @Named("mapIsTagged") - default boolean mapIsTagged(Boolean isTagged) { - return (isTagged == null) ? false : isTagged; - } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventType.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventType.java index f793dedb8d..a8d00f7e31 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventType.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventType.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation + * 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. @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.event.lcm; +package org.onap.cps.ncmp.api.impl.events.lcm; public enum LcmEventType { diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandler.java index 5ff2afa5e1..18bdcbeaa4 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandler.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandler.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation + * 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. @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.event.lcm; +package org.onap.cps.ncmp.api.impl.events.lcm; import java.util.Map; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandlerImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerImpl.java index 6485fdf76b..9d518432ad 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandlerImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerImpl.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.event.lcm; +package org.onap.cps.ncmp.api.impl.events.lcm; import static org.onap.cps.ncmp.api.inventory.CmHandleState.ADVISED; import static org.onap.cps.ncmp.api.inventory.CmHandleState.DELETED; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCreator.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreator.java index aef1ed9bd0..a72e664dcf 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCreator.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreator.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation + * 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. @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.event.lcm; +package org.onap.cps.ncmp.api.impl.events.lcm; import java.util.UUID; import lombok.Getter; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCreatorHelper.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreatorHelper.java index 40f70b9c68..1322b7277f 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCreatorHelper.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreatorHelper.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation + * 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. @@ -18,11 +18,11 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.event.lcm; +package org.onap.cps.ncmp.api.impl.events.lcm; -import static org.onap.cps.ncmp.api.impl.event.lcm.LcmEventType.CREATE; -import static org.onap.cps.ncmp.api.impl.event.lcm.LcmEventType.DELETE; -import static org.onap.cps.ncmp.api.impl.event.lcm.LcmEventType.UPDATE; +import static org.onap.cps.ncmp.api.impl.events.lcm.LcmEventType.CREATE; +import static org.onap.cps.ncmp.api.impl.events.lcm.LcmEventType.DELETE; +import static org.onap.cps.ncmp.api.impl.events.lcm.LcmEventType.UPDATE; import static org.onap.cps.ncmp.api.inventory.CmHandleState.DELETED; import com.google.common.collect.MapDifference; @@ -177,10 +177,8 @@ public class LcmEventsCreatorHelper { private static boolean hasDataSyncEnabledFlagChanged(final NcmpServiceCmHandle targetNcmpServiceCmHandle, final NcmpServiceCmHandle existingNcmpServiceCmHandle) { - final Boolean targetDataSyncFlag = targetNcmpServiceCmHandle.getCompositeState() == null - ? null : targetNcmpServiceCmHandle.getCompositeState().getDataSyncEnabled(); - final Boolean existingDataSyncFlag = existingNcmpServiceCmHandle.getCompositeState() == null - ? null : existingNcmpServiceCmHandle.getCompositeState().getDataSyncEnabled(); + final Boolean targetDataSyncFlag = targetNcmpServiceCmHandle.getCompositeState().getDataSyncEnabled(); + final Boolean existingDataSyncFlag = existingNcmpServiceCmHandle.getCompositeState().getDataSyncEnabled(); if (targetDataSyncFlag == null) { return existingDataSyncFlag != null; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsService.java index 2eba83053b..f258b45976 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsService.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsService.java @@ -18,12 +18,12 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.event.lcm; +package org.onap.cps.ncmp.api.impl.events.lcm; import io.micrometer.core.annotation.Timed; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.api.impl.event.EventsPublisher; +import org.onap.cps.ncmp.api.impl.events.EventsPublisher; import org.onap.ncmp.cmhandle.event.lcm.LcmEvent; import org.springframework.beans.factory.annotation.Value; import org.springframework.kafka.KafkaException; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/notifications/avc/AvcEventProducer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/notifications/avc/AvcEventProducer.java deleted file mode 100644 index b8fe730a16..0000000000 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/notifications/avc/AvcEventProducer.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * ============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.ncmp.api.impl.notifications.avc; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.event.model.AvcEvent; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.stereotype.Service; - -/** - * Producer for AVC events. - */ -@Slf4j -@Service -@RequiredArgsConstructor -public class AvcEventProducer { - - private final KafkaTemplate<String, AvcEvent> kafkaTemplate; - - private final AvcEventMapper avcEventMapper; - - @Value("${app.ncmp.avc.cm-events-topic}") - private String cmEventsTopic; - - /** - * Sends message to the configured topic with a message key. - * - * @param incomingAvcEvent message payload - */ - public void sendMessage(final AvcEvent incomingAvcEvent) { - // generate new event id while keeping other data - final AvcEvent outgoingAvcEvent = avcEventMapper.toOutgoingAvcEvent(incomingAvcEvent); - log.debug("Forwarding AVC event {} to topic {} ", outgoingAvcEvent.getEventId(), cmEventsTopic); - kafkaTemplate.send(cmEventsTopic, outgoingAvcEvent.getEventId(), outgoingAvcEvent); - } -} diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncTasks.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncTasks.java index d778afc3e8..914b626e33 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncTasks.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncTasks.java @@ -29,7 +29,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicInteger; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.api.impl.event.lcm.LcmEventsCmHandleStateHandler; +import org.onap.cps.ncmp.api.impl.events.lcm.LcmEventsCmHandleStateHandler; import org.onap.cps.ncmp.api.impl.utils.YangDataConverter; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; import org.onap.cps.ncmp.api.inventory.CmHandleState; diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy index f12969def6..bd63813e79 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy @@ -26,7 +26,7 @@ import com.hazelcast.map.IMap import org.onap.cps.api.CpsDataService import org.onap.cps.api.CpsModuleService import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService -import org.onap.cps.ncmp.api.impl.event.lcm.LcmEventsCmHandleStateHandler +import org.onap.cps.ncmp.api.impl.events.lcm.LcmEventsCmHandleStateHandler import org.onap.cps.ncmp.api.impl.exception.DmiRequestException import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy index 4acd249e61..871af842ea 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy @@ -25,7 +25,7 @@ package org.onap.cps.ncmp.api.impl import com.hazelcast.map.IMap import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService -import org.onap.cps.ncmp.api.impl.event.lcm.LcmEventsCmHandleStateHandler +import org.onap.cps.ncmp.api.impl.events.lcm.LcmEventsCmHandleStateHandler import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle import org.onap.cps.ncmp.api.inventory.CmHandleQueries import org.onap.cps.ncmp.api.inventory.CmHandleState diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/async/CpsAsyncRequestResponseEventIntegrationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/async/CpsAsyncRequestResponseEventIntegrationSpec.groovy index 51162c74e0..bcf75a29b2 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/async/CpsAsyncRequestResponseEventIntegrationSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/async/CpsAsyncRequestResponseEventIntegrationSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (c) 2022 Nordix Foundation. + * 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,6 +23,7 @@ package org.onap.cps.ncmp.api.impl.async import com.fasterxml.jackson.databind.ObjectMapper import org.apache.kafka.clients.consumer.KafkaConsumer import org.mapstruct.factory.Mappers +import org.onap.cps.ncmp.api.impl.events.EventsPublisher import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec import org.onap.cps.ncmp.event.model.DmiAsyncRequestResponseEvent import org.onap.cps.ncmp.event.model.NcmpAsyncRequestResponseEvent @@ -36,14 +37,15 @@ import org.testcontainers.spock.Testcontainers import java.time.Duration -@SpringBootTest(classes = [NcmpAsyncRequestResponseEventProducer, NcmpAsyncRequestResponseEventConsumer, ObjectMapper, JsonObjectMapper]) +@SpringBootTest(classes = [EventsPublisher, NcmpAsyncRequestResponseEventConsumer, ObjectMapper, JsonObjectMapper]) @Testcontainers @DirtiesContext class NcmpAsyncRequestResponseEventProducerIntegrationSpec extends MessagingBaseSpec { @SpringBean - NcmpAsyncRequestResponseEventProducer cpsAsyncRequestResponseEventProducerService = - new NcmpAsyncRequestResponseEventProducer(kafkaTemplate); + EventsPublisher cpsAsyncRequestResponseEventPublisher = + new EventsPublisher<NcmpAsyncRequestResponseEvent>(kafkaTemplate); + @SpringBean NcmpAsyncRequestResponseEventMapper ncmpAsyncRequestResponseEventMapper = @@ -51,7 +53,7 @@ class NcmpAsyncRequestResponseEventProducerIntegrationSpec extends MessagingBase @SpringBean NcmpAsyncRequestResponseEventConsumer ncmpAsyncRequestResponseEventConsumer = - new NcmpAsyncRequestResponseEventConsumer(cpsAsyncRequestResponseEventProducerService, + new NcmpAsyncRequestResponseEventConsumer(cpsAsyncRequestResponseEventPublisher, ncmpAsyncRequestResponseEventMapper) @Autowired diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/notifications/avc/AvcEventProducerIntegrationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avc/AvcEventConsumerSpec.groovy index a251ecbf0b..d57527a454 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/notifications/avc/AvcEventProducerIntegrationSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avc/AvcEventConsumerSpec.groovy @@ -18,12 +18,12 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.notifications.avc +package org.onap.cps.ncmp.api.impl.events.avc import com.fasterxml.jackson.databind.ObjectMapper import org.apache.kafka.clients.consumer.KafkaConsumer import org.mapstruct.factory.Mappers -import org.onap.cps.ncmp.api.impl.async.NcmpAsyncRequestResponseEventMapper +import org.onap.cps.ncmp.api.impl.events.EventsPublisher import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec import org.onap.cps.ncmp.event.model.AvcEvent import org.onap.cps.ncmp.utils.TestUtils @@ -36,19 +36,19 @@ import org.testcontainers.spock.Testcontainers import java.time.Duration -@SpringBootTest(classes = [AvcEventProducer, AvcEventConsumer, ObjectMapper, JsonObjectMapper]) +@SpringBootTest(classes = [EventsPublisher, AvcEventConsumer, ObjectMapper, JsonObjectMapper]) @Testcontainers @DirtiesContext -class AvcEventProducerIntegrationSpec extends MessagingBaseSpec { +class AvcEventConsumerSpec extends MessagingBaseSpec { @SpringBean AvcEventMapper avcEventMapper = Mappers.getMapper(AvcEventMapper.class) @SpringBean - AvcEventProducer avcEventProducer = new AvcEventProducer(kafkaTemplate, avcEventMapper) + EventsPublisher eventsPublisher = new EventsPublisher<AvcEvent>(kafkaTemplate) @SpringBean - AvcEventConsumer acvEventConsumer = new AvcEventConsumer(avcEventProducer) + AvcEventConsumer acvEventConsumer = new AvcEventConsumer(eventsPublisher, avcEventMapper) @Autowired JsonObjectMapper jsonObjectMapper @@ -57,9 +57,9 @@ class AvcEventProducerIntegrationSpec extends MessagingBaseSpec { def 'Consume and forward valid message'() { given: 'consumer has a subscription on a topic' - def cmEventsTopic = 'cm-events' - avcEventProducer.cmEventsTopic = cmEventsTopic - kafkaConsumer.subscribe([cmEventsTopic] as List<String>) + def cmEventsTopicName = 'cm-events' + acvEventConsumer.cmEventsTopicName = cmEventsTopicName + kafkaConsumer.subscribe([cmEventsTopicName] as List<String>) and: 'an event is sent' def jsonData = TestUtils.getResourceFileContent('sampleAvcInputEvent.json') def testEventSent = jsonObjectMapper.convertJsonString(jsonData, AvcEvent.class) diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/notifications/avc/SubscriptionCreateProducerDemo.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avc/SubscriptionCreateProducerDemo.groovy index 0b13cfd8ea..54a7ad3331 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/notifications/avc/SubscriptionCreateProducerDemo.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avc/SubscriptionCreateProducerDemo.groovy @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.notifications.avc +package org.onap.cps.ncmp.api.impl.events.avc import com.fasterxml.jackson.databind.ObjectMapper import org.onap.cps.ncmp.event.model.SubscriptionEvent diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/notifications/avc/SubscriptionEventMapperSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avc/SubscriptionEventMapperSpec.groovy index 93346303a8..3a7aa481c3 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/notifications/avc/SubscriptionEventMapperSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avc/SubscriptionEventMapperSpec.groovy @@ -18,11 +18,11 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.notifications.avc +package org.onap.cps.ncmp.api.impl.events.avc import com.fasterxml.jackson.databind.ObjectMapper import org.mapstruct.factory.Mappers -import org.onap.cps.ncmp.api.impl.event.avc.SubscriptionEventMapper +import org.onap.cps.ncmp.api.impl.events.avcsubscription.SubscriptionEventMapper import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus import org.onap.cps.ncmp.event.model.SubscriptionEvent import org.onap.cps.ncmp.utils.TestUtils diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/avc/SubscriptionEventConsumerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventConsumerSpec.groovy index d801e4ddf7..243c31b39b 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/avc/SubscriptionEventConsumerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventConsumerSpec.groovy @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.event.avc +package org.onap.cps.ncmp.api.impl.events.avcsubscription import com.fasterxml.jackson.databind.ObjectMapper import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistence diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/avc/SubscriptionEventForwarderSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarderSpec.groovy index f9e801ddbb..2b0adf3420 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/avc/SubscriptionEventForwarderSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarderSpec.groovy @@ -18,10 +18,10 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.event.avc +package org.onap.cps.ncmp.api.impl.events.avcsubscription import com.fasterxml.jackson.databind.ObjectMapper -import org.onap.cps.ncmp.api.impl.event.EventsPublisher +import org.onap.cps.ncmp.api.impl.events.EventsPublisher import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle import org.onap.cps.ncmp.api.inventory.InventoryPersistence import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec @@ -31,8 +31,6 @@ import org.onap.cps.spi.exceptions.OperationNotYetSupportedException import org.onap.cps.utils.JsonObjectMapper import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest -import org.springframework.kafka.core.KafkaTemplate -import org.springframework.util.concurrent.ListenableFuture; @SpringBootTest(classes = [ObjectMapper, JsonObjectMapper]) class SubscriptionEventForwarderSpec extends MessagingBaseSpec { diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandlerImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerImplSpec.groovy index ddede66393..f660be7103 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandlerImplSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerImplSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation + * 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. @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.event.lcm +package org.onap.cps.ncmp.api.impl.events.lcm import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle import org.onap.cps.ncmp.api.inventory.CompositeState diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCreatorSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreatorSpec.groovy index 18041fa6a5..f4adfc587c 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCreatorSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreatorSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation + * 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. @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.event.lcm +package org.onap.cps.ncmp.api.impl.events.lcm import org.onap.cps.ncmp.api.inventory.CmHandleState import org.onap.cps.ncmp.api.inventory.CompositeState @@ -36,11 +36,11 @@ class LcmEventsCreatorSpec extends Specification { def cmHandleId = 'test-cm-handle' def 'Map the LcmEvent for #operation'() { - given: 'NCMP cm handle details with current and old details' + given: 'NCMP cm handle details with current and old properties' def existingNcmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: cmHandleId, compositeState: new CompositeState(dataSyncEnabled: true, cmHandleState: existingCmHandleState), - publicProperties: ['publicProperty1': 'value1', 'publicProperty2': 'value2', 'publicProperty3': 'value3']) - def targetNcmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: cmHandleId, compositeState: new CompositeState(dataSyncEnabled: false, cmHandleState: targetCmHandleState), - publicProperties: ['publicProperty1': 'value1', 'publicProperty2': 'value22']) + publicProperties: existingPublicProperties) + def targetNcmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: cmHandleId, compositeState: new CompositeState(dataSyncEnabled: true, cmHandleState: targetCmHandleState), + publicProperties: targetPublicProperties) when: 'the event is populated' def result = objectUnderTest.populateLcmEvent(cmHandleId, targetNcmpServiceCmHandle, existingNcmpServiceCmHandle) then: 'event header is mapped correctly' @@ -49,21 +49,31 @@ class LcmEventsCreatorSpec extends Specification { assert result.eventType == LcmEventType.UPDATE.eventType and: 'event payload is mapped correctly with correct cmhandle id' assert result.event.cmHandleId == cmHandleId - and: 'it should have correct old values' + and: 'it should have correct old state and properties' assert result.event.oldValues.cmHandleState == expectedExistingCmHandleState - assert result.event.oldValues.dataSyncEnabled == true - and: 'the correct new values' + assert result.event.oldValues.cmHandleProperties == [expectedExistingPublicProperties] + and: 'the correct new state and properties' + assert result.event.newValues.cmHandleProperties == [expectedTargetPublicProperties] assert result.event.newValues.cmHandleState == expectedTargetCmHandleState - assert result.event.newValues.dataSyncEnabled == false - and: 'cmhandle properties are just the one which are differing' - assert result.event.oldValues.cmHandleProperties == [['publicProperty2': 'value2', 'publicProperty3': 'value3']] - assert result.event.newValues.cmHandleProperties == [['publicProperty2': 'value22']] where: 'following parameters are provided' - operation | existingCmHandleState | targetCmHandleState || expectedExistingCmHandleState | expectedTargetCmHandleState - 'UPDATE' | ADVISED | READY || Values.CmHandleState.ADVISED | Values.CmHandleState.READY - 'DELETING' | READY | DELETING || Values.CmHandleState.READY | Values.CmHandleState.DELETING - + operation | existingCmHandleState | targetCmHandleState | existingPublicProperties | targetPublicProperties || expectedExistingPublicProperties | expectedTargetPublicProperties | expectedExistingCmHandleState | expectedTargetCmHandleState + 'UPDATE' | ADVISED | READY | ['publicProperty1': 'value1', 'publicProperty2': 'value2'] | ['publicProperty1': 'value11'] || ['publicProperty1': 'value1', 'publicProperty2': 'value2'] | ['publicProperty1': 'value11'] | Values.CmHandleState.ADVISED | Values.CmHandleState.READY + 'DELETING' | READY | DELETING | ['publicProperty1': 'value3', 'publicProperty2': 'value4'] | ['publicProperty1': 'value33'] || ['publicProperty1': 'value3', 'publicProperty2': 'value4'] | ['publicProperty1': 'value33'] | Values.CmHandleState.READY | Values.CmHandleState.DELETING + 'CHANGE' | READY | READY | ['publicProperty1': 'value3', 'publicProperty2': 'value4'] | ['publicProperty1': 'value33'] || ['publicProperty1': 'value3', 'publicProperty2': 'value4'] | ['publicProperty1': 'value33'] | null | null + } + def 'Map the LcmEvent for all properties NO CHANGE'() { + given: 'NCMP cm handle details without any changes' + def publicProperties = ['publicProperty1': 'value3', 'publicProperty2': 'value4'] + def existingNcmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: cmHandleId, compositeState: new CompositeState(dataSyncEnabled: true, cmHandleState: READY), + publicProperties: publicProperties) + def targetNcmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: cmHandleId, compositeState: new CompositeState(dataSyncEnabled: true, cmHandleState: READY), + publicProperties: publicProperties) + when: 'the event is populated' + def result = objectUnderTest.populateLcmEvent(cmHandleId, targetNcmpServiceCmHandle, existingNcmpServiceCmHandle) + then: 'Properties are just the one which are same' + assert result.event.oldValues == null + assert result.event.newValues == null } def 'Map the LcmEvent for operation CREATE'() { diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsPublisherSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsPublisherSpec.groovy index f5b58a7536..7c9464dccb 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsPublisherSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsPublisherSpec.groovy @@ -18,11 +18,11 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.event.lcm +package org.onap.cps.ncmp.api.impl.events.lcm import com.fasterxml.jackson.databind.ObjectMapper import org.apache.kafka.clients.consumer.KafkaConsumer -import org.onap.cps.ncmp.api.impl.event.EventsPublisher +import org.onap.cps.ncmp.api.impl.events.EventsPublisher import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec import org.onap.cps.ncmp.utils.TestUtils import org.onap.cps.utils.JsonObjectMapper diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsServiceSpec.groovy index 4c632ddf04..65f4d50c68 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsServiceSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsServiceSpec.groovy @@ -18,9 +18,9 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.event.lcm +package org.onap.cps.ncmp.api.impl.events.lcm -import org.onap.cps.ncmp.api.impl.event.EventsPublisher +import org.onap.cps.ncmp.api.impl.events.EventsPublisher import org.onap.ncmp.cmhandle.event.lcm.LcmEvent import org.springframework.kafka.KafkaException import spock.lang.Specification diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncTasksSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncTasksSpec.groovy index 3deab112aa..382d5da4e3 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncTasksSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncTasksSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation + * Copyright (C) 2022-2023 Nordix Foundation * Modifications Copyright (C) 2022 Bell Canada * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,7 +24,7 @@ package org.onap.cps.ncmp.api.inventory.sync import com.hazelcast.config.Config import com.hazelcast.instance.impl.HazelcastInstanceFactory import com.hazelcast.map.IMap -import org.onap.cps.ncmp.api.impl.event.lcm.LcmEventsCmHandleStateHandler +import org.onap.cps.ncmp.api.impl.events.lcm.LcmEventsCmHandleStateHandler import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle import org.onap.cps.ncmp.api.inventory.CmHandleState import org.onap.cps.ncmp.api.inventory.CompositeState diff --git a/cps-parent/pom.xml b/cps-parent/pom.xml index 829ab04b68..9c229aa8cd 100755 --- a/cps-parent/pom.xml +++ b/cps-parent/pom.xml @@ -3,7 +3,7 @@ ============LICENSE_START======================================================= Copyright (c) 2021 Pantheon.tech. Modifications Copyright (C) 2021 Bell Canada. - Modifications Copyright (C) 2021-2022 Nordix Foundation. + Modifications Copyright (C) 2021-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. @@ -32,7 +32,7 @@ <groupId>org.onap.cps</groupId> <artifactId>cps-parent</artifactId> - <version>3.3.0-SNAPSHOT</version> + <version>3.3.1-SNAPSHOT</version> <packaging>pom</packaging> <properties> @@ -303,7 +303,7 @@ <dependency> <groupId>org.onap.oparent</groupId> <artifactId>checkstyle</artifactId> - <version>3.1.0</version> + <version>3.2.0</version> </dependency> <dependency> <groupId>${project.groupId}</groupId> diff --git a/cps-path-parser/pom.xml b/cps-path-parser/pom.xml index 5b861f76d6..25ef84c186 100644 --- a/cps-path-parser/pom.xml +++ b/cps-path-parser/pom.xml @@ -23,7 +23,7 @@ <parent> <groupId>org.onap.cps</groupId> <artifactId>cps-parent</artifactId> - <version>3.3.0-SNAPSHOT</version> + <version>3.3.1-SNAPSHOT</version> <relativePath>../cps-parent/pom.xml</relativePath> </parent> diff --git a/cps-path-parser/src/main/antlr4/org/onap/cps/cpspath/parser/antlr4/CpsPath.g4 b/cps-path-parser/src/main/antlr4/org/onap/cps/cpspath/parser/antlr4/CpsPath.g4 index db09b3c532..d4718111f6 100644 --- a/cps-path-parser/src/main/antlr4/org/onap/cps/cpspath/parser/antlr4/CpsPath.g4 +++ b/cps-path-parser/src/main/antlr4/org/onap/cps/cpspath/parser/antlr4/CpsPath.g4 @@ -1,6 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2021-2022 Nordix Foundation + * Modifications Copyright (C) 2023 TechMahindra Ltd * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,14 +41,16 @@ yangElement : containerName listElementRef? ; containerName : QName ; -listElementRef : OB leafCondition ( KW_AND leafCondition)* CB ; +listElementRef : OB leafCondition ( booleanOperators leafCondition)* CB ; -multipleLeafConditions : OB leafCondition ( KW_AND leafCondition)* CB ; +multipleLeafConditions : OB leafCondition ( booleanOperators leafCondition)* CB ; leafCondition : AT leafName EQ ( IntegerLiteral | StringLiteral) ; leafName : QName ; +booleanOperators : ( KW_AND | KW_OR ) ; + invalidPostFix : (AT | CB | COLONCOLON | EQ ).+ ; /* @@ -68,6 +71,7 @@ SLASH : '/' ; KW_ANCESTOR : 'ancestor' ; KW_AND : 'and' ; KW_TEXT_FUNCTION: 'text()' ; +KW_OR : 'or' ; IntegerLiteral : FragDigits ; // Add below type definitions for leafvalue comparision in https://jira.onap.org/browse/CPS-440 diff --git a/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathBooleanOperatorType.java b/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathBooleanOperatorType.java new file mode 100644 index 0000000000..b2f1dddb19 --- /dev/null +++ b/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathBooleanOperatorType.java @@ -0,0 +1,51 @@ +/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 TechMahindra Ltd
+ * ================================================================================
+ * 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.cpspath.parser;
+
+public enum CpsPathBooleanOperatorType {
+ AND("and"),
+ OR("or");
+
+ private final String operatorValue;
+
+ CpsPathBooleanOperatorType(final String operatorValue) {
+ this.operatorValue = operatorValue;
+ }
+
+ public String getValues() {
+ return this.operatorValue;
+ }
+
+ /**
+ * Finds the value of the given enumeration.
+ *
+ * @param operatorValue value of the enum
+ * @return a booleanOperatorType
+ */
+ public static CpsPathBooleanOperatorType fromString(final String operatorValue) {
+ for (final CpsPathBooleanOperatorType booleanOperatorType : CpsPathBooleanOperatorType.values()) {
+ if (booleanOperatorType.operatorValue.equalsIgnoreCase(operatorValue)) {
+ return booleanOperatorType;
+ }
+ }
+ return null;
+ }
+}
diff --git a/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathBuilder.java b/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathBuilder.java index 3a9d70ebbc..4299d13081 100644 --- a/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathBuilder.java +++ b/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathBuilder.java @@ -1,6 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2021-2022 Nordix Foundation + * Modifications Copyright (C) 2023 TechMahindra Ltd * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,8 +25,10 @@ import static org.onap.cps.cpspath.parser.CpsPathPrefixType.DESCENDANT; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Queue; import org.onap.cps.cpspath.parser.antlr4.CpsPathBaseListener; import org.onap.cps.cpspath.parser.antlr4.CpsPathParser; import org.onap.cps.cpspath.parser.antlr4.CpsPathParser.AncestorAxisContext; @@ -54,6 +57,10 @@ public class CpsPathBuilder extends CpsPathBaseListener { private List<String> containerNames = new ArrayList<>(); + final List<String> booleanOperators = new ArrayList<>(); + + final Queue<String> booleanOperatorsQueue = new LinkedList<>(); + @Override public void exitInvalidPostFix(final CpsPathParser.InvalidPostFixContext ctx) { throw new PathParsingException(ctx.getText()); @@ -90,13 +97,23 @@ public class CpsPathBuilder extends CpsPathBaseListener { throw new PathParsingException("Unsupported comparison value encountered in expression" + ctx.getText()); } leavesData.put(ctx.leafName().getText(), comparisonValue); - appendCondition(normalizedXpathBuilder, ctx.leafName().getText(), comparisonValue); + final String booleanOperator = booleanOperatorsQueue.poll(); + appendCondition(normalizedXpathBuilder, ctx.leafName().getText(), booleanOperator, comparisonValue); if (processingAncestorAxis) { - appendCondition(normalizedAncestorPathBuilder, ctx.leafName().getText(), comparisonValue); + appendCondition(normalizedAncestorPathBuilder, ctx.leafName().getText(), booleanOperator, comparisonValue); } } @Override + public void exitBooleanOperators(final CpsPathParser.BooleanOperatorsContext ctx) { + final CpsPathBooleanOperatorType cpsPathBooleanOperatorType = CpsPathBooleanOperatorType.fromString( + ctx.getText()); + booleanOperators.add(cpsPathBooleanOperatorType.getValues()); + booleanOperatorsQueue.add(cpsPathBooleanOperatorType.getValues()); + cpsPathQuery.setBooleanOperatorsType(booleanOperators); + } + + @Override public void exitDescendant(final DescendantContext ctx) { cpsPathQuery.setCpsPathPrefixType(DESCENDANT); cpsPathQuery.setDescendantName(normalizedXpathBuilder.substring(1)); @@ -170,13 +187,13 @@ public class CpsPathBuilder extends CpsPathBaseListener { } private void appendCondition(final StringBuilder currentNormalizedPathBuilder, final String name, - final Object value) { + final String booleanOperator, final Object value) { final char lastCharacter = currentNormalizedPathBuilder.charAt(currentNormalizedPathBuilder.length() - 1); - currentNormalizedPathBuilder.append(lastCharacter == '[' ? "" : " and ") - .append("@") - .append(name) - .append("='") - .append(value) - .append("'"); + currentNormalizedPathBuilder.append(lastCharacter == '[' ? "" : " " + booleanOperator + " ") + .append("@") + .append(name) + .append("='") + .append(value) + .append("'"); } } diff --git a/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathQuery.java b/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathQuery.java index 3985455263..2c96d91051 100644 --- a/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathQuery.java +++ b/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathQuery.java @@ -1,6 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2021-2023 Nordix Foundation + * Modifications Copyright (C) 2023 TechMahindra Ltd * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,6 +43,7 @@ public class CpsPathQuery { private String ancestorSchemaNodeIdentifier = ""; private String textFunctionConditionLeafName; private String textFunctionConditionValue; + private List<String> booleanOperatorsType; /** * Returns a cps path query. diff --git a/cps-path-parser/src/test/groovy/org/onap/cps/cpspath/parser/CpsPathQuerySpec.groovy b/cps-path-parser/src/test/groovy/org/onap/cps/cpspath/parser/CpsPathQuerySpec.groovy index b837a64fef..153dfbe9ed 100644 --- a/cps-path-parser/src/test/groovy/org/onap/cps/cpspath/parser/CpsPathQuerySpec.groovy +++ b/cps-path-parser/src/test/groovy/org/onap/cps/cpspath/parser/CpsPathQuerySpec.groovy @@ -1,6 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2021-2022 Nordix Foundation + * Modifications Copyright (C) 2023 TechMahindra Ltd * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,19 +67,23 @@ class CpsPathQuerySpec extends Specification { then: 'the query has the right normalized xpath type' assert result.normalizedXpath == expectedNormalizedXPath where: 'the following data is used' - scenario | cpsPath || expectedNormalizedXPath - 'yang container' | '/cps-path' || '/cps-path' - 'descendant anywhere' | '//cps-path' || '//cps-path' - 'descendant with leaf condition' | '//cps-path[@key=1]' || "//cps-path[@key='1']" - 'descendant with leaf value and ancestor' | '//cps-path[@key=1]/ancestor:parent[@key=1]' || "//cps-path[@key='1']/ancestor:parent[@key='1']" - 'parent & child' | '/parent/child' || '/parent/child' - 'parent leaf of type Integer & child' | '/parent/child[@code=1]/child2' || "/parent/child[@code='1']/child2" - 'parent leaf with double quotes' | '/parent/child[@code="1"]/child2' || "/parent/child[@code='1']/child2" - 'parent leaf with double quotes inside single quotes' | '/parent/child[@code=\'"1"\']/child2' || "/parent/child[@code='\"1\"']/child2" - 'parent leaf with single quotes inside double quotes' | '/parent/child[@code="\'1\'"]/child2' || "/parent/child[@code='\\\'1\\\'']/child2" - 'leaf with single quotes inside double quotes' | '/parent/child[@code="\'1\'"]' || "/parent/child[@code='\\\'1\\\'']" - 'leaf with more than one attribute' | '/parent/child[@key1=1 and @key2="abc"]' || "/parent/child[@key1='1' and @key2='abc']" - 'parent & child with more than one attribute' | '/parent/child[@key1=1 and @key2="abc"]/child2' || "/parent/child[@key1='1' and @key2='abc']/child2" + scenario | cpsPath || expectedNormalizedXPath + 'yang container' | '/cps-path' || '/cps-path' + 'descendant anywhere' | '//cps-path' || '//cps-path' + 'descendant with leaf condition' | '//cps-path[@key=1]' || "//cps-path[@key='1']" + 'descendant with leaf value and ancestor' | '//cps-path[@key=1]/ancestor:parent[@key=1]' || "//cps-path[@key='1']/ancestor:parent[@key='1']" + 'parent & child' | '/parent/child' || '/parent/child' + 'parent leaf of type Integer & child' | '/parent/child[@code=1]/child2' || "/parent/child[@code='1']/child2" + 'parent leaf with double quotes' | '/parent/child[@code="1"]/child2' || "/parent/child[@code='1']/child2" + 'parent leaf with double quotes inside single quotes' | '/parent/child[@code=\'"1"\']/child2' || "/parent/child[@code='\"1\"']/child2" + 'parent leaf with single quotes inside double quotes' | '/parent/child[@code="\'1\'"]/child2' || "/parent/child[@code='\\\'1\\\'']/child2" + 'leaf with single quotes inside double quotes' | '/parent/child[@code="\'1\'"]' || "/parent/child[@code='\\\'1\\\'']" + 'leaf with more than one attribute' | '/parent/child[@key1=1 and @key2="abc"]' || "/parent/child[@key1='1' and @key2='abc']" + 'parent & child with more than one attribute' | '/parent/child[@key1=1 and @key2="abc"]/child2' || "/parent/child[@key1='1' and @key2='abc']/child2" + 'leaf with more than one attribute has OR operator' | '/parent/child[@key1=1 or @key2="abc"]' || "/parent/child[@key1='1' or @key2='abc']" + 'parent & child with more than one attribute has OR operator' | '/parent/child[@key1=1 or @key2="abc"]/child2' || "/parent/child[@key1='1' or @key2='abc']/child2" + 'parent & child with multiple AND operators' | '/parent/child[@key1=1 and @key2="abc" and @key="xyz"]/child2' || "/parent/child[@key1='1' and @key2='abc' and @key='xyz']/child2" + 'parent & child with multiple OR operators' | '/parent/child[@key1=1 or @key2="abc" or @key="xyz"]/child2' || "/parent/child[@key1='1' or @key2='abc' or @key='xyz']/child2" } def 'Parse xpath to form the Normalized xpath containing #scenario.'() { @@ -100,10 +105,14 @@ class CpsPathQuerySpec extends Specification { and: 'the right parameters are set' result.descendantName == "child" result.leavesData.size() == expectedNumberOfLeaves + result.booleanOperatorsType == expectedOperators where: 'the following data is used' - scenario | cpsPath || expectedNumberOfLeaves - 'one attribute' | '//child[@common-leaf-name-int=5]' || 1 - 'more than one attribute' | '//child[@int-leaf=5 and @leaf-name="leaf value"]' || 2 + scenario | cpsPath || expectedNumberOfLeaves || expectedOperators + 'one attribute' | '//child[@common-leaf-name-int=5]' || 1 || null + 'more than one attribute has AND operator' | '//child[@int-leaf=5 and @leaf-name="leaf value"]' || 2 || ['and'] + 'more than one attribute has OR operator' | '//child[@int-leaf=5 or @leaf-name="leaf value"]' || 2 || ['or'] + 'more than one attribute has combinations and/or operator' | '//child[@int-leaf=5 and @leaf-name="leaf value" and @leaf-name="leaf value1" ]' || 2 || ['and', 'and'] + 'more than one attribute has combinations or/and operator' | '//child[@int-leaf=5 or @leaf-name="leaf value" or @leaf-name="leaf value1" ]' || 2 || ['or', 'or'] } def 'Parse #scenario cps path with text function condition'() { @@ -133,18 +142,17 @@ class CpsPathQuerySpec extends Specification { then: 'a CpsPathException is thrown' thrown(PathParsingException) where: 'the following data is used' - scenario | cpsPath - 'no / at the start' | 'invalid-cps-path/child' - 'additional / after descendant option' | '///cps-path' - 'float value' | '/parent/child[@someFloat=5.0]' - 'unmatched quotes, double quote first ' | '/parent/child[@someString="value with unmatched quotes\']' - 'unmatched quotes, single quote first' | '/parent/child[@someString=\'value with unmatched quotes"]' - 'end with descendant and more than one attribute separated by "or"' | '//child[@int-leaf=5 or @leaf-name="leaf value"]' - 'missing attribute value' | '//child[@int-leaf=5 and @name]' - 'incomplete ancestor value' | '//books/ancestor::' - 'invalid list element with missing [' | '/parent-206/child-206/grand-child-206@key="A"]' - 'invalid list element with incorrect ]' | '/parent-206/child-206/grand-child-206]@key="A"]' - 'invalid list element with incorrect ::' | '/parent-206/child-206/grand-child-206::@key"A"]' + scenario | cpsPath + 'no / at the start' | 'invalid-cps-path/child' + 'additional / after descendant option' | '///cps-path' + 'float value' | '/parent/child[@someFloat=5.0]' + 'unmatched quotes, double quote first ' | '/parent/child[@someString="value with unmatched quotes\']' + 'unmatched quotes, single quote first' | '/parent/child[@someString=\'value with unmatched quotes"]' + 'missing attribute value' | '//child[@int-leaf=5 and @name]' + 'incomplete ancestor value' | '//books/ancestor::' + 'invalid list element with missing [' | '/parent-206/child-206/grand-child-206@key="A"]' + 'invalid list element with incorrect ]' | '/parent-206/child-206/grand-child-206]@key="A"]' + 'invalid list element with incorrect ::' | '/parent-206/child-206/grand-child-206::@key"A"]' } def 'Parse cps path using ancestor by schema node identifier with a #scenario.'() { diff --git a/cps-rest/pom.xml b/cps-rest/pom.xml index 9d4f6331be..0b715c9f44 100755 --- a/cps-rest/pom.xml +++ b/cps-rest/pom.xml @@ -2,7 +2,7 @@ <!-- ============LICENSE_START======================================================= Copyright (c) 2020 Linux Foundation. - Modifications Copyright (C) 2020-2022 Nordix Foundation. + Modifications Copyright (C) 2020-2023 Nordix Foundation. Modifications Copyright (C) 2021 Bell Canada. ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,7 +28,7 @@ <parent> <groupId>org.onap.cps</groupId> <artifactId>cps-parent</artifactId> - <version>3.3.0-SNAPSHOT</version> + <version>3.3.1-SNAPSHOT</version> <relativePath>../cps-parent/pom.xml</relativePath> </parent> @@ -72,7 +72,6 @@ <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-ui</artifactId> - <version>1.5.11</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> diff --git a/cps-ri/pom.xml b/cps-ri/pom.xml index f282069e35..0e3bb633f0 100644 --- a/cps-ri/pom.xml +++ b/cps-ri/pom.xml @@ -3,7 +3,7 @@ ============LICENSE_START=======================================================
Copyright (C) 2020-2021 Pantheon.tech
Modifications Copyright (C) 2020-2021 Bell Canada
- Modifications Copyright (C) 2020-2022 Nordix Foundation
+ Modifications Copyright (C) 2020-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.
@@ -26,12 +26,16 @@ <parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.3.0-SNAPSHOT</version>
+ <version>3.3.1-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
<artifactId>cps-ri</artifactId>
+ <properties>
+ <minimum-coverage>0.80</minimum-coverage>
+ </properties>
+
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
@@ -63,10 +67,10 @@ <artifactId>postgresql</artifactId>
<version>${postgres.version}</version>
</dependency>
- <!-- Add Hibernate support for Postgres datatype JSONB -->
+ <!-- Add Hibernate support for Postgres datatype JSONB and Postgres arrays -->
<dependency>
- <groupId>com.vladmihalcea</groupId>
- <artifactId>hibernate-types-52</artifactId>
+ <groupId>io.hypersistence</groupId>
+ <artifactId>hypersistence-utils-hibernate-52</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
@@ -75,7 +79,6 @@ <dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
- <version>4.14.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntity.java b/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntity.java index 82afc5a818..05befc8711 100755 --- a/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntity.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntity.java @@ -21,7 +21,7 @@ package org.onap.cps.spi.entities; -import com.vladmihalcea.hibernate.type.json.JsonBinaryType; +import io.hypersistence.utils.hibernate.type.json.JsonBinaryType; import java.io.Serializable; import java.util.Set; import javax.persistence.CascadeType; diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java index aa631d1b1a..369e5289b1 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java @@ -458,6 +458,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService return new DataNodeBuilder() .withXpath(fragmentEntity.getXpath()) .withLeaves(leaves) + .withDataspace(fragmentEntity.getAnchor().getDataspace().getName()) .withAnchor(fragmentEntity.getAnchor().getName()) .withChildDataNodes(childDataNodes).build(); } diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java index 46b0fec1c2..f7b586d7b3 100755 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java @@ -22,7 +22,6 @@ package org.onap.cps.spi.repository; import java.util.Collection; import java.util.Optional; -import javax.validation.constraints.NotNull; import org.onap.cps.spi.entities.AnchorEntity; import org.onap.cps.spi.entities.DataspaceEntity; import org.onap.cps.spi.entities.SchemaSetEntity; @@ -35,25 +34,24 @@ import org.springframework.stereotype.Repository; @Repository public interface AnchorRepository extends JpaRepository<AnchorEntity, Integer> { - Optional<AnchorEntity> findByDataspaceAndName(@NotNull DataspaceEntity dataspaceEntity, @NotNull String name); + Optional<AnchorEntity> findByDataspaceAndName(DataspaceEntity dataspaceEntity, String name); - default AnchorEntity getByDataspaceAndName(@NotNull DataspaceEntity dataspace, - @NotNull String anchorName) { + default AnchorEntity getByDataspaceAndName(DataspaceEntity dataspace, String anchorName) { return findByDataspaceAndName(dataspace, anchorName) .orElseThrow(() -> new AnchorNotFoundException(anchorName, dataspace.getName())); } - Collection<AnchorEntity> findAllByDataspace(@NotNull DataspaceEntity dataspaceEntity); + Collection<AnchorEntity> findAllByDataspace(DataspaceEntity dataspaceEntity); - Collection<AnchorEntity> findAllBySchemaSet(@NotNull SchemaSetEntity schemaSetEntity); + Collection<AnchorEntity> findAllBySchemaSet(SchemaSetEntity schemaSetEntity); - Collection<AnchorEntity> findAllByDataspaceAndNameIn(@NotNull DataspaceEntity dataspaceEntity, - @NotNull Collection<String> anchorNames); + Collection<AnchorEntity> findAllByDataspaceAndNameIn(DataspaceEntity dataspaceEntity, + Collection<String> anchorNames); - Collection<AnchorEntity> findAllByDataspaceAndSchemaSetNameIn(@NotNull DataspaceEntity dataspaceEntity, - @NotNull Collection<String> schemaSetNames); + Collection<AnchorEntity> findAllByDataspaceAndSchemaSetNameIn(DataspaceEntity dataspaceEntity, + Collection<String> schemaSetNames); - Integer countByDataspace(@NotNull DataspaceEntity dataspaceEntity); + Integer countByDataspace(DataspaceEntity dataspaceEntity); @Query(value = "SELECT anchor.* FROM yang_resource\n" + "JOIN schema_set_yang_resources ON schema_set_yang_resources.yang_resource_id = yang_resource.id\n" @@ -65,6 +63,6 @@ public interface AnchorRepository extends JpaRepository<AnchorEntity, Integer> { Collection<AnchorEntity> getAnchorsByDataspaceIdAndModuleNames(@Param("dataspaceId") int dataspaceId, @Param("moduleNames") Collection<String> moduleNames, @Param("sizeOfModuleNames") int sizeOfModuleNames); - void deleteAllByDataspaceAndNameIn(@NotNull DataspaceEntity dataspaceEntity, - @NotNull Collection<String> anchorNames); + void deleteAllByDataspaceAndNameIn(DataspaceEntity dataspaceEntity, + Collection<String> anchorNames); } diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/DataspaceRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/DataspaceRepository.java index 10c6541d0c..b1ce127c4a 100755 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/DataspaceRepository.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/DataspaceRepository.java @@ -1,6 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2020 Bell Canada. All rights reserved. + * Modifications 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. @@ -20,7 +21,6 @@ package org.onap.cps.spi.repository; import java.util.Optional; -import javax.validation.constraints.NotNull; import org.onap.cps.spi.entities.DataspaceEntity; import org.onap.cps.spi.exceptions.DataspaceNotFoundException; import org.springframework.data.jpa.repository.JpaRepository; @@ -29,7 +29,7 @@ import org.springframework.stereotype.Repository; @Repository public interface DataspaceRepository extends JpaRepository<DataspaceEntity, Integer> { - Optional<DataspaceEntity> findByName(@NotNull String name); + Optional<DataspaceEntity> findByName(String name); /** * Get a dataspace by name. @@ -38,7 +38,7 @@ public interface DataspaceRepository extends JpaRepository<DataspaceEntity, Inte * @param name the name of the dataspace * @return the Dataspace found */ - default DataspaceEntity getByName(@NotNull final String name) { + default DataspaceEntity getByName(final String name) { return findByName(name).orElseThrow(() -> new DataspaceNotFoundException(name)); } } diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentNativeRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentNativeRepository.java index 13320bf763..bad68f7e58 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentNativeRepository.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentNativeRepository.java @@ -26,7 +26,6 @@ import java.util.Collection; * This interface is used in delete fragment entity by id with child using native sql queries. */ public interface FragmentNativeRepository { - void deleteFragmentEntity(long fragmentEntityId); /** * Delete fragment entities for each supplied xpath. diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentNativeRepositoryImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentNativeRepositoryImpl.java index 5c5458a039..04b7080def 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentNativeRepositoryImpl.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentNativeRepositoryImpl.java @@ -31,30 +31,13 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor public class FragmentNativeRepositoryImpl implements FragmentNativeRepository { - private static final String DROP_FRAGMENT_CONSTRAINT - = "ALTER TABLE fragment DROP CONSTRAINT fragment_parent_id_fkey;"; - private static final String ADD_FRAGMENT_CONSTRAINT_WITH_CASCADE - = "ALTER TABLE fragment ADD CONSTRAINT fragment_parent_id_fkey FOREIGN KEY (parent_id) " - + "REFERENCES fragment (id) ON DELETE CASCADE;"; - private static final String ADD_ORIGINAL_FRAGMENT_CONSTRAINT - = "ALTER TABLE fragment ADD CONSTRAINT fragment_parent_id_fkey FOREIGN KEY (parent_id) " - + "REFERENCES fragment (id) ON DELETE NO ACTION;"; - @PersistenceContext private final EntityManager entityManager; @Override - public void deleteFragmentEntity(final long fragmentEntityId) { - entityManager.createNativeQuery( - addFragmentConstraintWithDeleteCascade("DELETE FROM fragment WHERE id = ?")) - .setParameter(1, fragmentEntityId) - .executeUpdate(); - } - - @Override public void deleteByAnchorIdAndXpaths(final int anchorId, final Collection<String> xpaths) { - final String queryString = addFragmentConstraintWithDeleteCascade( - "DELETE FROM fragment f WHERE f.anchor_id = ? AND (f.xpath IN (:parameterPlaceholders))"); + final String queryString = + "DELETE FROM fragment f WHERE f.anchor_id = ? AND (f.xpath IN (:parameterPlaceholders))"; executeUpdateWithAnchorIdAndCollection(queryString, anchorId, xpaths); } @@ -62,8 +45,8 @@ public class FragmentNativeRepositoryImpl implements FragmentNativeRepository { public void deleteListsByAnchorIdAndXpaths(final int anchorId, final Collection<String> listXpaths) { final Collection<String> listXpathPatterns = listXpaths.stream().map(listXpath -> listXpath + "[%").collect(Collectors.toSet()); - final String queryString = addFragmentConstraintWithDeleteCascade( - "DELETE FROM fragment f WHERE f.anchor_id = ? AND (f.xpath LIKE ANY (array[:parameterPlaceholders]))"); + final String queryString = + "DELETE FROM fragment f WHERE f.anchor_id = ? AND (f.xpath LIKE ANY (array[:parameterPlaceholders]))"; executeUpdateWithAnchorIdAndCollection(queryString, anchorId, listXpathPatterns); } @@ -86,12 +69,4 @@ public class FragmentNativeRepositoryImpl implements FragmentNativeRepository { } } - private static String addFragmentConstraintWithDeleteCascade(final String queryString) { - return DROP_FRAGMENT_CONSTRAINT - + ADD_FRAGMENT_CONSTRAINT_WITH_CASCADE - + queryString + ";" - + DROP_FRAGMENT_CONSTRAINT - + ADD_ORIGINAL_FRAGMENT_CONSTRAINT; - } - } diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentQueryBuilder.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentQueryBuilder.java index c231595931..1643ca078a 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentQueryBuilder.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentQueryBuilder.java @@ -22,7 +22,10 @@ package org.onap.cps.spi.repository; import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; import java.util.Map; +import java.util.Queue; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; @@ -60,18 +63,7 @@ public class FragmentQueryBuilder { final Map<String, Object> queryParameters = new HashMap<>(); queryParameters.put("anchorId", anchorId); sqlStringBuilder.append(" AND xpath ~ :xpathRegex"); - final String xpathRegex = getXpathSqlRegex(cpsPathQuery, false); - queryParameters.put("xpathRegex", xpathRegex); - if (cpsPathQuery.hasLeafConditions()) { - sqlStringBuilder.append(" AND attributes @> :leafDataAsJson\\:\\:jsonb"); - queryParameters.put("leafDataAsJson", jsonObjectMapper.asJsonString( - cpsPathQuery.getLeavesData())); - } - - addTextFunctionCondition(cpsPathQuery, sqlStringBuilder, queryParameters); - final Query query = entityManager.createNativeQuery(sqlStringBuilder.toString(), FragmentEntity.class); - setQueryParameters(query, queryParameters); - return query; + return getQuery(cpsPathQuery, sqlStringBuilder, queryParameters); } /** @@ -83,14 +75,27 @@ public class FragmentQueryBuilder { public Query getQueryForCpsPath(final CpsPathQuery cpsPathQuery) { final StringBuilder sqlStringBuilder = new StringBuilder("SELECT * FROM FRAGMENT WHERE xpath ~ :xpathRegex"); final Map<String, Object> queryParameters = new HashMap<>(); + return getQuery(cpsPathQuery, sqlStringBuilder, queryParameters); + } + + private Query getQuery(final CpsPathQuery cpsPathQuery, final StringBuilder sqlStringBuilder, + final Map<String, Object> queryParameters) { final String xpathRegex = getXpathSqlRegex(cpsPathQuery, false); queryParameters.put("xpathRegex", xpathRegex); + final List<String> queryBooleanOperatorsType = cpsPathQuery.getBooleanOperatorsType(); if (cpsPathQuery.hasLeafConditions()) { - sqlStringBuilder.append(" AND attributes @> :leafDataAsJson\\:\\:jsonb"); - queryParameters.put("leafDataAsJson", jsonObjectMapper.asJsonString( - cpsPathQuery.getLeavesData())); + sqlStringBuilder.append(" AND ("); + final Queue<String> booleanOperatorsQueue = (queryBooleanOperatorsType == null) ? null : new LinkedList<>( + queryBooleanOperatorsType); + cpsPathQuery.getLeavesData().entrySet().forEach(entry -> { + sqlStringBuilder.append(" attributes @> "); + sqlStringBuilder.append("'" + jsonObjectMapper.asJsonString(entry) + "'"); + if (!(booleanOperatorsQueue == null || booleanOperatorsQueue.isEmpty())) { + sqlStringBuilder.append(" " + booleanOperatorsQueue.poll() + " "); + } + }); + sqlStringBuilder.append(")"); } - addTextFunctionCondition(cpsPathQuery, sqlStringBuilder, queryParameters); final Query query = entityManager.createNativeQuery(sqlStringBuilder.toString(), FragmentEntity.class); setQueryParameters(query, queryParameters); diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetRepository.java index 98d4420101..3263f34473 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetRepository.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetRepository.java @@ -25,7 +25,6 @@ import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -import javax.validation.constraints.NotNull; import org.onap.cps.spi.entities.DataspaceEntity; import org.onap.cps.spi.entities.SchemaSetEntity; import org.onap.cps.spi.exceptions.SchemaSetNotFoundException; @@ -38,17 +37,16 @@ import org.springframework.stereotype.Repository; @Repository public interface SchemaSetRepository extends JpaRepository<SchemaSetEntity, Integer> { - Optional<SchemaSetEntity> findByDataspaceAndName(@NotNull DataspaceEntity dataspaceEntity, - @NotNull String schemaSetName); + Optional<SchemaSetEntity> findByDataspaceAndName(DataspaceEntity dataspaceEntity, String schemaSetName); /** * Gets schema sets by dataspace. * @param dataspaceEntity dataspace entity * @return list of schema set entity */ - Collection<SchemaSetEntity> findByDataspace(@NotNull DataspaceEntity dataspaceEntity); + Collection<SchemaSetEntity> findByDataspace(DataspaceEntity dataspaceEntity); - Integer countByDataspace(@NotNull DataspaceEntity dataspaceEntity); + Integer countByDataspace(DataspaceEntity dataspaceEntity); /** * Gets a schema set by dataspace and schema set name. @@ -58,8 +56,7 @@ public interface SchemaSetRepository extends JpaRepository<SchemaSetEntity, Inte * @return schema set entity * @throws SchemaSetNotFoundException if SchemaSet not found */ - default SchemaSetEntity getByDataspaceAndName(@NotNull final DataspaceEntity dataspaceEntity, - @NotNull final String schemaSetName) { + default SchemaSetEntity getByDataspaceAndName(final DataspaceEntity dataspaceEntity, final String schemaSetName) { return findByDataspaceAndName(dataspaceEntity, schemaSetName) .orElseThrow(() -> new SchemaSetNotFoundException(dataspaceEntity.getName(), schemaSetName)); } @@ -71,7 +68,7 @@ public interface SchemaSetRepository extends JpaRepository<SchemaSetEntity, Inte * @return list of schema set entity * @throws SchemaSetNotFoundException if SchemaSet not found */ - default List<SchemaSetEntity> getByDataspace(@NotNull final DataspaceEntity dataspaceEntity) { + default List<SchemaSetEntity> getByDataspace(final DataspaceEntity dataspaceEntity) { return findByDataspace(dataspaceEntity).stream().collect(Collectors.toList()); } @@ -82,6 +79,6 @@ public interface SchemaSetRepository extends JpaRepository<SchemaSetEntity, Inte */ @Modifying @Query("DELETE FROM SchemaSetEntity s WHERE s.dataspace = :dataspaceEntity AND s.name IN (:schemaSetNames)") - void deleteByDataspaceAndNameIn(@NotNull @Param("dataspaceEntity") final DataspaceEntity dataspaceEntity, - @NotNull @Param("schemaSetNames") final Collection<String> schemaSetNames); + void deleteByDataspaceAndNameIn(@Param("dataspaceEntity") DataspaceEntity dataspaceEntity, + @Param("schemaSetNames") Collection<String> schemaSetNames); } diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java index 6ca4fff4f4..fff0a6a037 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java @@ -1,7 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2020 Pantheon.tech - * Modifications Copyright (C) 2021-2022 Nordix Foundation + * Modifications Copyright (C) 2021-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,6 @@ package org.onap.cps.spi.repository; import java.util.Collection; import java.util.List; import java.util.Set; -import javax.validation.constraints.NotNull; import org.onap.cps.spi.entities.YangResourceEntity; import org.onap.cps.spi.entities.YangResourceModuleReference; import org.springframework.data.jpa.repository.JpaRepository; @@ -36,7 +35,7 @@ import org.springframework.stereotype.Repository; public interface YangResourceRepository extends JpaRepository<YangResourceEntity, Long>, YangResourceNativeRepository, SchemaSetYangResourceRepository { - List<YangResourceEntity> findAllByChecksumIn(@NotNull Set<String> checksum); + List<YangResourceEntity> findAllByChecksumIn(Set<String> checksum); @Query(value = "SELECT DISTINCT\n" + "yang_resource.module_name AS module_name,\n" diff --git a/cps-ri/src/main/resources/changelog/changelog-master.yaml b/cps-ri/src/main/resources/changelog/changelog-master.yaml index 43a54caf64..bf172d8eae 100644 --- a/cps-ri/src/main/resources/changelog/changelog-master.yaml +++ b/cps-ri/src/main/resources/changelog/changelog-master.yaml @@ -50,3 +50,5 @@ databaseChangeLog: file: changelog/db/changes/16-insert-cm-handle-state.yaml - include: file: changelog/db/changes/17-add-index-to-schema-set-yang-resources.yaml + - include: + file: changelog/db/changes/18-cascade-delete-fragment-children.yaml diff --git a/cps-ri/src/main/resources/changelog/db/changes/18-cascade-delete-fragment-children.yaml b/cps-ri/src/main/resources/changelog/db/changes/18-cascade-delete-fragment-children.yaml new file mode 100644 index 0000000000..62a9e2f636 --- /dev/null +++ b/cps-ri/src/main/resources/changelog/db/changes/18-cascade-delete-fragment-children.yaml @@ -0,0 +1,34 @@ +databaseChangeLog: + - changeSet: + author: cps + id: 18 + changes: + - dropForeignKeyConstraint: + baseTableName: fragment + constraintName: fragment_parent_id_fkey + - addForeignKeyConstraint: + baseColumnNames: parent_id + baseTableName: fragment + constraintName: fragment_parent_id_fkey + deferrable: false + initiallyDeferred: false + onDelete: CASCADE + onUpdate: NO ACTION + referencedColumnNames: id + referencedTableName: fragment + validate: true + rollback: + - dropForeignKeyConstraint: + baseTableName: fragment + constraintName: fragment_parent_id_fkey + - addForeignKeyConstraint: + baseColumnNames: parent_id + baseTableName: fragment + constraintName: fragment_parent_id_fkey + deferrable: false + initiallyDeferred: false + onDelete: NO ACTION + onUpdate: NO ACTION + referencedColumnNames: id + referencedTableName: fragment + validate: true diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceQueryDataNodeSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceQueryDataNodeSpec.groovy deleted file mode 100644 index 60aaa81140..0000000000 --- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceQueryDataNodeSpec.groovy +++ /dev/null @@ -1,212 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation - * Modifications Copyright (C) 2021 Pantheon.tech - * Modifications Copyright (C) 2021 Bell Canada. - * Modifications Copyright (C) 2023 TechMahindra Ltd. - * ================================================================================ - * 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.spi.impl - -import org.onap.cps.spi.CpsDataPersistenceService -import org.onap.cps.spi.FetchDescendantsOption -import org.onap.cps.spi.exceptions.CpsPathException -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.test.context.jdbc.Sql - -import java.util.stream.Collectors - -import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS -import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS - -class CpsDataPersistenceQueryDataNodeSpec extends CpsPersistenceSpecBase { - - @Autowired - CpsDataPersistenceService objectUnderTest - - static final String SET_DATA = '/data/cps-path-query.sql' - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Cps Path query for leaf value(s) with : #scenario.'() { - when: 'a query is executed to get a data node by the given cps path' - def result = objectUnderTest.queryDataNodes(DATASPACE_NAME, ANCHOR_FOR_SHOP_EXAMPLE, cpsPath, fetchDescendantsOption) - then: 'the correct number of parent nodes are returned' - result.size() == expectedNumberOfParentNodes - then: 'the correct data is returned' - result.each { - assert it.getChildDataNodes().size() == expectedNumberOfChildNodes - } - where: 'the following data is used' - scenario | cpsPath | fetchDescendantsOption || expectedNumberOfParentNodes | expectedNumberOfChildNodes - 'String and no descendants' | '/shops/shop[@id=1]/categories[@code=1]/book[@title="Dune"]' | OMIT_DESCENDANTS || 1 | 0 - 'Integer and descendants' | '/shops/shop[@id=1]/categories[@code=1]/book[@price=5]' | INCLUDE_ALL_DESCENDANTS || 1 | 1 - 'No condition no descendants' | '/shops/shop[@id=1]/categories' | OMIT_DESCENDANTS || 3 | 0 - 'Integer and level 1 descendants' | '/shops' | new FetchDescendantsOption(1) || 1 | 5 - 'Integer and level 2 descendants' | '/shops/shop[@id=1]' | new FetchDescendantsOption(2) || 1 | 3 - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Query for attribute by cps path with cps paths that return no data because of #scenario.'() { - when: 'a query is executed to get data nodes for the given cps path' - def result = objectUnderTest.queryDataNodes(DATASPACE_NAME, ANCHOR_FOR_SHOP_EXAMPLE, cpsPath, OMIT_DESCENDANTS) - then: 'no data is returned' - result.isEmpty() - where: 'following cps queries are performed' - scenario | cpsPath - 'cps path is incomplete' | '/shops[@title="Dune"]' - 'leaf value does not exist' | '/shops/shop[@id=1]/categories[@code=1]/book[@title=\'does not exist\']' - 'incomplete end of xpath prefix' | '/shops/shop[@id=1]/categories/book[@price=15]' - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Cps Path query using descendant anywhere and #type (further) descendants.'() { - when: 'a query is executed to get a data node by the given cps path' - def cpsPath = '//categories[@code=1]' - def result = objectUnderTest.queryDataNodes(DATASPACE_NAME, ANCHOR_FOR_SHOP_EXAMPLE, cpsPath, includeDescendantsOption) - then: 'the data node has the correct number of children' - def dataNode = result.stream().findFirst().get() - dataNode.getChildDataNodes().size() == expectedNumberOfChildNodes - where: 'the following data is used' - type | includeDescendantsOption || expectedNumberOfChildNodes - 'omit' | OMIT_DESCENDANTS || 0 - 'include' | INCLUDE_ALL_DESCENDANTS || 1 - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Cps Path query using descendant anywhere with #scenario '() { - when: 'a query is executed to get a data node by the given cps path' - def result = objectUnderTest.queryDataNodes(DATASPACE_NAME, ANCHOR_FOR_SHOP_EXAMPLE, cpsPath, OMIT_DESCENDANTS) - then: 'the correct number of data nodes are retrieved' - result.size() == expectedXPaths.size() - and: 'xpaths of the retrieved data nodes are as expected' - for (int i = 0; i < result.size(); i++) { - assert result[i].getXpath() == expectedXPaths[i] - } - where: 'the following data is used' - scenario | cpsPath || expectedXPaths - 'fully unique descendant name' | '//categories[@code=2]' || ["/shops/shop[@id='1']/categories[@code='2']", "/shops/shop[@id='2']/categories[@code='1']", "/shops/shop[@id='2']/categories[@code='2']"] - 'descendant name match end of other node' | '//book' || ["/shops/shop[@id='1']/categories[@code='1']/book", "/shops/shop[@id='1']/categories[@code='2']/book"] - 'descendant with text condition on leaf' | '//book/title[text()="Chapters"]' || ["/shops/shop[@id='1']/categories[@code='2']/book"] - 'descendant with text condition case mismatch' | '//book/title[text()="chapters"]' || [] - 'descendant with text condition on int leaf' | '//book/price[text()="5"]' || ["/shops/shop[@id='1']/categories[@code='1']/book"] - 'descendant with text condition on leaf-list' | '//book/labels[text()="special offer"]' || ["/shops/shop[@id='1']/categories[@code='1']/book"] - 'descendant with text condition partial match' | '//book/labels[text()="special"]' || [] - 'descendant with text condition (existing) empty string' | '//book/labels[text()=""]' || ["/shops/shop[@id='1']/categories[@code='1']/book"] - 'descendant with text condition on int leaf-list' | '//book/editions[text()="2000"]' || ["/shops/shop[@id='1']/categories[@code='2']/book"] - 'descendant name match of leaf containing /' | '//categories/type[text()="text/with/slash"]' || ["/shops/shop[@id='1']/categories[@code='string/with/slash/']"] - 'descendant with text condition on leaf containing /' | '//categories[@code=\'string/with/slash\']' || ["/shops/shop[@id='1']/categories[@code='string/with/slash/']"] - 'descendant with text condition on leaf containing [' | '//book/author[@Address="String[with]square[bracket]"]'|| [] - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Cps Path query using descendant anywhere with #scenario condition(s) for a container element.'() { - when: 'a query is executed to get a data node by the given cps path' - def result = objectUnderTest.queryDataNodes(DATASPACE_NAME, ANCHOR_FOR_SHOP_EXAMPLE, cpsPath, OMIT_DESCENDANTS) - then: 'the correct number of data nodes are retrieved' - result.size() == expectedXPaths.size() - and: 'xpaths of the retrieved data nodes are as expected' - for (int i = 0; i < result.size(); i++) { - assert result[i].getXpath() == expectedXPaths[i] - } - where: 'the following data is used' - scenario | cpsPath || expectedXPaths - 'one leaf' | '//author[@FirstName="Joe"]' || ["/shops/shop[@id='1']/categories[@code='1']/book/author[@FirstName='Joe' and @Surname='Bloggs']", "/shops/shop[@id='1']/categories[@code='2']/book/author[@FirstName='Joe' and @Surname='Smith']"] - 'more than one leaf' | '//author[@FirstName="Joe" and @Surname="Bloggs"]' || ["/shops/shop[@id='1']/categories[@code='1']/book/author[@FirstName='Joe' and @Surname='Bloggs']"] - 'leaves reversed in order' | '//author[@Surname="Bloggs" and @FirstName="Joe"]' || ["/shops/shop[@id='1']/categories[@code='1']/book/author[@FirstName='Joe' and @Surname='Bloggs']"] - 'leaf and text condition' | '//author[@FirstName="Joe"]/Surname[text()="Bloggs"]' || ["/shops/shop[@id='1']/categories[@code='1']/book/author[@FirstName='Joe' and @Surname='Bloggs']"] - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Cps Path query using descendant anywhere with #scenario condition(s) for a list element.'() { - when: 'a query is executed to get a data node by the given cps path' - def result = objectUnderTest.queryDataNodes(DATASPACE_NAME, ANCHOR_FOR_SHOP_EXAMPLE, cpsPath, OMIT_DESCENDANTS) - then: 'the correct number of data nodes are retrieved' - result.size() == expectedXPaths.size() - and: 'xpaths of the retrieved data nodes are as expected' - for (int i = 0; i < result.size(); i++) { - assert result[i].getXpath() == expectedXPaths[i] - } - where: 'the following data is used' - scenario | cpsPath || expectedXPaths - 'one partial key leaf' | '//author[@FirstName="Joe"]' || ["/shops/shop[@id='1']/categories[@code='1']/book/author[@FirstName='Joe' and @Surname='Bloggs']", "/shops/shop[@id='1']/categories[@code='2']/book/author[@FirstName='Joe' and @Surname='Smith']"] - 'one non key leaf' | '//author[@title="Dune"]' || ["/shops/shop[@id='1']/categories[@code='1']/book/author[@FirstName='Joe' and @Surname='Bloggs']"] - 'mix of partial key and non key leaf' | '//author[@FirstName="Joe" and @title="Dune"]' || ["/shops/shop[@id='1']/categories[@code='1']/book/author[@FirstName='Joe' and @Surname='Bloggs']"] - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Query for attribute by cps path of type ancestor with #scenario.'() { - when: 'the given cps path is parsed' - def result = objectUnderTest.queryDataNodes(DATASPACE_NAME, ANCHOR_FOR_SHOP_EXAMPLE, cpsPath, INCLUDE_ALL_DESCENDANTS) - then: 'the xpaths of the retrieved data nodes are as expected' - result.size() == expectedXPaths.size() - if (result.size() > 0) { - def resultXpaths = result.stream().map(it -> it.xpath).collect(Collectors.toSet()) - resultXpaths.containsAll(expectedXPaths) - result.each { - assert it.childDataNodes.size() == expectedNumberOfChildren - } - } - where: 'the following data is used' - scenario | cpsPath || expectedXPaths || expectedNumberOfChildren - 'multiple list-ancestors' | '//book/ancestor::categories' || ["/shops/shop[@id='1']/categories[@code='2']", "/shops/shop[@id='1']/categories[@code='1']"] || 1 - 'one ancestor with list value' | '//book/ancestor::categories[@code=1]' || ["/shops/shop[@id='1']/categories[@code='1']"] || 1 - 'top ancestor' | '//shop[@id=1]/ancestor::shops' || ['/shops'] || 5 - 'list with index value in the xpath prefix' | '//categories[@code=1]/book/ancestor::shop[@id=1]' || ["/shops/shop[@id='1']"] || 3 - 'ancestor with parent list' | '//book/ancestor::shop[@id=1]/categories[@code=2]' || ["/shops/shop[@id='1']/categories[@code='2']"] || 1 - 'ancestor with parent' | '//phonenumbers[@type="mob"]/ancestor::info/contact' || ["/shops/shop[@id='3']/info/contact"] || 3 - 'ancestor combined with text condition' | '//book/title[text()="Dune"]/ancestor::shop' || ["/shops/shop[@id='1']"] || 3 - 'ancestor with parent that does not exist' | '//book/ancestor::parentDoesNoExist/categories' || [] || null - 'ancestor does not exist' | '//book/ancestor::ancestorDoesNotExist' || [] || null - } - - def 'Cps Path query with syntax error throws a CPS Path Exception.'() { - when: 'trying to execute a query with a syntax (parsing) error' - objectUnderTest.queryDataNodes(DATASPACE_NAME, ANCHOR_FOR_SHOP_EXAMPLE, 'cpsPath that cannot be parsed' , OMIT_DESCENDANTS) - then: 'a cps path exception is thrown' - thrown(CpsPathException) - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Cps Path query across anchors for leaf value(s) with : #scenario.'() { - when: 'a query is executed to get a data node by the given cps path' - def result = objectUnderTest.queryDataNodesAcrossAnchors(DATASPACE_NAME, cpsPath, includeDescendantsOption) - then: 'the correct number of queried nodes are returned' - assert result.size() == expectedNumberOfQueriedNodes - and : 'correct anchors are queried' - assert result.anchorName.containsAll(expectedAnchors) - where: 'the following data is used' - scenario | cpsPath | includeDescendantsOption || expectedNumberOfQueriedNodes || expectedAnchors - 'String and no descendants' | '/shops/shop[@id=1]/categories[@code=1]/book[@title="Dune"]' | OMIT_DESCENDANTS || 2 || ['ANCHOR-004', 'ANCHOR-005'] - 'Integer and descendants' | '/shops/shop[@id=1]/categories[@code=1]/book[@price=5]' | INCLUDE_ALL_DESCENDANTS || 3 || ['ANCHOR-004', 'ANCHOR-005'] - 'No condition no descendants' | '/shops/shop[@id=1]/categories' | OMIT_DESCENDANTS || 6 || ['ANCHOR-004', 'ANCHOR-005'] - 'multiple list-ancestors' | '//book/ancestor::categories' | INCLUDE_ALL_DESCENDANTS || 4 || ['ANCHOR-004', 'ANCHOR-005'] - 'one ancestor with list value' | '//book/ancestor::categories[@code=1]' | INCLUDE_ALL_DESCENDANTS || 2 || ['ANCHOR-004', 'ANCHOR-005'] - 'list with index value in the xpath prefix' | '//categories[@code=1]/book/ancestor::shop[@id=1]' | INCLUDE_ALL_DESCENDANTS || 2 || ['ANCHOR-004', 'ANCHOR-005'] - 'ancestor with parent list' | '//book/ancestor::shop[@id=1]/categories[@code=2]' | INCLUDE_ALL_DESCENDANTS || 2 || ['ANCHOR-004', 'ANCHOR-005'] - 'ancestor with parent' | '//phonenumbers[@type="mob"]/ancestor::info/contact' | INCLUDE_ALL_DESCENDANTS || 5 || ['ANCHOR-004', 'ANCHOR-005'] - 'ancestor combined with text condition' | '//book/title[text()="Dune"]/ancestor::shop' | INCLUDE_ALL_DESCENDANTS || 10 || ['ANCHOR-004', 'ANCHOR-005'] - 'ancestor with parent that does not exist' | '//book/ancestor::parentDoesNoExist/categories' | INCLUDE_ALL_DESCENDANTS || 0 || [] - 'ancestor does not exist' | '//book/ancestor::ancestorDoesNotExist' | INCLUDE_ALL_DESCENDANTS || 0 || [] - } - - def 'Cps Path query across anchors with syntax error throws a CPS Path Exception.'() { - when: 'trying to execute a query with a syntax (parsing) error' - objectUnderTest.queryDataNodesAcrossAnchors(DATASPACE_NAME, 'cpsPath that cannot be parsed' , OMIT_DESCENDANTS) - then: 'a cps path exception is thrown' - thrown(CpsPathException) - } -} diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsDataPersistenceServicePerfTest.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsDataPersistenceServicePerfTest.groovy index 7f1fb20f72..2628e9697f 100644 --- a/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsDataPersistenceServicePerfTest.groovy +++ b/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsDataPersistenceServicePerfTest.groovy @@ -47,7 +47,6 @@ class CpsDataPersistenceServicePerfTest extends CpsPersistencePerfSpecBase { static def NUMBER_OF_CHILDREN = 200 static def NUMBER_OF_GRAND_CHILDREN = 50 - static def TOTAL_NUMBER_OF_NODES = 1 + NUMBER_OF_CHILDREN + (NUMBER_OF_CHILDREN * NUMBER_OF_GRAND_CHILDREN) // Parent + Children + Grand-children @Sql([CLEAR_DATA, PERF_TEST_DATA]) def 'Create a node with many descendants (please note, subsequent tests depend on this running first).'() { @@ -60,63 +59,6 @@ class CpsDataPersistenceServicePerfTest extends CpsPersistencePerfSpecBase { recordAndAssertPerformance('Setup', 10000, setupDurationInMillis) } - def 'Get data node with many descendants by xpath #scenario'() { - when: 'get parent is executed with all descendants' - stopWatch.start() - def result = objectUnderTest.getDataNodes(PERF_DATASPACE, PERF_ANCHOR, xpath, INCLUDE_ALL_DESCENDANTS) - stopWatch.stop() - def readDurationInMillis = stopWatch.getTotalTimeMillis() - then: 'read duration is under #allowedDuration milliseconds' - recordAndAssertPerformance("Get ${scenario}", allowedDuration, readDurationInMillis) - and: 'data node is returned with all the descendants populated' - assert countDataNodes(result[0]) == TOTAL_NUMBER_OF_NODES - where: 'the following xPaths are used' - scenario | xpath || allowedDuration - 'parent' | PERF_TEST_PARENT || 500 - 'root' | '/' || 500 - } - - def 'Query parent data node with many descendants by cps-path'() { - when: 'query is executed with all descendants' - stopWatch.start() - def result = objectUnderTest.queryDataNodes(PERF_DATASPACE, PERF_ANCHOR, '//perf-parent-1' , INCLUDE_ALL_DESCENDANTS) - stopWatch.stop() - def readDurationInMillis = stopWatch.getTotalTimeMillis() - then: 'read duration is under 350 milliseconds' - recordAndAssertPerformance('Query with many descendants', 350, readDurationInMillis) - and: 'data node is returned with all the descendants populated' - assert countDataNodes(result) == TOTAL_NUMBER_OF_NODES - } - - def 'Performance of finding multiple xpaths'() { - when: 'we query for all grandchildren (except 1 for fun) with the new native method' - xpathsToAllGrandChildren.remove(0) - stopWatch.start() - def result = objectUnderTest.getDataNodesForMultipleXpaths(PERF_DATASPACE, PERF_ANCHOR, xpathsToAllGrandChildren, INCLUDE_ALL_DESCENDANTS) - stopWatch.stop() - def readDurationInMillis = stopWatch.getTotalTimeMillis() - then: 'the returned number of entities equal to the number of children * number of grandchildren' - assert result.size() == xpathsToAllGrandChildren.size() - and: 'it took less then 1000ms' - recordAndAssertPerformance('Find multiple xpaths', 1000, readDurationInMillis) - } - - def 'Query many descendants by cps-path with #scenario'() { - when: 'query is executed with all descendants' - stopWatch.start() - def result = objectUnderTest.queryDataNodes(PERF_DATASPACE, PERF_ANCHOR, '//perf-test-grand-child-1', descendantsOption) - stopWatch.stop() - def readDurationInMillis = stopWatch.getTotalTimeMillis() - then: 'read duration is under #allowedDuration milliseconds' - recordAndAssertPerformance("Query many descendants by cpspath (${scenario})", allowedDuration, readDurationInMillis) - and: 'data node is returned with all the descendants populated' - assert result.size() == NUMBER_OF_CHILDREN - where: 'the following options are used' - scenario | descendantsOption || allowedDuration - 'omit descendants ' | OMIT_DESCENDANTS || 150 - 'include descendants (although there are none)' | INCLUDE_ALL_DESCENDANTS || 150 - } - def 'Update data nodes with descendants'() { given: 'a list of xpaths to data nodes with descendants (xpath for each child)' def xpaths = (1..20).collect { diff --git a/cps-ri/src/test/resources/data/cps-path-query.sql b/cps-ri/src/test/resources/data/cps-path-query.sql deleted file mode 100644 index 5fe927bc09..0000000000 --- a/cps-ri/src/test/resources/data/cps-path-query.sql +++ /dev/null @@ -1,109 +0,0 @@ -/* - ============LICENSE_START======================================================= - Copyright (C) 2021-2022 Nordix Foundation. - Modifications Copyright (C) 2021 Bell Canada. - Modifications Copyright (C) 2023 TechMahindra Ltd. - ================================================================================ - 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========================================================= -*/ - -INSERT INTO DATASPACE (ID, NAME) VALUES - (1001, 'DATASPACE-001'); - -INSERT INTO SCHEMA_SET (ID, NAME, DATASPACE_ID) VALUES - (2001, 'SCHEMA-SET-001', 1001); - -INSERT INTO YANG_RESOURCE (ID, FILE_NAME, CONTENT, CHECKSUM, MODULE_NAME, REVISION) VALUES - (4001, 'TEST','', 'SAMPLECHECKSUM','TESTMODULENAME', 'SAMPLEREVISION'); - -UPDATE YANG_RESOURCE SET -content = 'module stores { - yang-version 1.1; - namespace "org:onap:ccsdk:sample"; - - prefix book-store; - - revision "2020-09-15" { - description - "Sample Model"; - } - } -' -where ID = 4001; - - -INSERT INTO SCHEMA_SET_YANG_RESOURCES (SCHEMA_SET_ID, YANG_RESOURCE_ID) VALUES - (2001, 4001); - -INSERT INTO ANCHOR (ID, NAME, DATASPACE_ID, SCHEMA_SET_ID) VALUES - (1003, 'ANCHOR-004', 1001, 2001); - -INSERT INTO ANCHOR (ID, NAME, DATASPACE_ID, SCHEMA_SET_ID) VALUES - (1004, 'ANCHOR-005', 1001, 2001); - -INSERT INTO FRAGMENT (ID, DATASPACE_ID, ANCHOR_ID, PARENT_ID, XPATH, ATTRIBUTES) VALUES - (1, 1001, 1003, null, '/shops', null), - (2, 1001, 1003, 1, '/shops/shop[@id=''1'']', '{"id" : 1, "type" : "bookstore"}'), - (3, 1001, 1003, 2, '/shops/shop[@id=''1'']/categories[@code=''1'']', '{"code" : 1, "type" : "bookstore", "name": "SciFi"}'), - (4, 1001, 1003, 2, '/shops/shop[@id=''1'']/categories[@code=''2'']', '{"code" : 2, "type" : "bookstore", "name": "Fiction"}'), - (31, 1001, 1003, 2, '/shops/shop[@id=''1'']/categories[@code=''string/with/slash/'']', '{"code" : "string/with/slash", "type" : "text/with/slash", "name": "Fiction"}'), - (5, 1001, 1003, 3, '/shops/shop[@id=''1'']/categories[@code=''1'']/book', '{"price" : 5, "title" : "Dune", "labels" : ["special offer","classics",""]}'), - (6, 1001, 1003, 4, '/shops/shop[@id=''1'']/categories[@code=''2'']/book', '{"price" : 15, "title" : "Chapters", "editions" : [2000,2010,2020]}'), - (7, 1001, 1003, 5, '/shops/shop[@id=''1'']/categories[@code=''1'']/book/author[@FirstName=''Joe'' and @Surname=''Bloggs'']', '{"FirstName" : "Joe", "Surname": "Bloggs","title": "Dune"}'), - (8, 1001, 1003, 6, '/shops/shop[@id=''1'']/categories[@code=''2'']/book/author[@FirstName=''Joe'' and @Surname=''Smith'']', '{"FirstName" : "Joe", "Surname": "Smith","title": "Chapters"}'), - (32, 1001, 1003, 6, '/shops/shop[@id=''1'']/categories[@code=''2'']/book/author[@FirstName=''Joe'' and @Address=''string[with]square[brackets]'']', '{"FirstName" : "Joe", "Address": "string[with]square[brackets]","title": "Chapters"}'); - - INSERT INTO FRAGMENT (ID, DATASPACE_ID, ANCHOR_ID, PARENT_ID, XPATH, ATTRIBUTES) VALUES - (9, 1001, 1003, 1, '/shops/shop[@id=''2'']', '{"type" : "bookstore"}'), - (10, 1001, 1003, 9, '/shops/shop[@id=''2'']/categories[@code=''1'']', '{"code" : 2, "type" : "bookstore", "name": "Kids"}'), - (11, 1001, 1003, 10, '/shops/shop[@id=''2'']/categories[@code=''2'']', '{"code" : 2, "type" : "bookstore", "name": "Fiction"}'); - - INSERT INTO FRAGMENT (ID, DATASPACE_ID, ANCHOR_ID, PARENT_ID, XPATH, ATTRIBUTES) VALUES - (12, 1001, 1003, 1, '/shops/shop[@id=''3'']', '{"type" : "garden centre"}'), - (13, 1001, 1003, 12, '/shops/shop[@id=''3'']/categories[@code=''1'']', '{"id" : 1, "type" : "garden centre", "name": "indoor plants"}'), - (14, 1001, 1003, 12, '/shops/shop[@id=''3'']/categories[@code=''2'']', '{"id" : 2, "type" : "garden centre", "name": "outdoor plants"}'), - (16, 1001, 1003, 1, '/shops/shop[@id=''3'']/info', null), - (17, 1001, 1003, 1, '/shops/shop[@id=''3'']/info/contact', null), - (18, 1001, 1003, 17, '/shops/shop[@id=''3'']/info/contact/website', '{"address" : "myshop.ie"}'), - (19, 1001, 1003, 17, '/shops/shop[@id=''3'']/info/contact/phonenumbers[@type=''mob'']', '{"type" : "mob", "number" : "123123456"}'), - (20, 1001, 1003, 17, '/shops/shop[@id=''3'']/info/contact/phonenumbers[@type=''landline'']', '{"type" : "landline", "number" : "012123456"}'); - - INSERT INTO FRAGMENT (ID, DATASPACE_ID, ANCHOR_ID, PARENT_ID, XPATH, ATTRIBUTES) VALUES - (41, 1001, 1004, null, '/shops', null), - (42, 1001, 1004, 1, '/shops/shop[@id=''1'']', '{"id" : 1, "type" : "bookstore"}'), - (43, 1001, 1004, 2, '/shops/shop[@id=''1'']/categories[@code=''1'']', '{"code" : 1, "type" : "bookstore", "name": "SciFi"}'), - (44, 1001, 1004, 2, '/shops/shop[@id=''1'']/categories[@code=''2'']', '{"code" : 2, "type" : "bookstore", "name": "Fiction"}'), - (71, 1001, 1004, 2, '/shops/shop[@id=''1'']/categories[@code=''string/with/slash/'']', '{"code" : "string/with/slash", "type" : "text/with/slash", "name": "Fiction"}'), - (45, 1001, 1004, 3, '/shops/shop[@id=''1'']/categories[@code=''1'']/book', '{"price" : 5, "title" : "Dune", "labels" : ["special offer","classics",""]}'), - (46, 1001, 1004, 4, '/shops/shop[@id=''1'']/categories[@code=''2'']/book', '{"price" : 15, "title" : "Chapters", "editions" : [2000,2010,2020]}'), - (47, 1001, 1004, 5, '/shops/shop[@id=''1'']/categories[@code=''1'']/book/author[@FirstName=''Joe'' and @Surname=''Bloggs'']', '{"FirstName" : "Joe", "Surname": "Bloggs","title": "Dune"}'), - (48, 1001, 1004, 6, '/shops/shop[@id=''1'']/categories[@code=''2'']/book/author[@FirstName=''Joe'' and @Surname=''Smith'']', '{"FirstName" : "Joe", "Surname": "Smith","title": "Chapters"}'), - (72, 1001, 1004, 6, '/shops/shop[@id=''1'']/categories[@code=''2'']/book/author[@FirstName=''Joe'' and @Address=''string[with]square[brackets]'']', '{"FirstName" : "Joe", "Address": "string[with]square[brackets]","title": "Chapters"}'); - - INSERT INTO FRAGMENT (ID, DATASPACE_ID, ANCHOR_ID, PARENT_ID, XPATH, ATTRIBUTES) VALUES - (49, 1001, 1004, 1, '/shops/shop[@id=''2'']', '{"type" : "bookstore"}'), - (50, 1001, 1004, 9, '/shops/shop[@id=''2'']/categories[@code=''1'']', '{"code" : 2, "type" : "bookstore", "name": "Kids"}'), - (51, 1001, 1004, 10, '/shops/shop[@id=''2'']/categories[@code=''2'']', '{"code" : 2, "type" : "bookstore", "name": "Fiction"}'); - - INSERT INTO FRAGMENT (ID, DATASPACE_ID, ANCHOR_ID, PARENT_ID, XPATH, ATTRIBUTES) VALUES - (52, 1001, 1004, 1, '/shops/shop[@id=''3'']', '{"type" : "garden centre"}'), - (53, 1001, 1004, 12, '/shops/shop[@id=''3'']/categories[@code=''1'']', '{"id" : 1, "type" : "garden centre", "name": "indoor plants"}'), - (54, 1001, 1004, 12, '/shops/shop[@id=''3'']/categories[@code=''2'']', '{"id" : 2, "type" : "garden centre", "name": "outdoor plants"}'), - (56, 1001, 1004, 1, '/shops/shop[@id=''3'']/info', null), - (57, 1001, 1004, 1, '/shops/shop[@id=''3'']/info/contact', null), - (58, 1001, 1004, 17, '/shops/shop[@id=''3'']/info/contact/website', '{"address" : "myshop.ie"}'), - (59, 1001, 1004, 17, '/shops/shop[@id=''3'']/info/contact/phonenumbers[@type=''mob'']', '{"type" : "mob", "number" : "123123456"}'), - (60, 1001, 1004, 17, '/shops/shop[@id=''3'']/info/contact/phonenumbers[@type=''landline'']', '{"type" : "landline", "number" : "012123456"}'); diff --git a/cps-service/pom.xml b/cps-service/pom.xml index 47f5508ff1..3c79681fe8 100644 --- a/cps-service/pom.xml +++ b/cps-service/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>org.onap.cps</groupId> <artifactId>cps-parent</artifactId> - <version>3.3.0-SNAPSHOT</version> + <version>3.3.1-SNAPSHOT</version> <relativePath>../cps-parent/pom.xml</relativePath> </parent> diff --git a/cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java b/cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java index 6fc36ebb61..e212933388 100644 --- a/cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java +++ b/cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2021 Bell Canada. All rights reserved. * Modifications Copyright (C) 2021 Pantheon.tech - * Modifications Copyright (C) 2022 Nordix Foundation. + * Modifications Copyright (C) 2022-2023 Nordix Foundation. * Modifications Copyright (C) 2022-2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -54,6 +54,7 @@ public class DataNodeBuilder { private String parentNodeXpath = ""; private Map<String, Serializable> leaves = Collections.emptyMap(); private Collection<DataNode> childDataNodes = Collections.emptySet(); + private String dataspaceName; private String anchorName; /** @@ -90,6 +91,17 @@ public class DataNodeBuilder { } /** + * To use dataspace name for creating {@link DataNode}. + * + * @param dataspaceName dataspace name for the data node + * @return DataNodeBuilder + */ + public DataNodeBuilder withDataspace(final String dataspaceName) { + this.dataspaceName = dataspaceName; + return this; + } + + /** * To use anchor name for creating {@link DataNode}. * * @param anchorName anchor name for the data node @@ -165,6 +177,7 @@ public class DataNodeBuilder { dataNode.setModuleNamePrefix(moduleNamePrefix); dataNode.setLeaves(leaves); dataNode.setChildDataNodes(childDataNodes); + dataNode.setDataspace(dataspaceName); dataNode.setAnchorName(anchorName); return dataNode; } diff --git a/csit/data/testTreePatchExample.json b/csit/data/testTreePatchExample.json new file mode 100644 index 0000000000..31210b6289 --- /dev/null +++ b/csit/data/testTreePatchExample.json @@ -0,0 +1,11 @@ +{ + "name": "Right", + "nest": { + "name": "Bigger", + "birds": [ + "Eagle", + "Falcon", + "Pigeon" + ] + } +}
\ No newline at end of file diff --git a/csit/tests/cps-data/cps-data.robot b/csit/tests/cps-data/cps-data.robot index 096bd07b79..ce2033c116 100644 --- a/csit/tests/cps-data/cps-data.robot +++ b/csit/tests/cps-data/cps-data.robot @@ -1,7 +1,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. @@ -42,6 +42,23 @@ Create Data Node ${response}= POST On Session CPS_URL ${uri} headers=${headers} data=${jsonData} Should Be Equal As Strings ${response.status_code} 201 +Patch Data Node + ${uri}= Set Variable ${basePath}/v1/dataspaces/${dataspaceName}/anchors/${anchorName}/nodes + ${params}= Create Dictionary xpath=/test-tree/branch[@name='Right'] + ${headers} Create Dictionary Content-Type=application/json Authorization=${auth} + ${jsonData}= Get Binary File ${DATADIR}${/}testTreePatchExample.json + ${response}= PATCH On Session CPS_URL ${uri} params=${params} headers=${headers} data=${jsonData} + Should Be Equal As Strings ${response.status_code} 200 + +Get Updated Data Node by XPath + ${uri}= Set Variable ${basePath}/v1/dataspaces/${dataspaceName}/anchors/${anchorName}/node + ${params}= Create Dictionary xpath=/test-tree/branch[@name='Right']/nest + ${headers}= Create Dictionary Authorization=${auth} + ${response}= Get On Session CPS_URL ${uri} params=${params} headers=${headers} expected_status=200 + ${responseJson}= Set Variable ${response.json()['tree:nest']} + Should Be Equal As Strings ${responseJson['name']} Bigger + Should Be Equal As Strings ${responseJson['birds']} ['Falcon', 'Eagle', 'Pigeon'] + Get Data Node by XPath ${uri}= Set Variable ${basePath}/v1/dataspaces/${dataspaceName}/anchors/${anchorName}/node ${params}= Create Dictionary xpath=/test-tree/branch[@name='LEFT/left']/nest diff --git a/dmi-plugin-stub/files/batchResponse.json b/dmi-plugin-stub/files/batchResponse.json new file mode 100644 index 0000000000..b0615df945 --- /dev/null +++ b/dmi-plugin-stub/files/batchResponse.json @@ -0,0 +1,40 @@ +{ + "eventId": "4cb32729-85e3-44d1-aa6e-c923b9b059a5", + "eventCorrelationId": "68f15800-8ed4-4bae-9e53-27a9e03e1911", + "eventTime": "2023-03-28T14:29:23.876+0000", + "eventType": "org.onap.cps.ncmp.event.model.BulkResponseEvent", + "eventSchema": "urn:cps:org.onap.cps.ncmp.event.model.BulkResponseEvent", + "eventSchemaVersion": "v1", + "event": { + "payload": [ + { + "cmHandle": "CmHandle5", + "additionalProperties": [ + { + "Shape": "cube", + "Size": "small", + "Color": "yellow" + } + ], + "state": { + "cmHandleState": "READY", + "lastUpdateTime": "2023-04-03T20:03:19.832+0000" + } + }, + { + "cmHandle": "CmHandle6", + "additionalProperties": [ + { + "Shape": "cube", + "Size": "small", + "Color": "yellow" + } + ], + "state": { + "cmHandleState": "READY", + "lastUpdateTime": "2023-04-02T20:01:19.832+0000" + } + } + ] + } +}
\ No newline at end of file diff --git a/dmi-plugin-perf-stub/files/moduleResourcesResponse.json b/dmi-plugin-stub/files/moduleResourcesResponse.json index 69eb9da92a..69eb9da92a 100644 --- a/dmi-plugin-perf-stub/files/moduleResourcesResponse.json +++ b/dmi-plugin-stub/files/moduleResourcesResponse.json diff --git a/dmi-plugin-perf-stub/files/moduleResponse.json b/dmi-plugin-stub/files/moduleResponse.json index ef49eb4883..ef49eb4883 100644 --- a/dmi-plugin-perf-stub/files/moduleResponse.json +++ b/dmi-plugin-stub/files/moduleResponse.json diff --git a/dmi-plugin-stub/mappings/batchCmHandles.json b/dmi-plugin-stub/mappings/batchCmHandles.json new file mode 100644 index 0000000000..2018516b4c --- /dev/null +++ b/dmi-plugin-stub/mappings/batchCmHandles.json @@ -0,0 +1,13 @@ +{ + "request": { + "method": "POST", + "urlPattern": "/dmi/v1/ch/batch/data/ds/.*" + }, + "response": { + "status": 200, + "bodyFileName": "batchResponse.json", + "headers": { + "Content-Type": "application/json" + } + } +} diff --git a/dmi-plugin-perf-stub/mappings/module.json b/dmi-plugin-stub/mappings/module.json index a1b35ba132..a1b35ba132 100644 --- a/dmi-plugin-perf-stub/mappings/module.json +++ b/dmi-plugin-stub/mappings/module.json diff --git a/dmi-plugin-perf-stub/mappings/moduleResources.json b/dmi-plugin-stub/mappings/moduleResources.json index 4efb9b0886..4efb9b0886 100644 --- a/dmi-plugin-perf-stub/mappings/moduleResources.json +++ b/dmi-plugin-stub/mappings/moduleResources.json diff --git a/dmi-plugin-perf-stub/start.sh b/dmi-plugin-stub/start.sh index ffa8ce8825..ffa8ce8825 100755 --- a/dmi-plugin-perf-stub/start.sh +++ b/dmi-plugin-stub/start.sh diff --git a/docker-compose/docker-compose.yml b/docker-compose/docker-compose.yml index 5c785873d5..720761d498 100644 --- a/docker-compose/docker-compose.yml +++ b/docker-compose/docker-compose.yml @@ -112,8 +112,8 @@ services: ports: - ${DMI_PORT:-8783}:8080 volumes: - - ../dmi-plugin-perf-stub/mappings:/home/wiremock/mappings - - ../dmi-plugin-perf-stub/files:/home/wiremock/__files + - ../dmi-plugin-stub/mappings:/home/wiremock/mappings + - ../dmi-plugin-stub/files:/home/wiremock/__files restart: unless-stopped profiles: - dmi-stub diff --git a/docs/release-notes.rst b/docs/release-notes.rst index 715886092d..29b933e575 100755 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -12,11 +12,11 @@ CPS Release Notes :depth: 2 .. -.. ====================== -.. * * * LONDON * * * -.. ====================== +.. ======================== +.. * * * MONTREAL * * * +.. ======================== -Version: 3.2.7 +Version: 3.3.1 ============== Release Data @@ -26,25 +26,59 @@ Release Data | **CPS Project** | | | | | +--------------------------------------+--------------------------------------------------------+ -| **Docker images** | onap/cps-and-ncmp:3.2.7 | +| **Docker images** | onap/cps-and-ncmp:3.3.1 | | | | +--------------------------------------+--------------------------------------------------------+ -| **Release designation** | 3.2.7 London | +| **Release designation** | 3.3.1 Montreal | | | | +--------------------------------------+--------------------------------------------------------+ -| **Release date** | Not been released yet | +| **Release date** | Not yet released | | | | +--------------------------------------+--------------------------------------------------------+ Bug Fixes --------- -3.2.7 +3.3.1 - None Features -------- - None +Version: 3.3.0 +============== + +Release Data +------------ + ++--------------------------------------+--------------------------------------------------------+ +| **CPS Project** | | +| | | ++--------------------------------------+--------------------------------------------------------+ +| **Docker images** | onap/cps-and-ncmp:3.3.0 | +| | | ++--------------------------------------+--------------------------------------------------------+ +| **Release designation** | 3.3.0 Montreal | +| | | ++--------------------------------------+--------------------------------------------------------+ +| **Release date** | 2023 April 20 | +| | | ++--------------------------------------+--------------------------------------------------------+ + +Bug Fixes +--------- +3.3.0 + - None + +Features +-------- + - `CPS-1215 <https://jira.onap.org/browse/CPS-1215>`_ Add OR operation for CPS Path + - `CPS-1617 <https://jira.onap.org/browse/CPS-1617>`_ Use cascade delete in fragments table + +.. ====================== +.. * * * LONDON * * * +.. ====================== + Version: 3.2.6 ============== diff --git a/integration-test/pom.xml b/integration-test/pom.xml index acba37b997..34fefa5d0a 100644 --- a/integration-test/pom.xml +++ b/integration-test/pom.xml @@ -23,7 +23,7 @@ <parent> <groupId>org.onap.cps</groupId> <artifactId>cps-parent</artifactId> - <version>3.3.0-SNAPSHOT</version> + <version>3.3.1-SNAPSHOT</version> <relativePath>../cps-parent/pom.xml</relativePath> </parent> diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy index 866fef4f24..b942a43af2 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy @@ -40,6 +40,8 @@ import org.testcontainers.spock.Testcontainers import spock.lang.Shared import spock.lang.Specification +import java.time.OffsetDateTime + @SpringBootTest(classes = [TestConfig, CpsAdminServiceImpl, CpsValidatorImpl]) @Testcontainers @EnableAutoConfiguration @@ -68,9 +70,7 @@ class CpsIntegrationSpecBase extends Specification { CpsQueryService cpsQueryService def static GENERAL_TEST_DATASPACE = 'generalTestDataspace' - def static FUNCTIONAL_TEST_DATASPACE = 'functionalTestDataspace' def static BOOKSTORE_SCHEMA_SET = 'bookstoreSchemaSet' - def static BOOKSTORE_ANCHOR = 'bookstoreAnchor' def static initialized = false @@ -107,4 +107,11 @@ class CpsIntegrationSpecBase extends Specification { } return true } + + def addAnchorsWithData(numberOfAnchors, dataspaceName, schemaSetName, anchorNamePrefix, data) { + (1..numberOfAnchors).each { + cpsAdminService.createAnchor(dataspaceName, schemaSetName, anchorNamePrefix + it) + cpsDataService.saveData(dataspaceName, anchorNamePrefix + it, data, OffsetDateTime.now()) + } + } } diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy index 5e5269114e..b7a6030d80 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy @@ -20,10 +20,14 @@ package org.onap.cps.integration.base -import java.time.OffsetDateTime - class FunctionalSpecBase extends CpsIntegrationSpecBase { + def static FUNCTIONAL_TEST_DATASPACE_1 = 'functionalTestDataspace1' + def static FUNCTIONAL_TEST_DATASPACE_2 = 'functionalTestDataspace2' + def static NUMBER_OF_ANCHORS_PER_DATASPACE_WITH_BOOKSTORE_DATA = 2 + def static BOOKSTORE_ANCHOR_1 = 'bookstoreAnchor1' + def static BOOKSTORE_ANCHOR_2 = 'bookstoreAnchor2' + def static initialized = false def setup() { @@ -35,15 +39,17 @@ class FunctionalSpecBase extends CpsIntegrationSpecBase { } def setupBookstoreInfraStructure() { - cpsAdminService.createDataspace(FUNCTIONAL_TEST_DATASPACE) + cpsAdminService.createDataspace(FUNCTIONAL_TEST_DATASPACE_1) + cpsAdminService.createDataspace(FUNCTIONAL_TEST_DATASPACE_2) def bookstoreYangModelAsString = readResourceDataFile('bookstore/bookstore.yang') - cpsModuleService.createSchemaSet(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, [bookstore: bookstoreYangModelAsString]) - cpsAdminService.createAnchor(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, BOOKSTORE_ANCHOR) + cpsModuleService.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET, [bookstore: bookstoreYangModelAsString]) + cpsModuleService.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_2, BOOKSTORE_SCHEMA_SET, [bookstore: bookstoreYangModelAsString]) } def addBookstoreData() { def bookstoreJsonData = readResourceDataFile('bookstore/bookstoreData.json') - cpsDataService.saveData(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_ANCHOR, bookstoreJsonData, OffsetDateTime.now()) + addAnchorsWithData(NUMBER_OF_ANCHORS_PER_DATASPACE_WITH_BOOKSTORE_DATA, FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET, 'bookstoreAnchor', bookstoreJsonData) + addAnchorsWithData(NUMBER_OF_ANCHORS_PER_DATASPACE_WITH_BOOKSTORE_DATA, FUNCTIONAL_TEST_DATASPACE_2, BOOKSTORE_SCHEMA_SET, 'bookstoreAnchor', bookstoreJsonData) } } diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy index c333911fcc..f609ba00e0 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy @@ -21,18 +21,19 @@ package org.onap.cps.integration.functional +import org.onap.cps.api.CpsDataService import org.onap.cps.integration.base.FunctionalSpecBase import org.onap.cps.spi.FetchDescendantsOption class CpsDataServiceIntegrationSpec extends FunctionalSpecBase { - def objectUnderTest + CpsDataService objectUnderTest def setup() { objectUnderTest = cpsDataService } def 'Read bookstore top-level container(s) using #fetchDescendantsOption.'() { when: 'get data nodes for bookstore container' - def result = objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_ANCHOR, '/bookstore', fetchDescendantsOption) + def result = objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore', fetchDescendantsOption) then: 'the tree consist ouf of #expectNumberOfDataNodes data nodes' assert countDataNodesInTree(result) == expectNumberOfDataNodes and: 'the top level data node has the expected attribute and value' @@ -40,8 +41,18 @@ class CpsDataServiceIntegrationSpec extends FunctionalSpecBase { where: 'the following option is used' fetchDescendantsOption || expectNumberOfDataNodes FetchDescendantsOption.OMIT_DESCENDANTS || 1 - FetchDescendantsOption.DIRECT_CHILDREN_ONLY || 4 - FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS || 8 - new FetchDescendantsOption(2) || 8 + FetchDescendantsOption.DIRECT_CHILDREN_ONLY || 6 + FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS || 17 + new FetchDescendantsOption(2) || 17 } + + def 'Read bookstore top-level container(s) has correct dataspace and anchor.'() { + when: 'get data nodes for bookstore container' + def result = objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) + then: 'the correct dataspace was queried' + assert result.dataspace.toSet() == [FUNCTIONAL_TEST_DATASPACE_1].toSet() + and: 'the correct anchor was queried' + assert result.anchorName.toSet() == [BOOKSTORE_ANCHOR_1].toSet() + } + } diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsQueryServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsQueryServiceIntegrationSpec.groovy index 496b36db99..bd39605de3 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsQueryServiceIntegrationSpec.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsQueryServiceIntegrationSpec.groovy @@ -1,6 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2023 Nordix Foundation + * Modifications Copyright (C) 2023 TechMahindra Ltd * ================================================================================ * Licensed under the Apache License, Version 2.0 (the 'License'); * you may not use this file except in compliance with the License. @@ -20,18 +21,25 @@ package org.onap.cps.integration.functional +import org.onap.cps.api.CpsQueryService import org.onap.cps.integration.base.FunctionalSpecBase import org.onap.cps.spi.FetchDescendantsOption +import org.onap.cps.spi.exceptions.CpsPathException +import spock.lang.Ignore + +import static org.onap.cps.spi.FetchDescendantsOption.DIRECT_CHILDREN_ONLY +import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS +import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase { - def objectUnderTest + CpsQueryService objectUnderTest def setup() { objectUnderTest = cpsQueryService } def 'Query bookstore using CPS path where #scenario.'() { when: 'query data nodes for bookstore container' - def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_ANCHOR, cpsPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) + def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, INCLUDE_ALL_DESCENDANTS) then: 'the result contains expected number of nodes' assert result.size() == expectedResultSize and: 'the result contains the expected leaf values' @@ -42,7 +50,233 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase { }) where: scenario | cpsPath || expectedResultSize | expectedLeaves - 'the and condition is used' | '//books[@lang="English" and @price=15]' || 2 | [lang:"English", price:15] - 'the and is used where result does not exist' | '//books[@lang="English" and @price=1000]' || 0 | [] + 'the AND condition is used' | '//books[@lang="English" and @price=15]' || 2 | [lang:"English", price:15] + 'the AND is used where result does not exist' | '//books[@lang="English" and @price=1000]' || 0 | [] + } + + def 'Cps Path query using combinations of OR operator #scenario.'() { + when: 'a query is executed to get response by the given cps path' + def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpspath, OMIT_DESCENDANTS) + then: 'the result contains expected number of nodes' + assert result.size() == expectedResultSize + and: 'the cps-path of queryDataNodes has the expectedLeaves' + assert result.leaves.sort() == expectedLeaves.sort() + println(expectedLeaves.toArray()) + where: 'the following data is used' + scenario | cpspath || expectedResultSize | expectedLeaves + 'the "OR" condition' | '//books[@lang="English" or @price=15]' || 6 | [[lang: "English", price: 15, title: "Annihilation", authors: ["Jeff VanderMeer"], editions: [2014]], + [lang: "English", price: 15, title: "The Gruffalo", authors: ["Julia Donaldson"], editions: [1999]], + [lang: "English", price: 14, title: "The Light Fantastic", authors: ["Terry Pratchett"], editions: [1986]], + [lang: "English", price: 13, title: "Good Omens", authors: ["Terry Pratchett", "Neil Gaiman"], editions: [2006]], + [lang: "English", price: 12, title: "The Colour of Magic", authors: ["Terry Pratchett"], editions: [1983]], + [lang: "English", price: 10, title: "Matilda", authors: ["Roald Dahl"], editions: [1988, 2000]]] + 'the "OR" condition with non-json data' | '//books[@title="xyz" or @price=15]' || 2 | [[lang: "English", price: 15, title: "Annihilation", authors: ["Jeff VanderMeer"], editions: [2014]], + [lang: "English", price: 15, title: "The Gruffalo", authors: ["Julia Donaldson"], editions: [1999]]] + 'combination of multiple AND' | '//books[@lang="English" and @price=15 and @edition=1983]' || 0 | [] + 'combination of multiple OR' | '//books[ @title="Matilda" or @price=15 or @edition=1983]' || 3 | [[lang: "English", price: 15, title: "Annihilation", authors: ["Jeff VanderMeer"], editions: [2014]], + [lang: "English", price: 10, title: "Matilda", authors: ["Roald Dahl"], editions: [1988, 2000]], + [lang: "English", price: 15, title: "The Gruffalo", authors: ["Julia Donaldson"], editions: [1999]]] + } + + def 'Cps Path query for leaf value(s) with #scenario.'() { + when: 'a query is executed to get a data node by the given cps path' + def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, fetchDescendantsOption) + then: 'the correct number of parent nodes are returned' + assert result.size() == expectedNumberOfParentNodes + and: 'the correct total number of data nodes are returned' + assert countDataNodesInTree(result) == expectedTotalNumberOfNodes + where: 'the following data is used' + scenario | cpsPath | fetchDescendantsOption || expectedNumberOfParentNodes | expectedTotalNumberOfNodes + 'string and no descendants' | '/bookstore/categories[@code="1"]/books[@title="Matilda"]' | OMIT_DESCENDANTS || 1 | 1 + 'integer and descendants' | '/bookstore/categories[@code="1"]/books[@price=15]' | INCLUDE_ALL_DESCENDANTS || 1 | 1 + 'no condition and no descendants' | '/bookstore/categories' | OMIT_DESCENDANTS || 4 | 4 + 'no condition and level 1 descendants' | '/bookstore' | new FetchDescendantsOption(1) || 1 | 6 + 'no condition and level 2 descendants' | '/bookstore' | new FetchDescendantsOption(2) || 1 | 17 + } + + def 'Query for attribute by cps path with cps paths that return no data because of #scenario.'() { + when: 'a query is executed to get data nodes for the given cps path' + def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, OMIT_DESCENDANTS) + then: 'no data is returned' + assert result.isEmpty() + where: 'following cps queries are performed' + scenario | cpsPath + 'cps path is incomplete' | '/bookstore[@title="Matilda"]' + 'leaf value does not exist' | '/bookstore/categories[@code="1"]/books[@title=\'does not exist\']' + 'incomplete end of xpath prefix' | '/bookstore/categories/books[@price=15]' + } + + def 'Cps Path query using descendant anywhere and #type (further) descendants.'() { + when: 'a query is executed to get a data node by the given cps path' + def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore/categories[@code="1"]', fetchDescendantsOption) + then: 'the data node has the correct number of children' + assert result[0].childDataNodes.xpath.sort() == expectedChildNodes.sort() + where: 'the following data is used' + type | fetchDescendantsOption || expectedChildNodes + 'omit' | OMIT_DESCENDANTS || [] + 'include' | INCLUDE_ALL_DESCENDANTS || ["/bookstore/categories[@code='1']/books[@title='Matilda']", + "/bookstore/categories[@code='1']/books[@title='The Gruffalo']"] + } + + def 'Cps Path query for all books.'() { + when: 'a query is executed to get all books' + def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '//books', OMIT_DESCENDANTS) + then: 'the expected number of books are returned' + assert result.size() == 9 + } + + def 'Cps Path query using descendant anywhere with #scenario.'() { + when: 'a query is executed to get a data node by the given cps path' + def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, OMIT_DESCENDANTS) + then: 'xpaths of the retrieved data nodes are as expected' + def bookTitles = result.collect { it.getLeaves().get('title') } + assert bookTitles.sort() == expectedBookTitles.sort() + where: 'the following data is used' + scenario | cpsPath || expectedBookTitles + 'string leaf condition' | '//books[@title="Matilda"]' || ["Matilda"] + 'text condition on leaf' | '//books/title[text()="Matilda"]' || ["Matilda"] + 'text condition case mismatch' | '//books/title[text()="matilda"]' || [] + 'text condition on int leaf' | '//books/price[text()="10"]' || ["Matilda"] + 'text condition on leaf-list' | '//books/authors[text()="Terry Pratchett"]' || ["Good Omens", "The Colour of Magic", "The Light Fantastic"] + 'text condition partial match' | '//books/authors[text()="Terry"]' || [] + 'text condition (existing) empty string' | '//books/lang[text()=""]' || ["A Book with No Language"] + 'text condition on int leaf-list' | '//books/editions[text()="2000"]' || ["Matilda"] + 'match of leaf containing /' | '//books[@lang="N/A"]' || ["Logarithm tables"] + 'text condition on leaf containing /' | '//books/lang[text()="N/A"]' || ["Logarithm tables"] + 'match of key containing /' | '//books[@title="Debian GNU/Linux"]' || ["Debian GNU/Linux"] + 'text condition on key containing /' | '//books/title[text()="Debian GNU/Linux"]' || ["Debian GNU/Linux"] + } + + def 'Cps Path query using descendant anywhere with #scenario condition for a container element.'() { + when: 'a query is executed to get a data node by the given cps path' + def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, OMIT_DESCENDANTS) + then: 'book titles from the retrieved data nodes are as expected' + def bookTitles = result.collect { it.getLeaves().get('title') } + assert bookTitles.sort() == expectedBookTitles.sort() + where: 'the following data is used' + scenario | cpsPath || expectedBookTitles + 'one leaf' | '//books[@price=14]' || ['The Light Fantastic'] + 'one text' | '//books/authors[text()="Terry Pratchett"]' || ['Good Omens', 'The Colour of Magic', 'The Light Fantastic'] + 'more than one leaf' | '//books[@price=12 and @lang="English"]' || ['The Colour of Magic'] + 'more than one leaf has "OR" condition' | '//books[@lang="English" or @price=15]' || ['Annihilation', 'Good Omens', 'Matilda', 'The Colour of Magic', 'The Gruffalo', 'The Light Fantastic'] + 'more than one leaf has "OR" condition with non-json data' | '//books[@title="xyz" or @price=13]' || ['Good Omens'] + 'more than one leaf has multiple AND' | '//books[@lang="English" and @price=13 and @edition=1983]' || [] + 'more than one leaf has multiple OR' | '//books[ @title="Matilda" or @price=15 or @edition=2006]' || ['Annihilation', 'Matilda', 'The Gruffalo'] + 'leaves reversed in order' | '//books[@lang="English" and @price=12]' || ['The Colour of Magic'] + 'leaf and text' | '//books[@price=14]/authors[text()="Terry Pratchett"]' || ['The Light Fantastic'] } + + def 'Cps Path query using descendant anywhere with #scenario condition(s) for a list element.'() { + when: 'a query is executed to get a data node by the given cps path' + def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, INCLUDE_ALL_DESCENDANTS) + then: 'xpaths of the retrieved data nodes are as expected' + result.xpath.toList() == ["/bookstore/premises/addresses[@house-number='2' and @street='Main Street']"] + where: 'the following data is used' + scenario | cpsPath + 'full composite key' | '//addresses[@house-number=2 and @street="Main Street"]' + 'one partial key leaf' | '//addresses[@house-number=2]' + 'one non key leaf' | '//addresses[@county="Kildare"]' + 'mix of partial key and non key leaf' | '//addresses[@street="Main Street" and @county="Kildare"]' + } + + def 'Query for attribute by cps path of type ancestor with #scenario.'() { + when: 'the given cps path is parsed' + def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, OMIT_DESCENDANTS) + then: 'the xpaths of the retrieved data nodes are as expected' + assert result.xpath.sort() == expectedXPaths.sort() + where: 'the following data is used' + scenario | cpsPath || expectedXPaths + 'multiple list-ancestors' | '//books/ancestor::categories' || ["/bookstore/categories[@code='1']", "/bookstore/categories[@code='2']", "/bookstore/categories[@code='3']", "/bookstore/categories[@code='4']"] + 'one ancestor with list value' | '//books/ancestor::categories[@code="1"]' || ["/bookstore/categories[@code='1']"] + 'top ancestor' | '//books/ancestor::bookstore' || ["/bookstore"] + 'list with index value in the xpath prefix' | '//categories[@code="1"]/books/ancestor::bookstore' || ["/bookstore"] + 'ancestor with parent list' | '//books/ancestor::bookstore/categories' || ["/bookstore/categories[@code='1']", "/bookstore/categories[@code='2']", "/bookstore/categories[@code='3']", "/bookstore/categories[@code='4']"] + 'ancestor with parent' | '//books/ancestor::bookstore/categories[@code="2"]' || ["/bookstore/categories[@code='2']"] + 'ancestor combined with text condition' | '//books/title[text()="Matilda"]/ancestor::bookstore' || ["/bookstore"] + 'ancestor with parent that does not exist' | '//books/ancestor::parentDoesNoExist/categories' || [] + 'ancestor does not exist' | '//books/ancestor::ancestorDoesNotExist' || [] + } + + def 'Query for attribute by cps path of type ancestor with #scenario descendants.'() { + when: 'the given cps path is parsed' + def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '//books/ancestor::bookstore', fetchDescendantsOption) + then: 'the xpaths of the retrieved data nodes are as expected' + assert countDataNodesInTree(result) == expectedNumberOfNodes + where: 'the following data is used' + scenario | fetchDescendantsOption || expectedNumberOfNodes + 'no' | OMIT_DESCENDANTS || 1 + 'direct' | DIRECT_CHILDREN_ONLY || 6 + 'all' | INCLUDE_ALL_DESCENDANTS || 17 + } + + def 'Cps Path query with syntax error throws a CPS Path Exception.'() { + when: 'trying to execute a query with a syntax (parsing) error' + objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, 'cpsPath that cannot be parsed' , OMIT_DESCENDANTS) + then: 'a cps path exception is thrown' + thrown(CpsPathException) + } + + @Ignore + def 'Cps Path query across anchors with #scenario.'() { + when: 'a query is executed to get a data nodes across anchors by the given CpsPath' + def result = objectUnderTest.queryDataNodesAcrossAnchors(FUNCTIONAL_TEST_DATASPACE_1, cpsPath, OMIT_DESCENDANTS) + then: 'the correct dataspace is queried' + assert result.dataspace.toSet() == [FUNCTIONAL_TEST_DATASPACE_1].toSet() + and: 'correct anchors are queried' + assert result.anchorName.toSet() == [BOOKSTORE_ANCHOR_1, BOOKSTORE_ANCHOR_2].toSet() + and: 'the correct number of nodes is returned' + assert result.size() == expectedXpathsPerAnchor.size() * NUMBER_OF_ANCHORS_PER_DATASPACE_WITH_BOOKSTORE_DATA + and: 'the queried nodes have expected xpaths' + assert result.xpath.toSet() == expectedXpathsPerAnchor.toSet() + where: 'the following data is used' + scenario | cpsPath || expectedXpathsPerAnchor + 'container node' | '/bookstore' || ["/bookstore"] + 'list node' | '/bookstore/categories' || ["/bookstore/categories[@code='1']", "/bookstore/categories[@code='2']", "/bookstore/categories[@code='3']", "/bookstore/categories[@code='4']"] + 'string leaf-condition' | '/bookstore[@bookstore-name="Easons"]' || ["/bookstore"] + 'integer leaf-condition' | '/bookstore/categories[@code="1"]/books[@price=15]' || ["/bookstore/categories[@code='1']/books[@title='The Gruffalo']"] + 'multiple list-ancestors' | '//books/ancestor::categories' || ["/bookstore/categories[@code='1']", "/bookstore/categories[@code='2']", "/bookstore/categories[@code='3']", "/bookstore/categories[@code='4']"] + 'one ancestor with list value' | '//books/ancestor::categories[@code="1"]' || ["/bookstore/categories[@code='1']"] + 'list with index value in the xpath prefix' | '//categories[@code="1"]/books/ancestor::bookstore' || ["/bookstore"] + 'ancestor with parent list' | '//books/ancestor::bookstore/categories' || ["/bookstore/categories[@code='1']", "/bookstore/categories[@code='2']", "/bookstore/categories[@code='3']", "/bookstore/categories[@code='4']"] + 'ancestor with parent list element' | '//books/ancestor::bookstore/categories[@code="2"]' || ["/bookstore/categories[@code='2']"] + 'ancestor combined with text condition' | '//books/title[text()="Matilda"]/ancestor::bookstore' || ["/bookstore"] + } + + @Ignore + def 'Cps Path query across anchors with #scenario descendants.'() { + when: 'a query is executed to get a data node by the given cps path' + def result = objectUnderTest.queryDataNodesAcrossAnchors(FUNCTIONAL_TEST_DATASPACE_1, '/bookstore', fetchDescendantsOption) + then: 'the correct dataspace was queried' + assert result.dataspace.toSet() == [FUNCTIONAL_TEST_DATASPACE_1].toSet() + and: 'correct number of datanodes are returned' + assert countDataNodesInTree(result) == expectedNumberOfNodesPerAnchor * NUMBER_OF_ANCHORS_PER_DATASPACE_WITH_BOOKSTORE_DATA + where: 'the following data is used' + scenario | fetchDescendantsOption || expectedNumberOfNodesPerAnchor + 'no' | OMIT_DESCENDANTS || 1 + 'direct' | DIRECT_CHILDREN_ONLY || 6 + 'all' | INCLUDE_ALL_DESCENDANTS || 17 + } + + @Ignore + def 'Cps Path query across anchors with ancestors and #scenario descendants.'() { + when: 'a query is executed to get a data node by the given cps path' + def result = objectUnderTest.queryDataNodesAcrossAnchors(FUNCTIONAL_TEST_DATASPACE_1, '//books/ancestor::bookstore', fetchDescendantsOption) + then: 'the correct dataspace was queried' + assert result.dataspace.toSet() == [FUNCTIONAL_TEST_DATASPACE_1].toSet() + and: 'correct number of datanodes are returned' + assert countDataNodesInTree(result) == expectedNumberOfNodesPerAnchor * NUMBER_OF_ANCHORS_PER_DATASPACE_WITH_BOOKSTORE_DATA + where: 'the following data is used' + scenario | fetchDescendantsOption || expectedNumberOfNodesPerAnchor + 'no' | OMIT_DESCENDANTS || 1 + 'direct' | DIRECT_CHILDREN_ONLY || 6 + 'all' | INCLUDE_ALL_DESCENDANTS || 17 + } + + def 'Cps Path query across anchors with syntax error throws a CPS Path Exception.'() { + when: 'trying to execute a query with a syntax (parsing) error' + objectUnderTest.queryDataNodesAcrossAnchors(FUNCTIONAL_TEST_DATASPACE_1, 'cpsPath that cannot be parsed' , OMIT_DESCENDANTS) + then: 'a cps path exception is thrown' + thrown(CpsPathException) + } + } diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy index e75f1dce36..d339f6ddcf 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy @@ -20,11 +20,8 @@ package org.onap.cps.integration.performance.base -import org.onap.cps.spi.FetchDescendantsOption - -import java.time.OffsetDateTime -import org.onap.cps.integration.base.CpsIntegrationSpecBase import org.onap.cps.rest.utils.MultipartFileUtil +import org.onap.cps.spi.FetchDescendantsOption import org.springframework.web.multipart.MultipartFile class CpsPerfTestBase extends PerfTestBase { @@ -41,8 +38,8 @@ class CpsPerfTestBase extends PerfTestBase { def setupPerformanceInfraStructure() { cpsAdminService.createDataspace(CPS_PERFORMANCE_TEST_DATASPACE) - def modelAsString = CpsIntegrationSpecBase.readResourceDataFile('bookstore/bookstore.yang') - cpsModuleService.createSchemaSet(CPS_PERFORMANCE_TEST_DATASPACE, CpsIntegrationSpecBase.BOOKSTORE_SCHEMA_SET, [bookstore: modelAsString]) + def modelAsString = readResourceDataFile('bookstore/bookstore.yang') + cpsModuleService.createSchemaSet(CPS_PERFORMANCE_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, [bookstore: modelAsString]) } def createInitialData() { @@ -55,16 +52,16 @@ class CpsPerfTestBase extends PerfTestBase { def createWarmupData() { def data = "{\"bookstore\":{}}" stopWatch.start() - addAnchorsWithData(1, CpsIntegrationSpecBase.BOOKSTORE_SCHEMA_SET, 'warmup', data) + addAnchorsWithData(1, CPS_PERFORMANCE_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'warmup', data) stopWatch.stop() def durationInMillis = stopWatch.getTotalTimeMillis() - recordAndAssertPerformance('Creating warmup anchor with tiny data tree', 250, durationInMillis) + recordAndAssertPerformance('Creating warmup anchor with tiny data tree', 500, durationInMillis) } def createLargeBookstoresData() { - def data = CpsIntegrationSpecBase.readResourceDataFile('bookstore/largeModelData.json') + def data = readResourceDataFile('bookstore/largeModelData.json') stopWatch.start() - addAnchorsWithData(5, CpsIntegrationSpecBase.BOOKSTORE_SCHEMA_SET, 'bookstore', data) + addAnchorsWithData(5, CPS_PERFORMANCE_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'bookstore', data) stopWatch.stop() def durationInMillis = stopWatch.getTotalTimeMillis() recordAndAssertPerformance('Creating bookstore anchors with large data tree', 3_000, durationInMillis) @@ -75,23 +72,23 @@ class CpsPerfTestBase extends PerfTestBase { def multipartFile = Mock(MultipartFile) multipartFile.getOriginalFilename() >> file.getName() multipartFile.getInputStream() >> new FileInputStream(file) - cpsModuleService.createSchemaSet(CPS_PERFORMANCE_TEST_DATASPACE, PerfTestBase.LARGE_SCHEMA_SET, MultipartFileUtil.extractYangResourcesMap(multipartFile)) + cpsModuleService.createSchemaSet(CPS_PERFORMANCE_TEST_DATASPACE, LARGE_SCHEMA_SET, MultipartFileUtil.extractYangResourcesMap(multipartFile)) } def addOpenRoadData() { - def data = CpsIntegrationSpecBase.readResourceDataFile('openroadm/innerNode.json') + def data = generateOpenRoadData(50) stopWatch.start() - addAnchorsWithData(5, PerfTestBase.LARGE_SCHEMA_SET, 'openroadm', data) + addAnchorsWithData(5, CPS_PERFORMANCE_TEST_DATASPACE, LARGE_SCHEMA_SET, 'openroadm', data) stopWatch.stop() def durationInMillis = stopWatch.getTotalTimeMillis() recordAndAssertPerformance('Creating openroadm anchors with large data tree', 25_000, durationInMillis) } - def addAnchorsWithData(numberOfAnchors, schemaSetName, anchorNamePrefix, data) { - (1..numberOfAnchors).each { - cpsAdminService.createAnchor(CPS_PERFORMANCE_TEST_DATASPACE, schemaSetName, anchorNamePrefix + it) - cpsDataService.saveData(CPS_PERFORMANCE_TEST_DATASPACE, anchorNamePrefix + it, data, OffsetDateTime.now()) - } + def generateOpenRoadData(numberOfNodes) { + def innerNode = readResourceDataFile('openroadm/innerNode.json') + return '{ "openroadm-devices": { "openroadm-device": [' + + (1..numberOfNodes).collect { innerNode.replace('NODE_ID_HERE', it.toString()) }.join(',') + + ']}}' } def 'Warm the database'() { @@ -101,8 +98,8 @@ class CpsPerfTestBase extends PerfTestBase { assert countDataNodesInTree(result) == 1 stopWatch.stop() def durationInMillis = stopWatch.getTotalTimeMillis() - then: 'all data is read within 15 seconds (warm up not critical)' - recordAndAssertPerformance("Warming database", 15_000, durationInMillis) + then: 'all data is read within 25 seconds (warm up not critical)' + recordAndAssertPerformance("Warming database", 25_000, durationInMillis) } } diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/NcmpRegistryPerfTestBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/NcmpRegistryPerfTestBase.groovy index adece2ebf5..d169bd7571 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/NcmpRegistryPerfTestBase.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/NcmpRegistryPerfTestBase.groovy @@ -40,12 +40,12 @@ class NcmpRegistryPerfTestBase extends PerfTestBase { def setupPerformanceInfraStructure() { cpsAdminService.createDataspace(NCMP_PERFORMANCE_TEST_DATASPACE) - def modelAsString = CpsIntegrationSpecBase.readResourceDataFile('ncmp-registry/dmi-registry@2022-05-10.yang') + def modelAsString = readResourceDataFile('ncmp-registry/dmi-registry@2022-05-10.yang') cpsModuleService.createSchemaSet(NCMP_PERFORMANCE_TEST_DATASPACE, REGISTRY_SCHEMA_SET, [registry: modelAsString]) } def createInitialData() { - def data = CpsIntegrationSpecBase.readResourceDataFile('ncmp-registry/1000-cmhandles.json') + def data = readResourceDataFile('ncmp-registry/1000-cmhandles.json') cpsAdminService.createAnchor(NCMP_PERFORMANCE_TEST_DATASPACE, REGISTRY_SCHEMA_SET, REGISTRY_ANCHOR) cpsDataService.saveData(NCMP_PERFORMANCE_TEST_DATASPACE, REGISTRY_ANCHOR, data, OffsetDateTime.now()) } diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsAdminServiceLimits.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsAdminServiceLimits.groovy new file mode 100644 index 0000000000..2c7c6ce35c --- /dev/null +++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsAdminServiceLimits.groovy @@ -0,0 +1,50 @@ +/* + * ============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.integration.performance.cps + +import org.onap.cps.integration.performance.base.CpsPerfTestBase +import org.springframework.dao.DataAccessResourceFailureException + +class CpsAdminServiceLimits extends CpsPerfTestBase { + + def objectUnderTest + + def setup() { objectUnderTest = cpsAdminService } + + def 'Get anchors from multiple schema set names limit exceeded: 32,766 (~ 2^15) schema set names.'() { + given: 'more than 32,766 schema set names' + def schemaSetNames = (0..32_766).collect { "size-of-this-name-does-not-matter-for-limit-" + it } + when: 'single get is executed to get all the anchors' + objectUnderTest.getAnchors(CPS_PERFORMANCE_TEST_DATASPACE, schemaSetNames) + then: 'a database exception is thrown' + thrown(DataAccessResourceFailureException.class) + } + + def 'Querying anchor names limit exceeded: 32,766 (~ 2^15) modules.'() { + given: 'more than 32,766 module names' + def moduleNames = (0..32_766).collect { "size-of-this-name-does-not-matter-for-limit-" + it } + when: 'single query is executed to get all the anchors' + objectUnderTest.queryAnchorNames(CPS_PERFORMANCE_TEST_DATASPACE, moduleNames) + then: 'a database exception is thrown' + thrown(DataAccessResourceFailureException.class) + } + +} diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsDataServiceLimits.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsDataServiceLimits.groovy new file mode 100644 index 0000000000..1cb4ed800c --- /dev/null +++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsDataServiceLimits.groovy @@ -0,0 +1,63 @@ +/* + * ============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.integration.performance.cps + +import java.time.OffsetDateTime +import org.onap.cps.integration.performance.base.CpsPerfTestBase +import org.springframework.dao.DataAccessResourceFailureException +import org.springframework.transaction.TransactionSystemException + +import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS + +class CpsDataServiceLimits extends CpsPerfTestBase { + + def objectUnderTest + + def setup() { objectUnderTest = cpsDataService } + + def 'Multiple get limit exceeded: 32,764 (~ 2^15) xpaths.'() { + given: 'more than 32,764 xpaths' + def xpaths = (0..32_764).collect { "/size/of/this/path/does/not/matter/for/limit[@id='" + it + "']" } + when: 'single operation is executed to get all datanodes with given xpaths' + objectUnderTest.getDataNodesForMultipleXpaths(CPS_PERFORMANCE_TEST_DATASPACE, 'bookstore1', xpaths, INCLUDE_ALL_DESCENDANTS) + then: 'a database exception is thrown' + thrown(DataAccessResourceFailureException.class) + } + + def 'Delete multiple datanodes limit exceeded: 32,767 (~ 2^15) xpaths.'() { + given: 'more than 32,767 xpaths' + def xpaths = (0..32_767).collect { "/size/of/this/path/does/not/matter/for/limit[@id='" + it + "']" } + when: 'single operation is executed to delete all datanodes with given xpaths' + objectUnderTest.deleteDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, 'bookstore1', xpaths, OffsetDateTime.now()) + then: 'a database exception is thrown' + thrown(TransactionSystemException.class) + } + + def 'Delete datanodes from multiple anchors limit exceeded: 32,766 (~ 2^15) anchors.'() { + given: 'more than 32,766 anchor names' + def anchorNames = (0..32_766).collect { "size-of-this-name-does-not-matter-for-limit-" + it } + when: 'single operation is executed to delete all datanodes in given anchors' + objectUnderTest.deleteDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, anchorNames, OffsetDateTime.now()) + then: 'a database exception is thrown' + thrown(DataAccessResourceFailureException.class) + } + +} diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/GetPerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/GetPerfTest.groovy index 30e8bf23d4..4676c908b9 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/GetPerfTest.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/GetPerfTest.groovy @@ -21,7 +21,10 @@ package org.onap.cps.integration.performance.cps import org.onap.cps.integration.performance.base.CpsPerfTestBase -import org.onap.cps.spi.FetchDescendantsOption + +import static org.onap.cps.spi.FetchDescendantsOption.DIRECT_CHILDREN_ONLY +import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS +import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS class GetPerfTest extends CpsPerfTestBase { @@ -29,11 +32,40 @@ class GetPerfTest extends CpsPerfTestBase { def setup() { objectUnderTest = cpsDataService } - def 'Read complete data trees from multiple anchors with #scenario.'() { + def 'Read top-level node with #scenario.'() { + when: 'get data nodes from 1 anchor' + stopWatch.start() + def result = objectUnderTest.getDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, anchor, '/openroadm-devices', fetchDescendantsOption) + stopWatch.stop() + assert countDataNodesInTree(result) == expectedNumberOfDataNodes + def durationInMillis = stopWatch.getTotalTimeMillis() + then: 'all data is read within #durationLimit ms' + recordAndAssertPerformance("Read datatrees with ${scenario}", durationLimit, durationInMillis) + where: 'the following parameters are used' + scenario | fetchDescendantsOption | anchor || durationLimit | expectedNumberOfDataNodes + 'no descendants' | OMIT_DESCENDANTS | 'openroadm1' || 100 | 1 + 'direct descendants' | DIRECT_CHILDREN_ONLY | 'openroadm2' || 100 | 1 + 50 + 'all descendants' | INCLUDE_ALL_DESCENDANTS | 'openroadm3' || 350 | 1 + 50 * 86 + } + + def 'Read data trees for multiple xpaths'() { + given: 'a collection of xpaths to get' + def xpaths = (1..50).collect { "/openroadm-devices/openroadm-device[@device-id='C201-7-1A-" + it + "']" } + when: 'get data nodes from 1 anchor' + stopWatch.start() + def result = objectUnderTest.getDataNodesForMultipleXpaths(CPS_PERFORMANCE_TEST_DATASPACE, 'openroadm4', xpaths, INCLUDE_ALL_DESCENDANTS) + stopWatch.stop() + assert countDataNodesInTree(result) == 50 * 86 + def durationInMillis = stopWatch.getTotalTimeMillis() + then: 'all data is read within 350 ms' + recordAndAssertPerformance("Read datatrees for multiple xpaths", 350, durationInMillis) + } + + def 'Read complete data trees using #scenario.'() { when: 'get data nodes for 5 anchors' stopWatch.start() (1..5).each { - def result = objectUnderTest.getDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, anchorPrefix + it, xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) + def result = objectUnderTest.getDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, anchorPrefix + it, xpath, INCLUDE_ALL_DESCENDANTS) assert countDataNodesInTree(result) == expectedNumberOfDataNodes } stopWatch.stop() @@ -42,10 +74,10 @@ class GetPerfTest extends CpsPerfTestBase { recordAndAssertPerformance("Read datatrees using ${scenario}", durationLimit, durationInMillis) where: 'the following xpaths are used' scenario | anchorPrefix | xpath || durationLimit | expectedNumberOfDataNodes - 'bookstore root' | 'bookstore' | '/' || 130 | 78 - 'bookstore top element' | 'bookstore' | '/bookstore' || 130 | 78 - 'openroadm root' | 'openroadm' | '/' || 750 | 2151 - 'openroadm top element' | 'openroadm' | '/openroadm-devices' || 750 | 2151 + 'bookstore root' | 'bookstore' | '/' || 250 | 78 + 'bookstore top element' | 'bookstore' | '/bookstore' || 250 | 78 + 'openroadm root' | 'openroadm' | '/' || 1000 | 1 + 50 * 86 + 'openroadm top element' | 'openroadm' | '/openroadm-devices' || 1000 | 1 + 50 * 86 } } diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/QueryPerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/QueryPerfTest.groovy new file mode 100644 index 0000000000..496842096f --- /dev/null +++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/QueryPerfTest.groovy @@ -0,0 +1,106 @@ +/* + * ============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.integration.performance.cps + +import org.onap.cps.integration.performance.base.CpsPerfTestBase + +import static org.onap.cps.spi.FetchDescendantsOption.DIRECT_CHILDREN_ONLY +import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS +import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS + +class QueryPerfTest extends CpsPerfTestBase { + + def objectUnderTest + + def setup() { objectUnderTest = cpsQueryService } + + def 'Query complete data trees with #scenario.'() { + when: 'query data nodes (using a fresh anchor with identical data for each test)' + stopWatch.start() + def result = objectUnderTest.queryDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, anchor, cpsPath, INCLUDE_ALL_DESCENDANTS) + stopWatch.stop() + def durationInMillis = stopWatch.getTotalTimeMillis() + then: 'the expected number of nodes is returned' + assert countDataNodesInTree(result) == expectedNumberOfDataNodes + and: 'all data is read within #durationLimit ms' + recordAndAssertPerformance("Query 1 anchor ${scenario}", durationLimit, durationInMillis) + where: 'the following parameters are used' + scenario | anchor | cpsPath || durationLimit | expectedNumberOfDataNodes + 'top element' | 'openroadm1' | '/openroadm-devices' || 250 | 50 * 86 + 1 + 'leaf condition' | 'openroadm2' | '//openroadm-device[@ne-state="inservice"]' || 650 | 50 * 86 + 'ancestors' | 'openroadm3' | '//openroadm-device/ancestor::openroadm-devices' || 250 | 50 * 86 + 1 + 'leaf condition + ancestors' | 'openroadm4' | '//openroadm-device[@status="success"]/ancestor::openroadm-devices' || 500 | 50 * 86 + 1 + } + + def 'Query complete data trees across all anchors with #scenario.'() { + when: 'query data nodes across all anchors' + stopWatch.start() + def result = objectUnderTest.queryDataNodesAcrossAnchors('cpsPerformanceDataspace', cpspath, INCLUDE_ALL_DESCENDANTS) + stopWatch.stop() + def durationInMillis = stopWatch.getTotalTimeMillis() + then: 'the expected number of nodes is returned' + assert countDataNodesInTree(result) == expectedNumberOfDataNodes + and: 'all data is read within #durationLimit ms' + recordAndAssertPerformance("Query across anchors ${scenario}", durationLimit, durationInMillis) + where: 'the following parameters are used' + scenario | cpspath || durationLimit | expectedNumberOfDataNodes + // FIXME Current implementation of queryDataNodesAcrossAnchors throws NullPointerException for next case. Uncomment after CPS-1582 is done. + // 'top element' | '/openroadm-devices' || 1 | 5 * (50 * 86 + 1) + 'leaf condition' | '//openroadm-device[@ne-state="inservice"]' || 2500 | 5 * (50 * 86) + 'ancestors' | '//openroadm-device/ancestor::openroadm-devices' || 12000 | 5 * (50 * 86 + 1) + 'leaf condition + ancestors' | '//openroadm-device[@status="success"]/ancestor::openroadm-devices' || 1000 | 5 * (50 * 86 + 1) + } + + def 'Query with leaf condition and #scenario.'() { + when: 'query data nodes (using a fresh anchor with identical data for each test)' + stopWatch.start() + def result = objectUnderTest.queryDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, anchor, '//openroadm-device[@status="success"]', fetchDescendantsOption) + stopWatch.stop() + def durationInMillis = stopWatch.getTotalTimeMillis() + then: 'the expected number of nodes is returned' + assert countDataNodesInTree(result) == expectedNumberOfDataNodes + and: 'all data is read within #durationLimit ms' + recordAndAssertPerformance("Query with ${scenario}", durationLimit, durationInMillis) + where: 'the following parameters are used' + scenario | fetchDescendantsOption | anchor || durationLimit | expectedNumberOfDataNodes + 'no descendants' | OMIT_DESCENDANTS | 'openroadm1' || 100 | 50 + 'direct descendants' | DIRECT_CHILDREN_ONLY | 'openroadm2' || 400 | 50 * 2 + 'all descendants' | INCLUDE_ALL_DESCENDANTS | 'openroadm3' || 500 | 50 * 86 + } + + def 'Query ancestors with #scenario.'() { + when: 'query data nodes (using a fresh anchor with identical data for each test)' + stopWatch.start() + def result = objectUnderTest.queryDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, anchor, '//openroadm-device[@ne-state="inservice"]/ancestor::openroadm-devices', fetchDescendantsOption) + stopWatch.stop() + def durationInMillis = stopWatch.getTotalTimeMillis() + then: 'the expected number of nodes is returned' + assert countDataNodesInTree(result) == expectedNumberOfDataNodes + and: 'all data is read within #durationLimit ms' + recordAndAssertPerformance("Query ancestors with ${scenario}", durationLimit, durationInMillis) + where: 'the following parameters are used' + scenario | fetchDescendantsOption | anchor || durationLimit | expectedNumberOfDataNodes + 'no descendants' | OMIT_DESCENDANTS | 'openroadm1' || 100 | 1 + 'direct descendants' | DIRECT_CHILDREN_ONLY | 'openroadm2' || 250 | 1 + 50 + 'all descendants' | INCLUDE_ALL_DESCENDANTS | 'openroadm3' || 400 | 1 + 50 * 86 + } + +} diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/CmHandleQueryPerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/CmHandleQueryPerfTest.groovy index 87327030c7..443dd7efd7 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/CmHandleQueryPerfTest.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/CmHandleQueryPerfTest.groovy @@ -22,7 +22,6 @@ package org.onap.cps.integration.performance.ncmp import java.util.stream.Collectors import org.onap.cps.integration.performance.base.NcmpRegistryPerfTestBase -import org.springframework.dao.DataAccessResourceFailureException import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS @@ -43,21 +42,12 @@ class CmHandleQueryPerfTest extends NcmpRegistryPerfTestBase { def result = cpsDataService.getDataNodesForMultipleXpaths(NCMP_PERFORMANCE_TEST_DATASPACE, REGISTRY_ANCHOR, xpaths, INCLUDE_ALL_DESCENDANTS) stopWatch.stop() def durationInMillis = stopWatch.getTotalTimeMillis() - then: 'the required operations are performed within 3 seconds' - recordAndAssertPerformance("CpsPath Registry attributes Query", 3_000, durationInMillis) + then: 'the required operations are performed within 1200 ms' + recordAndAssertPerformance("CpsPath Registry attributes Query", 1200, durationInMillis) and: 'all but 1 (other node) are returned' result.size() == 999 and: 'the tree contains all the expected descendants too' assert countDataNodesInTree(result) == 5 * 999 } - def 'Multiple get limit exceeded: 32,764 (~ 2^15) xpaths.'() { - given: 'more than 32,764 xpaths)' - def xpaths = (0..32_764).collect(i -> "/size/of/this/path/does/not/matter/for/limit[@id='" + i + "']") - when: 'single get is executed to get all the parent objects and their descendants' - cpsDataService.getDataNodesForMultipleXpaths(NCMP_PERFORMANCE_TEST_DATASPACE, REGISTRY_ANCHOR, xpaths, INCLUDE_ALL_DESCENDANTS) - then: 'an exception is thrown' - thrown(DataAccessResourceFailureException.class) - } - } diff --git a/integration-test/src/test/resources/data/bookstore/bookstore.yang b/integration-test/src/test/resources/data/bookstore/bookstore.yang index 2179fb93d9..62ebc73201 100644 --- a/integration-test/src/test/resources/data/bookstore/bookstore.yang +++ b/integration-test/src/test/resources/data/bookstore/bookstore.yang @@ -21,37 +21,56 @@ module stores { type string; } - list categories { + container premises { + list addresses { + key "house-number street"; - key "code"; - - leaf code { - type string; + leaf house-number { + type uint16; + } + leaf street { + type string; + } + leaf town { + type string; + } + leaf county { + type string; + } + } } - leaf name { - type string; - } + list categories { - list books { - key title; + key "code"; - leaf title { - type string; - } - leaf lang { + leaf code { type string; } - leaf-list authors { + + leaf name { type string; } - leaf pub_year { - type year; - } - leaf price { - type uint64; + + list books { + key title; + + leaf title { + type string; + } + leaf lang { + type string; + } + leaf-list authors { + type string; + } + leaf-list editions { + type year; + } + leaf price { + type uint64; + } } } } - } } diff --git a/integration-test/src/test/resources/data/bookstore/bookstoreData.json b/integration-test/src/test/resources/data/bookstore/bookstoreData.json index 1c6cb88f98..12df20e55b 100644 --- a/integration-test/src/test/resources/data/bookstore/bookstoreData.json +++ b/integration-test/src/test/resources/data/bookstore/bookstoreData.json @@ -1,6 +1,22 @@ { "bookstore": { "bookstore-name": "Easons", + "premises": { + "addresses": [ + { + "house-number": 2, + "street": "Main Street", + "town": "Maynooth", + "county": "Kildare" + }, + { + "house-number": 24, + "street": "Grafton Street", + "town": "Dublin", + "county": "Dublin" + } + ] + }, "categories": [ { "code": 1, @@ -10,14 +26,14 @@ "title": "Matilda", "lang": "English", "authors": ["Roald Dahl"], - "pub_year": 1988, + "editions": [1988, 2000], "price": 10 }, { "title": "The Gruffalo", "lang": "English", "authors": ["Julia Donaldson"], - "pub_year": 1999, + "editions": [1999], "price": 15 } ] @@ -30,7 +46,7 @@ "title": "Annihilation", "lang": "English", "authors": ["Jeff VanderMeer"], - "pub_year": 2014, + "editions": [2014], "price": 15 } ] @@ -43,12 +59,52 @@ "title": "Good Omens", "lang": "English", "authors": ["Neil Gaiman", "Terry Pratchett"], - "pub_year": 2006, + "editions": [2006], "price": 13 + }, + { + "title": "The Colour of Magic", + "lang": "English", + "authors": ["Terry Pratchett"], + "editions": [1983], + "price": 12 + }, + { + "title": "The Light Fantastic", + "lang": "English", + "authors": ["Terry Pratchett"], + "editions": [1986], + "price": 14 + }, + { + "title": "A Book with No Language", + "lang": "", + "authors": ["Joe Bloggs"], + "editions": [2023], + "price": 20 + } + ] + }, + { + "code": 4, + "name": "Computing", + "books" : [ + { + "title": "Debian GNU/Linux", + "lang": "German", + "authors": ["Peter H. Ganten", "Wulf Alex"], + "editions": [2007, 2013, 2021], + "price": 39 + }, + { + "title": "Logarithm tables", + "lang": "N/A", + "authors": ["Joe Bloggs"], + "editions": [2009], + "price": 11 } ] } - ] } -}
\ No newline at end of file +} diff --git a/integration-test/src/test/resources/data/bookstore/largeModelData.json b/integration-test/src/test/resources/data/bookstore/largeModelData.json index bdc22a7172..4a92a1da74 100644 --- a/integration-test/src/test/resources/data/bookstore/largeModelData.json +++ b/integration-test/src/test/resources/data/bookstore/largeModelData.json @@ -10,14 +10,14 @@ "title": "Matilda", "lang": "English", "authors": ["Roald Dahl"], - "pub_year": 1988, + "editions": [1988, 2000], "price": 10 }, { "title": "The Gruffalo", "lang": "English", "authors": ["Julia Donaldson"], - "pub_year": 1999, + "editions": [1999], "price": 15 } ] @@ -30,7 +30,7 @@ "title": "Annihilation", "lang": "English", "authors": ["Jeff VanderMeer"], - "pub_year": 2014, + "editions": [2014], "price": 15 } ] @@ -43,7 +43,7 @@ "title": "Good Omens", "lang": "English", "authors": ["Neil Gaiman", "Terry Pratchett"], - "pub_year": 2006, + "editions": [2006], "price": 13 } ] @@ -56,14 +56,14 @@ "title": "Matilda", "lang": "English", "authors": ["Roald Dahl"], - "pub_year": 1988, + "editions": [1988, 2000], "price": 10 }, { "title": "The Gruffalo", "lang": "English", "authors": ["Julia Donaldson"], - "pub_year": 1999, + "editions": [1999], "price": 15 } ] @@ -76,7 +76,7 @@ "title": "Annihilation", "lang": "English", "authors": ["Jeff VanderMeer"], - "pub_year": 2014, + "editions": [2014], "price": 15 } ] @@ -89,7 +89,7 @@ "title": "Good Omens", "lang": "English", "authors": ["Neil Gaiman", "Terry Pratchett"], - "pub_year": 2006, + "editions": [2006], "price": 13 } ] @@ -102,14 +102,14 @@ "title": "Matilda", "lang": "English", "authors": ["Roald Dahl"], - "pub_year": 1988, + "editions": [1988, 2000], "price": 10 }, { "title": "The Gruffalo", "lang": "English", "authors": ["Julia Donaldson"], - "pub_year": 1999, + "editions": [1999], "price": 15 } ] @@ -122,7 +122,7 @@ "title": "Annihilation", "lang": "English", "authors": ["Jeff VanderMeer"], - "pub_year": 2014, + "editions": [2014], "price": 15 } ] @@ -135,7 +135,7 @@ "title": "Good Omens", "lang": "English", "authors": ["Neil Gaiman", "Terry Pratchett"], - "pub_year": 2006, + "editions": [2006], "price": 13 } ] @@ -148,14 +148,14 @@ "title": "Matilda", "lang": "English", "authors": ["Roald Dahl"], - "pub_year": 1988, + "editions": [1988, 2000], "price": 10 }, { "title": "The Gruffalo", "lang": "English", "authors": ["Julia Donaldson"], - "pub_year": 1999, + "editions": [1999], "price": 15 } ] @@ -168,7 +168,7 @@ "title": "Annihilation", "lang": "English", "authors": ["Jeff VanderMeer"], - "pub_year": 2014, + "editions": [2014], "price": 15 } ] @@ -181,7 +181,7 @@ "title": "Good Omens", "lang": "English", "authors": ["Neil Gaiman", "Terry Pratchett"], - "pub_year": 2006, + "editions": [2006], "price": 13 } ] @@ -194,14 +194,14 @@ "title": "Matilda", "lang": "English", "authors": ["Roald Dahl"], - "pub_year": 1988, + "editions": [1988, 2000], "price": 10 }, { "title": "The Gruffalo", "lang": "English", "authors": ["Julia Donaldson"], - "pub_year": 1999, + "editions": [1999], "price": 15 } ] @@ -214,7 +214,7 @@ "title": "Annihilation", "lang": "English", "authors": ["Jeff VanderMeer"], - "pub_year": 2014, + "editions": [2014], "price": 15 } ] @@ -227,7 +227,7 @@ "title": "Good Omens", "lang": "English", "authors": ["Neil Gaiman", "Terry Pratchett"], - "pub_year": 2006, + "editions": [2006], "price": 13 } ] @@ -240,14 +240,14 @@ "title": "Matilda", "lang": "English", "authors": ["Roald Dahl"], - "pub_year": 1988, + "editions": [1988, 2000], "price": 10 }, { "title": "The Gruffalo", "lang": "English", "authors": ["Julia Donaldson"], - "pub_year": 1999, + "editions": [1999], "price": 15 } ] @@ -260,7 +260,7 @@ "title": "Annihilation", "lang": "English", "authors": ["Jeff VanderMeer"], - "pub_year": 2014, + "editions": [2014], "price": 15 } ] @@ -273,7 +273,7 @@ "title": "Good Omens", "lang": "English", "authors": ["Neil Gaiman", "Terry Pratchett"], - "pub_year": 2006, + "editions": [2006], "price": 13 } ] @@ -286,14 +286,14 @@ "title": "Matilda", "lang": "English", "authors": ["Roald Dahl"], - "pub_year": 1988, + "editions": [1988, 2000], "price": 10 }, { "title": "The Gruffalo", "lang": "English", "authors": ["Julia Donaldson"], - "pub_year": 1999, + "editions": [1999], "price": 15 } ] @@ -306,7 +306,7 @@ "title": "Annihilation", "lang": "English", "authors": ["Jeff VanderMeer"], - "pub_year": 2014, + "editions": [2014], "price": 15 } ] @@ -319,7 +319,7 @@ "title": "Good Omens", "lang": "English", "authors": ["Neil Gaiman", "Terry Pratchett"], - "pub_year": 2006, + "editions": [2006], "price": 13 } ] @@ -332,14 +332,14 @@ "title": "Matilda", "lang": "English", "authors": ["Roald Dahl"], - "pub_year": 1988, + "editions": [1988, 2000], "price": 10 }, { "title": "The Gruffalo", "lang": "English", "authors": ["Julia Donaldson"], - "pub_year": 1999, + "editions": [1999], "price": 15 } ] @@ -352,7 +352,7 @@ "title": "Annihilation", "lang": "English", "authors": ["Jeff VanderMeer"], - "pub_year": 2014, + "editions": [2014], "price": 15 } ] @@ -365,7 +365,7 @@ "title": "Good Omens", "lang": "English", "authors": ["Neil Gaiman", "Terry Pratchett"], - "pub_year": 2006, + "editions": [2006], "price": 13 } ] @@ -378,14 +378,14 @@ "title": "Matilda", "lang": "English", "authors": ["Roald Dahl"], - "pub_year": 1988, + "editions": [1988, 2000], "price": 10 }, { "title": "The Gruffalo", "lang": "English", "authors": ["Julia Donaldson"], - "pub_year": 1999, + "editions": [1999], "price": 15 } ] @@ -398,7 +398,7 @@ "title": "Annihilation", "lang": "English", "authors": ["Jeff VanderMeer"], - "pub_year": 2014, + "editions": [2014], "price": 15 } ] @@ -411,7 +411,7 @@ "title": "Good Omens", "lang": "English", "authors": ["Neil Gaiman", "Terry Pratchett"], - "pub_year": 2006, + "editions": [2006], "price": 13 } ] @@ -424,14 +424,14 @@ "title": "Matilda", "lang": "English", "authors": ["Roald Dahl"], - "pub_year": 1988, + "editions": [1988, 2000], "price": 10 }, { "title": "The Gruffalo", "lang": "English", "authors": ["Julia Donaldson"], - "pub_year": 1999, + "editions": [1999], "price": 15 } ] @@ -444,7 +444,7 @@ "title": "Annihilation", "lang": "English", "authors": ["Jeff VanderMeer"], - "pub_year": 2014, + "editions": [2014], "price": 15 } ] @@ -457,7 +457,7 @@ "title": "Good Omens", "lang": "English", "authors": ["Neil Gaiman", "Terry Pratchett"], - "pub_year": 2006, + "editions": [2006], "price": 13 } ] @@ -470,14 +470,14 @@ "title": "Matilda", "lang": "English", "authors": ["Roald Dahl"], - "pub_year": 1988, + "editions": [1988, 2000], "price": 10 }, { "title": "The Gruffalo", "lang": "English", "authors": ["Julia Donaldson"], - "pub_year": 1999, + "editions": [1999], "price": 15 } ] @@ -490,7 +490,7 @@ "title": "Annihilation", "lang": "English", "authors": ["Jeff VanderMeer"], - "pub_year": 2014, + "editions": [2014], "price": 15 } ] @@ -503,7 +503,7 @@ "title": "Good Omens", "lang": "English", "authors": ["Neil Gaiman", "Terry Pratchett"], - "pub_year": 2006, + "editions": [2006], "price": 13 } ] diff --git a/integration-test/src/test/resources/data/openroadm/innerNode.json b/integration-test/src/test/resources/data/openroadm/innerNode.json index 403d732f55..90f8aa168c 100644 --- a/integration-test/src/test/resources/data/openroadm/innerNode.json +++ b/integration-test/src/test/resources/data/openroadm/innerNode.json @@ -1,10056 +1,402 @@ { - "openroadm-devices": { - "openroadm-device": [ - { - "device-id": "C201-7-1A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-2A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-3A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-4A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-5A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-6A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-7A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-8A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-9A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-10A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-11A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-12A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-13A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-14A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-15A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-16A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-17A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-18A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-19A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-20A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-21A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-22A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-23A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-24A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - }, - { - "device-id": "C201-7-25A-NODE_ID_HERE", - "ne-state": "inservice", - "commission-date-time": "2022-11-06T14:12:23.260487-06:00", - "org-openroadm-device": { - "degree": [ - { - "degree-number": 1, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 2, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 3, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 4, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 5, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 6, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 7, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 8, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 9, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 10, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 11, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 12, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 13, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 14, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 15, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 16, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 17, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 18, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 19, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 20, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 21, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 22, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 23, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 24, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 25, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 26, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 27, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - }, - { - "degree-number": 28, - "max-wavelengths": 128, - "circuit-packs": [ - { - "index": 1 - } - ], - "connection-ports": [ - { - "index": 1 - } - ] - } - ] - }, - "status": "success" - } - ] - } + "device-id": "C201-7-1A-NODE_ID_HERE", + "ne-state": "inservice", + "commission-date-time": "2022-11-06T14:12:23.260487-06:00", + "org-openroadm-device": { + "degree": [ + { + "degree-number": 1, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 2, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 3, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 4, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 5, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 6, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 7, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 8, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 9, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 10, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 11, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 12, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 13, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 14, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 15, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 16, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 17, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 18, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 19, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 20, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 21, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 22, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 23, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 24, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 25, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 26, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 27, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + }, + { + "degree-number": 28, + "max-wavelengths": 128, + "circuit-packs": [ + { + "index": 1 + } + ], + "connection-ports": [ + { + "index": 1 + } + ] + } + ] + }, + "status": "success" } diff --git a/jacoco-report/pom.xml b/jacoco-report/pom.xml index 8241ebc4b7..55e54da36b 100644 --- a/jacoco-report/pom.xml +++ b/jacoco-report/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.onap.cps</groupId> <artifactId>cps-parent</artifactId> - <version>3.3.0-SNAPSHOT</version> + <version>3.3.1-SNAPSHOT</version> <relativePath>../cps-parent/pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> @@ -32,7 +32,7 @@ <groupId>org.onap.cps</groupId>
<artifactId>cps-aggregator</artifactId>
- <version>3.3.0-SNAPSHOT</version>
+ <version>3.3.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>cps</name>
diff --git a/releases/3.3.0-container.yaml b/releases/3.3.0-container.yaml new file mode 100644 index 0000000000..ade3928625 --- /dev/null +++ b/releases/3.3.0-container.yaml @@ -0,0 +1,8 @@ +distribution_type: container +container_release_tag: 3.3.0 +project: cps +log_dir: cps-maven-docker-stage-master/914/ +ref: d7764c4b1cf075d2caa1cd894b085ae9648eeb37 +containers: + - name: 'cps-and-ncmp' + version: '3.3.0-20230420T133752Z' diff --git a/releases/3.3.0.yaml b/releases/3.3.0.yaml new file mode 100644 index 0000000000..13024a4a56 --- /dev/null +++ b/releases/3.3.0.yaml @@ -0,0 +1,4 @@ +distribution_type: maven +log_dir: cps-maven-stage-master/920/ +project: cps +version: 3.3.0
\ No newline at end of file diff --git a/spotbugs/pom.xml b/spotbugs/pom.xml index 7385805fb3..fb40d93656 100644 --- a/spotbugs/pom.xml +++ b/spotbugs/pom.xml @@ -25,7 +25,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>org.onap.cps</groupId> <artifactId>spotbugs</artifactId> - <version>3.3.0-SNAPSHOT</version> + <version>3.3.1-SNAPSHOT</version> <properties> <nexusproxy>https://nexus.onap.org</nexusproxy> diff --git a/version.properties b/version.properties index 0777f6b538..e8f64bf28c 100755 --- a/version.properties +++ b/version.properties @@ -1,5 +1,5 @@ # ============LICENSE_START======================================================= -# Copyright (C) 2021-2022 Nordix Foundation +# Copyright (C) 2021-2023 Nordix Foundation # Modifications Copyright (C) 2022 Bell Canada. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,7 +22,7 @@ major=3 minor=3 -patch=0 +patch=1 base_version=${major}.${minor}.${patch} |