2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Modifications Copyright (c) 2019 Samsung
8 * ================================================================================
9 * Modifications Copyright (c) 2020 Nordix
10 * ================================================================================
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
15 * http://www.apache.org/licenses/LICENSE-2.0
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 * ============LICENSE_END=========================================================
24 package org.onap.so.apihandlerinfra;
26 import com.fasterxml.jackson.core.JsonProcessingException;
27 import com.fasterxml.jackson.databind.DeserializationFeature;
28 import com.fasterxml.jackson.databind.ObjectMapper;
29 import io.swagger.v3.oas.annotations.OpenAPIDefinition;
30 import io.swagger.v3.oas.annotations.Operation;
31 import io.swagger.v3.oas.annotations.info.Info;
32 import io.swagger.v3.oas.annotations.media.ArraySchema;
33 import io.swagger.v3.oas.annotations.media.Content;
34 import io.swagger.v3.oas.annotations.media.Schema;
35 import io.swagger.v3.oas.annotations.responses.ApiResponse;
36 import org.apache.http.HttpStatus;
37 import org.onap.so.apihandler.common.ErrorNumbers;
38 import org.onap.so.apihandler.common.ResponseBuilder;
39 import org.onap.so.apihandlerinfra.exceptions.ValidateException;
40 import org.onap.so.apihandlerinfra.logging.ErrorLoggerInfo;
41 import org.onap.so.apihandlerinfra.workflowspecificationbeans.*;
42 import org.onap.so.db.catalog.beans.*;
43 import org.onap.so.db.catalog.client.CatalogDbClient;
44 import org.onap.logging.filter.base.ErrorCode;
45 import org.onap.so.logger.MessageEnum;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48 import org.springframework.beans.factory.annotation.Autowired;
49 import org.springframework.stereotype.Component;
50 import javax.transaction.Transactional;
51 import javax.ws.rs.GET;
52 import javax.ws.rs.Path;
53 import javax.ws.rs.PathParam;
54 import javax.ws.rs.QueryParam;
55 import javax.ws.rs.core.Response;
57 import java.util.stream.Collectors;
60 @Path("onap/so/infra/workflowSpecifications")
61 @OpenAPIDefinition(info = @Info(title = "onap/so/infra/workflowSpecifications",
62 description = "Queries of Workflow Specifications"))
64 public class WorkflowSpecificationsHandler {
67 private ResponseBuilder builder;
70 private CatalogDbClient catalogDbClient;
72 private static Logger logger = LoggerFactory.getLogger(WorkflowSpecificationsHandler.class);
73 private static final String ARTIFACT_TYPE_WORKFLOW = "workflow";
74 private static final String NATIVE_WORKFLOW = "native";
75 private static final String EMPTY_BODY = "";
77 @Path("/{version:[vV]1}/workflows")
79 @Operation(description = "Finds Workflow Specifications", responses = @ApiResponse(
80 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
83 public Response queryWorkflowSpecifications(@QueryParam("vnfModelVersionId") String vnfModelVersionId,
84 @QueryParam("pnfModelVersionId") String pnfModelVersionId,
85 @QueryParam("resourceTarget") String resourceTarget, @PathParam("version") String version)
87 String apiVersion = version.substring(1);
89 List<Workflow> workflows = new ArrayList<>();
90 if (vnfModelVersionId == null && pnfModelVersionId == null && resourceTarget == null) {
91 workflows.addAll(queryWorkflowSpecificationsForAll());
93 // 1. query workflow specifications for given vnfModelVersionId if need.
94 if (vnfModelVersionId != null) {
95 List<Workflow> vnfWorkflows = queryWorkflowSpecificationsForVnf(vnfModelVersionId);
96 logger.debug("Retrieved " + vnfWorkflows.size() + " workflows for given vnfModelVersionId.");
97 if (vnfWorkflows.size() > 0) {
98 workflows.addAll(vnfWorkflows);
102 // 2. query workflow specifications for given pnfModelVersionId if need.
103 if (pnfModelVersionId != null) {
104 List<Workflow> pnfWorkflows = queryWorkflowSpecificationsForPnf(pnfModelVersionId);
105 logger.debug("Retrieved " + pnfWorkflows.size() + " workflows for given pnfModelVerionId.");
106 if (pnfWorkflows.size() > 0) {
107 workflows.addAll(pnfWorkflows);
111 // 3. query workflow specifications for given resourceTarget
112 if (resourceTarget != null) {
113 List<Workflow> workflowsForResourceTarget = queryWorkflowsForResourceTarget(resourceTarget);
115 "Retrieved " + workflowsForResourceTarget.size() + " workflows for given resource target.");
116 if (workflowsForResourceTarget.size() > 0) {
117 workflows.addAll(workflowsForResourceTarget);
123 List<Workflow> retWorkflows = workflows.stream()
124 .collect(Collectors.collectingAndThen(
125 Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Workflow::getArtifactUUID))),
128 Optional<String> optional = getResponseByWorkflowSpec(retWorkflows);
129 return builder.buildResponse(HttpStatus.SC_OK, "", optional.isPresent() ? optional.get() : EMPTY_BODY,
134 * @deprecated As of G release, workflows for all resource types (pnf,vnf,service) can be fetched using
135 * /workflowSpecifications/{version:[vV]1}/workflows?resourceTarget={resourceType} API
137 @Path("/{version:[vV]1}/pnfWorkflows")
139 @Operation(description = "Finds pnf workflow specifications", responses = @ApiResponse(
140 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
143 public Response getWorkflowsSpecForPnf(@PathParam("version") String version) throws Exception {
145 final String pnf_resource = "pnf";
146 String apiVersion = version.substring(1);
148 ObjectMapper mapper = new ObjectMapper();
149 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
151 List<Workflow> workflows = queryWorkflowsForResourceTarget(pnf_resource);
153 Optional<String> optional = getResponseByWorkflowSpec(workflows);
154 return builder.buildResponse(HttpStatus.SC_OK, "", optional.isPresent() ? optional.get() : EMPTY_BODY,
158 protected WorkflowSpecifications mapWorkflowsToWorkflowSpecifications(List<Workflow> workflows) {
159 if (workflows == null || workflows.isEmpty()) {
162 WorkflowSpecifications workflowSpecifications = new WorkflowSpecifications();
163 List<WorkflowSpecificationList> workflowSpecificationList = new ArrayList<>();
165 for (Workflow workflow : workflows) {
166 WorkflowSpecificationList workflowSpecificationListItem = new WorkflowSpecificationList();
167 WorkflowSpecification workflowSpecification = new WorkflowSpecification();
168 workflowSpecification.setArtifactInfo(buildArtifactInfo(workflow));
169 workflowSpecification.setActivitySequence(buildActivitySequence(workflow));
170 workflowSpecification.setWorkflowInputParameters(buildWorkflowInputParameters(workflow));
171 workflowSpecificationListItem.setWorkflowSpecification(workflowSpecification);
172 workflowSpecificationList.add(workflowSpecificationListItem);
174 workflowSpecifications.setWorkflowSpecificationList(workflowSpecificationList);
175 return workflowSpecifications;
178 private Optional<String> getResponseByWorkflowSpec(List<Workflow> workflows) throws ValidateException {
179 WorkflowSpecifications workflowSpecifications = mapWorkflowsToWorkflowSpecifications(workflows);
182 ObjectMapper mapper = new ObjectMapper();
183 return Optional.of(mapper.writeValueAsString(workflowSpecifications));
184 } catch (JsonProcessingException e) {
185 catchAndThrowValidationEx(e);
187 return Optional.empty();
190 private Response catchAndThrowValidationEx(JsonProcessingException e) throws ValidateException {
191 ErrorLoggerInfo errorLoggerInfo =
192 new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError).build();
193 ValidateException validateException =
194 new ValidateException.Builder("Mapping of request to JSON object failed : " + e.getMessage(),
195 HttpStatus.SC_BAD_REQUEST, ErrorNumbers.SVC_BAD_PARAMETER).cause(e).errorInfo(errorLoggerInfo)
197 throw validateException;
200 private ArtifactInfo buildArtifactInfo(Workflow workflow) {
201 ArtifactInfo artifactInfo = new ArtifactInfo();
202 artifactInfo.setArtifactType(ARTIFACT_TYPE_WORKFLOW);
203 artifactInfo.setArtifactUuid(workflow.getArtifactUUID());
204 artifactInfo.setArtifactName(workflow.getArtifactName());
205 if (workflow.getVersion() != null) {
206 artifactInfo.setArtifactVersion(workflow.getVersion().toString());
208 artifactInfo.setArtifactDescription(workflow.getDescription());
209 artifactInfo.setWorkflowName(workflow.getName());
210 artifactInfo.setOperationName(workflow.getOperationName());
211 artifactInfo.setWorkflowSource(workflow.getSource());
212 artifactInfo.setWorkflowResourceTarget(workflow.getResourceTarget());
216 private List<ActivitySequence> buildActivitySequence(Workflow workflow) {
217 List<WorkflowActivitySpecSequence> workflowActivitySpecSequences = workflow.getWorkflowActivitySpecSequence();
218 if (workflowActivitySpecSequences == null || workflowActivitySpecSequences.isEmpty()) {
221 List<ActivitySequence> activitySequences = new ArrayList<>();
222 for (WorkflowActivitySpecSequence workflowActivitySpecSequence : workflowActivitySpecSequences) {
223 if (workflowActivitySpecSequence != null) {
224 ActivitySpec activitySpec = workflowActivitySpecSequence.getActivitySpec();
225 if (activitySpec != null) {
226 ActivitySequence activitySequence = new ActivitySequence();
227 activitySequence.setName(activitySpec.getName());
228 logger.debug("Adding activity: " + activitySpec.getName());
229 activitySequence.setDescription(activitySpec.getDescription());
230 activitySequences.add(activitySequence);
234 return activitySequences;
237 private List<WorkflowInputParameter> buildWorkflowInputParameters(Workflow workflow) {
238 List<WorkflowActivitySpecSequence> workflowActivitySpecSequences = workflow.getWorkflowActivitySpecSequence();
239 if (workflowActivitySpecSequences == null || workflowActivitySpecSequences.isEmpty()) {
240 return new ArrayList<>();
242 Map<String, WorkflowInputParameter> workflowInputParameterMap = new HashMap<>();
243 for (WorkflowActivitySpecSequence workflowActivitySpecSequence : workflowActivitySpecSequences) {
244 if (workflowActivitySpecSequence != null) {
245 ActivitySpec activitySpec = workflowActivitySpecSequence.getActivitySpec();
246 if (activitySpec != null) {
247 List<ActivitySpecUserParameters> activitySpecUserParameters =
248 activitySpec.getActivitySpecUserParameters();
249 if (activitySpecUserParameters != null && !activitySpecUserParameters.isEmpty()) {
250 for (ActivitySpecUserParameters activitySpecUserParameter : activitySpecUserParameters) {
251 UserParameters userParameter = activitySpecUserParameter.getUserParameters();
252 if (userParameter != null) {
253 WorkflowInputParameter workflowInputParameter =
254 buildWorkflowInputParameter(userParameter);
255 workflowInputParameterMap.put(userParameter.getName(), workflowInputParameter);
263 if (workflowInputParameterMap.size() == 0) {
264 return new ArrayList<>();
266 List<WorkflowInputParameter> workflowInputParameterList =
267 workflowInputParameterMap.values().stream().collect(Collectors.toList());
268 return workflowInputParameterList;
271 private WorkflowInputParameter buildWorkflowInputParameter(UserParameters userParameter) {
272 WorkflowInputParameter workflowInputParameter = new WorkflowInputParameter();
273 workflowInputParameter.setLabel(userParameter.getLabel());
274 workflowInputParameter.setInputType(userParameter.getType());
275 workflowInputParameter.setRequired(userParameter.getIsRequried());
276 workflowInputParameter.setSoFieldName(userParameter.getName());
277 workflowInputParameter.setSoPayloadLocation(userParameter.getPayloadLocation());
278 workflowInputParameter.setValidation(buildValidationList(userParameter));
279 return workflowInputParameter;
282 private List<Validation> buildValidationList(UserParameters userParameter) {
283 List<Validation> validationList = null;
284 if (userParameter.getMaxLength() != null || userParameter.getAllowableChars() != null) {
285 validationList = new ArrayList<>();
286 Validation validation = new Validation();
287 if (userParameter.getMaxLength() != null) {
288 validation.setMaxLength(userParameter.getMaxLength().toString());
290 validation.setAllowableChars(userParameter.getAllowableChars());
291 validationList.add(validation);
293 return validationList;
296 private List<Workflow> queryWorkflowSpecificationsForAll() {
297 List<Workflow> workflows = catalogDbClient.findWorkflowBySource(NATIVE_WORKFLOW);
301 private List<Workflow> queryWorkflowSpecificationsForVnf(String vnfModelVersionId) {
302 List<Workflow> workflows = catalogDbClient.findWorkflowByVnfModelUUID(vnfModelVersionId);
304 List<Workflow> nativeWorkflows = catalogDbClient.findWorkflowBySource(NATIVE_WORKFLOW);
305 if (!nativeWorkflows.isEmpty()) {
306 workflows.addAll(nativeWorkflows);
311 private List<Workflow> queryWorkflowSpecificationsForPnf(String pnfModelVersionId) {
312 List<Workflow> workflows = catalogDbClient.findWorkflowByPnfModelUUID(pnfModelVersionId);
316 private List<Workflow> queryWorkflowsForResourceTarget(String resourceTarget) {
317 List<Workflow> workflows = catalogDbClient.findWorkflowByResourceTarget(resourceTarget);