2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.mso.apihandlerinfra.tenantisolation;
24 import java.util.HashMap;
26 import javax.ws.rs.Consumes;
27 import javax.ws.rs.POST;
28 import javax.ws.rs.Path;
29 import javax.ws.rs.PathParam;
30 import javax.ws.rs.Produces;
31 import javax.ws.rs.core.MediaType;
32 import javax.ws.rs.core.Response;
34 import org.apache.http.HttpStatus;
35 import com.fasterxml.jackson.databind.ObjectMapper;
36 import org.openecomp.mso.apihandler.common.ErrorNumbers;
37 import org.openecomp.mso.apihandlerinfra.Constants;
38 import org.openecomp.mso.apihandlerinfra.MsoException;
39 import org.openecomp.mso.apihandlerinfra.Status;
40 import org.openecomp.mso.apihandlerinfra.tenantisolationbeans.Action;
41 import org.openecomp.mso.apihandlerinfra.tenantisolationbeans.OperationalEnvironment;
42 import org.openecomp.mso.apihandlerinfra.tenantisolationbeans.RequestReferences;
43 import org.openecomp.mso.apihandlerinfra.tenantisolationbeans.TenantSyncResponse;
44 import org.openecomp.mso.logger.MessageEnum;
45 import org.openecomp.mso.logger.MsoLogger;
46 import org.openecomp.mso.requestsdb.InfraActiveRequests;
47 import org.openecomp.mso.requestsdb.RequestsDatabase;
48 import org.openecomp.mso.utils.UUIDChecker;
50 import com.wordnik.swagger.annotations.Api;
51 import com.wordnik.swagger.annotations.ApiOperation;
53 @Path("/cloudResources")
54 @Api(value="/cloudResources",description="API Requests for cloud resources - Tenant Isolation")
55 public class CloudOrchestration {
57 private static MsoLogger msoLogger = MsoLogger.getMsoLogger (MsoLogger.Catalog.APIH);
58 private TenantIsolationRunnable tenantIsolation = null;
59 private TenantIsolationRequest tenantIsolationRequest = null;
60 private RequestsDatabase requestsDatabase = null;
63 @Path("/{version:[vV][1]}/operationalEnvironments")
64 @Consumes(MediaType.APPLICATION_JSON)
65 @Produces(MediaType.APPLICATION_JSON)
66 @ApiOperation(value="Create an Operational Environment",response=Response.class)
67 public Response createOperationEnvironment(String request, @PathParam("version") String version) {
68 msoLogger.debug("Received request to Create Operational Environment");
69 return cloudOrchestration(request, Action.create, null, version);
73 @Path("/{version:[vV][1]}/operationalEnvironments/{operationalEnvironmentId}/activate")
74 @Consumes(MediaType.APPLICATION_JSON)
75 @Produces(MediaType.APPLICATION_JSON)
76 @ApiOperation(value="Activate an Operational Environment",response=Response.class)
77 public Response activateOperationEnvironment(String request, @PathParam("version") String version, @PathParam("operationalEnvironmentId") String operationalEnvironmentId) {
78 msoLogger.debug("Received request to Activate an Operational Environment");
79 HashMap<String, String> instanceIdMap = new HashMap<String,String>();
80 instanceIdMap.put("operationalEnvironmentId", operationalEnvironmentId);
81 return cloudOrchestration(request, Action.activate, instanceIdMap, version);
85 @Path("/{version:[vV][1]}/operationalEnvironments/{operationalEnvironmentId}/deactivate")
86 @Consumes(MediaType.APPLICATION_JSON)
87 @Produces(MediaType.APPLICATION_JSON)
88 @ApiOperation(value="Deactivate an Operational Environment",response=Response.class)
89 public Response deactivateOperationEnvironment(String request, @PathParam("version") String version, @PathParam("operationalEnvironmentId") String operationalEnvironmentId) {
90 msoLogger.debug("Received request to Deactivate an Operational Environment");
91 HashMap<String, String> instanceIdMap = new HashMap<String,String>();
92 instanceIdMap.put("operationalEnvironmentId", operationalEnvironmentId);
93 return cloudOrchestration(request, Action.deactivate, instanceIdMap, version);
97 private Response cloudOrchestration(String requestJSON, Action action, HashMap<String, String> instanceIdMap, String version) {
98 String requestId = UUIDChecker.generateUUID(msoLogger);
99 long startTime = System.currentTimeMillis ();
100 CloudOrchestrationRequest cor = null;
101 Response response = null;
102 getTenantIsolationRequest().setRequestId(requestId);
105 cor = convertJsonToCloudOrchestrationRequest(requestJSON, action, startTime, cor);
106 } catch(Exception e) {
107 response = getTenantIsolationRequest().buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
108 MsoException.ServiceException,
109 "Mapping of request to JSON object failed. " + e.getMessage(),
110 ErrorNumbers.SVC_BAD_PARAMETER,
112 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
117 getTenantIsolationRequest().parse(cor, instanceIdMap, action);
118 } catch(Exception e) {
119 msoLogger.debug ("Validation failed: ", e);
120 if (getTenantIsolationRequest().getRequestId () != null) {
121 msoLogger.debug ("Logging failed message to the database");
122 getTenantIsolationRequest().createRequestRecord (Status.FAILED, action);
124 response = getTenantIsolationRequest().buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
125 MsoException.ServiceException,
126 "Error parsing request. " + e.getMessage(),
127 ErrorNumbers.SVC_BAD_PARAMETER, null);
128 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
132 String instanceName = cor.getRequestDetails().getRequestInfo().getInstanceName();
133 String resourceType = cor.getRequestDetails().getRequestInfo().getResourceType().name();
134 InfraActiveRequests dup = null;
135 String messageAppend = null;
137 dup = duplicateCheck(action, instanceIdMap, startTime, instanceName, resourceType);
140 messageAppend = "already has a request being worked with a status of " + dup.getRequestStatus() + " (RequestId - " + dup.getRequestId() + ").";
142 } catch(Exception e) {
143 response = getTenantIsolationRequest().buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
144 MsoException.ServiceException,
146 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR,
148 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
153 if(dup == null && (Action.activate.equals(action) || Action.deactivate.equals(action))) {
154 dup = getRequestsDatabase().checkVnfIdStatus(cor.getOperationalEnvironmentId());
156 messageAppend = "OperationalEnvironmentId is not COMPLETED.";
159 } catch(Exception e) {
160 response = getTenantIsolationRequest().buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
161 MsoException.ServiceException,
163 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR,
165 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
170 String instance = null;
171 if(instanceName != null){
172 instance = instanceName;
174 instance = instanceIdMap.get(resourceType + "InstanceId");
176 String dupMessage = "Error: Locked instance - This " + resourceType + " (" + instance + ") " + messageAppend + " The existing request must finish or be cleaned up before proceeding.";
178 response = getTenantIsolationRequest().buildServiceErrorResponse(HttpStatus.SC_CONFLICT,
179 MsoException.ServiceException,
181 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR,
184 msoLogger.warn (MessageEnum.APIH_DUPLICATE_FOUND, dupMessage, "", "", MsoLogger.ErrorCode.SchemaError, dupMessage);
185 getTenantIsolationRequest().createRequestRecord (Status.FAILED, action);
186 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, dupMessage);
187 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
191 String instanceId = null;
193 if(instanceIdMap != null && instanceIdMap.get("operationalEnvironmentId") != null) {
194 instanceId = instanceIdMap.get("operationalEnvironmentId");
196 instanceId = UUIDChecker.generateUUID(msoLogger);
197 getTenantIsolationRequest().setOperationalEnvironmentId(instanceId);
198 cor.setOperationalEnvironmentId(instanceId);
201 msoLogger.debug("Creating record in Request DB");
202 getTenantIsolationRequest().createRequestRecord(Status.IN_PROGRESS, action);
203 } catch(Exception e) {
204 response = getTenantIsolationRequest().buildServiceErrorResponse (HttpStatus.SC_INTERNAL_SERVER_ERROR,
205 MsoException.ServiceException,
206 "Exception while creating record in DB " + e.getMessage(),
207 ErrorNumbers.SVC_BAD_PARAMETER,
209 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
214 OperationalEnvironment opEnv = cor.getRequestDetails().getRequestParameters().getOperationalEnvironmentType();
215 String operationalEnvType = opEnv != null ? opEnv.name() : null;
217 TenantIsolationRunnable runnable = getThread();
218 runnable.setAction(action);
219 runnable.setCor(cor);
220 runnable.setOperationalEnvType(operationalEnvType);
221 runnable.setRequestId(requestId);
223 Thread thread = new Thread(runnable);
225 } catch(Exception e) {
226 msoLogger.recordMetricEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while creating a new Thread", "APIH", null, null);
227 response = getTenantIsolationRequest().buildServiceErrorResponse (HttpStatus.SC_INTERNAL_SERVER_ERROR,
228 MsoException.ServiceException,
229 "Failed creating a Thread " + e.getMessage (),
230 ErrorNumbers.SVC_NO_SERVER_RESOURCES,
232 getTenantIsolationRequest().updateFinalStatus (Status.FAILED);
233 msoLogger.error (MessageEnum.APIH_GENERAL_EXCEPTION, Constants.MSO_PROP_APIHANDLER_INFRA, "", "", MsoLogger.ErrorCode.UnknownError, "Exception while creating a new Thread");
234 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.UnknownError, "Exception while creating a new Thread");
235 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
240 String encodedValue = new String(instanceId.getBytes("UTF-8"));
241 msoLogger.debug ("InstanceId: " + instanceId + " encoded to " + encodedValue);
243 TenantSyncResponse tenantResponse = new TenantSyncResponse();
244 RequestReferences reqReference = new RequestReferences();
245 reqReference.setInstanceId(encodedValue);
246 reqReference.setRequestId(requestId);
247 tenantResponse.setRequestReferences(reqReference);
249 response = Response.ok(tenantResponse).build();
251 msoLogger.debug ("Successful Sync response " + response.getEntity() + " with status code " + response.getStatus());
254 } catch(Exception e) {
255 msoLogger.recordMetricEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while building sync response", "APIH", null, null);
256 response = getTenantIsolationRequest().buildServiceErrorResponse (HttpStatus.SC_INTERNAL_SERVER_ERROR,
257 MsoException.ServiceException,
258 "Failed sending Sync Response " + e.getMessage (),
259 ErrorNumbers.SVC_NO_SERVER_RESOURCES,
261 getTenantIsolationRequest().updateFinalStatus (Status.FAILED);
262 msoLogger.error (MessageEnum.APIH_GENERAL_EXCEPTION, Constants.MSO_PROP_APIHANDLER_INFRA, "", "", MsoLogger.ErrorCode.UnknownError, "Exception while sending sync Response");
263 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.UnknownError, "Exception while sending sync Response");
264 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
269 private InfraActiveRequests duplicateCheck(Action action, HashMap<String, String> instanceIdMap, long startTime,
270 String instanceName, String requestScope) throws Exception {
271 InfraActiveRequests dup = null;
273 dup = getRequestsDatabase().checkInstanceNameDuplicate (instanceIdMap, instanceName, requestScope);
274 } catch (Exception e) {
275 msoLogger.error (MessageEnum.APIH_DUPLICATE_CHECK_EXC, Constants.MSO_PROP_APIHANDLER_INFRA, "", "", MsoLogger.ErrorCode.DataError, "Error during duplicate check ", e);
276 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Error during duplicate check");
277 throw new Exception(e);
282 private CloudOrchestrationRequest convertJsonToCloudOrchestrationRequest(String requestJSON, Action action, long startTime,
283 CloudOrchestrationRequest cor) throws Exception {
285 msoLogger.debug("Converting incoming JSON request to Object");
286 ObjectMapper mapper = new ObjectMapper();
287 cor = mapper.readValue(requestJSON, CloudOrchestrationRequest.class);
288 } catch(Exception e){
289 msoLogger.debug ("Mapping of request to JSON object failed : ", e);
290 if (getTenantIsolationRequest().getRequestId () != null) {
291 msoLogger.debug ("Mapping of request to JSON object failed");
292 getTenantIsolationRequest().createRequestRecord (Status.FAILED, action);
294 msoLogger.error (MessageEnum.APIH_REQUEST_VALIDATION_ERROR, Constants.MSO_PROP_APIHANDLER_INFRA, "", "", MsoLogger.ErrorCode.SchemaError, requestJSON, e);
295 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.SchemaError, "Mapping of request to JSON object failed");
296 throw new Exception(e);
301 public TenantIsolationRequest getTenantIsolationRequest() {
302 if(tenantIsolationRequest == null) {
303 tenantIsolationRequest = new TenantIsolationRequest();
305 return tenantIsolationRequest;
308 public void setTenantIsolationRequest(TenantIsolationRequest tenantIsolationRequest) {
309 this.tenantIsolationRequest = tenantIsolationRequest;
312 public RequestsDatabase getRequestsDatabase() {
313 if(requestsDatabase == null) {
314 requestsDatabase = RequestsDatabase.getInstance();
316 return requestsDatabase;
319 public void setRequestsDatabase(RequestsDatabase requestsDatabase) {
320 this.requestsDatabase = requestsDatabase;
323 public TenantIsolationRunnable getThread() {
324 if(tenantIsolation == null) {
325 tenantIsolation = new TenantIsolationRunnable();
327 return tenantIsolation;
330 public void setThread(TenantIsolationRunnable thread) {
331 this.tenantIsolation = thread;