Merge "Fix dateformat for APPC HealthCheck"
[so.git] / bpmn / so-bpmn-tasks / src / main / java / org / onap / so / bpmn / infrastructure / workflow / tasks / ExecutionPlan.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2021 Orange 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.infrastructure.workflow.tasks;
22
23 import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.TreeMap;
31 import java.util.stream.Collectors;
32
33 class ExecutionPlan extends ExecutionCollection<ExecutionGroup> {
34     private final Resource resource;
35     private ExecutionGroup currentGroup = null;
36
37     public ExecutionPlan(Resource resource, ExecutionGroup group) {
38         super(resource != null ? resource.getResourceType() : WorkflowType.SERVICE);
39         this.resource = resource;
40         if (group != null) {
41             group.addNestedPlans(Collections.singletonList(this));
42         }
43     }
44
45     public void changeCurrentGroup(ExecutionGroup group) {
46         if (currentGroup == null || !currentGroup.equals(group)) {
47             logger.info("Change " + getName() + " group[" + group.getName() + "]");
48             if (currentGroup != null)
49                 currentGroup.flushBlocksFromCache(this.blocksBuiltCache);
50         }
51         currentGroup = group;
52     }
53
54     Resource getResource() {
55         return resource;
56     }
57
58     protected String getName() {
59         return super.getName() + "["
60                 + (resource != null ? (resource.getProcessingPriority() + ", " + resource.getResourceId()) : "") + "]";
61     }
62
63     public static ExecutionPlan build(List<Resource> resourceList, boolean ascendingOrder) {
64         ExecutionPlan plan = new ExecutionPlan(null, null);
65         buildExecutionPlan(plan, resourceList, ascendingOrder);
66         if (plan.getNestedExecutions().size() == 1
67                 && plan.getNestedExecutions().get(0).getNestedExecutions().size() == 1)
68             plan = plan.getNestedExecutions().get(0).getNestedExecutions().get(0);
69         return plan;
70     }
71
72     private static void buildExecutionPlan(ExecutionPlan plan, List<Resource> resourceList, boolean ascendingOrder) {
73         Map<WorkflowType, List<Resource>> resourceGroups = new TreeMap<>();
74         for (Resource resource : resourceList) {
75             if (!resourceGroups.containsKey(resource.getResourceType())) {
76                 resourceGroups.put(resource.getResourceType(), new ArrayList<>());
77             }
78             resourceGroups.get(resource.getResourceType()).add(resource);
79         }
80         for (WorkflowType type : resourceGroups.keySet()) {
81             ExecutionGroup nestedGroup = new ExecutionGroup(type, plan);
82             List<Resource> resourceGroupSorted = resourceGroups.get(type).stream()
83                     .sorted(ascendingOrder ? Resource.sortByPriorityAsc : Resource.sortByPriorityDesc)
84                     .collect(Collectors.toList());
85             for (Resource resource : resourceGroupSorted) {
86                 ExecutionPlan planInGroup = new ExecutionPlan(resource, nestedGroup);
87                 if (resource.getChildren().size() > 0)
88                     buildExecutionPlan(planInGroup, resource.getChildren(), ascendingOrder);
89             }
90         }
91     }
92 }
93
94
95 class ExecutionGroup extends ExecutionCollection<ExecutionPlan> {
96
97     public ExecutionGroup(WorkflowType groupType, ExecutionPlan plan) {
98         super(groupType);
99         plan.addNestedPlans(Collections.singletonList(this));
100     }
101 }
102
103
104 class ExecutionCollection<T extends ExecutionCollection<?>> {
105
106     protected static final Logger logger = LoggerFactory.getLogger(ExecutionCollection.class);
107
108     protected final WorkflowType type;
109     protected List<ExecuteBuildingBlock> blocksBuiltCache;
110     protected final List<T> nestedExecutions;
111
112     public ExecutionCollection(WorkflowType type) {
113         this.type = type;
114         this.nestedExecutions = new ArrayList<>();
115         this.blocksBuiltCache = new ArrayList<>();
116     }
117
118     public WorkflowType getType() {
119         return type;
120     }
121
122     public List<T> getNestedExecutions() {
123         return nestedExecutions;
124     }
125
126     public void addNestedPlans(List<T> executions) {
127         nestedExecutions.addAll(executions);
128     }
129
130     public void pushBlockToCache(List<ExecuteBuildingBlock> blocksCache) {
131         if (blocksCache.size() == 0)
132             return;
133         this.flushNestedBlocksToCache();
134         String blocks =
135                 blocksCache.stream().map(x -> x.getBuildingBlock().getBpmnFlowName() + ", ").reduce("", String::concat);
136         blocks = blocks.substring(0, blocks.length() - 2);
137         logger.info("Push " + getName() + " (" + blocksCache.size() + ") blocks [" + blocks + "]");
138         this.blocksBuiltCache.addAll(blocksCache);
139     }
140
141     private void flushNestedBlocksToCache() {
142         for (T collection : nestedExecutions) {
143             collection.flushBlocksFromCache(this.blocksBuiltCache);
144         }
145     }
146
147     public void flushBlocksFromCache(List<ExecuteBuildingBlock> blockList) {
148         flushNestedBlocksToCache();
149         if (this.blocksBuiltCache.size() > 0) {
150             String blocks = this.blocksBuiltCache.stream().map(x -> x.getBuildingBlock().getBpmnFlowName() + ", ")
151                     .reduce("", String::concat);
152             blocks = blocks.substring(0, blocks.length() - 2);
153             logger.info("Flush " + getName() + " (" + blocksBuiltCache.size() + ") blocks [" + blocks + "]");
154             blockList.addAll(this.blocksBuiltCache);
155             this.blocksBuiltCache.clear();
156         }
157     }
158
159     public int getCacheSize() {
160         return blocksBuiltCache.size()
161                 + getNestedExecutions().stream().mapToInt(x -> x.getCacheSize()).reduce(0, Integer::sum);
162     }
163
164     protected String getName() {
165         return type.name();
166     }
167 }