--- /dev/null
+/* Copyright (c) 2019 AT&T Intellectual Property. #\r
+# #\r
+# Licensed under the Apache License, Version 2.0 (the "License"); #\r
+# you may not use this file except in compliance with the License. #\r
+# You may obtain a copy of the License at #\r
+# #\r
+# http://www.apache.org/licenses/LICENSE-2.0 #\r
+# #\r
+# Unless required by applicable law or agreed to in writing, software #\r
+# distributed under the License is distributed on an "AS IS" BASIS, #\r
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #\r
+# See the License for the specific language governing permissions and #\r
+# limitations under the License. #\r
+##############################################################################*/\r
+\r
+\r
+package org.oran.otf.api.service.impl;\r
+\r
+import org.oran.otf.api.Utilities;\r
+import org.oran.otf.api.handler.CamundaProcessDeploymentHandler;\r
+import org.oran.otf.api.service.TestStrategyService;\r
+import org.oran.otf.common.model.TestDefinition;\r
+import org.oran.otf.common.model.User;\r
+import org.oran.otf.common.model.local.BpmnInstance;\r
+import org.oran.otf.common.model.local.DeployTestStrategyRequest;\r
+import org.oran.otf.common.model.local.OTFApiResponse;\r
+import org.oran.otf.common.repository.GroupRepository;\r
+import org.oran.otf.common.repository.TestDefinitionRepository;\r
+import org.oran.otf.common.repository.UserRepository;\r
+import org.oran.otf.common.utility.http.ResponseUtility;\r
+import com.fasterxml.jackson.databind.ObjectMapper;\r
+import io.swagger.v3.oas.annotations.Hidden;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.util.Base64;\r
+import java.util.Optional;\r
+import javax.ws.rs.core.MediaType;\r
+import javax.ws.rs.core.Response;\r
+import org.apache.http.HttpResponse;\r
+import org.apache.http.conn.HttpHostConnectException;\r
+import org.apache.http.util.EntityUtils;\r
+import org.bson.types.ObjectId;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.stereotype.Service;\r
+\r
+@Service\r
+@Hidden\r
+public class TestStrategyServiceImpl implements TestStrategyService {\r
+\r
+ private static final Logger logger = LoggerFactory.getLogger(TestStrategyServiceImpl.class);\r
+\r
+ @Autowired private TestDefinitionRepository testDefinitionRepository;\r
+\r
+ @Autowired private UserRepository userRepository;\r
+\r
+ @Autowired private CamundaProcessDeploymentHandler camundaProcessDeploymentHandler;\r
+\r
+ @Autowired private GroupRepository groupRepository;\r
+\r
+ public Response deployTestStrategy(\r
+ InputStream bpmn,\r
+ InputStream compressedResources,\r
+ String testDefinitionId,\r
+ String testDefinitionDeployerId,\r
+ String definitionId,\r
+ String authorization) {\r
+ if (bpmn == null)\r
+ return Utilities.Http.BuildResponse.badRequestWithMessage(\r
+ "BPMN input stream cannot be null.");\r
+\r
+ // Decode the authorization header.\r
+ byte[] decodedAuthorization = Base64.getDecoder().decode(authorization.replace("Basic ", ""));\r
+ String credentials = new String(decodedAuthorization);\r
+ String[] credentialsArray = credentials.split(":");\r
+\r
+ /* Check if the request came from the system specified mechanized identifier. The request goes through AAF\r
+ * authorization before reaching this code, therefore, assume the headers aren't spoofed. */\r
+ if (!credentialsArray[0].equals(System.getenv("AAF_ID")))\r
+ return Utilities.Http.BuildResponse.badRequestWithMessage(\r
+ "Unauthorized to use this service.");\r
+\r
+ // Map to a POJO model2.\r
+ ObjectId _testDefinitionDeployerId = null;\r
+ ObjectId _testDefinitionId = null;\r
+\r
+ if (testDefinitionDeployerId != null && ObjectId.isValid(testDefinitionDeployerId))\r
+ _testDefinitionDeployerId = new ObjectId(testDefinitionDeployerId);\r
+ if (testDefinitionId != null && ObjectId.isValid(testDefinitionId))\r
+ _testDefinitionId = new ObjectId(testDefinitionId);\r
+\r
+ DeployTestStrategyRequest request =\r
+ new DeployTestStrategyRequest(_testDefinitionDeployerId, _testDefinitionId, definitionId);\r
+\r
+ // String bpmnContents = null;\r
+ // try (final Reader reader = new InputStreamReader(bpmn)) {\r
+ // bpmnContents = CharStreams.toString(reader);\r
+ // } catch (Exception e) {\r
+ // e.printStackTrace();\r
+ // }\r
+\r
+ // Check if the request actually contains a bpmn string.\r
+ // try {\r
+ // if (bpmnContents == null || bpmnContents.trim().length() == 0)\r
+ // return Utilities.Http.BuildResponse.badRequestWithMessage("BPMN contents are null.");\r
+ // } catch (Exception e) {\r
+ // logger.error(Utilities.getStackTrace(e));\r
+ // }\r
+\r
+ // If a test definition id is supplied, the request intends to update an existing test\r
+ // definition.\r
+ if (request.getTestDefinitionId() != null) {\r
+ // Check if the test definition exists in the database.\r
+ Optional<TestDefinition> testDefinitionOptional =\r
+ testDefinitionRepository.findById(request.getTestDefinitionId().toString());\r
+\r
+ if (!testDefinitionOptional.isPresent())\r
+ return Utilities.Http.BuildResponse.badRequestWithMessage(\r
+ String.format("Test definition (%s) was not found.", request.getTestDefinitionId()));\r
+\r
+ // Check if a user to update the definition was supplied.\r
+ if (request.getTestDefinitionDeployerId() == null)\r
+ return Utilities.Http.BuildResponse.badRequestWithMessage(\r
+ "Must specify testDefinitionDeployerId.");\r
+\r
+ // Check if the user requesting to update the definition is the user who originally created\r
+ // the definition.\r
+ TestDefinition testDefinition = testDefinitionOptional.get();\r
+\r
+ if (!testDefinition\r
+ .getCreatedBy()\r
+ .toString()\r
+ .equals(request.getTestDefinitionDeployerId().toString()))\r
+ return Utilities.Http.BuildResponse.badRequestWithMessage(\r
+ String.format(\r
+ "User (%s) is not authorized to update this test definition.",\r
+ request.getTestDefinitionDeployerId()));\r
+\r
+ // Check if the version to deploy already exists\r
+ for (BpmnInstance bpmnInstance : testDefinition.getBpmnInstances()) {\r
+ if (bpmnInstance.getProcessDefinitionId().equalsIgnoreCase(request.getDefinitionId()))\r
+ return Utilities.Http.BuildResponse.badRequestWithMessage(\r
+ String.format(\r
+ "A deployment with the definitionId %s already exists.",\r
+ request.getDefinitionId()));\r
+ }\r
+ }\r
+\r
+ // Make the deployment request to Camunda. Relay the response received by Camunda.\r
+ return camundaProcessDeploymentHandler.start(bpmn, compressedResources);\r
+ }\r
+\r
+ public Response deleteByDeploymentId(String deploymentId, String authorization) {\r
+ User user = Utilities.findUserByAuthHeader(authorization, userRepository);\r
+ if (!isAuthorized(authorization)) {\r
+ return Utilities.Http.BuildResponse.unauthorized();\r
+ }\r
+\r
+ String url =\r
+ String.format(\r
+ "%s:%s/%s/%s",\r
+ System.getenv("otf.camunda.host"),\r
+ System.getenv("otf.camunda.port"),\r
+ System.getenv("otf.camunda.deploymentDeletionUri"),\r
+ deploymentId);\r
+\r
+ try {\r
+ HttpResponse res = Utilities.Http.httpDeleteAAF(url);\r
+ String resStr = EntityUtils.toString(res.getEntity());\r
+ int status = res.getStatusLine().getStatusCode();\r
+ return Response.status(status)\r
+ .type(MediaType.APPLICATION_JSON)\r
+ .entity(new OTFApiResponse(status, resStr))\r
+ .build();\r
+\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ return Utilities.Http.BuildResponse.internalServerError();\r
+ }\r
+ }\r
+\r
+ public Response deleteByTestDefinitionId(String testDefinitionId, String authorization) {\r
+ User user = Utilities.findUserByAuthHeader(authorization, userRepository);\r
+ if (!isAuthorized(authorization)) {\r
+ return Utilities.Http.BuildResponse.unauthorizedWithMessage("Authorization headers not set.");\r
+ }\r
+\r
+ String url =\r
+ String.format(\r
+ "%s:%s/%s/%s",\r
+ System.getenv("otf.camunda.host"),\r
+ System.getenv("otf.camunda.port"),\r
+ System.getenv("otf.camunda.testDefinitionDeletionUri"),\r
+ testDefinitionId);\r
+\r
+ try {\r
+ HttpResponse res = Utilities.Http.httpDeleteAAF(url);\r
+ String resStr = EntityUtils.toString(res.getEntity());\r
+ int status = res.getStatusLine().getStatusCode();\r
+ return Response.status(status)\r
+ .type(MediaType.APPLICATION_JSON)\r
+ .entity(new OTFApiResponse(status, resStr))\r
+ .build();\r
+ } catch (HttpHostConnectException e) {\r
+ return ResponseUtility.Build.serviceUnavailableWithMessage(e.getMessage());\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ return Utilities.Http.BuildResponse.internalServerError();\r
+ }\r
+ }\r
+\r
+ private boolean isAuthorized(String authorization) {\r
+ User user = Utilities.findUserByAuthHeader(authorization, userRepository);\r
+ return (user.getEmail().equalsIgnoreCase("email@localhost")\r
+ || user.getEmail().equalsIgnoreCase("email@localhost"));\r
+ }\r
+\r
+ private DeployTestStrategyRequest mapToDeployTestStrategyRequest(String body) {\r
+ ObjectMapper mapper = new ObjectMapper();\r
+ try {\r
+ return mapper.readValue(body, DeployTestStrategyRequest.class); // Perform the mapping\r
+ } catch (IOException e) { // Indicates an unknown request body\r
+ logger.error(e.getMessage());\r
+ return null;\r
+ }\r
+ }\r
+}\r