3f22b1adffc3cca3a0b5c986892d87c59306ba6b
[integration.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * Simulator
4  * ================================================================================
5  * Copyright (C) 2019 Nokia. 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.pnfsimulator.template.search;
22
23 import com.google.gson.JsonElement;
24 import com.google.gson.JsonObject;
25 import org.onap.pnfsimulator.template.search.handler.PrimitiveValueCriteriaBuilder;
26 import org.onap.pnfsimulator.template.search.viewmodel.FlatTemplateContent;
27 import org.springframework.beans.factory.annotation.Autowired;
28 import org.springframework.data.mongodb.core.MongoTemplate;
29 import org.springframework.data.mongodb.core.query.Criteria;
30 import org.springframework.data.mongodb.core.query.Query;
31 import org.springframework.stereotype.Component;
32
33 import java.util.List;
34 import java.util.Map;
35 import java.util.regex.Pattern;
36 import java.util.stream.Collectors;
37
38 @Component
39 public class TemplateSearchHelper {
40     private static final String PARENT_TO_CHILD_KEY_SEPARATOR = ":"; //compliant with flat json stored in db
41     private static final String FLATTENED_JSON_KEY_REGEX = PARENT_TO_CHILD_KEY_SEPARATOR + "%s(?:(\\[[\\d]+\\]))?$";
42     private static final String FLATTENED_TEMPLATES_VIEW = "flatTemplatesView";
43
44     private MongoTemplate mongoTemplate;
45     private PrimitiveValueCriteriaBuilder criteriaBuilder;
46
47     @Autowired
48     public TemplateSearchHelper(MongoTemplate mongoTemplate) {
49         this.mongoTemplate = mongoTemplate;
50         this.criteriaBuilder = new PrimitiveValueCriteriaBuilder();
51     }
52
53     public List<String> getIdsOfDocumentMatchingCriteria(JsonObject jsonCriteria) {
54         if (isNullValuePresentInCriteria(jsonCriteria)) {
55             throw new IllegalJsonValueException("Null values in search criteria are not supported.");
56         }
57         Criteria mongoDialectCriteria = composeCriteria(jsonCriteria);
58         Query query = new Query(mongoDialectCriteria);
59         List<FlatTemplateContent> flatTemplateContents = mongoTemplate.find(query, FlatTemplateContent.class, FLATTENED_TEMPLATES_VIEW);
60         return flatTemplateContents
61                 .stream()
62                 .map(FlatTemplateContent::getId)
63                 .collect(Collectors.toList());
64     }
65
66
67     private Criteria composeCriteria(JsonObject criteria) {
68         Criteria[] criteriaArr = criteria.entrySet()
69                 .stream()
70                 .map(this::mapEntryCriteriaWithRegex)
71                 .toArray(Criteria[]::new);
72         return criteriaArr.length > 0 ? new Criteria().andOperator(criteriaArr) : new Criteria();
73     }
74
75     private Criteria mapEntryCriteriaWithRegex(Map.Entry<String, JsonElement> entry) {
76         Pattern primitiveOrArrayElemKeyRegex = getCaseInsensitive(String.format(FLATTENED_JSON_KEY_REGEX, entry.getKey()));
77         Criteria criteriaForJsonKey = Criteria.where("k").regex(primitiveOrArrayElemKeyRegex);
78         Criteria criteriaWithValue = criteriaBuilder.applyValueCriteriaBasedOnPrimitiveType(criteriaForJsonKey.and("v"), entry.getValue().getAsJsonPrimitive());
79         return Criteria.where("keyValues").elemMatch(criteriaWithValue);
80
81     }
82
83     private boolean isNullValuePresentInCriteria(JsonObject jsonObject) {
84         return jsonObject.entrySet()
85                 .stream()
86                 .map(Map.Entry::getValue)
87                 .anyMatch(JsonElement::isJsonNull);
88     }
89
90     static Pattern getCaseInsensitive(String base) {
91         return Pattern.compile(base, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
92     }
93 }
94
95