2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.pnfsimulator.template.search;
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;
33 import java.util.List;
35 import java.util.regex.Pattern;
36 import java.util.stream.Collectors;
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";
44 private MongoTemplate mongoTemplate;
45 private PrimitiveValueCriteriaBuilder criteriaBuilder;
48 public TemplateSearchHelper(MongoTemplate mongoTemplate) {
49 this.mongoTemplate = mongoTemplate;
50 this.criteriaBuilder = new PrimitiveValueCriteriaBuilder();
53 public List<String> getIdsOfDocumentMatchingCriteria(JsonObject jsonCriteria) {
54 if (isNullValuePresentInCriteria(jsonCriteria)) {
55 throw new IllegalJsonValueException("Null values in search criteria are not supported.");
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
62 .map(FlatTemplateContent::getId)
63 .collect(Collectors.toList());
67 private Criteria composeCriteria(JsonObject criteria) {
68 Criteria[] criteriaArr = criteria.entrySet()
70 .map(this::mapEntryCriteriaWithRegex)
71 .toArray(Criteria[]::new);
72 return criteriaArr.length > 0 ? new Criteria().andOperator(criteriaArr) : new Criteria();
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);
83 private boolean isNullValuePresentInCriteria(JsonObject jsonObject) {
84 return jsonObject.entrySet()
86 .map(Map.Entry::getValue)
87 .anyMatch(JsonElement::isJsonNull);
90 static Pattern getCaseInsensitive(String base) {
91 return Pattern.compile(base, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);