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