AAI-1523 Batch reformat aai-core
[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
28 import java.io.FileInputStream;
29 import java.io.FileNotFoundException;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.util.HashMap;
33 import java.util.Map;
34 import java.util.Properties;
35
36 import org.apache.commons.configuration.PropertiesConfiguration;
37 import org.apache.commons.lang.exception.ExceptionUtils;
38 import org.apache.tinkerpop.gremlin.structure.Graph;
39 import org.apache.tinkerpop.gremlin.structure.io.IoCore;
40 import org.janusgraph.core.JanusGraph;
41 import org.janusgraph.core.JanusGraphFactory;
42 import org.janusgraph.core.schema.JanusGraphManagement;
43 import org.onap.aai.dbgen.SchemaGenerator;
44 import org.onap.aai.exceptions.AAIException;
45 import org.onap.aai.util.AAIConstants;
46
47 /**
48  * Database Mapping class which acts as the middle man between the REST
49  * interface objects and JanusGraph DB objects. This class provides methods to commit
50  * the objects received on the REST interface into the JanusGraph graph database as
51  * vertices and edges. Transactions are also managed here by using a JanusGraph
52  * object to load, commit/rollback and shutdown for each request. The data model
53  * rules such as keys/required properties are handled by calling DBMeth methods
54  * which are driven by a specification file in json.
55  * 
56  * 
57  */
58 public class AAIGraph {
59
60     private static final EELFLogger logger = EELFManager.getInstance().getLogger(AAIGraph.class);
61     protected static final String COMPONENT = "aaidbmap";
62     protected Map<String, JanusGraph> graphs = new HashMap<>();
63     private static final String REALTIME_DB = "realtime";
64     private static final String CACHED_DB = "cached";
65     private static boolean isInit = false;
66
67     /**
68      * Instantiates a new AAI graph.
69      */
70     private AAIGraph() {
71         try {
72             String serviceName = System.getProperty("aai.service.name", "NA");
73             String rtConfig = System.getProperty("realtime.db.config");
74             String cachedConfig = System.getProperty("cached.db.config");
75             if (rtConfig == null) {
76                 rtConfig = AAIConstants.REALTIME_DB_CONFIG;
77             }
78             if (cachedConfig == null) {
79                 cachedConfig = AAIConstants.CACHED_DB_CONFIG;
80             }
81             this.loadGraph(REALTIME_DB, rtConfig, serviceName);
82             this.loadGraph(CACHED_DB, cachedConfig, serviceName);
83         } catch (Exception e) {
84             throw new RuntimeException("Failed to instantiate graphs", e);
85         }
86     }
87
88     private static class Helper {
89         private static final AAIGraph INSTANCE = new AAIGraph();
90
91         private Helper() {
92
93         }
94     }
95
96     /**
97      * Gets the single instance of AAIGraph.
98      *
99      * @return single instance of AAIGraph
100      */
101     public static AAIGraph getInstance() {
102         isInit = true;
103         return Helper.INSTANCE;
104     }
105
106     public static boolean isInit() {
107         return isInit;
108     }
109
110     private void loadGraph(String name, String configPath, String serviceName) throws Exception {
111         // Graph being opened by JanusGraphFactory is being placed in hashmap to be used later
112         // These graphs shouldn't be closed until the application shutdown
113         try {
114             PropertiesConfiguration propertiesConfiguration = new AAIGraphConfig.Builder(configPath)
115                     .forService(serviceName).withGraphType(name).buildConfiguration();
116             JanusGraph graph = JanusGraphFactory.open(propertiesConfiguration);
117
118             Properties graphProps = new Properties();
119             propertiesConfiguration.getKeys()
120                     .forEachRemaining(k -> graphProps.setProperty(k, propertiesConfiguration.getString(k)));
121
122             if ("inmemory".equals(graphProps.get("storage.backend"))) {
123                 // Load the propertyKeys, indexes and edge-Labels into the DB
124                 loadSchema(graph);
125                 loadSnapShotToInMemoryGraph(graph, graphProps);
126             }
127
128             if (graph == null) {
129                 throw new AAIException("AAI_5102");
130             }
131
132             graphs.put(name, graph);
133         } catch (FileNotFoundException fnfe) {
134             throw new AAIException("AAI_4001");
135         } catch (IOException e) {
136             throw new AAIException("AAI_4002");
137         }
138     }
139
140     private void loadSnapShotToInMemoryGraph(JanusGraph graph, Properties graphProps) {
141         if (logger.isDebugEnabled()) {
142             logger.debug("Load Snapshot to InMemory Graph");
143         }
144         if (graphProps.containsKey("load.snapshot.file")) {
145             String value = graphProps.getProperty("load.snapshot.file");
146             if ("true".equals(value)) {
147                 try (Graph transaction = graph.newTransaction()) {
148                     String location = System.getProperty("snapshot.location");
149                     logAndPrint(logger, "Loading snapshot to inmemory graph.");
150                     transaction.io(IoCore.graphson()).readGraph(location);
151                     transaction.tx().commit();
152                     logAndPrint(logger, "Snapshot loaded to inmemory graph.");
153                 } catch (Exception e) {
154                     logAndPrint(logger, "ERROR: Could not load datasnapshot to in memory graph. \n"
155                             + ExceptionUtils.getFullStackTrace(e));
156                     throw new RuntimeException(e);
157                 }
158             }
159         }
160     }
161
162     private void loadSchema(JanusGraph graph) {
163         // Load the propertyKeys, indexes and edge-Labels into the DB
164         JanusGraphManagement graphMgt = graph.openManagement();
165
166         System.out.println("-- loading schema into JanusGraph");
167         SchemaGenerator.loadSchemaIntoJanusGraph(graph, graphMgt, "inmemory");
168     }
169
170     /**
171      * Close all of the graph connections made in the instance.
172      */
173     public void graphShutdown() {
174         graphs.values().stream().filter(JanusGraph::isOpen).forEach(JanusGraph::close);
175     }
176
177     /**
178      * Gets the graph.
179      *
180      * @return the graph
181      */
182     public JanusGraph getGraph() {
183         return graphs.get(REALTIME_DB);
184     }
185
186     public void graphShutdown(DBConnectionType connectionType) {
187
188         graphs.get(this.getGraphName(connectionType)).close();
189     }
190
191     public JanusGraph getGraph(DBConnectionType connectionType) {
192         return graphs.get(this.getGraphName(connectionType));
193     }
194
195     private String getGraphName(DBConnectionType connectionType) {
196         String graphName = "";
197         if (DBConnectionType.CACHED.equals(connectionType)) {
198             graphName = this.CACHED_DB;
199         } else if (DBConnectionType.REALTIME.equals(connectionType)) {
200             graphName = this.REALTIME_DB;
201         }
202
203         return graphName;
204     }
205
206     private void logAndPrint(EELFLogger logger, String msg) {
207         System.out.println(msg);
208         logger.info(msg);
209     }
210 }