diff options
author | Chenfei Gao <cgao@research.att.com> | 2020-01-09 13:33:12 -0500 |
---|---|---|
committer | Chenfei Gao <cgao@research.att.com> | 2020-01-13 12:32:40 -0500 |
commit | c73f78ef267ec0bb4552cdaf74f0a42e8078e2ee (patch) | |
tree | 3ab1be8a1fb3dd19154090291e17eb6b691f19c7 | |
parent | 1d801e7c49105b19ac7bfd3f7addbac995fd1dc8 (diff) |
Added the new versioning validation for policy and policy type
The following rules are implemented to validate the version provided
in the POST payloads of policies and policy types:
1) If version field is not specified in POST payload, "406 - Not Acceptable"
would be returned along with the message "mandantory version field is missing".
2) If the version is not in the DB, we simply insert it.
3) If the version is in the DB, "406 - Not Acceptable" is returned along with
the message saying "specified version x.x.x" is already existing and the latest
version is x.x.x. It can force the user to create a newer version than the latest one.
4) The same versioning validation is applied to legacy types of policies too
so that everything is consistent.
Issue-ID: POLICY-2316
Change-Id: I395df0196a9d3073fd1f09060f943aeeb554d277
Signed-off-by: Chenfei Gao <cgao@research.att.com>
21 files changed, 1443 insertions, 268 deletions
diff --git a/main/src/main/java/org/onap/policy/api/main/rest/ApiRestController.java b/main/src/main/java/org/onap/policy/api/main/rest/ApiRestController.java index 6d6b4d14..f9eff4c2 100644 --- a/main/src/main/java/org/onap/policy/api/main/rest/ApiRestController.java +++ b/main/src/main/java/org/onap/policy/api/main/rest/ApiRestController.java @@ -3,7 +3,7 @@ * ONAP Policy API
* ================================================================================
* Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved.
- * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -374,26 +374,35 @@ public class ApiRestController extends CommonRestController { authorizations = @Authorization(value = "basicAuth"), tags = {"PolicyType",},
response = ToscaServiceTemplate.class,
responseHeaders = {
- @ResponseHeader(name = "X-MinorVersion",
- description = "Used to request or communicate a MINOR version back from the client"
- + " to the server, and from the server back to the client",
- response = String.class),
- @ResponseHeader(name = "X-PatchVersion",
- description = "Used only to communicate a PATCH version in a response for"
- + " troubleshooting purposes only, and will not be provided by"
- + " the client on request",
- response = String.class),
- @ResponseHeader(name = "X-LatestVersion",
- description = "Used only to communicate an API's latest version", response = String.class),
- @ResponseHeader(name = "X-ONAP-RequestID",
- description = "Used to track REST transactions for logging purpose", response = UUID.class)},
- extensions = {@Extension(name = "interface info",
- properties = {@ExtensionProperty(name = "api-version", value = "1.0.0"),
- @ExtensionProperty(name = "last-mod-release", value = "Dublin")})})
- @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid Body"),
- @ApiResponse(code = 401, message = "Authentication Error"),
- @ApiResponse(code = 403, message = "Authorization Error"),
- @ApiResponse(code = 500, message = "Internal Server Error")})
+ @ResponseHeader(name = "X-MinorVersion",
+ description = "Used to request or communicate a MINOR version back from the client"
+ + " to the server, and from the server back to the client",
+ response = String.class),
+ @ResponseHeader(name = "X-PatchVersion",
+ description = "Used only to communicate a PATCH version in a response for"
+ + " troubleshooting purposes only, and will not be provided by"
+ + " the client on request",
+ response = String.class),
+ @ResponseHeader(name = "X-LatestVersion",
+ description = "Used only to communicate an API's latest version",
+ response = String.class),
+ @ResponseHeader(name = "X-ONAP-RequestID",
+ description = "Used to track REST transactions for logging purpose",
+ response = UUID.class)
+ },
+ extensions = {
+ @Extension(name = "interface info", properties = {
+ @ExtensionProperty(name = "api-version", value = "1.0.0"),
+ @ExtensionProperty(name = "last-mod-release", value = "Dublin")
+ })
+ })
+ @ApiResponses(value = {
+ @ApiResponse(code = 400, message = "Invalid Body"),
+ @ApiResponse(code = 401, message = "Authentication Error"),
+ @ApiResponse(code = 403, message = "Authorization Error"),
+ @ApiResponse(code = 406, message = "Not Acceptable Payload"),
+ @ApiResponse(code = 500, message = "Internal Server Error")
+ })
public Response createPolicyType(
@ApiParam(value = "Entity body of policy type", required = true) ToscaServiceTemplate body,
@HeaderParam("X-ONAP-RequestID") @ApiParam("RequestID for http transaction") UUID requestId) {
@@ -758,27 +767,36 @@ public class ApiRestController extends CommonRestController { authorizations = @Authorization(value = "basicAuth"), tags = {"Policy",},
response = ToscaServiceTemplate.class,
responseHeaders = {
- @ResponseHeader(name = "X-MinorVersion",
- description = "Used to request or communicate a MINOR version back from the client"
- + " to the server, and from the server back to the client",
- response = String.class),
- @ResponseHeader(name = "X-PatchVersion",
- description = "Used only to communicate a PATCH version in a response for"
- + " troubleshooting purposes only, and will not be provided by"
- + " the client on request",
- response = String.class),
- @ResponseHeader(name = "X-LatestVersion",
- description = "Used only to communicate an API's latest version", response = String.class),
- @ResponseHeader(name = "X-ONAP-RequestID",
- description = "Used to track REST transactions for logging purpose", response = UUID.class)},
- extensions = {@Extension(name = "interface info",
- properties = {@ExtensionProperty(name = "api-version", value = "1.0.0"),
- @ExtensionProperty(name = "last-mod-release", value = "Dublin")})})
- @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid Body"),
- @ApiResponse(code = 401, message = "Authentication Error"),
- @ApiResponse(code = 403, message = "Authorization Error"),
- @ApiResponse(code = 404, message = "Resource Not Found"),
- @ApiResponse(code = 500, message = "Internal Server Error")})
+ @ResponseHeader(name = "X-MinorVersion",
+ description = "Used to request or communicate a MINOR version back from the client"
+ + " to the server, and from the server back to the client",
+ response = String.class),
+ @ResponseHeader(name = "X-PatchVersion",
+ description = "Used only to communicate a PATCH version in a response for"
+ + " troubleshooting purposes only, and will not be provided by"
+ + " the client on request",
+ response = String.class),
+ @ResponseHeader(name = "X-LatestVersion",
+ description = "Used only to communicate an API's latest version",
+ response = String.class),
+ @ResponseHeader(name = "X-ONAP-RequestID",
+ description = "Used to track REST transactions for logging purpose",
+ response = UUID.class)
+ },
+ extensions = {
+ @Extension(name = "interface info", properties = {
+ @ExtensionProperty(name = "api-version", value = "1.0.0"),
+ @ExtensionProperty(name = "last-mod-release", value = "Dublin")
+ })
+ })
+ @ApiResponses(value = {
+ @ApiResponse(code = 400, message = "Invalid Body"),
+ @ApiResponse(code = 401, message = "Authentication Error"),
+ @ApiResponse(code = 403, message = "Authorization Error"),
+ @ApiResponse(code = 404, message = "Resource Not Found"),
+ @ApiResponse(code = 406, message = "Not Acceptable Payload"),
+ @ApiResponse(code = 500, message = "Internal Server Error")
+ })
public Response createPolicy(
@PathParam("policyTypeId") @ApiParam(value = "ID of policy type", required = true) String policyTypeId,
@PathParam("policyTypeVersion") @ApiParam(value = "Version of policy type",
@@ -816,27 +834,36 @@ public class ApiRestController extends CommonRestController { authorizations = @Authorization(value = "basicAuth"), tags = {"Policy",},
response = ToscaServiceTemplate.class,
responseHeaders = {
- @ResponseHeader(name = "X-MinorVersion",
- description = "Used to request or communicate a MINOR version back from the client"
- + " to the server, and from the server back to the client",
- response = String.class),
- @ResponseHeader(name = "X-PatchVersion",
- description = "Used only to communicate a PATCH version in a response for"
- + " troubleshooting purposes only, and will not be provided by"
- + " the client on request",
- response = String.class),
- @ResponseHeader(name = "X-LatestVersion",
- description = "Used only to communicate an API's latest version", response = String.class),
- @ResponseHeader(name = "X-ONAP-RequestID",
- description = "Used to track REST transactions for logging purpose", response = UUID.class)},
- extensions = {@Extension(name = "interface info",
- properties = {@ExtensionProperty(name = "api-version", value = "1.0.0"),
- @ExtensionProperty(name = "last-mod-release", value = "El Alto")})})
- @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid Body"),
- @ApiResponse(code = 401, message = "Authentication Error"),
- @ApiResponse(code = 403, message = "Authorization Error"),
- @ApiResponse(code = 404, message = "Resource Not Found"),
- @ApiResponse(code = 500, message = "Internal Server Error")})
+ @ResponseHeader(name = "X-MinorVersion",
+ description = "Used to request or communicate a MINOR version back from the client"
+ + " to the server, and from the server back to the client",
+ response = String.class),
+ @ResponseHeader(name = "X-PatchVersion",
+ description = "Used only to communicate a PATCH version in a response for"
+ + " troubleshooting purposes only, and will not be provided by"
+ + " the client on request",
+ response = String.class),
+ @ResponseHeader(name = "X-LatestVersion",
+ description = "Used only to communicate an API's latest version",
+ response = String.class),
+ @ResponseHeader(name = "X-ONAP-RequestID",
+ description = "Used to track REST transactions for logging purpose",
+ response = UUID.class)
+ },
+ extensions = {
+ @Extension(name = "interface info", properties = {
+ @ExtensionProperty(name = "api-version", value = "1.0.0"),
+ @ExtensionProperty(name = "last-mod-release", value = "El Alto")
+ })
+ })
+ @ApiResponses(value = {
+ @ApiResponse(code = 400, message = "Invalid Body"),
+ @ApiResponse(code = 401, message = "Authentication Error"),
+ @ApiResponse(code = 403, message = "Authorization Error"),
+ @ApiResponse(code = 404, message = "Resource Not Found"),
+ @ApiResponse(code = 406, message = "Not Acceptable Payload"),
+ @ApiResponse(code = 500, message = "Internal Server Error")
+ })
public Response createPolicies(
@HeaderParam("X-ONAP-RequestID") @ApiParam("RequestID for http transaction") UUID requestId,
@ApiParam(value = "Entity body of policy", required = true) ToscaServiceTemplate body) {
diff --git a/main/src/main/java/org/onap/policy/api/main/rest/LegacyApiRestController.java b/main/src/main/java/org/onap/policy/api/main/rest/LegacyApiRestController.java index 1c2e8d8d..67ea856f 100644 --- a/main/src/main/java/org/onap/policy/api/main/rest/LegacyApiRestController.java +++ b/main/src/main/java/org/onap/policy/api/main/rest/LegacyApiRestController.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP Policy API * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -236,26 +236,35 @@ public class LegacyApiRestController extends CommonRestController { authorizations = @Authorization(value = "basicAuth"), tags = {"Legacy Guard Policy",}, response = LegacyGuardPolicyOutput.class, responseContainer = "Map", responseHeaders = { - @ResponseHeader(name = "X-MinorVersion", - description = "Used to request or communicate a MINOR version back from the client" - + " to the server, and from the server back to the client", - response = String.class), - @ResponseHeader(name = "X-PatchVersion", - description = "Used only to communicate a PATCH version in a response for" - + " troubleshooting purposes only, and will not be provided by" - + " the client on request", - response = String.class), - @ResponseHeader(name = "X-LatestVersion", - description = "Used only to communicate an API's latest version", response = String.class), - @ResponseHeader(name = "X-ONAP-RequestID", - description = "Used to track REST transactions for logging purpose", response = UUID.class)}, - extensions = {@Extension(name = "interface info", - properties = {@ExtensionProperty(name = "api-version", value = "1.0.0"), - @ExtensionProperty(name = "last-mod-release", value = "Dublin")})}) - @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid Body"), - @ApiResponse(code = 401, message = "Authentication Error"), - @ApiResponse(code = 403, message = "Authorization Error"), - @ApiResponse(code = 500, message = "Internal Server Error")}) + @ResponseHeader(name = "X-MinorVersion", + description = "Used to request or communicate a MINOR version back from the client" + + " to the server, and from the server back to the client", + response = String.class), + @ResponseHeader(name = "X-PatchVersion", + description = "Used only to communicate a PATCH version in a response for" + + " troubleshooting purposes only, and will not be provided by" + + " the client on request", + response = String.class), + @ResponseHeader(name = "X-LatestVersion", + description = "Used only to communicate an API's latest version", + response = String.class), + @ResponseHeader(name = "X-ONAP-RequestID", + description = "Used to track REST transactions for logging purpose", + response = UUID.class) + }, + extensions = { + @Extension(name = "interface info", properties = { + @ExtensionProperty(name = "api-version", value = "1.0.0"), + @ExtensionProperty(name = "last-mod-release", value = "Dublin") + }) + }) + @ApiResponses(value = { + @ApiResponse(code = 400, message = "Invalid Body"), + @ApiResponse(code = 401, message = "Authentication Error"), + @ApiResponse(code = 403, message = "Authorization Error"), + @ApiResponse(code = 406, message = "Not Acceptable Payload"), + @ApiResponse(code = 500, message = "Internal Server Error") + }) public Response createGuardPolicy( @HeaderParam("X-ONAP-RequestID") @ApiParam("RequestID for http transaction") UUID requestId, @ApiParam(value = "Entity body of policy", required = true) LegacyGuardPolicyInput body) { @@ -489,26 +498,35 @@ public class LegacyApiRestController extends CommonRestController { authorizations = @Authorization(value = "basicAuth"), tags = {"Legacy Operational Policy",}, response = LegacyOperationalPolicy.class, responseHeaders = { - @ResponseHeader(name = "X-MinorVersion", - description = "Used to request or communicate a MINOR version back from the client" - + " to the server, and from the server back to the client", - response = String.class), - @ResponseHeader(name = "X-PatchVersion", - description = "Used only to communicate a PATCH version in a response for" - + " troubleshooting purposes only, and will not be provided by" - + " the client on request", - response = String.class), - @ResponseHeader(name = "X-LatestVersion", - description = "Used only to communicate an API's latest version", response = String.class), - @ResponseHeader(name = "X-ONAP-RequestID", - description = "Used to track REST transactions for logging purpose", response = UUID.class)}, - extensions = {@Extension(name = "interface info", - properties = {@ExtensionProperty(name = "api-version", value = "1.0.0"), - @ExtensionProperty(name = "last-mod-release", value = "Dublin")})}) - @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid Body"), - @ApiResponse(code = 401, message = "Authentication Error"), - @ApiResponse(code = 403, message = "Authorization Error"), - @ApiResponse(code = 500, message = "Internal Server Error")}) + @ResponseHeader(name = "X-MinorVersion", + description = "Used to request or communicate a MINOR version back from the client" + + " to the server, and from the server back to the client", + response = String.class), + @ResponseHeader(name = "X-PatchVersion", + description = "Used only to communicate a PATCH version in a response for" + + " troubleshooting purposes only, and will not be provided by" + + " the client on request", + response = String.class), + @ResponseHeader(name = "X-LatestVersion", + description = "Used only to communicate an API's latest version", + response = String.class), + @ResponseHeader(name = "X-ONAP-RequestID", + description = "Used to track REST transactions for logging purpose", + response = UUID.class) + }, + extensions = { + @Extension(name = "interface info", properties = { + @ExtensionProperty(name = "api-version", value = "1.0.0"), + @ExtensionProperty(name = "last-mod-release", value = "Dublin") + }) + }) + @ApiResponses(value = { + @ApiResponse(code = 400, message = "Invalid Body"), + @ApiResponse(code = 401, message = "Authentication Error"), + @ApiResponse(code = 403, message = "Authorization Error"), + @ApiResponse(code = 406, message = "Not Acceptable Payload"), + @ApiResponse(code = 500, message = "Internal Server Error") + }) public Response createOperationalPolicy( @HeaderParam("X-ONAP-RequestID") @ApiParam("RequestID for http transaction") UUID requestId, @ApiParam(value = "Entity body of policy", required = true) LegacyOperationalPolicy body) { 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 index fc0f4368..4a490896 100644 --- 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 @@ -2,7 +2,7 @@ * ============LICENSE_START=======================================================
* ONAP Policy API
* ================================================================================
- * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.
* Modifications Copyright (C) 2019 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -121,7 +121,8 @@ public class CommonModelProvider implements AutoCloseable { */
protected <T> boolean hasData(Map<String, T> mapToCheck) {
- return (mapToCheck != null && !mapToCheck.isEmpty());
+ // We don't allow a null or empty map as well as a map entry with a valid key but null value
+ return (mapToCheck != null && !mapToCheck.isEmpty() && !mapToCheck.containsValue(null));
}
/**
diff --git a/main/src/main/java/org/onap/policy/api/main/rest/provider/LegacyGuardPolicyProvider.java b/main/src/main/java/org/onap/policy/api/main/rest/provider/LegacyGuardPolicyProvider.java index 978a8c0a..2a0874dc 100644 --- a/main/src/main/java/org/onap/policy/api/main/rest/provider/LegacyGuardPolicyProvider.java +++ b/main/src/main/java/org/onap/policy/api/main/rest/provider/LegacyGuardPolicyProvider.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP Policy API * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,11 +33,14 @@ 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.base.PfModelRuntimeException; import org.onap.policy.models.pdp.concepts.PdpGroup; import org.onap.policy.models.pdp.concepts.PdpGroupFilter; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; import org.onap.policy.models.tosca.legacy.concepts.LegacyGuardPolicyInput; import org.onap.policy.models.tosca.legacy.concepts.LegacyGuardPolicyOutput; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Class to provide all kinds of legacy guard policy operations. @@ -46,6 +49,8 @@ import org.onap.policy.models.tosca.legacy.concepts.LegacyGuardPolicyOutput; */ public class LegacyGuardPolicyProvider extends CommonModelProvider { + private static final Logger LOGGER = LoggerFactory.getLogger(LegacyGuardPolicyProvider.class); + private static final String INVALID_POLICY_VERSION = "legacy policy version is not an integer"; private static final String LEGACY_MINOR_PATCH_SUFFIX = ".0.0"; private static final Map<String, PfConceptKey> GUARD_POLICY_TYPE_MAP = new LinkedHashMap<>(); @@ -109,6 +114,7 @@ public class LegacyGuardPolicyProvider extends CommonModelProvider { public Map<String, LegacyGuardPolicyOutput> createGuardPolicy(LegacyGuardPolicyInput body) throws PfModelException { + validateGuardPolicyVersion(body); return modelsProvider.createGuardPolicy(body); } @@ -152,6 +158,79 @@ public class LegacyGuardPolicyProvider extends CommonModelProvider { } /** + * Validates the provided guard policy version in the payload. + * + * @param body the guard policy payload + * + * @throws PfModelException the PfModel parsing exception + */ + private void validateGuardPolicyVersion(LegacyGuardPolicyInput body) throws PfModelException { + + validateGuardPolicyVersionExist(body); + validateNoDuplicateVersionInDb(body); + } + + /** + * Validates that the guard policy has version specified. + * + * @param body the guard policy payload + * + * @throws PfModelException the PfModel parsing exception + */ + private void validateGuardPolicyVersionExist(LegacyGuardPolicyInput body) throws PfModelException { + + if (body.getPolicyVersion() == null) { + String errMsg = "mandatory field 'policy-version' is missing in the policy: " + body.getPolicyId(); + throw new PfModelException(Response.Status.NOT_ACCEPTABLE, errMsg); + } + } + + /** + * Validates that there is no duplicate version already stored in the database. + * + * @param body the guard policy payload + * + * @throws PfModelException the PfModel parsing exception + */ + private void validateNoDuplicateVersionInDb(LegacyGuardPolicyInput body) throws PfModelException { + + try { + modelsProvider.getGuardPolicy(body.getPolicyId(), body.getPolicyVersion()); + } catch (PfModelRuntimeException exc) { + if (!hasSameGuardPolicyFound(body, exc)) { + return; + } + throw new PfModelException(exc.getErrorResponse().getResponseCode(), "unexpected runtime error", exc); + } + + // If it gets here, there is one duplicate version stored in the DB. + // Try to get the latest version and return it to the user. + Map<String, LegacyGuardPolicyOutput> latest = modelsProvider.getGuardPolicy(body.getPolicyId(), null); + final String[] versionArray = latest.values().iterator().next().getVersion().split("\\."); + String errMsg = "guard policy " + body.getPolicyId() + ":" + body.getPolicyVersion() + + " already exists; its latest version is " + versionArray[0]; + throw new PfModelException(Response.Status.NOT_ACCEPTABLE, errMsg); + } + + /** + * Checks if the same guard policy found in the database. + * + * @param body the legacy guard policy payload + * @param exc the thrown runtime exception from policy model provider + * + * @return a boolean flag indicating the check result + */ + private boolean hasSameGuardPolicyFound(LegacyGuardPolicyInput body, PfModelRuntimeException exc) { + + if (exc.getErrorResponse().getResponseCode() == Response.Status.BAD_REQUEST + && exc.getErrorResponse().getErrorMessage().contains("no policy found")) { + LOGGER.debug("no duplicate policy {}:{} found in the DB", body.getPolicyId(), body.getPolicyVersion()); + return false; + } + return true; + } + + /** * Retrieves guard policy type given guard policy ID. * * @param policyId the ID of guard policy diff --git a/main/src/main/java/org/onap/policy/api/main/rest/provider/LegacyOperationalPolicyProvider.java b/main/src/main/java/org/onap/policy/api/main/rest/provider/LegacyOperationalPolicyProvider.java index 8319de41..6bffb2b0 100644 --- a/main/src/main/java/org/onap/policy/api/main/rest/provider/LegacyOperationalPolicyProvider.java +++ b/main/src/main/java/org/onap/policy/api/main/rest/provider/LegacyOperationalPolicyProvider.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP Policy API * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,10 +30,13 @@ 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.base.PfModelRuntimeException; import org.onap.policy.models.pdp.concepts.PdpGroup; import org.onap.policy.models.pdp.concepts.PdpGroupFilter; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; import org.onap.policy.models.tosca.legacy.concepts.LegacyOperationalPolicy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Class to provide all kinds of legacy operational policy operations. @@ -42,6 +45,8 @@ import org.onap.policy.models.tosca.legacy.concepts.LegacyOperationalPolicy; */ public class LegacyOperationalPolicyProvider extends CommonModelProvider { + private static final Logger LOGGER = LoggerFactory.getLogger(LegacyOperationalPolicyProvider.class); + private static final String INVALID_POLICY_VERSION = "legacy policy version is not an integer"; private static final String LEGACY_MINOR_PATCH_SUFFIX = ".0.0"; private static final PfConceptKey LEGACY_OPERATIONAL_TYPE = @@ -84,7 +89,7 @@ public class LegacyOperationalPolicyProvider extends CommonModelProvider { throws PfModelException { return collectDeployedPolicies( - policyId, LEGACY_OPERATIONAL_TYPE, modelsProvider::getOperationalPolicy, List::add, new ArrayList<>()); + policyId, LEGACY_OPERATIONAL_TYPE, modelsProvider::getOperationalPolicy, List::add, new ArrayList<>(5)); } /** @@ -96,6 +101,7 @@ public class LegacyOperationalPolicyProvider extends CommonModelProvider { */ public LegacyOperationalPolicy createOperationalPolicy(LegacyOperationalPolicy body) throws PfModelException { + validateOperationalPolicyVersion(body); return modelsProvider.createOperationalPolicy(body); } @@ -126,7 +132,7 @@ public class LegacyOperationalPolicyProvider extends CommonModelProvider { */ private void validateDeleteEligibility(String policyId, String policyVersion) throws PfModelException { - List<ToscaPolicyIdentifier> policies = new ArrayList<>(); + List<ToscaPolicyIdentifier> policies = new ArrayList<>(5); policies.add(new ToscaPolicyIdentifier(policyId, policyVersion + LEGACY_MINOR_PATCH_SUFFIX)); PdpGroupFilter pdpGroupFilter = PdpGroupFilter.builder().policyList(policies).build(); @@ -137,4 +143,77 @@ public class LegacyOperationalPolicyProvider extends CommonModelProvider { constructDeletePolicyViolationMessage(policyId, policyVersion, pdpGroups)); } } + + /** + * Validates the specified version of the operational policy provided in the payload. + * + * @param body the operational policy payload + * + * @throws PfModelException on errors parsing PfModel + */ + private void validateOperationalPolicyVersion(LegacyOperationalPolicy body) throws PfModelException { + + validateOperationalPolicyVersionExist(body); + validateNoDuplicateVersionInDb(body); + } + + /** + * Validates whether the version of the operational policy is specified in the payload. + * + * @param body the operational policy payload + * + * @throws PfModelException on errors parsing PfModel + */ + private void validateOperationalPolicyVersionExist(LegacyOperationalPolicy body) throws PfModelException { + + if (body.getPolicyVersion() == null) { + String errMsg = "mandatory field 'policy-version' is missing in the policy: " + body.getPolicyId(); + throw new PfModelException(Response.Status.NOT_ACCEPTABLE, errMsg); + } + } + + /** + * Validates that there is no duplicate version of the operational policy which is already stored in the database. + * + * @param body the operational policy payload + * + * @throws PfModelException on errors parsing PfModel + */ + private void validateNoDuplicateVersionInDb(LegacyOperationalPolicy body) throws PfModelException { + + try { + modelsProvider.getOperationalPolicy(body.getPolicyId(), body.getPolicyVersion()); + } catch (PfModelRuntimeException exc) { + if (!hasSameOperationalPolicyFound(body, exc)) { + return; + } + throw new PfModelException(exc.getErrorResponse().getResponseCode(), "unexpected runtime error", exc); + } + + // There is one duplicate version stored in the DB. + // Try to get the latest version + LegacyOperationalPolicy latest = modelsProvider.getOperationalPolicy(body.getPolicyId(), null); + final String[] versionArray = latest.getPolicyVersion().split("\\."); + String errMsg = "operational policy " + body.getPolicyId() + ":" + body.getPolicyVersion() + + " already exists; its latest version is " + versionArray[0]; + throw new PfModelException(Response.Status.NOT_ACCEPTABLE, errMsg); + } + + /** + * Checks if the same operational policy found in the database. + * + * @param body the legacy operational policy payload + * @param exc the runtime exception thrown by policy model provider + * + * @return a boolean flag indicating the check result + */ + private boolean hasSameOperationalPolicyFound(LegacyOperationalPolicy body, PfModelRuntimeException exc) { + + if (exc.getErrorResponse().getResponseCode() == Response.Status.BAD_REQUEST + && exc.getErrorResponse().getErrorMessage().contains("no policy found")) { + LOGGER.debug("no duplicate policy {}:{} found in the DB", body.getPolicyId(), body.getPolicyVersion()); + return false; + } + return true; + } }
\ No newline at end of file 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 index 99dcd715..e45674cc 100644 --- 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 @@ -2,7 +2,7 @@ * ============LICENSE_START=======================================================
* ONAP Policy API
* ================================================================================
- * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,9 +23,12 @@ 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.Map.Entry;
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;
@@ -66,10 +69,8 @@ public class PolicyProvider extends CommonModelProvider { public ToscaServiceTemplate fetchPolicies(String policyTypeId, String policyTypeVersion,
String policyId, String policyVersion) throws PfModelException {
- ToscaPolicyFilter policyFilter = ToscaPolicyFilter.builder()
- .name(policyId).version(policyVersion)
- .type(policyTypeId).typeVersion(policyTypeVersion).build();
- ToscaServiceTemplate serviceTemplate = modelsProvider.getFilteredPolicies(policyFilter);
+ ToscaServiceTemplate serviceTemplate = getFilteredPolicies(
+ policyTypeId, policyTypeVersion, policyId, policyVersion);
if (!hasPolicy(serviceTemplate)) {
throw new PfModelException(Response.Status.NOT_FOUND,
@@ -93,10 +94,8 @@ public class PolicyProvider extends CommonModelProvider { public ToscaServiceTemplate fetchLatestPolicies(String policyTypeId, String policyTypeVersion,
String policyId) throws PfModelException {
- ToscaPolicyFilter policyFilter = ToscaPolicyFilter.builder()
- .name(policyId).version(ToscaPolicyFilter.LATEST_VERSION)
- .type(policyTypeId).typeVersion(policyTypeVersion).build();
- ToscaServiceTemplate serviceTemplate = modelsProvider.getFilteredPolicies(policyFilter);
+ ToscaServiceTemplate serviceTemplate = getFilteredPolicies(
+ policyTypeId, policyTypeVersion, policyId, ToscaPolicyFilter.LATEST_VERSION);
if (!hasPolicy(serviceTemplate)) {
throw new PfModelException(Response.Status.NOT_FOUND,
@@ -121,15 +120,15 @@ public class PolicyProvider extends CommonModelProvider { String policyTypeId, String policyTypeVersion, String policyId) throws PfModelException {
return collectDeployedPolicies(policyId, new PfConceptKey(policyTypeId, policyTypeVersion),
- modelsProvider::getPolicyList, List::addAll, new ArrayList<>());
+ modelsProvider::getPolicyList, List::addAll, new ArrayList<>(5));
}
/**
- * Creates a new policy for a policy type ID and version.
+ * 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 policy
+ * @param body the entity body of polic(ies)
*
* @return the ToscaServiceTemplate object
*
@@ -140,7 +139,7 @@ public class PolicyProvider extends CommonModelProvider { validatePolicyTypeExist(policyTypeId, policyTypeVersion);
validatePolicyTypeMatch(policyTypeId, policyTypeVersion, body);
-
+ validatePolicyVersion(body);
return modelsProvider.createPolicies(body);
}
@@ -155,6 +154,7 @@ public class PolicyProvider extends CommonModelProvider { */
public ToscaServiceTemplate createPolicies(ToscaServiceTemplate body) throws PfModelException {
+ validatePolicyVersion(body);
return modelsProvider.createPolicies(body);
}
@@ -244,9 +244,9 @@ public class PolicyProvider extends CommonModelProvider { private void validateDeleteEligibility(String policyTypeId, String policyTypeVersion,
String policyId, String policyVersion) throws PfModelException {
- List<ToscaPolicyTypeIdentifier> policyTypes = new ArrayList<>();
+ List<ToscaPolicyTypeIdentifier> policyTypes = new ArrayList<>(1);
policyTypes.add(new ToscaPolicyTypeIdentifier(policyTypeId, policyTypeVersion));
- List<ToscaPolicyIdentifier> policies = new ArrayList<>();
+ List<ToscaPolicyIdentifier> policies = new ArrayList<>(1);
policies.add(new ToscaPolicyIdentifier(policyId, policyVersion));
PdpGroupFilter pdpGroupFilter = PdpGroupFilter.builder()
.policyTypeList(policyTypes).policyList(policies).build();
@@ -260,6 +260,145 @@ public class PolicyProvider extends CommonModelProvider { }
/**
+ * Validates the provided policy version in the payload.
+ *
+ * @param body the provided TOSCA service template which contains the policies
+ *
+ * @throws PfModelException the PfModel parsing exception
+ */
+ private void validatePolicyVersion(ToscaServiceTemplate body) throws PfModelException {
+
+ validatePolicyVersionExist(body);
+ validateNoDuplicateVersionInDb(body);
+ validateNoDuplicateVersionInPl(body);
+ }
+
+ /**
+ * Validates the existence of at least one policies in the provided payload.
+ *
+ * @param body the TOSCA service template payload to check against
+ *
+ * @throws PfModelException the PfModel parsing exception
+ */
+ private void validatePolicyVersionExist(ToscaServiceTemplate body) throws PfModelException {
+
+ List<String> invalidPolicyNames = new ArrayList<>(body.getToscaTopologyTemplate().getPolicies().size());
+ for (Map<String, ToscaPolicy> policy : body.getToscaTopologyTemplate().getPolicies()) {
+ ToscaPolicy policyContent = policy.values().iterator().next();
+ if (policyContent.getVersion() == null) {
+ invalidPolicyNames.add(policy.keySet().iterator().next());
+ }
+ }
+
+ if (!invalidPolicyNames.isEmpty()) {
+ String errMsg = "mandatory 'version' field is missing in policies: "
+ + String.join(", ", invalidPolicyNames);
+ throw new PfModelException(Response.Status.NOT_ACCEPTABLE, errMsg);
+ }
+ }
+
+ /**
+ * Validates there is no duplicate policy version stored in the database.
+ *
+ * @param body the TOSCA service template payload to check against
+ *
+ * @throws PfModelException the PfModel parsing exception
+ */
+ private void validateNoDuplicateVersionInDb(ToscaServiceTemplate body) throws PfModelException {
+
+ Map<String, String> invalidPolicies = new HashMap<>();
+ for (Map<String, ToscaPolicy> policy: body.getToscaTopologyTemplate().getPolicies()) {
+ ToscaPolicy policyContent = policy.values().iterator().next();
+ String policyName = policy.keySet().iterator().next();
+ String policyVersion = policyContent.getVersion();
+ String policyTypeName = policyContent.getType();
+ String policyTypeVersion = policyContent.getTypeVersion();
+ ToscaServiceTemplate serviceTemplate =
+ getFilteredPolicies(policyTypeName, policyTypeVersion, policyName, policyVersion);
+ if (hasPolicy(serviceTemplate)) {
+ String latestVersion = getFilteredPolicies(policyTypeName, policyTypeVersion,
+ policyName, ToscaPolicyFilter.LATEST_VERSION).getToscaTopologyTemplate().getPoliciesAsMap()
+ .values().iterator().next().getVersion();
+ invalidPolicies.put(String.join(":", policyName, policyVersion), latestVersion);
+ }
+ }
+
+ if (!invalidPolicies.isEmpty()) {
+ List<String> duplicateVersions = new ArrayList<>(5);
+ for (Entry<String, String> invalidPolicy : invalidPolicies.entrySet()) {
+ String eachDuplicateVersion = "policy " + invalidPolicy.getKey()
+ + " already exists; its latest version is " + invalidPolicy.getValue();
+ duplicateVersions.add(eachDuplicateVersion);
+ }
+ throw new PfModelException(Response.Status.NOT_ACCEPTABLE, String.join("\n", duplicateVersions));
+ }
+ }
+
+ /**
+ * Validates there is no duplicate policy version in the provided payload if multiple policies are present.
+ *
+ * @param body the TOSCA service template payload to check against
+ *
+ * @throws PfModelException the PfModel parsing exception
+ */
+ private void validateNoDuplicateVersionInPl(ToscaServiceTemplate body) throws PfModelException {
+
+ List<Map<String, ToscaPolicy>> policies = body.getToscaTopologyTemplate().getPolicies();
+ List<String> duplicateVersions = new ArrayList<>();
+ for (int i = 0; i < policies.size() - 1; i++) {
+ for (int j = i + 1; j < policies.size(); j++) {
+ if (hasSameNameVersion(policies.get(i), policies.get(j))) {
+ String nameVersion = policies.get(i).keySet().iterator().next() + ":"
+ + policies.get(i).values().iterator().next().getVersion();
+ duplicateVersions.add(nameVersion);
+ }
+ }
+ }
+
+ if (!duplicateVersions.isEmpty()) {
+ String errMsg = "the same version of policies '" + String.join(", ", duplicateVersions)
+ + "' appear multiple times in the payload";
+ throw new PfModelException(Response.Status.NOT_ACCEPTABLE, errMsg);
+ }
+ }
+
+ /**
+ * Checks if two policies have the same name and version.
+ *
+ * @param policy1 the first policy
+ * @param policy2 the second policy
+ *
+ * @return the boolean flag to indicate the result
+ */
+ private boolean hasSameNameVersion(Map<String, ToscaPolicy> policy1, Map<String, ToscaPolicy> policy2) {
+
+ return (policy1.keySet().iterator().next().equals(policy2.keySet().iterator().next())
+ && policy1.values().iterator().next().getVersion().equals(
+ policy2.values().iterator().next().getVersion()));
+ }
+
+ /**
+ * 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
+ *
+ * @return the TOSCA service template containing the specified version of the policy
+ *
+ * @throws PfModelException the PfModel parsing exception
+ */
+ private ToscaServiceTemplate getFilteredPolicies(String policyTypeName, String policyTypeVersion,
+ String policyName, String policyVersion) throws PfModelException {
+
+ ToscaPolicyFilter policyFilter = ToscaPolicyFilter.builder()
+ .name(policyName).version(policyVersion)
+ .type(policyTypeName).typeVersion(policyTypeVersion).build();
+ return modelsProvider.getFilteredPolicies(policyFilter);
+ }
+
+ /**
* Constructs returned message for not found resource.
*
* @param policyTypeId the ID of policy type
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 index 57524518..d23615c0 100644 --- 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 @@ -2,7 +2,7 @@ * ============LICENSE_START=======================================================
* ONAP Policy API
* ================================================================================
- * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,11 +22,17 @@ 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.Map.Entry;
import javax.ws.rs.core.Response;
+
import org.onap.policy.models.base.PfModelException;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyFilter;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeFilter;
import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
@@ -57,9 +63,7 @@ public class PolicyTypeProvider extends CommonModelProvider { public ToscaServiceTemplate fetchPolicyTypes(String policyTypeId, String policyTypeVersion)
throws PfModelException {
- ToscaPolicyTypeFilter policyTypeFilter = ToscaPolicyTypeFilter.builder()
- .name(policyTypeId).version(policyTypeVersion).build();
- ToscaServiceTemplate serviceTemplate = modelsProvider.getFilteredPolicyTypes(policyTypeFilter);
+ ToscaServiceTemplate serviceTemplate = getFilteredPolicyTypes(policyTypeId, policyTypeVersion);
if (policyTypeId != null && !hasPolicyType(serviceTemplate)) {
throw new PfModelException(Response.Status.NOT_FOUND,
@@ -80,9 +84,8 @@ public class PolicyTypeProvider extends CommonModelProvider { */
public ToscaServiceTemplate fetchLatestPolicyTypes(String policyTypeId) throws PfModelException {
- ToscaPolicyTypeFilter policyTypeFilter = ToscaPolicyTypeFilter.builder()
- .name(policyTypeId).version(ToscaPolicyTypeFilter.LATEST_VERSION).build();
- ToscaServiceTemplate serviceTemplate = modelsProvider.getFilteredPolicyTypes(policyTypeFilter);
+ ToscaServiceTemplate serviceTemplate =
+ getFilteredPolicyTypes(policyTypeId, ToscaPolicyTypeFilter.LATEST_VERSION);
if (!hasPolicyType(serviceTemplate)) {
throw new PfModelException(Response.Status.NOT_FOUND,
constructResourceNotFoundMessage(policyTypeId, null));
@@ -101,6 +104,11 @@ public class PolicyTypeProvider extends CommonModelProvider { */
public ToscaServiceTemplate createPolicyType(ToscaServiceTemplate body) throws PfModelException {
+ if (!hasPolicyType(body)) {
+ throw new PfModelException(Response.Status.BAD_REQUEST,
+ "no policy types specified in the service template");
+ }
+ validatePolicyTypeVersion(body);
return modelsProvider.createPolicyTypes(body);
}
@@ -150,6 +158,96 @@ public class PolicyTypeProvider extends CommonModelProvider { }
/**
+ * Validates the provided policy type version in the payload.
+ *
+ * @param body the provided TOSCA service template which contains the policy types
+ *
+ * @throws PfModelException the PfModel parsing exception
+ */
+ private void validatePolicyTypeVersion(ToscaServiceTemplate body) throws PfModelException {
+
+ validatePolicyTypeVersionExist(body);
+ validateNoDuplicateVersionInDb(body);
+ }
+
+ /**
+ * Validates that each policy type has a version specified in the payload.
+ *
+ * @param body the TOSCA service template payload to check against
+ *
+ * @throws PfModelException the PfModel parsing exception
+ */
+ private void validatePolicyTypeVersionExist(ToscaServiceTemplate body) throws PfModelException {
+
+ List<String> invalidPolicyTypeNames = new ArrayList<>();
+ for (Entry<String, ToscaPolicyType> policyType: body.getPolicyTypes().entrySet()) {
+ if (!"tosca.policies.Root".equals(policyType.getValue().getDerivedFrom())
+ && policyType.getValue().getVersion() == null) {
+ invalidPolicyTypeNames.add(policyType.getKey());
+ }
+ }
+
+ if (!invalidPolicyTypeNames.isEmpty()) {
+ String errorMsg = "mandatory 'version' field is missing in policy types: "
+ + String.join(", ", invalidPolicyTypeNames);
+ throw new PfModelException(Response.Status.NOT_ACCEPTABLE, errorMsg);
+ }
+ }
+
+ /**
+ * Validates that there is no duplicate version of the policy type stored in the database.
+ *
+ * @param body the TOSCA service template payload
+ *
+ * @throws PfModelException the PfModel parsing exception
+ */
+ private void validateNoDuplicateVersionInDb(ToscaServiceTemplate body) throws PfModelException {
+
+ Map<String, String> invalidPolicyTypes = new HashMap<>();
+ for (Entry<String, ToscaPolicyType> policyType: body.getPolicyTypes().entrySet()) {
+ if ("tosca.policies.Root".equals(policyType.getValue().getDerivedFrom())) {
+ continue;
+ }
+ String policyTypeName = policyType.getKey();
+ String policyTypeVersion = policyType.getValue().getVersion();
+ ToscaServiceTemplate serviceTemplate = getFilteredPolicyTypes(policyTypeName, policyTypeVersion);
+ if (hasPolicyType(serviceTemplate)) {
+ String latestVersion = getFilteredPolicyTypes(policyTypeName, ToscaPolicyTypeFilter.LATEST_VERSION)
+ .getPolicyTypesAsMap().entrySet().iterator().next().getKey().getVersion();
+ invalidPolicyTypes.put(String.join(":", policyTypeName, policyTypeVersion), latestVersion);
+ }
+ }
+
+ if (!invalidPolicyTypes.isEmpty()) {
+ List<String> duplicateVersions = new ArrayList<>(invalidPolicyTypes.size());
+ for (Entry<String, String> invalidPolicyType : invalidPolicyTypes.entrySet()) {
+ String eachDuplicateVersion = "policy type " + invalidPolicyType.getKey()
+ + " already exists; its latest version is " + invalidPolicyType.getValue();
+ duplicateVersions.add(eachDuplicateVersion);
+ }
+ throw new PfModelException(Response.Status.NOT_ACCEPTABLE, String.join("\n", duplicateVersions));
+ }
+ }
+
+ /**
+ * 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 {
+
+ ToscaPolicyTypeFilter policyTypeFilter = ToscaPolicyTypeFilter.builder()
+ .name(policyTypeName).version(policyTypeVersion).build();
+ return modelsProvider.getFilteredPolicyTypes(policyTypeFilter);
+ }
+
+ /**
* Constructs returned message for not found resource.
*
* @param policyTypeId the ID of policy type
diff --git a/main/src/test/java/org/onap/policy/api/main/rest/TestApiRestServer.java b/main/src/test/java/org/onap/policy/api/main/rest/TestApiRestServer.java index abc87383..124e8583 100644 --- a/main/src/test/java/org/onap/policy/api/main/rest/TestApiRestServer.java +++ b/main/src/test/java/org/onap/policy/api/main/rest/TestApiRestServer.java @@ -1,7 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2019 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -104,13 +104,16 @@ public class TestApiRestServer { "policytypes/onap.policies.monitoring.cdap.tca.hi.lo.app/versions/1.0.0/policies"; private static final String POLICYTYPES_TCA_POLICIES_VCPE = "policytypes/onap.policies.monitoring.cdap.tca.hi.lo.app/versions/1.0.0/policies/onap.restart.tca"; - private static final String POLICYTYPES_TCA_POLICIES_VCPE_VERSION = "policytypes/" + private static final String POLICYTYPES_TCA_POLICIES_VCPE_VERSION1 = "policytypes/" + "onap.policies.monitoring.cdap.tca.hi.lo.app/versions/1.0.0/policies/onap.restart.tca/versions/1.0.0"; + private static final String POLICYTYPES_TCA_POLICIES_VCPE_VERSION2 = "policytypes/" + + "onap.policies.monitoring.cdap.tca.hi.lo.app/versions/1.0.0/policies/onap.restart.tca/versions/2.0.0"; private static final String POLICYTYPES_TCA_POLICIES_VCPE_LATEST = "policytypes/" + "onap.policies.monitoring.cdap.tca.hi.lo.app/versions/1.0.0/policies/onap.restart.tca/versions/latest"; private static final String POLICYTYPES_TCA_POLICIES_VCPE_DEPLOYED = "policytypes/" + "onap.policies.monitoring.cdap.tca.hi.lo.app/versions/1.0.0/policies/onap.restart.tca/versions/deployed"; + private static final String GUARD_POLICYTYPE = "onap.policies.controlloop.Guard"; private static final String GUARD_POLICIES = "policytypes/onap.policies.controlloop.Guard/versions/1.0.0/policies"; private static final String GUARD_POLICIES_VDNS_FL_LATEST = "policytypes/onap.policies.controlloop.Guard/versions/1.0.0/policies/guard.frequency.scaleout" @@ -126,6 +129,7 @@ public class TestApiRestServer { private static final String GUARD_POLICIES_VDNS_MINMAX_VERSION = "policytypes/" + "onap.policies.controlloop.Guard/versions/1.0.0/policies/guard.minmax.scaleout/versions/1"; + private static final String OPS_POLICYTYPE = "onap.policies.controlloop.Operational"; private static final String OPS_POLICIES = "policytypes/onap.policies.controlloop.Operational/versions/1.0.0/policies"; private static final String OPS_POLICIES_VCPE_LATEST = @@ -153,19 +157,19 @@ public class TestApiRestServer { // @formatter:off private static final String[] TOSCA_POLICY_RESOURCE_NAMES = { "policies/vCPE.policy.monitoring.input.tosca.json", - "policies/vCPE.policy.monitoring.input.tosca.yaml", + "policies/vCPE.policy.monitoring.input.tosca.v2.yaml", "policies/vDNS.policy.monitoring.input.tosca.json", - "policies/vDNS.policy.monitoring.input.tosca.yaml", + "policies/vDNS.policy.monitoring.input.tosca.v2.yaml", "policies/vFirewall.policy.monitoring.input.tosca.json", - "policies/vFirewall.policy.monitoring.input.tosca.yaml" + "policies/vFirewall.policy.monitoring.input.tosca.v2.yaml" }; private static final String[] TOSCA_POLICIES_RESOURCE_NAMES = { "policies/vCPE.policies.optimization.input.tosca.json", - "policies/vCPE.policies.optimization.input.tosca.yaml" + "policies/vCPE.policies.optimization.input.tosca.v2.yaml" }; - private static final String[] TOSCA_PPOLICYTYPE_RESOURCE_NAMES = { + private static final String[] TOSCA_POLICYTYPE_RESOURCE_NAMES = { "policytypes/onap.policies.monitoring.cdap.tca.hi.lo.app.yaml", "policytypes/onap.policies.monitoring.dcaegen2.collectors.datafile.datafile-app-server.yaml", "policytypes/onap.policies.Optimization.yaml", @@ -190,12 +194,23 @@ public class TestApiRestServer { "policies/vDNS.policy.guard.minmax.input.json" }; + private static final String[] LEGACY_GUARD_POLICY_NAMES = { + "guard.frequency.scaleout", + "guard.minmax.scaleout" + }; + private static final String[] LEGACY_OPERATIONAL_POLICY_RESOURCE_NAMES = { "policies/vCPE.policy.operational.input.json", "policies/vDNS.policy.operational.input.json", "policies/vFirewall.policy.operational.input.json" }; + private static final String[] LEGACY_OPERATIONAL_POLICY_NAMES = { + "operational.restart", + "operational.scaleout", + "operational.modifyconfig" + }; + private static PolicyModelsProviderParameters providerParams; private static ApiParameterGroup apiParamGroup; private static PolicyProvider policyProvider; @@ -271,23 +286,17 @@ public class TestApiRestServer { */ @Before public void beforeClearDatabase() throws Exception { + Response rawResponse = readResource(POLICYTYPES, APP_JSON); ToscaServiceTemplate response = rawResponse.readEntity(ToscaServiceTemplate.class); for (ToscaEntityKey policyTypeKey : response.getPolicyTypesAsMap().keySet()) { - String getPoliciesPath = - "policytypes/" + policyTypeKey.getName() + "/versions/" + policyTypeKey.getVersion() + "/policies"; - - Response rawPolicyResponse = readResource(getPoliciesPath, APP_JSON); - if (Response.Status.OK.getStatusCode() == rawPolicyResponse.getStatus()) { - ToscaServiceTemplate policyResponse = rawPolicyResponse.readEntity(ToscaServiceTemplate.class); - - for (ToscaEntityKey policyKey : policyResponse.getToscaTopologyTemplate().getPoliciesAsMap().keySet()) { - String deletePolicyPath = - "policytypes/" + policyTypeKey.getName() + "/versions/" + policyTypeKey.getVersion() - + "/policies/" + policyKey.getName() + "/versions/" + policyKey.getVersion(); - deleteResource(deletePolicyPath, APP_JSON); - } + if (GUARD_POLICYTYPE.equals(policyTypeKey.getName()) + || OPS_POLICYTYPE.equals(policyTypeKey.getName())) { + deleteLegacyPolicies(LEGACY_GUARD_POLICY_NAMES, GUARD_POLICYTYPE); + deleteLegacyPolicies(LEGACY_OPERATIONAL_POLICY_NAMES, OPS_POLICYTYPE); + } else { + deleteToscaPolicies(policyTypeKey); } String deletePolicyTypePath = @@ -312,7 +321,7 @@ public class TestApiRestServer { @Test public void testCreatePolicyTypes() throws Exception { - for (String resrcName : TOSCA_PPOLICYTYPE_RESOURCE_NAMES) { + for (String resrcName : TOSCA_POLICYTYPE_RESOURCE_NAMES) { Response rawResponse = createResource(POLICYTYPES, resrcName); assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus()); ToscaServiceTemplate response = rawResponse.readEntity(ToscaServiceTemplate.class); @@ -329,7 +338,7 @@ public class TestApiRestServer { Response rawResponse2 = createResource(POLICYTYPES, standardCoder.encode(response)); assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), rawResponse2.getStatus()); ErrorResponse errorResponse = rawResponse2.readEntity(ErrorResponse.class); - assertEquals("no policy types specified on service template", errorResponse.getErrorMessage()); + assertEquals("no policy types specified in the service template", errorResponse.getErrorMessage()); } @Test @@ -378,7 +387,7 @@ public class TestApiRestServer { Response rawResponse2 = createResource(POLICIES, "src/test/resources/policies/BadTestPolicy.yaml"); assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), rawResponse2.getStatus()); ErrorResponse errorResponse = rawResponse2.readEntity(ErrorResponse.class); - assertEquals("policy type NULL:0.0.0 for policy onap.restart.tca:1.0.0 does not exist", + assertEquals("policy type NULL:0.0.0 for policy onap.restart.tca:2.0.0 does not exist", errorResponse.getErrorMessage()); } @@ -531,7 +540,10 @@ public class TestApiRestServer { rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE, mediaType); assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus()); - rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION, mediaType); + rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION1, mediaType); + assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus()); + + rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION2, mediaType); assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus()); rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE_LATEST, mediaType); @@ -551,7 +563,7 @@ public class TestApiRestServer { private void testDeletePolicies(String mediaType) throws Exception { createPolicyTypes(); - Response rawResponse = deleteResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION, mediaType); + Response rawResponse = deleteResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION1, mediaType); assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rawResponse.getStatus()); ErrorResponse error = rawResponse.readEntity(ErrorResponse.class); assertEquals( @@ -571,7 +583,7 @@ public class TestApiRestServer { } private void testDeletePolicyVersion(String mediaType) throws Exception { - for (String resrcName : TOSCA_PPOLICYTYPE_RESOURCE_NAMES) { + for (String resrcName : TOSCA_POLICYTYPE_RESOURCE_NAMES) { Response rawResponse = createResource(POLICYTYPES, resrcName); assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus()); ToscaServiceTemplate response = rawResponse.readEntity(ToscaServiceTemplate.class); @@ -582,10 +594,10 @@ public class TestApiRestServer { Response rawResponse = createResource(POLICYTYPES_TCA_POLICIES, resrcName); assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus()); } - Response rawResponse = deleteResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION, mediaType); + Response rawResponse = deleteResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION1, mediaType); assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus()); - rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION, mediaType); + rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION1, mediaType); assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rawResponse.getStatus()); ErrorResponse errorResponse = rawResponse.readEntity(ErrorResponse.class); assertEquals( @@ -593,6 +605,17 @@ public class TestApiRestServer { + "onap.policies.monitoring.cdap.tca.hi.lo.app:1.0.0 does not exist", errorResponse.getErrorMessage()); + rawResponse = deleteResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION2, mediaType); + assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus()); + + rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION2, mediaType); + assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rawResponse.getStatus()); + errorResponse = rawResponse.readEntity(ErrorResponse.class); + assertEquals( + "policy with ID onap.restart.tca:2.0.0 and type " + + "onap.policies.monitoring.cdap.tca.hi.lo.app:1.0.0 does not exist", + errorResponse.getErrorMessage()); + rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE, mediaType); assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rawResponse.getStatus()); errorResponse = rawResponse.readEntity(ErrorResponse.class); @@ -621,7 +644,7 @@ public class TestApiRestServer { } private void testGetAllVersionOfPolicy(String mediaType) throws Exception { - for (String resrcName : TOSCA_PPOLICYTYPE_RESOURCE_NAMES) { + for (String resrcName : TOSCA_POLICYTYPE_RESOURCE_NAMES) { Response rawResponse = createResource(POLICYTYPES, resrcName); assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus()); ToscaServiceTemplate response = rawResponse.readEntity(ToscaServiceTemplate.class); @@ -920,7 +943,7 @@ public class TestApiRestServer { } private void createPolicyTypes() throws Exception { - for (String resrcName : TOSCA_PPOLICYTYPE_RESOURCE_NAMES) { + for (String resrcName : TOSCA_POLICYTYPE_RESOURCE_NAMES) { Response rawResponse = createResource(POLICYTYPES, resrcName); assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus()); } @@ -1006,4 +1029,33 @@ public class TestApiRestServer { assertEquals(code, report.getCode()); assertEquals(message, report.getMessage()); } + + private void deleteToscaPolicies(ToscaEntityKey policyTypeKey) throws Exception { + + String getPoliciesPath = + "policytypes/" + policyTypeKey.getName() + "/versions/" + policyTypeKey.getVersion() + "/policies"; + + Response rawPolicyResponse = readResource(getPoliciesPath, APP_JSON); + if (Response.Status.OK.getStatusCode() == rawPolicyResponse.getStatus()) { + ToscaServiceTemplate policyResponse = rawPolicyResponse.readEntity(ToscaServiceTemplate.class); + + for (ToscaEntityKey policyKey : policyResponse.getToscaTopologyTemplate().getPoliciesAsMap().keySet()) { + String deletePolicyPath = + "policytypes/" + policyTypeKey.getName() + "/versions/" + policyTypeKey.getVersion() + + "/policies/" + policyKey.getName() + "/versions/" + policyKey.getVersion(); + deleteResource(deletePolicyPath, APP_JSON); + } + } + } + + private void deleteLegacyPolicies(String[] legacyPolicyNames, String legacyPolicyType) throws Exception { + + for (String policyName : legacyPolicyNames) { + String policyPath = + "policytypes/" + legacyPolicyType + "/versions/1.0.0/policies/" + policyName + "/versions/1"; + if (Response.Status.OK.getStatusCode() == readResource(policyPath, APP_JSON).getStatus()) { + deleteResource(policyPath, APP_JSON); + } + } + } }
\ No newline at end of file diff --git a/main/src/test/java/org/onap/policy/api/main/rest/provider/TestLegacyGuardPolicyProvider.java b/main/src/test/java/org/onap/policy/api/main/rest/provider/TestLegacyGuardPolicyProvider.java index 3104a100..71ce44b1 100644 --- a/main/src/test/java/org/onap/policy/api/main/rest/provider/TestLegacyGuardPolicyProvider.java +++ b/main/src/test/java/org/onap/policy/api/main/rest/provider/TestLegacyGuardPolicyProvider.java @@ -78,6 +78,8 @@ public class TestLegacyGuardPolicyProvider { private static final String POLICY_RESOURCE = "policies/vDNS.policy.guard.frequency.input.json"; private static final String POLICY_RESOURCE_VER1 = "policies/vDNS.policy.guard.frequency.input.ver1.json"; private static final String POLICY_RESOURCE_VER2 = "policies/vDNS.policy.guard.frequency.input.ver2.json"; + private static final String POLICY_RESOURCE_WITH_NO_VERSION = + "policies/vDNS.policy.guard.frequency.no.policyversion.json"; private static final String POLICY_TYPE_RESOURCE = "policytypes/onap.policies.controlloop.guard.FrequencyLimiter.yaml"; private static final String POLICY_TYPE_ID = "onap.policies.controlloop.guard.FrequencyLimiter:1.0.0"; @@ -271,7 +273,7 @@ public class TestLegacyGuardPolicyProvider { } @Test - public void testCreateGuardPolicy() { + public void testCreateGuardPolicy() throws Exception { assertThatThrownBy(() -> { String policyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE); @@ -279,21 +281,33 @@ public class TestLegacyGuardPolicyProvider { guardPolicyProvider.createGuardPolicy(policyToCreate); }).hasMessage("policy type " + POLICY_TYPE_ID + " for policy " + POLICY_ID + " does not exist"); - assertThatCode(() -> { - ToscaServiceTemplate policyTypeServiceTemplate = standardYamlCoder.decode( - ResourceUtils.getResourceAsString(POLICY_TYPE_RESOURCE), ToscaServiceTemplate.class); - policyTypeProvider.createPolicyType(policyTypeServiceTemplate); + ToscaServiceTemplate policyTypeServiceTemplate = standardYamlCoder.decode( + ResourceUtils.getResourceAsString(POLICY_TYPE_RESOURCE), ToscaServiceTemplate.class); + policyTypeProvider.createPolicyType(policyTypeServiceTemplate); - String policyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE); - LegacyGuardPolicyInput policyToCreate = standardCoder.decode(policyString, LegacyGuardPolicyInput.class); - Map<String, LegacyGuardPolicyOutput> createdPolicy = guardPolicyProvider.createGuardPolicy(policyToCreate); - assertNotNull(createdPolicy); - assertFalse(createdPolicy.isEmpty()); - assertTrue(createdPolicy.containsKey("guard.frequency.scaleout")); - assertEquals("onap.policies.controlloop.guard.FrequencyLimiter", - createdPolicy.get("guard.frequency.scaleout").getType()); - assertEquals("1.0.0", createdPolicy.get("guard.frequency.scaleout").getVersion()); - }).doesNotThrowAnyException(); + String policyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE); + LegacyGuardPolicyInput policyToCreate = standardCoder.decode(policyString, LegacyGuardPolicyInput.class); + Map<String, LegacyGuardPolicyOutput> createdPolicy = guardPolicyProvider.createGuardPolicy(policyToCreate); + assertNotNull(createdPolicy); + assertFalse(createdPolicy.isEmpty()); + assertTrue(createdPolicy.containsKey("guard.frequency.scaleout")); + assertEquals("onap.policies.controlloop.guard.FrequencyLimiter", + createdPolicy.get("guard.frequency.scaleout").getType()); + assertEquals("1.0.0", createdPolicy.get("guard.frequency.scaleout").getVersion()); + + assertThatThrownBy(() -> { + String badPolicyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE_WITH_NO_VERSION); + LegacyGuardPolicyInput badPolicyToCreate = + standardCoder.decode(badPolicyString, LegacyGuardPolicyInput.class); + guardPolicyProvider.createGuardPolicy(badPolicyToCreate); + }).hasMessage("mandatory field 'policy-version' is missing in the policy: guard.frequency.scaleout"); + + assertThatThrownBy(() -> { + String duplicatePolicyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE); + LegacyGuardPolicyInput duplicatePolicyToCreate = + standardCoder.decode(duplicatePolicyString, LegacyGuardPolicyInput.class); + guardPolicyProvider.createGuardPolicy(duplicatePolicyToCreate); + }).hasMessage("guard policy guard.frequency.scaleout:1 already exists; its latest version is 1"); } @Test diff --git a/main/src/test/java/org/onap/policy/api/main/rest/provider/TestLegacyOperationalPolicyProvider.java b/main/src/test/java/org/onap/policy/api/main/rest/provider/TestLegacyOperationalPolicyProvider.java index 31e22e3f..72e57a98 100644 --- a/main/src/test/java/org/onap/policy/api/main/rest/provider/TestLegacyOperationalPolicyProvider.java +++ b/main/src/test/java/org/onap/policy/api/main/rest/provider/TestLegacyOperationalPolicyProvider.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP Policy API * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2019 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -74,6 +74,8 @@ public class TestLegacyOperationalPolicyProvider { private static StandardYamlCoder standardYamlCoder; private static final String POLICY_RESOURCE = "policies/vCPE.policy.operational.input.json"; + private static final String POLICY_RESOURCE_WITH_NO_VERSION = + "policies/vDNS.policy.operational.no.policyversion.json"; private static final String POLICY_TYPE_RESOURCE = "policytypes/onap.policies.controlloop.Operational.yaml"; private static final String POLICY_TYPE_ID = "onap.policies.controlloop.Operational:1.0.0"; private static final String POLICY_ID = "operational.restart:1.0.0"; @@ -119,7 +121,7 @@ public class TestLegacyOperationalPolicyProvider { } @Test - public void testFetchOperationalPolicy() { + public void testFetchOperationalPolicy() throws Exception { assertThatThrownBy(() -> { operationalPolicyProvider.fetchOperationalPolicy("dummy", null); @@ -129,31 +131,24 @@ public class TestLegacyOperationalPolicyProvider { operationalPolicyProvider.fetchOperationalPolicy("dummy", "dummy"); }).hasMessage("legacy policy version is not an integer"); - assertThatCode(() -> { - ToscaServiceTemplate policyTypeServiceTemplate = standardYamlCoder.decode( - ResourceUtils.getResourceAsString(POLICY_TYPE_RESOURCE), ToscaServiceTemplate.class); - policyTypeProvider.createPolicyType(policyTypeServiceTemplate); - - String policyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE); - LegacyOperationalPolicy policyToCreate = standardCoder.decode(policyString, LegacyOperationalPolicy.class); - LegacyOperationalPolicy createdPolicy = operationalPolicyProvider.createOperationalPolicy(policyToCreate); - assertNotNull(createdPolicy); + ToscaServiceTemplate policyTypeServiceTemplate = standardYamlCoder.decode( + ResourceUtils.getResourceAsString(POLICY_TYPE_RESOURCE), ToscaServiceTemplate.class); + policyTypeProvider.createPolicyType(policyTypeServiceTemplate); - policyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE); - policyToCreate = standardCoder.decode(policyString, LegacyOperationalPolicy.class); - createdPolicy = operationalPolicyProvider.createOperationalPolicy(policyToCreate); - assertNotNull(createdPolicy); + String policyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE); + LegacyOperationalPolicy policyToCreate = standardCoder.decode(policyString, LegacyOperationalPolicy.class); + LegacyOperationalPolicy createdPolicy = operationalPolicyProvider.createOperationalPolicy(policyToCreate); + assertNotNull(createdPolicy); - LegacyOperationalPolicy firstVersion = - operationalPolicyProvider.fetchOperationalPolicy("operational.restart", "1"); - assertNotNull(firstVersion); - assertEquals("1", firstVersion.getPolicyVersion()); + LegacyOperationalPolicy firstVersion = + operationalPolicyProvider.fetchOperationalPolicy("operational.restart", "1"); + assertNotNull(firstVersion); + assertEquals("1", firstVersion.getPolicyVersion()); - LegacyOperationalPolicy latestVersion = - operationalPolicyProvider.fetchOperationalPolicy("operational.restart", null); - assertNotNull(latestVersion); - assertEquals("2", latestVersion.getPolicyVersion()); - }).doesNotThrowAnyException(); + LegacyOperationalPolicy latestVersion = + operationalPolicyProvider.fetchOperationalPolicy("operational.restart", null); + assertNotNull(latestVersion); + assertEquals("1", latestVersion.getPolicyVersion()); assertThatThrownBy(() -> { operationalPolicyProvider.fetchOperationalPolicy("operational.restart", "1.0.0"); @@ -163,11 +158,8 @@ public class TestLegacyOperationalPolicyProvider { operationalPolicyProvider.fetchOperationalPolicy("operational.restart", "latest");; }).hasMessage("legacy policy version is not an integer"); - assertThatCode(() -> { - operationalPolicyProvider.deleteOperationalPolicy("operational.restart", "1"); - operationalPolicyProvider.deleteOperationalPolicy("operational.restart", "2"); - policyTypeProvider.deletePolicyType("onap.policies.controlloop.Operational", "1.0.0"); - }).doesNotThrowAnyException(); + operationalPolicyProvider.deleteOperationalPolicy("operational.restart", "1"); + policyTypeProvider.deletePolicyType("onap.policies.controlloop.Operational", "1.0.0"); } @Test @@ -263,7 +255,7 @@ public class TestLegacyOperationalPolicyProvider { } @Test - public void testCreateOperationalPolicy() { + public void testCreateOperationalPolicy() throws Exception { assertThatThrownBy(() -> { String policyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE); @@ -271,18 +263,30 @@ public class TestLegacyOperationalPolicyProvider { operationalPolicyProvider.createOperationalPolicy(policyToCreate); }).hasMessage("policy type " + POLICY_TYPE_ID + " for policy " + POLICY_ID + " does not exist"); - assertThatCode(() -> { - ToscaServiceTemplate policyTypeServiceTemplate = standardYamlCoder.decode( - ResourceUtils.getResourceAsString(POLICY_TYPE_RESOURCE), ToscaServiceTemplate.class); - policyTypeProvider.createPolicyType(policyTypeServiceTemplate); + ToscaServiceTemplate policyTypeServiceTemplate = standardYamlCoder.decode( + ResourceUtils.getResourceAsString(POLICY_TYPE_RESOURCE), ToscaServiceTemplate.class); + policyTypeProvider.createPolicyType(policyTypeServiceTemplate); - String policyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE); - LegacyOperationalPolicy policyToCreate = standardCoder.decode(policyString, LegacyOperationalPolicy.class); - LegacyOperationalPolicy createdPolicy = operationalPolicyProvider.createOperationalPolicy(policyToCreate); - assertNotNull(createdPolicy); - assertEquals("operational.restart", createdPolicy.getPolicyId()); - assertTrue(createdPolicy.getContent().startsWith("controlLoop%3A%0A%20%20version%3A%202.0.0%0A%20%20")); - }).doesNotThrowAnyException(); + String policyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE); + LegacyOperationalPolicy policyToCreate = standardCoder.decode(policyString, LegacyOperationalPolicy.class); + LegacyOperationalPolicy createdPolicy = operationalPolicyProvider.createOperationalPolicy(policyToCreate); + assertNotNull(createdPolicy); + assertEquals("operational.restart", createdPolicy.getPolicyId()); + assertTrue(createdPolicy.getContent().startsWith("controlLoop%3A%0A%20%20version%3A%202.0.0%0A%20%20")); + + assertThatThrownBy(() -> { + String badPolicyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE_WITH_NO_VERSION); + LegacyOperationalPolicy badPolicyToCreate = + standardCoder.decode(badPolicyString, LegacyOperationalPolicy.class); + operationalPolicyProvider.createOperationalPolicy(badPolicyToCreate); + }).hasMessage("mandatory field 'policy-version' is missing in the policy: operational.scaleout"); + + assertThatThrownBy(() -> { + String duplicatePolicyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE); + LegacyOperationalPolicy duplicatePolicyToCreate = + standardCoder.decode(duplicatePolicyString, LegacyOperationalPolicy.class); + operationalPolicyProvider.createOperationalPolicy(duplicatePolicyToCreate); + }).hasMessage("operational policy operational.restart:1 already exists; its latest version is 1"); } @Test diff --git a/main/src/test/java/org/onap/policy/api/main/rest/provider/TestPolicyProvider.java b/main/src/test/java/org/onap/policy/api/main/rest/provider/TestPolicyProvider.java index 4221c670..aed40bc9 100644 --- a/main/src/test/java/org/onap/policy/api/main/rest/provider/TestPolicyProvider.java +++ b/main/src/test/java/org/onap/policy/api/main/rest/provider/TestPolicyProvider.java @@ -76,6 +76,9 @@ public class TestPolicyProvider { private static final String POLICY_RESOURCE_WITH_BAD_POLICYTYPE_ID = "policies/vCPE.policy.bad.policytypeid.json"; private static final String POLICY_RESOURCE_WITH_BAD_POLICYTYPE_VERSION = "policies/vCPE.policy.bad.policytypeversion.json"; + private static final String POLICY_RESOURCE_WITH_NO_POLICY_VERSION = "policies/vCPE.policy.no.policyversion.json"; + private static final String POLICY_RESOURCE_WITH_DUPLICATE_POLICY_VERSION = + "policies/vCPE.policy.duplicate.policyversion.json"; private static final String MULTIPLE_POLICIES_RESOURCE = "policies/vCPE.policies.optimization.input.tosca.json"; // @formatter:off @@ -86,7 +89,8 @@ public class TestPolicyProvider { "policytypes/onap.policies.optimization.service.QueryPolicy.yaml", "policytypes/onap.policies.optimization.service.SubscriberPolicy.yaml", "policytypes/onap.policies.optimization.resource.Vim_fit.yaml", - "policytypes/onap.policies.optimization.resource.VnfPolicy.yaml" + "policytypes/onap.policies.optimization.resource.VnfPolicy.yaml", + "policytypes/onap.policies.monitoring.cdap.tca.hi.lo.app.yaml" }; // @formatter:on @@ -245,17 +249,15 @@ public class TestPolicyProvider { } @Test - public void testCreatePolicy() { + public void testCreatePolicy() throws Exception { assertThatThrownBy(() -> { policyProvider.createPolicy("dummy", "1.0.0", new ToscaServiceTemplate()); }).hasMessage("policy type with ID dummy:1.0.0 does not exist"); - assertThatCode(() -> { - ToscaServiceTemplate policyTypeServiceTemplate = standardYamlCoder.decode( - ResourceUtils.getResourceAsString(POLICY_TYPE_RESOURCE), ToscaServiceTemplate.class); - policyTypeProvider.createPolicyType(policyTypeServiceTemplate); - }).doesNotThrowAnyException(); + ToscaServiceTemplate policyTypeServiceTemplate = standardYamlCoder.decode( + ResourceUtils.getResourceAsString(POLICY_TYPE_RESOURCE), ToscaServiceTemplate.class); + policyTypeProvider.createPolicyType(policyTypeServiceTemplate); assertThatThrownBy(() -> { String badPolicyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE_WITH_BAD_POLICYTYPE_ID); @@ -273,13 +275,35 @@ public class TestPolicyProvider { badPolicyServiceTemplate); }).hasMessage("policy type version does not match"); - assertThatCode(() -> { - String policyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE); - ToscaServiceTemplate policyServiceTemplate = standardCoder.decode(policyString, ToscaServiceTemplate.class); - ToscaServiceTemplate serviceTemplate = policyProvider - .createPolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0", policyServiceTemplate); - assertFalse(serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).isEmpty()); - }).doesNotThrowAnyException(); + assertThatThrownBy(() -> { + String badPolicyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE_WITH_NO_POLICY_VERSION); + ToscaServiceTemplate badPolicyServiceTemplate = + standardCoder.decode(badPolicyString, ToscaServiceTemplate.class); + policyProvider.createPolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0", + badPolicyServiceTemplate); + }).hasMessage("mandatory 'version' field is missing in policies: onap.restart.tca"); + + assertThatThrownBy(() -> { + String badPolicyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE_WITH_DUPLICATE_POLICY_VERSION); + ToscaServiceTemplate badPolicyServiceTemplate = + standardCoder.decode(badPolicyString, ToscaServiceTemplate.class); + policyProvider.createPolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0", + badPolicyServiceTemplate); + }).hasMessage("the same version of policies 'onap.restart.tca:1.0.0' appear multiple times in the payload"); + + String policyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE); + ToscaServiceTemplate policyServiceTemplate = standardCoder.decode(policyString, ToscaServiceTemplate.class); + ToscaServiceTemplate serviceTemplate = policyProvider + .createPolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0", policyServiceTemplate); + assertFalse(serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).isEmpty()); + + assertThatThrownBy(() -> { + String badPolicyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE); + ToscaServiceTemplate badPolicyServiceTemplate = + standardCoder.decode(badPolicyString, ToscaServiceTemplate.class); + policyProvider.createPolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0", + badPolicyServiceTemplate); + }).hasMessage("policy onap.restart.tca:1.0.0 already exists; its latest version is 1.0.0"); } @Test @@ -306,6 +330,13 @@ public class TestPolicyProvider { ToscaServiceTemplate multiPoliciesServiceTemplate = standardCoder.decode(multiPoliciesString, ToscaServiceTemplate.class); policyProvider.createPolicies(multiPoliciesServiceTemplate); + + assertThatThrownBy(() -> { + String badPolicyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE_WITH_DUPLICATE_POLICY_VERSION); + ToscaServiceTemplate badPolicyServiceTemplate = + standardCoder.decode(badPolicyString, ToscaServiceTemplate.class); + policyProvider.createPolicies(badPolicyServiceTemplate); + }).hasMessage("the same version of policies 'onap.restart.tca:1.0.0' appear multiple times in the payload"); } @Test diff --git a/main/src/test/java/org/onap/policy/api/main/rest/provider/TestPolicyTypeProvider.java b/main/src/test/java/org/onap/policy/api/main/rest/provider/TestPolicyTypeProvider.java index a17a7c9a..cc84febd 100644 --- a/main/src/test/java/org/onap/policy/api/main/rest/provider/TestPolicyTypeProvider.java +++ b/main/src/test/java/org/onap/policy/api/main/rest/provider/TestPolicyTypeProvider.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP Policy API * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2019 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,7 +23,6 @@ package org.onap.policy.api.main.rest.provider; -import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.Assert.assertFalse; @@ -56,6 +55,10 @@ public class TestPolicyTypeProvider { private static final String POLICY_RESOURCE = "policies/vCPE.policy.monitoring.input.tosca.yaml"; private static final String POLICY_TYPE_RESOURCE = "policytypes/onap.policies.monitoring.cdap.tca.hi.lo.app.yaml"; + private static final String POLICY_TYPE_RESOURCE_WITH_NO_VERSION = + "policytypes/onap.policies.optimization.Resource.no.version.yaml"; + private static final String POLICY_TYPE_NAME = "onap.policies.monitoring.cdap.tca.hi.lo.app"; + private static final String POLICY_TYPE_VERSION = "1.0.0"; /** * Initializes parameters. @@ -92,12 +95,10 @@ public class TestPolicyTypeProvider { } @Test - public void testFetchPolicyTypes() { + public void testFetchPolicyTypes() throws Exception { - assertThatCode(() -> { - ToscaServiceTemplate serviceTemplate = policyTypeProvider.fetchPolicyTypes(null, null); - assertFalse(serviceTemplate.getPolicyTypes().isEmpty()); - }).doesNotThrowAnyException(); + ToscaServiceTemplate serviceTemplate = policyTypeProvider.fetchPolicyTypes(null, null); + assertFalse(serviceTemplate.getPolicyTypes().isEmpty()); assertThatThrownBy(() -> { policyTypeProvider.fetchPolicyTypes("dummy", null); @@ -117,31 +118,41 @@ public class TestPolicyTypeProvider { } @Test - public void testCreatePolicyType() { + public void testCreatePolicyType() throws Exception { - assertThatCode(() -> { - ToscaServiceTemplate policyTypeServiceTemplate = standardYamlCoder.decode( + ToscaServiceTemplate policyTypeServiceTemplate = standardYamlCoder.decode( + ResourceUtils.getResourceAsString(POLICY_TYPE_RESOURCE), ToscaServiceTemplate.class); + ToscaServiceTemplate serviceTemplate = policyTypeProvider.createPolicyType(policyTypeServiceTemplate); + assertFalse(serviceTemplate.getPolicyTypes().isEmpty()); + + String errorMessage = "policy type onap.policies.monitoring.cdap.tca.hi.lo.app:1.0.0 already exists; " + + "its latest version is 1.0.0"; + assertThatThrownBy(() -> { + ToscaServiceTemplate duplicatePolicyType = standardYamlCoder.decode( ResourceUtils.getResourceAsString(POLICY_TYPE_RESOURCE), ToscaServiceTemplate.class); - ToscaServiceTemplate serviceTemplate = policyTypeProvider.createPolicyType(policyTypeServiceTemplate); - assertFalse(serviceTemplate.getPolicyTypes().isEmpty()); - }).doesNotThrowAnyException(); + policyTypeProvider.createPolicyType(duplicatePolicyType); + }).hasMessage(errorMessage); + + assertThatThrownBy(() -> { + ToscaServiceTemplate badPolicyType = standardYamlCoder.decode(ResourceUtils.getResourceAsString( + POLICY_TYPE_RESOURCE_WITH_NO_VERSION), ToscaServiceTemplate.class); + policyTypeProvider.createPolicyType(badPolicyType); + }).hasMessage("mandatory 'version' field is missing in policy types: onap.policies.optimization.Resource"); + + policyTypeProvider.deletePolicyType(POLICY_TYPE_NAME, POLICY_TYPE_VERSION); } @Test - public void testDeletePolicyType() { + public void testDeletePolicyType() throws Exception { - assertThatCode(() -> { - ToscaServiceTemplate policyTypeServiceTemplate = standardYamlCoder.decode( - ResourceUtils.getResourceAsString(POLICY_TYPE_RESOURCE), ToscaServiceTemplate.class); - ToscaServiceTemplate serviceTemplate = policyTypeProvider.createPolicyType(policyTypeServiceTemplate); - assertFalse(serviceTemplate.getPolicyTypes().isEmpty()); - }).doesNotThrowAnyException(); + ToscaServiceTemplate policyTypeServiceTemplate = standardYamlCoder.decode( + ResourceUtils.getResourceAsString(POLICY_TYPE_RESOURCE), ToscaServiceTemplate.class); + ToscaServiceTemplate serviceTemplate = policyTypeProvider.createPolicyType(policyTypeServiceTemplate); + assertFalse(serviceTemplate.getPolicyTypes().isEmpty()); - assertThatCode(() -> { - ToscaServiceTemplate policyServiceTemplate = standardYamlCoder.decode( - ResourceUtils.getResourceAsString(POLICY_RESOURCE), ToscaServiceTemplate.class); - policyProvider.createPolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0", policyServiceTemplate); - }).doesNotThrowAnyException(); + ToscaServiceTemplate policyServiceTemplate = standardYamlCoder.decode( + ResourceUtils.getResourceAsString(POLICY_RESOURCE), ToscaServiceTemplate.class); + policyProvider.createPolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0", policyServiceTemplate); String exceptionMessage = "policy type with ID onap.policies.monitoring.cdap.tca.hi.lo.app:1.0.0 " + "cannot be deleted as it is parameterized by policies onap.restart.tca:1.0.0"; @@ -149,17 +160,13 @@ public class TestPolicyTypeProvider { policyTypeProvider.deletePolicyType("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0"); }).hasMessage(exceptionMessage); - assertThatCode(() -> { - ToscaServiceTemplate serviceTemplate = policyProvider - .deletePolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0", "onap.restart.tca", "1.0.0"); - assertFalse(serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).isEmpty()); - }).doesNotThrowAnyException(); - - assertThatCode(() -> { - ToscaServiceTemplate serviceTemplate = - policyTypeProvider.deletePolicyType("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0"); - assertFalse(serviceTemplate.getPolicyTypes().isEmpty()); - }).doesNotThrowAnyException(); + serviceTemplate = policyProvider + .deletePolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0", "onap.restart.tca", "1.0.0"); + assertFalse(serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).isEmpty()); + + serviceTemplate = + policyTypeProvider.deletePolicyType("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0"); + assertFalse(serviceTemplate.getPolicyTypes().isEmpty()); assertThatThrownBy(() -> { policyTypeProvider.deletePolicyType("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0"); diff --git a/main/src/test/resources/policies/vCPE.policies.optimization.input.tosca.v2.yaml b/main/src/test/resources/policies/vCPE.policies.optimization.input.tosca.v2.yaml new file mode 100644 index 00000000..a946ba4e --- /dev/null +++ b/main/src/test/resources/policies/vCPE.policies.optimization.input.tosca.v2.yaml @@ -0,0 +1,333 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +topology_template: + policies: + - + OSDF_CASABLANCA.Affinity_Default: + type: onap.policies.optimization.resource.AffinityPolicy + version: 2.0.0 + type_version: 1.0.0 + metadata: + policy-id: OSDF_CASABLANCA.Affinity_Default + policy-version: 2 + properties: + scope: [] + services: [] + resources: [] + geography: [] + identity: affinity_vCPE + applicableResources: any + affinityProperties: + qualifier: same + category: complex + - + OSDF_CASABLANCA.Affinity_Default_US: + type: onap.policies.optimization.resource.AffinityPolicy + version: 2.0.0 + type_version: 1.0.0 + metadata: + policy-id: OSDF_CASABLANCA.Affinity_Default_US + policy-version: 2 + properties: + scope: [] + services: [] + resources: [] + geography: [US] + identity: affinity_vCPE + applicableResources: any + affinityProperties: + qualifier: same + category: complex + - + OSDF_CASABLANCA.Affinity_Default_vCPE_US_0: + type: onap.policies.optimization.resource.AffinityPolicy + version: 2.0.0 + type_version: 1.0.0 + metadata: + policy-id: OSDF_CASABLANCA.Affinity_Default_vCPE_US_0 + policy-version: 2 + properties: + scope: [] + services: [vCPE] + resources: [] + geography: [US] + identity: affinity_vCPE + applicableResources: any + affinityProperties: + qualifier: different + category: complex + - + OSDF_CASABLANCA.Affinity_vCPE_US_Gold_1: + type: onap.policies.optimization.resource.AffinityPolicy + version: 2.0.0 + type_version: 1.0.0 + metadata: + policy-id: OSDF_CASABLANCA.Affinity_vCPE_1 + policy-version: 2 + properties: + scope: [gold] + services: [vCPE] + resources: [vGMuxInfra, vG] + geography: [US, INTERNATIONAL] + identity: affinity_vCPE + applicableResources: any + affinityProperties: + qualifier: same + category: availabilityZone + - + OSDF_CASABLANCA.Affinity_vCPE_US_Platinum_1: + type: onap.policies.optimization.resource.AffinityPolicy + version: 2.0.0 + type_version: 1.0.0 + metadata: + policy-id: OSDF_CASABLANCA.Affinity_vCPE_1 + policy-version: 2 + properties: + scope: [platinum] + services: [vCPE] + resources: [vGMuxInfra, vG] + geography: [US, INTERNATIONAL] + identity: affinity_vCPE + applicableResources: any + affinityProperties: + qualifier: different + category: availabilityZone + - + OSDF_CASABLANCA.Capacity_vG_1: + type: onap.policies.optimization.resource.Vim_fit + version: 2.0.0 + type_version: 1.0.0 + metadata: + policy-id: OSDF_CASABLANCA.Capacity_vG_1 + policy-version: 2 + properties: + scope: [] + services: [vCPE] + resources: [vG] + geography: [US, INTERNATIONAL] + identity: capacity_vG + applicableResources: any + capacityProperty: + controller: multicloud + request: "{\"vCPU\": 10, \"Memory\": {\"quantity\": {\"get_param\": \"REQUIRED_MEM\"}, \"unit\": \"GB\"}, \"Storage\": {\"quantity\": {\"get_param\": \"REQUIRED_DISK\"}, \"unit\": \"GB\"}}" + - + OSDF_CASABLANCA.Capacity_vG_2: + type: onap.policies.optimization.resource.Vim_fit + version: 2.0.0 + type_version: 1.0.0 + metadata: + policy-id: OSDF_CASABLANCA.Capacity_vG_2 + policy-version: 2 + properties: + scope: [] + services: [vCPE] + resources: [vG] + geography: [US, INTERNATIONAL] + identity: capacity_vG + applicableResources: any + capacityProperty: + controller: multicloud + request: "{\"vCPU\": 15, \"Memory\": {\"quantity\": {\"get_param\": \"REQUIRED_MEM\"}, \"unit\": \"MB\"}, \"Storage\": {\"quantity\": {\"get_param\": \"REQUIRED_DISK\"}, \"unit\": \"GB\"}}" + - + OSDF_CASABLANCA.Distance_vG_1: + type: onap.policies.optimization.resource.DistancePolicy + version: 2.0.0 + type_version: 1.0.0 + metadata: + policy-id: OSDF_CASABLANCA.Distance_vG_1 + policy-version: 2 + properties: + scope: [platinum] + services: [vCPE] + resources: [vG] + geography: [US, INTERNATIONAL] + identity: distance-vG + applicableResources: any + distanceProperties: + locationInfo: customer_loc + distance: + value: 1500 + operator: "<" + unit: km + - + OSDF_CASABLANCA.hpa_policy_Default: + type: onap.policies.optimization.resource.HpaPolicy + version: 2.0.0 + type_version: 1.0.0 + metadata: + policy-id: OSDF_CASABLANCA.hpa_policy_Default + policy-version: 2 + properties: + scope: [] + services: [] + resources: [] + geography: [] + identity: hpa-vG + flavorFeatures: + - + id: vg_1 + type: vnfc + directives: + - type: flavor_directives + attributes: + - attribute_name: flavor_label_vm_01 + attribute_value: "" + flavorProperties: + - + hpa-feature: basicCapabilities + mandatory: True + architecture: generic + directives: [] + hpa-feature-attributes: + - hpa-attribute-key: numVirtualCpu + hpa-attribute-value: 8 + operator: ['>='] + unit: "" + - hpa-attribute-key: virtualMemSize + hpa-attribute-value: 6 + operator: ['<='] + unit: "" + - + hpa-feature: ovsDpdk + mandatory: False + architecture: generic + directives: [] + hpa-feature-attributes: + - hpa-attribute-key: dataProcessingAccelerationLibrary + hpa-attribute-value: ovsDpdk_version + operator: [=] + unit: "" + - + OSDF_CASABLANCA.hpa_policy_vG_1: + type: onap.policies.optimization.resource.HpaPolicy + version: 2.0.0 + type_version: 1.0.0 + metadata: + policy-id: OSDF_CASABLANCA.hpa_policy_vG_1 + policy-version: 2 + properties: + scope: [] + services: [vCPE, vOtherService] + resources: [vG] + geography: [] + identity: hpa-vG + flavorFeatures: + - + id: vg_1 + type: vnfc + directives: + - type: flavor_directives + attributes: + - attribute_name: flavor_label_vm_01 + attribute_value: "" + flavorProperties: + - + hpa-feature: basicCapabilities + mandatory: True + architecture: generic + directives: [] + hpa-feature-attributes: + - hpa-attribute-key: numVirtualCpu + hpa-attribute-value: 6 + operator: ['>='] + unit: "" + - hpa-attribute-key: virtualMemSize + hpa-attribute-value: 4 + operator: ['<='] + unit: "" + - + hpa-feature: ovsDpdk + mandatory: False + architecture: generic + directives: [] + hpa-feature-attributes: + - hpa-attribute-key: dataProcessingAccelerationLibrary + hpa-attribute-value: ovsDpdk_version + operator: [=] + unit: "" + - + OSDF_CASABLANCA.queryPolicy_vCPE: + type: onap.policies.optimization.service.QueryPolicy + version: 2.0.0 + type_version: 1.0.0 + metadata: + policy-id: OSDF_CASABLANCA.queryPolicy_vCPE + policy-version: 2 + properties: + scope: [] + services: [vCPE] + geography: [US, INTERNATIONAL] + identity: vCPE_Query_Policy + queryProperties: + - + attribute: locationId + attribute_location: customerLocation + value: "" + - + attribute: id + attribute_location: "vpnInfo.vpnId" + value: "" + - + attribute: upstreamBW + attribute_location: "vpnInfo.upstreamBW" + value: "" + - + attribute: customerLatitude + attribute_location: customerLatitude + value: 1.1 + - + attribute: customerLongitude + attribute_location: customerLongitude + value: 2.2 + - + OSDF_CASABLANCA.SubscriberPolicy_v1: + type: onap.policies.optimization.service.SubscriberPolicy + version: 2.0.0 + type_version: 1.0.0 + metadata: + policy-id: OSDF_CASABLANCA.SubscriberPolicy_v1 + policy-version: 2 + properties: + scope: [] + services: [vCPE] + identity: subscriber_vCPE + subscriberProperties: + subscriberName: [subscriber_x, subscriber_y] + subscriberRole: [platinum] + provStatus: [CAPPED] + - + OSDF_CASABLANCA.SubscriberPolicy_v2: + type: onap.policies.optimization.service.SubscriberPolicy + version: 2.0.0 + type_version: 1.0.0 + metadata: + policy-id: OSDF_CASABLANCA.SubscriberPolicy_v2 + policy-version: 2 + properties: + scope: [] + services: [vCPE] + identity: subscriber_vCPE + subscriberProperties: + subscriberName: [subscriber_a, subscriber_b] + subscriberRole: [gold] + provStatus: [CAPPED] + - + OSDF_CASABLANCA.vnfPolicy_vG: + type: onap.policies.optimization.resource.VnfPolicy + version: 2.0.0 + type_version: 1.0.0 + metadata: + policy-id: OSDF_CASABLANCA.vnfPolicy_vG + policy-version: 2 + properties: + scope: [] + services: [vCPE] + resources: [vG] + geography: [US, INTERNATIONAL] + identity: vnf_vG + applicableResources: any + vnfProperties: + - + inventoryProvider: aai + serviceType: "" + inventoryType: cloudRegionId + customerId: "" diff --git a/main/src/test/resources/policies/vCPE.policy.duplicate.policyversion.json b/main/src/test/resources/policies/vCPE.policy.duplicate.policyversion.json new file mode 100644 index 00000000..6caeb503 --- /dev/null +++ b/main/src/test/resources/policies/vCPE.policy.duplicate.policyversion.json @@ -0,0 +1,95 @@ +{ + "tosca_definitions_version": "tosca_simple_yaml_1_0_0", + "topology_template": { + "policies": [ + { + "onap.restart.tca": { + "type": "onap.policies.monitoring.cdap.tca.hi.lo.app", + "version": "1.0.0", + "type_version": "1.0.0", + "metadata": { + "policy-id": "onap.restart.tca" + }, + "properties": { + "tca_policy" : { + "domain": "measurementsForVfScaling", + "metricsPerEventName": [ + { + "eventName": "Measurement_vGMUX", + "controlLoopSchemaType": "VNF", + "policyScope": "DCAE", + "policyName": "DCAE.Config_tca-hi-lo", + "policyVersion": "v0.0.1", + "thresholds": [ + { + "closedLoopControlName": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e", + "version": "1.0.2", + "fieldPath": "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value", + "thresholdValue": 0, + "direction": "EQUAL", + "severity": "MAJOR", + "closedLoopEventStatus": "ABATED" + }, + { + "closedLoopControlName": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e", + "version": "1.0.2", + "fieldPath": "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value", + "thresholdValue": 0, + "direction": "GREATER", + "severity": "CRITICAL", + "closedLoopEventStatus": "ONSET" + } + ] + } + ] + } + } + } + }, + { + "onap.restart.tca": { + "type": "onap.policies.monitoring.cdap.tca.hi.lo.app", + "version": "1.0.0", + "type_version": "1.0.0", + "metadata": { + "policy-id": "onap.restart.tca" + }, + "properties": { + "tca_policy" : { + "domain": "measurementsForVfScaling", + "metricsPerEventName": [ + { + "eventName": "Measurement_vGMUX", + "controlLoopSchemaType": "VNF", + "policyScope": "DCAE", + "policyName": "DCAE.Config_tca-hi-lo", + "policyVersion": "v0.0.1", + "thresholds": [ + { + "closedLoopControlName": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e", + "version": "1.0.2", + "fieldPath": "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value", + "thresholdValue": 0, + "direction": "EQUAL", + "severity": "MAJOR", + "closedLoopEventStatus": "ABATED" + }, + { + "closedLoopControlName": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e", + "version": "1.0.2", + "fieldPath": "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value", + "thresholdValue": 0, + "direction": "GREATER", + "severity": "CRITICAL", + "closedLoopEventStatus": "ONSET" + } + ] + } + ] + } + } + } + } + ] + } +}
\ No newline at end of file diff --git a/main/src/test/resources/policies/vCPE.policy.monitoring.input.tosca.v2.yaml b/main/src/test/resources/policies/vCPE.policy.monitoring.input.tosca.v2.yaml new file mode 100644 index 00000000..523e9bb5 --- /dev/null +++ b/main/src/test/resources/policies/vCPE.policy.monitoring.input.tosca.v2.yaml @@ -0,0 +1,36 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +topology_template: + policies: + - + onap.restart.tca: + type: onap.policies.monitoring.cdap.tca.hi.lo.app + version: 2.0.0 + metadata: + policy-id: onap.restart.tca + properties: + tca_policy: + domain: measurementsForVfScaling + metricsPerEventName: + - + eventName: Measurement_vGMUX + controlLoopSchemaType: VNF + policyScope: DCAE + policyName: "DCAE.Config_tca-hi-lo" + policyVersion: "v0.0.1" + thresholds: + - + closedLoopControlName: "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e" + version: "1.0.2" + fieldPath: "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value" + thresholdValue: 0 + direction: EQUAL + severity: MAJOR + closedLoopEventStatus: ABATED + - + closedLoopControlName: "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e" + version: "1.0.2" + fieldPath: "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value" + thresholdValue: 0 + direction: GREATER + severity: CRITICAL + closedLoopEventStatus: ONSET
\ No newline at end of file diff --git a/main/src/test/resources/policies/vCPE.policy.no.policyversion.json b/main/src/test/resources/policies/vCPE.policy.no.policyversion.json new file mode 100644 index 00000000..b70d5965 --- /dev/null +++ b/main/src/test/resources/policies/vCPE.policy.no.policyversion.json @@ -0,0 +1,50 @@ +{ + "tosca_definitions_version": "tosca_simple_yaml_1_0_0", + "topology_template": { + "policies": [ + { + "onap.restart.tca": { + "type": "onap.policies.monitoring.cdap.tca.hi.lo.app", + "type_version": "1.0.0", + "metadata": { + "policy-id": "onap.restart.tca" + }, + "properties": { + "tca_policy" : { + "domain": "measurementsForVfScaling", + "metricsPerEventName": [ + { + "eventName": "Measurement_vGMUX", + "controlLoopSchemaType": "VNF", + "policyScope": "DCAE", + "policyName": "DCAE.Config_tca-hi-lo", + "policyVersion": "v0.0.1", + "thresholds": [ + { + "closedLoopControlName": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e", + "version": "1.0.2", + "fieldPath": "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value", + "thresholdValue": 0, + "direction": "EQUAL", + "severity": "MAJOR", + "closedLoopEventStatus": "ABATED" + }, + { + "closedLoopControlName": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e", + "version": "1.0.2", + "fieldPath": "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value", + "thresholdValue": 0, + "direction": "GREATER", + "severity": "CRITICAL", + "closedLoopEventStatus": "ONSET" + } + ] + } + ] + } + } + } + } + ] + } +}
\ No newline at end of file diff --git a/main/src/test/resources/policies/vDNS.policy.guard.frequency.no.policyversion.json b/main/src/test/resources/policies/vDNS.policy.guard.frequency.no.policyversion.json new file mode 100644 index 00000000..346765ef --- /dev/null +++ b/main/src/test/resources/policies/vDNS.policy.guard.frequency.no.policyversion.json @@ -0,0 +1,14 @@ +{ + "policy-id" : "guard.frequency.scaleout", + "content" : { + "actor": "SO", + "recipe": "VF Module Create", + "targets": ".*", + "clname": "ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3", + "limit": "1", + "timeWindow": "10", + "timeUnits": "minute", + "guardActiveStart": "00:00:01-05:00", + "guardActiveEnd": "23:59:59-05:00" + } +} diff --git a/main/src/test/resources/policies/vDNS.policy.monitoring.input.tosca.v2.yaml b/main/src/test/resources/policies/vDNS.policy.monitoring.input.tosca.v2.yaml new file mode 100644 index 00000000..9893af1d --- /dev/null +++ b/main/src/test/resources/policies/vDNS.policy.monitoring.input.tosca.v2.yaml @@ -0,0 +1,36 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +topology_template: + policies: + - + onap.scaleout.tca: + type: onap.policies.monitoring.cdap.tca.hi.lo.app + version: 2.0.0 + metadata: + policy-id: onap.scaleout.tca + properties: + tca_policy: + domain: measurementsForVfScaling + metricsPerEventName: + - + eventName: vLoadBalancer + controlLoopSchemaType: VNF + policyScope: "type=configuration" + policyName: "onap.scaleout.tca" + policyVersion: "v0.0.1" + thresholds: + - + closedLoopControlName: "ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3" + closedLoopEventStatus: ONSET + version: "1.0.2" + fieldPath: "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedBroadcastPacketsAccumulated" + thresholdValue: 500 + direction: LESS_OR_EQUAL + severity: MAJOR + - + closedLoopControlName: "ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3" + closedLoopEventStatus: ONSET + version: "1.0.2" + fieldPath: "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedBroadcastPacketsAccumulated" + thresholdValue: 5000 + direction: GREATER_OR_EQUAL + severity: CRITICAL diff --git a/main/src/test/resources/policies/vDNS.policy.operational.no.policyversion.json b/main/src/test/resources/policies/vDNS.policy.operational.no.policyversion.json new file mode 100644 index 00000000..dabde011 --- /dev/null +++ b/main/src/test/resources/policies/vDNS.policy.operational.no.policyversion.json @@ -0,0 +1,4 @@ +{ + "policy-id" : "operational.scaleout", + "content" : "controlLoop%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20version%3A%202.0.0%0A%20%20%20%20%20%20%20%20%20%20%20%20%20controlLoopName%3A%20ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3%0A%20%20%20%20%20%20%20%20%20%20%20%20%20trigger_policy%3A%20unique-policy-id-1-scale-up%0A%20%20%20%20%20%20%20%20%20%20%20%20%20timeout%3A%201200%0A%20%20%20%20%20%20%20%20%20%20%20%20%20abatement%3A%20false%0A%20%20%20%20%20%20%20%20%20%20%20policies%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20-%20id%3A%20unique-policy-id-1-scale-up%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name%3A%20Create%20a%20new%20VF%20Module%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20description%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20actor%3A%20SO%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20recipe%3A%20VF%20Module%20Create%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20target%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type%3A%20VNF%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20payload%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20requestParameters%3A%20'%7B%22usePreload%22%3Atrue%2C%22userParams%22%3A%5B%5D%7D'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20configurationParameters%3A%20'%5B%7B%22ip-addr%22%3A%22%24.vf-module-topology.vf-module-parameters.param%5B9%5D%22%2C%22oam-ip-addr%22%3A%22%24.vf-module-topology.vf-module-parameters.param%5B16%5D%22%2C%22enabled%22%3A%22%24.vf-module-topology.vf-module-parameters.param%5B23%5D%22%7D%5D'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20retry%3A%200%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20timeout%3A%201200%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20success%3A%20final_success%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20failure%3A%20final_failure%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20failure_timeout%3A%20final_failure_timeout%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20failure_retries%3A%20final_failure_retries%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20failure_exception%3A%20final_failure_exception%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20failure_guard%3A%20final_failure_guard" +}
\ No newline at end of file diff --git a/main/src/test/resources/policies/vFirewall.policy.monitoring.input.tosca.v2.yaml b/main/src/test/resources/policies/vFirewall.policy.monitoring.input.tosca.v2.yaml new file mode 100644 index 00000000..d76dc53e --- /dev/null +++ b/main/src/test/resources/policies/vFirewall.policy.monitoring.input.tosca.v2.yaml @@ -0,0 +1,36 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +topology_template: + policies: + - + onap.vfirewall.tca: + type: onap.policies.monitoring.cdap.tca.hi.lo.app + version: 2.0.0 + metadata: + policy-id: onap.vfirewall.tca + properties: + tca_policy: + domain: measurementsForVfScaling + metricsPerEventName: + - + eventName: vLoadBalancer + controlLoopSchemaType: VNF + policyScope: "resource=vLoadBalancer;type=configuration" + policyName: "onap.vfirewall.tca" + policyVersion: "v0.0.1" + thresholds: + - + closedLoopControlName: "ControlLoop-vFirewall-d0a1dfc6-94f5-4fd4-a5b5-4630b438850a" + closedLoopEventStatus: ONSET + version: "1.0.2" + fieldPath: "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedBroadcastPacketsAccumulated" + thresholdValue: 500 + direction: LESS_OR_EQUAL + severity: MAJOR + - + closedLoopControlName: "ControlLoop-vFirewall-d0a1dfc6-94f5-4fd4-a5b5-4630b438850a" + closedLoopEventStatus: ONSET + version: "1.0.2" + fieldPath: "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedBroadcastPacketsAccumulated" + thresholdValue: 5000 + direction: GREATER_OR_EQUAL + severity: CRITICAL
\ No newline at end of file diff --git a/main/src/test/resources/policytypes/onap.policies.optimization.Resource.no.version.yaml b/main/src/test/resources/policytypes/onap.policies.optimization.Resource.no.version.yaml new file mode 100644 index 00000000..cab66238 --- /dev/null +++ b/main/src/test/resources/policytypes/onap.policies.optimization.Resource.no.version.yaml @@ -0,0 +1,22 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +policy_types: + onap.policies.optimization.Resource: + derived_from: onap.policies.Optimization + description: The base policy type for all policies that govern optimization for a Resource in a Service. + properties: + services: + description: One or more services that the policy applies to. + type: list + metadata: + matchable: true + required: true + entry_schema: + type: string + resources: + description: One or more VNF resources that the policy applies to. + type: list + metadata: + matchable: true + required: true + entry_schema: + type: string
\ No newline at end of file |