8da382f7e512e8069e0049231ebe8563f2f8fa72
[aai/aai-common.git] / aai-core / src / main / java / org / openecomp / aai / parsers / query / LegacyQueryParser.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * org.openecomp.aai
4  * ================================================================================
5  * Copyright (C) 2017 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.openecomp.aai.parsers.query;
22
23 import java.io.UnsupportedEncodingException;
24 import java.net.URI;
25 import java.net.URISyntaxException;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Map.Entry;
31 import java.util.Set;
32
33 import javax.ws.rs.core.MultivaluedMap;
34
35 import org.openecomp.aai.exceptions.AAIException;
36 import org.openecomp.aai.introspection.Introspector;
37 import org.openecomp.aai.introspection.Loader;
38 import org.openecomp.aai.introspection.exceptions.AAIUnknownObjectException;
39 import org.openecomp.aai.parsers.uri.Parsable;
40 import org.openecomp.aai.parsers.uri.URIParser;
41 import org.openecomp.aai.parsers.uri.URIToObject;
42 import org.openecomp.aai.query.builder.QueryBuilder;
43 import org.openecomp.aai.restcore.util.URITools;
44 import org.openecomp.aai.schema.enums.PropertyMetadata;
45 import org.openecomp.aai.serialization.db.EdgeType;
46 import com.att.eelf.configuration.EELFLogger;
47 import com.att.eelf.configuration.EELFManager;
48
49 /**
50  * The Class LegacyQueryParser.
51  */
52 public class LegacyQueryParser extends QueryParser implements Parsable {
53
54         private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(LegacyQueryParser.class);
55
56         private Introspector previous = null;
57
58         /**
59          * Instantiates a new legacy query parser.
60          *
61          * @param loader the loader
62          * @param queryBuilder the query builder
63          * @param uri the uri
64          * @throws UnsupportedEncodingException the unsupported encoding exception
65          * @throws AAIException the AAI exception
66          */
67         public LegacyQueryParser(Loader loader, QueryBuilder queryBuilder, URI uri) throws UnsupportedEncodingException, AAIException {
68                 super(loader, queryBuilder, uri);
69                 URIParser parser = new URIParser(loader, uri);
70                 parser.parse(this);
71         }
72         
73         /**
74          * Instantiates a new legacy query parser.
75          *
76          * @param loader the loader
77          * @param queryBuilder the query builder
78          * @param uri the uri
79          * @param queryParams the query params
80          * @throws UnsupportedEncodingException the unsupported encoding exception
81          * @throws AAIException the AAI exception
82          */
83         public LegacyQueryParser(Loader loader, QueryBuilder queryBuilder, URI uri, MultivaluedMap<String, String> queryParams) throws UnsupportedEncodingException, AAIException {
84                 super(loader, queryBuilder, uri);
85                 URIParser parser = new URIParser(loader, uri, queryParams);
86                 parser.parse(this);
87         }
88
89         /**
90          * Instantiates a new legacy query parser.
91          *
92          * @param loader the loader
93          * @param queryBuilder the query builder
94          */
95         public LegacyQueryParser(Loader loader, QueryBuilder queryBuilder) {
96                 super(loader, queryBuilder);
97         }
98         
99         /**
100          * @throws AAIException 
101          * @{inheritDoc}
102          */
103         @Override
104         public void processObject(Introspector obj, MultivaluedMap<String, String> uriKeys) throws AAIException {
105                 if (previous != null) {
106                         this.parentResourceType = previous.getDbName();
107                         queryBuilder.createEdgeTraversal(EdgeType.TREE, previous, obj);
108                 }
109                 if (previous == null) {
110                         queryBuilder.createDBQuery(obj);
111                         this.handleUriKeys(obj, uriKeys);
112                 } else {
113                         queryBuilder.createKeyQuery(obj);
114                         this.handleUriKeys(obj, uriKeys);
115                 }
116                 previous = obj;
117                 this.resultResource = obj.getDbName();
118         }
119         
120         /**
121          * @{inheritDoc}
122          */
123         @Override
124         public void processContainer(Introspector obj, MultivaluedMap<String, String> uriKeys, boolean isFinalContainer) throws AAIException {
125                 if (isFinalContainer) {
126                         if (previous != null) {
127                                 this.parentResourceType = previous.getDbName();
128                                 queryBuilder.createEdgeTraversal(EdgeType.TREE, previous, obj);
129                         }
130                         
131                         if (previous == null) {
132                                 queryBuilder.createContainerQuery(obj);
133                                 queryBuilder.markParentBoundary();
134                         }
135                         if (!uriKeys.isEmpty()) {
136
137                                 try {
138                                         Introspector child = obj.newIntrospectorInstanceOfNestedProperty(obj.getChildName());
139                                         this.handleUriKeys(child, uriKeys);
140                                 } catch (AAIUnknownObjectException e) {
141                                         LOGGER.warn("Skipping container child " + obj.getChildName() + " (Unknown Object)", e);
142                                 }
143                         }
144                         
145                         this.resultResource = obj.getChildDBName();
146                         this.containerResource = obj.getName();
147                 }
148         }
149         
150         private void handleUriKeys(Introspector obj, MultivaluedMap<String, String> uriKeys) throws AAIException {
151                 for (String key : uriKeys.keySet()) {
152                         //to validate whether this property exists
153                         if (!obj.hasProperty(key)) {
154                                 throw new AAIException("AAI_3000", "property: " + key + " not found on " + obj.getDbName());
155                         }
156
157                         List<String> values = uriKeys.get(key);
158                         String dbPropertyName = key;
159                         Map<String, String> linkedProperties = new HashMap<>();
160                         final Map<PropertyMetadata, String> metadata = obj.getPropertyMetadata(key);
161                         if (metadata.containsKey(PropertyMetadata.DATA_LINK)) {
162                                 linkedProperties.put(key, metadata.get(PropertyMetadata.DATA_LINK));
163                         }
164                         if (metadata.containsKey(PropertyMetadata.DB_ALIAS)) {
165                                 dbPropertyName = metadata.get(PropertyMetadata.DB_ALIAS);
166                         }
167                         
168                         if (!linkedProperties.containsKey(key)) {
169                                 if (values.size() > 1) {
170                                         queryBuilder.getVerticesByIndexedProperty(dbPropertyName, obj.castValueAccordingToSchema(key, values));
171                                 } else {
172                                         queryBuilder.getVerticesByIndexedProperty(dbPropertyName, obj.castValueAccordingToSchema(key, values.get(0)));
173                                 }
174                         }
175                         handleLinkedProperties(obj, uriKeys, linkedProperties);
176                 }
177         }
178         private void handleLinkedProperties(Introspector obj, MultivaluedMap<String, String> uriKeys, Map<String, String> linkedProperties) throws AAIException {
179                 
180                 QueryBuilder[] builders = new QueryBuilder[linkedProperties.keySet().size()];
181                 Set<Entry<String, String>> entrySet = linkedProperties.entrySet();
182                 int i = 0;
183                 Iterator<Entry<String, String>> itr = entrySet.iterator();
184                 
185                 while (itr.hasNext()) {
186                         Entry<String, String> entry = itr.next();
187                         Introspector child;
188                         try {
189                                 child = new URIToObject(this.latestLoader, new URI(URITools.replaceTemplates(obj, entry.getValue(), PropertyMetadata.DATA_LINK, true).orElse(""))).getEntity();
190                         } catch (IllegalArgumentException | UnsupportedEncodingException | URISyntaxException e) {
191                                 throw new AAIException("AAI_4000", e);
192                         } 
193                         List<String> values = uriKeys.get(entry.getKey());
194                         QueryBuilder builder = queryBuilder.newInstance();
195                         builder.createEdgeTraversal(EdgeType.TREE, obj, child);
196                         if (values.size() > 1) {
197                                 builder.getVerticesByIndexedProperty(entry.getKey(), obj.castValueAccordingToSchema(entry.getKey(), values));
198                         } else {
199                                 builder.getVerticesByIndexedProperty(entry.getKey(), obj.castValueAccordingToSchema(entry.getKey(), values.get(0)));
200                         }
201                         
202                         builders[i] = builder;
203                         i++;
204                 }
205                 
206                 queryBuilder.where(builders);
207                 
208         }
209
210         /**
211          * @{inheritDoc}
212          */
213         @Override
214         public void processNamespace(Introspector obj) {
215         
216         }
217         
218         /**
219          * @{inheritDoc}
220          */
221         @Override
222         public String getCloudRegionTransform() {
223                 return "add";
224         }
225         
226         /**
227          * @{inheritDoc}
228          */
229         @Override
230         public boolean useOriginalLoader() {
231                 return false;
232         }
233 }