91348a086dced1af6719af0a454be0f5db34d3a4
[cps.git] /
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2024-2025 OpenInfra Foundation Europe. All rights reserved.
4  *  ================================================================================
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *  SPDX-License-Identifier: Apache-2.0
18  *  ============LICENSE_END=========================================================
19  */
20
21 package org.onap.cps.policyexecutor.stub.controller;
22
23 import com.fasterxml.jackson.core.JsonProcessingException;
24 import com.fasterxml.jackson.databind.ObjectMapper;
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
27 import lombok.RequiredArgsConstructor;
28 import lombok.extern.slf4j.Slf4j;
29 import org.onap.cps.policyexecutor.stub.api.OperationPermissionApi;
30 import org.onap.cps.policyexecutor.stub.model.Operation;
31 import org.onap.cps.policyexecutor.stub.model.PermissionRequest;
32 import org.onap.cps.policyexecutor.stub.model.PermissionResponse;
33 import org.springframework.http.HttpStatus;
34 import org.springframework.http.HttpStatusCode;
35 import org.springframework.http.ResponseEntity;
36 import org.springframework.web.bind.annotation.RequestMapping;
37 import org.springframework.web.bind.annotation.RestController;
38
39 @RestController
40 @RequestMapping("/operation-permission/v1")
41 @RequiredArgsConstructor
42 @Slf4j
43 public class PolicyExecutorStubController implements OperationPermissionApi {
44
45     private final Sleeper sleeper;
46     private final ObjectMapper objectMapper;
47
48     private static final Pattern PATTERN_SIMULATION = Pattern.compile("policySimulation=(\\w+_\\w+)");
49     private static final Pattern PATTERN_HTTP_ERROR = Pattern.compile("httpError_(\\d{3})");
50     private static final Pattern PATTERN_SLOW_RESPONSE = Pattern.compile("slowResponse_(\\d{1,3})");
51     private static final Pattern PATTERN_POLICY_RESPONSE = Pattern.compile("policyResponse_(\\w+)");
52
53     private int decisionCounter = 0;
54
55     @Override
56     public ResponseEntity<PermissionResponse> initiatePermissionRequest(final String contentType,
57                                                                         final PermissionRequest permissionRequest,
58                                                                         final String accept,
59                                                                         final String authorization) {
60         log.info("Stub Policy Executor Invoked");
61         log.info("Permission Request: {}", formatPermissionRequest(permissionRequest));
62         if (permissionRequest.getOperations().isEmpty()) {
63             return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
64         }
65         final Operation firstOperation = permissionRequest.getOperations().iterator().next();
66         log.info("1st Operation: {} for resource: {}", firstOperation.getOperation(),
67                                                        firstOperation.getResourceIdentifier());
68         if (!"delete".equals(firstOperation.getOperation()) && firstOperation.getChangeRequest() == null) {
69             log.warn("Change Request is required for {} operations", firstOperation.getOperation());
70             return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
71         }
72         return createPolicyExecutionResponse(firstOperation.getResourceIdentifier());
73     }
74
75     private ResponseEntity<PermissionResponse> createPolicyExecutionResponse(final String resourceIdentifier) {
76         final String id = String.valueOf(++decisionCounter);
77         String permissionResult = "allow";
78         String message = "all good";
79         Matcher matcher = PATTERN_SIMULATION.matcher(resourceIdentifier);
80         if (matcher.find()) {
81             final String simulation = matcher.group(1);
82             matcher = PATTERN_SLOW_RESPONSE.matcher(simulation);
83             if (matcher.matches()) {
84                 try {
85                     final int slowResponseTimeInSeconds = Integer.parseInt(matcher.group(1));
86                     sleeper.haveALittleRest(slowResponseTimeInSeconds);
87                 } catch (final InterruptedException e) {
88                     log.trace("Sleep interrupted, re-interrupting the thread");
89                     Thread.currentThread().interrupt(); // Re-interrupt the thread
90                 }
91             }
92             matcher = PATTERN_HTTP_ERROR.matcher(simulation);
93             if (matcher.matches()) {
94                 final int errorCode = Integer.parseInt(matcher.group(1));
95                 log.warn("Stub is mocking an error response, code: {}", errorCode);
96                 return new ResponseEntity<>(HttpStatusCode.valueOf(errorCode));
97             }
98             matcher = PATTERN_POLICY_RESPONSE.matcher(simulation);
99             if (matcher.matches()) {
100                 permissionResult = matcher.group(1);
101                 message = "Stub is mocking a policy response: " + permissionResult;
102             }
103         }
104         log.info("Decision: {} ({})", permissionResult, message);
105         return ResponseEntity.ok(new PermissionResponse(id, permissionResult, message));
106     }
107
108     private String formatPermissionRequest(final PermissionRequest permissionRequest)  {
109         try {
110             return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(permissionRequest);
111         } catch (final JsonProcessingException jsonProcessingException) {
112             log.error("Error while formatting permission request", jsonProcessingException);
113             return "invalid json";
114         }
115     }
116
117 }