From 06cd50a60832b5c7b23181145b035472bfff1ebe Mon Sep 17 00:00:00 2001 From: rameshiyer27 Date: Mon, 28 Feb 2022 16:55:31 +0000 Subject: Add spring repository and service layer for tosca node templates Removed policy, policyType providers along with models provider configurations. Issue-ID: POLICY-3923 Signed-off-by: zrrmmua Change-Id: I696be6380758dbcc5b53cef635f3065eb0ce9a70 --- main/pom.xml | 2 +- .../policy/api/main/config/PolicyApiConfig.java | 43 +--- .../main/repository/NodeTemplateRepository.java | 30 +++ .../api/main/repository/NodeTypeRepository.java | 30 +++ .../api/main/rest/NodeTemplateController.java | 19 +- .../main/rest/provider/CommonModelProvider.java | 228 --------------------- .../main/rest/provider/NodeTemplateProvider.java | 110 ---------- .../api/main/rest/provider/PolicyProvider.java | 165 --------------- .../api/main/rest/provider/PolicyTypeProvider.java | 127 ------------ .../api/main/service/NodeTemplateService.java | 144 +++++++++++++ .../main/service/ToscaServiceTemplateService.java | 144 +++++++++++++ main/src/main/resources/application.yaml | 9 - .../api/main/rest/TestNodeTemplateController.java | 10 +- .../TestCommonToscaServiceTemplateService.java | 2 + .../api/main/service/TestNodeTemplateService.java | 120 +++++++++++ .../TestToscaServiceTemplateForNodeTemplate.java | 160 +++++++++++++++ main/src/test/resources/application-test.yaml | 9 - .../dummy.apex.decisionmaker.policy.yaml | 14 ++ .../nodetemplates.metadatasets.update.json | 2 +- .../src/main/resources/etc/apiParameters.yaml | 9 - .../apisetup/config/api/etc/defaultConfig.json | 9 - 21 files changed, 660 insertions(+), 726 deletions(-) create mode 100644 main/src/main/java/org/onap/policy/api/main/repository/NodeTemplateRepository.java create mode 100644 main/src/main/java/org/onap/policy/api/main/repository/NodeTypeRepository.java delete mode 100644 main/src/main/java/org/onap/policy/api/main/rest/provider/CommonModelProvider.java delete mode 100644 main/src/main/java/org/onap/policy/api/main/rest/provider/NodeTemplateProvider.java delete mode 100644 main/src/main/java/org/onap/policy/api/main/rest/provider/PolicyProvider.java delete mode 100644 main/src/main/java/org/onap/policy/api/main/rest/provider/PolicyTypeProvider.java create mode 100644 main/src/main/java/org/onap/policy/api/main/service/NodeTemplateService.java create mode 100644 main/src/test/java/org/onap/policy/api/main/service/TestNodeTemplateService.java create mode 100644 main/src/test/java/org/onap/policy/api/main/service/TestToscaServiceTemplateForNodeTemplate.java create mode 100644 main/src/test/resources/nodetemplates/dummy.apex.decisionmaker.policy.yaml diff --git a/main/pom.xml b/main/pom.xml index 963f6d4c..ebd7cb59 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -38,7 +38,7 @@ org.onap.policy.models - policy-models-provider + policy-models-pdp ${policy.models.version} diff --git a/main/src/main/java/org/onap/policy/api/main/config/PolicyApiConfig.java b/main/src/main/java/org/onap/policy/api/main/config/PolicyApiConfig.java index e1cc58c6..48202a8a 100644 --- a/main/src/main/java/org/onap/policy/api/main/config/PolicyApiConfig.java +++ b/main/src/main/java/org/onap/policy/api/main/config/PolicyApiConfig.java @@ -1,6 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2022 Bell Canada. All rights reserved. + * Modifications 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. @@ -21,54 +22,12 @@ package org.onap.policy.api.main.config; import org.onap.policy.api.main.rest.StatisticsReport; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.provider.PolicyModelsProvider; -import org.onap.policy.models.provider.PolicyModelsProviderFactory; -import org.onap.policy.models.provider.PolicyModelsProviderParameters; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class PolicyApiConfig { - @Value("${policy-api.name}") - private String groupName; - @Value("${database.name}") - private String databaseName; - @Value("${database.implementation}") - private String databaseImplementation; - @Value("${database.driver}") - private String databaseDriver; - @Value("${database.url}") - private String databaseUrl; - @Value("${database.user}") - private String databaseUser; - @Value("${database.password}") - private String databasePassword; - @Value("${database.persistenceUnit}") - private String databasePersistenceUnit; - - /** - * Initialize database configuration. - * - * @return PolicyModelsProvider - * @throws PfModelException Policy exception - */ - @Bean(destroyMethod = "close") - public PolicyModelsProvider policyModelsProvider() throws PfModelException { - PolicyModelsProviderParameters modelsProviderParameters = new PolicyModelsProviderParameters(); - modelsProviderParameters.setName(databaseName); - modelsProviderParameters.setImplementation(databaseImplementation); - modelsProviderParameters.setDatabaseDriver(databaseDriver); - modelsProviderParameters.setDatabaseUrl(databaseUrl); - modelsProviderParameters.setDatabaseUser(databaseUser); - modelsProviderParameters.setDatabasePassword(databasePassword); - modelsProviderParameters.setPersistenceUnit(databasePersistenceUnit); - modelsProviderParameters.setDatabaseDriver(databaseDriver); - return new PolicyModelsProviderFactory().createPolicyModelsProvider(modelsProviderParameters); - } - /** * Initialize the statistics report bean. * diff --git a/main/src/main/java/org/onap/policy/api/main/repository/NodeTemplateRepository.java b/main/src/main/java/org/onap/policy/api/main/repository/NodeTemplateRepository.java new file mode 100644 index 00000000..9fdecbd5 --- /dev/null +++ b/main/src/main/java/org/onap/policy/api/main/repository/NodeTemplateRepository.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.api.main.repository; + +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplate; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface NodeTemplateRepository extends JpaRepository { +} diff --git a/main/src/main/java/org/onap/policy/api/main/repository/NodeTypeRepository.java b/main/src/main/java/org/onap/policy/api/main/repository/NodeTypeRepository.java new file mode 100644 index 00000000..144dff27 --- /dev/null +++ b/main/src/main/java/org/onap/policy/api/main/repository/NodeTypeRepository.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.api.main.repository; + +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeType; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface NodeTypeRepository extends JpaRepository { +} diff --git a/main/src/main/java/org/onap/policy/api/main/rest/NodeTemplateController.java b/main/src/main/java/org/onap/policy/api/main/rest/NodeTemplateController.java index 90e03dab..19b37980 100644 --- a/main/src/main/java/org/onap/policy/api/main/rest/NodeTemplateController.java +++ b/main/src/main/java/org/onap/policy/api/main/rest/NodeTemplateController.java @@ -38,8 +38,9 @@ import io.swagger.annotations.SwaggerDefinition; import java.net.HttpURLConnection; import java.util.List; import java.util.UUID; +import lombok.RequiredArgsConstructor; import org.onap.policy.api.main.exception.PolicyApiRuntimeException; -import org.onap.policy.api.main.rest.provider.NodeTemplateProvider; +import org.onap.policy.api.main.service.ToscaServiceTemplateService; import org.onap.policy.common.endpoints.event.comm.Topic; import org.onap.policy.common.endpoints.utils.NetLoggerUtil; import org.onap.policy.models.base.PfModelException; @@ -48,10 +49,8 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -79,12 +78,12 @@ import org.springframework.web.bind.annotation.RestController; @ExtensionProperty(name = "component", value = "Policy Framework")})}), schemes = {SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS}, securityDefinition = @SecurityDefinition(basicAuthDefinitions = {@BasicAuthDefinition(key = "basicAuth")})) +@RequiredArgsConstructor public class NodeTemplateController extends CommonRestController { private static final Logger LOGGER = LoggerFactory.getLogger(NodeTemplateController.class); - @Autowired - private NodeTemplateProvider provider; + private final ToscaServiceTemplateService toscaServiceTemplateService; /** * Creates one or more new tosca node templates in one call. @@ -130,7 +129,7 @@ public class NodeTemplateController extends CommonRestController { toJson(body)); } try { - ToscaServiceTemplate nodeTemplates = provider.createNodeTemplates(body); + ToscaServiceTemplate nodeTemplates = toscaServiceTemplateService.createToscaNodeTemplates(body); return makeOkResponse(requestId, nodeTemplates); } catch (PfModelException | PfModelRuntimeException pfme) { final var msg = "POST /nodetemplates"; @@ -183,7 +182,7 @@ public class NodeTemplateController extends CommonRestController { toJson(body)); } try { - ToscaServiceTemplate nodeTemplates = provider.updateToscaNodeTemplates(body); + ToscaServiceTemplate nodeTemplates = toscaServiceTemplateService.updateToscaNodeTemplates(body); return makeOkResponse(requestId, nodeTemplates); } catch (PfModelException | PfModelRuntimeException pfme) { final var msg = "PUT /nodetemplates"; @@ -233,7 +232,7 @@ public class NodeTemplateController extends CommonRestController { @RequestHeader(name = REQUEST_ID_NAME, required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId) { try { - ToscaServiceTemplate nodeTemplates = provider.deleteToscaNodeTemplate(name, version); + ToscaServiceTemplate nodeTemplates = toscaServiceTemplateService.deleteToscaNodeTemplate(name, version); return makeOkResponse(requestId, nodeTemplates); } catch (PfModelException | PfModelRuntimeException pfme) { final var msg = String.format("DELETE /nodetemplates/%s/versions/%s", name, version); @@ -287,7 +286,7 @@ public class NodeTemplateController extends CommonRestController { @RequestHeader(name = REQUEST_ID_NAME, required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId) { try { - List nodeTemplates = provider.fetchToscaNodeTemplates(name, version); + List nodeTemplates = toscaServiceTemplateService.fetchToscaNodeTemplates(name, version); return makeOkResponse(requestId, nodeTemplates); } catch (PfModelException | PfModelRuntimeException pfme) { var msg = String.format("GET /nodetemplates/%s/versions/%s", name, version); @@ -335,7 +334,7 @@ public class NodeTemplateController extends CommonRestController { @RequestHeader(name = REQUEST_ID_NAME, required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId) { try { - List nodeTemplates = provider.fetchToscaNodeTemplates(null, null); + List nodeTemplates = toscaServiceTemplateService.fetchToscaNodeTemplates(null, null); return makeOkResponse(requestId, nodeTemplates); } catch (PfModelException | PfModelRuntimeException pfme) { var msg = "GET /nodetemplates"; diff --git a/main/src/main/java/org/onap/policy/api/main/rest/provider/CommonModelProvider.java b/main/src/main/java/org/onap/policy/api/main/rest/provider/CommonModelProvider.java deleted file mode 100644 index 287c0b2b..00000000 --- a/main/src/main/java/org/onap/policy/api/main/rest/provider/CommonModelProvider.java +++ /dev/null @@ -1,228 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP Policy API - * ================================================================================ - * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2019-2021 Nordix Foundation. - * Modifications Copyright (C) 2022 Bell Canada. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.api.main.rest.provider; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.BiConsumer; -import javax.ws.rs.core.Response; -import org.apache.commons.lang3.tuple.Pair; -import org.onap.policy.models.base.PfConceptKey; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.pdp.concepts.PdpGroup; -import org.onap.policy.models.pdp.concepts.PdpGroupFilter; -import org.onap.policy.models.pdp.concepts.PdpSubGroup; -import org.onap.policy.models.pdp.enums.PdpState; -import org.onap.policy.models.provider.PolicyModelsProvider; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; - -/** - * Super class for providers that use a model provider. - */ -public class CommonModelProvider { - - protected final PolicyModelsProvider modelsProvider; - - /** - * Constructs the object, populating {@link #modelsProvider}. - * - */ - public CommonModelProvider(PolicyModelsProvider modelsProvider) { - this.modelsProvider = modelsProvider; - } - - /** - * Collects all deployed versions of specified policy in all pdp groups. - * - * @param policyId the ID of policy - * @param policyType the concept key of policy type - * @param getter the custom generic getter Bifunction - * @param consumer the BiConsumer - * @param data the data structure storing retrieved deployed policies - * - * @return a map between pdp group and deployed versions of specified policy in that group - * - * @throws PfModelException the PfModel parsing exception - */ - protected Map, T> collectDeployedPolicies(String policyId, PfConceptKey policyType, - BiFunctionWithEx getter, BiConsumer consumer, T data) throws PfModelException { - - List pdpGroups = getPolicyTypeFilteredPdpGroups(policyType); - hasActivePdpGroup(pdpGroups, policyType, policyId); - return constructDeployedPolicyMap(pdpGroups, policyId, policyType, getter, consumer, data); - } - - @FunctionalInterface - protected interface BiFunctionWithEx { - public R apply(T value1, U value2) throws PfModelException; - } - - /** - * Checks if the list of pdp groups is empty. If so, throws exception saying specified policy deployment is not - * found in all existing pdp groups. - * - * @param pdpGroups the list of pdp groups to check against - * @param policyType the concept key of policy type - * @param policyId the ID of policy - * - * @throws PfModelException the PfModel parsing exception - */ - private void hasActivePdpGroup(List pdpGroups, PfConceptKey policyType, String policyId) - throws PfModelException { - - if (pdpGroups.isEmpty()) { - throw new PfModelException(Response.Status.NOT_FOUND, - constructDeploymentNotFoundMessage(policyType, policyId)); - } - } - - /** - * Retrieves all pdp groups supporting specified policy type. - * - * @param policyType the policy type - * - * @return a list of pdp groups supporting specified policy type - * - * @throws PfModelException the PfModel parsing exception - */ - private List getPolicyTypeFilteredPdpGroups(PfConceptKey policyType) throws PfModelException { - - List policyTypes = new ArrayList<>(); - policyTypes.add(new ToscaConceptIdentifier(policyType.getName(), policyType.getVersion())); - var pdpGroupFilter = PdpGroupFilter.builder().policyTypeList(policyTypes).groupState(PdpState.ACTIVE) - .pdpState(PdpState.ACTIVE).build(); - return modelsProvider.getFilteredPdpGroups(pdpGroupFilter); - } - - /** - * Constructs the map of deployed pdp groups and deployed policies. - * - * @param pdpGroups the list of pdp groups that contain the specified policy - * @param policyId the ID of policy - * @param policyType the concept key of policy type - * @param getter the custom generic getter BiFunction - * @param consumer the BiConsumer - * @param data the data structure storing retrieved deployed policies - * - * @return the constructed map of pdp groups and deployed policies - * - * @throws PfModelException the PfModel parsing exception - */ - private Map, T> constructDeployedPolicyMap(List pdpGroups, String policyId, - PfConceptKey policyType, BiFunctionWithEx getter, BiConsumer consumer, T data) - throws PfModelException { - - Map, T> deployedPolicyMap = new HashMap<>(); - for (PdpGroup pdpGroup : pdpGroups) { - List policyIdentifiers = extractPolicyIdentifiers(policyId, pdpGroup, policyType); - var deployedPolicies = getDeployedPolicies(policyIdentifiers, policyType, getter, consumer, data); - deployedPolicyMap.put(Pair.of(pdpGroup.getName(), pdpGroup.getVersion()), deployedPolicies); - } - return deployedPolicyMap; - } - - /** - * Extracts policy identifiers matching specified policy ID from specified pdp group. - * - * @param policyId the ID of policy to match - * @param pdpGroup the target pdp group to search - * @param policyType the concept key of policy type - * - * @return the list of policy identifiers - * - * @throws PfModelException the PfModel parsing exception - */ - private List extractPolicyIdentifiers(String policyId, PdpGroup pdpGroup, - PfConceptKey policyType) throws PfModelException { - - List policyIdentifiers = new ArrayList<>(); - for (PdpSubGroup pdpSubGroup : pdpGroup.getPdpSubgroups()) { - for (ToscaConceptIdentifier policyIdentifier : pdpSubGroup.getPolicies()) { - if (policyId.equalsIgnoreCase(policyIdentifier.getName())) { - policyIdentifiers.add(policyIdentifier); - } - } - } - if (policyIdentifiers.isEmpty()) { - throw new PfModelException(Response.Status.NOT_FOUND, - constructDeploymentNotFoundMessage(policyType, policyId)); - } - return policyIdentifiers; - } - - /** - * Retrieves deployed policies in a generic way. - * - * @param policyIdentifiers the identifiers of the policies to return - * @param policyType the concept key of current policy type - * @param getter the method reference of getting deployed policies - * @param consumer the method reference of consuming the returned policies - * @param data the data structure of deployed policies to return - * - * @return the generic type of policy data structure to return - * - * @throws PfModelException the PfModel parsing exception - */ - private T getDeployedPolicies(List policyIdentifiers, PfConceptKey policyType, - BiFunctionWithEx getter, BiConsumer consumer, T data) throws PfModelException { - - for (ToscaConceptIdentifier policyIdentifier : policyIdentifiers) { - var result = getter.apply(policyIdentifier.getName(), - getTrimedVersionForLegacyType(policyIdentifier.getVersion(), policyType)); - consumer.accept(data, result); - } - return data; - } - - /** - * Trims the version for legacy policies. - * - * @param fullVersion the full version format with major, minor, patch - * @param policyType the concept key of policy type - * - * @return the trimmed version - */ - private String getTrimedVersionForLegacyType(String fullVersion, PfConceptKey policyType) { - return (policyType.getName().contains("guard") || policyType.getName().contains("Operational")) - ? fullVersion.split("\\.")[0] - : fullVersion; - } - - /** - * Constructs returned message for not found policy deployment. - * - * @param policyType the concept key of policy type - * @param policyId the ID of policy - * - * @return constructed message - */ - private String constructDeploymentNotFoundMessage(PfConceptKey policyType, String policyId) { - - return "could not find policy with ID " + policyId + " and type " + policyType.getName() + ":" - + policyType.getVersion() + " deployed in any pdp group"; - } -} \ No newline at end of file diff --git a/main/src/main/java/org/onap/policy/api/main/rest/provider/NodeTemplateProvider.java b/main/src/main/java/org/onap/policy/api/main/rest/provider/NodeTemplateProvider.java deleted file mode 100644 index 2ff50248..00000000 --- a/main/src/main/java/org/onap/policy/api/main/rest/provider/NodeTemplateProvider.java +++ /dev/null @@ -1,110 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP Policy API - * ================================================================================ - * Copyright (C) 2022 Nordix Foundation. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.api.main.rest.provider; - -import java.util.List; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.provider.PolicyModelsProvider; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; -import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -public class NodeTemplateProvider extends CommonModelProvider { - - /** - * Default constructor. - */ - @Autowired - public NodeTemplateProvider(PolicyModelsProvider modelsProvider) throws PfModelException { - super(modelsProvider); - } - - - /** - * Retrieves a node template matching specified ID and version. - * - * @param name the name of the node template, null to return all entries - * @param version the version of node template, null to return all entries - * - * @return the List of node templates - * - * @throws PfModelException the PfModel parsing exception - */ - public List fetchToscaNodeTemplates(final String name, final String version) - throws PfModelException { - - return modelsProvider.getToscaNodeTemplate(name, version); - } - - - /** - * Creates one or more new node templates. - * - * @param serviceTemplate service template containing node template definitions - * - * @return the ToscaServiceTemplate object - * - * @throws PfModelException the PfModel parsing exception - */ - public ToscaServiceTemplate createNodeTemplates(ToscaServiceTemplate serviceTemplate) - throws PfModelException { - - return modelsProvider.createToscaNodeTemplates(serviceTemplate); - } - - - /** - * Update one or more node templates. - * - * @param serviceTemplate service template with updated node templates - * @return the ToscaServiceTemplate object - * - * @throws PfModelException the PfModel parsing exception - */ - public ToscaServiceTemplate updateToscaNodeTemplates(ToscaServiceTemplate serviceTemplate) - throws PfModelException { - - return modelsProvider.updateToscaNodeTemplates(serviceTemplate); - } - - - /** - * Deletes the node template matching specified ID and version. - * - * @param name the name of the node template - * @param version the version of the node template - * - * @return the ToscaServiceTemplate object - * - * @throws PfModelException the PfModel parsing exception - */ - public ToscaServiceTemplate deleteToscaNodeTemplate(String name, String version) - throws PfModelException { - - return modelsProvider.deleteToscaNodeTemplate(name, version); - } - - -} diff --git a/main/src/main/java/org/onap/policy/api/main/rest/provider/PolicyProvider.java b/main/src/main/java/org/onap/policy/api/main/rest/provider/PolicyProvider.java deleted file mode 100644 index 1e5ed477..00000000 --- a/main/src/main/java/org/onap/policy/api/main/rest/provider/PolicyProvider.java +++ /dev/null @@ -1,165 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP Policy API - * ================================================================================ - * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2020-2021 Nordix Foundation. - * Modifications Copyright (C) 2022 Bell Canada. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.api.main.rest.provider; - -import org.onap.policy.api.main.rest.PolicyFetchMode; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.provider.PolicyModelsProvider; -import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; -import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; -import org.onap.policy.models.tosca.authorative.concepts.ToscaTypedEntityFilter; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -/** - * Class to provide all kinds of policy operations. - * - * @author Chenfei Gao (cgao@research.att.com) - */ -@Service -public class PolicyProvider extends CommonModelProvider { - - /** - * Default constructor. - */ - @Autowired - public PolicyProvider(PolicyModelsProvider modelsProvider) throws PfModelException { - super(modelsProvider); - } - - /** - * Retrieves a list of policies matching specified ID and version of both policy type and policy. - * - * @param policyTypeId the ID of policy type - * @param policyTypeVersion the version of policy type - * @param policyId the ID of policy - * @param policyVersion the version of policy - * @param mode the fetch mode for policies - * - * @return the ToscaServiceTemplate object - * - * @throws PfModelException the PfModel parsing exception - */ - public ToscaServiceTemplate fetchPolicies(final String policyTypeId, final String policyTypeVersion, - final String policyId, final String policyVersion, final PolicyFetchMode mode) throws PfModelException { - - return getFilteredPolicies(policyTypeId, policyTypeVersion, policyId, policyVersion, mode); - } - - /** - * Retrieves a list of policies with the latest versions that match specified policy type id and version. - * - * @param policyTypeId the ID of policy type - * @param policyTypeVersion the version of policy type - * @param policyId the ID of the policy - * @param mode the fetch mode for policies - * @return the ToscaServiceTemplate object - * - * @throws PfModelException the PfModel parsing exception - */ - public ToscaServiceTemplate fetchLatestPolicies(final String policyTypeId, final String policyTypeVersion, - final String policyId, final PolicyFetchMode mode) throws PfModelException { - - return getFilteredPolicies(policyTypeId, policyTypeVersion, policyId, ToscaTypedEntityFilter.LATEST_VERSION, - mode); - } - - /** - * Creates one or more new policies for the same policy type ID and version. - * - * @param policyTypeId the ID of policy type - * @param policyTypeVersion the version of policy type - * @param body the entity body of polic(ies) - * - * @return the ToscaServiceTemplate object - * - * @throws PfModelException the PfModel parsing exception - */ - public ToscaServiceTemplate createPolicy(String policyTypeId, String policyTypeVersion, ToscaServiceTemplate body) - throws PfModelException { - - return modelsProvider.createPolicies(body); - } - - /** - * Creates one or more new policies. - * - * @param body the entity body of policy - * - * @return the ToscaServiceTemplate object - * - * @throws PfModelException the PfModel parsing exception - */ - public ToscaServiceTemplate createPolicies(ToscaServiceTemplate body) throws PfModelException { - return modelsProvider.createPolicies(body); - } - - /** - * Deletes the policy matching specified ID and version of both policy type and policy. - * - * @param policyTypeId the ID of policy type - * @param policyTypeVersion the version of policy type - * @param policyId the ID of policy - * @param policyVersion the version of policy - * - * @return the ToscaServiceTemplate object - * - * @throws PfModelException the PfModel parsing exception - */ - public ToscaServiceTemplate deletePolicy(String policyTypeId, String policyTypeVersion, String policyId, - String policyVersion) throws PfModelException { - - return modelsProvider.deletePolicy(policyId, policyVersion); - } - - /** - * Retrieves the specified version of the policy. - * - * @param policyTypeName the name of the policy type - * @param policyTypeVersion the version of the policy type - * @param policyName the name of the policy - * @param policyVersion the version of the policy - * @param mode the fetch mode for policies - * - * @return the TOSCA service template containing the specified version of the policy - * - * @throws PfModelException the PfModel parsing exception - */ - private ToscaServiceTemplate getFilteredPolicies(final String policyTypeName, final String policyTypeVersion, - final String policyName, final String policyVersion, final PolicyFetchMode mode) throws PfModelException { - - ToscaTypedEntityFilter policyFilter = ToscaTypedEntityFilter.builder() - .name(policyName).version(policyVersion).type(policyTypeName).typeVersion(policyTypeVersion).build(); - - ToscaServiceTemplate serviceTemplate = modelsProvider.getFilteredPolicies(policyFilter); - - if (mode == null || PolicyFetchMode.BARE.equals(mode)) { - serviceTemplate.setPolicyTypes(null); - serviceTemplate.setDataTypes(null); - } - - return serviceTemplate; - } -} \ No newline at end of file diff --git a/main/src/main/java/org/onap/policy/api/main/rest/provider/PolicyTypeProvider.java b/main/src/main/java/org/onap/policy/api/main/rest/provider/PolicyTypeProvider.java deleted file mode 100644 index 4db16985..00000000 --- a/main/src/main/java/org/onap/policy/api/main/rest/provider/PolicyTypeProvider.java +++ /dev/null @@ -1,127 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP Policy API - * ================================================================================ - * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2020-2021 Nordix Foundation. - * Modifications Copyright (C) 2022 Bell Canada. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.api.main.rest.provider; - -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.provider.PolicyModelsProvider; -import org.onap.policy.models.tosca.authorative.concepts.ToscaEntityFilter; -import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType; -import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -/** - * Class to provide all kinds of policy type operations. - * - * @author Chenfei Gao (cgao@research.att.com) - */ -@Service -public class PolicyTypeProvider extends CommonModelProvider { - - /** - * Default constructor. - */ - @Autowired - public PolicyTypeProvider(PolicyModelsProvider modelsProvider) throws PfModelException { - super(modelsProvider); - } - - /** - * Retrieves a list of policy types matching specified policy type ID and version. - * - * @param policyTypeId the ID of policy type - * @param policyTypeVersion the version of policy type - * - * @return the ToscaServiceTemplate object - * - * @throws PfModelException the PfModel parsing exception - */ - public ToscaServiceTemplate fetchPolicyTypes(String policyTypeId, String policyTypeVersion) - throws PfModelException { - - return getFilteredPolicyTypes(policyTypeId, policyTypeVersion); - } - - /** - * Retrieves a list of policy types with the latest versions. - * - * @param policyTypeId the ID of policy type - * - * @return the ToscaServiceTemplate object - * - * @throws PfModelException the PfModel parsing exception - */ - public ToscaServiceTemplate fetchLatestPolicyTypes(String policyTypeId) throws PfModelException { - - return getFilteredPolicyTypes(policyTypeId, ToscaEntityFilter.LATEST_VERSION); - } - - /** - * Creates a new policy type. - * - * @param body the entity body of policy type - * - * @return the ToscaServiceTemplate object - * @throws PfModelException the PfModel parsing exception - */ - public ToscaServiceTemplate createPolicyType(ToscaServiceTemplate body) throws PfModelException { - - return modelsProvider.createPolicyTypes(body); - } - - /** - * Delete the policy type matching specified policy type ID and version. - * - * @param policyTypeId the ID of policy type - * @param policyTypeVersion the version of policy type - * - * @return the ToscaServiceTemplate object - * - * @throws PfModelException the PfModel parsing exception - */ - public ToscaServiceTemplate deletePolicyType(String policyTypeId, String policyTypeVersion) - throws PfModelException { - - return modelsProvider.deletePolicyType(policyTypeId, policyTypeVersion); - } - - /** - * Retrieves the specified version of the policy type. - * - * @param policyTypeName the name of the policy type - * @param policyTypeVersion the version of the policy type - * - * @return the TOSCA service template containing the specified version of the policy type - * - * @throws PfModelException the PfModel parsing exception - */ - private ToscaServiceTemplate getFilteredPolicyTypes(String policyTypeName, String policyTypeVersion) - throws PfModelException { - - ToscaEntityFilter policyTypeFilter = - ToscaEntityFilter.builder().name(policyTypeName).version(policyTypeVersion).build(); - return modelsProvider.getFilteredPolicyTypes(policyTypeFilter); - } -} \ No newline at end of file diff --git a/main/src/main/java/org/onap/policy/api/main/service/NodeTemplateService.java b/main/src/main/java/org/onap/policy/api/main/service/NodeTemplateService.java new file mode 100644 index 00000000..b4eec379 --- /dev/null +++ b/main/src/main/java/org/onap/policy/api/main/service/NodeTemplateService.java @@ -0,0 +1,144 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.api.main.service; + +import java.util.Optional; +import javax.ws.rs.core.Response; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import org.onap.policy.api.main.repository.NodeTemplateRepository; +import org.onap.policy.api.main.repository.NodeTypeRepository; +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.base.PfModelRuntimeException; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplate; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplates; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeType; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicy; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate; +import org.onap.policy.models.tosca.utils.ToscaUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +public class NodeTemplateService { + + private static final Logger LOGGER = LoggerFactory.getLogger(NodeTemplateService.class); + + private final NodeTemplateRepository nodeTemplateRepository; + private final NodeTypeRepository nodeTypeRepository; + + /** + * Delete the specified node template. + * + * @param nodeTemplateKey the node template key containing name and version + */ + public void deleteNodeTemplate(final PfConceptKey nodeTemplateKey) { + nodeTemplateRepository.deleteById(nodeTemplateKey); + } + + + /** + * Update the specified tosca node template. + * @param incomingServiceTemplate incoming service template + */ + public void updateToscaNodeTemplates(@NonNull final JpaToscaServiceTemplate incomingServiceTemplate) + throws PfModelRuntimeException, PfModelException { + for (JpaToscaNodeTemplate nodeTemplate : incomingServiceTemplate.getTopologyTemplate().getNodeTemplates() + .getAll(null)) { + //verify if the node template is referenced in the metadata of created policies + assertNodeTemplateNotUsedInPolicy(nodeTemplate.getName(), nodeTemplate.getVersion(), + incomingServiceTemplate); + verifyNodeTypeInDbTemplate(nodeTemplate); + Optional dbNodeTemplate = nodeTemplateRepository.findById(nodeTemplate.getKey()); + if (dbNodeTemplate.isPresent()) { + nodeTemplateRepository.save(nodeTemplate); + } else { + throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE, "node template " + + nodeTemplate.getName() + " version " + nodeTemplate.getVersion() + " does not exist in database"); + } + } + + // Return the service template with updated node templates + var updatedNodeTemplates = new JpaToscaNodeTemplates(); + updatedNodeTemplates.setKey(incomingServiceTemplate.getTopologyTemplate().getNodeTemplates().getKey()); + + for (PfConceptKey key : incomingServiceTemplate.getTopologyTemplate().getNodeTemplates() + .getConceptMap().keySet()) { + Optional jpaNodeTemplate = nodeTemplateRepository.findById(key); + jpaNodeTemplate.ifPresent( + jpaToscaNodeTemplate -> updatedNodeTemplates.getConceptMap().put(key, jpaToscaNodeTemplate)); + } + incomingServiceTemplate.getTopologyTemplate().setNodeTemplates(updatedNodeTemplates); + + } + + + /** + * Verify the node type for a toscaNodeTemplate . + * + * @param toscaNodeTemplate the toscaNodeTemplate to check the toscaNodeTemplate type for + */ + public void verifyNodeTypeInDbTemplate(final JpaToscaNodeTemplate toscaNodeTemplate) throws + PfModelException { + PfConceptKey nodeTypeKey = toscaNodeTemplate.getType(); + + Optional nodeType = nodeTypeRepository.findById(nodeTypeKey); + + if (nodeType.isEmpty()) { + String errorMessage = + "NODE_TYPE " + nodeTypeKey + " for toscaNodeTemplate " + toscaNodeTemplate.getId() + + " does not exist"; + throw new PfModelException(Response.Status.NOT_ACCEPTABLE, errorMessage); + } + } + + /** + * Assert that the node template is not referenced in any Tosca policy. + * + * @param name the name of node template + * @param version the version of node template + * @throws PfModelException if node template referenced in a policy + */ + public void assertNodeTemplateNotUsedInPolicy(String name, String version, JpaToscaServiceTemplate dbTemplate) + throws PfModelException { + try { + //Retrieve all the policies from db, return if policies doesn't exist + ToscaUtils.assertPoliciesExist(dbTemplate); + } catch (PfModelRuntimeException e) { + LOGGER.debug("Could not verify the node template reference in created policies ", e); + return; + } + for (JpaToscaPolicy policy : dbTemplate.getTopologyTemplate().getPolicies().getConceptMap().values()) { + if (policy.getMetadata().getOrDefault("metadataSetName", "").equals(name) + && policy.getMetadata().getOrDefault("metadataSetVersion", "").equals(version)) { + throw new PfModelException(Response.Status.NOT_ACCEPTABLE, + "Node template is in use, it is referenced in Tosca Policy " + policy.getName() + " version " + + policy.getVersion()); + } + } + + } +} diff --git a/main/src/main/java/org/onap/policy/api/main/service/ToscaServiceTemplateService.java b/main/src/main/java/org/onap/policy/api/main/service/ToscaServiceTemplateService.java index 0fa02258..d578d0dc 100644 --- a/main/src/main/java/org/onap/policy/api/main/service/ToscaServiceTemplateService.java +++ b/main/src/main/java/org/onap/policy/api/main/service/ToscaServiceTemplateService.java @@ -1,6 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2022 Bell Canada. All rights reserved. + * Modifications 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. @@ -20,8 +21,10 @@ package org.onap.policy.api.main.service; +import java.util.ArrayList; import java.util.List; import java.util.Optional; +import javax.annotation.Nonnull; import javax.ws.rs.core.Response; import lombok.NonNull; import lombok.RequiredArgsConstructor; @@ -33,10 +36,14 @@ import org.onap.policy.models.base.PfConceptKey; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.tosca.authorative.concepts.ToscaEntityFilter; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaTypedEntityFilter; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplate; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplates; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTypes; import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicies; import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyTypes; import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate; @@ -63,6 +70,7 @@ public class ToscaServiceTemplateService { public static final String DO_NOT_EXIST_MSG = " do not exist"; private final ToscaServiceTemplateRepository toscaServiceTemplateRepository; + private final NodeTemplateService nodeTemplateService; private final PdpGroupService pdpGroupService; private final PolicyTypeService policyTypeService; private final PolicyService policyService; @@ -428,6 +436,142 @@ public class ToscaServiceTemplateService { return returnServiceTemplate.toAuthorative(); } + /** + * Write a node template to the database. + * + * @param serviceTemplate the service template to be written + * @return the service template created by this method + * @throws PfModelException on errors writing the metadataSets + */ + public ToscaServiceTemplate createToscaNodeTemplates(@NonNull final ToscaServiceTemplate serviceTemplate) + throws PfModelException { + + LOGGER.debug("->write: tosca nodeTemplates={}", serviceTemplate); + final var incomingServiceTemplate = new JpaToscaServiceTemplate(serviceTemplate); + + ToscaUtils.assertNodeTemplatesExist(incomingServiceTemplate); + + Optional nodeTypes = Optional.ofNullable(incomingServiceTemplate.getNodeTypes()); + for (JpaToscaNodeTemplate nodeTemplate : incomingServiceTemplate.getTopologyTemplate().getNodeTemplates() + .getAll(null)) { + // verify node types in the db if mismatch/empty entities in the template + if (! (nodeTypes.isPresent() && nodeTypes.get().getKeys().contains(nodeTemplate.getType()))) { + nodeTemplateService.verifyNodeTypeInDbTemplate(nodeTemplate); + } + } + // append the incoming fragment to the DB TOSCA service template + final var serviceTemplateToWrite = + ToscaServiceTemplateUtils.addFragment(getDefaultJpaToscaServiceTemplate(), incomingServiceTemplate); + + final var result = serviceTemplateToWrite.validate("service template."); + if (!result.isValid()) { + throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE, result.getResult()); + } + toscaServiceTemplateRepository.save(serviceTemplateToWrite); + LOGGER.debug("<-createdToscaNodeTemplates: writtenServiceTemplate={}", serviceTemplateToWrite); + + return serviceTemplate; + } + + /** + * Update tosca node template. + * + * @param serviceTemplate the service template containing the definitions of the node templates to be updated. + * @return the TOSCA service template containing the node templates that were updated + * @throws PfModelRuntimeException on errors updating node templates + */ + public ToscaServiceTemplate updateToscaNodeTemplates(@NonNull final ToscaServiceTemplate serviceTemplate) + throws PfModelException { + LOGGER.debug("->updateToscaNodeTemplates: serviceTemplate={}", serviceTemplate); + final var incomingServiceTemplate = new JpaToscaServiceTemplate(serviceTemplate); + + ToscaUtils.assertNodeTemplatesExist(incomingServiceTemplate); + nodeTemplateService.updateToscaNodeTemplates(incomingServiceTemplate); + + LOGGER.debug("<-updatedToscaNodeTemplates: serviceTemplate={}", serviceTemplate); + return incomingServiceTemplate.toAuthorative(); + } + + + /** + * Delete a tosca node template. + * + * @param name the name of node template + * @param version the version of node template + * @return the TOSCA service template containing the node template that were deleted + * @throws PfModelException on errors deleting node templates + */ + public ToscaServiceTemplate deleteToscaNodeTemplate(@NonNull final String name, @Nonnull final String version) + throws PfModelException { + LOGGER.debug("->deleteToscaNodeTemplate: name={}, version={}", name, version); + + JpaToscaServiceTemplate dbServiceTemplate = getDefaultJpaToscaServiceTemplate(); + final var nodeTemplateKey = new PfConceptKey(name, version); + + if (!ToscaUtils.doNodeTemplatesExist(dbServiceTemplate)) { + throw new PfModelRuntimeException(Response.Status.NOT_FOUND, "no node templates found"); + } + JpaToscaNodeTemplate nodeTemplate4Deletion = dbServiceTemplate.getTopologyTemplate().getNodeTemplates() + .get(new PfConceptKey(name, version)); + if (nodeTemplate4Deletion == null) { + throw new PfModelRuntimeException(Response.Status.NOT_FOUND, "node template " + name + ":" + version + + NOT_FOUND); + } + //Verify if the node template is referenced in the metadata of created policies + nodeTemplateService.assertNodeTemplateNotUsedInPolicy(name, version, dbServiceTemplate); + + dbServiceTemplate.getTopologyTemplate().getNodeTemplates().getConceptMap().remove(nodeTemplateKey); + toscaServiceTemplateRepository.save(dbServiceTemplate); + + // remove the entry from the tosca node template table + nodeTemplateService.deleteNodeTemplate(nodeTemplateKey); + + // prepare the return service template + var deletedServiceTemplate = new JpaToscaServiceTemplate(); + deletedServiceTemplate.setTopologyTemplate(new JpaToscaTopologyTemplate()); + deletedServiceTemplate.getTopologyTemplate().setNodeTemplates(new JpaToscaNodeTemplates()); + deletedServiceTemplate.getTopologyTemplate().getNodeTemplates().getConceptMap() + .put(nodeTemplateKey, nodeTemplate4Deletion); + + LOGGER.debug("<-deleteToscaNodeTemplate: key={}, serviceTemplate={}", nodeTemplateKey, deletedServiceTemplate); + return deletedServiceTemplate.toAuthorative(); + } + + + /** + * Get tosca node templates. + * + * @param name the name of the node template to get, set to null to get all node templates + * @param version the version of the node template to get, set to null to get all versions + * @return the node templates with the specified key + * @throws PfModelException on errors getting node templates + */ + public List fetchToscaNodeTemplates(final String name, final String version) + throws PfModelException { + LOGGER.debug("->getNodeTemplate: name={}, version={}", name, version); + List nodeTemplates = new ArrayList<>(); + var jpaNodeTemplates = new JpaToscaNodeTemplates(); + + var dbServiceTemplate = getDefaultJpaToscaServiceTemplate(); + //Return empty if no nodeTemplates present in db + if (!ToscaUtils.doNodeTemplatesExist(dbServiceTemplate)) { + return nodeTemplates; + } + jpaNodeTemplates = dbServiceTemplate.getTopologyTemplate().getNodeTemplates(); + + //Filter specific nodeTemplates + if (name != null && version != null) { + var filterKey = new PfConceptKey(name, version); + jpaNodeTemplates.getConceptMap().entrySet().removeIf(entity -> !entity.getKey().equals(filterKey)); + } + jpaNodeTemplates.getConceptMap().forEach((key, value) -> nodeTemplates.add(value.toAuthorative())); + LOGGER.debug("<-getNodeTemplateMetadataSet: name={}, version={}, nodeTemplates={}", name, version, + nodeTemplates); + + return nodeTemplates; + } + + /** * Get Service Template. * diff --git a/main/src/main/resources/application.yaml b/main/src/main/resources/application.yaml index f46810e4..35ca4ed0 100644 --- a/main/src/main/resources/application.yaml +++ b/main/src/main/resources/application.yaml @@ -25,15 +25,6 @@ policy-api: name: ApiGroup aaf: false -database: - name: PolicyProviderParameterGroup - implementation: org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl - driver: org.mariadb.jdbc.Driver - url: jdbc:mariadb://mariadb:3306/policyadmin - user: policy_user - password: policy_user - persistenceUnit: PolicyDb - policy-preload: policyTypes: - policytypes/onap.policies.monitoring.tcagen2.yaml diff --git a/main/src/test/java/org/onap/policy/api/main/rest/TestNodeTemplateController.java b/main/src/test/java/org/onap/policy/api/main/rest/TestNodeTemplateController.java index 5244f3c9..993fbee1 100644 --- a/main/src/test/java/org/onap/policy/api/main/rest/TestNodeTemplateController.java +++ b/main/src/test/java/org/onap/policy/api/main/rest/TestNodeTemplateController.java @@ -36,11 +36,9 @@ import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.onap.policy.api.main.PolicyApiApplication; -import org.onap.policy.api.main.rest.provider.NodeTemplateProvider; import org.onap.policy.api.main.rest.utils.CommonTestRestController; +import org.onap.policy.api.main.service.ToscaServiceTemplateService; import org.onap.policy.common.utils.security.SelfSignedKeyStore; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.errors.concepts.ErrorResponse; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; @@ -86,7 +84,7 @@ public class TestNodeTemplateController extends CommonTestRestController { private int apiPort; @Autowired - private NodeTemplateProvider provider; + private ToscaServiceTemplateService toscaServiceTemplateService; /** * Initializes parameters and set up test environment. @@ -107,8 +105,8 @@ public class TestNodeTemplateController extends CommonTestRestController { public void clearDb() { for (String name : nodeTemplateKeys) { try { - provider.deleteToscaNodeTemplate(name, "1.0.0"); - } catch (PfModelException | PfModelRuntimeException e) { + toscaServiceTemplateService.deleteToscaNodeTemplate(name, "1.0.0"); + } catch (Exception e) { //do nothing } } diff --git a/main/src/test/java/org/onap/policy/api/main/service/TestCommonToscaServiceTemplateService.java b/main/src/test/java/org/onap/policy/api/main/service/TestCommonToscaServiceTemplateService.java index 8d80cac8..4af30937 100644 --- a/main/src/test/java/org/onap/policy/api/main/service/TestCommonToscaServiceTemplateService.java +++ b/main/src/test/java/org/onap/policy/api/main/service/TestCommonToscaServiceTemplateService.java @@ -47,6 +47,8 @@ public class TestCommonToscaServiceTemplateService { protected PolicyTypeService policyTypeService; @Mock protected PolicyService policyService; + @Mock + protected NodeTemplateService nodeTemplateService; /** * Setup the DB TOSCA service template object post create, and delete request. diff --git a/main/src/test/java/org/onap/policy/api/main/service/TestNodeTemplateService.java b/main/src/test/java/org/onap/policy/api/main/service/TestNodeTemplateService.java new file mode 100644 index 00000000..7d85eef2 --- /dev/null +++ b/main/src/test/java/org/onap/policy/api/main/service/TestNodeTemplateService.java @@ -0,0 +1,120 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP Policy API + * ================================================================================ + * Copyright (C) 2022 Nordix Foundation. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.api.main.service; + + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +import java.util.Optional; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.policy.api.main.repository.NodeTemplateRepository; +import org.onap.policy.api.main.repository.NodeTypeRepository; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.coder.YamlJsonTranslator; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplate; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeType; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate; + +@RunWith(MockitoJUnitRunner.class) +public class TestNodeTemplateService { + + @Mock + private NodeTemplateRepository nodeTemplateRepository; + + @Mock + private NodeTypeRepository nodeTypeRepository; + + @InjectMocks + private NodeTemplateService nodeTemplateService; + + private static final String POLICY_WITH_METADATA_SET_REF = "nodetemplates/dummy.apex.decisionmaker.policy.yaml"; + private static final String UPDATED_NODE_TEMPLATE_JSON = "nodetemplates/nodetemplates.metadatasets.update.json"; + + private static ToscaServiceTemplate updatedToscaServiceTemplate; + private StandardCoder standardCoder; + private YamlJsonTranslator yamlJsonTranslator = new YamlJsonTranslator(); + ToscaServiceTemplate policyServiceTemplate; + + /** + * Set up for tests. + * @throws CoderException if error in json parsing + */ + @Before + public void setUp() throws CoderException { + standardCoder = new StandardCoder(); + policyServiceTemplate = + yamlJsonTranslator.fromYaml(ResourceUtils.getResourceAsString(POLICY_WITH_METADATA_SET_REF), + ToscaServiceTemplate.class); + updatedToscaServiceTemplate = + standardCoder.decode(ResourceUtils.getResourceAsString(UPDATED_NODE_TEMPLATE_JSON), + ToscaServiceTemplate.class); + } + + @Test + public void testVerifyNodeType() { + assertThatThrownBy(() -> { + nodeTemplateService.verifyNodeTypeInDbTemplate(new JpaToscaNodeTemplate()); + }).hasMessageMatching("^NODE_TYPE .* for toscaNodeTemplate .* does not exist$"); + + JpaToscaNodeTemplate jpaToscaNodeTemplate = new JpaToscaNodeTemplate(); + PfConceptKey nodeType = new PfConceptKey("dummyType", "1.0.0"); + jpaToscaNodeTemplate.setType(nodeType); + jpaToscaNodeTemplate.setKey(new PfConceptKey("dummyName", "1.0.0")); + Mockito.when(nodeTypeRepository.findById(nodeType)).thenReturn(Optional.of(new JpaToscaNodeType())); + assertDoesNotThrow(() -> nodeTemplateService.verifyNodeTypeInDbTemplate(jpaToscaNodeTemplate)); + } + + @Test + public void testNodeTemplateUsedInPolicy() { + assertDoesNotThrow(() -> nodeTemplateService.assertNodeTemplateNotUsedInPolicy("dummyName", "1.0.0", + new JpaToscaServiceTemplate(policyServiceTemplate))); + + assertThatThrownBy(() -> { + nodeTemplateService.assertNodeTemplateNotUsedInPolicy("apexMetadata_decisionMaker", "1.0.0", + new JpaToscaServiceTemplate(policyServiceTemplate)); + }).hasMessage("Node template is in use, it is referenced in Tosca Policy operational.apex.decisionMaker " + + "version 1.0.0"); + } + + @Test + public void testNodeTemplateUpdate() throws PfModelException { + + Mockito.when(nodeTypeRepository.findById(Mockito.any())).thenReturn(Optional.of(new JpaToscaNodeType())); + Mockito.when(nodeTemplateRepository.findById(Mockito.any())).thenReturn(Optional.of( + new JpaToscaNodeTemplate())); + assertDoesNotThrow(() -> nodeTemplateService.updateToscaNodeTemplates( + new JpaToscaServiceTemplate(updatedToscaServiceTemplate))); + } +} diff --git a/main/src/test/java/org/onap/policy/api/main/service/TestToscaServiceTemplateForNodeTemplate.java b/main/src/test/java/org/onap/policy/api/main/service/TestToscaServiceTemplateForNodeTemplate.java new file mode 100644 index 00000000..6c6f0162 --- /dev/null +++ b/main/src/test/java/org/onap/policy/api/main/service/TestToscaServiceTemplateForNodeTemplate.java @@ -0,0 +1,160 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP Policy API + * ================================================================================ + * Copyright (C) 2022 Nordix Foundation. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.api.main.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplate; + +@RunWith(MockitoJUnitRunner.class) +public class TestToscaServiceTemplateForNodeTemplate extends TestCommonToscaServiceTemplateService { + + private static final String NODE_TEMPLATES_JSON = "nodetemplates/nodetemplates.metadatasets.input.tosca.json"; + private static final String UPDATED_NODE_TEMPLATE_JSON = "nodetemplates/nodetemplates.metadatasets.update.json"; + private static ToscaServiceTemplate toscaServiceTemplate; + private static ToscaServiceTemplate updatedToscaServiceTemplate; + private StandardCoder standardCoder; + + @InjectMocks + private ToscaServiceTemplateService toscaServiceTemplateService; + + + @Before + public void setUp() { + super.setUp(); + } + + /** + * Fetch json files required for the tests. + * + * @throws CoderException when error parsing the json + */ + @Before + public void fetchToscaNodeTemplateJson() throws CoderException { + standardCoder = new StandardCoder(); + toscaServiceTemplate = + standardCoder.decode(ResourceUtils.getResourceAsString(NODE_TEMPLATES_JSON), ToscaServiceTemplate.class); + updatedToscaServiceTemplate = + standardCoder.decode(ResourceUtils.getResourceAsString(UPDATED_NODE_TEMPLATE_JSON), + ToscaServiceTemplate.class); + } + + @Test + public void testToscaNodeTemplatesGet() throws Exception { + + assertNotNull(toscaServiceTemplate); + var createdTemplate = toscaServiceTemplateService.createToscaNodeTemplates(toscaServiceTemplate); + mockDbServiceTemplate(createdTemplate, null, null); + + //Fetch all node templates if id is null + List gotToscaNodeTemplates = toscaServiceTemplateService + .fetchToscaNodeTemplates(null, null); + assertEquals(3, gotToscaNodeTemplates.size()); + + // Get filtered node templates + List filteredNodeTemplates = toscaServiceTemplateService + .fetchToscaNodeTemplates("apexMetadata_adaptive", "1.0.0"); + assertEquals(1, filteredNodeTemplates.size()); + + //Get invalid node template + List filteredNodeTemplatesInvalid = toscaServiceTemplateService + .fetchToscaNodeTemplates("invalidname", "1.0.0"); + assertThat(filteredNodeTemplatesInvalid).isEmpty(); + } + + @Test + public void testToscaNodeTemplatesCreate() throws Exception { + + assertThatThrownBy(() -> { + toscaServiceTemplateService.createToscaNodeTemplates(null); + }).hasMessageMatching("^serviceTemplate is marked .*on.*ull but is null$"); + + ToscaServiceTemplate createdNodeTemplates = + toscaServiceTemplateService.createToscaNodeTemplates(toscaServiceTemplate); + assertThat(createdNodeTemplates.getToscaTopologyTemplate().getNodeTemplates()).hasSize(3); + assertThat(createdNodeTemplates.getToscaTopologyTemplate().getNodeTemplates().get("apexMetadata_grpc") + .getMetadata()).containsKey("threshold"); + } + + @Test + public void testToscaNodeTemplateUpdate() throws Exception { + + assertThatThrownBy(() -> { + toscaServiceTemplateService.updateToscaNodeTemplates(null); + }).hasMessageMatching("^serviceTemplate is marked non-null but is null$"); + + JpaToscaNodeTemplate jpaNodeTemplate = new JpaToscaNodeTemplate(); + PfConceptKey key = new PfConceptKey("apexMetadata_grpc", "1.0.0"); + jpaNodeTemplate.setKey(key); + jpaNodeTemplate.setDescription("Updated Metadata set for GRPC"); + ToscaServiceTemplate updatedTemplate = + toscaServiceTemplateService.updateToscaNodeTemplates(updatedToscaServiceTemplate); + assertEquals("Updated Metadata set for GRPC", + updatedTemplate.getToscaTopologyTemplate().getNodeTemplates().get("apexMetadata_grpc") + .getDescription()); + } + + @Test + public void testToscaNodeTemplateDelete() throws Exception { + + assertThatThrownBy(() -> { + toscaServiceTemplateService.deleteToscaNodeTemplate(null, null); + }).hasMessageMatching("^name is marked .*on.*ull but is null$"); + + assertThatThrownBy(() -> { + toscaServiceTemplateService.deleteToscaNodeTemplate("name", null); + }).hasMessageMatching("^version is marked .*on.*ull but is null$"); + + var createdTemplate = toscaServiceTemplateService.createToscaNodeTemplates(toscaServiceTemplate); + mockDbServiceTemplate(createdTemplate, null, null); + assertThatThrownBy(() -> { + toscaServiceTemplateService.deleteToscaNodeTemplate("dummyname", "1.0.1"); + }).hasMessage("node template dummyname:1.0.1 not found"); + + ToscaServiceTemplate responseTemplate = + toscaServiceTemplateService.deleteToscaNodeTemplate("apexMetadata_decisionMaker", "1.0.0"); + + assertTrue(responseTemplate.getToscaTopologyTemplate().getNodeTemplates() + .containsKey("apexMetadata_decisionMaker")); + assertThat(responseTemplate.getToscaTopologyTemplate().getNodeTemplates()).hasSize(1); + + assertThat(toscaServiceTemplateService.fetchToscaNodeTemplates(null, null)).hasSize(2); + } + +} diff --git a/main/src/test/resources/application-test.yaml b/main/src/test/resources/application-test.yaml index 6ed69ea0..f47873b7 100644 --- a/main/src/test/resources/application-test.yaml +++ b/main/src/test/resources/application-test.yaml @@ -11,12 +11,3 @@ spring: naming: physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl implicit-strategy: org.onap.policy.common.spring.utils.CustomImplicitNamingStrategy - -database: - name: PolicyProviderParameterGroup - implementation: org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl - driver: org.h2.Driver - url: jdbc:h2:mem:testdb - user: policy_user - password: policy_user - persistenceUnit: ToscaConceptTest \ No newline at end of file diff --git a/main/src/test/resources/nodetemplates/dummy.apex.decisionmaker.policy.yaml b/main/src/test/resources/nodetemplates/dummy.apex.decisionmaker.policy.yaml new file mode 100644 index 00000000..c2e96b55 --- /dev/null +++ b/main/src/test/resources/nodetemplates/dummy.apex.decisionmaker.policy.yaml @@ -0,0 +1,14 @@ +--- +# Representation of apex decision maker policy with metadataSet reference in the metadata field. + +tosca_definitions_version: tosca_simple_yaml_1_1_0 +topology_template: + policies: + - operational.apex.decisionMaker: + type: onap.policies.Test + type_version: 1.0.0 + name: operational.apex.decisionMaker + version: 1.0.0 + metadata: + metadataSetName: apexMetadata_decisionMaker + metadataSetVersion: 1.0.0 \ No newline at end of file diff --git a/main/src/test/resources/nodetemplates/nodetemplates.metadatasets.update.json b/main/src/test/resources/nodetemplates/nodetemplates.metadatasets.update.json index 767f1fb1..c6aa65b3 100644 --- a/main/src/test/resources/nodetemplates/nodetemplates.metadatasets.update.json +++ b/main/src/test/resources/nodetemplates/nodetemplates.metadatasets.update.json @@ -13,7 +13,7 @@ "version": "1.0.0", "type": "org.onap.nodetypes.policy.MetadataSet", "type_version": "1.0.0", - "description": "Metadata set for GRPC", + "description": "Updated Metadata set for GRPC", "metadata": { "policyModel": { "key": { diff --git a/packages/policy-api-tarball/src/main/resources/etc/apiParameters.yaml b/packages/policy-api-tarball/src/main/resources/etc/apiParameters.yaml index fcb6d9f7..2c19199a 100644 --- a/packages/policy-api-tarball/src/main/resources/etc/apiParameters.yaml +++ b/packages/policy-api-tarball/src/main/resources/etc/apiParameters.yaml @@ -25,15 +25,6 @@ policy-api: name: ApiGroup aaf: false -database: - name: PolicyProviderParameterGroup - implementation: org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl - driver: org.mariadb.jdbc.Driver - url: jdbc:mariadb://mariadb:3306/policyadmin - user: policy_user - password: policy_user - persistenceUnit: PolicyDb - policy-preload: policyTypes: - policytypes/onap.policies.monitoring.tcagen2.yaml diff --git a/testsuites/stability/src/main/resources/apisetup/config/api/etc/defaultConfig.json b/testsuites/stability/src/main/resources/apisetup/config/api/etc/defaultConfig.json index 59e6fc4d..c463ac6d 100644 --- a/testsuites/stability/src/main/resources/apisetup/config/api/etc/defaultConfig.json +++ b/testsuites/stability/src/main/resources/apisetup/config/api/etc/defaultConfig.json @@ -8,15 +8,6 @@ "https": true, "aaf": false }, - "databaseProviderParameters": { - "name": "PolicyProviderParameterGroup", - "implementation": "org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl", - "databaseDriver": "org.mariadb.jdbc.Driver", - "databaseUrl": "jdbc:mariadb://mariadb:3306/policyadmin", - "databaseUser": "policy_user", - "databasePassword": "policy_user", - "persistenceUnit": "PolicyDb" - }, "preloadPolicyTypes": [ "policytypes/onap.policies.monitoring.cdap.tca.hi.lo.app.yaml", "policytypes/onap.policies.monitoring.dcaegen2.collectors.datafile.datafile-app-server.yaml", -- cgit 1.2.3-korg