diff options
Diffstat (limited to 'src')
68 files changed, 0 insertions, 5308 deletions
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/Application.java b/src/main/java/org/onap/cps/ncmp/dmi/Application.java deleted file mode 100644 index 69d21ba1..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/Application.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.dmi; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class Application { - - public static void main(final String[] args) { - SpringApplication.run(Application.class, args); - } - -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/config/DmiConfiguration.java b/src/main/java/org/onap/cps/ncmp/dmi/config/DmiConfiguration.java deleted file mode 100644 index 83ef6f89..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/config/DmiConfiguration.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.dmi.config; - -import lombok.Getter; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; - -/** - * Provides access to cps base url and cps authentication. - */ -@Configuration -public class DmiConfiguration { - - private static final int TIMEOUT = 5000; - - @Getter - @Component - public static class CpsProperties { - - @Value("${cps-core.baseUrl}") - private String baseUrl; - @Value("${cps-core.dmiRegistrationUrl}") - private String dmiRegistrationUrl; - @Value("${cps-core.auth.username}") - private String authUsername; - @Value("${cps-core.auth.password}") - private String authPassword; - } - - @Getter - @Component - public static class SdncProperties { - - @Value("${sdnc.baseUrl}") - private String baseUrl; - @Value("${sdnc.auth.username}") - private String authUsername; - @Value("${sdnc.auth.password}") - private String authPassword; - @Value("${sdnc.topologyId}") - public String topologyId; - } - - /** - * Returns restTemplate bean for the spring context. - * - * @param restTemplateBuilder restTemplate builder - * @return {@code RestTemplate} rest template - */ - @Bean - public RestTemplate restTemplate(final RestTemplateBuilder restTemplateBuilder) { - final RestTemplate restTemplate = restTemplateBuilder.build(); - setCustomRequestFactoryToSupportPatch(restTemplate); - return restTemplate; - } - - private void setCustomRequestFactoryToSupportPatch(final RestTemplate restTemplate) { - final HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); - requestFactory.setConnectTimeout(TIMEOUT); - restTemplate.setRequestFactory(requestFactory); - } -}
\ No newline at end of file diff --git a/src/main/java/org/onap/cps/ncmp/dmi/config/DmiPluginConfig.java b/src/main/java/org/onap/cps/ncmp/dmi/config/DmiPluginConfig.java deleted file mode 100644 index fb22b358..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/config/DmiPluginConfig.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * 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. - * 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.dmi.config; - -import lombok.Getter; -import org.springdoc.core.models.GroupedOpenApi; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.stereotype.Component; - - -@Configuration -public class DmiPluginConfig { - - /** - * Swagger-ui configuration using springdoc. - */ - @Bean("dmi-plugin-api") - public GroupedOpenApi api() { - return GroupedOpenApi.builder().group("dmi-plugin-api") - .pathsToMatch("/swagger-ui/**,/swagger-resources/**,/v3/api-docs").build(); - } - - @Getter - @Component - public static class DmiPluginProperties { - - @Value("${dmi.service.url}") - private String dmiServiceUrl; - } -} - diff --git a/src/main/java/org/onap/cps/ncmp/dmi/config/WebSecurityConfig.java b/src/main/java/org/onap/cps/ncmp/dmi/config/WebSecurityConfig.java deleted file mode 100644 index ac92cb4a..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/config/WebSecurityConfig.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * 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. - * 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.dmi.config; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; -import org.springframework.security.web.SecurityFilterChain; - -/** - * Configuration class to implement application security. - * It enforces Basic Authentication access control. - */ -@Configuration -@EnableWebSecurity -public class WebSecurityConfig { - - private static final String USER_ROLE = "USER"; - - private final String username; - private final String password; - private final String[] permitUris; - - /** - * Constructor. Accepts parameters from configuration. - * - * @param permitUris comma-separated list of uri patterns for endpoints permitted - * @param username username - * @param password password - */ - public WebSecurityConfig( - @Autowired @Value("${security.permit-uri}") final String permitUris, - @Autowired @Value("${security.auth.username}") final String username, - @Autowired @Value("${security.auth.password}") final String password - ) { - super(); - this.permitUris = permitUris.isEmpty() ? new String[] {"/v3/api-docs"} : permitUris.split("\\s{0,9},\\s{0,9}"); - this.username = username; - this.password = password; - } - - /** - * Return the configuration for secure access to the modules REST end points. - * - * @param http the HTTP security settings. - * @return the HTTP security settings. - */ - @Bean - // The team decided to disable default CSRF Spring protection and not implement CSRF tokens validation. - // ncmp is a stateless REST API that is not as vulnerable to CSRF attacks as web applications running in - // web browsers are. ncmp does not manage sessions, each request requires the authentication token in the header. - // See https://docs.spring.io/spring-security/site/docs/5.3.8.RELEASE/reference/html5/#csrf - @SuppressWarnings("squid:S4502") - public SecurityFilterChain filterChain(final HttpSecurity http) throws Exception { - http - .httpBasic(httpBasicCustomizer -> {}) - .authorizeHttpRequests(authorizeHttpRequestsCustomizer -> { - authorizeHttpRequestsCustomizer.requestMatchers(permitUris).permitAll(); - authorizeHttpRequestsCustomizer.anyRequest().authenticated(); - }) - .csrf(AbstractHttpConfigurer::disable); - - return http.build(); - } - - /** - * In memory user authenticaion details. - * - * @return in memory authentication. - */ - @Bean - public InMemoryUserDetailsManager userDetailsService() { - final UserDetails user = User.builder() - .username(username) - .password("{noop}" + password) - .roles(USER_ROLE) - .build(); - return new InMemoryUserDetailsManager(user); - } -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/config/kafka/KafkaConfig.java b/src/main/java/org/onap/cps/ncmp/dmi/config/kafka/KafkaConfig.java deleted file mode 100644 index 25ee92ae..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/config/kafka/KafkaConfig.java +++ /dev/null @@ -1,142 +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.dmi.config.kafka; - -import io.cloudevents.CloudEvent; -import java.util.Map; -import lombok.RequiredArgsConstructor; -import org.apache.kafka.clients.producer.ProducerConfig; -import org.springframework.boot.autoconfigure.kafka.KafkaProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.kafka.annotation.EnableKafka; -import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; -import org.springframework.kafka.core.ConsumerFactory; -import org.springframework.kafka.core.DefaultKafkaConsumerFactory; -import org.springframework.kafka.core.DefaultKafkaProducerFactory; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.kafka.core.ProducerFactory; -import org.springframework.kafka.support.serializer.JsonDeserializer; -import org.springframework.kafka.support.serializer.JsonSerializer; - -/** - * kafka Configuration for legacy and cloud events. - * - * @param <T> valid legacy event to be published over the wire. - */ -@Configuration -@EnableKafka -@RequiredArgsConstructor -public class KafkaConfig<T> { - - private final KafkaProperties kafkaProperties; - - /** - * This sets the strategy for creating legacy Kafka producer instance from kafka properties defined into - * application.yml and replaces value-serializer by JsonSerializer. - * - * @return legacy event producer instance. - */ - @Bean - public ProducerFactory<String, T> legacyEventProducerFactory() { - final Map<String, Object> producerConfigProperties = kafkaProperties.buildProducerProperties(); - producerConfigProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class); - return new DefaultKafkaProducerFactory<>(producerConfigProperties); - } - - /** - * The ConsumerFactory implementation is to produce new legacy instance for provided kafka properties defined - * into application.yml and replaces deserializer-value by JsonDeserializer. - * - * @return an instance of legacy consumer factory. - */ - @Bean - public ConsumerFactory<String, T> legacyEventConsumerFactory() { - final Map<String, Object> consumerConfigProperties = kafkaProperties.buildConsumerProperties(); - consumerConfigProperties.put("spring.deserializer.value.delegate.class", JsonDeserializer.class); - return new DefaultKafkaConsumerFactory<>(consumerConfigProperties); - } - - /** - * This sets the strategy for creating cloud Kafka producer instance from kafka properties defined into - * application.yml with CloudEventSerializer. - * - * @return cloud event producer instance. - */ - @Bean - public ProducerFactory<String, CloudEvent> cloudEventProducerFactory() { - final Map<String, Object> producerConfigProperties = kafkaProperties.buildProducerProperties(); - return new DefaultKafkaProducerFactory<>(producerConfigProperties); - } - - /** - * The ConsumerFactory implementation to produce new legacy instance for provided kafka properties defined - * into application.yml having CloudEventDeserializer as deserializer-value. - * - * @return an instance of cloud consumer factory. - */ - @Bean - public ConsumerFactory<String, CloudEvent> cloudEventConsumerFactory() { - final Map<String, Object> consumerConfigProperties = kafkaProperties.buildConsumerProperties(); - return new DefaultKafkaConsumerFactory<>(consumerConfigProperties); - } - - /** - * A legacy Kafka event template for executing high-level operations. The legacy producer factory ensure this. - * - * @return an instance of legacy Kafka template. - */ - @Bean - @Primary - public KafkaTemplate<String, T> legacyEventKafkaTemplate() { - final KafkaTemplate<String, T> kafkaTemplate = new KafkaTemplate<>(legacyEventProducerFactory()); - kafkaTemplate.setConsumerFactory(legacyEventConsumerFactory()); - return kafkaTemplate; - } - - /** - * A cloud Kafka event template for executing high-level operations. The cloud producer factory ensure this. - * - * @return an instance of cloud Kafka template. - */ - @Bean - public KafkaTemplate<String, CloudEvent> cloudEventKafkaTemplate() { - final KafkaTemplate<String, CloudEvent> kafkaTemplate = new KafkaTemplate<>(cloudEventProducerFactory()); - kafkaTemplate.setConsumerFactory(cloudEventConsumerFactory()); - return kafkaTemplate; - } - - /** - * A cloud Kafka event template for executing high-level operations. The cloud producer factory ensure this. - * - * @return an instance of cloud Kafka template. - */ - @Bean - public ConcurrentKafkaListenerContainerFactory<String, CloudEvent> - cloudEventConcurrentKafkaListenerContainerFactory() { - final ConcurrentKafkaListenerContainerFactory<String, CloudEvent> containerFactory = - new ConcurrentKafkaListenerContainerFactory<>(); - containerFactory.setConsumerFactory(cloudEventConsumerFactory()); - return containerFactory; - } - -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/datajobs/rest/controller/DmiDatajobsRestController.java b/src/main/java/org/onap/cps/ncmp/dmi/datajobs/rest/controller/DmiDatajobsRestController.java deleted file mode 100644 index bbc1c20d..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/datajobs/rest/controller/DmiDatajobsRestController.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2024 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.dmi.datajobs.rest.controller; - -import org.onap.cps.ncmp.dmi.datajobs.model.SubjobReadRequest; -import org.onap.cps.ncmp.dmi.datajobs.model.SubjobWriteRequest; -import org.onap.cps.ncmp.dmi.datajobs.rest.api.DmiDatajobApi; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RequestMapping("${rest.api.dmi-base-path}") -@RestController -public class DmiDatajobsRestController implements DmiDatajobApi { - /** - * * This method is not implemented for ONAP DMI plugin. - * - * @param requestId Identifier for the overall Datajob (required) - * @param subjobReadRequest Operation body (optional) - * @return (@ code ResponseEntity) response entity - */ - @Override - public ResponseEntity<Void> readDataJob(final String requestId, - final SubjobReadRequest subjobReadRequest) { - - return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); - } - - /** - * * This method is not implemented for ONAP DMI plugin. - * - * @param requestId Identifier for the overall Datajob (required) - * @param subjobWriteRequest Operation body (optional) - * @return (@ code ResponseEntity) response entity - */ - @Override - public ResponseEntity<Void> writeDataJob(final String requestId, - final SubjobWriteRequest subjobWriteRequest) { - return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); - } -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/exception/CloudEventConstructionException.java b/src/main/java/org/onap/cps/ncmp/dmi/exception/CloudEventConstructionException.java deleted file mode 100644 index f61c156a..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/exception/CloudEventConstructionException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2024 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.dmi.exception; - -public class CloudEventConstructionException extends DmiException { - - private static final long serialVersionUID = 7747941311132087621L; - - /** - * CloudEventConstructionException. - * - * @param message the error message - * @param details the error details - * @param cause the error cause - */ - public CloudEventConstructionException(final String message, final String details, final Throwable cause) { - super(message, details, cause); - } -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/exception/CmHandleRegistrationException.java b/src/main/java/org/onap/cps/ncmp/dmi/exception/CmHandleRegistrationException.java deleted file mode 100644 index 1874389e..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/exception/CmHandleRegistrationException.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.dmi.exception; - -public class CmHandleRegistrationException extends DmiException { - - private static final long serialVersionUID = 8973438585188332404L; - - /** - * Constructor. - * - * @param details the error details - */ - public CmHandleRegistrationException(final String details) { - super("Not able to register the given cm-handles.", details); - } - -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/exception/DmiException.java b/src/main/java/org/onap/cps/ncmp/dmi/exception/DmiException.java deleted file mode 100644 index c099a1cc..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/exception/DmiException.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.dmi.exception; - -import lombok.Getter; - -/** - * Dmi exception. - */ -public class DmiException extends RuntimeException { - - private static final long serialVersionUID = 1481520410918497487L; - - @Getter - final String details; - - /** - * Constructor. - * - * @param message the error message - * @param details the error details - */ - public DmiException(final String message, final String details) { - super(message); - this.details = details; - } - - /** - * Constructor. - * - * @param message the error message - * @param details the error details - * @param cause the cause of the exception - */ - public DmiException(final String message, final String details, final Throwable cause) { - super(message, cause); - this.details = details; - } - -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/exception/DmiExceptionHandler.java b/src/main/java/org/onap/cps/ncmp/dmi/exception/DmiExceptionHandler.java deleted file mode 100644 index 49db7d8b..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/exception/DmiExceptionHandler.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.dmi.exception; - -import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.dmi.model.ErrorMessage; -import org.onap.cps.ncmp.dmi.rest.controller.DmiRestController; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.RestControllerAdvice; - -@Slf4j -@RestControllerAdvice(assignableTypes = {DmiRestController.class}) -public class DmiExceptionHandler { - - private DmiExceptionHandler() { - } - - /** - * Default exception handler. - * - * @param exception the exception to handle - * @return response with response code 500. - */ - @ExceptionHandler - public static ResponseEntity<Object> handleInternalServerErrorExceptions(final Exception exception) { - return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception); - } - - @ExceptionHandler({ModulesNotFoundException.class, ModuleResourceNotFoundException.class}) - public static ResponseEntity<Object> handleNotFoundExceptions(final DmiException exception) { - return buildErrorResponse(HttpStatus.NOT_FOUND, exception); - } - - @ExceptionHandler({CmHandleRegistrationException.class, DmiException.class}) - public static ResponseEntity<Object> handleAnyOtherDmiExceptions(final DmiException exception) { - return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception); - } - - private static ResponseEntity<Object> buildErrorResponse(final HttpStatus httpStatus, final Exception exception) { - logForNonDmiException(exception); - final var errorMessage = new ErrorMessage(); - errorMessage.setStatus(httpStatus.toString()); - errorMessage.setMessage(exception.getMessage()); - errorMessage.setDetails(exception instanceof DmiException ? ((DmiException) exception).getDetails() : - "Check logs for details."); - return new ResponseEntity<>(errorMessage, httpStatus); - } - - private static void logForNonDmiException(final Exception exception) { - if (exception.getCause() != null || !(exception instanceof DmiException)) { - log.error("Exception occurred", exception); - } - } -}
\ No newline at end of file diff --git a/src/main/java/org/onap/cps/ncmp/dmi/exception/HttpClientRequestException.java b/src/main/java/org/onap/cps/ncmp/dmi/exception/HttpClientRequestException.java deleted file mode 100644 index b4b0249f..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/exception/HttpClientRequestException.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021-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.dmi.exception; - -import lombok.Getter; -import org.springframework.http.HttpStatus; - -@Getter -public class HttpClientRequestException extends DmiException { - - private static final long serialVersionUID = 881438585188332404L; - - private final HttpStatus httpStatus; - - /** - * Constructor. - * - * @param cmHandle cmHandle identifier - * @param details response body from the client available as details - * @param httpStatus http status from the client - */ - public HttpClientRequestException(final String cmHandle, final String details, final HttpStatus httpStatus) { - super("Resource data request failed for CM Handle: " + cmHandle, details); - this.httpStatus = httpStatus; - } -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/exception/InvalidDatastoreException.java b/src/main/java/org/onap/cps/ncmp/dmi/exception/InvalidDatastoreException.java deleted file mode 100644 index aa5b0cb7..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/exception/InvalidDatastoreException.java +++ /dev/null @@ -1,32 +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.dmi.exception; - -public class InvalidDatastoreException extends RuntimeException { - /** - * Instantiates a new Invalid datastore exception. - * - * @param message the message - */ - public InvalidDatastoreException(final String message) { - super(message); - } -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/exception/ModuleResourceNotFoundException.java b/src/main/java/org/onap/cps/ncmp/dmi/exception/ModuleResourceNotFoundException.java deleted file mode 100644 index 65db2712..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/exception/ModuleResourceNotFoundException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.dmi.exception; - -public class ModuleResourceNotFoundException extends DmiException { - - private static final long serialVersionUID = 4764849097602543408L; - - private static final String ERROR_MESSAGE = "Module resource not found for given cmHandle: "; - - /** - * Constructor. - * - * @param cmHandle the cm handle - * @param details the details of the error - */ - public ModuleResourceNotFoundException(final String cmHandle, final String details) { - super(ERROR_MESSAGE + cmHandle, details); - } -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/exception/ModulesNotFoundException.java b/src/main/java/org/onap/cps/ncmp/dmi/exception/ModulesNotFoundException.java deleted file mode 100644 index ded54d91..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/exception/ModulesNotFoundException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.dmi.exception; - -public class ModulesNotFoundException extends DmiException { - - private static final long serialVersionUID = 980438585188332404L; - - private static final String ERROR_MESSAGE = "Not able to register the given cm-handles: "; - - /** - * Constructor. - * - * @param cmHandle cmHandle identifier - * @param details the error details - */ - public ModulesNotFoundException(final String cmHandle, final String details) { - super(ERROR_MESSAGE + cmHandle, details); - } -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/exception/SdncException.java b/src/main/java/org/onap/cps/ncmp/dmi/exception/SdncException.java deleted file mode 100644 index a83485a9..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/exception/SdncException.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Bell Canada - * ================================================================================ - * 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.dmi.exception; - -import org.springframework.http.HttpStatus; - -/* -Use this exception when SDNC contract fails - */ -public class SdncException extends DmiException { - - private static final long serialVersionUID = -2076096996672060566L; - - /** - * Constructor. - * - * @param message message - * @param httpStatus httpStatus - * @param responseBody responseBody - */ - public SdncException(final String message, final HttpStatus httpStatus, final String responseBody) { - super(message, String.format("sdnc http status: %s, response body : %s ", - httpStatus.toString(), - responseBody)); - } - - public SdncException(final String message, final String details, final Throwable cause) { - super(message, details, cause); - } - -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/notifications/async/AsyncTaskExecutor.java b/src/main/java/org/onap/cps/ncmp/dmi/notifications/async/AsyncTaskExecutor.java deleted file mode 100644 index 6a1c6d1d..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/notifications/async/AsyncTaskExecutor.java +++ /dev/null @@ -1,121 +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.dmi.notifications.async; - -import com.google.gson.JsonObject; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; -import java.util.function.Supplier; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.dmi.exception.HttpClientRequestException; -import org.onap.cps.ncmp.dmi.model.DataAccessRequest; -import org.onap.cps.ncmp.event.model.DmiAsyncRequestResponseEvent; -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Service; - -@Slf4j -@Service -@RequiredArgsConstructor -public class AsyncTaskExecutor { - - private final DmiAsyncRequestResponseEventProducer dmiAsyncRequestResponseEventProducer; - - private static final DmiAsyncRequestResponseEventCreator dmiAsyncRequestResponseEventCreator = - new DmiAsyncRequestResponseEventCreator(); - - private static final Map<DataAccessRequest.OperationEnum, HttpStatus> operationToHttpStatusMap = new HashMap<>(6); - - static { - operationToHttpStatusMap.put(null, HttpStatus.OK); - operationToHttpStatusMap.put(DataAccessRequest.OperationEnum.READ, HttpStatus.OK); - operationToHttpStatusMap.put(DataAccessRequest.OperationEnum.CREATE, HttpStatus.CREATED); - operationToHttpStatusMap.put(DataAccessRequest.OperationEnum.PATCH, HttpStatus.OK); - operationToHttpStatusMap.put(DataAccessRequest.OperationEnum.UPDATE, HttpStatus.OK); - operationToHttpStatusMap.put(DataAccessRequest.OperationEnum.DELETE, HttpStatus.NO_CONTENT); - } - - /** - * Execute task asynchronously and publish response to supplied topic. - * - * @param taskSupplier functional method is get() task need to executed asynchronously - * @param topicName topic name where message need to be published - * @param requestId unique requestId for async request - * @param operation the operation performed - * @param timeOutInMilliSeconds task timeout in milliseconds - */ - public void executeAsyncTask(final Supplier<String> taskSupplier, - final String topicName, - final String requestId, - final DataAccessRequest.OperationEnum operation, - final int timeOutInMilliSeconds) { - CompletableFuture.supplyAsync(taskSupplier::get) - .orTimeout(timeOutInMilliSeconds, TimeUnit.MILLISECONDS) - .whenCompleteAsync((resourceDataAsJson, throwable) -> { - if (throwable == null) { - final String status = operationToHttpStatusMap.get(operation).getReasonPhrase(); - final String code = String.valueOf(operationToHttpStatusMap.get(operation).value()); - publishAsyncEvent(topicName, requestId, resourceDataAsJson, status, code); - } else { - log.error("Error occurred with async request {}", throwable.getMessage()); - publishAsyncFailureEvent(topicName, requestId, throwable); - } - }); - log.info("Async task completed."); - } - - private void publishAsyncEvent(final String topicName, - final String requestId, - final String resourceDataAsJson, - final String status, - final String code) { - final DmiAsyncRequestResponseEvent cpsAsyncRequestResponseEvent = - dmiAsyncRequestResponseEventCreator.createEvent(resourceDataAsJson, topicName, requestId, status, code); - - dmiAsyncRequestResponseEventProducer.sendMessage(requestId, cpsAsyncRequestResponseEvent); - } - - private void publishAsyncFailureEvent(final String topicName, - final String requestId, - final Throwable throwable) { - HttpStatus httpStatus = HttpStatus.INTERNAL_SERVER_ERROR; - - if (throwable instanceof HttpClientRequestException) { - final HttpClientRequestException httpClientRequestException = (HttpClientRequestException) throwable; - httpStatus = httpClientRequestException.getHttpStatus(); - } - - final JsonObject errorDetails = new JsonObject(); - errorDetails.addProperty("errorDetails", throwable.getMessage()); - publishAsyncEvent( - topicName, - requestId, - errorDetails.toString(), - httpStatus.getReasonPhrase(), - String.valueOf(httpStatus.value()) - ); - } -} - - - diff --git a/src/main/java/org/onap/cps/ncmp/dmi/notifications/async/DmiAsyncRequestResponseEventCreator.java b/src/main/java/org/onap/cps/ncmp/dmi/notifications/async/DmiAsyncRequestResponseEventCreator.java deleted file mode 100644 index 1e6c84b1..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/notifications/async/DmiAsyncRequestResponseEventCreator.java +++ /dev/null @@ -1,90 +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.dmi.notifications.async; - -import com.fasterxml.jackson.databind.ObjectMapper; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; -import java.util.HashMap; -import java.util.UUID; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.dmi.Application; -import org.onap.cps.ncmp.event.model.DmiAsyncRequestResponseEvent; -import org.onap.cps.ncmp.event.model.EventContent; - -/** - * Helper to create DmiAsyncRequestResponseEvent. - */ -@Slf4j -public class DmiAsyncRequestResponseEventCreator { - - private static final DateTimeFormatter dateTimeFormatter - = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - - private final ObjectMapper objectMapper = new ObjectMapper(); - - /** - * Create an event. - * - * @param resourceDataAsJson the resource data as json - * @param topicParamInQuery the topic to send response to - * @param requestId the request id - * @param status the status of the request - * @param code the code of the response - * - * @return DmiAsyncRequestResponseEvent - */ - public DmiAsyncRequestResponseEvent createEvent(final String resourceDataAsJson, - final String topicParamInQuery, - final String requestId, - final String status, - final String code) { - final DmiAsyncRequestResponseEvent dmiAsyncRequestResponseEvent = new DmiAsyncRequestResponseEvent(); - - dmiAsyncRequestResponseEvent.setEventId(UUID.randomUUID().toString()); - dmiAsyncRequestResponseEvent.setEventCorrelationId(requestId); - dmiAsyncRequestResponseEvent.setEventType(DmiAsyncRequestResponseEvent.class.getName()); - dmiAsyncRequestResponseEvent.setEventSchema("urn:cps:" + DmiAsyncRequestResponseEvent.class.getName()); - dmiAsyncRequestResponseEvent.setEventSchemaVersion("v1"); - dmiAsyncRequestResponseEvent.setEventSource(Application.class.getPackageName()); - dmiAsyncRequestResponseEvent.setEventTarget(topicParamInQuery); - dmiAsyncRequestResponseEvent.setEventTime(ZonedDateTime.now().format(dateTimeFormatter)); - dmiAsyncRequestResponseEvent.setEventContent(getEventContent(resourceDataAsJson, status, code)); - - return dmiAsyncRequestResponseEvent; - } - - @SneakyThrows - private EventContent getEventContent(final String resourceDataAsJson, final String status, final String code) { - final EventContent eventContent = new EventContent(); - - eventContent.setResponseDataSchema("urn:cps:" + DmiAsyncRequestResponseEvent.class.getName() + ":v1"); - eventContent.setResponseStatus(status); - eventContent.setResponseCode(code); - - eventContent.setAdditionalProperty("response-data", - objectMapper.readValue(resourceDataAsJson, HashMap.class)); - - return eventContent; - } - -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/notifications/async/DmiAsyncRequestResponseEventProducer.java b/src/main/java/org/onap/cps/ncmp/dmi/notifications/async/DmiAsyncRequestResponseEventProducer.java deleted file mode 100644 index 00fea330..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/notifications/async/DmiAsyncRequestResponseEventProducer.java +++ /dev/null @@ -1,47 +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.dmi.notifications.async; - -import lombok.RequiredArgsConstructor; -import org.onap.cps.ncmp.event.model.DmiAsyncRequestResponseEvent; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class DmiAsyncRequestResponseEventProducer { - - private final KafkaTemplate<String, DmiAsyncRequestResponseEvent> kafkaTemplate; - - @Value("${app.ncmp.async.topic}") - private String dmiNcmpTopic; - - /** - * Sends message to the configured topic with a message key. - * - * @param requestId the request id - * @param dmiAsyncRequestResponseEvent the event to publish - */ - public void sendMessage(final String requestId, final DmiAsyncRequestResponseEvent dmiAsyncRequestResponseEvent) { - kafkaTemplate.send(dmiNcmpTopic, requestId, dmiAsyncRequestResponseEvent); - } -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/notifications/avc/DmiDataAvcCloudEventCreator.java b/src/main/java/org/onap/cps/ncmp/dmi/notifications/avc/DmiDataAvcCloudEventCreator.java deleted file mode 100644 index b8bd277d..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/notifications/avc/DmiDataAvcCloudEventCreator.java +++ /dev/null @@ -1,104 +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.dmi.notifications.avc; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.cloudevents.CloudEvent; -import io.cloudevents.core.builder.CloudEventBuilder; -import java.net.URI; -import java.time.format.DateTimeFormatter; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.events.avc1_0_0.AvcEvent; -import org.onap.cps.ncmp.events.avc1_0_0.Data; -import org.onap.cps.ncmp.events.avc1_0_0.DatastoreChanges; -import org.onap.cps.ncmp.events.avc1_0_0.Edit; -import org.onap.cps.ncmp.events.avc1_0_0.IetfYangPatchYangPatch; -import org.onap.cps.ncmp.events.avc1_0_0.PushChangeUpdate; -import org.onap.cps.ncmp.events.avc1_0_0.Value; - -/** - * Helper to create AvcEvents. - */ -@Slf4j -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class DmiDataAvcCloudEventCreator { - - private static final DateTimeFormatter dateTimeFormatter = - DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - - private static final ObjectMapper objectMapper = new ObjectMapper(); - - /** - * Creates CloudEvent for DMI Data AVC. - * - * @param eventCorrelationId correlationid - * @return Cloud Event - */ - public static CloudEvent createCloudEvent(final String eventCorrelationId) { - - CloudEvent cloudEvent = null; - - try { - cloudEvent = CloudEventBuilder.v1().withId(UUID.randomUUID().toString()).withSource(URI.create("NCMP")) - .withType(AvcEvent.class.getName()) - .withDataSchema(URI.create("urn:cps:" + AvcEvent.class.getName() + ":1.0.0")) - .withExtension("correlationid", eventCorrelationId) - .withData(objectMapper.writeValueAsBytes(createDmiDataAvcEvent())).build(); - } catch (final JsonProcessingException jsonProcessingException) { - log.error("Unable to convert object to json : {}", jsonProcessingException.getMessage()); - } - - return cloudEvent; - } - - private static AvcEvent createDmiDataAvcEvent() { - final AvcEvent avcEvent = new AvcEvent(); - final Data data = new Data(); - final PushChangeUpdate pushChangeUpdate = new PushChangeUpdate(); - final DatastoreChanges datastoreChanges = new DatastoreChanges(); - final IetfYangPatchYangPatch ietfYangPatchYangPatch = new IetfYangPatchYangPatch(); - ietfYangPatchYangPatch.setPatchId("abcd"); - final Edit edit1 = new Edit(); - final Value value = new Value(); - final Map<String, Object> attributeMap = new LinkedHashMap<>(); - attributeMap.put("isHoAllowed", false); - value.setAttributes(List.of(attributeMap)); - edit1.setEditId("editId"); - edit1.setOperation("replace"); - edit1.setTarget("target_xpath"); - edit1.setValue(value); - ietfYangPatchYangPatch.setEdit(List.of(edit1)); - datastoreChanges.setIetfYangPatchYangPatch(ietfYangPatchYangPatch); - pushChangeUpdate.setDatastoreChanges(datastoreChanges); - data.setPushChangeUpdate(pushChangeUpdate); - - avcEvent.setData(data); - return avcEvent; - } - -}
\ No newline at end of file diff --git a/src/main/java/org/onap/cps/ncmp/dmi/notifications/avc/DmiDataAvcEventProducer.java b/src/main/java/org/onap/cps/ncmp/dmi/notifications/avc/DmiDataAvcEventProducer.java deleted file mode 100644 index 075dcf20..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/notifications/avc/DmiDataAvcEventProducer.java +++ /dev/null @@ -1,50 +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.dmi.notifications.avc; - - -import io.cloudevents.CloudEvent; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.apache.kafka.clients.producer.ProducerRecord; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.stereotype.Service; - -@Service -@Slf4j -@RequiredArgsConstructor -public class DmiDataAvcEventProducer { - - private final KafkaTemplate<String, CloudEvent> cloudEventKafkaTemplate; - - /** - * Publishing DMI Data AVC event payload as CloudEvent. - * - * @param requestId the request id - * @param cloudAvcEvent event with data as DMI DataAVC event - */ - public void publishDmiDataAvcCloudEvent(final String requestId, final CloudEvent cloudAvcEvent) { - final ProducerRecord<String, CloudEvent> producerRecord = - new ProducerRecord<>("dmi-cm-events", requestId, cloudAvcEvent); - cloudEventKafkaTemplate.send(producerRecord); - log.debug("AVC event sent"); - } -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/notifications/avc/DmiDataAvcEventSimulationController.java b/src/main/java/org/onap/cps/ncmp/dmi/notifications/avc/DmiDataAvcEventSimulationController.java deleted file mode 100644 index c5fb8fbe..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/notifications/avc/DmiDataAvcEventSimulationController.java +++ /dev/null @@ -1,61 +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.dmi.notifications.avc; - -import io.cloudevents.CloudEvent; -import java.util.UUID; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - - -@RequestMapping("${rest.api.dmi-base-path}") -@RestController -@Slf4j -@RequiredArgsConstructor -public class DmiDataAvcEventSimulationController { - - private final DmiDataAvcEventProducer dmiDataAvcEventProducer; - - /** - * Simulate Event for AVC. - * - * @param numberOfSimulatedEvents number of events to be generated - * @return ResponseEntity - */ - @GetMapping(path = "/v1/simulateDmiDataEvent") - public ResponseEntity<Void> simulateEvents( - @RequestParam("numberOfSimulatedEvents") final Integer numberOfSimulatedEvents) { - - for (int i = 0; i < numberOfSimulatedEvents; i++) { - final String eventCorrelationId = UUID.randomUUID().toString(); - final CloudEvent cloudEvent = DmiDataAvcCloudEventCreator.createCloudEvent(eventCorrelationId); - dmiDataAvcEventProducer.publishDmiDataAvcCloudEvent(eventCorrelationId, cloudEvent); - } - - return new ResponseEntity<>(HttpStatus.OK); - } -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiInEventConsumer.java b/src/main/java/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiInEventConsumer.java deleted file mode 100644 index 3a9838b0..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiInEventConsumer.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2024 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.dmi.notifications.cmsubscription; - -import io.cloudevents.CloudEvent; -import lombok.RequiredArgsConstructor; -import org.apache.kafka.clients.consumer.ConsumerRecord; -import org.onap.cps.ncmp.dmi.notifications.cmsubscription.model.CmNotificationSubscriptionStatus; -import org.onap.cps.ncmp.dmi.notifications.mapper.CloudEventMapper; -import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.dmi_to_ncmp.CmNotificationSubscriptionDmiOutEvent; -import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.dmi_to_ncmp.Data; -import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.CmNotificationSubscriptionDmiInEvent; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.kafka.annotation.KafkaListener; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class CmNotificationSubscriptionDmiInEventConsumer { - - - @Value("${app.dmi.avc.cm-subscription-dmi-out}") - private String cmNotificationSubscriptionDmiOutTopic; - @Value("${dmi.service.name}") - private String dmiName; - private final KafkaTemplate<String, CloudEvent> cloudEventKafkaTemplate; - - /** - * Consume the cmNotificationSubscriptionDmiInCloudEvent event. - * - * @param cmNotificationSubscriptionDmiInCloudEvent the event to be consumed - */ - @KafkaListener(topics = "${app.dmi.avc.cm-subscription-dmi-in}", - containerFactory = "cloudEventConcurrentKafkaListenerContainerFactory") - public void consumeCmNotificationSubscriptionDmiInEvent( - final ConsumerRecord<String, CloudEvent> cmNotificationSubscriptionDmiInCloudEvent) { - final CmNotificationSubscriptionDmiInEvent cmNotificationSubscriptionDmiInEvent = - CloudEventMapper.toTargetEvent(cmNotificationSubscriptionDmiInCloudEvent.value(), - CmNotificationSubscriptionDmiInEvent.class); - if (cmNotificationSubscriptionDmiInEvent != null) { - final String subscriptionId = cmNotificationSubscriptionDmiInCloudEvent.value().getId(); - final String subscriptionType = cmNotificationSubscriptionDmiInCloudEvent.value().getType(); - final String correlationId = String.valueOf(cmNotificationSubscriptionDmiInCloudEvent.value() - .getExtension("correlationid")); - - if ("subscriptionCreateRequest".equals(subscriptionType)) { - createAndSendCmNotificationSubscriptionDmiOutEvent(subscriptionId, "subscriptionCreateResponse", - correlationId, CmNotificationSubscriptionStatus.ACCEPTED); - } else if ("subscriptionDeleteRequest".equals(subscriptionType)) { - createAndSendCmNotificationSubscriptionDmiOutEvent(subscriptionId, "subscriptionDeleteResponse", - correlationId, CmNotificationSubscriptionStatus.ACCEPTED); - } - } - } - - /** - * Create Dmi out event object and send to response topic. - * - * @param eventKey the events key - * @param subscriptionType the subscriptions type - * @param correlationId the events correlation Id - * @param cmNotificationSubscriptionStatus subscriptions status accepted/rejected - */ - public void createAndSendCmNotificationSubscriptionDmiOutEvent( - final String eventKey, final String subscriptionType, final String correlationId, - final CmNotificationSubscriptionStatus cmNotificationSubscriptionStatus) { - - final CmNotificationSubscriptionDmiOutEvent cmNotificationSubscriptionDmiOutEvent = - new CmNotificationSubscriptionDmiOutEvent(); - final Data cmNotificationSubscriptionDmiOutEventData = new Data(); - - if (cmNotificationSubscriptionStatus.equals(CmNotificationSubscriptionStatus.ACCEPTED)) { - cmNotificationSubscriptionDmiOutEventData.setStatusCode("1"); - cmNotificationSubscriptionDmiOutEventData.setStatusMessage("ACCEPTED"); - } else { - cmNotificationSubscriptionDmiOutEventData.setStatusCode("104"); - cmNotificationSubscriptionDmiOutEventData.setStatusMessage("REJECTED"); - } - cmNotificationSubscriptionDmiOutEvent.setData(cmNotificationSubscriptionDmiOutEventData); - - cloudEventKafkaTemplate.send(cmNotificationSubscriptionDmiOutTopic, eventKey, - CmNotificationSubscriptionDmiOutEventToCloudEventMapper.toCloudEvent(cmNotificationSubscriptionDmiOutEvent, - subscriptionType, dmiName, correlationId)); - - } - - - -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiOutEventToCloudEventMapper.java b/src/main/java/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiOutEventToCloudEventMapper.java deleted file mode 100644 index 51205da2..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiOutEventToCloudEventMapper.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2024 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.dmi.notifications.cmsubscription; - -import com.fasterxml.jackson.databind.ObjectMapper; -import io.cloudevents.CloudEvent; -import io.cloudevents.core.builder.CloudEventBuilder; -import java.net.URI; -import java.util.UUID; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.onap.cps.ncmp.dmi.exception.CloudEventConstructionException; -import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.dmi_to_ncmp.CmNotificationSubscriptionDmiOutEvent; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class CmNotificationSubscriptionDmiOutEventToCloudEventMapper { - - private static final ObjectMapper objectMapper = new ObjectMapper(); - - /** - * Maps SubscriptionEventResponse to a CloudEvent. - * - * @param cmSubscriptionDmiOutEvent object. - * @param subscriptionType String of subscription type. - * @param dmiName String of dmiName. - * @param correlationId String of correlationId. - * @return CloudEvent built. - */ - public static CloudEvent toCloudEvent(final CmNotificationSubscriptionDmiOutEvent cmSubscriptionDmiOutEvent, - final String subscriptionType, final String dmiName, - final String correlationId) { - try { - return CloudEventBuilder.v1().withId(UUID.randomUUID().toString()).withSource(URI.create(dmiName)) - .withType(subscriptionType) - .withDataSchema(URI.create("urn:cps:org.onap.ncmp.dmi.cm.subscription:1.0.0")) - .withExtension("correlationid", correlationId) - .withData(objectMapper.writeValueAsBytes(cmSubscriptionDmiOutEvent)).build(); - } catch (final Exception ex) { - throw new CloudEventConstructionException("The Cloud Event could not be constructed", - "Invalid object passed", ex); - } - } - -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/notifications/cmsubscription/model/CmNotificationSubscriptionStatus.java b/src/main/java/org/onap/cps/ncmp/dmi/notifications/cmsubscription/model/CmNotificationSubscriptionStatus.java deleted file mode 100644 index 40b1297f..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/notifications/cmsubscription/model/CmNotificationSubscriptionStatus.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2024 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.dmi.notifications.cmsubscription.model; - -public enum CmNotificationSubscriptionStatus { - - ACCEPTED("ACCEPTED"), REJECTED("REJECTED"); - - private final String cmNotificationSubscriptionStatusValue; - - CmNotificationSubscriptionStatus(final String cmNotificationSubscriptionStatusValue) { - this.cmNotificationSubscriptionStatusValue = cmNotificationSubscriptionStatusValue; - } -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/notifications/mapper/CloudEventMapper.java b/src/main/java/org/onap/cps/ncmp/dmi/notifications/mapper/CloudEventMapper.java deleted file mode 100644 index 8f196cfc..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/notifications/mapper/CloudEventMapper.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (c) 2024 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.dmi.notifications.mapper; - -import com.fasterxml.jackson.databind.ObjectMapper; -import io.cloudevents.CloudEvent; -import io.cloudevents.core.CloudEventUtils; -import io.cloudevents.core.data.PojoCloudEventData; -import io.cloudevents.jackson.PojoCloudEventDataMapper; -import io.cloudevents.rw.CloudEventRWException; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class CloudEventMapper { - - private static final ObjectMapper objectMapper = new ObjectMapper(); - - /** - * Generic method to map cloud event data to target event class object. - * - * @param cloudEvent input cloud event - * @param targetEventClass target event class - * @param <T> target event class type - * @return mapped target event - */ - public static <T> T toTargetEvent(final CloudEvent cloudEvent, final Class<T> targetEventClass) { - PojoCloudEventData<T> mappedCloudEvent = null; - - try { - mappedCloudEvent = - CloudEventUtils.mapData(cloudEvent, PojoCloudEventDataMapper.from(objectMapper, targetEventClass)); - - } catch (final CloudEventRWException cloudEventRwException) { - log.error("Unable to map cloud event to target event class type : {} with cause : {}", targetEventClass, - cloudEventRwException.getMessage()); - } - - return mappedCloudEvent == null ? null : mappedCloudEvent.getValue(); - } - -}
\ No newline at end of file diff --git a/src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java b/src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java deleted file mode 100644 index cad5e726..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2023 Nordix Foundation - * Modifications Copyright (C) 2022 Bell Canada - * ================================================================================ - * 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.dmi.rest.controller; - -import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.dmi.model.CmHandles; -import org.onap.cps.ncmp.dmi.model.DataAccessRequest; -import org.onap.cps.ncmp.dmi.model.ModuleReferencesRequest; -import org.onap.cps.ncmp.dmi.model.ModuleResourcesReadRequest; -import org.onap.cps.ncmp.dmi.model.ModuleSet; -import org.onap.cps.ncmp.dmi.model.ResourceDataOperationRequests; -import org.onap.cps.ncmp.dmi.model.YangResources; -import org.onap.cps.ncmp.dmi.notifications.async.AsyncTaskExecutor; -import org.onap.cps.ncmp.dmi.rest.api.DmiPluginApi; -import org.onap.cps.ncmp.dmi.rest.api.DmiPluginInternalApi; -import org.onap.cps.ncmp.dmi.rest.controller.handlers.DatastoreType; -import org.onap.cps.ncmp.dmi.service.DmiService; -import org.onap.cps.ncmp.dmi.service.model.ModuleReference; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RequestMapping("${rest.api.dmi-base-path}") -@RestController -@Slf4j -@RequiredArgsConstructor -public class DmiRestController implements DmiPluginApi, DmiPluginInternalApi { - - private final DmiService dmiService; - private final ObjectMapper objectMapper; - private final AsyncTaskExecutor asyncTaskExecutor; - private static final Map<OperationEnum, HttpStatus> operationToHttpStatusMap = new HashMap<>(6); - - @Value("${notification.async.executor.time-out-value-in-ms:2000}") - private int timeOutInMillis; - - static { - operationToHttpStatusMap.put(null, HttpStatus.OK); - operationToHttpStatusMap.put(OperationEnum.READ, HttpStatus.OK); - operationToHttpStatusMap.put(OperationEnum.CREATE, HttpStatus.CREATED); - operationToHttpStatusMap.put(OperationEnum.PATCH, HttpStatus.OK); - operationToHttpStatusMap.put(OperationEnum.UPDATE, HttpStatus.OK); - operationToHttpStatusMap.put(OperationEnum.DELETE, HttpStatus.NO_CONTENT); - } - - @Override - public ResponseEntity<ModuleSet> getModuleReferences(final String cmHandle, - final ModuleReferencesRequest body) { - // For onap-dmi-plugin we don't need cmHandleProperties, so DataAccessReadRequest is not used. - final ModuleSet moduleSet = dmiService.getModulesForCmHandle(cmHandle); - return ResponseEntity.ok(moduleSet); - } - - @Override - public ResponseEntity<YangResources> retrieveModuleResources( - final String cmHandle, - final ModuleResourcesReadRequest moduleResourcesReadRequest) { - final List<ModuleReference> moduleReferences = convertRestObjectToJavaApiObject(moduleResourcesReadRequest); - final YangResources yangResources = dmiService.getModuleResources(cmHandle, moduleReferences); - log.info("Module set tag received: {}", moduleResourcesReadRequest.getModuleSetTag()); - return new ResponseEntity<>(yangResources, HttpStatus.OK); - } - - /** - * This method register given list of cm-handles to ncmp. - * - * @param cmHandles list of cm-handles - * @return (@ code ResponseEntity) response entity - */ - public ResponseEntity<String> registerCmHandles(final CmHandles cmHandles) { - final List<String> cmHandlesList = cmHandles.getCmHandles(); - if (cmHandlesList.isEmpty()) { - return new ResponseEntity<>("Need at least one cmHandle to process.", HttpStatus.BAD_REQUEST); - } - dmiService.registerCmHandles(cmHandlesList); - return new ResponseEntity<>("cm-handle registered successfully.", HttpStatus.CREATED); - } - - /** - * This method is not implemented for ONAP DMI plugin. - * - * @param topic client given topic name - * @param requestId requestId generated by NCMP as an ack for client - * @param resourceDataOperationRequests list of operation details - * @return (@ code ResponseEntity) response entity - */ - @Override - public ResponseEntity<Void> getResourceDataForCmHandleDataOperation(final String topic, final String requestId, - final ResourceDataOperationRequests resourceDataOperationRequests) { - log.info("Request Details (for testing purposes)"); - log.info("Request Id: {}", requestId); - log.info("Topic: {}", topic); - - log.info("Details of the first Operation"); - log.info("Resource Identifier: {}", resourceDataOperationRequests.get(0).getResourceIdentifier()); - log.info("Module Set Tag: {}", resourceDataOperationRequests.get(0).getCmHandles().get(0).getModuleSetTag()); - log.info("Operation Id: {}", resourceDataOperationRequests.get(0).getOperationId()); - log.info("Cm Handles: {}", resourceDataOperationRequests.get(0).getCmHandles()); - log.info("Options: {}", resourceDataOperationRequests.get(0).getOptions()); - - return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); - } - - /** - * This method fetches the resource for given cm handle using pass through operational or running datastore. - * It filters the response on the basis of options query parameters and returns response. Passthrough Running - * supports both read and write operation whereas passthrough operational does not support write operations. - * - * @param datastoreName name of the datastore - * @param cmHandle cm handle identifier - * @param resourceIdentifier resource identifier to fetch data - * @param optionsParamInQuery options query parameter - * @param topicParamInQuery topic name for (triggering) async responses - * @param dataAccessRequest data Access Request - * @return {@code ResponseEntity} response entity - */ - @Override - public ResponseEntity<Object> dataAccessPassthrough(final String datastoreName, - final String cmHandle, - final String resourceIdentifier, - final String optionsParamInQuery, - final String topicParamInQuery, - final DataAccessRequest dataAccessRequest) { - log.info("Module set tag: {}", dataAccessRequest.getModuleSetTag()); - if (DatastoreType.PASSTHROUGH_OPERATIONAL == DatastoreType.fromDatastoreName(datastoreName)) { - return dataAccessPassthroughOperational(resourceIdentifier, cmHandle, dataAccessRequest, - optionsParamInQuery, topicParamInQuery); - } - return dataAccessPassthroughRunning(resourceIdentifier, cmHandle, dataAccessRequest, - optionsParamInQuery, topicParamInQuery); - } - - private ResponseEntity<Object> dataAccessPassthroughOperational(final String resourceIdentifier, - final String cmHandle, - final DataAccessRequest dataAccessRequest, - final String optionsParamInQuery, - final String topicParamInQuery) { - if (isReadOperation(dataAccessRequest)) { - if (hasTopic(topicParamInQuery)) { - return handleAsyncRequest(resourceIdentifier, cmHandle, dataAccessRequest, optionsParamInQuery, - topicParamInQuery); - } - - final String resourceDataAsJson = dmiService.getResourceData(cmHandle, resourceIdentifier, - optionsParamInQuery, DmiService.RESTCONF_CONTENT_PASSTHROUGH_OPERATIONAL_QUERY_PARAM); - return ResponseEntity.ok(resourceDataAsJson); - } - return new ResponseEntity<>(HttpStatus.BAD_REQUEST); - } - - private ResponseEntity<Object> dataAccessPassthroughRunning(final String resourceIdentifier, - final String cmHandle, - final DataAccessRequest dataAccessRequest, - final String optionsParamInQuery, - final String topicParamInQuery) { - if (hasTopic(topicParamInQuery)) { - asyncTaskExecutor.executeAsyncTask(() -> - getSdncResponseForPassThroughRunning( - resourceIdentifier, - cmHandle, - dataAccessRequest, - optionsParamInQuery), - topicParamInQuery, - dataAccessRequest.getRequestId(), - dataAccessRequest.getOperation(), - timeOutInMillis - ); - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } - - final String sdncResponse = - getSdncResponseForPassThroughRunning(resourceIdentifier, cmHandle, dataAccessRequest, optionsParamInQuery); - return new ResponseEntity<>(sdncResponse, operationToHttpStatusMap.get(dataAccessRequest.getOperation())); - } - - private String getSdncResponseForPassThroughRunning(final String resourceIdentifier, - final String cmHandle, - final DataAccessRequest dataAccessRequest, - final String optionsParamInQuery) { - if (isReadOperation(dataAccessRequest)) { - return dmiService.getResourceData(cmHandle, resourceIdentifier, optionsParamInQuery, - DmiService.RESTCONF_CONTENT_PASSTHROUGH_RUNNING_QUERY_PARAM); - } - - return dmiService.writeData(dataAccessRequest.getOperation(), cmHandle, resourceIdentifier, - dataAccessRequest.getDataType(), dataAccessRequest.getData()); - } - - private boolean isReadOperation(final DataAccessRequest dataAccessRequest) { - return dataAccessRequest.getOperation() == null - || dataAccessRequest.getOperation().equals(DataAccessRequest.OperationEnum.READ); - } - - private List<ModuleReference> convertRestObjectToJavaApiObject( - final ModuleResourcesReadRequest moduleResourcesReadRequest) { - return objectMapper - .convertValue(moduleResourcesReadRequest.getData().getModules(), - new TypeReference<List<ModuleReference>>() {}); - } - - private boolean hasTopic(final String topicParamInQuery) { - return !(topicParamInQuery == null || topicParamInQuery.isBlank()); - } - - private ResponseEntity<Object> handleAsyncRequest(final String resourceIdentifier, - final String cmHandle, - final DataAccessRequest dataAccessRequest, - final String optionsParamInQuery, - final String topicParamInQuery) { - asyncTaskExecutor.executeAsyncTask(() -> - dmiService.getResourceData( - cmHandle, - resourceIdentifier, - optionsParamInQuery, - DmiService.RESTCONF_CONTENT_PASSTHROUGH_OPERATIONAL_QUERY_PARAM), - topicParamInQuery, - dataAccessRequest.getRequestId(), - dataAccessRequest.getOperation(), - timeOutInMillis - ); - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } - -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/rest/controller/handlers/DatastoreType.java b/src/main/java/org/onap/cps/ncmp/dmi/rest/controller/handlers/DatastoreType.java deleted file mode 100644 index 3f280403..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/rest/controller/handlers/DatastoreType.java +++ /dev/null @@ -1,65 +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.dmi.rest.controller.handlers; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import lombok.Getter; -import org.onap.cps.ncmp.dmi.exception.InvalidDatastoreException; - -@Getter -public enum DatastoreType { - - PASSTHROUGH_RUNNING("ncmp-datastore:passthrough-running"), - PASSTHROUGH_OPERATIONAL("ncmp-datastore:passthrough-operational"); - - DatastoreType(final String datastoreName) { - this.datastoreName = datastoreName; - } - - private final String datastoreName; - private static final Map<String, DatastoreType> datastoreNameToDatastoreType = new HashMap<>(); - - static { - Arrays.stream(DatastoreType.values()).forEach( - type -> datastoreNameToDatastoreType.put(type.getDatastoreName(), type)); - } - - /** - * From datastore name get datastore type. - * - * @param datastoreName the datastore name - * @return the datastore type - */ - public static DatastoreType fromDatastoreName(final String datastoreName) { - - final DatastoreType datastoreType = datastoreNameToDatastoreType.get(datastoreName); - - if (null == datastoreType) { - throw new InvalidDatastoreException(datastoreName + " is an invalid datastore name"); - } - - return datastoreType; - } - -} - diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java b/src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java deleted file mode 100644 index f0826a81..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2023 Nordix Foundation - * Modifications Copyright (C) 2022 Bell Canada - * ================================================================================ - * 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.dmi.service; - -import jakarta.validation.constraints.NotNull; -import java.util.List; -import org.onap.cps.ncmp.dmi.exception.DmiException; -import org.onap.cps.ncmp.dmi.model.DataAccessRequest; -import org.onap.cps.ncmp.dmi.model.ModuleSet; -import org.onap.cps.ncmp.dmi.model.YangResources; -import org.onap.cps.ncmp.dmi.service.model.ModuleReference; - - - -/** - * Interface for handling Dmi plugin Data. - */ -public interface DmiService { - - String RESTCONF_CONTENT_PASSTHROUGH_OPERATIONAL_QUERY_PARAM = "content=all"; - String RESTCONF_CONTENT_PASSTHROUGH_RUNNING_QUERY_PARAM = "content=config"; - - /** - * This method fetches all modules for given Cm Handle. - * - * @param cmHandle cm-handle to fetch the modules information - * @return {@code String} returns all modules - * @throws DmiException can throw dmi exception - */ - ModuleSet getModulesForCmHandle(String cmHandle) throws DmiException; - - /** - * This method used to register the given {@code CmHandles} which contains list of {@code CmHandle} to cps - * repository. - * - * @param cmHandles list of cm-handles - */ - void registerCmHandles(List<String> cmHandles); - - /** - * Get module resources for the given cm handle and modules. - * - * @param cmHandle cmHandle - * @param modules a list of module data - * @return returns all yang resources - */ - YangResources getModuleResources(String cmHandle, List<ModuleReference> modules); - - /** - * This method use to fetch the resource data from cm handle for the given datastore and resource - * Identifier. Options query parameter are used to filter the response from network resource. - * - * @param cmHandle cm handle identifier - * @param resourceIdentifier resource identifier - * @param optionsParamInQuery options query parameter - * @param restconfContentQueryParam restconf content i.e. datastore to use - * @return {@code Object} response from network function - */ - String getResourceData(@NotNull String cmHandle, - @NotNull String resourceIdentifier, - String optionsParamInQuery, - String restconfContentQueryParam); - - /** - * Write resource data to sdnc (will default to 'content=config', does not need to be specified). - * - * @param cmHandle cmHandle - * @param resourceIdentifier resource identifier - * @param dataType accept header parameter - * @param data request data - * @return response from sdnc - */ - String writeData(DataAccessRequest.OperationEnum operation, String cmHandle, - String resourceIdentifier, String dataType, - String data); -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java b/src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java deleted file mode 100644 index 6acbe09b..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2023 Nordix Foundation - * Modifications Copyright (C) 2021-2022 Bell Canada - * ================================================================================ - * 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.dmi.service; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectWriter; -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.dmi.config.DmiPluginConfig.DmiPluginProperties; -import org.onap.cps.ncmp.dmi.exception.CmHandleRegistrationException; -import org.onap.cps.ncmp.dmi.exception.DmiException; -import org.onap.cps.ncmp.dmi.exception.HttpClientRequestException; -import org.onap.cps.ncmp.dmi.exception.ModuleResourceNotFoundException; -import org.onap.cps.ncmp.dmi.exception.ModulesNotFoundException; -import org.onap.cps.ncmp.dmi.model.DataAccessRequest; -import org.onap.cps.ncmp.dmi.model.ModuleSet; -import org.onap.cps.ncmp.dmi.model.ModuleSetSchemasInner; -import org.onap.cps.ncmp.dmi.model.YangResource; -import org.onap.cps.ncmp.dmi.model.YangResources; -import org.onap.cps.ncmp.dmi.service.client.NcmpRestClient; -import org.onap.cps.ncmp.dmi.service.model.CmHandleOperation; -import org.onap.cps.ncmp.dmi.service.model.CreatedCmHandle; -import org.onap.cps.ncmp.dmi.service.model.ModuleReference; -import org.onap.cps.ncmp.dmi.service.model.ModuleSchema; -import org.onap.cps.ncmp.dmi.service.operation.SdncOperations; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Service; - -@Service -@Slf4j -public class DmiServiceImpl implements DmiService { - - private SdncOperations sdncOperations; - private NcmpRestClient ncmpRestClient; - private ObjectMapper objectMapper; - private DmiPluginProperties dmiPluginProperties; - - /** - * Constructor. - * - * @param dmiPluginProperties dmiPluginProperties - * @param ncmpRestClient ncmpRestClient - * @param sdncOperations sdncOperations - * @param objectMapper objectMapper - */ - public DmiServiceImpl(final DmiPluginProperties dmiPluginProperties, - final NcmpRestClient ncmpRestClient, - final SdncOperations sdncOperations, final ObjectMapper objectMapper) { - this.dmiPluginProperties = dmiPluginProperties; - this.ncmpRestClient = ncmpRestClient; - this.objectMapper = objectMapper; - this.sdncOperations = sdncOperations; - } - - @Override - public ModuleSet getModulesForCmHandle(final String cmHandle) throws DmiException { - final Collection<ModuleSchema> moduleSchemas = sdncOperations.getModuleSchemasFromNode(cmHandle); - if (moduleSchemas.isEmpty()) { - throw new ModulesNotFoundException(cmHandle, "SDNC returned no modules for given cm-handle."); - } else { - final ModuleSet moduleSet = new ModuleSet(); - moduleSchemas.forEach(moduleSchema -> - moduleSet.addSchemasItem(toModuleSetSchemas(moduleSchema))); - return moduleSet; - } - } - - @Override - public YangResources getModuleResources(final String cmHandle, final List<ModuleReference> moduleReferences) { - final YangResources yangResources = new YangResources(); - for (final ModuleReference moduleReference : moduleReferences) { - final String moduleRequest = createModuleRequest(moduleReference); - final ResponseEntity<String> responseEntity = sdncOperations.getModuleResource(cmHandle, moduleRequest); - if (responseEntity.getStatusCode() == HttpStatus.OK) { - final YangResource yangResource = YangResourceExtractor.toYangResource(moduleReference, responseEntity); - yangResources.add(yangResource); - } else if (responseEntity.getStatusCode() == HttpStatus.NOT_FOUND) { - log.error("SDNC did not return a module resource for the given cmHandle {}", cmHandle); - throw new ModuleResourceNotFoundException(cmHandle, - "SDNC did not return a module resource for the given cmHandle."); - } else { - log.error("Error occurred when getting module resources from SDNC for the given cmHandle {}", cmHandle); - throw new HttpClientRequestException( - cmHandle, responseEntity.getBody(), (HttpStatus) responseEntity.getStatusCode()); - } - } - return yangResources; - } - - @Override - public void registerCmHandles(final List<String> cmHandles) { - final CmHandleOperation cmHandleOperation = new CmHandleOperation(); - cmHandleOperation.setDmiPlugin(dmiPluginProperties.getDmiServiceUrl()); - final List<CreatedCmHandle> createdCmHandleList = new ArrayList<>(); - for (final String cmHandle : cmHandles) { - final CreatedCmHandle createdCmHandle = new CreatedCmHandle(); - createdCmHandle.setCmHandle(cmHandle); - createdCmHandleList.add(createdCmHandle); - } - cmHandleOperation.setCreatedCmHandles(createdCmHandleList); - final String cmHandlesJson; - try { - cmHandlesJson = objectMapper.writeValueAsString(cmHandleOperation); - } catch (final JsonProcessingException e) { - log.error("Parsing error occurred while converting cm-handles to JSON {}", cmHandles); - throw new DmiException("Internal Server Error.", - "Parsing error occurred while converting given cm-handles object list to JSON "); - } - final ResponseEntity<String> responseEntity = ncmpRestClient.registerCmHandlesWithNcmp(cmHandlesJson); - if (!responseEntity.getStatusCode().is2xxSuccessful()) { - throw new CmHandleRegistrationException(responseEntity.getBody()); - } - } - - private ModuleSetSchemasInner toModuleSetSchemas(final ModuleSchema moduleSchema) { - final ModuleSetSchemasInner moduleSetSchemas = new ModuleSetSchemasInner(); - moduleSetSchemas.setModuleName(moduleSchema.getIdentifier()); - moduleSetSchemas.setNamespace(moduleSchema.getNamespace()); - moduleSetSchemas.setRevision(moduleSchema.getVersion()); - return moduleSetSchemas; - } - - @Override - public String getResourceData(final String cmHandle, - final String resourceIdentifier, - final String optionsParamInQuery, - final String restconfContentQueryParam) { - final ResponseEntity<String> responseEntity = sdncOperations.getResouceDataForOperationalAndRunning(cmHandle, - resourceIdentifier, - optionsParamInQuery, - restconfContentQueryParam); - return prepareAndSendResponse(responseEntity, cmHandle); - } - - @Override - public String writeData(final DataAccessRequest.OperationEnum operation, - final String cmHandle, - final String resourceIdentifier, - final String dataType, final String data) { - final ResponseEntity<String> responseEntity = - sdncOperations.writeData(operation, cmHandle, resourceIdentifier, dataType, data); - return prepareAndSendResponse(responseEntity, cmHandle); - } - - private String prepareAndSendResponse(final ResponseEntity<String> responseEntity, final String cmHandle) { - if (responseEntity.getStatusCode().is2xxSuccessful()) { - return responseEntity.getBody(); - } else { - throw new HttpClientRequestException(cmHandle, responseEntity.getBody(), - (HttpStatus) responseEntity.getStatusCode()); - } - } - - private String createModuleRequest(final ModuleReference moduleReference) { - final Map<String, String> ietfNetconfModuleReferences = new LinkedHashMap<>(); - ietfNetconfModuleReferences.put("ietf-netconf-monitoring:identifier", moduleReference.getName()); - ietfNetconfModuleReferences.put("ietf-netconf-monitoring:version", moduleReference.getRevision()); - final ObjectWriter objectWriter = objectMapper.writer().withRootName("ietf-netconf-monitoring:input"); - final String moduleRequest; - try { - moduleRequest = objectWriter.writeValueAsString(ietfNetconfModuleReferences); - } catch (final JsonProcessingException e) { - log.error("JSON exception occurred when creating the module request for the given module reference {}", - moduleReference.getName()); - throw new DmiException("Unable to process JSON.", - "JSON exception occurred when creating the module request.", e); - } - return moduleRequest; - } - -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/YangResourceExtractor.java b/src/main/java/org/onap/cps/ncmp/dmi/service/YangResourceExtractor.java deleted file mode 100644 index d41240b9..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/service/YangResourceExtractor.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.dmi.service; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.dmi.exception.ModuleResourceNotFoundException; -import org.onap.cps.ncmp.dmi.model.YangResource; -import org.onap.cps.ncmp.dmi.service.model.ModuleReference; -import org.springframework.http.ResponseEntity; - -@Slf4j -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class YangResourceExtractor { - - static YangResource toYangResource(final ModuleReference moduleReference, - final ResponseEntity<String> responseEntity) { - final YangResource yangResource = new YangResource(); - yangResource.setModuleName(moduleReference.getName()); - yangResource.setRevision(moduleReference.getRevision()); - yangResource.setYangSource(extractYangSourceFromBody(responseEntity)); - return yangResource; - } - - private static String extractYangSourceFromBody(final ResponseEntity<String> responseEntity) { - final JsonObject responseBodyAsJsonObject = new Gson().fromJson(responseEntity.getBody(), JsonObject.class); - final JsonObject monitoringOutputAsJsonObject = - responseBodyAsJsonObject.getAsJsonObject("ietf-netconf-monitoring:output"); - if (monitoringOutputAsJsonObject == null - || monitoringOutputAsJsonObject.getAsJsonPrimitive("data") == null) { - log.error("Error occurred when trying to parse the response body from sdnc {}", responseEntity.getBody()); - throw new ModuleResourceNotFoundException(responseEntity.getBody(), - "Error occurred when trying to parse the response body from sdnc."); - } - return monitoringOutputAsJsonObject.getAsJsonPrimitive("data").getAsString(); - } - -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/client/NcmpRestClient.java b/src/main/java/org/onap/cps/ncmp/dmi/service/client/NcmpRestClient.java deleted file mode 100644 index 94783f3b..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/service/client/NcmpRestClient.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.dmi.service.client; - -import org.onap.cps.ncmp.dmi.config.DmiConfiguration.CpsProperties; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; -import org.springframework.web.util.UriComponentsBuilder; - -@Component -public class NcmpRestClient { - - private CpsProperties cpsProperties; - private RestTemplate restTemplate; - - public NcmpRestClient(final CpsProperties cpsProperties, final RestTemplate restTemplate) { - this.cpsProperties = cpsProperties; - this.restTemplate = restTemplate; - } - - /** - * Register a cmHandle with NCMP using a HTTP call. - * @param jsonData json data - * @return the response entity - */ - public ResponseEntity<String> registerCmHandlesWithNcmp(final String jsonData) { - final var ncmpRegistrationUrl = buildNcmpRegistrationUrl(); - final var httpHeaders = new HttpHeaders(); - httpHeaders.setBasicAuth(cpsProperties.getAuthUsername(), cpsProperties.getAuthPassword()); - httpHeaders.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); - final var httpEntity = new HttpEntity<>(jsonData, httpHeaders); - return restTemplate.exchange(ncmpRegistrationUrl, HttpMethod.POST, httpEntity, String.class); - } - - private String buildNcmpRegistrationUrl() { - return UriComponentsBuilder - .fromHttpUrl(cpsProperties.getBaseUrl()) - .path(cpsProperties.getDmiRegistrationUrl()) - .toUriString(); - } -}
\ No newline at end of file diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java b/src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java deleted file mode 100644 index 179707ab..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021-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.dmi.service.client; - -import org.onap.cps.ncmp.dmi.config.DmiConfiguration.SdncProperties; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; - -@Component -public class SdncRestconfClient { - - private SdncProperties sdncProperties; - private RestTemplate restTemplate; - - public SdncRestconfClient(final SdncProperties sdncProperties, final RestTemplate restTemplate) { - this.sdncProperties = sdncProperties; - this.restTemplate = restTemplate; - } - - /** - * restconf get operation on sdnc. - * - * @param getResourceUrl sdnc get url - * @return the response entity - */ - public ResponseEntity<String> getOperation(final String getResourceUrl) { - return getOperation(getResourceUrl, new HttpHeaders()); - } - - /** - * Overloaded restconf get operation on sdnc with http headers. - * - * @param getResourceUrl sdnc get url - * @param httpHeaders http headers - * @return the response entity - */ - public ResponseEntity<String> getOperation(final String getResourceUrl, final HttpHeaders httpHeaders) { - return httpOperationWithJsonData(HttpMethod.GET, getResourceUrl, null, httpHeaders); - } - - /** - * restconf http operations on sdnc. - * - * @param httpMethod HTTP Method - * @param resourceUrl sdnc resource url - * @param jsonData json data - * @param httpHeaders HTTP Headers - * @return response entity - */ - public ResponseEntity<String> httpOperationWithJsonData(final HttpMethod httpMethod, - final String resourceUrl, - final String jsonData, - final HttpHeaders httpHeaders) { - final String sdncBaseUrl = sdncProperties.getBaseUrl(); - final String sdncRestconfUrl = sdncBaseUrl.concat(resourceUrl); - httpHeaders.setBasicAuth(sdncProperties.getAuthUsername(), sdncProperties.getAuthPassword()); - final HttpEntity<String> httpEntity; - if (jsonData == null) { - httpEntity = new HttpEntity<>(httpHeaders); - } else { - httpEntity = new HttpEntity<>(jsonData, httpHeaders); - } - return restTemplate.exchange(sdncRestconfUrl, httpMethod, httpEntity, String.class); - } -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/model/CmHandleOperation.java b/src/main/java/org/onap/cps/ncmp/dmi/service/model/CmHandleOperation.java deleted file mode 100644 index 82eac92a..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/service/model/CmHandleOperation.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.dmi.service.model; - -import com.fasterxml.jackson.annotation.JsonInclude; -import java.util.List; -import lombok.Getter; -import lombok.Setter; - -@JsonInclude(JsonInclude.Include.NON_NULL) -@Getter -@Setter -public class CmHandleOperation { - - private String dmiPlugin; - private List<CreatedCmHandle> createdCmHandles; -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/model/CreatedCmHandle.java b/src/main/java/org/onap/cps/ncmp/dmi/service/model/CreatedCmHandle.java deleted file mode 100644 index 6ab6a01e..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/service/model/CreatedCmHandle.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.dmi.service.model; - -import com.fasterxml.jackson.annotation.JsonInclude; -import java.util.Map; -import lombok.Getter; -import lombok.Setter; - -@JsonInclude(JsonInclude.Include.NON_NULL) -@Getter -@Setter -public class CreatedCmHandle { - - private String cmHandle; - private Map<String, String> cmHandleProperties; - -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/model/ModuleReference.java b/src/main/java/org/onap/cps/ncmp/dmi/service/model/ModuleReference.java deleted file mode 100644 index 75c37dff..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/service/model/ModuleReference.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.dmi.service.model; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; - -/** - * Module Reference. - */ -@Getter -@Setter -@EqualsAndHashCode -public class ModuleReference { - - private String name; - private String revision; -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/model/ModuleSchema.java b/src/main/java/org/onap/cps/ncmp/dmi/service/model/ModuleSchema.java deleted file mode 100644 index c77e0e41..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/service/model/ModuleSchema.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation - * Modifications Copyright (C) 2021 Bell Canada - * ================================================================================ - * 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.dmi.service.model; - -import java.util.List; -import lombok.Data; - -@Data -public class ModuleSchema { - - private String identifier; - private String version; - private String format; - private String namespace; - private List<String> location; - -} diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java b/src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java deleted file mode 100644 index fd94e634..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2023 Nordix Foundation - * Modifications Copyright (C) 2021-2022 Bell Canada - * ================================================================================ - * 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.dmi.service.operation; - -import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum; - -import com.jayway.jsonpath.Configuration; -import com.jayway.jsonpath.JsonPath; -import com.jayway.jsonpath.JsonPathException; -import com.jayway.jsonpath.TypeRef; -import com.jayway.jsonpath.spi.json.JacksonJsonProvider; -import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import org.onap.cps.ncmp.dmi.config.DmiConfiguration.SdncProperties; -import org.onap.cps.ncmp.dmi.exception.SdncException; -import org.onap.cps.ncmp.dmi.model.DataAccessRequest; -import org.onap.cps.ncmp.dmi.service.client.SdncRestconfClient; -import org.onap.cps.ncmp.dmi.service.model.ModuleSchema; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.util.UriComponentsBuilder; - -@Component -public class SdncOperations { - - private static final String TOPOLOGY_URL_TEMPLATE_DATA = "/rests/data/network-topology:network-topology/"; - private static final String TOPOLOGY_URL_TEMPLATE_OPERATIONAL = - "/rests/operations/network-topology:network-topology/"; - private static final String GET_SCHEMA_URL = "ietf-netconf-monitoring:netconf-state/schemas"; - private static final String GET_SCHEMA_SOURCES_URL = "/ietf-netconf-monitoring:get-schema"; - private static final String PATH_TO_MODULE_SCHEMAS = "$.ietf-netconf-monitoring:schemas.schema"; - private static final int QUERY_PARAM_SPLIT_LIMIT = 2; - private static final int QUERY_PARAM_VALUE_INDEX = 1; - private static final int QUERY_PARAM_NAME_INDEX = 0; - - private static EnumMap<OperationEnum, HttpMethod> operationToHttpMethodMap = new EnumMap<>(OperationEnum.class); - - static { - operationToHttpMethodMap.put(OperationEnum.READ, HttpMethod.GET); - operationToHttpMethodMap.put(OperationEnum.CREATE, HttpMethod.POST); - operationToHttpMethodMap.put(OperationEnum.PATCH, HttpMethod.PATCH); - operationToHttpMethodMap.put(OperationEnum.UPDATE, HttpMethod.PUT); - operationToHttpMethodMap.put(OperationEnum.DELETE, HttpMethod.DELETE); - } - - private final SdncProperties sdncProperties; - private final SdncRestconfClient sdncRestconfClient; - private final String topologyUrlData; - private final String topologyUrlOperational; - - private Configuration jsonPathConfiguration = Configuration.builder() - .mappingProvider(new JacksonMappingProvider()) - .jsonProvider(new JacksonJsonProvider()) - .build(); - - /** - * Constructor for {@code SdncOperations}. This method also manipulates url properties. - * - * @param sdncProperties {@code SdncProperties} - * @param sdncRestconfClient {@code SdncRestconfClient} - */ - public SdncOperations(final SdncProperties sdncProperties, final SdncRestconfClient sdncRestconfClient) { - this.sdncProperties = sdncProperties; - this.sdncRestconfClient = sdncRestconfClient; - topologyUrlOperational = getTopologyUrlOperational(); - topologyUrlData = getTopologyUrlData(); - } - - /** - * This method fetches list of modules usind sdnc client. - * - * @param nodeId node id for node - * @return a collection of module schemas - */ - public Collection<ModuleSchema> getModuleSchemasFromNode(final String nodeId) { - final String urlWithNodeId = prepareGetSchemaUrl(nodeId); - final ResponseEntity<String> modulesResponseEntity = sdncRestconfClient.getOperation(urlWithNodeId); - if (modulesResponseEntity.getStatusCode() == HttpStatus.OK) { - final String modulesResponseBody = modulesResponseEntity.getBody(); - if (modulesResponseBody == null || modulesResponseBody.isBlank()) { - return Collections.emptyList(); - } - return convertToModuleSchemas(modulesResponseBody); - } - throw new SdncException( - String.format("SDNC failed to get Modules Schema for node %s", nodeId), - (HttpStatus) modulesResponseEntity.getStatusCode(), modulesResponseEntity.getBody()); - } - - /** - * Get module schema. - * - * @param nodeId node ID - * @param moduleProperties module properties - * @return response entity - */ - public ResponseEntity<String> getModuleResource(final String nodeId, final String moduleProperties) { - final String getYangResourceUrl = prepareGetOperationSchemaUrl(nodeId); - final HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.setContentType(MediaType.APPLICATION_JSON); - return sdncRestconfClient.httpOperationWithJsonData( - HttpMethod.POST, getYangResourceUrl, moduleProperties, httpHeaders); - } - - /** - * This method fetches the resource data for given node identifier on given resource using sdnc client. - * - * @param nodeId network resource identifier - * @param resourceId resource identifier - * @param optionsParamInQuery fields query - * @param restConfContentQueryParam restConf content query param - * @return {@code ResponseEntity} response entity - */ - public ResponseEntity<String> getResouceDataForOperationalAndRunning(final String nodeId, - final String resourceId, - final String optionsParamInQuery, - final String restConfContentQueryParam) { - final String getResourceDataUrl = prepareResourceDataUrl(nodeId, - resourceId, buildQueryParamMap(optionsParamInQuery, restConfContentQueryParam)); - return sdncRestconfClient.getOperation(getResourceDataUrl); - } - - /** - * Write resource data. - * - * @param nodeId network resource identifier - * @param resourceId resource identifier - * @param contentType http content type - * @param requestData request data - * @return {@code ResponseEntity} response entity - */ - public ResponseEntity<String> writeData(final DataAccessRequest.OperationEnum operation, - final String nodeId, - final String resourceId, - final String contentType, - final String requestData) { - final String getResourceDataUrl = prepareWriteUrl(nodeId, resourceId); - final HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.setContentType(MediaType.parseMediaType(contentType)); - final HttpMethod httpMethod = operationToHttpMethodMap.get(operation); - return sdncRestconfClient.httpOperationWithJsonData(httpMethod, getResourceDataUrl, requestData, httpHeaders); - } - - private MultiValueMap<String, String> buildQueryParamMap(final String optionsParamInQuery, - final String restConfContentQueryParam) { - return getQueryParamsAsMap(optionsParamInQuery, restConfContentQueryParam); - } - - private MultiValueMap<String, String> getQueryParamsAsMap(final String optionsParamInQuery, - final String restConfContentQueryParam) { - final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>(); - if (optionsParamInQuery != null && !optionsParamInQuery.isBlank()) { - queryParams.setAll(extractQueryParams(optionsParamInQuery, restConfContentQueryParam)); - } - return queryParams; - } - - private String stripParenthesisFromOptionsQuery(final String optionsParamInQuery) { - return optionsParamInQuery.substring(1, optionsParamInQuery.length() - 1); - } - - private String prepareGetSchemaUrl(final String nodeId) { - return addResource(addTopologyDataUrlwithNode(nodeId), GET_SCHEMA_URL); - } - - private String prepareWriteUrl(final String nodeId, final String resourceId) { - return addResource(addTopologyDataUrlwithNode(nodeId), resourceId); - } - - private String prepareGetOperationSchemaUrl(final String nodeId) { - return UriComponentsBuilder.fromUriString(topologyUrlOperational) - .pathSegment("node={nodeId}") - .pathSegment("yang-ext:mount") - .path(GET_SCHEMA_SOURCES_URL) - .buildAndExpand(nodeId).toUriString(); - } - - private String prepareResourceDataUrl(final String nodeId, - final String resourceId, - final MultiValueMap<String, String> queryMap) { - return addQuery(addResource(addTopologyDataUrlwithNode(nodeId), resourceId), queryMap); - } - - private String addResource(final String url, final String resourceId) { - return UriComponentsBuilder.fromUriString(url) - .pathSegment(resourceId) - .buildAndExpand().toUriString(); - } - - private String addQuery(final String url, final MultiValueMap<String, String> queryMap) { - return UriComponentsBuilder.fromUriString(url) - .queryParams(queryMap) - .buildAndExpand().toUriString(); - } - - private String addTopologyDataUrlwithNode(final String nodeId) { - return UriComponentsBuilder.fromUriString(topologyUrlData) - .pathSegment("node={nodeId}") - .pathSegment("yang-ext:mount") - .buildAndExpand(nodeId).toUriString(); - } - - private List<ModuleSchema> convertToModuleSchemas(final String modulesListAsJson) { - try { - return JsonPath.using(jsonPathConfiguration).parse(modulesListAsJson).read( - PATH_TO_MODULE_SCHEMAS, new TypeRef<>() { - }); - } catch (final JsonPathException jsonPathException) { - throw new SdncException("SDNC Response processing failed", - "SDNC response is not in the expected format.", jsonPathException); - } - } - - private String getTopologyUrlData() { - return UriComponentsBuilder.fromUriString(TOPOLOGY_URL_TEMPLATE_DATA) - .path("topology={topologyId}") - .buildAndExpand(this.sdncProperties.getTopologyId()).toUriString(); - } - - private String getTopologyUrlOperational() { - return UriComponentsBuilder.fromUriString( - TOPOLOGY_URL_TEMPLATE_OPERATIONAL) - .path("topology={topologyId}") - .buildAndExpand(this.sdncProperties.getTopologyId()).toUriString(); - } - - private Map<String, String> extractQueryParams(final String optionsParamInQuery, - final String restConfContentQueryParam) { - final String QueryParamsAsString = stripParenthesisFromOptionsQuery(optionsParamInQuery) - + "," + restConfContentQueryParam; - final String[] splitTempQueryByComma = QueryParamsAsString.split(","); - return Arrays.stream(splitTempQueryByComma) - .map(queryParamPair -> queryParamPair.split("=", QUERY_PARAM_SPLIT_LIMIT)) - .filter(queryParam -> queryParam.length > 1) - .collect(Collectors.toMap( - queryParam -> queryParam[QUERY_PARAM_NAME_INDEX], - queryParam -> queryParam[QUERY_PARAM_VALUE_INDEX])); - } -} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml deleted file mode 100644 index 003aa191..00000000 --- a/src/main/resources/application.yml +++ /dev/null @@ -1,128 +0,0 @@ -# ============LICENSE_START======================================================= -# Copyright (C) 2021-2024 Nordix Foundation -# Modifications Copyright (C) 2021 Bell Canada. -# ================================================================================ -# 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========================================================= - -server: - port: 8080 - -dmi: - service: - url: ${DMI_SERVICE_URL} - name: ${DMI_SERVICE_NAME:ncmp-dmi-plugin} - -rest: - api: - dmi-base-path: /dmi - -security: - permit-uri: /actuator/**,/swagger-ui.html,/swagger-ui/**,/swagger-resources/**,/api-docs/**,/v3/api-docs/** - auth: - username: ${DMI_USERNAME} - password: ${DMI_PASSWORD} - -# When updating to sprinboot 2.6.4 an exception would occur when starting the container -# "Failed to start bean 'documentationPluginsBootstrapper'. -# This is a known issue with springfox and springboot introduced in 2.6.x: -# https://github.com/springfox/springfox/issues/3462 -spring: - application: - name: ncmp-dmi-plugin - mvc: - pathmatch: - matching-strategy: ANT_PATH_MATCHER - kafka: - bootstrap-servers: ${KAFKA_BOOTSTRAP_SERVER:localhost:9092} - security: - protocol: PLAINTEXT - producer: - key-serializer: org.apache.kafka.common.serialization.StringSerializer - value-serializer: io.cloudevents.kafka.CloudEventSerializer - client-id: ncmp-dmi-plugin - consumer: - group-id: ${NCMP_CONSUMER_GROUP_ID:ncmp-group} - key-deserializer: org.springframework.kafka.support.serializer.ErrorHandlingDeserializer - value-deserializer: org.springframework.kafka.support.serializer.ErrorHandlingDeserializer - properties: - spring.deserializer.key.delegate.class: org.apache.kafka.common.serialization.StringDeserializer - spring.deserializer.value.delegate.class: io.cloudevents.kafka.CloudEventDeserializer - spring.json.use.type.headers: false - - jackson: - serialization: - FAIL_ON_EMPTY_BEANS: false - -app: - ncmp: - async: - topic: ${NCMP_ASYNC_M2M_TOPIC:ncmp-async-m2m} - dmi: - avc: - cm-subscription-dmi-in: ${CM_SUBSCRIPTION_DMI_IN_TOPIC:ncmp-dmi-cm-avc-subscription} - cm-subscription-dmi-out: ${CM_SUBSCRIPTION_DMI_OUT_TOPIC:dmi-ncmp-cm-avc-subscription} - -notification: - async: - executor: - time-out-value-in-ms: 2000 - -# Actuator -management: - endpoints: - web: - exposure: - include: info,health,loggers,prometheus - endpoint: - health: - show-details: always - # kubernetes probes: liveness and readiness - probes: - enabled: true - loggers: - enabled: true - -cps-core: - baseUrl: http://${CPS_CORE_HOST}:${CPS_CORE_PORT} - dmiRegistrationUrl : /ncmpInventory/v1/ch - auth: - username: ${CPS_CORE_USERNAME} - password: ${CPS_CORE_PASSWORD} - -sdnc: - baseUrl: http://${SDNC_HOST}:${SDNC_PORT} - topologyId: ${SDNC_TOPOLOGY_ID:topology-netconf} - auth: - username: ${SDNC_USERNAME} - password: ${SDNC_PASSWORD} - -logging: - format: json - level: - org.springframework: ERROR - org.onap.cps: DEBUG - pattern: - console: "%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" - file: "%d %p %c{1.} [%t] %m%n" - file: dmi.log - -springdoc: - swagger-ui: - disable-swagger-default-url: true - urlsPrimaryName: query - urls: - - name: query - url: /api-docs/openapi.yaml diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml deleted file mode 100644 index 355209b4..00000000 --- a/src/main/resources/logback-spring.xml +++ /dev/null @@ -1,75 +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========================================================= ---> - -<configuration scan="true" scanPeriod="30 seconds" debug="false"> - - <include resource="org/springframework/boot/logging/logback/defaults.xml" /> - <include resource="org/springframework/boot/logging/logback/console-appender.xml" /> - - <springProperty scope="context" name="springAppName" source="spring.application.name"/> - <springProperty scope="context" name="username" source="security.auth.username"/> - <springProperty scope="context" name="loggingFormat" source="logging.format"/> - - <property name="currentTimeStamp" value="%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX,UTC}"/> - - <appender name="jsonConsole" - class="ch.qos.logback.core.ConsoleAppender"> - <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder"> - <providers> - <pattern> - <omitEmptyFields>true</omitEmptyFields> - <pattern> - { - "logTimeStamp": "${currentTimeStamp:-}", - "logTypeName": "", - "logLevel": "%level", - "traceId": "%X{traceId:-}", - "statusCode": "", - "principalId": "${username:-}", - "serviceName": "${springAppName:-}", - "message": "%message", - "spanId": "%X{spanId:-}", - "processId": "${PID:-}", - "threadName": "%thread", - "class": "%logger{40}", - "exception": "%wEx" - } - </pattern> - </pattern> - </providers> - </encoder> - </appender> - - <appender name="asyncConsole" class="ch.qos.logback.classic.AsyncAppender"> - <if condition='property("loggingFormat").equalsIgnoreCase("json")'> - <then> - <appender-ref ref="jsonConsole"/> - </then> - <else> - <appender-ref ref="CONSOLE"/> - </else> - </if> - </appender> - - <root level="INFO"> - <appender-ref ref="asyncConsole"/> - </root> - -</configuration> diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/api/kafka/MessagingBaseSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/api/kafka/MessagingBaseSpec.groovy deleted file mode 100644 index 13dd043d..00000000 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/api/kafka/MessagingBaseSpec.groovy +++ /dev/null @@ -1,79 +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.dmi.api.kafka - -import io.cloudevents.CloudEvent -import io.cloudevents.kafka.CloudEventDeserializer -import io.cloudevents.kafka.CloudEventSerializer -import org.apache.kafka.clients.consumer.KafkaConsumer -import org.apache.kafka.common.serialization.StringDeserializer -import org.apache.kafka.common.serialization.StringSerializer -import org.springframework.kafka.core.DefaultKafkaProducerFactory -import org.springframework.kafka.core.KafkaTemplate -import org.springframework.kafka.support.serializer.JsonSerializer -import org.springframework.test.context.DynamicPropertyRegistry -import org.springframework.test.context.DynamicPropertySource -import org.testcontainers.containers.KafkaContainer -import org.testcontainers.utility.DockerImageName -import spock.lang.Specification - -class MessagingBaseSpec extends Specification { - - def setupSpec() { - kafkaTestContainer.start() - } - - def cleanupSpec() { - kafkaTestContainer.stop() - } - - static kafkaTestContainer = new KafkaContainer(DockerImageName.parse('registry.nordix.org/onaptest/confluentinc/cp-kafka:6.2.1').asCompatibleSubstituteFor('confluentinc/cp-kafka')) - - def producerConfigProperties(valueSerializer) { - return [('bootstrap.servers'): kafkaTestContainer.getBootstrapServers().split(',')[0], - ('retries') : 0, - ('batch-size') : 16384, - ('linger.ms') : 1, - ('buffer.memory') : 33554432, - ('key.serializer') : StringSerializer, - ('value.serializer') : valueSerializer] - } - - def consumerConfigProperties(consumerGroupId, valueDeserializer) { - return [('bootstrap.servers') : kafkaTestContainer.getBootstrapServers().split(',')[0], - ('key.deserializer') : StringDeserializer, - ('value.deserializer'): valueDeserializer, - ('auto.offset.reset') : 'earliest', - ('group.id') : consumerGroupId - ] - } - - def kafkaTemplate = new KafkaTemplate<>(new DefaultKafkaProducerFactory<Integer, String>(producerConfigProperties(JsonSerializer))) - def kafkaConsumer = new KafkaConsumer<>(consumerConfigProperties('ncmp-test-group', StringDeserializer)) - - def cloudEventKafkaTemplate = new KafkaTemplate(new DefaultKafkaProducerFactory<String, CloudEvent>(producerConfigProperties(CloudEventSerializer))) - def cloudEventKafkaConsumer = new KafkaConsumer<>(consumerConfigProperties('ncmp-test-group', CloudEventDeserializer)) - - @DynamicPropertySource - static void registerKafkaProperties(DynamicPropertyRegistry dynamicPropertyRegistry) { - dynamicPropertyRegistry.add('spring.kafka.bootstrap-servers', kafkaTestContainer::getBootstrapServers) - } -} diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/config/DmiConfigurationSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/config/DmiConfigurationSpec.groovy deleted file mode 100644 index 9d80b71f..00000000 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/config/DmiConfigurationSpec.groovy +++ /dev/null @@ -1,66 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.dmi.config - -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.boot.web.client.RestTemplateBuilder -import org.springframework.test.context.ContextConfiguration -import spock.lang.Specification - -@SpringBootTest -@ContextConfiguration(classes = [DmiConfiguration.CpsProperties, DmiConfiguration.SdncProperties]) -class DmiConfigurationSpec extends Specification { - - @Autowired - DmiConfiguration.CpsProperties cpsProperties - - @Autowired - DmiConfiguration.SdncProperties sdncProperties - - def 'CPS properties configuration.'() { - expect: 'CPS properties are set to values in test configuration yaml file' - cpsProperties.baseUrl == 'some url for cps' - cpsProperties.dmiRegistrationUrl == 'some registration url' - cpsProperties.authUsername == 'some cps core user' - cpsProperties.authPassword == 'some cps core password' - } - - def 'SDNC properties configuration.'() { - expect: 'SDNC properties are set to values in test configuration yaml file' - sdncProperties.authUsername == 'test' - sdncProperties.authPassword == 'test' - sdncProperties.baseUrl == 'http://test' - sdncProperties.topologyId == 'test-topology' - } - - def 'Rest template building.'() { - given: 'a DMI configuration' - DmiConfiguration objectUnderTest = new DmiConfiguration() - and: 'a rest template builder' - RestTemplateBuilder mockRestTemplateBuilder = Spy(RestTemplateBuilder) - when: 'rest template method is invoked' - objectUnderTest.restTemplate(mockRestTemplateBuilder) - then: 'DMI configuration uses the build method on the template builder' - 1 * mockRestTemplateBuilder.build() - } - -} diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/config/DmiPluginConfigSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/config/DmiPluginConfigSpec.groovy deleted file mode 100644 index c09403d7..00000000 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/config/DmiPluginConfigSpec.groovy +++ /dev/null @@ -1,52 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * 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. - * 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.dmi.config - -import org.springdoc.core.models.GroupedOpenApi -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.test.context.ContextConfiguration -import spock.lang.Specification - -@SpringBootTest -@ContextConfiguration(classes = [DmiPluginConfig.DmiPluginProperties]) -class DmiPluginConfigSpec extends Specification { - - @Autowired - DmiPluginConfig.DmiPluginProperties dmiPluginProperties - - def 'DMI plugin properties configuration.'() { - expect: 'DMI plugin properties are set to values in test configuration yaml file' - dmiPluginProperties.dmiServiceUrl == 'some url for the dmi service' - } - - def 'DMI plugin api creation.'() { - given: 'a DMI plugin configuration' - DmiPluginConfig objectUnderTest = new DmiPluginConfig() - when: 'the api method is invoked' - def result = objectUnderTest.api() - then: 'a spring web plugin docket is returned' - result instanceof GroupedOpenApi - and: 'it is named "dmi-plugin-api"' - result.group == 'dmi-plugin-api' - } - -} diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/config/kafka/KafkaConfigSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/config/kafka/KafkaConfigSpec.groovy deleted file mode 100644 index a3bf52b3..00000000 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/config/kafka/KafkaConfigSpec.groovy +++ /dev/null @@ -1,62 +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.dmi.config.kafka - -import io.cloudevents.CloudEvent -import io.cloudevents.kafka.CloudEventDeserializer -import io.cloudevents.kafka.CloudEventSerializer -import org.spockframework.spring.EnableSharedInjection -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.autoconfigure.kafka.KafkaProperties -import org.springframework.boot.context.properties.EnableConfigurationProperties -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.kafka.core.KafkaTemplate -import org.springframework.kafka.support.serializer.JsonDeserializer -import org.springframework.kafka.support.serializer.JsonSerializer -import spock.lang.Shared -import spock.lang.Specification - -@SpringBootTest(classes = [KafkaProperties, KafkaConfig]) -@EnableSharedInjection -@EnableConfigurationProperties -class KafkaConfigSpec extends Specification { - - @Shared - @Autowired - KafkaTemplate<String, String> legacyEventKafkaTemplate - - @Shared - @Autowired - KafkaTemplate<String, CloudEvent> cloudEventKafkaTemplate - - def 'Verify kafka template serializer and deserializer configuration for #eventType.'() { - expect: 'kafka template is instantiated' - assert kafkaTemplateInstance.properties['beanName'] == beanName - and: 'verify event key and value serializer' - assert kafkaTemplateInstance.properties['producerFactory'].configs['value.serializer'].asType(String.class).contains(valueSerializer.getCanonicalName()) - and: 'verify event key and value deserializer' - assert kafkaTemplateInstance.properties['consumerFactory'].configs['spring.deserializer.value.delegate.class'].asType(String.class).contains(delegateDeserializer.getCanonicalName()) - where: 'the following event type is used' - eventType | kafkaTemplateInstance || beanName | valueSerializer | delegateDeserializer - 'legacy event' | legacyEventKafkaTemplate || 'legacyEventKafkaTemplate' | JsonSerializer | JsonDeserializer - 'cloud event' | cloudEventKafkaTemplate || 'cloudEventKafkaTemplate' | CloudEventSerializer | CloudEventDeserializer - } -} diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/datajobs/rest/controller/DmiDatajobsRestControllerSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/datajobs/rest/controller/DmiDatajobsRestControllerSpec.groovy deleted file mode 100644 index c55f53c1..00000000 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/datajobs/rest/controller/DmiDatajobsRestControllerSpec.groovy +++ /dev/null @@ -1,69 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2024 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.dmi.datajobs.rest.controller - -import org.onap.cps.ncmp.dmi.config.WebSecurityConfig -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.beans.factory.annotation.Value -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest -import org.springframework.context.annotation.Import -import org.springframework.http.HttpStatus -import org.springframework.security.test.context.support.WithMockUser -import org.springframework.test.web.servlet.MockMvc -import spock.lang.Specification - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post - -@Import(WebSecurityConfig) -@WebMvcTest(DmiDatajobsRestController.class) -@WithMockUser -class DmiDatajobsRestControllerSpec extends Specification{ - - @Autowired - private MockMvc mvc - - @Value('${rest.api.dmi-base-path}/v1') - def basePathV1 - - def 'write request should return 501 HTTP Status' () { - given: 'URL to write a data job' - def getModuleUrl = "${basePathV1}/writeJob/001" - when: 'the request is posted' - def response = mvc.perform( - post(getModuleUrl) - .contentType('application/3gpp-json-patch+json') - ).andReturn().response - then: 'response value is Not Implemented' - response.status == HttpStatus.NOT_IMPLEMENTED.value() - } - - def 'read request should return 501 HTTP Status' () { - given: 'URL to write a data job' - def getModuleUrl = "${basePathV1}/readJob/001" - when: 'the request is posted' - def response = mvc.perform( - post(getModuleUrl) - .contentType('application/3gpp-json-patch+json') - ).andReturn().response - then: 'response value is Not Implemented' - response.status == HttpStatus.NOT_IMPLEMENTED.value() - } -} diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/async/AsyncTaskExecutorIntegrationSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/async/AsyncTaskExecutorIntegrationSpec.groovy deleted file mode 100644 index 12ca05cf..00000000 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/async/AsyncTaskExecutorIntegrationSpec.groovy +++ /dev/null @@ -1,110 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * 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. - * 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.dmi.notifications.async - -import com.fasterxml.jackson.databind.ObjectMapper -import org.onap.cps.ncmp.dmi.api.kafka.MessagingBaseSpec -import org.onap.cps.ncmp.dmi.exception.HttpClientRequestException -import org.onap.cps.ncmp.dmi.model.DataAccessRequest -import org.onap.cps.ncmp.event.model.DmiAsyncRequestResponseEvent -import org.spockframework.spring.SpringBean -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.http.HttpStatus -import org.springframework.test.annotation.DirtiesContext -import org.testcontainers.spock.Testcontainers - -import java.time.Duration -import java.util.function.Supplier - -@SpringBootTest(classes = [AsyncTaskExecutor, DmiAsyncRequestResponseEventProducer]) -@Testcontainers -@DirtiesContext -class AsyncTaskExecutorIntegrationSpec extends MessagingBaseSpec { - - @SpringBean - DmiAsyncRequestResponseEventProducer cpsAsyncRequestResponseEventProducer = - new DmiAsyncRequestResponseEventProducer(kafkaTemplate) - - def spiedObjectMapper = Spy(ObjectMapper) - def mockSupplier = Mock(Supplier) - - def objectUnderTest = new AsyncTaskExecutor(cpsAsyncRequestResponseEventProducer) - - private static final String TEST_TOPIC = 'test-topic' - - def setup() { - cpsAsyncRequestResponseEventProducer.dmiNcmpTopic = TEST_TOPIC - kafkaConsumer.subscribe([TEST_TOPIC] as List<String>) - } - - def cleanup() { - kafkaConsumer.close() - } - - def 'Publish and Subscribe message - success'() { - when: 'a successful event is published' - objectUnderTest.publishAsyncEvent(TEST_TOPIC, '12345','{}', 'OK', '200') - and: 'the topic is polled' - def records = kafkaConsumer.poll(Duration.ofMillis(1500)) - then: 'the record received is the event sent' - def record = records.iterator().next() - DmiAsyncRequestResponseEvent event = spiedObjectMapper.readValue(record.value(), DmiAsyncRequestResponseEvent) - and: 'the status & code matches expected' - assert event.getEventContent().getResponseStatus() == 'OK' - assert event.getEventContent().getResponseCode() == '200' - } - - def 'Publish and Subscribe message - failure'() { - when: 'a failure event is published' - def exception = new HttpClientRequestException('some cm handle', 'Node not found', HttpStatus.INTERNAL_SERVER_ERROR) - objectUnderTest.publishAsyncFailureEvent(TEST_TOPIC, '67890', exception) - and: 'the topic is polled' - def records = kafkaConsumer.poll(Duration.ofMillis(1500)) - then: 'the record received is the event sent' - def record = records.iterator().next() - DmiAsyncRequestResponseEvent event = spiedObjectMapper.readValue(record.value(), DmiAsyncRequestResponseEvent) - and: 'the status & code matches expected' - assert event.getEventContent().getResponseStatus() == 'Internal Server Error' - assert event.getEventContent().getResponseCode() == '500' - } - - def 'Execute an Async Task using asyncTaskExecutor and throw an error'() { - given: 'A task to be executed' - def requestId = '123456' - def operationEnum = DataAccessRequest.OperationEnum.CREATE - def timeOut = 100 - when: 'AsyncTask has been executed' - objectUnderTest.executeAsyncTask(taskSupplierForFailingTask(), TEST_TOPIC, requestId, operationEnum, timeOut) - def records = kafkaConsumer.poll(Duration.ofMillis(1500)) - then: 'the record received is the event sent' - def record = records.iterator().next() - DmiAsyncRequestResponseEvent event = spiedObjectMapper.readValue(record.value(), DmiAsyncRequestResponseEvent) - and: 'the status & code matches expected' - assert event.getEventContent().getResponseStatus() == 'Internal Server Error' - assert event.getEventContent().getResponseCode() == '500' - - } - - def taskSupplierForFailingTask() { - return () -> { throw new RuntimeException('original exception message') } - } - -}
\ No newline at end of file diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/avc/AvcEventExecutorIntegrationSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/avc/AvcEventExecutorIntegrationSpec.groovy deleted file mode 100644 index a7557bb9..00000000 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/avc/AvcEventExecutorIntegrationSpec.groovy +++ /dev/null @@ -1,61 +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.dmi.notifications.avc - -import com.fasterxml.jackson.databind.ObjectMapper -import io.cloudevents.core.CloudEventUtils -import io.cloudevents.jackson.PojoCloudEventDataMapper -import org.onap.cps.ncmp.dmi.api.kafka.MessagingBaseSpec -import org.onap.cps.ncmp.events.avc1_0_0.AvcEvent -import org.spockframework.spring.SpringBean -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.test.annotation.DirtiesContext -import org.testcontainers.spock.Testcontainers - -import java.time.Duration - -@SpringBootTest(classes = [DmiDataAvcEventProducer]) -@Testcontainers -@DirtiesContext -class AvcEventExecutorIntegrationSpec extends MessagingBaseSpec { - - @SpringBean - DmiDataAvcEventProducer dmiDataAvcEventProducer = new DmiDataAvcEventProducer(cloudEventKafkaTemplate) - - def dmiService = new DmiDataAvcEventSimulationController(dmiDataAvcEventProducer) - - def objectMapper = new ObjectMapper() - - def 'Publish Avc Event'() { - given: 'a simulated event' - dmiService.simulateEvents(1) - and: 'a consumer subscribed to dmi-cm-events topic' - cloudEventKafkaConsumer.subscribe(['dmi-cm-events']) - when: 'the next event record is consumed' - def record = cloudEventKafkaConsumer.poll(Duration.ofMillis(1500)).iterator().next() - then: 'record has correct topic' - assert record.topic == 'dmi-cm-events' - and: 'the record value can be mapped to an avcEvent' - def dmiDataAvcEvent = record.value() - def convertedAvcEvent = CloudEventUtils.mapData(dmiDataAvcEvent, PojoCloudEventDataMapper.from(objectMapper, AvcEvent.class)).getValue() - assert convertedAvcEvent != null - } -}
\ No newline at end of file diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiInEventConsumerSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiInEventConsumerSpec.groovy deleted file mode 100644 index f1f476f6..00000000 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiInEventConsumerSpec.groovy +++ /dev/null @@ -1,149 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2024 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.dmi.notifications.cmsubscription - -import ch.qos.logback.classic.Level -import ch.qos.logback.classic.Logger -import ch.qos.logback.classic.spi.ILoggingEvent -import ch.qos.logback.core.read.ListAppender -import com.fasterxml.jackson.databind.ObjectMapper -import io.cloudevents.CloudEvent -import io.cloudevents.core.builder.CloudEventBuilder -import org.apache.kafka.clients.consumer.ConsumerRecord -import org.onap.cps.ncmp.dmi.TestUtils -import org.onap.cps.ncmp.dmi.api.kafka.MessagingBaseSpec -import org.onap.cps.ncmp.dmi.notifications.cmsubscription.model.CmNotificationSubscriptionStatus -import org.onap.cps.ncmp.dmi.notifications.mapper.CloudEventMapper -import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.dmi_to_ncmp.CmNotificationSubscriptionDmiOutEvent -import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.dmi_to_ncmp.Data -import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.CmNotificationSubscriptionDmiInEvent -import org.slf4j.LoggerFactory -import org.spockframework.spring.SpringBean -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.test.annotation.DirtiesContext -import org.testcontainers.spock.Testcontainers - -import java.sql.Timestamp -import java.time.Duration -import java.time.OffsetDateTime -import java.time.ZoneId - - -@Testcontainers -@DirtiesContext -class CmNotificationSubscriptionDmiInEventConsumerSpec extends MessagingBaseSpec { - def objectMapper = new ObjectMapper() - def testTopic = 'dmi-ncmp-cm-avc-subscription' - def testDmiName = 'test-ncmp-dmi' - - @SpringBean - CmNotificationSubscriptionDmiInEventConsumer objectUnderTest = new CmNotificationSubscriptionDmiInEventConsumer(cloudEventKafkaTemplate) - - def logger = Spy(ListAppender<ILoggingEvent>) - - void setup() { - ((Logger) LoggerFactory.getLogger(CloudEventMapper.class)).addAppender(logger) - logger.start() - } - - void cleanup() { - ((Logger) LoggerFactory.getLogger(CloudEventMapper.class)).detachAndStopAllAppenders() - } - - def 'Sends subscription cloud event response successfully.'() { - given: 'an subscription event response' - objectUnderTest.dmiName = testDmiName - objectUnderTest.cmNotificationSubscriptionDmiOutTopic = testTopic - def correlationId = 'test-subscriptionId#test-ncmp-dmi' - def cmSubscriptionDmiOutEventData = new Data(statusCode: subscriptionStatusCode, statusMessage: subscriptionStatusMessage) - def subscriptionEventResponse = - new CmNotificationSubscriptionDmiOutEvent().withData(cmSubscriptionDmiOutEventData) - and: 'consumer has a subscription' - kafkaConsumer.subscribe([testTopic] as List<String>) - when: 'an event is published' - def eventKey = UUID.randomUUID().toString() - objectUnderTest.createAndSendCmNotificationSubscriptionDmiOutEvent(eventKey, "subscriptionCreatedStatus", correlationId, subscriptionAcceptanceType) - and: 'topic is polled' - def records = kafkaConsumer.poll(Duration.ofMillis(1500)) - then: 'poll returns one record and close kafkaConsumer' - assert records.size() == 1 - def record = records.iterator().next() - kafkaConsumer.close() - and: 'the record value matches the expected event value' - def expectedValue = objectMapper.writeValueAsString(subscriptionEventResponse) - assert expectedValue == record.value - assert eventKey == record.key - where: 'given #scenario' - scenario | subscriptionAcceptanceType | subscriptionStatusCode | subscriptionStatusMessage - 'Subscription is Accepted' | CmNotificationSubscriptionStatus.ACCEPTED | '1' | 'ACCEPTED' - 'Subscription is Rejected' | CmNotificationSubscriptionStatus.REJECTED | '104' | 'REJECTED' - } - - def 'Consume valid message.'() { - given: 'an event' - objectUnderTest.dmiName = testDmiName - def eventKey = UUID.randomUUID().toString() - def timestamp = new Timestamp(1679521929511) - def jsonData = TestUtils.getResourceFileContent('cmNotificationSubscriptionCreationEvent.json') - def subscriptionEvent = objectMapper.readValue(jsonData, CmNotificationSubscriptionDmiInEvent.class) - objectUnderTest.cmNotificationSubscriptionDmiOutTopic = testTopic - def cloudEvent = CloudEventBuilder.v1().withId(UUID.randomUUID().toString()).withSource(URI.create('test-ncmp-dmi')) - .withType(subscriptionType) - .withDataSchema(URI.create("urn:cps:" + CmNotificationSubscriptionDmiInEvent.class.getName() + ":1.0.0")) - .withExtension("correlationid", eventKey) - .withTime(OffsetDateTime.ofInstant(timestamp.toInstant(), ZoneId.of("UTC"))) - .withData(objectMapper.writeValueAsBytes(subscriptionEvent)).build() - def testEventSent = new ConsumerRecord<String, CloudEvent>('topic-name', 0, 0, eventKey, cloudEvent) - when: 'the valid event is consumed' - objectUnderTest.consumeCmNotificationSubscriptionDmiInEvent(testEventSent) - then: 'no exception is thrown' - noExceptionThrown() - where: 'given #scenario' - scenario | subscriptionType - 'Subscription Create Event' | "subscriptionCreated" - 'Subscription Delete Event' | "subscriptionDeleted" - } - - def 'Consume invalid message.'() { - given: 'an invalid event body' - objectUnderTest.dmiName = testDmiName - def eventKey = UUID.randomUUID().toString() - def timestamp = new Timestamp(1679521929511) - def invalidJsonBody = "/////" - objectUnderTest.cmNotificationSubscriptionDmiOutTopic = testTopic - def cloudEvent = CloudEventBuilder.v1().withId(UUID.randomUUID().toString()).withSource(URI.create('test-ncmp-dmi')) - .withType("subscriptionCreated") - .withDataSchema(URI.create("urn:cps:org.onap.ncmp.dmi.cm.subscription:1.0.0")) - .withTime(OffsetDateTime.ofInstant(timestamp.toInstant(), ZoneId.of("UTC"))) - .withExtension("correlationid", eventKey).withData(objectMapper.writeValueAsBytes(invalidJsonBody)).build() - def testEventSent = new ConsumerRecord<String, CloudEvent>('topic-name', 0, 0, eventKey, cloudEvent) - when: 'the invalid event is consumed' - objectUnderTest.consumeCmNotificationSubscriptionDmiInEvent(testEventSent) - then: 'exception is thrown and event is logged' - def loggingEvent = getLoggingEvent() - assert loggingEvent.level == Level.ERROR - assert loggingEvent.formattedMessage.contains('Unable to map cloud event to target event class type') - } - - def getLoggingEvent() { - return logger.list[0] - } -}
\ No newline at end of file diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiOutEventToCloudEventMapperSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiOutEventToCloudEventMapperSpec.groovy deleted file mode 100644 index 8ca629f1..00000000 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiOutEventToCloudEventMapperSpec.groovy +++ /dev/null @@ -1,69 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2024 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.dmi.notifications.cmsubscription - -import com.fasterxml.jackson.databind.ObjectMapper -import io.cloudevents.core.builder.CloudEventBuilder -import org.onap.cps.ncmp.dmi.exception.CloudEventConstructionException -import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.dmi_to_ncmp.CmNotificationSubscriptionDmiOutEvent -import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.dmi_to_ncmp.Data -import org.spockframework.spring.SpringBean -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest -import spock.lang.Specification - -@SpringBootTest(classes = [ObjectMapper]) -class CmNotificationSubscriptionDmiOutEventToCloudEventMapperSpec extends Specification { - - @Autowired - def objectMapper = new ObjectMapper() - - @SpringBean - CmNotificationSubscriptionDmiOutEventToCloudEventMapper objectUnderTest = new CmNotificationSubscriptionDmiOutEventToCloudEventMapper() - - def 'Convert a Cm Subscription DMI Out Event to CloudEvent successfully.'() { - given: 'a Cm Subscription DMI Out Event and an event key' - def dmiName = 'test-ncmp-dmi' - def correlationId = 'subscription1#test-ncmp-dmi' - def cmSubscriptionDmiOutEventData = new Data(statusCode: "1", statusMessage: "accepted") - def cmSubscriptionDmiOutEvent = - new CmNotificationSubscriptionDmiOutEvent().withData(cmSubscriptionDmiOutEventData) - when: 'a Cm Subscription DMI Out Event is converted' - def result = objectUnderTest.toCloudEvent(cmSubscriptionDmiOutEvent, "subscriptionCreatedStatus", dmiName, correlationId) - then: 'Cm Subscription DMI Out Event is converted as expected' - def expectedCloudEvent = CloudEventBuilder.v1().withId(UUID.randomUUID().toString()).withSource(URI.create('test-ncmp-dmi')) - .withType("subscriptionCreated") - .withDataSchema(URI.create("urn:cps:" + CmNotificationSubscriptionDmiOutEvent.class.getName() + ":1.0.0")) - .withExtension("correlationid", correlationId) - .withData(objectMapper.writeValueAsBytes(cmSubscriptionDmiOutEvent)).build() - assert expectedCloudEvent.data == result.data - } - - def 'Map the Cloud Event to data of the subscription event with null parameters causes an exception'() { - given: 'an empty subscription response event and event key' - def correlationId = 'subscription1#test-ncmp-dmi' - def cmSubscriptionDmiOutEvent = new CmNotificationSubscriptionDmiOutEvent() - when: 'the cm subscription dmi out Event map to data of cloud event' - objectUnderTest.toCloudEvent(cmSubscriptionDmiOutEvent, "subscriptionCreatedStatus", null , correlationId) - then: 'a run time exception is thrown' - thrown(CloudEventConstructionException) - } -} diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/mapper/CloudEventMapperSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/mapper/CloudEventMapperSpec.groovy deleted file mode 100644 index 0b404776..00000000 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/mapper/CloudEventMapperSpec.groovy +++ /dev/null @@ -1,53 +0,0 @@ -/* - * ============LICENSE_START======================================================== - * Copyright (c) 2024 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.dmi.notifications.mapper - -import com.fasterxml.jackson.databind.ObjectMapper -import io.cloudevents.core.builder.CloudEventBuilder -import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.client_to_ncmp.CmNotificationSubscriptionNcmpInEvent -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest -import spock.lang.Specification - -@SpringBootTest(classes = [ObjectMapper]) -class CloudEventMapperSpec extends Specification { - - @Autowired - ObjectMapper objectMapper - - def 'Cloud event to Target event type when it is #scenario'() { - expect: 'Events mapped correctly' - assert mappedCloudEvent == (CloudEventMapper.toTargetEvent(testCloudEvent(), targetClass) != null) - where: 'below are the scenarios' - scenario | targetClass || mappedCloudEvent - 'valid concrete type' | CmNotificationSubscriptionNcmpInEvent.class || true - 'invalid concrete type' | ArrayList.class || false - } - - def testCloudEvent() { - return CloudEventBuilder.v1().withData(objectMapper.writeValueAsBytes(new CmNotificationSubscriptionNcmpInEvent())) - .withId("cmhandle1") - .withSource(URI.create('test-source')) - .withDataSchema(URI.create('test')) - .withType('org.onap.cm.events.cm-subscription') - .build() - } -} diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/ControllerSecuritySpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/ControllerSecuritySpec.groovy deleted file mode 100644 index 3f5d4a80..00000000 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/ControllerSecuritySpec.groovy +++ /dev/null @@ -1,76 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * 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. - * 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.dmi.rest.controller - -import org.onap.cps.ncmp.dmi.config.WebSecurityConfig -import org.springframework.context.annotation.Import - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get - -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest -import org.springframework.http.HttpStatus -import org.springframework.test.web.servlet.MockMvc -import spock.lang.Specification - -@WebMvcTest(controllers = TestController.class) -@Import(WebSecurityConfig) -class ControllerSecuritySpec extends Specification { - - @Autowired - MockMvc mvc - - def testEndpoint = '/test' - - def 'Get request with valid authentication'() { - when: 'request is sent with authentication' - def response = mvc.perform( - get(testEndpoint).header("Authorization", 'Basic Y3BzdXNlcjpjcHNyMGNrcyE=') - ).andReturn().response - then: 'HTTP OK status code is returned' - assert response.status == HttpStatus.OK.value() - } - - def 'Get request without authentication'() { - when: 'request is sent without authentication' - def response = mvc.perform(get(testEndpoint)).andReturn().response - then: 'HTTP Unauthorized status code is returned' - assert response.status == HttpStatus.UNAUTHORIZED.value() - } - - def 'Get request with invalid authentication'() { - when: 'request is sent with invalid authentication' - def response = mvc.perform( - get(testEndpoint).header("Authorization", 'Basic invalid auth') - ).andReturn().response - then: 'HTTP Unauthorized status code is returned' - assert response.status == HttpStatus.UNAUTHORIZED.value() - } - - def 'Security Config #scenario permit URIs'() { - expect: 'can create a web security configuration' - new WebSecurityConfig(permitUris,'user','password') - where: 'the following string of permit URIs is provided' - scenario | permitUris - 'with' | 'a,b' - 'without' | '' - } -} diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy deleted file mode 100644 index a519de7b..00000000 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy +++ /dev/null @@ -1,406 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2023 Nordix Foundation - * Modifications Copyright (C) 2021-2022 Bell Canada - * ================================================================================ - * 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.dmi.rest.controller - - -import ch.qos.logback.classic.Logger -import ch.qos.logback.classic.spi.ILoggingEvent -import ch.qos.logback.core.read.ListAppender -import org.onap.cps.ncmp.dmi.TestUtils -import org.onap.cps.ncmp.dmi.config.WebSecurityConfig -import org.onap.cps.ncmp.dmi.exception.DmiException -import org.onap.cps.ncmp.dmi.exception.ModuleResourceNotFoundException -import org.onap.cps.ncmp.dmi.exception.ModulesNotFoundException -import org.onap.cps.ncmp.dmi.model.ModuleSet -import org.onap.cps.ncmp.dmi.model.ModuleSetSchemasInner -import org.onap.cps.ncmp.dmi.model.YangResource -import org.onap.cps.ncmp.dmi.model.YangResources -import org.onap.cps.ncmp.dmi.notifications.async.AsyncTaskExecutor -import org.onap.cps.ncmp.dmi.notifications.async.DmiAsyncRequestResponseEventProducer -import org.onap.cps.ncmp.dmi.service.DmiService -import org.onap.cps.ncmp.dmi.service.model.ModuleReference -import org.slf4j.LoggerFactory -import org.spockframework.spring.SpringBean -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.beans.factory.annotation.Value -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest -import org.springframework.context.annotation.Import -import org.springframework.http.HttpStatus -import org.springframework.http.MediaType -import org.springframework.kafka.core.KafkaTemplate -import org.springframework.security.test.context.support.WithMockUser -import org.springframework.test.web.servlet.MockMvc -import spock.lang.Specification - -import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.CREATE -import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.DELETE -import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.PATCH -import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.READ -import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.UPDATE -import static org.springframework.http.HttpStatus.BAD_REQUEST -import static org.springframework.http.HttpStatus.CREATED -import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR -import static org.springframework.http.HttpStatus.NO_CONTENT -import static org.springframework.http.HttpStatus.OK -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post - -@Import(WebSecurityConfig) -@WebMvcTest(DmiRestController.class) -@WithMockUser -class DmiRestControllerSpec extends Specification { - - @Autowired - private MockMvc mvc - - @SpringBean - DmiService mockDmiService = Mock() - - @SpringBean - DmiAsyncRequestResponseEventProducer cpsAsyncRequestResponseEventProducer = new DmiAsyncRequestResponseEventProducer(Mock(KafkaTemplate)) - - @SpringBean - AsyncTaskExecutor asyncTaskExecutor = new AsyncTaskExecutor(cpsAsyncRequestResponseEventProducer) - - def logger = Spy(ListAppender<ILoggingEvent>) - - void setup() { - ((Logger) LoggerFactory.getLogger(DmiRestController.class)).addAppender(logger) - logger.start() - } - - void cleanup() { - ((Logger) LoggerFactory.getLogger(DmiRestController.class)).detachAndStopAllAppenders() - } - - @Value('${rest.api.dmi-base-path}/v1') - def basePathV1 - - def 'Get all modules.'() { - given: 'URL for getting all modules and some request data' - def getModuleUrl = "$basePathV1/ch/node1/modules" - def someValidJson = '{}' - and: 'DMI service returns some module' - def moduleSetSchema = new ModuleSetSchemasInner(namespace:'some-namespace', - moduleName:'some-moduleName', - revision:'some-revision') - def moduleSetSchemasList = [moduleSetSchema] as List<ModuleSetSchemasInner> - def moduleSet = new ModuleSet() - moduleSet.schemas(moduleSetSchemasList) - mockDmiService.getModulesForCmHandle('node1') >> moduleSet - when: 'the request is posted' - def response = mvc.perform(post(getModuleUrl) - .contentType(MediaType.APPLICATION_JSON).content(someValidJson)) - .andReturn().response - then: 'status is OK' - response.status == OK.value() - and: 'the response content matches the result from the DMI service' - response.getContentAsString() == '{"schemas":[{"moduleName":"some-moduleName","revision":"some-revision","namespace":"some-namespace"}]}' - } - - def 'Get all modules with exception handling of #scenario.'() { - given: 'URL for getting all modules and some request data' - def getModuleUrl = "$basePathV1/ch/node1/modules" - def someValidJson = '{}' - and: 'a #exception is thrown during the process' - mockDmiService.getModulesForCmHandle('node1') >> { throw exception } - when: 'the request is posted' - def response = mvc.perform( post(getModuleUrl) - .contentType(MediaType.APPLICATION_JSON).content(someValidJson)) - .andReturn().response - then: 'response status is #expectedResponse' - response.status == expectedResponse.value() - where: 'the scenario is #scenario' - scenario | exception || expectedResponse - 'dmi service exception' | new DmiException('','') || HttpStatus.INTERNAL_SERVER_ERROR - 'no modules found' | new ModulesNotFoundException('','') || HttpStatus.NOT_FOUND - 'any other runtime exception' | new RuntimeException() || HttpStatus.INTERNAL_SERVER_ERROR - 'runtime exception with cause' | new RuntimeException('', new RuntimeException()) || HttpStatus.INTERNAL_SERVER_ERROR - } - - def 'Register given list.'() { - given: 'register cm handle url and cmHandles' - def registerCmhandlesPost = "${basePathV1}/inventory/cmHandles" - def cmHandleJson = '{"cmHandles":["node1", "node2"]}' - when: 'the request is posted' - def response = mvc.perform( - post(registerCmhandlesPost) - .contentType(MediaType.APPLICATION_JSON) - .content(cmHandleJson) - ).andReturn().response - then: 'register cm handles in dmi service is invoked with correct parameters' - 1 * mockDmiService.registerCmHandles(_ as List<String>) - and: 'response status is created' - response.status == CREATED.value() - } - - def 'register cm handles called with empty content.'() { - given: 'register cm handle url and empty json' - def registerCmhandlesPost = "${basePathV1}/inventory/cmHandles" - def emptyJson = '{"cmHandles":[]}' - when: 'the request is posted' - def response = mvc.perform( - post(registerCmhandlesPost).contentType(MediaType.APPLICATION_JSON) - .content(emptyJson) - ).andReturn().response - then: 'response status is "bad request"' - response.status == BAD_REQUEST.value() - and: 'dmi service is not called' - 0 * mockDmiService.registerCmHandles(_) - } - - def 'Retrieve module resources.'() { - given: 'URL to get module resources' - def getModulesEndpoint = "$basePathV1/ch/some-cm-handle/moduleResources" - and: 'request data to get some modules' - String jsonData = TestUtils.getResourceFileContent('moduleResources.json') - and: 'the DMI service returns the yang resources' - ModuleReference moduleReference1 = new ModuleReference(name: 'ietf-yang-library', revision: '2016-06-21') - ModuleReference moduleReference2 = new ModuleReference(name: 'nc-notifications', revision: '2008-07-14') - def moduleReferences = [moduleReference1, moduleReference2] - def yangResources = new YangResources() - def yangResource = new YangResource(yangSource: '"some-data"', moduleName: 'NAME', revision: 'REVISION') - yangResources.add(yangResource) - mockDmiService.getModuleResources('some-cm-handle', moduleReferences) >> yangResources - when: 'the request is posted' - def response = mvc.perform(post(getModulesEndpoint) - .contentType(MediaType.APPLICATION_JSON) - .content(jsonData)).andReturn().response - then: 'a OK status is returned' - response.status == OK.value() - and: 'the response content matches the result from the DMI service' - response.getContentAsString() == '[{"yangSource":"\\"some-data\\"","moduleName":"NAME","revision":"REVISION"}]' - } - - def 'Retrieve module resources with exception handling.'() { - given: 'URL to get module resources' - def getModulesEndpoint = "$basePathV1/ch/some-cm-handle/moduleResources" - and: 'request data to get some modules' - String jsonData = TestUtils.getResourceFileContent('moduleResources.json') - and: 'the system throws a not-found exception (during the processing)' - mockDmiService.getModuleResources('some-cm-handle', _) >> { throw Mock(ModuleResourceNotFoundException.class) } - when: 'the request is posted' - def response = mvc.perform(post(getModulesEndpoint) - .contentType(MediaType.APPLICATION_JSON) - .content(jsonData)).andReturn().response - then: 'a not found status is returned' - response.status == HttpStatus.NOT_FOUND.value() - } - - def 'Retrieve module resources and ensure module set tag is logged.'() { - given: 'URL to get module resources' - def getModulesEndpoint = "$basePathV1/ch/some-cm-handle/moduleResources" - and: 'request data to get some modules' - String jsonData = TestUtils.getResourceFileContent('moduleResources.json') - and: 'the DMI service returns the yang resources' - def moduleReferences = [] - def yangResources = new YangResources() - def yangResource = new YangResource() - yangResources.add(yangResource) - mockDmiService.getModuleResources('some-cm-handle', moduleReferences) >> yangResources - when: 'the request is posted' - mvc.perform(post(getModulesEndpoint) - .contentType(MediaType.APPLICATION_JSON) - .content(jsonData)) - then: 'the module set tag is logged' - def loggingMessage = getLoggingMessage(0) - assert loggingMessage.contains('module-set-tag1') - } - - def 'Get resource data for pass-through operational.'() { - given: 'Get resource data url and some request data' - def getResourceDataForCmHandleUrl = "${basePathV1}/ch/some-cmHandle/data/ds/ncmp-datastore:passthrough-operational" + - "?resourceIdentifier=parent/child&options=(fields=myfields,depth=5)" - def someValidJson = '{}' - when: 'the request is posted' - def response = mvc.perform( - post(getResourceDataForCmHandleUrl).contentType(MediaType.APPLICATION_JSON).content(someValidJson) - ).andReturn().response - then: 'response status is ok' - response.status == OK.value() - and: 'dmi service method to get resource data is invoked once' - 1 * mockDmiService.getResourceData('some-cmHandle', - 'parent/child', - '(fields=myfields,depth=5)', - 'content=all') - } - - def 'Get resource data for pass-through operational with write request (invalid).'() { - given: 'Get resource data url' - def getResourceDataForCmHandleUrl = "${basePathV1}/ch/some-cmHandle/data/ds/ncmp-datastore:passthrough-operational" + - "?resourceIdentifier=parent/child&options=(fields=myfields,depth=5)" - and: 'an invalid write request data for "create" operation' - def jsonData = '{"operation":"create"}' - when: 'the request is posted' - def response = mvc.perform( - post(getResourceDataForCmHandleUrl).contentType(MediaType.APPLICATION_JSON).content(jsonData) - ).andReturn().response - then: 'response status is bad request' - response.status == BAD_REQUEST.value() - and: 'dmi service is not invoked' - 0 * mockDmiService.getResourceData(*_) - } - - def 'Get resource data for invalid datastore'() { - given: 'Get resource data url' - def getResourceDataForCmHandleUrl = "${basePathV1}/ch/some-cmHandle/data/ds/dummy-datastore" + - "?resourceIdentifier=parent/child&options=(fields=myfields,depth=5)" - and: 'an invalid write request data for "create" operation' - def jsonData = '{"operation":"create"}' - when: 'the request is posted' - def response = mvc.perform( - post(getResourceDataForCmHandleUrl).contentType(MediaType.APPLICATION_JSON).content(jsonData) - ).andReturn().response - then: 'response status is internal server error' - response.status == INTERNAL_SERVER_ERROR.value() - and: 'response contains expected error message' - response.contentAsString.contains('dummy-datastore is an invalid datastore name') - } - - def 'data with #scenario operation using passthrough running.'() { - given: 'write data for passthrough running url' - def writeDataForPassthroughRunning = "${basePathV1}/ch/some-cmHandle/data/ds/ncmp-datastore:passthrough-running" + - "?resourceIdentifier=some-resourceIdentifier" - and: 'request data for #scenario' - def jsonData = TestUtils.getResourceFileContent(requestBodyFile) - and: 'dmi service is called' - mockDmiService.writeData(operationEnum, 'some-cmHandle', - 'some-resourceIdentifier', dataType, - 'normal request body' ) >> '{some-json}' - when: 'the request is posted' - def response = mvc.perform( - post(writeDataForPassthroughRunning).contentType(MediaType.APPLICATION_JSON) - .content(jsonData) - ).andReturn().response - then: 'response status is #expectedResponseStatus' - response.status == expectedResponseStatus - and: 'the response content matches the result from the DMI service' - response.getContentAsString() == expectedJsonResponse - where: 'given request body and data' - scenario | requestBodyFile | operationEnum | dataType || expectedResponseStatus | expectedJsonResponse - 'Create' | 'createDataWithNormalChar.json' | CREATE | 'application/json' || CREATED.value() | '{some-json}' - 'Update' | 'updateData.json' | UPDATE | 'application/json' || OK.value() | '{some-json}' - 'Delete' | 'deleteData.json' | DELETE | 'application/json' || NO_CONTENT.value() | '{some-json}' - 'Read' | 'readData.json' | READ | 'application/json' || OK.value() | '' - 'Patch' | 'patchData.json' | PATCH | 'application/yang.patch+json' || OK.value() | '{some-json}' - } - - def 'Create data using passthrough for special characters.'(){ - given: 'create data for cmHandle url' - def writeDataForCmHandlePassthroughRunning = "${basePathV1}/ch/some-cmHandle/data/ds/ncmp-datastore:passthrough-running" + - "?resourceIdentifier=some-resourceIdentifier" - and: 'request data with special characters' - def jsonData = TestUtils.getResourceFileContent('createDataWithSpecialChar.json') - and: 'dmi service returns data' - mockDmiService.writeData(CREATE, 'some-cmHandle', 'some-resourceIdentifier', 'application/json', - 'data with quote \" and new line \n') >> '{some-json}' - when: 'the request is posted' - def response = mvc.perform( - post(writeDataForCmHandlePassthroughRunning).contentType(MediaType.APPLICATION_JSON).content(jsonData) - ).andReturn().response - then: 'response status is CREATED' - response.status == CREATED.value() - and: 'the response content matches the result from the DMI service' - response.getContentAsString() == '{some-json}' - } - - def 'PassThrough Returns OK when topic is used for async'(){ - given: 'Passthrough read URL and request data with a topic (parameter)' - def readPassThroughUrl ="${basePathV1}/ch/some-cmHandle/data/ds/ncmp-datastore:" + - resourceIdentifier + - '?resourceIdentifier=some-resourceIdentifier&topic=test-topic' - def jsonData = TestUtils.getResourceFileContent('readData.json') - when: 'the request is posted' - def response = mvc.perform( - post(readPassThroughUrl).contentType(MediaType.APPLICATION_JSON).content(jsonData) - ).andReturn().response - then: 'response status is OK' - assert response.status == HttpStatus.NO_CONTENT.value() - where: 'the following values are used' - resourceIdentifier << ['passthrough-operational', 'passthrough-running'] - } - - def 'PassThrough logs module set tag'(){ - given: 'Passthrough read URL and request data with a module set tag (parameter)' - def readPassThroughUrl ="${basePathV1}/ch/some-cmHandle/data/ds/ncmp-datastore:" + - 'passthrough-running?resourceIdentifier=some-resourceIdentifier' - def jsonData = TestUtils.getResourceFileContent('readData.json') - when: 'the request is posted' - mvc.perform( - post(readPassThroughUrl).contentType(MediaType.APPLICATION_JSON).content(jsonData)) - then: 'response status is OK' - def loggingMessage = getLoggingMessage(0) - assert loggingMessage.contains('module-set-tag-example') - } - - def 'Get resource data for pass-through running with #scenario value in resource identifier param.'() { - given: 'Get resource data url' - def getResourceDataForCmHandleUrl = "${basePathV1}/ch/some-cmHandle/data/ds/ncmp-datastore:passthrough-running" + - "?resourceIdentifier="+resourceIdentifier+"&options=(fields=myfields,depth=5)" - and: 'some valid json data' - def json = '{"cmHandleProperties" : { "prop1" : "value1", "prop2" : "value2"}}' - when: 'the request is posted' - def response = mvc.perform( - post(getResourceDataForCmHandleUrl).contentType(MediaType.APPLICATION_JSON).content(json) - ).andReturn().response - then: 'response status is ok' - response.status == OK.value() - and: 'dmi service method to get resource data is invoked once with correct parameters' - 1 * mockDmiService.getResourceData('some-cmHandle', - resourceIdentifier, - '(fields=myfields,depth=5)', - 'content=config') - where: 'tokens are used in the resource identifier parameter' - scenario | resourceIdentifier - '/' | 'id/with/slashes' - '?' | 'idWith?' - ',' | 'idWith,' - '=' | 'idWith=' - '[]' | 'idWith[]' - '? needs to be encoded as %3F' | 'idWith%3F' - - } - - def 'Execute a data operation for a list of operations.'() { - given: 'an endpoint for a data operation request with list of cmhandles in request body' - def resourceDataUrl = "$basePathV1/data?topic=client-topic-name&requestId=some-requestId" - and: 'list of operation details are received into request body' - def dataOperationRequestBody = '[{"operation": "read", "operationId": "14", "datastore": "ncmp-datastore:passthrough-operational", "options": "some options", "resourceIdentifier": "some resourceIdentifier",' + - '"cmHandles": [ {"id": "cmHandle123", "moduleSetTag": "module-set-tag1", "cmHandleProperties": { "myProp`": "some value", "otherProp": "other value"}}]}]' - when: 'the dmi resource data for dataOperation api is called.' - def response = mvc.perform( - post(resourceDataUrl).contentType(MediaType.APPLICATION_JSON).content(dataOperationRequestBody) - ).andReturn().response - then: 'the resource data operation endpoint returns the not implemented response' - assert response.status == 501 - and: 'the job details are correctly received (logged)' - assert getLoggingMessage(1).contains('some-requestId') - assert getLoggingMessage(2).contains('client-topic-name') - assert getLoggingMessage(4).contains('some resourceIdentifier') - assert getLoggingMessage(5).contains('module-set-tag1') - and: 'the operation Id is correctly received (logged)' - assert getLoggingMessage(6).contains('14') - } - - def getLoggingMessage(int index) { - return logger.list[index].formattedMessage - } -}
\ No newline at end of file diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy deleted file mode 100644 index 8531d35f..00000000 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy +++ /dev/null @@ -1,273 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation - * Modifications Copyright (C) 2021-2022 Bell Canada - * ================================================================================ - * 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.dmi.service - -import com.fasterxml.jackson.core.JsonProcessingException -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.ObjectWriter -import org.onap.cps.ncmp.dmi.config.DmiPluginConfig -import org.onap.cps.ncmp.dmi.exception.CmHandleRegistrationException -import org.onap.cps.ncmp.dmi.exception.DmiException -import org.onap.cps.ncmp.dmi.exception.ModuleResourceNotFoundException -import org.onap.cps.ncmp.dmi.exception.ModulesNotFoundException -import org.onap.cps.ncmp.dmi.exception.HttpClientRequestException -import org.onap.cps.ncmp.dmi.service.model.ModuleReference -import org.onap.cps.ncmp.dmi.model.YangResource -import org.onap.cps.ncmp.dmi.model.YangResources -import org.onap.cps.ncmp.dmi.service.client.NcmpRestClient -import org.onap.cps.ncmp.dmi.service.model.ModuleSchema -import org.onap.cps.ncmp.dmi.service.operation.SdncOperations -import org.springframework.http.HttpStatus -import org.springframework.http.ResponseEntity -import spock.lang.Specification - -import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.CREATE -import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.UPDATE - -class DmiServiceImplSpec extends Specification { - - - def mockNcmpRestClient = Mock(NcmpRestClient) - def mockDmiPluginProperties = Mock(DmiPluginConfig.DmiPluginProperties) - def spyObjectMapper = Spy(ObjectMapper) - def mockObjectMapper = Mock(ObjectMapper) - def mockSdncOperations = Mock(SdncOperations) - def objectUnderTest = new DmiServiceImpl(mockDmiPluginProperties, mockNcmpRestClient, mockSdncOperations, spyObjectMapper) - - def 'Register cm handles with ncmp.'() { - given: 'some cm-handle ids' - def givenCmHandlesList = ['node1', 'node2'] - and: 'json payload' - def expectedJson = '{"dmiPlugin":"test-dmi-service","createdCmHandles":[{"cmHandle":"node1"},{"cmHandle":"node2"}]}' - and: 'process returns "test-dmi-service" for service name' - mockDmiPluginProperties.getDmiServiceUrl() >> 'test-dmi-service' - when: 'the cm handles are registered' - objectUnderTest.registerCmHandles(givenCmHandlesList) - then: 'register cm handle with ncmp is called with the expected json and return "created" status' - 1 * mockNcmpRestClient.registerCmHandlesWithNcmp(expectedJson) >> new ResponseEntity<>(HttpStatus.CREATED) - } - - def 'Register cm handles with ncmp called with exception #scenario.'() { - given: 'some cm-handle ids' - def cmHandlesList = ['node1', 'node2'] - and: 'process returns "test-dmi-service" for service name' - mockDmiPluginProperties.getDmiServiceUrl() >> 'test-dmi-service' - and: 'returns #responseEntity' - mockNcmpRestClient.registerCmHandlesWithNcmp(_ as String) >> responseEntity - when: 'the cm handles are registered' - objectUnderTest.registerCmHandles(cmHandlesList) - then: 'a registration exception is thrown' - thrown(CmHandleRegistrationException.class) - where: 'given #scenario' - scenario | responseEntity - 'ncmp rest client returns bad request' | new ResponseEntity<>(HttpStatus.BAD_REQUEST) - 'ncmp rest client returns internal server error' | new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR) - } - - def 'Register cm handles with ncmp with wrong data.'() { - given: 'some cm-handle ids' - def cmHandlesList = ['node1', 'node2'] - and: ' "JsonProcessingException" occurs during parsing' - objectUnderTest.objectMapper = mockObjectMapper - mockObjectMapper.writeValueAsString(_) >> { throw new JsonProcessingException('some error.') } - when: 'the cmHandles are registered' - objectUnderTest.registerCmHandles(cmHandlesList) - then: 'a dmi exception is thrown' - thrown(DmiException.class) - } - - def ' Get modules for a cm-handle.'() { - given: 'a cm handle' - def cmHandle = 'node1' - and: 'process returns one module schema for the cmhandle' - def moduleSchema = new ModuleSchema( - identifier: "example-identifier", - namespace: "example:namespace", - version: "example-version") - mockSdncOperations.getModuleSchemasFromNode(cmHandle) >> List.of(moduleSchema) - when: 'modules for cmHandle is requested' - def result = objectUnderTest.getModulesForCmHandle(cmHandle) - then: 'one module is returned' - result.schemas.size() == 1 - and: 'module has expected values' - with(result.schemas[0]) { - it.getRevision() == moduleSchema.getVersion() - it.getModuleName() == moduleSchema.getIdentifier() - it.getNamespace() == moduleSchema.getNamespace(); - } - } - - def 'no modules found for the cmhandle.'() { - given: 'cm handle id' - def cmHandle = 'node1' - and: 'process returns no modules' - mockSdncOperations.getModuleSchemasFromNode(cmHandle) >> Collections.emptyList(); - when: 'modules for cm-handle is requested' - objectUnderTest.getModulesForCmHandle(cmHandle) - then: 'module not found exception is thrown' - thrown(ModulesNotFoundException) - } - - def 'Get multiple module resources.'() { - given: 'a cmHandle' - def cmHandle = 'some-cmHandle' - and: 'multiple module references' - def moduleReference1 = new ModuleReference(name: 'name-1', revision: 'revision-1') - def moduleReference2 = new ModuleReference(name: 'name-2', revision: 'revision-2') - def moduleList = [moduleReference1, moduleReference2] - when: 'module resources is requested' - def result = objectUnderTest.getModuleResources(cmHandle, moduleList) - then: 'SDNC operation service is called same number of module references given' - 2 * mockSdncOperations.getModuleResource(cmHandle, _) >>> [new ResponseEntity<String>('{"ietf-netconf-monitoring:output": {"data": "some-data1"}}', HttpStatus.OK), - new ResponseEntity<String>('{"ietf-netconf-monitoring:output": {"data": "some-data2"}}', HttpStatus.OK)] - and: 'the result contains the expected properties' - def yangResources = new YangResources() - def yangResource1 = new YangResource(yangSource: 'some-data1', moduleName: 'name-1', revision: 'revision-1') - def yangResource2 = new YangResource(yangSource: 'some-data2', moduleName: 'name-2', revision: 'revision-2') - yangResources.add(yangResource1) - yangResources.add(yangResource2) - assert result == yangResources - } - - def 'Get a module resource with module resource not found exception for #scenario.'() { - given: 'a cmHandle and module reference list' - def cmHandle = 'some-cmHandle' - def moduleReference = new ModuleReference(name: 'NAME', revision: 'REVISION') - def moduleList = [moduleReference] - when: 'module resources is requested' - objectUnderTest.getModuleResources(cmHandle, moduleList) - then: 'SDNC operation service is called once with a response body that contains no data' - 1 * mockSdncOperations.getModuleResource(cmHandle, _) >> new ResponseEntity<String>(responseBody, HttpStatus.OK) - and: 'an exception is thrown' - thrown(ModuleResourceNotFoundException) - where: 'the following values are returned' - scenario | responseBody - 'a response body containing no data object' | '{"ietf-netconf-monitoring:output": {"null": "some-data"}}' - 'a response body containing no ietf-netconf-monitoring:output object' | '{"null": {"data": "some-data"}}' - } - - def 'Get module resources when sdnc returns #scenario response.'() { - given: 'sdnc returns a #scenario response' - mockSdncOperations.getModuleResource(_ as String, _ as String) >> new ResponseEntity<String>('some-response-body', httpStatus) - when: 'module resources is requested' - objectUnderTest.getModuleResources('some-cmHandle', [new ModuleReference()] as LinkedList<ModuleReference>) - then: '#expectedException is thrown' - thrown(expectedException) - where: 'the following values are returned' - scenario | httpStatus || expectedException - 'not found' | HttpStatus.NOT_FOUND || ModuleResourceNotFoundException - 'internal server error' | HttpStatus.INTERNAL_SERVER_ERROR || DmiException - } - - def 'Get module resources with JSON processing exception.'() { - given: 'a json processing exception during process' - def mockObjectWriter = Mock(ObjectWriter) - spyObjectMapper.writer() >> mockObjectWriter - mockObjectWriter.withRootName(_) >> mockObjectWriter - def jsonProcessingException = new JsonProcessingException('') - mockObjectWriter.writeValueAsString(_) >> { throw jsonProcessingException } - when: 'module resources is requested' - objectUnderTest.getModuleResources('some-cmHandle', [new ModuleReference()] as LinkedList<ModuleReference>) - then: 'an exception is thrown' - def thrownException = thrown(DmiException.class) - and: 'the exception has the expected message and details' - thrownException.message == 'Unable to process JSON.' - thrownException.details == 'JSON exception occurred when creating the module request.' - and: 'the cause is the original json processing exception' - thrownException.cause == jsonProcessingException - } - - def 'Get resource data for passthrough operational.'() { - given: 'sdnc operation returns OK response' - mockSdncOperations.getResouceDataForOperationalAndRunning( - 'someCmHandle', - 'someResourceId', - '(fields=x/y/z,depth=10,test=abc)', - 'content=all') >> new ResponseEntity<>('response json', HttpStatus.OK) - when: 'resource data is requested' - def response = objectUnderTest.getResourceData( - 'someCmHandle', - 'someResourceId', - '(fields=x/y/z,depth=10,test=abc)', - 'content=all') - then: 'response matches the response returned from the SDNC service' - response == 'response json' - } - - def 'Get resource data with not found exception.'() { - given: 'sdnc operation returns "NOT_FOUND" response' - mockSdncOperations.getResouceDataForOperationalAndRunning(*_) >> new ResponseEntity<>(HttpStatus.NOT_FOUND) - when: 'resource data is requested' - objectUnderTest.getResourceData('someCmHandle', 'someResourceId', - '(fields=x/y/z,depth=10,test=abc)', 'content=config') - then: 'http client request exception' - thrown(HttpClientRequestException.class) - } - - def 'Get resource data for passthrough running.'() { - given: 'sdnc operation returns OK response' - mockSdncOperations.getResouceDataForOperationalAndRunning(*_) >> new ResponseEntity<>('response json', HttpStatus.OK) - when: 'resource data is requested' - def response = objectUnderTest.getResourceData( - 'someCmHandle', - 'someResourceId', - '(fields=x/y/z,depth=10,test=abc)', - 'content=config') - then: 'response have expected json' - response == 'response json' - } - - def 'Write resource data for passthrough running with a #scenario from sdnc.'() { - given: 'sdnc returns a response with #scenario' - mockSdncOperations.writeData(operationEnum, _, _, _, _) >> new ResponseEntity<String>('response json', httpResponse) - when: 'resource data is written to sdnc' - def response = objectUnderTest.writeData(operationEnum, 'some-cmHandle', - 'some-resourceIdentifier', 'some-dataType', '{some-data}') - then: 'the response matches the expected data' - response == 'response json' - where: 'the following values are used' - scenario | httpResponse | operationEnum - '200 OK with an update operation' | HttpStatus.OK | UPDATE - '201 CREATED with a create operation' | HttpStatus.CREATED | CREATE - } - - def 'Write resource data with special characters.'() { - given: 'sdnc returns a created response' - mockSdncOperations.writeData(CREATE, 'some-cmHandle', - 'some-resourceIdentifier', 'some-dataType', 'data with quote " and \n new line') >> new ResponseEntity<String>('response json', HttpStatus.CREATED) - when: 'resource data is written to sdnc' - def response = objectUnderTest.writeData(CREATE, 'some-cmHandle', - 'some-resourceIdentifier', 'some-dataType', 'data with quote " and \n new line') - then: 'the response matches the expected data' - response == 'response json' - } - - def 'Write resource data for passthrough running with a 500 response from sdnc.'() { - given: 'sdnc returns internal server error response' - mockSdncOperations.writeData(CREATE, _, _, _, _) >> new ResponseEntity<String>('response json', HttpStatus.INTERNAL_SERVER_ERROR) - when: 'resource data is written to sdnc' - objectUnderTest.writeData(CREATE, 'some-cmHandle', - 'some-resourceIdentifier', 'some-dataType', _ as String) - then: 'a dmi exception is thrown' - thrown(DmiException.class) - } -}
\ No newline at end of file diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/service/YangResourceExtractorSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/service/YangResourceExtractorSpec.groovy deleted file mode 100644 index 656cfcb5..00000000 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/service/YangResourceExtractorSpec.groovy +++ /dev/null @@ -1,98 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.dmi.service - -import com.google.gson.JsonSyntaxException -import org.onap.cps.ncmp.dmi.exception.ModuleResourceNotFoundException -import org.onap.cps.ncmp.dmi.service.model.ModuleReference -import org.springframework.http.ResponseEntity -import spock.lang.Specification - -class YangResourceExtractorSpec extends Specification { - - static def BACK_SLASH = '\\'; - static def NEW_LINE = '\n'; - static def QUOTE = '"'; - static def TAB = '\t'; - - static def YANG_ESCAPED_NEW_LINE = '\\n' - static def YANG_ESCAPED_BACK_SLASH = '\\\\' - static def YANG_ESCAPED_QUOTE = '\\"' - static def YANG_ESCAPED_TAB = '\\t' - - static def SDNC_OUTPUT_JSON_NAME = '"ietf-netconf-monitoring:output"' - - def moduleReference = new ModuleReference(name: 'test', revision: 'rev') - def responseEntity = Mock(ResponseEntity) - - def 'Extract yang resource with escaped characters in the source.'() { - given: 'a response entity with a data field of value #jsonValue' - responseEntity.getBody() >> '{' + SDNC_OUTPUT_JSON_NAME + ': { "data": "' + jsonValue + '" }}' - when: 'the yang resource is extracted' - def result = YangResourceExtractor.toYangResource(moduleReference, responseEntity) - then: 'the yang source string is as expected' - result.getYangSource() == expectedString - where: 'the following data is used' - jsonValue || expectedString - 'line1' + YANG_ESCAPED_NEW_LINE + 'line2' || 'line1' + NEW_LINE + 'line2' - 'a' + YANG_ESCAPED_BACK_SLASH+'b' || 'a'+BACK_SLASH +'b' - 'a' + YANG_ESCAPED_QUOTE + 'b' || 'a'+QUOTE+'b' - 'a' + YANG_ESCAPED_TAB + 'b' || 'a'+TAB+'b' - } - - def 'Extract yang resource with escaped characters in the source inside escaped double quotes.'() { - given: 'a response entity with a data field of value #jsonValue wrapped in escaped double quotes' - responseEntity.getBody() >> '{' + SDNC_OUTPUT_JSON_NAME + ': { "data": "' + YANG_ESCAPED_QUOTE + jsonValue + YANG_ESCAPED_QUOTE + '" }}' - when: 'the yang resource is extracted' - def result = YangResourceExtractor.toYangResource(moduleReference, responseEntity) - then: 'the yang source string is as expected' - result.getYangSource() == expectedString - where: 'the following data is used' - jsonValue || expectedString - 'line1' + YANG_ESCAPED_NEW_LINE + 'line2' || '"line1' + NEW_LINE + 'line2"' - 'a' + YANG_ESCAPED_BACK_SLASH+'b' || '"a'+BACK_SLASH +'b"' - 'a' + YANG_ESCAPED_QUOTE + 'b' || '"a'+QUOTE+'b"' - 'a' + YANG_ESCAPED_TAB + 'b' || '"a'+TAB+'b"' - } - - def 'Attempt to extract yang resource with un-escaped double quotes in the source.'() { - given: 'a response entity with a data field with unescaped double quotes' - responseEntity.getBody() >> '{' + SDNC_OUTPUT_JSON_NAME + ': { "data": "' + QUOTE + 'some data' + QUOTE + '" }}' - when: 'Json is converted to String' - YangResourceExtractor.toYangResource(moduleReference, responseEntity) - then: 'the output of the method is equal to the output from the test template' - thrown(JsonSyntaxException) - } - - def 'Attempt to extract yang resource without #without.'() { - given: 'a response entity with a body without #without' - responseEntity.getBody() >> jsonBody - when: 'Json is converted to String' - YangResourceExtractor.toYangResource(moduleReference, responseEntity) - then: 'the output of the method is equal to the output from the test template' - thrown(ModuleResourceNotFoundException) - where: - without | jsonBody - 'data' | '{' + SDNC_OUTPUT_JSON_NAME + ': { "something": "else" }}' - SDNC_OUTPUT_JSON_NAME | '{"something:else": { "data": "data" }}' - } - -} diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/service/client/NcmpRestClientSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/service/client/NcmpRestClientSpec.groovy deleted file mode 100644 index 4d7e27e2..00000000 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/service/client/NcmpRestClientSpec.groovy +++ /dev/null @@ -1,57 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021-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.dmi.service.client - -import org.onap.cps.ncmp.dmi.config.DmiConfiguration -import org.springframework.http.HttpMethod -import org.springframework.http.ResponseEntity -import org.springframework.web.client.RestTemplate -import spock.lang.Specification - -class NcmpRestClientSpec extends Specification { - def objectUnderTest = new NcmpRestClient(mockCpsProperties, mockRestTemplate) - def mockCpsProperties = Mock(DmiConfiguration.CpsProperties) - def mockRestTemplate = Mock(RestTemplate) - - def setup() { - objectUnderTest.cpsProperties = mockCpsProperties - objectUnderTest.restTemplate = mockRestTemplate - } - - def 'Register a cm handle.'() { - given: 'some request data' - def someRequestData = 'some request data' - and: 'configuration data' - mockCpsProperties.baseUrl >> 'http://some-uri' - mockCpsProperties.dmiRegistrationUrl >> 'some-url' - mockCpsProperties.authUsername >> 'some-username' - mockCpsProperties.authPassword >> 'some-password' - and: 'the rest template returns a valid response entity' - def mockResponseEntity = Mock(ResponseEntity) - when: 'registering a cm handle' - def result = objectUnderTest.registerCmHandlesWithNcmp(someRequestData) - then: 'the rest template is called with the correct uri and original request data in the body' - 1 * mockRestTemplate.exchange({ it.toString() == 'http://some-uri/some-url' }, - HttpMethod.POST, { it.body.contains(someRequestData) }, String.class) >> mockResponseEntity - and: 'the output of the method is equal to the output from the rest template service' - result == mockResponseEntity - } -}
\ No newline at end of file diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClientSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClientSpec.groovy deleted file mode 100644 index f334f780..00000000 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClientSpec.groovy +++ /dev/null @@ -1,102 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021-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.dmi.service.client - -import org.onap.cps.ncmp.dmi.config.DmiConfiguration -import org.springframework.http.HttpEntity -import org.springframework.http.HttpHeaders -import org.springframework.http.HttpMethod -import org.springframework.http.ResponseEntity -import org.springframework.web.client.RestTemplate -import spock.lang.Specification - -import static org.springframework.http.HttpMethod.GET -import static org.springframework.http.HttpMethod.POST -import static org.springframework.http.HttpMethod.DELETE -import static org.springframework.http.HttpMethod.PUT - -class SdncRestconfClientSpec extends Specification { - - def mockSdncProperties = Mock(DmiConfiguration.SdncProperties) - def mockRestTemplate = Mock(RestTemplate) - def objectUnderTest = new SdncRestconfClient(mockSdncProperties, mockRestTemplate) - - def 'SDNC GET operation.'() { - given: 'a get resource url' - def getResourceUrl = '/getResourceUrl' - and: 'test configuration data' - setupTestConfigurationData() - and: 'the process returns a valid response entity' - def mockResponseEntity = Mock(ResponseEntity) - mockRestTemplate.exchange({ it.toString() == 'http://some-uri/getResourceUrl' }, - HttpMethod.GET, _ as HttpEntity, String.class) >> mockResponseEntity - when: 'the resource is fetched' - def result = objectUnderTest.getOperation(getResourceUrl) - then: 'the output of the method is equal to the output from the rest template service' - result == mockResponseEntity - } - - def 'SDNC #scenario operation called.'() { - given: 'some request data' - def someRequestData = 'some request data' - and: 'a url for get module resources' - def getModuleResourceUrl = '/getModuleResourceUrl' - and: 'test configuration data' - setupTestConfigurationData() - and: 'the process returns a valid response entity' - def mockResponseEntity = Mock(ResponseEntity) - when: 'the resource is fetched' - def result = objectUnderTest.httpOperationWithJsonData(expectedHttpMethod, getModuleResourceUrl, someRequestData, new HttpHeaders()) - then: 'the rest template is called with the correct uri and json in the body' - 1 * mockRestTemplate.exchange({ it.toString() == 'http://some-uri/getModuleResourceUrl' }, - expectedHttpMethod, { it.body.contains(someRequestData) }, String.class) >> mockResponseEntity - and: 'the output of the method is the same as the output from the rest template service' - result == mockResponseEntity - where: 'the following values are used' - scenario || expectedHttpMethod - 'POST' || POST - 'PUT' || PUT - 'GET' || GET - 'DELETE' || DELETE - } - - def 'SDNC GET operation with headers.'() { - given: 'a get url' - def getResourceUrl = '/getResourceUrl' - and: 'test configuration data' - setupTestConfigurationData() - and: 'the process returns a valid response entity' - def mockResponseEntity = Mock(ResponseEntity) - mockRestTemplate.exchange({ it.toString() == 'http://some-uri/getResourceUrl' }, - HttpMethod.GET, _ as HttpEntity, String.class) >> mockResponseEntity - when: 'the resource is fetched with headers' - def result = objectUnderTest.getOperation(getResourceUrl, new HttpHeaders()) - then: 'the output of the method is equal to the output from the rest template service' - result == mockResponseEntity - } - - def setupTestConfigurationData() { - mockSdncProperties.baseUrl >> 'http://some-uri' - mockSdncProperties.authUsername >> 'some-username' - mockSdncProperties.authPassword >> 'some-password' - mockSdncProperties.topologyId >> 'some-topology-id' - } -}
\ No newline at end of file diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/service/operation/SdncOperationsSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/service/operation/SdncOperationsSpec.groovy deleted file mode 100644 index 9dcb72e6..00000000 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/service/operation/SdncOperationsSpec.groovy +++ /dev/null @@ -1,176 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation - * Modifications Copyright (C) 2021-2022 Bell Canada - * ================================================================================ - * 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.dmi.service.operation - -import org.onap.cps.ncmp.dmi.TestUtils -import org.onap.cps.ncmp.dmi.config.DmiConfiguration -import org.onap.cps.ncmp.dmi.exception.SdncException -import org.onap.cps.ncmp.dmi.service.client.SdncRestconfClient -import org.spockframework.spring.SpringBean -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.http.HttpHeaders -import org.springframework.http.HttpMethod -import org.springframework.http.HttpStatus -import org.springframework.http.ResponseEntity -import org.springframework.test.context.ContextConfiguration -import spock.lang.Specification - -import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.CREATE -import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.DELETE -import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.PATCH -import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.UPDATE -import static org.onap.cps.ncmp.dmi.model.DataAccessRequest.OperationEnum.READ - -@SpringBootTest -@ContextConfiguration(classes = [DmiConfiguration.SdncProperties, SdncOperations]) -class SdncOperationsSpec extends Specification { - - @SpringBean - SdncRestconfClient mockSdncRestClient = Mock() - - @Autowired - SdncOperations objectUnderTest - - def 'get modules from node.'() { - given: 'a node id and url' - def nodeId = 'node1' - def expectedUrl = '/rests/data/network-topology:network-topology/topology=test-topology/node=node1/yang-ext:mount/ietf-netconf-monitoring:netconf-state/schemas' - and: 'sdnc returns one module during process' - mockSdncRestClient.getOperation(expectedUrl) >> - ResponseEntity.ok(TestUtils.getResourceFileContent('ModuleSchema.json')) - when: 'module schemas from node are fetched' - def moduleSchemas = objectUnderTest.getModuleSchemasFromNode(nodeId) - then: 'one module is found' - moduleSchemas.size() == 1 - and: 'module schema has expected values' - with(moduleSchemas[0]) { - it.getIdentifier() == "example-identifier" - it.getNamespace() == "example:namespace" - it.getVersion() == "example-version" - it.getFormat() == "example-format" - it.getLocation() == ["example-location"] - } - } - - def 'No modules from Node: SDNC Response - #scenario .'() { - given: 'node id and url' - def nodeId = 'node1' - def expectedUrl = '/rests/data/network-topology:network-topology/topology=test-topology/node=node1/yang-ext:mount/ietf-netconf-monitoring:netconf-state/schemas' - and: 'sdnc operation returns #scenario' - mockSdncRestClient.getOperation(expectedUrl) >> ResponseEntity.ok(responseBody) - when: 'the module schemas are requested' - def moduleSchemas = objectUnderTest.getModuleSchemasFromNode(nodeId) - then: 'no module schemas are returned' - moduleSchemas.size() == 0 - where: - scenario | responseBody - 'null response body' | null - 'empty response body ' | '' - 'no module schema' | '{ "ietf-netconf-monitoring:schemas" : { "schema" : [] } } ' - } - - def 'Error handling - modules from node: #scenario'() { - given: 'node id and url' - def nodeId = 'node1' - def expectedUrl = '/rests/data/network-topology:network-topology/topology=test-topology/node=node1/yang-ext:mount/ietf-netconf-monitoring:netconf-state/schemas' - and: '#scenario is returned during process' - mockSdncRestClient.getOperation(expectedUrl) >> new ResponseEntity<>(sdncResponseBody, sdncHttpStatus) - when: 'module schemas from node are fetched' - objectUnderTest.getModuleSchemasFromNode(nodeId) - then: 'SDNCException is thrown' - def thrownException = thrown(SdncException) - thrownException.getDetails().contains(expectedExceptionDetails) - where: - scenario | sdncHttpStatus | sdncResponseBody || expectedExceptionDetails - 'failed response from SDNC' | HttpStatus.BAD_REQUEST | '{ "errorMessage" : "incorrect input"}' || '{ "errorMessage" : "incorrect input"}' - 'invalid json response' | HttpStatus.OK | 'invalid-json' || 'SDNC response is not in the expected format' - 'response in unexpected json schema' | HttpStatus.OK | '{ "format" : "incorrect" }' || 'SDNC response is not in the expected format' - } - - def 'Get module resources from SDNC.'() { - given: 'node id and url' - def nodeId = 'some-node' - def expectedUrl = '/rests/operations/network-topology:network-topology/topology=test-topology/node=some-node/yang-ext:mount/ietf-netconf-monitoring:get-schema' - when: 'module resource is fetched with the expected parameters' - objectUnderTest.getModuleResource(nodeId, 'some-json-data') - then: 'the SDNC Rest client is invoked with the correct parameters' - 1 * mockSdncRestClient.httpOperationWithJsonData(HttpMethod.POST, expectedUrl, 'some-json-data', _ as HttpHeaders) - } - - def 'Get resource data from node to SDNC.'() { - given: 'expected url' - def expectedUrl = '/rests/data/network-topology:network-topology/topology=test-topology/node=node1/yang-ext:mount/testResourceId?a=1&b=2&content=testContent' - when: 'resource data is fetched for given node ID' - objectUnderTest.getResouceDataForOperationalAndRunning('node1', 'testResourceId', - '(a=1,b=2)', 'content=testContent') - then: 'the SDNC get operation is executed with the correct URL' - 1 * mockSdncRestClient.getOperation(expectedUrl) - } - - def 'Write resource data with #scenario operation to SDNC.'() { - given: 'expected url' - def expectedUrl = '/rests/data/network-topology:network-topology/topology=test-topology/node=node1/yang-ext:mount/testResourceId' - when: 'write resource data for passthrough running is called' - objectUnderTest.writeData(operationEnum, 'node1', 'testResourceId', 'application/json', 'requestData') - then: 'the #expectedHttpMethod operation is executed with the correct parameters' - 1 * mockSdncRestClient.httpOperationWithJsonData(expectedHttpMethod, expectedUrl, 'requestData', _ as HttpHeaders) - where: 'the following values are used' - scenario | operationEnum || expectedHttpMethod - 'Create' | CREATE || HttpMethod.POST - 'Update' | UPDATE || HttpMethod.PUT - 'Read' | READ || HttpMethod.GET - 'Delete' | DELETE || HttpMethod.DELETE - 'Patch' | PATCH || HttpMethod.PATCH - } - - def 'build query param list for SDNC where options #scenario'() { - when: 'query param list is built' - def result = objectUnderTest.buildQueryParamMap(optionsParamInQuery, 'd=4') - .toSingleValueMap().toString() - then: 'result matches the expected result' - result == expectedResult - where: 'following parameters are used' - scenario | optionsParamInQuery || expectedResult - 'is single key-value pair' | '(a=x)' || '[a:x, d:4]' - 'is multiple key-value pairs' | '(a=x,b=y,c=z)' || '[a:x, b:y, c:z, d:4]' - 'has / as special char' | '(a=x,b=y,c=t/z)' || '[a:x, b:y, c:t/z, d:4]' - 'has " as special char' | '(a=x,b=y,c="z")' || '[a:x, b:y, c:"z", d:4]' - 'has [] as special char' | '(a=x,b=y,c=[z])' || '[a:x, b:y, c:[z], d:4]' - 'has = in value' | '(a=(x=y),b=x=y)' || '[a:(x=y), b:x=y, d:4]' - 'is empty' | '' || '[:]' - 'is null' | null || '[:]' - } - - def 'options parameters contains a comma #scenario'() { - when: 'query param list is built with #scenario' - def result = objectUnderTest.buildQueryParamMap(optionsParamInQuery, 'd=4').toSingleValueMap() - then: 'expect 2 elements from options where we are ignoring empty query param value, +1 from content query param (2+1) = 3 elements' - def expectedNoOfElements = 3 - and: 'results contains equal elements as expected' - result.size() == expectedNoOfElements - where: 'following parameters are used' - scenario | optionsParamInQuery - '"," in value' | '(a=(x,y),b=y)' - '"," in string value' | '(a="x,y",b=y)' - } -} diff --git a/src/test/java/org/onap/cps/ncmp/dmi/TestUtils.java b/src/test/java/org/onap/cps/ncmp/dmi/TestUtils.java deleted file mode 100644 index c10d91a5..00000000 --- a/src/test/java/org/onap/cps/ncmp/dmi/TestUtils.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.dmi; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; - -/** - * Common convenience methods for testing. - */ -public class TestUtils { - - /** - * Convert a file in the test resource folder to file. - * - * @param filename to name of the file in test/resources - * @return the file - * @throws IOException when there is an IO issue - */ - public static File readFile(final String filename) { - return new File(ClassLoader.getSystemClassLoader().getResource(filename).getFile()); - } - - /** - * Convert a file in the test resource folder to a string. - * - * @param filename to name of the file in test/resources - * @return the content of the file as a String - * @throws IOException when there is an IO issue - */ - public static String getResourceFileContent(final String filename) throws IOException { - final File file = readFile(filename); - return new String(Files.readAllBytes(file.toPath())); - } -} diff --git a/src/test/java/org/onap/cps/ncmp/dmi/rest/controller/TestController.java b/src/test/java/org/onap/cps/ncmp/dmi/rest/controller/TestController.java deleted file mode 100644 index 5240e239..00000000 --- a/src/test/java/org/onap/cps/ncmp/dmi/rest/controller/TestController.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.dmi.rest.controller; - -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class TestController { - - @GetMapping("/test") - ResponseEntity<String> test() { - return new ResponseEntity<>(HttpStatus.OK); - } -} diff --git a/src/test/resources/ModuleSchema.json b/src/test/resources/ModuleSchema.json deleted file mode 100644 index 50c67154..00000000 --- a/src/test/resources/ModuleSchema.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "ietf-netconf-monitoring:schemas": { - "schema": [ - { - "identifier": "example-identifier", - "version": "example-version", - "format": "example-format", - "namespace": "example:namespace", - "location": [ - "example-location" - ] - } - ] - } -}
\ No newline at end of file diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml deleted file mode 100644 index ddc2b45f..00000000 --- a/src/test/resources/application.yml +++ /dev/null @@ -1,79 +0,0 @@ -# ============LICENSE_START======================================================= -# 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. -# 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========================================================= - -rest: - api: - dmi-base-path: /dmi - -security: - permit-uri: /actuator/**,/swagger-ui/**,/swagger-resources/**,/v3/api-docs - auth: - username: cpsuser - password: cpsr0cks! - -sdnc: - baseUrl: http://test - topologyId: test-topology - auth: - username: test - password: test - -cps-core: - baseUrl: some url for cps - dmiRegistrationUrl: some registration url - auth: - username: some cps core user - password: some cps core password - -dmi: - service: - url: some url for the dmi service - avc: - subscription-topic: ncmp-dmi-cm-avc-subscription - subscription-response-topic: dmi-ncmp-cm-avc-subscription - -spring: - application: - name: ncmp-dmi-plugin - mvc: - pathmatch: - matching-strategy: ANT_PATH_MATCHER - kafka: - bootstrap-servers: ${KAFKA_BOOTSTRAP_SERVER} - security: - protocol: PLAINTEXT - producer: - key-serializer: org.apache.kafka.common.serialization.StringSerializer - value-serializer: io.cloudevents.kafka.CloudEventSerializer - client-id: ncmp-dmi-plugin - consumer: - group-id: ${NCMP_CONSUMER_GROUP_ID:ncmp-group} - key-deserializer: org.springframework.kafka.support.serializer.ErrorHandlingDeserializer - value-deserializer: org.springframework.kafka.support.serializer.ErrorHandlingDeserializer - properties: - spring.deserializer.key.delegate.class: org.apache.kafka.common.serialization.StringDeserializer - spring.deserializer.value.delegate.class: io.cloudevents.kafka.CloudEventDeserializer - spring.json.use.type.headers: false - -app: - ncmp: - async: - topic: ${NCMP_ASYNC_M2M_TOPIC:ncmp-async-m2m} - -logging: - format: json diff --git a/src/test/resources/cmNotificationSubscriptionCreationEvent.json b/src/test/resources/cmNotificationSubscriptionCreationEvent.json deleted file mode 100644 index 3b780976..00000000 --- a/src/test/resources/cmNotificationSubscriptionCreationEvent.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "data": { - "cmhandles": [ - { - "cmhandleId": "CMHandle1", - "private-properties": { - "prop1": "prop-value" - } - }, - { - "cmhandleId": "CMHandle2", - "private-properties": { - "prop-x": "prop-valuex", - "prop-p": "prop-valuep" - } - }, - { - "cmhandleId": "CMHandle3", - "private-properties": { - "prop-y": "prop-valuey" - } - } - ], - "predicates": [ - { - "targetFilter": [ - "CMHandle1", - "CMHandle2", - "CMHandle3" - ], - "scopeFilter": { - "datastore": "ncmp-datastore:passthrough-running", - "xpath-filter": [ - "//_3gpp-nr-nrm-gnbdufunction:GNBDUFunction/_3gpp-nr-nrm-nrcelldu:NRCellDU/", - "//_3gpp-nr-nrm-gnbcuupfunction:GNBCUUPFunction//", - "//_3gpp-nr-nrm-gnbcucpfunction:GNBCUCPFunction/_3gpp-nr-nrm-nrcelldu:NRCellCU//", - "//_3gpp-nr-nrm-nrsectorcarrier:NRSectorCarrier//" - ] - } - } - ] - } -}
\ No newline at end of file diff --git a/src/test/resources/createDataWithNormalChar.json b/src/test/resources/createDataWithNormalChar.json deleted file mode 100644 index 31cdf1c5..00000000 --- a/src/test/resources/createDataWithNormalChar.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "operation": "create", - "dataType": "application/json", - "data": "normal request body", - "cmHandleProperties": { - "some-property": "some-property-value" - } -}
\ No newline at end of file diff --git a/src/test/resources/createDataWithSpecialChar.json b/src/test/resources/createDataWithSpecialChar.json deleted file mode 100644 index 1e7622ee..00000000 --- a/src/test/resources/createDataWithSpecialChar.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "operation": "create", - "dataType": "application/json", - "data": "data with quote \" and new line \n", - "cmHandleProperties": { - "some-property": "some-property-value" - } -}
\ No newline at end of file diff --git a/src/test/resources/deleteData.json b/src/test/resources/deleteData.json deleted file mode 100644 index 2233fa01..00000000 --- a/src/test/resources/deleteData.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "operation": "delete", - "dataType": "application/json", - "data": "normal request body", - "cmHandleProperties": { - "some-property": "some-property-value" - } -}
\ No newline at end of file diff --git a/src/test/resources/moduleResources.json b/src/test/resources/moduleResources.json deleted file mode 100644 index 23adfcba..00000000 --- a/src/test/resources/moduleResources.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "data": { - "modules": [ - { - "name": "ietf-yang-library", - "revision": "2016-06-21" - }, - { - "name": "nc-notifications", - "revision": "2008-07-14" - } - ] - }, - "cmHandleProperties": { - "subsystemId": "system-001" - }, - "moduleSetTag": "module-set-tag1" -} diff --git a/src/test/resources/patchData.json b/src/test/resources/patchData.json deleted file mode 100644 index e5466eaf..00000000 --- a/src/test/resources/patchData.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "operation": "patch", - "dataType": "application/yang.patch+json", - "data": "normal request body", - "cmHandleProperties": { - "some-property": "some-property-value" - } -}
\ No newline at end of file diff --git a/src/test/resources/readData.json b/src/test/resources/readData.json deleted file mode 100644 index 53f6d2ed..00000000 --- a/src/test/resources/readData.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "operation": "read", - "dataType": "application/json", - "data": "normal request body", - "cmHandleProperties": { - "some-property": "some-property-value" - }, - "moduleSetTag": "module-set-tag-example" -}
\ No newline at end of file diff --git a/src/test/resources/updateData.json b/src/test/resources/updateData.json deleted file mode 100644 index 7cbf4f0c..00000000 --- a/src/test/resources/updateData.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "operation": "update", - "dataType": "application/json", - "data": "normal request body", - "cmHandleProperties": { - "some-property": "some-property-value" - } -}
\ No newline at end of file |