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;
23 import java.io.StringReader;
24 import java.io.StringWriter;
25 import java.sql.Timestamp;
26 import java.text.SimpleDateFormat;
27 import java.util.Calendar;
28 import java.util.Date;
30 import javax.ws.rs.core.Response;
31 import javax.xml.bind.JAXBContext;
32 import javax.xml.bind.JAXBException;
33 import javax.xml.bind.Marshaller;
34 import javax.xml.bind.Unmarshaller;
35 import javax.xml.transform.OutputKeys;
36 import javax.xml.transform.Transformer;
37 import javax.xml.transform.TransformerFactory;
38 import javax.xml.transform.dom.DOMSource;
39 import javax.xml.transform.sax.SAXSource;
40 import javax.xml.transform.stream.StreamResult;
42 import org.hibernate.Session;
43 import org.w3c.dom.Document;
44 import org.w3c.dom.Element;
45 import org.w3c.dom.Node;
46 import org.w3c.dom.NodeList;
47 import org.xml.sax.InputSource;
49 import org.openecomp.mso.apihandler.common.ErrorNumbers;
50 import org.openecomp.mso.apihandler.common.ValidationException;
51 import org.openecomp.mso.apihandlerinfra.networkbeans.ActionType;
52 import org.openecomp.mso.apihandlerinfra.networkbeans.NetworkInputs;
53 import org.openecomp.mso.apihandlerinfra.networkbeans.NetworkRequest;
54 import org.openecomp.mso.apihandlerinfra.networkbeans.ObjectFactory;
55 import org.openecomp.mso.apihandlerinfra.networkbeans.RequestInfo;
56 import org.openecomp.mso.apihandlerinfra.networkbeans.RequestStatusType;
57 import org.openecomp.mso.logger.MessageEnum;
58 import org.openecomp.mso.logger.MsoLogger;
59 import org.openecomp.mso.properties.MsoJavaProperties;
60 import org.openecomp.mso.requestsdb.HibernateUtil;
61 import org.openecomp.mso.requestsdb.InfraActiveRequests;
62 import org.openecomp.mso.requestsdb.RequestsDatabase;
64 public class NetworkMsoInfraRequest {
66 private String requestId;
67 private String requestXML;
68 private String requestUri;
69 private RequestInfo rinfo;
70 private NetworkInputs networkInputs;
71 private String networkParams;
72 private ActionType action;
73 private String errorMessage;
74 private String httpResponse;
75 private String responseBody;
76 private RequestStatusType status;
77 private long startTime;
78 private long progress = Constants.PROGRESS_REQUEST_RECEIVED;
80 private static MsoLogger msoLogger = MsoLogger.getMsoLogger (MsoLogger.Catalog.APIH);
81 private static final String NOT_PROVIDED = "not provided";
83 NetworkMsoInfraRequest (String requestId) {
84 this.requestId = requestId;
85 Calendar startTimeCalendar = Calendar.getInstance ();
86 this.startTime = startTimeCalendar.getTimeInMillis ();
87 MsoLogger.setLogContext (requestId, null);
92 void parse (String reqXML, String version, MsoJavaProperties props) throws ValidationException {
94 msoLogger.debug ("Validating the request");
96 this.requestXML = reqXML;
98 NetworkRequest networkReq = null;
99 boolean isWrongRootElement = false;
102 JAXBContext jaxbContext = JAXBContext.newInstance (NetworkRequest.class);
103 Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller ();
105 InputSource inputSource = new InputSource (new StringReader (reqXML));
106 SAXSource source = new SAXSource (inputSource);
108 if (reqXML.contains ("network-request") && !reqXML.contains ("vnf-request")) {
109 networkReq = jaxbUnmarshaller.unmarshal (source, NetworkRequest.class).getValue ();
111 isWrongRootElement = true;
114 } catch (Exception e) {
115 msoLogger.error (MessageEnum.APIH_VNFREQUEST_VALIDATION_ERROR, "", "", MsoLogger.ErrorCode.DataError, "Exception when parsing reqXML", e);
116 throw new ValidationException ("format for network request");
119 if (isWrongRootElement) {
120 msoLogger.error (MessageEnum.APIH_REQUEST_VALIDATION_ERROR_REASON, "root element is not correct", "", "", MsoLogger.ErrorCode.DataError, "root element <network-request> expected");
121 throw new ValidationException ("root element <network-request> expected");
124 if (networkReq == null) {
125 throw new ValidationException ("network-request");
128 this.rinfo = networkReq.getRequestInfo ();
130 if (this.rinfo == null) {
131 throw new ValidationException ("request-info");
134 action = this.rinfo.getAction ();
135 if (action == null) {
136 throw new ValidationException ("action");
139 if (!InfraUtils.isActionAllowed (props, "network", version, action.value ())) {
140 throw new ValidationException ("action allowable for version " + version + " of network request");
143 this.networkInputs = networkReq.getNetworkInputs ();
144 if (this.networkInputs == null) {
145 throw new ValidationException ("network-inputs");
148 // Verify that the elements correspond to the version
150 if (version.equals(Constants.SCHEMA_VERSION_V1)) {
151 if (this.networkInputs.getBackoutOnFailure() != null || this.networkInputs.getAicCloudRegion() != null ||
152 this.networkInputs.getServiceInstanceId() != null) {
153 throw new ValidationException ("format for v1 version of network request");
156 else if (version.equals(Constants.SCHEMA_VERSION_V2)) {
157 if (this.networkInputs.getServiceType() != null || this.networkInputs.getAicNodeClli() != null ||
158 this.networkInputs.getServiceInstanceId() != null) {
159 throw new ValidationException ("format for v2 version of network request");
162 else if (version.equals(Constants.SCHEMA_VERSION_V3)) {
163 if (this.networkInputs.getServiceType() != null || this.networkInputs.getAicNodeClli() != null) {
164 throw new ValidationException ("format for v3 version of network request");
171 if (this.networkInputs.getNetworkId () == null) {
172 throw new ValidationException ("network-id");
179 if (ActionType.CREATE.equals (action) && this.networkInputs.getNetworkName () == null) {
180 throw new ValidationException ("network-name");
183 if (this.networkInputs.getNetworkType () == null) {
184 throw new ValidationException ("network-type");
187 if (!version.equals(Constants.SCHEMA_VERSION_V1) && this.networkInputs.getServiceId () == null) {
188 throw new ValidationException ("service-id ");
191 if (this.networkInputs.getServiceType () != null && this.networkInputs.getServiceId () != null) {
192 throw new ValidationException ("service-type or service-id ");
195 if (version.equals(Constants.SCHEMA_VERSION_V1) && this.networkInputs.getAicNodeClli () == null) {
196 throw new ValidationException ("aic-node-clli");
199 if ((version.equals (Constants.SCHEMA_VERSION_V2) || version.equals (Constants.SCHEMA_VERSION_V3)) && (this.networkInputs.getAicCloudRegion () == null || this.networkInputs.getAicCloudRegion ().isEmpty())) {
200 throw new ValidationException ("aic-cloud-region");
203 if (version.equals(Constants.SCHEMA_VERSION_V3) && this.networkInputs.getServiceInstanceId () == null) {
204 throw new ValidationException ("service-instance-id");
207 if (ActionType.CREATE.equals (action)) {
208 if (this.networkInputs.getTenantId () == null) {
209 throw new ValidationException ("tenant-id");
214 Object vpN = networkReq.getNetworkParams ();
217 Node node = (Node) vpN;
218 Document doc = node.getOwnerDocument ();
219 this.networkParams = domToStr (doc);
222 msoLogger.debug ("NetworkParams: " + this.networkParams);
224 msoLogger.debug ("Request valid");
226 // Rebuild the request string for BPEL to include request-id
227 rinfo.setRequestId (this.requestId);
228 networkReq.setRequestInfo (rinfo);
230 StringWriter stringWriter = new StringWriter ();
232 JAXBContext jaxbContext = JAXBContext.newInstance (NetworkRequest.class);
233 Marshaller jaxbMarshaller = jaxbContext.createMarshaller ();
235 // output pretty printed
236 jaxbMarshaller.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, true);
238 jaxbMarshaller.marshal (networkReq, stringWriter);
240 } catch (JAXBException e) {
241 msoLogger.debug ("Exception: ", e);
244 this.requestXML = stringWriter.toString ().replace ("http://ecomp.att.com/mso/infra/network-request",
245 "http://ecomp.att.com/mso/infra/vnf-request");
246 msoLogger.debug("REQUEST XML to BPEL: " + this.requestXML);
250 public void createRequestRecord (Status status) {
252 long startTime = System.currentTimeMillis ();
254 Session session = null;
257 session = HibernateUtil.getSessionFactory ().openSession ();
258 session.beginTransaction ();
260 InfraActiveRequests aq = new InfraActiveRequests ();
261 aq.setRequestId (requestId);
263 Timestamp startTimeStamp = new Timestamp (Calendar.getInstance ().getTimeInMillis ());
265 if (rinfo.getAction () != null) {
266 aq.setAction (rinfo.getAction ().value ());
267 aq.setRequestAction (RequestActionMap.getMappedRequestAction (rinfo.getAction ().value ()));
269 aq.setSource (rinfo.getSource ());
271 // Set up mandatory parameters
272 aq.setAction (NOT_PROVIDED);
273 aq.setRequestAction (NOT_PROVIDED);
276 aq.setRequestBody (this.requestXML);
277 aq.setRequestScope (ModelType.network.name ());
279 if (networkInputs != null) {
280 if (networkInputs.getNetworkId () != null) {
281 aq.setVnfId (networkInputs.getNetworkId ());
283 if (networkInputs.getNetworkName () != null) {
284 aq.setVnfName (networkInputs.getNetworkName ());
286 if (networkInputs.getNetworkType () != null) {
287 aq.setVnfType (networkInputs.getNetworkType ());
289 if (networkInputs.getServiceInstanceId () != null) {
290 aq.setServiceInstanceId (networkInputs.getServiceInstanceId ());
292 if (networkInputs.getServiceType () != null) {
293 aq.setServiceType (networkInputs.getServiceType ());
295 if (networkInputs.getServiceId () != null) {
296 aq.setServiceType (networkInputs.getServiceId ());
298 if (networkInputs.getAicNodeClli () != null) {
299 aq.setAicNodeClli (networkInputs.getAicNodeClli ());
301 if (networkInputs.getTenantId () != null) {
302 aq.setTenantId (networkInputs.getTenantId ());
304 if (networkInputs.getProvStatus () != null) {
305 aq.setProvStatus (networkInputs.getProvStatus ());
309 aq.setStartTime (startTimeStamp);
310 aq.setRequestStatus (status.toString ());
311 aq.setLastModifiedBy (Constants.MODIFIED_BY_APIHANDLER);
312 aq.setRequestType ("NETWORK");
314 if (networkParams != null) {
315 msoLogger.debug ("Storing networkParams: " + networkParams);
316 aq.setVnfParams (this.networkParams);
319 if ((status == Status.FAILED) || (status == Status.COMPLETE)) {
320 aq.setStatusMessage (this.errorMessage);
321 aq.setResponseBody (this.responseBody);
323 Calendar endTime = Calendar.getInstance ();
324 Timestamp endTimeStamp = new Timestamp (endTime.getTimeInMillis ());
325 aq.setEndTime (endTimeStamp);
327 aq.setProgress (this.progress);
330 msoLogger.debug ("About to insert a record");
333 session.getTransaction ().commit ();
335 msoLogger.recordMetricEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully", "RequestDB", "saveRequest", null);
337 } catch (Exception e) {
338 msoLogger.error (MessageEnum.APIH_DB_INSERT_EXC, "", "", MsoLogger.ErrorCode.SchemaError, "Exception in createRequestRecord", e);
339 msoLogger.recordMetricEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, e.getMessage (), "RequestDB", "saveRequest", null);
340 if (session != null) {
343 if (!status.equals (Status.FAILED)) {
349 public void updateFinalStatus (Status status) {
351 RequestsDatabase.updateInfraFinalStatus (requestId,
356 Constants.MODIFIED_BY_APIHANDLER);
357 } catch (Exception e) {
358 msoLogger.error (MessageEnum.APIH_DB_UPDATE_EXC, e.getMessage (), "", "", MsoLogger.ErrorCode.SchemaError, "Exception in updateFinalStatus");
359 msoLogger.debug ("Exception: ", e);
363 public Response buildResponse (int httpResponseCode, String errorCode, InfraActiveRequests inProgress) {
364 return buildResponseWithError (httpResponseCode, errorCode, inProgress, null);
367 public Response buildResponseWithError (int httpResponseCode,
369 InfraActiveRequests inProgress,
370 String errorString) {
372 ObjectFactory beansObjectFactory = new ObjectFactory ();
374 NetworkRequest vr = beansObjectFactory.createNetworkRequest ();
376 RequestInfo ri = beansObjectFactory.createRequestInfo ();
378 ri.setRequestId (requestId);
379 ri.setRequestStatus (this.status);
380 ri.setAction (this.rinfo.getAction ());
381 ri.setSource (this.rinfo.getSource ());
383 String errorMsg = null;
384 if (errorCode != null) {
385 // If error code is actually an XML error response from BPEL, treat it specially:
386 if (!Messages.errors.containsKey (errorCode)) {
387 if (errorCode.length () > 300) {
388 errorMsg = errorCode.substring (0, 299);
390 errorMsg = errorCode;
395 if (inProgress == null) {
396 if (errorCode.equals (ErrorNumbers.RECIPE_DOES_NOT_EXIST)) {
397 errorMsg = String.format (Messages.errors.get (errorCode), "network", errorString);
399 errorMsg = String.format (Messages.errors.get (errorCode), errorString);
401 } else if (errorCode.equals (ErrorNumbers.LOCKED_CREATE_ON_THE_SAME_VNF_NAME_IN_PROGRESS)) {
402 errorMsg = String.format (Messages.errors.get (errorCode),
404 inProgress.getVnfName (),
405 inProgress.getRequestStatus (),
407 } else if (errorCode.equals (ErrorNumbers.LOCKED_SAME_ACTION_AND_VNF_ID)) {
408 errorMsg = String.format (Messages.errors.get (errorCode),
410 inProgress.getVnfId (),
411 inProgress.getRequestStatus (),
412 inProgress.getAction (),
417 ri.setStatusMessage (errorMsg);
418 this.errorMessage = errorMsg;
420 ri.setProgress ((int) this.progress);
422 Date startDate = new Date (this.startTime);
423 SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss.SSS");
424 String startTimeString = sdf.format (startDate);
426 ri.setStartTime (startTimeString);
428 vr.setRequestInfo (ri);
429 vr.setNetworkInputs (this.networkInputs);
431 StringWriter stringWriter = new StringWriter ();
433 JAXBContext jaxbContext = JAXBContext.newInstance (NetworkRequest.class);
434 Marshaller jaxbMarshaller = jaxbContext.createMarshaller ();
435 jaxbMarshaller.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, true);
437 jaxbMarshaller.marshal (vr, stringWriter);
439 } catch (JAXBException e) {
440 msoLogger.debug ("Exception: ", e);
443 String response = stringWriter.toString ();
445 this.httpResponse = Integer.toString (httpResponseCode);
446 this.responseBody = response;
448 // Log the failed request into the MSO Requests database
450 return Response.status (httpResponseCode).entity (response).build ();
454 public Response buildResponseFailedValidation (int httpResponseCode, String exceptionMessage) {
456 ObjectFactory beansObjectFactory = new ObjectFactory ();
457 NetworkRequest vr = beansObjectFactory.createNetworkRequest ();
459 RequestInfo ri = beansObjectFactory.createRequestInfo ();
460 ri.setRequestId (requestId);
462 if (this.rinfo != null) {
463 if (this.rinfo.getAction () != null) {
464 ri.setAction (this.rinfo.getAction ());
466 ri.setAction (ActionType.NOT_PROVIDED);
468 if (this.rinfo.getSource () != null) {
469 ri.setSource (this.rinfo.getSource ());
472 ri.setAction (ActionType.NOT_PROVIDED);
475 // Nothing more is expected for this request
477 String errorMsg = String.format (Messages.errors.get (ErrorNumbers.REQUEST_FAILED_SCHEMA_VALIDATION
480 ri.setStatusMessage (errorMsg);
481 this.errorMessage = errorMsg;
483 ri.setProgress ((int) this.progress);
484 ri.setRequestStatus (RequestStatusType.FAILED);
485 Date startDate = new Date (this.startTime);
486 SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss.SSS");
487 String startTimeString = sdf.format (startDate);
489 ri.setStartTime (startTimeString);
491 vr.setRequestInfo (ri);
492 vr.setNetworkInputs (this.networkInputs);
494 StringWriter stringWriter = new StringWriter ();
496 JAXBContext jaxbContext = JAXBContext.newInstance (NetworkRequest.class);
497 Marshaller jaxbMarshaller = jaxbContext.createMarshaller ();
499 // output pretty printed
500 jaxbMarshaller.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, true);
502 jaxbMarshaller.marshal (vr, stringWriter);
504 } catch (JAXBException e) {
505 msoLogger.debug ("Error marshalling", e);
508 String response = stringWriter.toString ();
510 this.httpResponse = Integer.toString (httpResponseCode);
511 this.responseBody = response;
513 return Response.status (httpResponseCode).entity (response).build ();
516 public String getRequestUri () {
520 public void setRequestUri (String requestUri) {
521 this.requestUri = requestUri;
524 public NetworkInputs getNetworkInputs () {
525 return networkInputs;
528 public RequestInfo getRequestInfo () {
532 public String getResponseBody () {
536 public void setResponseBody (String responseBody) {
537 this.responseBody = responseBody;
540 public String getHttpResponse () {
544 public void setHttpResponse (String httpResponse) {
545 this.httpResponse = httpResponse;
548 public String getRequestId () {
552 public String getRequestXML () {
556 public void setRequestXML (String requestXML) {
557 this.requestXML = requestXML;
560 public RequestStatusType getStatus () {
564 public void setStatus (RequestStatusType status) {
565 this.status = status;
569 this.progress = Constants.PROGRESS_REQUEST_COMPLETED;
572 this.progress = Constants.PROGRESS_REQUEST_IN_PROGRESS;
577 public String getServiceType () {
578 if (this.networkInputs.getServiceType () != null)
579 return this.networkInputs.getServiceType ();
580 if (this.networkInputs.getServiceId () != null)
581 return this.networkInputs.getServiceId ();
585 public static String domToStr (Document doc) {
591 StringWriter sw = new StringWriter ();
592 StreamResult sr = new StreamResult (sw);
593 TransformerFactory tf = TransformerFactory.newInstance ();
594 Transformer t = tf.newTransformer ();
595 t.setOutputProperty (OutputKeys.STANDALONE, "yes");
596 NodeList nl = doc.getDocumentElement ().getChildNodes ();
597 DOMSource source = null;
598 for (int x = 0; x < nl.getLength (); x++) {
599 Node e = nl.item (x);
600 if (e instanceof Element) {
601 source = new DOMSource (e);
605 if (source != null) {
606 t.transform (source, sr);
608 String s = sw.toString ();
614 } catch (Exception e) {
615 msoLogger.error (MessageEnum.APIH_DOM2STR_ERROR, "", "", MsoLogger.ErrorCode.DataError, "Exception in domToStr", e);