diff options
author | 2024-12-09 11:22:29 +0000 | |
---|---|---|
committer | 2024-12-10 18:33:49 +0000 | |
commit | 9c4745535aeb1e68e1a3c8fdda358dbcbb673362 (patch) | |
tree | 0e01214a546223d35a23cd7b932d208e389c1757 /policy-executor-stub/src | |
parent | f325ca432bae326cc279c85907543ccf3f45400c (diff) |
Policy Executor API Review Board Comments
- Implemented Guild review comments in API
- Updated Stub to reflect new API and 'support' all operations
- Updated production code to use new API
- Updated Semi-Integration Tests
Issue-ID: CPS-2479
Change-Id: Ibe307b0d859312b534009a384e9f71e1ea2affe0
Signed-off-by: ToineSiebelink <toine.siebelink@est.tech>
Diffstat (limited to 'policy-executor-stub/src')
2 files changed, 70 insertions, 80 deletions
diff --git a/policy-executor-stub/src/main/java/org/onap/cps/policyexecutor/stub/controller/PolicyExecutorStubController.java b/policy-executor-stub/src/main/java/org/onap/cps/policyexecutor/stub/controller/PolicyExecutorStubController.java index 88073c0a0f..aef27a6389 100644 --- a/policy-executor-stub/src/main/java/org/onap/cps/policyexecutor/stub/controller/PolicyExecutorStubController.java +++ b/policy-executor-stub/src/main/java/org/onap/cps/policyexecutor/stub/controller/PolicyExecutorStubController.java @@ -20,72 +20,66 @@ package org.onap.cps.policyexecutor.stub.controller; -import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.onap.cps.policyexecutor.stub.api.PolicyExecutorApi; -import org.onap.cps.policyexecutor.stub.model.NcmpDelete; -import org.onap.cps.policyexecutor.stub.model.PolicyExecutionRequest; -import org.onap.cps.policyexecutor.stub.model.PolicyExecutionResponse; -import org.onap.cps.policyexecutor.stub.model.Request; +import org.onap.cps.policyexecutor.stub.api.OperationPermissionApi; +import org.onap.cps.policyexecutor.stub.model.Operation; +import org.onap.cps.policyexecutor.stub.model.PermissionRequest; +import org.onap.cps.policyexecutor.stub.model.PermissionResponse; import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController +@RequestMapping("/operation-permission/v1") @RequiredArgsConstructor @Slf4j -public class PolicyExecutorStubController implements PolicyExecutorApi { +public class PolicyExecutorStubController implements OperationPermissionApi { private final Sleeper sleeper; - private final ObjectMapper objectMapper; private static final Pattern ERROR_CODE_PATTERN = Pattern.compile("(\\d{3})"); private int decisionCounter = 0; private static int slowResponseTimeInSeconds = 40; @Override - public ResponseEntity<PolicyExecutionResponse> executePolicyAction( - final String action, - final PolicyExecutionRequest policyExecutionRequest, - final String authorization) { - log.info("Stub Policy Executor Invoked (only supports 'delete' operations)"); - if (policyExecutionRequest.getRequests().isEmpty()) { + public ResponseEntity<PermissionResponse> initiatePermissionRequest(final String contentType, + final PermissionRequest permissionRequest, + final String accept, + final String authorization) { + log.info("Stub Policy Executor Invoked"); + if (permissionRequest.getOperations().isEmpty()) { return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } - final Request firstRequest = policyExecutionRequest.getRequests().iterator().next(); - log.info("1st Request Schema:{}", firstRequest.getSchema()); - if (firstRequest.getSchema().contains("ncmp-delete-schema:1.0.0")) { - return handleNcmpDeleteSchema(firstRequest); + final Operation firstOperation = permissionRequest.getOperations().iterator().next(); + log.info("1st Operation: {}", firstOperation.getOperation()); + if (!"delete".equals(firstOperation.getOperation()) && firstOperation.getChangeRequest() == null) { + log.warn("Change Request is required for " + firstOperation.getOperation() + " operations"); + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } - log.warn("This stub only supports 'delete' operations"); - return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + return handleOperation(firstOperation); } - private ResponseEntity<PolicyExecutionResponse> handleNcmpDeleteSchema(final Request request) { - final NcmpDelete ncmpDelete = objectMapper.convertValue(request.getData(), NcmpDelete.class); - - final String targetIdentifier = ncmpDelete.getTargetIdentifier(); - - if (targetIdentifier == null) { - return new ResponseEntity<>(HttpStatus.BAD_REQUEST); - } + private ResponseEntity<PermissionResponse> handleOperation(final Operation operation) { + final String targetIdentifier = operation.getTargetIdentifier(); final Matcher matcher = ERROR_CODE_PATTERN.matcher(targetIdentifier); if (matcher.find()) { final int errorCode = Integer.parseInt(matcher.group(1)); + log.warn("Stub is mocking an error response, code: " + errorCode); return new ResponseEntity<>(HttpStatusCode.valueOf(errorCode)); } return createPolicyExecutionResponse(targetIdentifier); } - private ResponseEntity<PolicyExecutionResponse> createPolicyExecutionResponse(final String targetIdentifier) { - final String decisionId = String.valueOf(++decisionCounter); - final String decision; + private ResponseEntity<PermissionResponse> createPolicyExecutionResponse(final String targetIdentifier) { + final String id = String.valueOf(++decisionCounter); + final String permissionResult; final String message; if (targetIdentifier.toLowerCase(Locale.getDefault()).contains("slow")) { try { @@ -96,17 +90,14 @@ public class PolicyExecutorStubController implements PolicyExecutorApi { } } if (targetIdentifier.toLowerCase(Locale.getDefault()).contains("cps-is-great")) { - decision = "allow"; + permissionResult = "allow"; message = "All good"; } else { - decision = "deny"; + permissionResult = "deny"; message = "Only FDNs containing 'cps-is-great' are allowed"; } - log.info("Decision: {} ({})", decision, message); - final PolicyExecutionResponse policyExecutionResponse = - new PolicyExecutionResponse(decisionId, decision, message); - - return ResponseEntity.ok(policyExecutionResponse); + log.info("Decision: {} ({})", permissionResult, message); + return ResponseEntity.ok(new PermissionResponse(id, permissionResult, message)); } } diff --git a/policy-executor-stub/src/test/groovy/org/onap/cps/policyexecutor/stub/controller/PolicyExecutorStubControllerSpec.groovy b/policy-executor-stub/src/test/groovy/org/onap/cps/policyexecutor/stub/controller/PolicyExecutorStubControllerSpec.groovy index 44460daa7e..75bd676b2f 100644 --- a/policy-executor-stub/src/test/groovy/org/onap/cps/policyexecutor/stub/controller/PolicyExecutorStubControllerSpec.groovy +++ b/policy-executor-stub/src/test/groovy/org/onap/cps/policyexecutor/stub/controller/PolicyExecutorStubControllerSpec.groovy @@ -21,10 +21,9 @@ package org.onap.cps.policyexecutor.stub.controller import com.fasterxml.jackson.databind.ObjectMapper -import org.onap.cps.policyexecutor.stub.model.NcmpDelete -import org.onap.cps.policyexecutor.stub.model.PolicyExecutionRequest -import org.onap.cps.policyexecutor.stub.model.PolicyExecutionResponse -import org.onap.cps.policyexecutor.stub.model.Request +import org.onap.cps.policyexecutor.stub.model.Operation +import org.onap.cps.policyexecutor.stub.model.PermissionRequest +import org.onap.cps.policyexecutor.stub.model.PermissionResponse import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest @@ -47,14 +46,14 @@ class PolicyExecutorStubControllerSpec extends Specification { @SpringBean Sleeper sleeper = Spy() - def url = '/policy-executor/api/v1/some-action' + def url = '/operation-permission/v1/permissions' def setup() { PolicyExecutorStubController.slowResponseTimeInSeconds = 1 } - def 'Execute policy action.'() { - given: 'a policy execution request with target: #targetIdentifier' + def 'Permission request with #targetIdentifier.'() { + given: 'a permission request with target: #targetIdentifier' def requestBody = createRequestBody(targetIdentifier) when: 'request is posted' def response = mockMvc.perform(post(url) @@ -66,19 +65,19 @@ class PolicyExecutorStubControllerSpec extends Specification { assert response.status == HttpStatus.OK.value() and: 'the response body has the expected decision details' def responseBody = response.contentAsString - def policyExecutionResponse = objectMapper.readValue(responseBody, PolicyExecutionResponse.class) - assert policyExecutionResponse.decisionId == expectedDecsisonId - assert policyExecutionResponse.decision == expectedDecision - assert policyExecutionResponse.message == expectedMessage + def permissionResponse = objectMapper.readValue(responseBody, PermissionResponse.class) + assert permissionResponse.id == expectedId + assert permissionResponse.permissionResult == expectedResult + assert permissionResponse.message == expectedMessage where: 'the following targets are used' - targetIdentifier || expectedDecsisonId | expectedDecision | expectedMessage - 'some fdn' || '1' | 'deny' | "Only FDNs containing 'cps-is-great' are allowed" - 'fdn with cps-is-great' || '2' | 'allow' | 'All good' - 'slow' || '3' | 'deny' | "Only FDNs containing 'cps-is-great' are allowed" + targetIdentifier || expectedId | expectedResult | expectedMessage + 'some fdn' || '1' | 'deny' | "Only FDNs containing 'cps-is-great' are allowed" + 'fdn with cps-is-great' || '2' | 'allow' | 'All good' + 'slow' || '3' | 'deny' | "Only FDNs containing 'cps-is-great' are allowed" } - def 'Execute policy action with a HTTP error code.'() { - given: 'a policy execution request with a target fdn with a 3-digit error code' + def 'Permission request with a HTTP error code.'() { + given: 'a permission request with a target fdn with a 3-digit error code' def requestBody = createRequestBody('target with error code 418') when: 'request is posted' def response = mockMvc.perform(post(url) @@ -90,8 +89,8 @@ class PolicyExecutorStubControllerSpec extends Specification { assert response.status == 418 } - def 'Execute policy action without authorization header.'() { - given: 'a valid policy execution request' + def 'Permission request without authorization header.'() { + given: 'a valid permission request' def requestBody = createRequestBody('some target') when: 'request is posted without authorization header' def response = mockMvc.perform(post(url) @@ -102,10 +101,10 @@ class PolicyExecutorStubControllerSpec extends Specification { assert response.status == HttpStatus.OK.value() } - def 'Execute policy action with no requests.'() { - given: 'a policy execution request' - def policyExecutionRequest = new PolicyExecutionRequest('some decision type', []) - def requestBody = objectMapper.writeValueAsString(policyExecutionRequest) + def 'Permission request with no operations.'() { + given: 'a permission request with no operations' + def permissionRequest = new PermissionRequest('some decision type', []) + def requestBody = objectMapper.writeValueAsString(permissionRequest) when: 'request is posted' def response = mockMvc.perform(post(url) .header('Authorization','some string') @@ -116,8 +115,8 @@ class PolicyExecutorStubControllerSpec extends Specification { assert response.status == HttpStatus.BAD_REQUEST.value() } - def 'Execute policy action with invalid json for request data.'() { - when: 'request is posted' + def 'Request with invalid json for request data.'() { + when: 'request with invalid json is posted' def response = mockMvc.perform(post(url) .header('Authorization','some string') .contentType(MediaType.APPLICATION_JSON) @@ -127,8 +126,8 @@ class PolicyExecutorStubControllerSpec extends Specification { assert response.status == HttpStatus.BAD_REQUEST.value() } - def 'Execute policy action with interrupted exception during slow response.'() { - given: 'a policy execution request with target: "slow"' + def 'Permission request with interrupted exception during slow response.'() { + given: 'a permission request with target: "slow" (stub will be slow)' def requestBody = createRequestBody('slow') sleeper.haveALittleRest(_) >> { throw new InterruptedException() } when: 'request is posted' @@ -140,9 +139,9 @@ class PolicyExecutorStubControllerSpec extends Specification { noExceptionThrown() } - def 'Execute policy action with missing or invalid attributes.'() { - given: 'a policy execution request with decisionType=#decisionType, schema=#schema, targetIdentifier=#targetIdentifier' - def requestBody = createRequestBody(decisionType, schema, targetIdentifier) + def 'Permission request with missing or invalid attributes.'() { + given: 'Permission request with operation=#operation and targetIdentifier=#targetIdentifier' + def requestBody = createRequestBody(operation, targetIdentifier, changeRequest) when: 'request is posted' def response = mockMvc.perform(post(url) .header('Authorization','something') @@ -152,22 +151,22 @@ class PolicyExecutorStubControllerSpec extends Specification { then: 'response status as expected' assert response.status == expectedStatus.value() where: 'following parameters are used' - decisionType | schema | targetIdentifier || expectedStatus - 'something' | 'ncmp-delete-schema:1.0.0' | 'something' || HttpStatus.OK - null | 'ncmp-delete-schema:1.0.0' | 'something' || HttpStatus.BAD_REQUEST - 'something' | 'other schema' | 'something' || HttpStatus.BAD_REQUEST - 'something' | 'ncmp-delete-schema:1.0.0' | null || HttpStatus.BAD_REQUEST + operation | targetIdentifier | changeRequest || expectedStatus + 'delete' | 'something' | null || HttpStatus.OK + 'other' | 'something' | '{}' || HttpStatus.OK + 'delete' | null | null || HttpStatus.BAD_REQUEST + 'other' | 'something' | null || HttpStatus.BAD_REQUEST } - def createRequestBody(decisionType, schema, targetIdentifier) { - def ncmpDelete = new NcmpDelete(targetIdentifier: targetIdentifier) - def request = new Request(schema, ncmpDelete) - def policyExecutionRequest = new PolicyExecutionRequest(decisionType, [request]) - return objectMapper.writeValueAsString(policyExecutionRequest) + def createRequestBody(targetIdentifier) { + return createRequestBody('delete', targetIdentifier, '{}') } - def createRequestBody(targetIdentifier) { - return createRequestBody('some decision type', 'ncmp-delete-schema:1.0.0', targetIdentifier) + def createRequestBody(operationName, targetIdentifier, changeRequest) { + def operation = new Operation(operationName, targetIdentifier) + operation.setChangeRequest(changeRequest) + def permissionRequest = new PermissionRequest('cm-legacy', [operation]) + return objectMapper.writeValueAsString(permissionRequest) } } |