Merge "Fixed Sonar "Blocker Bugs""
[aai/aai-common.git] / aai-core / src / main / java / org / onap / aai / dbmap / AAIGraph.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  *  Modifications Copyright © 2018 IBM.
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *    http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.aai.dbmap;
24
25 import com.att.eelf.configuration.EELFLogger;
26 import com.att.eelf.configuration.EELFManager;
27 import java.io.FileNotFoundException;
28 import java.util.HashMap;
29 import java.util.Map;
30 import java.util.Properties;
31 import org.apache.commons.configuration.ConfigurationException;
32 import org.apache.commons.configuration.PropertiesConfiguration;
33 import org.apache.commons.lang.exception.ExceptionUtils;
34 import org.apache.tinkerpop.gremlin.structure.Graph;
35 import org.apache.tinkerpop.gremlin.structure.io.IoCore;
36 import org.janusgraph.core.JanusGraph;
37 import org.janusgraph.core.JanusGraphFactory;
38 import org.janusgraph.core.schema.JanusGraphManagement;
39 import org.onap.aai.dbgen.SchemaGenerator;
40 import org.onap.aai.exceptions.AAIException;
41 import org.onap.aai.util.AAIConstants;
42
43 /**
44  * Database Mapping class which acts as the middle man between the REST
45  * interface objects and JanusGraph DB objects. This class provides methods to commit
46  * the objects received on the REST interface into the JanusGraph graph database as
47  * vertices and edges. Transactions are also managed here by using a JanusGraph
48  * object to load, commit/rollback and shutdown for each request. The data model
49  * rules such as keys/required properties are handled by calling DBMeth methods
50  * which are driven by a specification file in json.
51  * 
52  * 
53  */
54 public class AAIGraph {
55
56     private static final EELFLogger logger = EELFManager.getInstance().getLogger(AAIGraph.class);
57     protected static final String COMPONENT = "aaidbmap";
58     protected Map<String, JanusGraph> graphs = new HashMap<>();
59     private static final String REALTIME_DB = "realtime";
60     private static final String CACHED_DB = "cached";
61     private static boolean isInit = false;
62
63     /**
64      * Instantiates a new AAI graph.
65      */
66     private AAIGraph() {
67         try {
68             String serviceName = System.getProperty("aai.service.name", "NA");
69             String rtConfig = System.getProperty("realtime.db.config");
70             String cachedConfig = System.getProperty("cached.db.config");
71             if (rtConfig == null) {
72                 rtConfig = AAIConstants.REALTIME_DB_CONFIG;
73             }
74             if (cachedConfig == null) {
75                 cachedConfig = AAIConstants.CACHED_DB_CONFIG;
76             }
77             this.loadGraph(REALTIME_DB, rtConfig, serviceName);
78             this.loadGraph(CACHED_DB, cachedConfig, serviceName);
79         } catch (Exception e) {
80             throw new RuntimeException("Failed to instantiate graphs", e);
81         }
82     }
83
84     private static class Helper {
85         private static final AAIGraph INSTANCE = new AAIGraph();
86
87         private Helper() {
88
89         }
90     }
91
92     /**
93      * Gets the single instance of AAIGraph.
94      *
95      * @return single instance of AAIGraph
96      */
97     public static AAIGraph getInstance() {
98         isInit = true;
99         return Helper.INSTANCE;
100     }
101
102     public static boolean isInit() {
103         return isInit;
104     }
105
106     private void loadGraph(final String name, final String configPath, final String serviceName)
107         throws AAIException, ConfigurationException {
108         // Graph being opened by JanusGraphFactory is being placed in hashmap to be used later
109         // These graphs shouldn't be closed until the application shutdown
110         try {
111             final PropertiesConfiguration propertiesConfiguration =
112                 new AAIGraphConfig.Builder(configPath).forService(serviceName).withGraphType(name).buildConfiguration();
113             final JanusGraph graph = JanusGraphFactory.open(propertiesConfiguration);
114
115             final Properties graphProps = new Properties();
116             propertiesConfiguration.getKeys()
117                 .forEachRemaining(k -> graphProps.setProperty(k, propertiesConfiguration.getString(k)));
118
119             if ("inmemory".equals(graphProps.get("storage.backend"))) {
120                 // Load the propertyKeys, indexes and edge-Labels into the DB
121                 loadSchema(graph);
122                 loadSnapShotToInMemoryGraph(graph, graphProps);
123             }
124
125             if (graph == null) {
126                 throw new AAIException("AAI_5102");
127             }
128
129             graphs.put(name, graph);
130         } catch (final FileNotFoundException fnfe) {
131             throw new AAIException("AAI_4001");
132         }
133     }
134
135     private void loadSnapShotToInMemoryGraph(final JanusGraph graph, final Properties graphProps) {
136         if (logger.isDebugEnabled()) {
137             logger.debug("Load Snapshot to InMemory Graph");
138         }
139         if (graphProps.containsKey("load.snapshot.file")) {
140             String value = graphProps.getProperty("load.snapshot.file");
141             if ("true".equals(value)) {
142                 try (Graph transaction = graph.newTransaction()) {
143                     String location = System.getProperty("snapshot.location");
144                     logAndPrint(logger, "Loading snapshot to inmemory graph.");
145                     transaction.io(IoCore.graphson()).readGraph(location);
146                     transaction.tx().commit();
147                     logAndPrint(logger, "Snapshot loaded to inmemory graph.");
148                 } catch (Exception e) {
149                     logAndPrint(logger, "ERROR: Could not load datasnapshot to in memory graph. \n"
150                             + ExceptionUtils.getFullStackTrace(e));
151                     throw new RuntimeException(e);
152                 }
153             }
154         }
155     }
156
157     private void loadSchema(final JanusGraph graph) {
158         // Load the propertyKeys, indexes and edge-Labels into the DB
159         JanusGraphManagement graphMgt = graph.openManagement();
160
161         System.out.println("-- loading schema into JanusGraph");
162         SchemaGenerator.loadSchemaIntoJanusGraph(graph, graphMgt, "inmemory");
163     }
164
165     /**
166      * Close all of the graph connections made in the instance.
167      */
168     public void graphShutdown() {
169         graphs.values().stream().filter(JanusGraph::isOpen).forEach(JanusGraph::close);
170     }
171
172     /**
173      * Gets the graph.
174      *
175      * @return the graph
176      */
177     public JanusGraph getGraph() {
178         return graphs.get(REALTIME_DB);
179     }
180
181     public void graphShutdown(final DBConnectionType connectionType) {
182
183         graphs.get(this.getGraphName(connectionType)).close();
184     }
185
186     public JanusGraph getGraph(final DBConnectionType connectionType) {
187         return graphs.get(this.getGraphName(connectionType));
188     }
189
190     private String getGraphName(final DBConnectionType connectionType) {
191         String graphName = "";
192         if (DBConnectionType.CACHED.equals(connectionType)) {
193             graphName = this.CACHED_DB;
194         } else if (DBConnectionType.REALTIME.equals(connectionType)) {
195             graphName = this.REALTIME_DB;
196         }
197
198         return graphName;
199     }
200
201     private void logAndPrint(final EELFLogger logger, final String msg) {
202         System.out.println(msg);
203         logger.info(msg);
204     }
205 }