2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 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
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=========================================================
20 package org.onap.aai.cacher.injestion.parser.strategy.aai.dmaap;
22 import com.att.eelf.configuration.EELFLogger;
23 import com.att.eelf.configuration.EELFManager;
24 import com.google.gson.JsonArray;
25 import com.google.gson.JsonElement;
26 import com.google.gson.JsonObject;
27 import org.onap.aai.cacher.injestion.parser.strategy.AAIResourceGetAllPayloadParserStrategy;
28 import org.onap.aai.cacher.injestion.parser.strategy.aai.AAIResourcesUriTemplates;
29 import org.onap.aai.cacher.injestion.parser.strategy.aai.AAIUriSegment;
30 import org.onap.aai.cacher.model.CacheEntry;
31 import org.springframework.beans.factory.annotation.Autowired;
32 import org.springframework.beans.factory.config.ConfigurableBeanFactory;
33 import org.springframework.context.annotation.Scope;
34 import org.springframework.stereotype.Component;
35 import org.springframework.util.LinkedMultiValueMap;
36 import org.springframework.util.MultiValueMap;
38 import java.util.ArrayList;
39 import java.util.List;
41 import java.util.Optional;
42 import java.util.stream.Collectors;
45 * AAI resource get all parser strategy
47 @Component(value = "aai-resource-dmaap")
48 @Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON)
49 public class AAIResourceDmaapParserStrategy extends AAIResourceGetAllPayloadParserStrategy {
51 private final static EELFLogger LOGGER = EELFManager.getInstance().getLogger(AAIResourceDmaapParserStrategy.class);
54 public AAIResourceDmaapParserStrategy(AAIResourcesUriTemplates aaiResourcesUriTemplates) {
55 super(aaiResourcesUriTemplates);
59 * Parses aai resources specific payloads generating the details for caching.
66 public List<CacheEntry> process(String originalKey, JsonObject jsonObject) {
67 final List<CacheEntry> cacheEntries;
69 JsonObject header = jsonObject.getAsJsonObject("event-header");
70 String topEntityType = header.get("top-entity-type").getAsString();
71 String fullUri = header.get("entity-link").getAsString();
72 if ( fullUri.endsWith("/")) {
73 fullUri = fullUri.substring(0, fullUri.length() - 1);
75 String entityUri = aaiResourcesUriTemplates.getAAIUriFromEntityUri(fullUri);
76 String fullUriPrefix = aaiResourcesUriTemplates.getAAIUriFromEntityUriPrefix(fullUri);
78 DmaapAction actionType = DmaapAction.valueOf(header.get("action").getAsString());
80 List<AAIUriSegment> uriSegments = aaiResourcesUriTemplates.getAaiUriSegments(entityUri);
82 // get base uri so if is top lvl use "" else go 1 back from current node type. to reuse exist functions.
83 String baseUri = getBaseUri(uriSegments);
85 // get wrapped wrap obj it looks like a get-all result with 1
86 // will wrap address lists even though they do not normally have a wrapper
87 JsonObject wrappedEntityObject = getWrappedEntityObject(jsonObject.getAsJsonObject("entity"), uriSegments);
90 cacheEntries = internalProcess(topEntityType, wrappedEntityObject, baseUri);
92 // modify action to map to dmaap event type
93 cacheEntries.forEach(cacheEntry -> cacheEntry.setDbAction(actionType.getDbAction()));
95 // cache entries for relationships
96 MultiValueMap<String, AAIRelatedToDetails> cacheEntriesRelationships =
97 getFromRelationshipFullUriToRelationshipObj(cacheEntries, fullUriPrefix, actionType);
99 if (jsonObject.has("existing-obj")) {
100 MultiValueMap<String, AAIRelatedToDetails> existingCacheEntriesRelationships =
101 getFromRelationshipFullUriToRelationshipObj(
102 internalProcess(topEntityType, jsonObject.getAsJsonObject("existing-obj"), baseUri),
106 adjustRelationshipsBasedOnExisting(existingCacheEntriesRelationships, cacheEntriesRelationships);
110 cacheEntries.addAll(getRelationshipCacheEntries(cacheEntriesRelationships));
112 getParentUpdateCacheEntryIfNeeded(topEntityType, entityUri, actionType, uriSegments).ifPresent(cacheEntries::add);
117 private Optional<CacheEntry> getParentUpdateCacheEntryIfNeeded(String topEntityType, String entityUri, DmaapAction actionType, List<AAIUriSegment> uriSegments) {
119 if (uriSegments.size() <= 1) {
120 return Optional.empty();
123 switch (actionType) {
125 return Optional.of(getParentUpdateCacheEntry(topEntityType, entityUri, actionType, uriSegments));
127 return Optional.of(getParentUpdateCacheEntry(topEntityType, entityUri, DmaapAction.UPDATE, uriSegments));
129 return Optional.empty();
133 private CacheEntry getParentUpdateCacheEntry(String topEntityType, String entityUri, DmaapAction actionType, List<AAIUriSegment> uriSegments) {
134 String parentUri = String.join(
136 uriSegments.stream().limit(uriSegments.size()-1).map(AAIUriSegment::getSegment).collect(Collectors.toList()));
137 JsonObject findQuery = new JsonObject();
138 findQuery.addProperty("_id", parentUri);
139 JsonObject nestedFindQuery = new JsonObject();
140 nestedFindQuery.addProperty("_id", parentUri);
141 StringBuilder nestedField = new StringBuilder();
142 uriSegments.get(uriSegments.size()-1).getSegmentPlural().ifPresent(plural -> nestedField.append(plural).append("."));
143 nestedField.append(uriSegments.get(uriSegments.size()-1).getSegmentSingular());
144 JsonObject nestedIdentifier = new JsonObject();
145 JsonArray ja = new JsonArray();
147 nestedIdentifier.add("$in", ja);
148 return CacheEntry.CacheEntryBuilder.createCacheEntry()
149 .inCollection(topEntityType)
150 .withDbAction(actionType.getDbAction())
153 .isNestedPayloadString(true)
154 .withNestedString(entityUri)
155 .withFindQuery(findQuery)
156 .withNestedFind(nestedFindQuery)
157 .withNestedField(nestedField.toString())
158 .withNestedFieldIdentifierObj(nestedIdentifier)
162 private List<CacheEntry> getRelationshipCacheEntries(MultiValueMap<String, AAIRelatedToDetails> cacheEntriesRelationships) {
163 final List<CacheEntry> cacheEntries = new ArrayList<>();
164 JsonObject relatedToObj;
165 for (Map.Entry<String, List<AAIRelatedToDetails>> relationship : cacheEntriesRelationships.entrySet()) {
166 for (AAIRelatedToDetails aaiRelatedToDetails : relationship.getValue()) {
167 relatedToObj = fullUriToRelationshipObj(relationship.getKey(), aaiRelatedToDetails.getLabel());
168 cacheEntries.add(generateRelationshipCacheEntry(relatedToObj, aaiRelatedToDetails.getActionType(),
169 aaiRelatedToDetails.getFullUri()));
175 private CacheEntry generateRelationshipCacheEntry(JsonObject entity, DmaapAction actionType, String fullUri) {
177 String uri = aaiResourcesUriTemplates.getAAIUriFromEntityUri(fullUri);
178 List<AAIUriSegment> uriSegmentList = aaiResourcesUriTemplates.getAaiUriSegments(uri);
179 String collection = uriSegmentList.get(0).getSegmentSingular();
180 JsonObject findQuery = new JsonObject();
181 findQuery.addProperty("_id", uri);
182 JsonObject nestedFindQuery = new JsonObject();
183 nestedFindQuery.addProperty("_id", uri);
184 nestedFindQuery.addProperty("relationship-list.relationship.related-link", entity.get("related-link").getAsString());
185 String nestedField = "relationship-list.relationship";
186 JsonObject nestedIdentifier = new JsonObject();
187 nestedIdentifier.addProperty("related-link", entity.get("related-link").getAsString());
189 return CacheEntry.CacheEntryBuilder.createCacheEntry().inCollection(collection).withDbAction(actionType.getDbAction())
190 .withId(uri).isNested(true).withPayload(entity).withFindQuery(findQuery)
191 .withNestedFind(nestedFindQuery).withNestedField(nestedField)
192 .withNestedFieldIdentifierObj(nestedIdentifier).build();
195 private void adjustRelationshipsBasedOnExisting(MultiValueMap<String, AAIRelatedToDetails> existingCacheEntriesRelationships,
196 MultiValueMap<String, AAIRelatedToDetails> cacheEntriesRelationships) {
197 existingCacheEntriesRelationships.forEach((k, v) -> {
198 if (cacheEntriesRelationships.containsKey(k)) {
201 for (int i = 0; i < cacheEntriesRelationships.get(k).size(); i++) {
202 if (cacheEntriesRelationships.get(k).get(i).getFullUri().equals(oldA.getFullUri())) {
208 cacheEntriesRelationships.get(k).remove(cacheEntriesRelationships.get(k).get(found));
210 oldA.setActionType(DmaapAction.DELETE);
211 cacheEntriesRelationships.get(k).add(oldA);
215 v.forEach(aaiRelatedToDetails -> {
216 aaiRelatedToDetails.setActionType(DmaapAction.DELETE);
217 cacheEntriesRelationships.add(k, aaiRelatedToDetails);
223 private MultiValueMap<String, AAIRelatedToDetails> getFromRelationshipFullUriToRelationshipObj(
224 List<CacheEntry> cacheEntries,
225 String fullUriPrefix,
226 DmaapAction actionType) {
227 final MultiValueMap<String, AAIRelatedToDetails> relationshipMapping = new LinkedMultiValueMap<>();
228 for (CacheEntry cacheEntry : cacheEntries) {
229 for (Map.Entry<String, JsonElement> e : cacheEntry.getPayload().entrySet()) {
230 if (e.getKey().equals("relationship-list") && e.getValue().isJsonObject()) {
231 JsonArray relationships = e.getValue().getAsJsonObject().getAsJsonArray("relationship");
232 for (JsonElement relationship : relationships) {
233 relationshipMapping.add(fullUriPrefix + cacheEntry.getId(), new AAIRelatedToDetails(
234 relationship.getAsJsonObject().get("related-link").getAsString(),
235 relationship.getAsJsonObject().get("relationship-label").getAsString(), actionType));
240 return relationshipMapping;
244 * Given fullUri uri generate an aai relationship obj
249 protected JsonObject fullUriToRelationshipObj(String fullUri, String label) {
250 final JsonObject relObj = new JsonObject();
251 final JsonArray relData = new JsonArray();
252 String uri = aaiResourcesUriTemplates.getAAIUriFromEntityUri(fullUri);
253 List<AAIUriSegment> uriSegmentList = aaiResourcesUriTemplates.getAaiUriSegments(uri);
255 relObj.addProperty("related-to", uriSegmentList.get(uriSegmentList.size() - 1).getSegmentSingular());
257 relObj.addProperty("relationship-label", label);
259 relObj.addProperty("related-link", fullUri);
261 for (AAIUriSegment aaiUriSegment : uriSegmentList) {
262 aaiUriSegment.getSegmentKeyValues().forEach((k, v) -> {
263 JsonObject relDataEntry;
264 relDataEntry = new JsonObject();
265 relDataEntry.addProperty("relationship-key", aaiUriSegment.getSegmentSingular() + "." + k);
266 relDataEntry.addProperty("relationship-value", v);
267 relData.add(relDataEntry);
270 relObj.add("relationship-data", relData);
275 private JsonObject getWrappedEntityObject(JsonObject dmaapEntity, List<AAIUriSegment> uriSegments) {
276 JsonObject objectWrapper = new JsonObject();
277 JsonArray arrayWrapper = new JsonArray();
278 String arrayKey = uriSegments.get(0).getSegmentSingular();
279 JsonObject entityBody = dmaapEntity.getAsJsonObject();
281 if (uriSegments.size() > 1) {
282 Optional<String> segmentPlural;
283 String segmentSingular;
287 JsonElement jsonElement;
289 for (int i = 1; i < uriSegments.size(); i++) {
291 if (uriSegments.get(i).getSegmentPlural().isPresent()) {
292 segmentPlural = uriSegments.get(i).getSegmentPlural();
293 segmentSingular = uriSegments.get(i).getSegmentSingular();
294 if ( segmentSingular.equals("cvlan-tag")) {
295 // map to what is in the entity
296 segmentSingular = "cvlan-tag-entry";
298 jsonObj = entityBody.getAsJsonObject(uriSegments.get(i).getSegmentPlural().get());
299 jsonArray = jsonObj.getAsJsonArray(segmentSingular);
300 if ( jsonArray == null ) {
301 LOGGER.error("failed in getWrappedEntityObject " + segmentSingular + " not found in " + jsonObj );
302 // exception expected for missing template
304 entityBody = jsonArray.get(0).getAsJsonObject();
305 arrayKey = uriSegments.get(i).getSegmentSingular();
307 entityBody = entityBody.getAsJsonArray(uriSegments.get(i).getSegmentSingular()).get(0).getAsJsonObject();
308 arrayKey = uriSegments.get(i).getSegmentSingular();
313 arrayWrapper.add(entityBody);
314 objectWrapper.add(arrayKey, arrayWrapper);
315 return objectWrapper;
318 private String getBaseUri(List<AAIUriSegment> uriSegments) {
319 if (uriSegments.isEmpty() || uriSegments.size() == 1) {
322 return String.join("", uriSegments.subList(0, uriSegments.size()-1).stream().map(AAIUriSegment::getSegment).collect(Collectors.toList()));