5bbd2aae32bb31b5e6cb7c7576b5efffd9053f0d
[sdc/sdc-tosca.git] / sdc-tosca / src / main / java / org / onap / sdc / tosca / parser / impl / QueryProcessor.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * sdc-tosca
4  * ================================================================================
5  * Copyright (C) 2017 - 2019 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.sdc.tosca.parser.impl;
22
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.stream.Collectors;
27 import org.onap.sdc.tosca.parser.api.IEntityDetails;
28 import org.onap.sdc.tosca.parser.elements.queries.EntityQuery;
29 import org.onap.sdc.tosca.parser.elements.queries.TopologyTemplateQuery;
30 import org.onap.sdc.tosca.parser.enums.EntityTemplateType;
31 import org.onap.sdc.tosca.parser.enums.SdcTypes;
32 import org.onap.sdc.toscaparser.api.NodeTemplate;
33 import org.onap.sdc.toscaparser.api.ToscaTemplate;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 /**
38  * Performs search for entity templates inside node template according to query criteria
39  */
40 class QueryProcessor {
41     private static final Logger logger = LoggerFactory.getLogger(QueryProcessor.class.getName());
42
43     private final EntityQuery entityQuery;
44     private final TopologyTemplateQuery topologyTemplateQuery;
45     private final ToscaTemplate toscaTemplate;
46     private boolean isRecursive = false;
47
48     QueryProcessor(ToscaTemplate toscaTemplate, EntityQuery entityQuery, TopologyTemplateQuery topologyTemplateQuery, boolean isRecursive) {
49         this.toscaTemplate = toscaTemplate;
50         this.entityQuery = entityQuery == null ? EntityQuery.newBuilder(EntityTemplateType.ALL).build() : entityQuery;
51         this.topologyTemplateQuery = topologyTemplateQuery;
52         this.isRecursive = isRecursive;
53     }
54
55     List<IEntityDetails> doQuery() {
56         final List<IEntityDetails> entityDetailsList = Collections.emptyList();
57         if (isServiceSearch()) {
58             //search for entities inside the service
59             if (logger.isDebugEnabled()) {
60                 logger.debug("Service {} is searched for {}", toscaTemplate.getMetaData().getValue(SdcPropertyNames.PROPERTY_NAME_NAME), entityQuery);
61             }
62             entityDetailsList.addAll(entityQuery.getEntitiesFromService(toscaTemplate));
63
64             if (!isRecursive) {
65                 return entityDetailsList;
66             }
67         }
68
69         List<NodeTemplate> foundTopologyTemplates = getInternalTopologyTemplates(toscaTemplate.getNodeTemplates(), false);
70         if (isRecursive) {
71             if (logger.isDebugEnabled()) {
72                 logger.debug("Search for entities recursively");
73             }
74             //go over internal topology templates of the found templates
75             // and search for instances of the same type
76             //if the queried topology template is "SERVICE",  search for all instances of templates in the service
77             List<NodeTemplate> internalTopologyTemplates = foundTopologyTemplates.stream()
78                     .filter(nt->nt.getSubMappingToscaTemplate() != null)
79                     .map(nt->getInternalTopologyTemplates(nt.getSubMappingToscaTemplate().getNodeTemplates(), true))
80                     .flatMap(List::stream)
81                     .collect(Collectors.toList());
82             foundTopologyTemplates.addAll(internalTopologyTemplates);
83         }
84         if (logger.isDebugEnabled()) {
85             logger.debug("Found topology templates {} matching following query criteria: {}",
86                     foundTopologyTemplates, topologyTemplateQuery);
87         }
88         //go over all node templates found according to query criteria and recursive flag and
89         // search for the requested entities.
90         entityDetailsList.addAll(searchEntitiesInsideTopologyTemplates(foundTopologyTemplates));
91
92         return entityDetailsList;
93     }
94
95     private Map<String, NodeTemplate> convertListToMap(List<NodeTemplate> nodeTemplateList) {
96         // we use map to avoid duplicate search through same node templates
97         return nodeTemplateList.stream()
98                 .collect(Collectors.toMap(NodeTemplate::getName, nt->nt, (nt1, nt2)->nt1));
99     }
100
101     private List<IEntityDetails> searchEntitiesInsideTopologyTemplates(List<NodeTemplate> foundTopologyTemplates) {
102         return convertListToMap(foundTopologyTemplates)
103                 .values()
104                 .stream()
105                 .map(entityQuery::getEntitiesFromTopologyTemplate)
106                 .flatMap(List::stream)
107                 .collect(Collectors.toList());
108     }
109
110     private boolean isServiceSearch() {
111         return topologyTemplateQuery.getNodeTemplateType() == SdcTypes.SERVICE;
112     }
113
114     private List<NodeTemplate> getInternalTopologyTemplates(List<NodeTemplate> nodeTemplateList, boolean isRecursive) {
115         if (nodeTemplateList != null) {
116             return nodeTemplateList
117                 .stream()
118                 .map(child -> getTopologyTemplatesByQuery(child, isRecursive))
119                 .flatMap(List::stream)
120                 .collect(Collectors.toList());
121         }
122         return Collections.emptyList();
123     }
124
125     private List<NodeTemplate> getTopologyTemplatesByQuery(NodeTemplate current, boolean isRecursive) {
126         final List<NodeTemplate> topologyTemplateList = Collections.emptyList();
127
128         boolean isTopologyTemplateFound = isRecursive ?
129                 SdcTypes.isComplex(current.getMetadata().getValue(SdcPropertyNames.PROPERTY_NAME_TYPE))
130                 : topologyTemplateQuery.isMatchingSearchCriteria(current);
131         if (isTopologyTemplateFound) {
132             topologyTemplateList.add(current);
133             if (!isRecursive) {
134                 //recursion stop condition
135                 return topologyTemplateList;
136             }
137         }
138         if (SdcTypes.isComplex(current.getMetadata().getValue(SdcPropertyNames.PROPERTY_NAME_TYPE)) &&
139                current.getSubMappingToscaTemplate() != null) {
140            //search the node template inside a given topology template
141             topologyTemplateList.addAll(current.getSubMappingToscaTemplate().getNodeTemplates()
142                     .stream()
143                     .map(nt->getTopologyTemplatesByQuery(nt, isRecursive))
144                     .flatMap(List::stream)
145                     .collect(Collectors.toList()));
146         }
147         return topologyTemplateList;
148     }
149
150 }