c08fcef5b3fd50b39373cd911b0c7997558ca1d4
[sdc/sdc-workflow-designer.git] /
1 /**
2  * Copyright (c) 2017-2018 ZTE Corporation.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the Apache License, Version 2.0
5  * and the Eclipse Public License v1.0 which both accompany this distribution,
6  * and are available at http://www.eclipse.org/legal/epl-v10.html
7  * and http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Contributors:
10  *     ZTE - initial API and implementation and/or initial documentation
11  */
12
13 package org.onap.sdc.workflowdesigner.resources;
14
15 import java.io.IOException;
16 import java.net.URI;
17 import java.nio.file.Paths;
18 import java.util.List;
19 import java.util.UUID;
20
21 import javax.ws.rs.Consumes;
22 import javax.ws.rs.GET;
23 import javax.ws.rs.PUT;
24 import javax.ws.rs.Path;
25 import javax.ws.rs.PathParam;
26 import javax.ws.rs.Produces;
27 import javax.ws.rs.QueryParam;
28 import javax.ws.rs.core.MediaType;
29 import javax.ws.rs.core.Response;
30
31 import org.dom4j.Comment;
32 import org.dom4j.Document;
33 import org.dom4j.DocumentException;
34 import org.dom4j.DocumentHelper;
35 import org.eclipse.jetty.http.HttpStatus;
36 import org.onap.sdc.workflowdesigner.common.SDCProxyException;
37 import org.onap.sdc.workflowdesigner.config.AppConfig;
38 import org.onap.sdc.workflowdesigner.externalservice.sdc.SDCServiceProxy;
39 import org.onap.sdc.workflowdesigner.externalservice.sdc.entity.WorkflowArtifactInfo;
40 import org.onap.sdc.workflowdesigner.model.Process;
41 import org.onap.sdc.workflowdesigner.parser.Bpmn4ToscaJsonParser;
42 import org.onap.sdc.workflowdesigner.resources.entity.WorkflowInfo;
43 import org.onap.sdc.workflowdesigner.utils.FileCommonUtils;
44 import org.onap.sdc.workflowdesigner.utils.JsonUtils;
45 import org.onap.sdc.workflowdesigner.utils.RestUtils;
46 import org.onap.sdc.workflowdesigner.utils.ToolUtils;
47 import org.onap.sdc.workflowdesigner.writer.BpmnPlanArtefactWriter;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51 import com.codahale.metrics.annotation.Timed;
52
53 import io.swagger.annotations.Api;
54 import io.swagger.annotations.ApiOperation;
55 import io.swagger.annotations.ApiParam;
56 import io.swagger.annotations.ApiResponse;
57 import io.swagger.annotations.ApiResponses;
58
59 /**
60  * Workflow Modeler Resource.
61  * 
62  */
63 @Path("/models")
64 @Api(tags = {"Workflow Modeler"})
65 public class WorkflowModelerResource {
66   private static final Logger logger = LoggerFactory.getLogger(WorkflowModelerResource.class);
67
68   private static final String WORKFLOW_JSON_TEMP_FILE_NAME = "temp_workflow.json";
69   private static final String WORKFLOW_XML_TEMP_FILE_NAME = "temp_workflow.xml";
70
71
72   /**
73    * 
74    * @return Response
75    */
76   @Path("/{id}")
77   @GET
78   @Consumes(MediaType.APPLICATION_JSON)
79   @Produces(MediaType.APPLICATION_JSON)
80   @ApiOperation(value = "Get Model", response = WorkflowInfo.class)
81   @ApiResponses(value = {
82       @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "microservice not found",
83           response = String.class),
84       @ApiResponse(code = HttpStatus.UNSUPPORTED_MEDIA_TYPE_415,
85           message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
86       @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500, message = "server internal error",
87           response = String.class)})
88   @Timed
89   public Response getModel(@ApiParam(value = "id") @PathParam("id") String id,
90       @ApiParam(value = "name") @QueryParam("name") String name,
91       @ApiParam(value = "uuid") @QueryParam("uuid") String uuid,
92       @ApiParam(value = "operationId") @QueryParam("operationId") String operationId) {
93     if (AppConfig.isSDCAdapter()) {
94       return getModelfromSDC(uuid, operationId, id, name);
95     } else {
96       return getModelfromLocal();
97     }
98
99   }
100
101   /**
102    * @return
103    */
104   private Response getModelfromLocal() {
105     try {
106       String json = FileCommonUtils.readString(WORKFLOW_JSON_TEMP_FILE_NAME);
107       return Response.status(Response.Status.OK).entity(json).build();
108     } catch (IOException e) {
109       logger.error("get workflow from local failed.", e);
110       throw RestUtils.newInternalServerErrorException(e);
111     }
112   }
113
114
115   /**
116    * @param uuid
117    * @param operationId
118    * @param id
119    * @param name
120    * @return
121    */
122   private Response getModelfromSDC(String uuid, String operationId, String id, String name) {
123     try {
124       SDCServiceProxy sdcProxy = new SDCServiceProxy();
125       WorkflowArtifactInfo wai = sdcProxy.getWorkflowArtifact(uuid, operationId, id);
126       String bpmn = wai.getPayloadData();
127       String json = readJsonfromBPMN(bpmn);
128       if (ToolUtils.isEmpty(json)) {
129         WorkflowInfo wfi = newEmptyWorkflowInfo(uuid, operationId, id, name);
130         return Response.status(Response.Status.OK).entity(wfi).build();
131       }
132       return Response.status(Response.Status.OK).entity(json).build();
133     } catch (SDCProxyException e) {
134       logger.error("get workflow from sdc failed.", e);
135       throw RestUtils.newInternalServerErrorException(e);
136     } catch (DocumentException e) {
137       logger.error("get workflow from sdc failed.", e);
138       throw RestUtils.newInternalServerErrorException(e);
139     }
140   }
141
142   /**
143    * @param id
144    * @param operationId
145    * @param uuid
146    * @param name
147    * @return
148    */
149   private WorkflowInfo newEmptyWorkflowInfo(String uuid, String operationId, String id,
150       String name) {
151     WorkflowInfo wfi = new WorkflowInfo();
152     wfi.setId(id);
153     wfi.setName(name);
154     wfi.setUuid(uuid);
155     wfi.setOperationId(operationId);
156
157     return wfi;
158   }
159
160
161
162   @Path("/{id}")
163   @PUT
164   @Consumes(MediaType.APPLICATION_JSON)
165   @Produces(MediaType.APPLICATION_JSON)
166   @ApiOperation(value = "Save Model", response = String.class)
167   @ApiResponses(value = {
168       @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "microservice not found",
169           response = String.class),
170       @ApiResponse(code = HttpStatus.UNSUPPORTED_MEDIA_TYPE_415,
171           message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
172       @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500, message = "server internal error",
173           response = String.class)})
174   @Timed
175   public Response saveModel(@ApiParam(value = "id") @PathParam("id") String id,
176       @ApiParam(value = "Model Content", required = true) String json) {
177     try {
178       FileCommonUtils.write(WORKFLOW_JSON_TEMP_FILE_NAME, json);
179
180       URI srcUri = Paths.get(".", WORKFLOW_JSON_TEMP_FILE_NAME).toUri();
181       String processName = "plan_" + UUID.randomUUID().toString();
182       String bpmn = buildBPMN(srcUri, processName);
183       String jsonBpmn = insertJson2Bpmn(json, bpmn);
184
185       if (AppConfig.isSDCAdapter()) {
186         save2SDC(json, jsonBpmn);
187       }
188       FileCommonUtils.write(WORKFLOW_XML_TEMP_FILE_NAME, jsonBpmn);
189
190       return Response.status(Response.Status.OK).entity(json).build();
191     } catch (IOException e) {
192       logger.error("save workflow failed.", e);
193       throw RestUtils.newInternalServerErrorException(e);
194     } catch (Exception e) {
195       logger.error("convert workflow from json to bpmn failed.", e);
196       throw RestUtils.newInternalServerErrorException(e);
197     }
198   }
199
200   /**
201    * @param json
202    * @param bpmn
203    * @return
204    */
205   protected String insertJson2Bpmn(String json, String bpmn) {
206     StringBuffer sb = new StringBuffer(bpmn);
207     sb.append("<!-- \n").append(json).append("-->\n");
208
209     return sb.toString();
210   }
211
212   /**
213    * 
214    * @return
215    * @throws DocumentException
216    */
217   protected String readJsonfromBPMN(String bpmn) throws DocumentException {
218     if (ToolUtils.isEmpty(bpmn)) {
219       return null;
220     }
221
222     Document doc = DocumentHelper.parseText(bpmn);
223     List<?> elementList = doc.content();
224     for (Object object : elementList) {
225       if (object instanceof Comment) {
226         Comment comment = (Comment) object;
227         return comment.getText().trim();
228       }
229     }
230
231     return null;
232   }
233
234
235   /**
236    * @param json
237    * @param bpmn
238    * @throws SDCProxyException
239    */
240   private void save2SDC(String json, String bpmn) throws SDCProxyException {
241     WorkflowInfo workflowInfo = JsonUtils.fromJson(json, WorkflowInfo.class);
242     WorkflowArtifactInfo workflowArtifactInfo =
243         new WorkflowArtifactInfo(workflowInfo.getName(), workflowInfo.getDescription(), bpmn);
244
245     SDCServiceProxy sdcProxy = new SDCServiceProxy();
246     sdcProxy.saveWorkflowArtifact(workflowInfo.getUuid(), workflowInfo.getOperationId(),
247         workflowInfo.getId(), workflowArtifactInfo);
248   }
249
250   /**
251    * 
252    * @param srcUri
253    * @param processName
254    * @return
255    * @throws IOException
256    * @throws Exception
257    */
258   protected String buildBPMN(URI srcUri, String processName) throws IOException, Exception {
259     Bpmn4ToscaJsonParser parser = new Bpmn4ToscaJsonParser();
260     Process process = parser.parse(processName, srcUri);
261
262     // transform bpmn template
263     BpmnPlanArtefactWriter writer = new BpmnPlanArtefactWriter(process);
264     return writer.completePlanTemplate();
265   }
266
267 }