2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017 AT&T Intellectual Property.
6 * Copyright © 2017 Amdocs
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
22 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
24 package org.openecomp.crud.dao.champ;
26 import org.openecomp.aai.champ.ChampAPI;
27 import org.openecomp.aai.champ.ChampGraph;
28 import org.openecomp.aai.champ.exceptions.ChampMarshallingException;
29 import org.openecomp.aai.champ.exceptions.ChampObjectNotExistsException;
30 import org.openecomp.aai.champ.exceptions.ChampRelationshipNotExistsException;
31 import org.openecomp.aai.champ.exceptions.ChampSchemaViolationException;
32 import org.openecomp.aai.champ.exceptions.ChampUnmarshallingException;
33 import org.openecomp.aai.champ.graph.impl.TitanChampGraphImpl;
34 import org.openecomp.aai.champ.model.ChampObject;
35 import org.openecomp.aai.champ.model.ChampRelationship;
36 import org.openecomp.aai.champ.model.fluent.object.ObjectBuildOrPropertiesStep;
37 import org.openecomp.cl.api.Logger;
38 import org.openecomp.cl.eelf.LoggerFactory;
39 import org.openecomp.crud.dao.GraphDao;
40 import org.openecomp.crud.entity.Edge;
41 import org.openecomp.crud.entity.Vertex;
42 import org.openecomp.crud.exception.CrudException;
43 import org.openecomp.crud.logging.CrudServiceMsgs;
45 import java.util.ArrayList;
46 import java.util.HashMap;
47 import java.util.List;
49 import java.util.Optional;
50 import java.util.Properties;
51 import java.util.Random;
52 import java.util.stream.Collectors;
53 import java.util.stream.Stream;
57 * This is the integration layer between the CRUD API service and the low level Champ library
58 * for graph database interaction.
60 public class ChampDao implements GraphDao {
62 public static final String CONFIG_STORAGE_BACKEND = "storage.backend";
63 public static final String CONFIG_STORAGE_BACKEND_DB = "storage.backend.db";
64 public static final String STORAGE_HBASE_DB = "hbase";
65 public static final String STORAGE_CASSANDRA_DB = "cassandra";
66 public static final String CONFIG_STORAGE_HOSTNAMES = "storage.hostnames";
67 public static final String CONFIG_STORAGE_PORT = "storage.port";
68 public static final String CONFIG_HBASE_ZNODE_PARENT = "storage.hbase.ext.zookeeper.znode.parent";
69 public static final String CONFIG_GRAPH_NAME = "graph.name";
70 public static final String GRAPH_UNQ_INSTANCE_ID_SUFFIX = "graph.unique-instance-id-suffix";
72 public static final String CONFIG_EVENT_STREAM_PUBLISHER = "event.stream.publisher";
73 public static final String CONFIG_EVENT_STREAM_NUM_PUBLISHERS = "event.stream.num-publishers";
76 public static final String DEFAULT_GRAPH_NAME = "default_graph";
78 private enum GraphType {
85 * Set of configuration properties for the DAI.
87 private Properties daoConfig;
90 * Instance of the API used for interacting with the Champ library.
92 private ChampGraph champApi = null;
94 private Logger logger = LoggerFactory.getInstance().getLogger(ChampDao.class.getName());
98 * Creates a new instance of the ChampDao.
100 * @param config - Set of configuration properties to be applied to this instance
103 public ChampDao(Properties config) {
105 // Store the configuration properties.
108 // Apply the configuration to the DAO.
115 public Vertex getVertex(String id, String type) throws CrudException {
119 if (logger.isDebugEnabled()) {
120 logger.debug("getVertex with id: " + id);
123 long idAsLong = Long.parseLong(id);
125 // Request the vertex from the graph db.
126 Optional<ChampObject> retrievedVertex = champApi.retrieveObject(idAsLong);
129 if (retrievedVertex.isPresent() && retrievedVertex.get().getProperties()
130 .get(org.openecomp.schema.OxmModelValidator.Metadata.NODE_TYPE.propertyName())!=null && retrievedVertex.get().getProperties()
131 .get(org.openecomp.schema.OxmModelValidator.Metadata.NODE_TYPE.propertyName()).toString()
132 .equalsIgnoreCase(type)) {
134 // Yup, convert it to a Vector object and return it.
135 return vertexFromChampObject(retrievedVertex.get(),type);
139 // We didn't find a vertex with the supplied id, so just throw an
141 throw new CrudException("No vertex with id " + id + " found in graph",
142 javax.ws.rs.core.Response.Status.NOT_FOUND);
145 } catch (ChampUnmarshallingException | ChampTransactionException e) {
147 // Something went wrong - throw an exception.
148 throw new CrudException(e.getMessage(),
149 javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR);
155 public List<Edge> getVertexEdges(String id) throws CrudException {
157 if (logger.isDebugEnabled()) {
158 logger.debug("get Edges incident to vertex with id: " + id + " from graph");
162 long idAsLong = Long.parseLong(id); // GDF - what to do about id???
164 // Request the vertex from the graph db.
165 Optional<ChampObject> retrievedVertex = champApi.retrieveObject(idAsLong);
168 if (retrievedVertex.isPresent()) {
170 // Query the Champ library for the edges which are incident to the specified
172 Stream<ChampRelationship> relationships =
173 champApi.retrieveRelationships(retrievedVertex.get());
175 // Build an edge list from the result stream.
176 List<Edge> edges = new ArrayList<Edge>();
177 relationships.forEach(r -> edges.add(edgeFromChampRelationship(r)));
183 // We couldn't find the specified vertex, so throw an exception.
184 throw new CrudException("No vertex with id " + id + " found in graph",
185 javax.ws.rs.core.Response.Status.NOT_FOUND);
188 } catch (ChampUnmarshallingException e) {
190 // Something went wrong, so throw an exception.
191 throw new CrudException(e.getMessage(),
192 javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR);
194 } catch (ChampObjectNotExistsException e) {
196 // We couldn't find the specified vertex, so throw an exception.
197 throw new CrudException("No vertex with id " + id + " found in graph",
198 javax.ws.rs.core.Response.Status.NOT_FOUND);
199 } catch (ChampTransactionException e) {
200 throw new CrudException("Transaction error occured",
201 javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR);
207 public Vertex addVertex(String type, Map<String, Object> properties) throws CrudException {
209 if (logger.isDebugEnabled()) {
210 logger.debug("Add/update vertex: {label: " + type
211 + " properties:" + propertiesMapToString(properties));
214 //Add the aai_node_type so that AAI can read the data created by gizmo
215 properties.put(org.openecomp.schema.OxmModelValidator.Metadata.NODE_TYPE.propertyName(), type);
217 // Create an object to represent our vertex in the format expected by the Champ library.
218 ChampObject objectToCreate = buildChampObject(type, properties);
222 // Ask the Champ library to store our vertex, placing the returned object into a
223 // list so that we can easily put that into our result object.
224 return vertexFromChampObject(champApi.storeObject(objectToCreate),type);
226 } catch (ChampMarshallingException
227 | ChampSchemaViolationException
228 | ChampObjectNotExistsException
229 | ChampTransactionException e) {
231 // Something went wrong - throw an exception.
232 throw new CrudException(e.getMessage(),
233 javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR);
239 public Vertex updateVertex(String id, String type, Map<String, Object> properties)
240 throws CrudException {
242 if (logger.isDebugEnabled()) {
243 logger.debug("Update vertex with id: " + id + " with properties: "
244 + propertiesMapToString(properties));
246 //Add the aai_node_type so that AAI can read the data created by gizmo
247 properties.put(org.openecomp.schema.OxmModelValidator.Metadata.NODE_TYPE.propertyName(), type);
250 // Now, build the updated version of the Champ Object...
251 ChampObject updateObject = buildChampObject(id, type, properties);
252 // ...and send it to the Champ library.
253 return vertexFromChampObject(champApi.replaceObject(updateObject),type);
255 } catch (ChampObjectNotExistsException e) {
256 throw new CrudException("Not Found", javax.ws.rs.core.Response.Status.NOT_FOUND);
257 } catch (NumberFormatException | ChampMarshallingException | ChampSchemaViolationException e) {
258 throw new CrudException(e.getMessage(),
259 javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR);
260 } catch (ChampTransactionException e) {
261 throw new CrudException("Transaction error occured",
262 javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR);
269 public List<Vertex> getVertices(String type, Map<String, Object> filter) throws CrudException {
271 if (logger.isDebugEnabled()) {
272 logger.debug("Retrieve vertices with type label: " + type + " which map query parameters: "
273 + propertiesMapToString(filter));
277 filter.put(org.openecomp.schema.OxmModelValidator.Metadata.NODE_TYPE.propertyName(), type);
280 Stream<ChampObject> retrievedVertices;
282 retrievedVertices = champApi.queryObjects(filter);
284 } catch (ChampTransactionException e) {
285 throw new CrudException("Transaction error occured",
286 javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR);
289 List<Vertex> vertices = retrievedVertices
290 .map(v -> vertexFromChampObject(v,type))
291 .collect(Collectors.toList());
294 if (logger.isDebugEnabled()) {
295 logger.debug("Resulting vertex list: " + retrievedVertices);
298 // ...and return it to the caller.
302 private Object getRelKey(String id) {
304 // convert into Long if applicable . TODO : revisit in story NUC-304
306 key = Long.parseLong(id);
307 } catch (NumberFormatException e) {
308 // The id isn't a Long, leave it as a string
315 public Edge getEdge(String id, String type) throws CrudException {
317 if (logger.isDebugEnabled()) {
318 logger.debug("Get edge with id: " + id);
323 // Request the edge from the graph db.
324 Optional<ChampRelationship> relationship = champApi.retrieveRelationship(getRelKey(id));
327 if (relationship.isPresent() && relationship.get().getType().equals(type)) {
329 // Yup - return the result.
330 return edgeFromChampRelationship(relationship.get());
334 // We didn't find an edge with the supplied id, so throw an exception.
335 throw new CrudException("No edge with id " + id + " found in graph",
336 javax.ws.rs.core.Response.Status.NOT_FOUND);
339 } catch (ChampUnmarshallingException | ChampTransactionException e) {
341 // Something went wrong, so throw an exception.
342 throw new CrudException(e.getMessage(),
343 javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR);
348 public Edge addEdge(String type,
351 Map<String, Object> properties) throws CrudException {
353 // For now, assume source and target are straight ids...
356 Optional<ChampObject> sourceObject
357 = champApi.retrieveObject(Long.parseLong(source.getId().get()));
358 if (!sourceObject.isPresent() || !sourceObject.get().getType().equals(source.getType())) {
359 throw new CrudException("Error creating edge - source vertex with id " + source
360 + " does not exist in graph data base",
361 javax.ws.rs.core.Response.Status.BAD_REQUEST);
364 Optional<ChampObject> targetObject
365 = champApi.retrieveObject(Long.parseLong(target.getId().get()));
366 if (!targetObject.isPresent() || !targetObject.get().getType().equals(target.getType())) {
367 throw new CrudException("Error creating edge - target vertex with id " + target
368 + " does not exist in graph data base",
369 javax.ws.rs.core.Response.Status.BAD_REQUEST);
372 // Now, create the ChampRelationship object for our edge and store it in
373 // the graph database.
374 return edgeFromChampRelationship(
375 champApi.storeRelationship(
376 new ChampRelationship.Builder(sourceObject.get(), targetObject.get(), type)
377 .properties(properties)
380 } catch (ChampMarshallingException
381 | ChampObjectNotExistsException
382 | ChampSchemaViolationException
383 | ChampRelationshipNotExistsException
384 | ChampUnmarshallingException | NumberFormatException | ChampTransactionException e) {
386 throw new CrudException("Error creating edge: " + e.getMessage(),
387 javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR);
393 public List<Edge> getEdges(String type, Map<String, Object> filter) throws CrudException {
395 filter.put(ChampRelationship.ReservedPropertyKeys.CHAMP_RELATIONSHIP_TYPE.toString(), type);
397 Stream<ChampRelationship> retrievedRelationships;
399 retrievedRelationships = champApi.queryRelationships(filter);
401 } catch (ChampTransactionException e) {
402 throw new CrudException("Transaction error occured",
403 javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR);
406 // Process the result stream from the Champ library into an Edge list, keeping only
407 // edges of the specified type.
408 List<Edge> edges = retrievedRelationships
409 .map(r -> edgeFromChampRelationship(r))
410 .collect(Collectors.toList());
416 public Edge updateEdge(Edge edge) throws CrudException {
418 if (logger.isDebugEnabled()) {
419 logger.debug("Update edge with id: " + edge.getId() + " with properties: "
420 + propertiesMapToString(edge.getProperties()));
424 // Now, build the updated version of the Champ Relationship...
425 ChampRelationship updateRelationship = new ChampRelationship.Builder(
426 buildChampObject(edge.getSource().getId().get(), edge.getSource().getType(),
427 edge.getSource().getProperties()),
428 buildChampObject(edge.getTarget().getId().get(), edge.getTarget().getType(),
429 edge.getTarget().getProperties()),
430 edge.getType()).key(getRelKey(edge.getId().get()))
431 .properties(edge.getProperties()).build();
432 // ...and send it to the Champ library.
433 return edgeFromChampRelationship(champApi.replaceRelationship(updateRelationship));
436 } catch (ChampRelationshipNotExistsException ex) {
437 throw new CrudException("Not Found", javax.ws.rs.core.Response.Status.NOT_FOUND);
438 } catch (NumberFormatException |
439 ChampUnmarshallingException |
440 ChampMarshallingException |
441 ChampSchemaViolationException |
442 ChampTransactionException ex) {
444 throw new CrudException(ex.getMessage(),
445 javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR);
450 public void deleteVertex(String id, String type) throws CrudException {
454 // First, retrieve the vertex that we intend to delete.
455 Optional<ChampObject> retrievedVertex = champApi.retrieveObject(Long.parseLong(id));
458 if (!retrievedVertex.isPresent() || !retrievedVertex.get().getType().equals(type)) {
459 throw new CrudException("Failed to delete vertex with id: "
460 + id + " - vertex does not exist.",
461 javax.ws.rs.core.Response.Status.NOT_FOUND);
464 // Now, verify that there are no edges incident to the vertex (they must be deleted
466 Stream<ChampRelationship> relationships =
467 champApi.retrieveRelationships(retrievedVertex.get());
469 if (relationships.count() > 0) {
470 throw new CrudException("Attempt to delete vertex with id "
471 + id + " which has incident edges.",
472 javax.ws.rs.core.Response.Status.BAD_REQUEST);
475 // Finally, we can attempt to delete our vertex.
476 champApi.deleteObject(Long.parseLong(id));
479 } catch (NumberFormatException
480 | ChampUnmarshallingException
481 | ChampObjectNotExistsException
482 | ChampTransactionException e) {
484 throw new CrudException(e.getMessage(),
485 javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR);
490 public void deleteEdge(String id, String type) throws CrudException {
494 // First, retrieve the edge that we want to delete.
495 Optional<ChampRelationship> relationshipToDelete
496 = champApi.retrieveRelationship(getRelKey(id));
500 if (!relationshipToDelete.isPresent() || !relationshipToDelete.get().getType().equals(type)) {
501 throw new CrudException("Failed to delete edge with id: " + id + " - edge does not exist",
502 javax.ws.rs.core.Response.Status.NOT_FOUND);
505 // Now we can delete the edge.
506 champApi.deleteRelationship(relationshipToDelete.get());
508 } catch (ChampRelationshipNotExistsException
509 | NumberFormatException
510 | ChampUnmarshallingException
511 | ChampTransactionException e) {
513 throw new CrudException(e.getMessage(),
514 javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR);
520 * This helper method generates a string representation of a properties map for
523 * @param properties - The properties map to be converted.
524 * @return - The log statement friendly conversion of the properties map.
526 private String propertiesMapToString(Map<String, Object> properties) {
528 StringBuilder sb = new StringBuilder();
531 for (String key : properties.keySet()) {
532 sb.append("(").append(key).append(" -> ").append(properties.get(key)).append(") ");
537 return sb.toString();
542 * This helper method constructs a {@link ChampObject} suitable for passing to the Champ library.
544 * @param type - The type to assign to our ChampObject
545 * @param properties - The set of properties to assign to our ChampObject
546 * @return - A populated ChampObject
548 private ChampObject buildChampObject(String type, Map<String, Object> properties) {
550 ObjectBuildOrPropertiesStep objectInProgress = ChampObject.create()
554 for (String key : properties.keySet()) {
555 objectInProgress.withProperty(key, properties.get(key));
557 return objectInProgress.build();
562 * This helper method constructs a {@link ChampObject} suitable for passing to the Champ library.
564 * @param id - Unique identifier for this object.
565 * @param type - The type to assign to our ChampObject
566 * @param properties - The set of properties to assign to our ChampObject
567 * @return - A populated ChampObject
569 private ChampObject buildChampObject(String id, String type, Map<String, Object> properties) {
571 ObjectBuildOrPropertiesStep objectInProgress = ChampObject.create()
573 .withKey(Long.parseLong(id));
575 for (String key : properties.keySet()) {
576 objectInProgress.withProperty(key, properties.get(key));
578 return objectInProgress.build();
584 private Vertex vertexFromChampObject(ChampObject champObject, String type) {
586 // Get the identifier for this vertex from the Champ object.
587 Object id = champObject.getKey().orElse("");
589 // Start building our {@link Vertex} object.
590 Vertex.Builder vertexBuilder = new Vertex.Builder(type);
591 vertexBuilder.id(id.toString());
593 // Convert the properties associated with the Champ object into the form expected for
595 for (String key : champObject.getProperties().keySet()) {
596 vertexBuilder.property(key, champObject.getProperties().get(key));
600 return vertexBuilder.build();
605 * This helper method converts a {@link ChampRelationship} from the Champ library into an
606 * equivalent {@link Edge} object that is understood by the CRUD Service.
608 * @param relationship - The ChampRelationship object to be converted.
609 * @return - An Edge object corresponding to the supplied ChampRelationship
611 private Edge edgeFromChampRelationship(ChampRelationship relationship) {
613 // Populate the edge's id, if available.
614 Object relationshipId = relationship.getKey().orElse("");
616 Edge.Builder edgeBuilder = new Edge.Builder(relationship.getType())
617 .id(relationshipId.toString());
618 edgeBuilder.source(vertexFromChampObject(relationship.getSource(),
619 relationship.getSource().getProperties()
620 .get(org.openecomp.schema.OxmModelValidator.Metadata.NODE_TYPE.propertyName()) == null
621 ? relationship.getSource().getType()
622 : relationship.getSource().getProperties()
623 .get(org.openecomp.schema.OxmModelValidator.Metadata.NODE_TYPE.propertyName()).toString()));
624 edgeBuilder.target(vertexFromChampObject(relationship.getTarget(),
625 relationship.getTarget().getProperties()
626 .get(org.openecomp.schema.OxmModelValidator.Metadata.NODE_TYPE.propertyName()) == null
627 ? relationship.getTarget().getType()
628 : relationship.getTarget().getProperties()
629 .get(org.openecomp.schema.OxmModelValidator.Metadata.NODE_TYPE.propertyName()).toString()));
631 for (String key : relationship.getProperties().keySet()) {
632 edgeBuilder.property(key, relationship.getProperties().get(key).toString());
635 return edgeBuilder.build();
640 * Performs all one-time configuration operations which are required when creating
641 * a new instance of the DAO.
643 private void configure() {
645 // Instantiate the Champ library API.
648 // Determine which back end we are using.
649 switch (getBackendTypeFromConfig()) {
653 logger.info(CrudServiceMsgs.INSTANTIATE_GRAPH_DAO,
655 daoConfig.getProperty(CONFIG_GRAPH_NAME, DEFAULT_GRAPH_NAME),
658 champApi = ChampGraph.Factory.newInstance(ChampGraph.Type.IN_MEMORY,
659 daoConfig.getProperty(CONFIG_GRAPH_NAME, DEFAULT_GRAPH_NAME));
665 String db = daoConfig.getProperty(CONFIG_STORAGE_BACKEND_DB);
666 Short graphIdSuffix = (short) new Random().nextInt(Short.MAX_VALUE);
667 logger.info(CrudServiceMsgs.TITAN_GRAPH_INFO, GRAPH_UNQ_INSTANCE_ID_SUFFIX
668 + ": = " + graphIdSuffix);
669 if (db.equalsIgnoreCase(STORAGE_CASSANDRA_DB)) {
670 logger.info(CrudServiceMsgs.INSTANTIATE_GRAPH_DAO, "Titan with cassandra backend",
671 daoConfig.getProperty(CONFIG_GRAPH_NAME, DEFAULT_GRAPH_NAME),
672 daoConfig.getProperty(CONFIG_STORAGE_HOSTNAMES));
674 TitanChampGraphImpl.Builder champApiBuilder =
675 new TitanChampGraphImpl.Builder(daoConfig.getProperty(CONFIG_GRAPH_NAME,
677 .property("storage.backend", "cassandrathrift")
678 .property(GRAPH_UNQ_INSTANCE_ID_SUFFIX, graphIdSuffix)
679 .property("storage.hostname", daoConfig.get(CONFIG_STORAGE_HOSTNAMES));
681 if (daoConfig.containsKey(CONFIG_EVENT_STREAM_PUBLISHER)) {
682 champApiBuilder.property("champ.event.stream.publisher",
683 daoConfig.get(CONFIG_EVENT_STREAM_PUBLISHER));
686 if (daoConfig.containsKey(CONFIG_EVENT_STREAM_NUM_PUBLISHERS)) {
687 champApiBuilder.property("champ.event.stream.publisher-pool-size",
688 daoConfig.get(CONFIG_EVENT_STREAM_NUM_PUBLISHERS));
691 champApi = champApiBuilder.build();
693 } else if (db.equalsIgnoreCase(STORAGE_HBASE_DB)) {
695 logger.info(CrudServiceMsgs.INSTANTIATE_GRAPH_DAO, "Titan with Hbase backend",
696 daoConfig.getProperty(CONFIG_GRAPH_NAME, DEFAULT_GRAPH_NAME),
697 daoConfig.getProperty(CONFIG_STORAGE_HOSTNAMES));
698 TitanChampGraphImpl.Builder champApiBuilder =
699 new TitanChampGraphImpl.Builder(daoConfig
700 .getProperty(CONFIG_GRAPH_NAME, DEFAULT_GRAPH_NAME))
701 .property("storage.backend", "hbase")
702 .property("storage.hbase.ext.zookeeper.znode.parent",
703 daoConfig.get(CONFIG_HBASE_ZNODE_PARENT))
704 .property("storage.port", daoConfig.get(CONFIG_STORAGE_PORT))
705 .property(GRAPH_UNQ_INSTANCE_ID_SUFFIX, graphIdSuffix)
706 .property("storage.hostname", daoConfig.get(CONFIG_STORAGE_HOSTNAMES));
708 if (daoConfig.containsKey(CONFIG_EVENT_STREAM_PUBLISHER)) {
709 champApiBuilder.property("champ.event.stream.publisher",
710 daoConfig.get(CONFIG_EVENT_STREAM_PUBLISHER));
713 if (daoConfig.containsKey(CONFIG_EVENT_STREAM_NUM_PUBLISHERS)) {
714 champApiBuilder.property("champ.event.stream.publisher-pool-size",
715 daoConfig.get(CONFIG_EVENT_STREAM_NUM_PUBLISHERS));
717 champApi = champApiBuilder.build();
719 logger.error(CrudServiceMsgs.INVALID_GRAPH_BACKEND,
720 daoConfig.getProperty(CONFIG_STORAGE_BACKEND_DB));
723 } catch (com.thinkaurelius.titan.core.TitanException e) {
725 logger.error(CrudServiceMsgs.INSTANTIATE_GRAPH_BACKEND_ERR, "Titan", e.getMessage());
732 logger.error(CrudServiceMsgs.INVALID_GRAPH_BACKEND,
733 daoConfig.getProperty(CONFIG_STORAGE_BACKEND));
737 } catch (CrudException e) {
738 logger.error(CrudServiceMsgs.INSTANTIATE_GRAPH_BACKEND_ERR,
739 daoConfig.getProperty(CONFIG_STORAGE_BACKEND), e.getMessage());
745 * Performs any necessary shut down operations when the DAO is no longer needed.
747 public void close() {
749 if (champApi != null) {
751 logger.info(CrudServiceMsgs.STOPPING_CHAMP_DAO);
759 * This helper function converts the 'graph back end type' config parameter into the
760 * corresponding {@link ChampAPI.Type}.
762 * @return - A {@link ChampAPI.Type}
763 * @throws CrudException
765 private GraphType getBackendTypeFromConfig() throws CrudException {
767 // Get the back end type from the DAO's configuration properties.
768 String backend = daoConfig.getProperty(CONFIG_STORAGE_BACKEND, "in-memory");
770 // Now, find the appropriate ChampAPI type and return it.
771 if (backend.equals("in-memory")) {
772 return GraphType.IN_MEMORY;
773 } else if (backend.equals("titan")) {
774 return GraphType.TITAN;
777 // If we are here, then whatever was in the config properties didn't match to a supported
778 // back end type, so just throw an exception and let the caller figure it out.
779 throw new CrudException("Invalid graph backend type '" + backend + "' specified.",
780 javax.ws.rs.core.Response.Status.BAD_REQUEST);