Springboot 2.0 upgrade
[so.git] / bpmn / MSOCommonBPMN / src / main / java / org / onap / so / bpmn / common / validation / BuildingBlockValidatorRunner.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 - 2018 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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.onap.so.bpmn.common.validation;
22
23 import java.lang.annotation.Annotation;
24 import java.util.ArrayList;
25 import java.util.Comparator;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Optional;
29 import java.util.stream.Collectors;
30
31 import javax.annotation.PostConstruct;
32 import javax.annotation.Priority;
33
34 import org.camunda.bpm.engine.delegate.BpmnError;
35 import org.javatuples.Pair;
36 import org.onap.so.bpmn.common.BuildingBlockExecution;
37 import org.onap.so.client.exception.ExceptionBuilder;
38 import org.reflections.Reflections;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41 import org.springframework.beans.factory.annotation.Autowired;
42 import org.springframework.context.ApplicationContext;
43 import org.springframework.stereotype.Component;
44
45
46 /**
47  * Controls running all pre and post validation for building blocks.
48  * 
49  * To define a validation you must make it a spring bean and implement either {@link org.onap.so.bpmn.common.validation.PreBuildingBlockValidator} or 
50  * {@link org.onap.so.bpmn.common.validation.PostBuildingBlockValidator} your validation will automatically be
51  * run by this class.
52  *
53  */
54 @Component
55 public class BuildingBlockValidatorRunner {
56
57         private static Logger logger = LoggerFactory.getLogger(BuildingBlockValidatorRunner.class);
58         @Autowired
59         private ApplicationContext context;
60         
61         @Autowired
62         private ExceptionBuilder exceptionBuilder;
63         
64         private List<PreBuildingBlockValidator> preBuildingBlockValidators;
65         private List<PostBuildingBlockValidator> postBuildingBlockValidators;
66
67         
68         @PostConstruct
69         protected void init() {
70                 
71                 preBuildingBlockValidators = new ArrayList<>(
72                                 Optional.ofNullable(context.getBeansOfType(PreBuildingBlockValidator.class)).orElse(new HashMap<>()).values());
73                 postBuildingBlockValidators = new ArrayList<>(
74                                 Optional.ofNullable(context.getBeansOfType(PostBuildingBlockValidator.class)).orElse(new HashMap<>()).values());
75         }
76         
77         public boolean preValidate(String bbName, BuildingBlockExecution execution) {
78                 return validate(preBuildingBlockValidators, bbName, execution);
79         }
80         
81         
82         public boolean postValidate(String bbName, BuildingBlockExecution execution) {
83                 return validate(postBuildingBlockValidators, bbName, execution);
84         }
85         
86         
87         protected boolean validate(List<? extends BuildingBlockValidator> validators, String bbName, BuildingBlockExecution execution) {
88                 List<Pair<String, Boolean>> results = runValidations(validators, bbName, execution);
89                 
90                 if (!results.isEmpty()) {
91                         exceptionBuilder.buildAndThrowWorkflowException(execution, 7000,
92                                         "Failed Validations:\n" + results.stream().map(item -> item.getValue0()).collect(Collectors.joining("\n")));
93                 }
94                 
95                 return true;
96                 
97         }
98         protected List<Pair<String, Boolean>> runValidations(List<? extends BuildingBlockValidator> validators, String bbName, BuildingBlockExecution execution) {
99                 
100                 List<BuildingBlockValidator> filtered = filterValidators(validators, bbName);
101                 
102                 List<Pair<String,Boolean>> results = new ArrayList<>();
103                 filtered.forEach(item -> results.add(new Pair<>(item.getClass().getName(), item.validate(execution))));
104                 
105                 return results.stream().filter(item -> item.getValue1().equals(false)).collect(Collectors.toList());
106         }
107         
108         protected List<BuildingBlockValidator> filterValidators(List<? extends BuildingBlockValidator> validators, String bbName) {
109                 return validators.stream()
110                                 .filter(item -> {
111                                         return item.forBuildingBlock().contains(bbName);
112                                 })
113                                 .sorted(Comparator.comparing(item -> {
114                                         Priority p = Optional.ofNullable(item.getClass().getAnnotation(Priority.class)).orElse(new Priority() {
115                                                 public int value() {
116                                                         return 1000;
117                                                 }
118
119                                                 @Override
120                                                 public Class<? extends Annotation> annotationType() {
121                                                         return Priority.class;
122                                                 }
123                                         });
124                                         return p.value();
125                                 })).collect(Collectors.toList());
126         }
127         
128         protected <T> List<T> buildalidatorList(Reflections reflections, Class<T> clazz) {
129                 List<T> result = new ArrayList<>();
130                 try {
131                         for (Class<? extends T> klass : reflections.getSubTypesOf(clazz)) {
132                                 result.add(klass.newInstance());
133                         }
134                 } catch (InstantiationException | IllegalAccessException e) {
135                         logger.error("failed to build validator list for " + clazz.getName(), e);
136                         throw new RuntimeException(e);
137                 }
138                 
139                 return result;
140         }
141         
142         protected List<PreBuildingBlockValidator> getPreBuildingBlockValidators() {
143                 return this.preBuildingBlockValidators;
144         }
145         
146         protected List<PostBuildingBlockValidator> getPostBuildingBlockValidators() {
147                 return this.postBuildingBlockValidators;
148         }
149         
150 }