1 /* Copyright (c) 2019 AT&T Intellectual Property. #
\r
3 # Licensed under the Apache License, Version 2.0 (the "License"); #
\r
4 # you may not use this file except in compliance with the License. #
\r
5 # You may obtain a copy of the License at #
\r
7 # http://www.apache.org/licenses/LICENSE-2.0 #
\r
9 # Unless required by applicable law or agreed to in writing, software #
\r
10 # distributed under the License is distributed on an "AS IS" BASIS, #
\r
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
\r
12 # See the License for the specific language governing permissions and #
\r
13 # limitations under the License. #
\r
14 ##############################################################################*/
\r
17 package org.oran.otf.api.service.impl;
\r
19 import org.oran.otf.api.Utilities;
\r
20 import org.oran.otf.api.handler.CamundaProcessDeploymentHandler;
\r
21 import org.oran.otf.api.service.TestStrategyService;
\r
22 import org.oran.otf.common.model.TestDefinition;
\r
23 import org.oran.otf.common.model.User;
\r
24 import org.oran.otf.common.model.local.BpmnInstance;
\r
25 import org.oran.otf.common.model.local.DeployTestStrategyRequest;
\r
26 import org.oran.otf.common.model.local.OTFApiResponse;
\r
27 import org.oran.otf.common.repository.GroupRepository;
\r
28 import org.oran.otf.common.repository.TestDefinitionRepository;
\r
29 import org.oran.otf.common.repository.UserRepository;
\r
30 import org.oran.otf.common.utility.http.ResponseUtility;
\r
31 import com.fasterxml.jackson.databind.ObjectMapper;
\r
32 import io.swagger.v3.oas.annotations.Hidden;
\r
33 import java.io.IOException;
\r
34 import java.io.InputStream;
\r
35 import java.util.Base64;
\r
36 import java.util.Optional;
\r
37 import javax.ws.rs.core.MediaType;
\r
38 import javax.ws.rs.core.Response;
\r
39 import org.apache.http.HttpResponse;
\r
40 import org.apache.http.conn.HttpHostConnectException;
\r
41 import org.apache.http.util.EntityUtils;
\r
42 import org.bson.types.ObjectId;
\r
43 import org.slf4j.Logger;
\r
44 import org.slf4j.LoggerFactory;
\r
45 import org.springframework.beans.factory.annotation.Autowired;
\r
46 import org.springframework.stereotype.Service;
\r
50 public class TestStrategyServiceImpl implements TestStrategyService {
\r
52 private static final Logger logger = LoggerFactory.getLogger(TestStrategyServiceImpl.class);
\r
54 @Autowired private TestDefinitionRepository testDefinitionRepository;
\r
56 @Autowired private UserRepository userRepository;
\r
58 @Autowired private CamundaProcessDeploymentHandler camundaProcessDeploymentHandler;
\r
60 @Autowired private GroupRepository groupRepository;
\r
62 public Response deployTestStrategy(
\r
64 InputStream compressedResources,
\r
65 String testDefinitionId,
\r
66 String testDefinitionDeployerId,
\r
67 String definitionId,
\r
68 String authorization) {
\r
70 return Utilities.Http.BuildResponse.badRequestWithMessage(
\r
71 "BPMN input stream cannot be null.");
\r
73 // Decode the authorization header.
\r
74 byte[] decodedAuthorization = Base64.getDecoder().decode(authorization.replace("Basic ", ""));
\r
75 String credentials = new String(decodedAuthorization);
\r
76 String[] credentialsArray = credentials.split(":");
\r
78 /* Check if the request came from the system specified mechanized identifier. The request goes through AAF
\r
79 * authorization before reaching this code, therefore, assume the headers aren't spoofed. */
\r
80 if (!credentialsArray[0].equals(System.getenv("AAF_ID")))
\r
81 return Utilities.Http.BuildResponse.badRequestWithMessage(
\r
82 "Unauthorized to use this service.");
\r
84 // Map to a POJO model2.
\r
85 ObjectId _testDefinitionDeployerId = null;
\r
86 ObjectId _testDefinitionId = null;
\r
88 if (testDefinitionDeployerId != null && ObjectId.isValid(testDefinitionDeployerId))
\r
89 _testDefinitionDeployerId = new ObjectId(testDefinitionDeployerId);
\r
90 if (testDefinitionId != null && ObjectId.isValid(testDefinitionId))
\r
91 _testDefinitionId = new ObjectId(testDefinitionId);
\r
93 DeployTestStrategyRequest request =
\r
94 new DeployTestStrategyRequest(_testDefinitionDeployerId, _testDefinitionId, definitionId);
\r
96 // String bpmnContents = null;
\r
97 // try (final Reader reader = new InputStreamReader(bpmn)) {
\r
98 // bpmnContents = CharStreams.toString(reader);
\r
99 // } catch (Exception e) {
\r
100 // e.printStackTrace();
\r
103 // Check if the request actually contains a bpmn string.
\r
105 // if (bpmnContents == null || bpmnContents.trim().length() == 0)
\r
106 // return Utilities.Http.BuildResponse.badRequestWithMessage("BPMN contents are null.");
\r
107 // } catch (Exception e) {
\r
108 // logger.error(Utilities.getStackTrace(e));
\r
111 // If a test definition id is supplied, the request intends to updatean existing test
\r
113 if (request.getTestDefinitionId() != null) {
\r
114 // Check if the test definition exists in the database.
\r
115 Optional<TestDefinition> testDefinitionOptional =
\r
116 testDefinitionRepository.findById(request.getTestDefinitionId().toString());
\r
118 if (!testDefinitionOptional.isPresent())
\r
119 return Utilities.Http.BuildResponse.badRequestWithMessage(
\r
120 String.format("Test definition (%s) was not found.", request.getTestDefinitionId()));
\r
122 // Check if a user to update the definition was supplied.
\r
123 if (request.getTestDefinitionDeployerId() == null)
\r
124 return Utilities.Http.BuildResponse.badRequestWithMessage(
\r
125 "Must specify testDefinitionDeployerId.");
\r
127 // Check if the user requesting to update the definition is the user who originally created
\r
129 TestDefinition testDefinition = testDefinitionOptional.get();
\r
131 if (!testDefinition
\r
134 .equals(request.getTestDefinitionDeployerId().toString()))
\r
135 return Utilities.Http.BuildResponse.badRequestWithMessage(
\r
137 "User (%s) is not authorized to update this test definition.",
\r
138 request.getTestDefinitionDeployerId()));
\r
140 // Check if the version to deploy already exists
\r
141 for (BpmnInstance bpmnInstance : testDefinition.getBpmnInstances()) {
\r
142 if (bpmnInstance.getProcessDefinitionId().equalsIgnoreCase(request.getDefinitionId()))
\r
143 return Utilities.Http.BuildResponse.badRequestWithMessage(
\r
145 "A deployment with the definitionId %s already exists.",
\r
146 request.getDefinitionId()));
\r
150 // Make the deployment request to Camunda. Relay the response received by Camunda.
\r
151 return camundaProcessDeploymentHandler.start(bpmn, compressedResources);
\r
154 public Response deleteByDeploymentId(String deploymentId, String authorization) {
\r
155 User user = Utilities.findUserByAuthHeader(authorization, userRepository);
\r
156 if (!isAuthorized(authorization)) {
\r
157 return Utilities.Http.BuildResponse.unauthorized();
\r
163 System.getenv("otf.camunda.host"),
\r
164 System.getenv("otf.camunda.port"),
\r
165 System.getenv("otf.camunda.deploymentDeletionUri"),
\r
169 HttpResponse res = Utilities.Http.httpDeleteAAF(url);
\r
170 String resStr = EntityUtils.toString(res.getEntity());
\r
171 int status = res.getStatusLine().getStatusCode();
\r
172 return Response.status(status)
\r
173 .type(MediaType.APPLICATION_JSON)
\r
174 .entity(new OTFApiResponse(status, resStr))
\r
177 } catch (Exception e) {
\r
178 e.printStackTrace();
\r
179 return Utilities.Http.BuildResponse.internalServerError();
\r
183 public Response deleteByTestDefinitionId(String testDefinitionId, String authorization) {
\r
184 User user = Utilities.findUserByAuthHeader(authorization, userRepository);
\r
185 if (!isAuthorized(authorization)) {
\r
186 return Utilities.Http.BuildResponse.unauthorizedWithMessage("Authorization headers not set.");
\r
192 System.getenv("otf.camunda.host"),
\r
193 System.getenv("otf.camunda.port"),
\r
194 System.getenv("otf.camunda.testDefinitionDeletionUri"),
\r
198 HttpResponse res = Utilities.Http.httpDeleteAAF(url);
\r
199 String resStr = EntityUtils.toString(res.getEntity());
\r
200 int status = res.getStatusLine().getStatusCode();
\r
201 return Response.status(status)
\r
202 .type(MediaType.APPLICATION_JSON)
\r
203 .entity(new OTFApiResponse(status, resStr))
\r
205 } catch (HttpHostConnectException e) {
\r
206 return ResponseUtility.Build.serviceUnavailableWithMessage(e.getMessage());
\r
207 } catch (Exception e) {
\r
208 e.printStackTrace();
\r
209 return Utilities.Http.BuildResponse.internalServerError();
\r
213 private boolean isAuthorized(String authorization) {
\r
214 User user = Utilities.findUserByAuthHeader(authorization, userRepository);
\r
215 return (user.getEmail().equalsIgnoreCase(System.getenv("AAF_ID")));
\r
218 private DeployTestStrategyRequest mapToDeployTestStrategyRequest(String body) {
\r
219 ObjectMapper mapper = new ObjectMapper();
\r
221 return mapper.readValue(body, DeployTestStrategyRequest.class); // Perform the mapping
\r
222 } catch (IOException e) { // Indicates an unknown request body
\r
223 logger.error(e.getMessage());
\r