Enhancements for the aai-common library
[aai/aai-common.git] / aai-core / src / main / java / org / onap / aai / serialization / queryformats / HistoryFormat.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
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
10  * <p>
11  * http://www.apache.org/licenses/LICENSE-2.0
12  * <p>
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.aai.serialization.queryformats;
22
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25 import com.google.gson.Gson;
26 import com.google.gson.JsonArray;
27 import com.google.gson.JsonObject;
28 import com.google.gson.JsonParser;
29 import org.apache.tinkerpop.gremlin.structure.*;
30 import org.onap.aai.db.props.AAIProperties;
31 import org.onap.aai.introspection.Loader;
32 import org.onap.aai.serialization.db.DBSerializer;
33 import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
34 import org.onap.aai.serialization.queryformats.params.Depth;
35 import org.onap.aai.serialization.queryformats.params.EndTs;
36 import org.onap.aai.serialization.queryformats.params.NodesOnly;
37 import org.onap.aai.serialization.queryformats.params.StartTs;
38 import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
39
40 import java.util.Iterator;
41 import java.util.List;
42 import java.util.Set;
43 import java.util.stream.Collectors;
44 import java.util.stream.Stream;
45
46 public abstract class HistoryFormat extends MultiFormatMapper {
47
48     private static final Logger LOGGER = LoggerFactory.getLogger(HistoryFormat.class);
49
50     protected static final String KEY = "key";
51     protected static final String VALUE = "value";
52     protected static final String TIMESTAMP = "timestamp";
53     protected static final String NODE_TYPE = "node-type";
54     protected static final String END_TIMESTAMP = "end-timestamp";
55     protected static final String SOT = "sot";
56     protected static final String END_SOT = "end-sot";
57     protected static final String TX_ID = "tx-id";
58     protected static final String END_TX_ID = "end-tx-id";
59     protected static final String PROPERTIES = "properties";
60     protected static final String RELATED_TO = "related-to";
61     protected static final String NODE_ACTIONS = "node-actions";
62
63     protected JsonParser parser = new JsonParser();
64     protected final DBSerializer serializer;
65     protected final Loader loader;
66     protected final UrlBuilder urlBuilder;
67     protected final int depth;
68     protected final boolean nodesOnly;
69     protected long startTs;
70     protected long endTs;
71     protected static final Set<String> ignoredKeys =
72         Stream.of(AAIProperties.LAST_MOD_TS, AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, AAIProperties.CREATED_TS)
73         .collect(Collectors.toSet());
74
75     protected HistoryFormat(Builder builder) {
76         this.urlBuilder = builder.getUrlBuilder();
77         this.loader = builder.getLoader();
78         this.serializer = builder.getSerializer();
79         this.depth = builder.getDepth();
80         this.nodesOnly = builder.isNodesOnly();
81         this.startTs = builder.getStartTs();
82         this.endTs = builder.getEndTs();
83     }
84
85     @Override
86     public int parallelThreshold() {
87         return 100;
88     }
89
90     protected JsonObject createMetaPropertiesObject(VertexProperty<Object> prop) {
91         JsonObject json = new JsonObject();
92         Iterator iter = prop.properties();
93
94         while (iter.hasNext()) {
95             Property<Object> metaProp = (Property) iter.next();
96             mapPropertyValues(json, metaProp.key(), metaProp.value());
97         }
98
99         return json;
100     }
101
102     protected JsonObject mapPropertyValues(JsonObject json, String propertyKey, Object propertyValue) {
103         if (propertyValue instanceof String) {
104             json.addProperty(propertyKey, (String) propertyValue);
105         } else if (propertyValue instanceof Boolean) {
106             json.addProperty(propertyKey, (Boolean) propertyValue);
107         } else if (propertyValue instanceof Number) {
108             json.addProperty(propertyKey, (Number) propertyValue);
109         } else {
110             if (!(propertyValue instanceof List)) {
111                 return json;
112             }
113
114             Gson gson = new Gson();
115             String list = gson.toJson(propertyValue);
116             json.addProperty(propertyKey, list);
117         }
118         return json;
119     }
120
121     protected JsonArray createRelationshipObject(Vertex v) throws AAIFormatVertexException {
122         JsonArray relatedToList = new JsonArray();
123         Iterator<Edge> inIter = v.edges(Direction.IN);
124         Iterator<Edge> outIter = v.edges(Direction.OUT);
125
126         while (inIter.hasNext()) {
127             Edge e = inIter.next();
128             if (isValidEdge(e)) {
129                 relatedToList.add(getRelatedObject(e, e.outVertex()));
130             }
131         }
132
133         while (outIter.hasNext()) {
134             Edge e = outIter.next();
135             if (isValidEdge(e)) {
136                 relatedToList.add(getRelatedObject(e, e.inVertex()));
137             }
138         }
139
140         return relatedToList;
141
142     }
143
144     protected abstract boolean isValidEdge(Edge e);
145
146     protected abstract JsonObject getRelatedObject(Edge e, Vertex related) throws AAIFormatVertexException;
147
148
149
150     public static class Builder implements NodesOnly<Builder>, Depth<Builder>, StartTs<Builder>, EndTs<Builder> {
151
152         protected final Loader loader;
153         protected final DBSerializer serializer;
154         protected final UrlBuilder urlBuilder;
155         protected boolean includeUrl = false;
156         protected boolean nodesOnly = false;
157         protected int depth = 1;
158         protected boolean modelDriven = false;
159         protected long startTs = -1;
160         protected long endTs = -1;
161
162         public Builder(Loader loader, DBSerializer serializer, UrlBuilder urlBuilder) {
163             this.loader = loader;
164             this.serializer = serializer;
165             this.urlBuilder = urlBuilder;
166         }
167
168         protected Loader getLoader() {
169             return this.loader;
170         }
171
172         protected DBSerializer getSerializer() {
173             return this.serializer;
174         }
175
176         protected UrlBuilder getUrlBuilder() {
177             return this.urlBuilder;
178         }
179
180         public Builder includeUrl() {
181             this.includeUrl = true;
182             return this;
183         }
184
185         public Builder nodesOnly(Boolean nodesOnly) {
186             this.nodesOnly = nodesOnly;
187             return this;
188         }
189
190         public Builder startTs(String startTs) {
191             this.startTs = Long.parseLong(startTs);
192             return this;
193         }
194
195         public Builder endTs(String endTs) {
196             this.endTs = Long.parseLong(endTs);
197             return this;
198         }
199
200
201         public boolean isNodesOnly() {
202             return this.nodesOnly;
203         }
204
205         public Builder depth(Integer depth) {
206             this.depth = depth;
207             return this;
208         }
209
210         public int getDepth() {
211             return this.depth;
212         }
213
214         public boolean isIncludeUrl() {
215             return this.includeUrl;
216         }
217
218         public Builder modelDriven() {
219             this.modelDriven = true;
220             return this;
221         }
222
223         public boolean getModelDriven() {
224             return this.modelDriven;
225         }
226
227         public long getStartTs() {
228             return this.startTs;
229         }
230
231         public long getEndTs() {
232             return this.endTs;
233         }
234
235         public HistoryFormat build(Format format) {
236
237             if(Format.state.equals(format)) {
238                 return new StateFormat(this);
239             } else {
240                 return new LifecycleFormat(this);
241             }
242
243         }
244     }
245
246 }