diff --git a/graph_workers/spidercrab.py b/graph_workers/spidercrab.py index 28362be..e3a8aac 100644 --- a/graph_workers/spidercrab.py +++ b/graph_workers/spidercrab.py @@ -15,15 +15,14 @@ import uuid ### TODO: this line shouldn't be here (it worked on Konrad's laptop?) adding toquickly test sys.path.append(os.path.join(os.path.dirname(__file__), '..')) -sys.path.append(os.path.join(os.path.dirname(__file__), '../lionfish')) +sys.path.append(os.path.join(os.path.dirname(__file__), '../lionfish/python_lionfish/client/')) from don_corleone import don_utils as du from graph_workers.graph_defines import * from graph_workers.graph_utils import * from graph_workers.graph_worker import GraphWorker from graph_workers.privileges import construct_full_privilege -import python_lionfish -from python_lionfish.client import Client +from client import Client # Defining levels to get rid of other loggers info_level = 100 @@ -129,7 +128,7 @@ def __init__( self.required_privileges = construct_full_privilege() # TODO: use configuration! - self.odm_client = Client('localhost', 7777) + self.odm_client = Client('localhost', 7777) self.terminate_event = threading.Event() self.runtime_id = runtime_id self.master_sources_urls_file = master_sources_urls_file @@ -387,7 +386,7 @@ def _check_and_init_db(self): info_level, 'Spidercrab model not found in the database. Creating...' ) - self.odm_client.create_model('Spidercrab') + self.odm_client.create_model_node('Spidercrab') self.logger.log( info_level, 'Spidercrab model created.' diff --git a/lionfish/README.md b/lionfish/README.md index bec530d..3f80328 100755 --- a/lionfish/README.md +++ b/lionfish/README.md @@ -118,8 +118,8 @@ The table below applies to read methods: **_getChildren_**, **_getInstances_** #### Set 1.3 The table below applies to write methods: **_setProperties_**, **_deleteProperties_**, -**_createNode_**, **_deleteNode_**, **_deleteRelationship_**, **_setRelationshipProperties_**, -**_deleteRelationshipProperties_** +**_setRelationshipProperties_**, **_deleteRelationshipProperties_**, **_createNode_**, +**_deleteNode_**, **_deleteRelationship_**, **_popRelationship_** | using batch | correct input | | :---------: | :-----------: | diff --git a/lionfish/build.sbt b/lionfish/build.sbt index 4b4771d..e709312 100755 --- a/lionfish/build.sbt +++ b/lionfish/build.sbt @@ -4,7 +4,7 @@ name := "lionfish" oneJarSettings -version := "0.9.3" +version := "0.9.5" scalaVersion := "2.10.4" @@ -51,7 +51,7 @@ libraryDependencies += "org.neo4j.app" % "neo4j-server" % "2.0.3" classifier "st //libraryDependencies += "commons-beanutils" % "commons-beanutils-core" % "1.8.0" libraryDependencies ++= Seq( - "org.neo4j.app" % "neo4j-server" % "2.0.2" + "org.neo4j.app" % "neo4j-server" % "2.0.3" ) libraryDependencies ++= Seq("com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.3.3") @@ -63,4 +63,6 @@ libraryDependencies ++= Seq( libraryDependencies += "org.scalatest" % "scalatest_2.10" % "2.1.4" % "test" +parallelExecution in Test := false + libraryDependencies += "commons-lang" % "commons-lang" % "2.6" diff --git a/lionfish/python_lionfish/client/client.py b/lionfish/python_lionfish/client/client.py index 8e6206d..f1d95ed 100755 --- a/lionfish/python_lionfish/client/client.py +++ b/lionfish/python_lionfish/client/client.py @@ -91,7 +91,7 @@ def __init__(self, address=ADDRESS, port=PORT): try: self._conn.connect((self._address, self._port)) except Exception as e: - raise Exception('Connecting failed. {error}'.format(error=str(e))) + raise Exception('Failed to connect with server. {error}'.format(error=str(e))) def connect(self): pass @@ -99,9 +99,8 @@ def connect(self): def disconnect(self): try: self._conn.close() - logger.log(info_level, 'The client has disconnected.') except Exception as e: - logger.log(error_level, 'Disconnecting failed. {error}' + logger.log(error_level, 'Failed to disconnect from server. {error}' .format(error=str(e))) raise e @@ -110,7 +109,7 @@ def send(self, data): send_message(self._conn, data) except Exception, e: logger.log(info_level, 'Not sent data {data}'.format(data=data)) - logger.log(error_level, 'Sending data failed. {error}' + logger.log(error_level, 'Failed to send data. {error}' .format(error=str(e))) raise e @@ -119,7 +118,7 @@ def recv(self): try: data = get_message(self._conn) except Exception as e: - logger.log(error_level, 'Receiving data failed. {error}' + logger.log(error_level, 'Failed to receive data. {error}' .format(error=str(e))) raise e return data @@ -127,6 +126,36 @@ def recv(self): def get_batch(self): return self.Batch(self) + def execute_query(self, query, **params): + """ + Executes query with given params + @param query string + @param params dictionary/keywords + """ + data = { + 'methodName': 'executeQuery', + 'args': { + 'query': query, + 'parameters': params + } + } + + request = { + 'type': 'sequence', + 'tasks': [data] + } + + if inspect.stack()[1][3] == '_get_data_for_batch': + return data + self.send(request) + result = None + try: + result = self.recv()[0] + except Exception as e: + logger.log(error_level, 'Failed to execute query. {error}' + .format(error=str(e))) + return result + def get_by_uuid(self, uuid, **params): """ Gets a node of given uuid @@ -198,11 +227,33 @@ def get_by_tag(self, tag, **params): result = self.recv() return result[0] + def get_by_username(self, username, **params): + """ + Gets a node by given username + @param username string + """ + data = { + 'methodName': 'getByUsername', + 'args': { + 'username': username + } + } + + request = { + 'type': 'sequence', + 'tasks': [data] + } + + if inspect.stack()[1][3] == '_get_data_for_batch': + return data + self.send(request) + result = self.recv() + return result[0] + def get_by_label(self, label, **params): """ - Gets a node by given model_name and link - @param model_name string - @param link string + Gets a node by given label + @param label string """ data = { 'methodName': 'getByLabel', @@ -243,7 +294,7 @@ def get_model_nodes(self, **params): return result[0] def get_children(self, parent_uuid, relationship_type, children_properties={}, - relationship_properties={}, **params): + relationship_properties={}, limit=0, **params): """ Gets children of node with parent_uuid uuid related by relation relationship_type with children_properties and relationship_properties @@ -258,7 +309,8 @@ def get_children(self, parent_uuid, relationship_type, children_properties={}, 'parentUuid': parent_uuid, 'relType': relationship_type, 'childrenProps': children_properties, - 'relProps': relationship_properties + 'relProps': relationship_properties, + 'limit': limit } } @@ -273,7 +325,8 @@ def get_children(self, parent_uuid, relationship_type, children_properties={}, result = self.recv() return result[0] - def get_instances(self, model_name, children_properties={}, relationship_properties={}, **params): + def get_instances(self, model_name, children_properties={}, relationship_properties={}, + limit=0, **params): """ Gets all instances of given model_name with children_properties and relationship_properties @param model_name string @@ -285,7 +338,32 @@ def get_instances(self, model_name, children_properties={}, relationship_propert 'args': { 'modelName': model_name, 'childrenProps': children_properties, - 'relProps': relationship_properties + 'relProps': relationship_properties, + 'limit': limit + } + } + + request = { + 'type': 'sequence', + 'tasks': [data] + } + + if inspect.stack()[1][3] == '_get_data_for_batch': + return data + self.send(request) + result = self.recv() + return result[0] + + def get_user_feeds(self, uuid, limit=0, **params): + """ + Gets all feeds of given user uuid + @param uuid string + """ + data = { + 'methodName': 'getUserFeeds', + 'args': { + 'uuid': uuid, + 'limit': limit } } @@ -300,9 +378,57 @@ def get_instances(self, model_name, children_properties={}, relationship_propert result = self.recv() return result[0] + def set_label(self, uuid, label, **params): + """ + Sets the label to the node of given uuid + @param uuid string + @param label string + """ + data = { + 'methodName': 'setLabel', + 'args': { + 'uuid': uuid, + 'label': label + } + } + + request = { + 'type': 'sequence', + 'tasks': [data] + } + + if inspect.stack()[1][3] == '_get_data_for_batch': + return data + self.send(request) + self.recv() + + def delete_label(self, uuid, label, **params): + """ + Deletes the label from the node of given uuid + @param uuid string + @param label string + """ + data = { + 'methodName': 'deleteLabel', + 'args': { + 'uuid': uuid, + 'label': label + } + } + + request = { + 'type': 'sequence', + 'tasks': [data] + } + + if inspect.stack()[1][3] == '_get_data_for_batch': + return data + self.send(request) + self.recv() + def set(self, uuid, **properties): """ - Sets properties to a node of given uuid + Sets properties to the node of given uuid @param uuid string @param properties dictionary/keywords """ @@ -326,7 +452,7 @@ def set(self, uuid, **properties): def set_properties(self, uuid, **properties): """ - Sets properties to a node of given uuid + Sets properties to the node of given uuid @param uuid string @param properties dictionary/keywords """ @@ -350,7 +476,7 @@ def set_properties(self, uuid, **properties): def delete_properties(self, uuid, **property_keys): """ - Deletes property_keys of a node of given uuid + Deletes property_keys of the node of given uuid @param uuid string @param property_keys dictionary/keywords """ @@ -372,6 +498,60 @@ def delete_properties(self, uuid, **property_keys): self.send(request) self.recv() + def set_relationship_properties(self, start_node_uuid, end_node_uuid, **properties): + """ + Sets properties to a relationship between two nodes given by start_node_uuid + and end_node_uuid + @param start_node_uuid string + @param end_node_uuid string + @param properties dictionary/keywords + """ + data = { + 'methodName': 'setRelationshipProperties', + 'args': { + 'startNodeUuid': start_node_uuid, + 'endNodeUuid': end_node_uuid, + 'props': properties + } + } + + request = { + 'type': 'sequence', + 'tasks': [data] + } + + if inspect.stack()[1][3] == '_get_data_for_batch': + return data + self.send(request) + self.recv() + + def delete_relationship_properties(self, start_node_uuid, end_node_uuid, **prop_keys): + """ + Deletes properties of a relationship between two nodes given by start_node_uuid + and end_node_uuid + @param start_node_uuid string + @param end_node_uuid string + @param property_keys dictionary/keywords + """ + data = { + 'methodName': 'deleteRelationshipProperties', + 'args': { + 'startNodeUuid': start_node_uuid, + 'endNodeUuid': end_node_uuid, + 'propKeys': prop_keys + } + } + + request = { + 'type': 'sequence', + 'tasks': [data] + } + + if inspect.stack()[1][3] == '_get_data_for_batch': + return data + self.send(request) + self.recv() + def create_model_node(self, model_name, **properties): """ Creates a node with properties to the model given by model_name @@ -448,7 +628,7 @@ def delete_node(self, uuid, **params): def create_relationship(self, start_node_uuid, end_node_uuid, relationship_type, **properties): """ - Creates a relationship relationship_type with properties + Creates a relationship of type relationship_type with properties between nodes of start_node_uuid and end_node_uuid @param start_node_uuid string @param end_node_uuid string @@ -476,17 +656,22 @@ def create_relationship(self, start_node_uuid, end_node_uuid, relationship_type, result = self.recv() return result[0] - def delete_relationship(self, start_node_uuid, end_node_uuid, **params): + def create_unique_relationship(self, start_node_uuid, end_node_uuid, relationship_type, **properties): """ - Deletes a relationship between nodes of start_node_uuid and end_node_uuid + Creates an unique relationship of type relationship_type with properties + between nodes of start_node_uuid and end_node_uuid @param start_node_uuid string @param end_node_uuid string + @param relationship_type string + @param properties dictionary/keywords """ data = { - 'methodName': 'deleteRelationships', + 'methodName': 'createUniqueRelationships', 'args': { 'startNodeUuid': start_node_uuid, - 'endNodeUuid': end_node_uuid + 'endNodeUuid': end_node_uuid, + 'type': relationship_type, + 'props': properties } } @@ -498,22 +683,20 @@ def delete_relationship(self, start_node_uuid, end_node_uuid, **params): if inspect.stack()[1][3] == '_get_data_for_batch': return data self.send(request) - self.recv() + result = self.recv() + return result[0] - def set_relationship_properties(self, start_node_uuid, end_node_uuid, **properties): + def delete_relationship(self, start_node_uuid, end_node_uuid, **params): """ - Sets properties to a relationship between two nodes given by start_node_uuid - and end_node_uuid + Deletes the relationship between nodes of start_node_uuid and end_node_uuid @param start_node_uuid string @param end_node_uuid string - @param properties dictionary/keywords """ data = { - 'methodName': 'setRelationshipProperties', + 'methodName': 'deleteRelationships', 'args': { 'startNodeUuid': start_node_uuid, - 'endNodeUuid': end_node_uuid, - 'props': properties + 'endNodeUuid': end_node_uuid } } @@ -527,20 +710,17 @@ def set_relationship_properties(self, start_node_uuid, end_node_uuid, **properti self.send(request) self.recv() - def delete_relationship_properties(self, start_node_uuid, end_node_uuid, **prop_keys): + def pop_relationship(self, start_node_uuid, rel_type, **params): """ - Deletes properties of a relationship between two nodes given by start_node_uuid - and end_node_uuid + Deletes the relationship of a given rel_type, starting from node of start_node_uuid @param start_node_uuid string - @param end_node_uuid string - @param property_keys dictionary/keywords + @param rel_type string """ data = { - 'methodName': 'deleteRelationshipProperties', + 'methodName': 'popRelationships', 'args': { 'startNodeUuid': start_node_uuid, - 'endNodeUuid': end_node_uuid, - 'propKeys': prop_keys + 'relType': rel_type } } @@ -552,47 +732,5 @@ def delete_relationship_properties(self, start_node_uuid, end_node_uuid, **prop_ if inspect.stack()[1][3] == '_get_data_for_batch': return data self.send(request) - self.recv() - - # def execute_query(self, query_string, **params): - # """ - # Executes query_string with given query_params - # and returns results as python dictionaries - # @param query_string string - # @param params dictionary/keywords - # """ - # data = { - # 'methodName': 'execute_query', - # 'args': [query_string, params] - # } - # - # request = { - # 'type': 'sequence', - # 'tasks': [data] - # } - # - # if inspect.stack()[1][3] == '_get_data_for_batch': - # return data - # self.send(request) - # return self.recv() - # - # def run_query(self, query_string, **params): - # """ - # Runs query_string with given query_params - # @param query_string string - # @param params dictionary/keywords - # """ - # data = { - # 'methodName': 'run_query', - # 'args': [query_string, params] - # } - # - # request = { - # 'type': 'sequence', - # 'tasks': [data] - # } - # - # if inspect.stack()[1][3] == '_get_data_for_batch': - # return data - # self.send(request) - # self.recv() + result = self.recv() + return result[0] diff --git a/lionfish/python_lionfish/server/lionfish_restart.sh b/lionfish/python_lionfish/server/lionfish_restart.sh deleted file mode 100755 index 888db93..0000000 --- a/lionfish/python_lionfish/server/lionfish_restart.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -list=$(pgrep -f "odm_server.py") - -for proc in $list -do - sudo kill -9 $proc -done - -if [ "${#list[@]}" -gt 0 ] -then - echo "Terminating Lionfish server... OK" -fi - -sudo python ~/ocean/lionfish/odm_server.py diff --git a/lionfish/python_lionfish/server/neo4j_restart.sh b/lionfish/python_lionfish/server/neo4j_restart.sh deleted file mode 100755 index abc75dc..0000000 --- a/lionfish/python_lionfish/server/neo4j_restart.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -sudo /usr/local/lib/neo4j/bin/neo4j restart diff --git a/lionfish/python_lionfish/server/odm_server.py b/lionfish/python_lionfish/server/odm_server.py deleted file mode 100755 index ae19a7d..0000000 --- a/lionfish/python_lionfish/server/odm_server.py +++ /dev/null @@ -1,650 +0,0 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- - -""" -Lionfish (formerly Ocean Database Manager) - -general idea is as follows: ODM have many get procedures, however only one way -to add or set node/rel (add_node, set, add_rel, del_rel, del_node) - -get_by_uuid will be cached, as well as multiget. Other get procedures are -not guaranteed to be cached -""" - -from py2neo import neo4j -import uuid -import os -import socket -import logging -from threading import Thread -import sys -import json - -sys.path.append(os.path.join(os.path.dirname(__file__), '../../../don_corleone/')) -sys.path.append(os.path.join(os.path.dirname(__file__), - '../../../graph_workers')) - -# DonCorleone configuration -from don_utils import get_configuration - -from graph_defines import * -from graph_utils import * - - -# Defining levels to get rid of other loggers -info_level = 100 -error_level = 200 - -logging.basicConfig(level=info_level) -logger = logging.getLogger(__name__ + '_ocean') -ch = logging.StreamHandler() -formatter = logging.Formatter('%(funcName)s - %(asctime)s - %(message)s') -ch.setFormatter(formatter) -logger.addHandler(ch) -logger.propagate = False -ch_file = logging.FileHandler(os.path.join(os.path.dirname(__file__), - '../../../logs/odm_server.log')) -ch_file.setLevel(info_level) -logger.addHandler(ch_file) - - -class DatabaseManager(object): - """ Driver for Neo4j database """ - def __init__(self, neo4j_host=None, neo4j_port = None): - """ Creates DatabaseManager driver """ - logger.log(info_level, 'Created DatabaseManager object') - self._graph_db = neo4j.GraphDatabaseService( - 'http://{0}:{1}/db/data/'.format(neo4j_host if neo4j_host else - get_configuration("neo4j","host"), neo4j_port if neo4j_port else get_configuration("neo4j", "port")) - ) - self._uuid_images = dict() - self._model_name_images = dict() - - self._init_uuid_images() - self._init_model_name_images() - - def _init_model_name_images(self): - self._model_name_images.clear() - query_string = '' \ - 'MATCH (e:Model)' \ - 'RETURN e.model_name, e.uuid' - query_results = self._execute_query(query_string) - for record in query_results: - key = record[0] - value = record[1] - self._model_name_images[key] = value - - def _init_uuid_images(self): - self._uuid_images.clear() - query_string = \ - 'MATCH (e:Node)' \ - 'RETURN e.uuid, id(e)' - query_results = self._execute_query(query_string) - for record in query_results: - key = record[0] - value = record[1] - self._uuid_images[key] = value - - @error_handle_odm - def _str(self, dictionary): - string = '{' - for key, value in dictionary.iteritems(): - string += '{0}: {1}, '.format( - key, json.dumps(value, ensure_ascii=False) - ) - - if len(string) > 1: - string = string[:len(string) - 2] - return string + '}' - - @error_handle_odm - def _execute_query(self, query_string, **query_params): - """ - Executes query and returns results as python dictionaries - @param query_string string - @param multi_value bool - @param query_params dictionary - """ - # Executes cypher query - cypher_query = neo4j.CypherQuery(self._graph_db, unicode(query_string)) - query_results = cypher_query.execute(**query_params) - - results = [] - for result in query_results: - values = [] - for value in result.values: - if value.__class__.__name__ in ('Node', 'Relationship'): - values.append(value.get_properties()) - else: - values.append(value) - results.append(values) - return results - - @error_handle_odm - def _run_query(self, query_string, **query_params): - """ - Runs query only - @param query_string - @param query_params - """ - cypher_query = neo4j.CypherQuery(self._graph_db, unicode(query_string)) - cypher_query.run(**query_params) - - @error_handle_odm - def get_by_uuid(self, node_uuid_list): - # Prepares MATCH statement - match_str = '' - for i, item in enumerate(node_uuid_list): - match_str += 'OPTIONAL MATCH (e{0}:Node {{uuid: {1}}}) '\ - .format(i, json.dumps(item)) - - # Prepares RETURN statement - return_str = 'RETURN DISTINCT ' - for i in range(0, len(node_uuid_list)): - return_str += '(e{0}), '.format(i) - return_str = return_str[:len(return_str) - 2] - - # Builds query and gets results - query_string = match_str + return_str - results = self._execute_query(query_string) - return results[0] - - @error_handle_odm - def get_by_link(self, node_list): - # Prepares MATCH statement - match_str = '' - for i, item in enumerate(node_list): - match_str += 'OPTIONAL MATCH (e{0}:{1} {{link: {2}}}) '\ - .format(i, item['model_name'], json.dumps(item['link'])) - - # Prepares RETURN statement - return_str = 'RETURN DISTINCT ' - for i in range(0, len(node_list)): - return_str += '(e{0}), '.format(i) - return_str = return_str[:len(return_str) - 2] - - # Builds query and gets results - query_string = match_str + return_str - results = self._execute_query(query_string) - return results[0] - - @error_handle_odm - def get_model_nodes(self): - # Builds query and gets results - query_string = \ - 'MATCH (e:Model) ' \ - 'RETURN (e)' - return self._execute_query(query_string) - - @error_handle_odm - def get_children(self, node_list): - # Prepares query - query_string = '' - for i, item in enumerate(node_list): - query_string += \ - 'MATCH (e:Node {{uuid: {0}}})-[r:`{1}`]->(a:Node {2}) ' \ - 'RETURN (a) '.format(json.dumps(item['uuid']), item['rel_type'], - self._str(item['children_params'])) - if i < len(node_list) - 1: - query_string += 'UNION ALL MATCH (a:Root) RETURN (a) UNION ALL ' - - # Gets results and extracts them from default list - raw_results = self._execute_query(query_string) - results = [[]] - no = 0 - for item in raw_results: - if 'root' not in item[0]: - results[no].append(item[0]) - else: - results.append([]) - no += 1 - return results - - @error_handle_odm - def get_instances(self, model_name_list): - # Prepares query - query_string = '' - for i, item in enumerate(model_name_list): - query_string += \ - 'MATCH (e:Model {{model_name: {0}}})-[:`<>`]->(a:{1}) ' \ - 'RETURN (a) '.format(json.dumps(item), item) - if i < len(model_name_list) - 1: - query_string += 'UNION ALL MATCH (a:Root) RETURN (a) UNION ALL ' - - # Gets results and extracts them from default list - raw_results = self._execute_query(query_string) - results = [[]] - no = 0 - for item in raw_results: - if 'root' not in item[0]: - results[no].append(item[0]) - else: - results.append([]) - no += 1 - return results - - @error_handle_odm - def set(self, node_list): - # Prepares MATCH statement - match_str = 'MATCH ' - for i, item in enumerate(node_list): - match_str += '(e{0}:Node {{uuid: {1}}}), '\ - .format(i, json.dumps(item['uuid'])) - match_str = match_str[:len(match_str) - 2] + ' ' - - # Prepares SET statement - set_str = 'SET ' - for i, node in enumerate(node_list): - for key, value in node['params'].iteritems(): - set_str += 'e{0}.{1} = {2}, '\ - .format(i, key, json.dumps(value, ensure_ascii=False)) - set_str = set_str[:len(set_str) - 2] - - # Builds query and runs it - query_string = match_str + set_str - self._run_query(query_string) - - @error_handle_odm - def create_nodes(self, node_list): - # Prepares params - fail_list = [] - for i, item in enumerate(node_list): - model_name = item['model_name'] - if model_name not in self._model_name_images: - fail_list.append(i) - continue - - # Default values loaded from graph_defines - params = dict(GRAPH_MODELS[model_name]) \ - if model_name in GRAPH_MODELS else {} - params.update(item['params']) - params['uuid'] = str(uuid.uuid1()) - item['params'] = params - - # Removes the nodes with incorrect model names - deleted_count = 0 - for i in fail_list: - node_list.pop(i - deleted_count) - deleted_count += 1 - - # All given uuids are bad - if len(node_list) == 0: - node_uuid_list = [] - for i in range(0, len(fail_list)): - node_uuid_list.append(None) - return node_uuid_list - - # Prepares MATCH statement - match_str = 'MATCH ' - for i, item in enumerate(node_list): - match_str += '(e{0}:Model {{model_name: {1}}}), '\ - .format(i, json.dumps(item['model_name'])) - match_str = match_str[:len(match_str) - 2] + ' ' - - # Prepares CREATE statement - create_str = 'CREATE UNIQUE ' - for i, item in enumerate(node_list): - create_str += '(e{0})-[:`{1}`]->(a{0}:Node:{2} {3}), '\ - .format(i, item['rel_type'], item['model_name'], - self._str(item['params'])) - create_str = create_str[:len(create_str) - 2] + ' ' - - # Prepares RETURN statement - return_str = 'RETURN ' - for i in range(0, len(node_list)): - return_str += 'id(a{0}), '.format(i) - return_str = return_str[:len(return_str) - 2] - - # Builds query and gets results - query_string = match_str + create_str + return_str - results = self._execute_query(query_string) - - # Prepares the list of uuids to be returned - node_uuid_list = [] - for i, item in enumerate(node_list): - self._uuid_images[item['params']['uuid']] = results[0][i] - node_uuid_list.append(item['params']['uuid']) - - # Fills the list of uuids with broken requests - for i in fail_list: - node_uuid_list.insert(i, None) - - return node_uuid_list - - @error_handle_odm - def delete_nodes(self, node_uuid_list): - # Prepares params - fail_list = [] - for i, item in enumerate(node_uuid_list): - if item not in self._uuid_images: - fail_list.append(i) - continue - - # Removes the incorrect uuid - deleted_count = 0 - for i in fail_list: - node_uuid_list.pop(i - deleted_count) - deleted_count += 1 - - # All given uuids are bad - if len(node_uuid_list) == 0: - return - - # Prepares MATCH statement - match_str = 'MATCH ' - for i, item in enumerate(node_uuid_list): - match_str += '(e{0}:Node {{uuid: {1}}})-[r{0}]-(), '\ - .format(i, json.dumps(item)) - match_str = match_str[:len(match_str) - 2] + ' ' - - # Prepares DELETE statement - delete_str = 'DELETE ' - for i in range(0, len(node_uuid_list)): - delete_str += '(e{0}), (r{0}), '.format(i) - delete_str = delete_str[:len(delete_str) - 2] - - # Builds query and runs it - query_string = match_str + delete_str - self._run_query(query_string) - - # Removes uuids of deleted nodes from cache - for node_uuid in node_uuid_list: - if node_uuid in self._uuid_images: - del self._uuid_images[node_uuid] - - @error_handle_odm - def create_model(self, params): - - # TODO: Improve (currently merged add_node and add_rel methods) - - model_name = params[0] - - print params - print model_name - - if model_name in self._model_name_images: - raise Exception('Model already exists') - - node_params = { - 'model_name': str(model_name), - 'uuid': str(uuid.uuid1()), - } - query_string = \ - ''' - CREATE (e:Node:Model {node_params}) - RETURN id(e) - ''' - node_results = self._execute_query(query_string, - node_params=node_params) - if len(node_results) == 0: - raise Exception('Executing query failed') - - self._uuid_images[node_params['uuid']] = node_results[0] - self._model_name_images[model_name] = node_params['uuid'] - end_node_uuid = node_params['uuid'] - - if end_node_uuid not in self._uuid_images: - raise Exception('Unknown uuid') - - start_node_id = 0 - end_node_id = self._uuid_images[end_node_uuid] - rel_type = '<>' - rel_params = {} - - query_string = \ - ''' - START a=node({start_node_id}), b=node({end_node_id}) - CREATE (a)-[r:`''' + rel_type + '''` {rel_params}]->(b) - ''' - # There is a problem with node_params if they are given to _run_query - self._run_query(query_string, start_node_id=start_node_id, - end_node_id=end_node_id, rel_params=rel_params) - - self._init_model_name_images() - - @error_handle_odm - # TODO: This is not a completely good function - def create_relationships(self, rel_list): - # Prepares arguments - fail_list = [] - for i, item in enumerate(rel_list): - if item['start_node_uuid'] not in self._uuid_images \ - or item['end_node_uuid'] not in self._uuid_images: - fail_list.append(i) - continue - - # Removes the nodes with incorrect model names - deleted_count = 0 - for i in fail_list: - rel_list.pop(i - deleted_count) - deleted_count += 1 - - # All given uuids are bad - if len(rel_list) == 0: - return - - # Prepares MATCH statement - match_str = 'MATCH ' - for i, item in enumerate(rel_list): - match_str += '(a{0}:Node {{uuid: {1}}}), (b{0}:Node {{uuid: {2}}}), '\ - .format(i, json.dumps(item['start_node_uuid']), - json.dumps(item['end_node_uuid'])) - match_str = match_str[:len(match_str) - 2] + ' ' - - # Prepares CREATE statement - create_str = 'CREATE UNIQUE ' - for i, item in enumerate(rel_list): - create_str += '(a{0})-[r{0}:`{1}` {2}]->(b{0}), '\ - .format(i, item['type'], self._str(item['params'])) - create_str = create_str[:len(create_str) - 2] - - # Builds query and runs it - query_string = match_str + create_str - self._run_query(query_string) - - @error_handle_odm - def delete_relationships(self, rel_list): - # Prepares MATCH statement - match_str = 'MATCH ' - for i, item in enumerate(rel_list): - match_str += '(a{0}:Node {{uuid: {1}}})' \ - '-[r{0}]->(b{0}:Node {{uuid: {2}}}), '\ - .format(i, json.dumps(item['start_node_uuid']), - json.dumps(item['end_node_uuid'])) - match_str = match_str[:len(match_str) - 2] + ' ' - - # Prepares DELETE statement - delete_str = 'DELETE ' - for i in range(0, len(rel_list)): - delete_str += '(r{0}), '.format(i) - delete_str = delete_str[:len(delete_str) - 2] - - # Builds query and runs it - query_string = match_str + delete_str - self._run_query(query_string) - - @error_handle_odm - def execute_query(self, query_string, query_params): - return self._execute_query(query_string, **query_params) - - @error_handle_odm - def run_query(self, query_string, query_params): - self._run_query(query_string, **query_params) - - -class Connection(): - def __init__(self, client_id, conn, manager): - self._id = client_id - self._conn = conn - self._manager = manager - - def _send(self, data): - try: - send_message(self._conn, data) - except Exception, e: - logger.log(info_level, 'Not sent data {data}'.format(data=data)) - logger.log(error_level, 'Sending data to client {id} failed. {error}' - .format(id=self._id, error=str(e))) - - def _recv(self, logs=True): - data = None - try: - data = get_message(self._conn) - except Exception, e: - if logs: - logger.log( - error_level, - 'Receiving data from client {id} failed. ' - '{error}'.format(id=self._id, error=str(e)) - ) - return data - - def _disconnect(self): - try: - self._conn.close() - logger.log(info_level, 'Client {id} disconnected.' - .format(id=self._id)) - except Exception, e: - logger.log(error_level, 'Disconnecting with client {id} failed. ' - '{error}'.format(id=self._id, error=str(e))) - - @error_handle_odm - def _execute_function(self, request): - func_name = request['func_name'] - args = request['args'] - - if func_name != 'execute_query' and func_name != 'run_query': - for i in range(0, len(args)): - args[i] = [args[i]] - - logger.log(info_level, 'Client {id}: {func_name}'.format( - id=self._id, func_name=func_name - )) - - func = getattr(self._manager, str(func_name)) - - results = func(*args) - return results - - @error_handle_odm - def _execute_batch(self, request): - tasks = request['tasks'] - count = request['count'] - - # Prepares request to be executed - # TODO: consider execute_query and run_query as nonbatchable - results = [] - for i in range(0, count): - results.append([None]) - - for func_name, params in tasks.iteritems(): - full_args = [] - for i in range(0, len(params[0][0])): - full_args.append([]) - for args, no in params: - for i, item in enumerate(args): - full_args[i].append(item) - - logger.log(info_level, 'Client {id}: {func_name}'.format( - id=self._id, func_name=func_name - )) - - func = getattr(self._manager, str(func_name)) - raw_results = func(*full_args) - - if raw_results: - for i, item in enumerate(raw_results): - results[params[i][1]] = item - - return results - - def handle(self): - while True: - request = self._recv(logs=False) - if not request: - break - - try: - # Single request or batch - if 'tasks' not in request: - results = self._execute_function(request) - else: - results = self._execute_batch(request) - self._send(results) - except: - pass - - self._disconnect() - - -class ODMServer(object): - def __init__(self, host, port, neo4j_host=None, neo4j_port=None): - self._host = host - self._port = port - self._manager = DatabaseManager(neo4j_host, neo4j_port) - self._dynamic_id = 0 - - def _get_new_id(self): - self._dynamic_id += 1 - return self._dynamic_id - - def _handle_connections(self, server_socket): - while True: - conn, addr = server_socket.accept() - new_id = self._get_new_id() - conn = Connection(new_id, conn, self._manager) - Thread(target=conn.handle).start() - logger.log(info_level, 'Client {id} connected {addr}.' - .format(addr=addr, id=new_id)) - - def start(self): - server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - - try: - server_socket.bind((self._host, self._port)) - server_socket.listen(10) - logger.log(info_level, 'The server is listening on port {port}.' - .format(port=self._port)) - self._handle_connections(server_socket) - except Exception, e: - logger.log(error_level, 'Starting server failed. {error}' - .format(error=str(e))) - - -from optparse import OptionParser - -if __name__ == '__main__': - parser = OptionParser() - parser.add_option( - '-k', - '--host', - dest='host', - default='', - help='Host to bind to, default is empty - correct in almost all the cases' - ) - parser.add_option( - '--neo4j_host', - dest='neo4j_host', - default='127.0.0.1', - help='Host to bind to neo4j' - ) - parser.add_option( - '--neo4j_port', - dest='neo4j_port', - default='7474', - help='Port to bind to neo4j' - ) - parser.add_option( - '-p', - '--port', - dest='port', - default=7777, - type=int, - help='Port to bind to' - ) - (options, args) = parser.parse_args() - - logger.info("HOST="+options.host + " PORT="+str(options.port)) - - server = ODMServer(options.host, options.port, options.neo4j_host, options.neo4j_port) - server.start() diff --git a/lionfish/src/main/resources/cacheWorkerSystem.conf b/lionfish/src/main/resources/cacheWorkerSystem.conf new file mode 100644 index 0000000..fed1452 --- /dev/null +++ b/lionfish/src/main/resources/cacheWorkerSystem.conf @@ -0,0 +1,21 @@ +include "application" + +akka { + actor { + provider = "akka.remote.RemoteActorRefProvider" + deployment { + /parent/cacheWorkerPool { + router = round-robin-pool + nr-of-instances = 5 + target.nodes = ["akka.tcp://cacheWorkerSystem@localhost:7781"] + } + } + } + remote { + enabled-transports = ["akka.remote.netty.tcp"] + netty.tcp { + hostname = "localhost", + port = 7774 + } + } +} \ No newline at end of file diff --git a/lionfish/src/main/resources/databaseWorkerSystem.conf b/lionfish/src/main/resources/databaseWorkerSystem.conf new file mode 100644 index 0000000..432831c --- /dev/null +++ b/lionfish/src/main/resources/databaseWorkerSystem.conf @@ -0,0 +1,21 @@ +include "application" + +akka { + actor { + provider = "akka.remote.RemoteActorRefProvider" + deployment { + /parent/databaseWorkerPool { + router = round-robin-pool + nr-of-instances = 5 + target.nodes = ["akka.tcp://databaseWorkerSystem@localhost:7782"] + } + } + } + remote { + enabled-transports = ["akka.remote.netty.tcp"] + netty.tcp { + hostname = "localhost", + port = 7773 + } + } +} \ No newline at end of file diff --git a/lionfish/src/main/resources/masterSystem.conf b/lionfish/src/main/resources/masterSystem.conf new file mode 100644 index 0000000..59deff7 --- /dev/null +++ b/lionfish/src/main/resources/masterSystem.conf @@ -0,0 +1,14 @@ +include "application" + +akka { + actor { + provider = "akka.remote.RemoteActorRefProvider" + } + remote { + enabled-transports = ["akka.remote.netty.tcp"] + netty.tcp { + hostname = "localhost", + port = 7775 + } + } +} diff --git a/lionfish/src/main/resources/requestHandlerSystem.conf b/lionfish/src/main/resources/requestHandlerSystem.conf new file mode 100644 index 0000000..bb7ade2 --- /dev/null +++ b/lionfish/src/main/resources/requestHandlerSystem.conf @@ -0,0 +1,14 @@ +include "application" + +akka { + actor { + provider = "akka.remote.RemoteActorRefProvider" + } + remote { + enabled-transports = ["akka.remote.netty.tcp"] + netty.tcp { + hostname = "localhost", + port = 7776 + } + } +} diff --git a/lionfish/src/main/scala/com/lionfish/client/BatchStream.scala b/lionfish/src/main/scala/com/lionfish/client/BatchStream.scala index afb0b87..3fff66e 100755 --- a/lionfish/src/main/scala/com/lionfish/client/BatchStream.scala +++ b/lionfish/src/main/scala/com/lionfish/client/BatchStream.scala @@ -9,8 +9,17 @@ class BatchStream( } override def execute(): Any = { - val result = macroMethod.executeBatch() - macroMethod = null + var result: List[Any] = null + + try { + result = macroMethod.executeBatch() + macroMethod = null + } catch { + case e: Exception => { + log.error(s"Failed to execute the batch.") + } + } + result } } diff --git a/lionfish/src/main/scala/com/lionfish/client/Database.scala b/lionfish/src/main/scala/com/lionfish/client/Database.scala index be10fa5..2d0c9c2 100755 --- a/lionfish/src/main/scala/com/lionfish/client/Database.scala +++ b/lionfish/src/main/scala/com/lionfish/client/Database.scala @@ -5,8 +5,8 @@ import com.typesafe.config.ConfigFactory import com.lionfish.utils.Config object Database extends Factory { - private var serverAddress = Config.defaultServerAddress - private var serverPort = Config.defaultServerPort + private var serverAddress = Config.serverAddress + private var serverPort = Config.serverPort def getServerAddress = { serverAddress @@ -32,6 +32,25 @@ object Database extends Factory { new SequenceStream(serverAddress, serverPort) } + /** + * Executes Cypher query + * @return list of lists of data + */ + case class executeQuery(private val query: String, + private val parameters: Map[String, Any]) extends Method { + override def getRequest: Map[String, Any] = { + val request = Map( + "methodName" -> "executeQuery", + "args" -> Map( + "query" -> query, + "parameters" -> parameters + ) + ) + + request + } + } + case class getByUuid(private val nodeUuid: String) extends Method { override def getRequest: Map[String, Any] = { val request = Map( @@ -45,7 +64,8 @@ object Database extends Factory { } } - case class getByLink(private val modelName: String, link: String) extends Method { + case class getByLink(private val modelName: String, + private val link: String) extends Method { override def getRequest: Map[String, Any] = { val request = Map( "methodName" -> "getByLink", @@ -85,6 +105,19 @@ object Database extends Factory { } } + case class getByUsername(private val username: String) extends Method { + override def getRequest: Map[String, Any] = { + val request = Map( + "methodName" -> "getByUsername", + "args" -> Map( + "username" -> username + ) + ) + + request + } + } + case class getModelNodes() extends Method { override def getRequest: Map[String, Any] = { val request = Map( @@ -96,9 +129,11 @@ object Database extends Factory { } } - case class getChildren(private val parentUuid: String, relationshipType: String, - childrenProperties: Map[String, Any] = Map(), - relationshipProperties: Map[String, Any] = Map()) extends Method { + case class getChildren(private val parentUuid: String, + private val relationshipType: String, + private val childrenProperties: Map[String, Any] = Map(), + private val relationshipProperties: Map[String, Any] = Map(), + private val limit: Int = 0) extends Method { override def getRequest: Map[String, Any] = { val request = Map( "methodName" -> "getChildren", @@ -106,7 +141,8 @@ object Database extends Factory { "parentUuid" -> parentUuid, "relType" -> relationshipType, "childrenProps" -> childrenProperties, - "relProps" -> relationshipProperties + "relProps" -> relationshipProperties, + "limit" -> limit ) ) @@ -115,15 +151,17 @@ object Database extends Factory { } case class getInstances(private val modelName: String, - childrenProperties: Map[String, Any] = Map(), - relationshipProperties: Map[String, Any] = Map()) extends Method { + private val childrenProperties: Map[String, Any] = Map(), + private val relationshipProperties: Map[String, Any] = Map(), + private val limit: Int = 0) extends Method { override def getRequest: Map[String, Any] = { val request = Map( "methodName" -> "getInstances", "args" -> Map( "modelName" -> modelName, "childrenProps" -> childrenProperties, - "relProps" -> relationshipProperties + "relProps" -> relationshipProperties, + "limit" -> limit ) ) @@ -131,12 +169,14 @@ object Database extends Factory { } } - case class getUserFeeds(private val uuid: String) extends Method { + case class getUserFeeds(private val uuid: String, + private val limit: Int = 0) extends Method { override def getRequest: Map[String, Any] = { val request = Map( "methodName" -> "getUserFeeds", "args" -> Map( - "uuid" -> uuid + "uuid" -> uuid, + "limit" -> limit ) ) @@ -144,8 +184,8 @@ object Database extends Factory { } } - case class setLabel(private val uuid: String, label: String) - extends Method { + case class setLabel(private val uuid: String, + private val label: String) extends Method { override def getRequest: Map[String, Any] = { val request = Map( "methodName" -> "setLabel", @@ -159,8 +199,8 @@ object Database extends Factory { } } - case class deleteLabel(private val uuid: String, label: String) - extends Method { + case class deleteLabel(private val uuid: String, + private val label: String) extends Method { override def getRequest: Map[String, Any] = { val request = Map( "methodName" -> "deleteLabel", @@ -174,8 +214,8 @@ object Database extends Factory { } } - case class setProperties(private val uuid: String, properties: Map[String, Any]) - extends Method { + case class setProperties(private val uuid: String, + private val properties: Map[String, Any]) extends Method { override def getRequest: Map[String, Any] = { val request = Map( "methodName" -> "setProperties", @@ -189,8 +229,8 @@ object Database extends Factory { } } - case class deleteProperties(private val uuid: String, propertyKeys: List[String]) - extends Method { + case class deleteProperties(private val uuid: String, + private val propertyKeys: List[String]) extends Method { override def getRequest: Map[String, Any] = { val request = Map( "methodName" -> "deleteProperties", @@ -204,6 +244,40 @@ object Database extends Factory { } } + case class setRelationshipProperties(private val startNodeUuid: String, + private val endNodeUuid: String, + private val properties: Map[String, Any]) extends Method { + override def getRequest: Map[String, Any] = { + val request = Map( + "methodName" -> "setRelationshipProperties", + "args" -> Map( + "startNodeUuid" -> startNodeUuid, + "endNodeUuid" -> endNodeUuid, + "props" -> properties + ) + ) + + request + } + } + + case class deleteRelationshipProperties(private val startNodeUuid: String, + private val endNodeUuid: String, + private val propertyKeys: List[String]) extends Method { + override def getRequest: Map[String, Any] = { + val request = Map( + "methodName" -> "deleteRelationshipProperties", + "args" -> Map( + "startNodeUuid" -> startNodeUuid, + "endNodeUuid" -> endNodeUuid, + "propKeys" -> propertyKeys + ) + ) + + request + } + } + case class createModelNode(private val modelName: String) extends Method { override def getRequest: Map[String, Any] = { val request = Map( @@ -217,8 +291,9 @@ object Database extends Factory { } } - case class createNode(private val modelName: String, relationshipType: String, - properties: Map[String, Any]) extends Method { + case class createNode(private val modelName: String, + private val relationshipType: String, + private val properties: Map[String, Any]) extends Method { override def getRequest: Map[String, Any] = { val request = Map( "methodName" -> "createNodes", @@ -246,9 +321,10 @@ object Database extends Factory { } } - case class createRelationship(private val startNodeUuid: String, endNodeUuid: String, - relationshipType: String, properties: Map[String, Any] = Map()) - extends Method { + case class createRelationship(private val startNodeUuid: String, + private val endNodeUuid: String, + private val relationshipType: String, + private val properties: Map[String, Any] = Map()) extends Method { override def getRequest: Map[String, Any] = { val request = Map( "methodName" -> "createRelationships", @@ -264,8 +340,8 @@ object Database extends Factory { } } - case class deleteRelationship(private val startNodeUuid: String, endNodeUuid: String) - extends Method { + case class deleteRelationship(private val startNodeUuid: String, + private val endNodeUuid: String) extends Method { override def getRequest: Map[String, Any] = { val request = Map( "methodName" -> "deleteRelationships", @@ -279,33 +355,14 @@ object Database extends Factory { } } - case class setRelationshipProperties(private val startNodeUuid: String, endNodeUuid: String, - properties: Map[String, Any]) - extends Method { + case class popRelationship(private val startNodeUuid: String, + private val relType: String) extends Method { override def getRequest: Map[String, Any] = { val request = Map( - "methodName" -> "setRelationshipProperties", + "methodName" -> "popRelationships", "args" -> Map( "startNodeUuid" -> startNodeUuid, - "endNodeUuid" -> endNodeUuid, - "props" -> properties - ) - ) - - request - } - } - - case class deleteRelationshipProperties(private val startNodeUuid: String, endNodeUuid: String, - propertyKeys: List[String]) - extends Method { - override def getRequest: Map[String, Any] = { - val request = Map( - "methodName" -> "deleteRelationshipProperties", - "args" -> Map( - "startNodeUuid" -> startNodeUuid, - "endNodeUuid" -> endNodeUuid, - "propKeys" -> propertyKeys + "relType" -> relType ) ) diff --git a/lionfish/src/main/scala/com/lionfish/client/Method.scala b/lionfish/src/main/scala/com/lionfish/client/Method.scala index 8b98e31..ab2b727 100755 --- a/lionfish/src/main/scala/com/lionfish/client/Method.scala +++ b/lionfish/src/main/scala/com/lionfish/client/Method.scala @@ -21,13 +21,13 @@ trait Method { this } - def executeSequence()(implicit socket: Socket): Any = { + def executeSequence()(implicit socket: Socket): List[Any] = { val finalRequest: Map[String, Any] = Map( "type" -> "sequence", "tasks" -> tasks.toList ) - execute(finalRequest) + execute(finalRequest).asInstanceOf[List[Any]] } def executeBatch()(implicit socket: Socket): List[Any] = { diff --git a/lionfish/src/main/scala/com/lionfish/client/SequenceStream.scala b/lionfish/src/main/scala/com/lionfish/client/SequenceStream.scala index 0a6d0fb..89a1385 100755 --- a/lionfish/src/main/scala/com/lionfish/client/SequenceStream.scala +++ b/lionfish/src/main/scala/com/lionfish/client/SequenceStream.scala @@ -5,23 +5,21 @@ class SequenceStream( protected val serverPort: Int) extends Stream { override def !!(method: Method): Any = { - val result = method.executeSequence().asInstanceOf[List[Any]] - - if (result != null && result.length == 1) { - result(0) - } else { - result - } + method.executeSequence() } override def execute(): Any = { - val result = macroMethod.executeSequence().asInstanceOf[List[Any]] - macroMethod = null + var result: List[Any] = null - if (result != null && result.length == 1) { - result(0) - } else { - result + try { + result = macroMethod.executeSequence() + macroMethod = null + } catch { + case e: Exception => { + log.error(s"Failed to execute the sequence.") + } } + + result } } diff --git a/lionfish/src/main/scala/com/lionfish/client/Stream.scala b/lionfish/src/main/scala/com/lionfish/client/Stream.scala index 488308e..966e4da 100755 --- a/lionfish/src/main/scala/com/lionfish/client/Stream.scala +++ b/lionfish/src/main/scala/com/lionfish/client/Stream.scala @@ -1,16 +1,21 @@ package com.lionfish.client import java.net.Socket +import com.lionfish.logging.Logging trait Stream { + protected val log = Logging protected val serverAddress: String protected val serverPort: Int // Connects to the server protected implicit val socket: Socket = new Socket(serverAddress, serverPort) - protected var macroMethod: Method = null + def close() = { + socket.close() + } + def <<(method: Method): Stream = { if (macroMethod == null) { macroMethod = method diff --git a/lionfish/src/main/scala/com/lionfish/logging/DebugLogger.scala b/lionfish/src/main/scala/com/lionfish/logging/DebugLogger.scala new file mode 100644 index 0000000..9162854 --- /dev/null +++ b/lionfish/src/main/scala/com/lionfish/logging/DebugLogger.scala @@ -0,0 +1,14 @@ +package com.lionfish.logging + +class DebugLogger extends Logger { + private val mask = 5 + private val prefix = Console.CYAN + "[DEBUG] " + Console.RESET + + override def log(level: Int, message: String) = { + if (level == mask) { + println(prefix + message) + } else if (next != null) { + next.log(level, message) + } + } +} diff --git a/lionfish/src/main/scala/com/lionfish/logging/ErrorLogger.scala b/lionfish/src/main/scala/com/lionfish/logging/ErrorLogger.scala new file mode 100644 index 0000000..7fd4d68 --- /dev/null +++ b/lionfish/src/main/scala/com/lionfish/logging/ErrorLogger.scala @@ -0,0 +1,14 @@ +package com.lionfish.logging + +class ErrorLogger extends Logger { + private val mask = 1 + private val prefix = Console.BOLD + Console.RED + "[ERROR] " + Console.RESET + + override def log(level: Int, message: String) = { + if (level == mask) { + println(prefix + message) + } else if (next != null) { + next.log(level, message) + } + } +} diff --git a/lionfish/src/main/scala/com/lionfish/logging/InfoLogger.scala b/lionfish/src/main/scala/com/lionfish/logging/InfoLogger.scala new file mode 100644 index 0000000..edc1075 --- /dev/null +++ b/lionfish/src/main/scala/com/lionfish/logging/InfoLogger.scala @@ -0,0 +1,14 @@ +package com.lionfish.logging + +class InfoLogger extends Logger { + private val mask = 3 + private val prefix = Console.YELLOW + "[INFO] " + Console.RESET + + override def log(level: Int, message: String) = { + if (level == mask) { + println(prefix + message) + } else if (next != null) { + next.log(level, message) + } + } +} diff --git a/lionfish/src/main/scala/com/lionfish/logging/Logger.scala b/lionfish/src/main/scala/com/lionfish/logging/Logger.scala new file mode 100644 index 0000000..eccfa6c --- /dev/null +++ b/lionfish/src/main/scala/com/lionfish/logging/Logger.scala @@ -0,0 +1,12 @@ +package com.lionfish.logging + +trait Logger { + protected var next: Logger = null + + def setNext(logger: Logger): Logger = { + next = logger + logger + } + + def log(level: Int, message: String) +} diff --git a/lionfish/src/main/scala/com/lionfish/logging/Logging.scala b/lionfish/src/main/scala/com/lionfish/logging/Logging.scala new file mode 100644 index 0000000..4cc26d0 --- /dev/null +++ b/lionfish/src/main/scala/com/lionfish/logging/Logging.scala @@ -0,0 +1,23 @@ +package com.lionfish.logging + +object Logging { + private val errorMask = 1 + private val infoMask = 3 + private val debugMask = 5 + + // Chain of responsibility + private val logger: Logger = new DebugLogger + logger.setNext(new InfoLogger).setNext(new ErrorLogger) + + def error(message: String) = { + logger.log(errorMask, message) + } + + def info(message: String) = { + logger.log(infoMask, message) + } + + def debug(message: String) = { + logger.log(debugMask, message) + } +} diff --git a/lionfish/src/main/scala/com/lionfish/messages/Connection.scala b/lionfish/src/main/scala/com/lionfish/messages/Connection.scala new file mode 100644 index 0000000..1dca3b8 --- /dev/null +++ b/lionfish/src/main/scala/com/lionfish/messages/Connection.scala @@ -0,0 +1,5 @@ +package com.lionfish.messages + +import java.net.Socket + +case class Connection(socket: Socket) extends Message diff --git a/lionfish/src/main/scala/com/lionfish/messages/Response.scala b/lionfish/src/main/scala/com/lionfish/messages/Response.scala index 8086469..5cbf2bd 100755 --- a/lionfish/src/main/scala/com/lionfish/messages/Response.scala +++ b/lionfish/src/main/scala/com/lionfish/messages/Response.scala @@ -1,3 +1,3 @@ package com.lionfish.messages -case class Response(clientUuid: String, result: Any) extends Message +case class Response(clientUuid: String, request: Request, result: Any) extends Message diff --git a/lionfish/src/main/scala/com/lionfish/server/Connection.scala b/lionfish/src/main/scala/com/lionfish/server/Connection.scala deleted file mode 100644 index 5c9cbbc..0000000 --- a/lionfish/src/main/scala/com/lionfish/server/Connection.scala +++ /dev/null @@ -1,40 +0,0 @@ -package com.lionfish.server - -import java.net.Socket -import java.util.UUID -import scala.concurrent.Await -import scala.concurrent.duration._ -import akka.actor._ -import akka.util.Timeout -import akka.pattern.ask -import com.lionfish.utils.IO -import com.lionfish.messages.Request - -class Connection(private val master: ActorRef)(private implicit val socket: Socket) extends Runnable { - private implicit val timeout = Timeout(600 seconds) - private val connectionUuid = UUID.randomUUID().toString - - private def disconnect() = { - try { - socket.close() - } catch { - case e: Exception => { - println(s"Connection failed to disconnect. Error message: $e") - } - } - } - - def run() = { - // Process requests - var request: Map[String, Any] = null - while ({request = IO.receive[Map[String, Any]](); request} != null) { - try { - val future = master ? Request(connectionUuid, request) - val response = Await.result[Any](future, timeout.duration) - IO.send(response) - } - } - - disconnect() - } -} diff --git a/lionfish/src/main/scala/com/lionfish/server/Launcher.scala b/lionfish/src/main/scala/com/lionfish/server/Launcher.scala index a2b0835..10d510b 100755 --- a/lionfish/src/main/scala/com/lionfish/server/Launcher.scala +++ b/lionfish/src/main/scala/com/lionfish/server/Launcher.scala @@ -1,75 +1,133 @@ package com.lionfish.server -import java.net._ -import akka.actor._ -import com.typesafe.config.ConfigFactory import com.lionfish.utils.Config +import com.lionfish.logging.Logging object Launcher { - private def parseParams(args: Array[String]): Map[String, Any] = { - var result: Map[String, Any] = Map() + private val log = Logging + + private def configure(args: Array[String]) = { + var debug = false + var customPort = false for (item <- args) { val arg = item.split("=") arg(0) match { case "--debug" => { - result += "debug" -> null + try { + if (!customPort) { + Config.serverAddress = "localhost" + Config.serverPort = 7777 + debug = true + log.info("Running in the debug mode (port: 7777).") + } else { + throw new Exception() + } + } catch { + case e: Exception => log.info("Custom port already set or invalid parameter: debug.") + } } case "--port" => { try { - result += "port" -> arg(1).toInt - println("port") + val value = arg(1).toInt + if (value > 0 && !debug) { + Config.serverPort = arg(1).toInt + customPort = true + log.info(s"Using custom server port: $value.") + } else { + throw new Exception() + } } catch { - case e: Exception => println("Invalid parameter: port") + case e: Exception => log.info("Debug mode already set or invalid parameter: port.") } } case "--neo4j-path" => { try { - result += "neo4j-path" -> arg(1) - println("neo4j-path") + val value = arg(1) + Config.neo4jPath = value + log.info(s"Using Neo4j custom path: $value.") } catch { - case e: Exception => println("Invalid parameter: neo4j-path") + case e: Exception => log.info("Invalid parameter: neo4j-path.") } } case "--neo4j-console-port" => { try { - result += "neo4j-console-port" -> arg(1).toInt - println("neo4j-console-port") + val value = arg(1).toInt + if (value > 0) { + Config.neo4jConsolePort = arg(1).toInt + log.info(s"Using custom Neo4j console port: $value.") + } else { + throw new Exception() + } + } catch { + case e: Exception => log.info("Invalid parameter: neo4j-console-port.") + } + } + case "--use-cache" => { + try { + Config.useCache = true + log.info("Using cache.") + } catch { + case e: Exception => log.info("Custom port already set or invalid parameter: debug.") + } + } + case "--cache-port" => { + try { + val value = arg(1).toInt + if (value > 0) { + Config.cachePort = arg(1).toInt + log.info(s"Using custom cache port: $value.") + } else { + throw new Exception() + } } catch { - case e: Exception => println("Invalid parameter: neo4j-console-port") + case e: Exception => log.info("Invalid parameter: neo4j-console-port.") + } + } + case "--num-of-request-handlers" => { + try { + val value = arg(1).toInt + if (value > 0) { + Config.numberOfRequestHandlers = value + log.info(s"Using custom number of request handlers ($value).") + } else { + throw new Exception() + } + } catch { + case e: Exception => log.info("Invalid parameter: num-of-request-handlers.") + } + } + case "--num-of-cache-workers" => { + try { + val value = arg(1).toInt + if (value > 0) { + Config.numberOfCacheWorkers = value + log.info(s"Using custom number of cache workers ($value).") + } else { + throw new Exception() + } + } catch { + case e: Exception => log.info("Invalid parameter: num-of-cache-workers.") + } + } + case "--num-of-db-workers" => { + try { + val value = arg(1).toInt + if (value > 0) { + Config.numberOfDatabaseWorkers = value + log.info(s"Using custom number of database workers ($value).") + } else { + throw new Exception() + } + } catch { + case e: Exception => log.info("Invalid parameter: num-of-db-workers.") } } } } - - result } def main(args: Array[String]) = { - // Parses params - val params = parseParams(args) - - // Sets params - if (params.contains("debug")) { - Server.port = 7777 - } else if (params.contains("port")) { - Server.port = params("port").asInstanceOf[Int] - } - - if (params.contains("neo4j-path")) { - var neo4jPath = params("neo4j-path").asInstanceOf[String] - if (neo4jPath(neo4jPath.length - 1) == '/') { - neo4jPath = neo4jPath.substring(0, neo4jPath.length - 1) - } - - DatabaseManager.setNeo4jPath(neo4jPath) - } - - if (params.contains("neo4j-console-port")) { - DatabaseManager.setNeo4jConsolePort(params("neo4j-console-port").asInstanceOf[Int]) - } - - - DatabaseManager.initNeo4jConsole() + configure(args) new Thread(Server).start() } } diff --git a/lionfish/src/main/scala/com/lionfish/server/Master.scala b/lionfish/src/main/scala/com/lionfish/server/Master.scala deleted file mode 100755 index bde03fe..0000000 --- a/lionfish/src/main/scala/com/lionfish/server/Master.scala +++ /dev/null @@ -1,30 +0,0 @@ -package com.lionfish.server - -import akka.actor.{Actor, ActorRef, ActorSystem, Props} -import akka.routing.RoundRobinPool -import akka.event.Logging -import com.lionfish.messages._ - -class Master extends Actor { - val log = Logging(context.system, this) - log.info("Master is running.") - - var senderMap: Map[String, ActorRef] = Map() - - // Creates request handler system and pool - private val requestHandlerSystem = ActorSystem("masterSystem") - private val requestHandlerPool = requestHandlerSystem.actorOf( - Props[RequestHandler].withRouter(RoundRobinPool(10)), "requestHandlerPool") - - def receive = { - case req @ Request(connectionUuid, request) => { - senderMap += connectionUuid -> sender - requestHandlerPool ! req - } - case Response(connectionUuid, result) => { - // TODO: error handling - senderMap(connectionUuid) ! result - senderMap -= connectionUuid - } - } -} diff --git a/lionfish/src/main/scala/com/lionfish/server/Server.scala b/lionfish/src/main/scala/com/lionfish/server/Server.scala index 1293105..feb8ef1 100644 --- a/lionfish/src/main/scala/com/lionfish/server/Server.scala +++ b/lionfish/src/main/scala/com/lionfish/server/Server.scala @@ -2,23 +2,61 @@ package com.lionfish.server import java.net.ServerSocket import scala.concurrent.Lock -import akka.actor.{ActorSystem, Props} +import akka.actor.{Props, ActorSystem} +import akka.routing.RoundRobinPool +import com.typesafe.config.ConfigFactory import com.lionfish.utils.Config +import com.lionfish.messages.Connection +import com.lionfish.workers._ +import com.lionfish.logging.Logging +import com.lionfish.wrappers._ object Server extends Runnable { - var port = Config.defaultServerPort + private val log = Logging + private val serverPort = Config.serverPort private val threadLock = new Lock val debugLock = new Lock debugLock.acquire() + // Sets database wrapper + private val wrapper: DatabaseWrapper = new Neo4jWrapper + wrapper.init() + + // Creates database workers + private val databaseWorkerSystem = ActorSystem( + "databaseWorkerSystem", ConfigFactory.load("databaseWorkerSystem")) + private val databaseWorkerPool = databaseWorkerSystem.actorOf( + Props(new DatabaseWorker(wrapper)).withRouter( + RoundRobinPool(Config.numberOfDatabaseWorkers)), "databaseWorkerPool") + log.info("Starting " + Config.numberOfDatabaseWorkers + " database workers.") + + // Creates cache workers + private val cacheWorkerSystem = ActorSystem( + "cacheWorkerSystem", ConfigFactory.load("cacheWorkerSystem")) + private val cacheWorkerPool = cacheWorkerSystem.actorOf( + Props(new CacheWorker).withRouter( + RoundRobinPool(Config.numberOfCacheWorkers)), "cacheWorkerPool") + log.info("Starting " + Config.numberOfCacheWorkers + " cache workers.") + // Creates master worker - private val masterSystem = ActorSystem("masterSystem") - private val master = masterSystem.actorOf(Props(new Master)) + private val masterSystem = ActorSystem( + "masterSystem", ConfigFactory.load("masterSystem")) + private val master = masterSystem.actorOf(Props(new Master), "master") + log.info("Starting master.") + + // Creates request handlers + private val requestHandlerSystem = ActorSystem( + "requestHandlerSystem", ConfigFactory.load("requestHandlerSystem")) + private val requestHandlerPool = requestHandlerSystem.actorOf( + Props(new RequestHandler).withRouter( + RoundRobinPool(Config.numberOfRequestHandlers)), "requestHandlerPool") + log.info("Starting " + Config.numberOfRequestHandlers + " request handlers.") + // Handles incoming connections private def handleConnections(serverSocket: ServerSocket) = { while (true) { - implicit val socket = serverSocket.accept() - new Thread(new Connection(master)).start() + val socket = serverSocket.accept() + requestHandlerPool ! Connection(socket) } } @@ -27,17 +65,17 @@ object Server extends Runnable { threadLock.acquire() try { - val serverSocket = new ServerSocket(port) + val serverSocket = new ServerSocket(serverPort) debugLock.release() handleConnections(serverSocket) serverSocket.close() } catch { case e: Exception => { - println(s"Failed to start the Lionfish server. Error message: $e") + log.error(s"Failed to start the Lionfish server. Error message: $e") } } finally { threadLock.release() - println("The Lionfish server terminated.") + log.info("The Lionfish server terminated.") } } } diff --git a/lionfish/src/main/scala/com/lionfish/utils/Config.scala b/lionfish/src/main/scala/com/lionfish/utils/Config.scala index 9a14842..74efd9e 100755 --- a/lionfish/src/main/scala/com/lionfish/utils/Config.scala +++ b/lionfish/src/main/scala/com/lionfish/utils/Config.scala @@ -1,11 +1,20 @@ package com.lionfish.utils object Config { - val defaultServerAddress = "ocean-lionfish.no-ip.biz" - val defaultServerPort = 21 - val defaultNeo4jPath = "/usr/lib/neo4j" - val defaultNeo4jConsolePort = 7474 + val masterSystemPort = 7775 + val cacheWorkerSystemPort = 7774 + val databaseWorkerSystemPort = 7773 - val debugServerAddress = "localhost" - val debugServerPort = 7777 + var cacheAddress = "127.0.0.1" + var cachePort = 7772 + + var serverAddress = "ocean-lionfish.no-ip.biz" + var serverPort = 21 + var neo4jPath = "/usr/lib/neo4j" + var neo4jConsolePort = 7474 + var useCache = false + + var numberOfRequestHandlers = 10 + var numberOfCacheWorkers = 10 + var numberOfDatabaseWorkers = 10 } diff --git a/lionfish/src/main/scala/com/lionfish/utils/IO.scala b/lionfish/src/main/scala/com/lionfish/utils/IO.scala index feab275..1d82d78 100644 --- a/lionfish/src/main/scala/com/lionfish/utils/IO.scala +++ b/lionfish/src/main/scala/com/lionfish/utils/IO.scala @@ -2,8 +2,11 @@ package com.lionfish.utils import java.net.Socket import java.nio.ByteBuffer +import com.lionfish.logging.Logging object IO { + private val log = Logging + // Sends a message to socket def send(rawData: Any)(implicit socket: Socket) = { try { @@ -22,7 +25,7 @@ object IO { outputStream.write(msg) } catch { case e: Exception => { - println(s"Failed to send data. Error message: $e") + log.error(s"Failed to send data. Error message: $e") } } } @@ -57,7 +60,7 @@ object IO { JSON.deserialise[T](msg) } catch { case e: Exception => { - println(s"Failed to receive data. Error message: $e") + log.error(s"Failed to receive data. Error message: $e") } null.asInstanceOf[T] } diff --git a/lionfish/src/main/scala/com/lionfish/utils/Model.scala b/lionfish/src/main/scala/com/lionfish/utils/Model.scala new file mode 100644 index 0000000..c648cf8 --- /dev/null +++ b/lionfish/src/main/scala/com/lionfish/utils/Model.scala @@ -0,0 +1,9 @@ +package com.lionfish.utils + +object Model { + val NEO_USER = "NeoUser" + val TAG = "Tag" + val CONTENT = "Content" + val CONTENT_SOURCE = "ContentSource" + val FEED = "Feed" +} diff --git a/lionfish/src/main/scala/com/lionfish/workers/CacheWorker.scala b/lionfish/src/main/scala/com/lionfish/workers/CacheWorker.scala new file mode 100644 index 0000000..e34798c --- /dev/null +++ b/lionfish/src/main/scala/com/lionfish/workers/CacheWorker.scala @@ -0,0 +1,77 @@ +package com.lionfish.workers + +import java.net.InetSocketAddress +import akka.actor._ +import net.spy.memcached.MemcachedClient +import com.lionfish.messages._ +import com.lionfish.utils.Config +import com.lionfish.logging.Logging + +class CacheWorker extends Worker with Actor { + private val log = Logging + private val masterSystemPort = Config.masterSystemPort + private val databaseWorkerSystemPort = Config.databaseWorkerSystemPort + private var cacheClient: MemcachedClient = null + + // If the user wants to use cache + if (Config.useCache) { + cacheClient = new MemcachedClient(new InetSocketAddress(Config.cacheAddress, Config.cachePort)) + } + + // Master worker + private val masterPath = + s"akka.tcp://masterSystem@localhost:$masterSystemPort/user/master" + private val master = context.actorSelection(masterPath) + + // Database worker pool system + private val databaseWorkerPath = + s"akka.tcp://databaseWorkerSystem@localhost:$databaseWorkerSystemPort/user/databaseWorkerPool" + private val databaseWorkerPool = context.actorSelection(databaseWorkerPath) + + // Decides whether fetch data from cache or database + override def processRequest(request: Request): Any = { + val requestHash = request.hashCode().toString + + // If the user wants to use cache + if (Config.useCache) { + val cachedResult = cacheClient.get(requestHash) + if (cachedResult != null) { + // If the data exists in the cache + val uuid = request.connectionUuid + log.info(s"Fetching data from cache.") + + context.self ! Response(uuid, request, cachedResult) + } else { + databaseWorkerPool ! request + } + } else { + databaseWorkerPool ! request + } + + null + } + + // Saves response to the cache + def processResponse(response: Response) = { + val requestHash = response.request.hashCode().toString + val result = response.result + + // TODO: make a set of "cacheable" methods + if (Config.useCache) { + val cachedResult = cacheClient.get(requestHash) + if (cachedResult == null) { + cacheClient.set(requestHash, 3600, result) + } + } + } + + def receive = { + case req @ Request(uuid, request) => { + processRequest(req) + } + case res @ Response(uuid, request, result) => { + processResponse(res) + master ! res + } + } +} diff --git a/lionfish/src/main/scala/com/lionfish/server/RequestHandler.scala b/lionfish/src/main/scala/com/lionfish/workers/DatabaseWorker.scala similarity index 51% rename from lionfish/src/main/scala/com/lionfish/server/RequestHandler.scala rename to lionfish/src/main/scala/com/lionfish/workers/DatabaseWorker.scala index c290213..0878c10 100755 --- a/lionfish/src/main/scala/com/lionfish/server/RequestHandler.scala +++ b/lionfish/src/main/scala/com/lionfish/workers/DatabaseWorker.scala @@ -1,12 +1,14 @@ -package com.lionfish.server +package com.lionfish.workers import scala.collection.mutable.ListBuffer import akka.actor.Actor -import akka.event.Logging import com.lionfish.messages._ +import com.lionfish.logging.Logging +import com.lionfish.wrappers._ + +class DatabaseWorker(private val wrapper: DatabaseWrapper) extends Worker with Actor { + private val log = Logging -class RequestHandler extends Actor { - val log = Logging(context.system, this) private def executeBatch(request: Map[String, Any]): List[Any] = { try { val count = request("count").asInstanceOf[Int] @@ -19,67 +21,79 @@ class RequestHandler extends Actor { fullArgs += item(0).asInstanceOf[Map[String, Any]] } - println(s"Executing $methodName in batch.") + log.info(s"Executing $methodName in a batch.") // TODO: Solve this with reflection var rawResult: List[Any] = null methodName match { + case "executeQuery" => { + rawResult = wrapper.executeQuery(fullArgs.toList) + } case "getByUuid" => { - rawResult = DatabaseManager.getByUuid(fullArgs.toList) + rawResult = wrapper.getByUuid(fullArgs.toList) } case "getByLink" => { - rawResult = DatabaseManager.getByLink(fullArgs.toList) + rawResult = wrapper.getByLink(fullArgs.toList) } case "getByTag" => { - rawResult = DatabaseManager.getByTag(fullArgs.toList) + rawResult = wrapper.getByTag(fullArgs.toList) + } + case "getByUsername" => { + rawResult = wrapper.getByUsername(fullArgs.toList) } case "getByLabel" => { - rawResult = DatabaseManager.getByLabel(fullArgs.toList) + rawResult = wrapper.getByLabel(fullArgs.toList) } case "getModelNodes" => { - rawResult = DatabaseManager.getModelNodes(fullArgs.toList) + rawResult = wrapper.getModelNodes(fullArgs.toList) } case "getChildren" => { - rawResult = DatabaseManager.getChildren(fullArgs.toList) + rawResult = wrapper.getChildren(fullArgs.toList) } case "getInstances" => { - rawResult = DatabaseManager.getInstances(fullArgs.toList) + rawResult = wrapper.getInstances(fullArgs.toList) } case "getUserFeeds" => { - rawResult = DatabaseManager.getUserFeeds(fullArgs.toList) + rawResult = wrapper.getUserFeeds(fullArgs.toList) } case "setLabel" => { - rawResult = DatabaseManager.setLabel(fullArgs.toList) + rawResult = wrapper.setLabel(fullArgs.toList) } case "deleteLabel" => { - rawResult = DatabaseManager.deleteLabel(fullArgs.toList) + rawResult = wrapper.deleteLabel(fullArgs.toList) } case "setProperties" => { - rawResult = DatabaseManager.setProperties(fullArgs.toList) + rawResult = wrapper.setProperties(fullArgs.toList) } case "deleteProperties" => { - rawResult = DatabaseManager.deleteProperties(fullArgs.toList) + rawResult = wrapper.deleteProperties(fullArgs.toList) + } + case "setRelationshipProperties" => { + rawResult = wrapper.setRelationshipProperties(fullArgs.toList) + } + case "deleteRelationshipProperties" => { + rawResult = wrapper.deleteRelationshipProperties(fullArgs.toList) } case "createModelNodes" => { - rawResult = DatabaseManager.createModelNodes(fullArgs.toList) + rawResult = wrapper.createModelNodes(fullArgs.toList) } case "createNodes" => { - rawResult = DatabaseManager.createNodes(fullArgs.toList) + rawResult = wrapper.createNodes(fullArgs.toList) } case "deleteNodes" => { - rawResult = DatabaseManager.deleteNodes(fullArgs.toList) + rawResult = wrapper.deleteNodes(fullArgs.toList) } case "createRelationships" => { - rawResult = DatabaseManager.createRelationships(fullArgs.toList) + rawResult = wrapper.createRelationships(fullArgs.toList) } - case "deleteRelationships" => { - rawResult = DatabaseManager.deleteRelationships(fullArgs.toList) + case "createUniqueRelationships" => { + rawResult = wrapper.createUniqueRelationships(fullArgs.toList) } - case "setRelationshipProperties" => { - rawResult = DatabaseManager.setRelationshipProperties(fullArgs.toList) + case "deleteRelationships" => { + rawResult = wrapper.deleteRelationships(fullArgs.toList) } - case "deleteRelationshipProperties" => { - rawResult = DatabaseManager.deleteRelationshipProperties(fullArgs.toList) + case "popRelationships" => { + rawResult = wrapper.popRelationships(fullArgs.toList) } case _ => throw new NoSuchMethodException(methodName) } @@ -109,67 +123,79 @@ class RequestHandler extends Actor { val methodName = item("methodName").asInstanceOf[String] val args = List(item("args").asInstanceOf[Map[String, Any]]) - println(s"Executing $methodName in sequence.") + log.info(s"Executing $methodName in a sequence.") // TODO: Solve this with reflection var rawResult: List[Any] = null methodName match { + case "executeQuery" => { + rawResult = wrapper.executeQuery(args) + } case "getByUuid" => { - rawResult = DatabaseManager.getByUuid(args) + rawResult = wrapper.getByUuid(args) } case "getByLink" => { - rawResult = DatabaseManager.getByLink(args) + rawResult = wrapper.getByLink(args) } case "getByTag" => { - rawResult = DatabaseManager.getByTag(args) + rawResult = wrapper.getByTag(args) + } + case "getByUsername" => { + rawResult = wrapper.getByUsername(args) } case "getByLabel" => { - rawResult = DatabaseManager.getByLabel(args) + rawResult = wrapper.getByLabel(args) } case "getModelNodes" => { - rawResult = DatabaseManager.getModelNodes(args) + rawResult = wrapper.getModelNodes(args) } case "getChildren" => { - rawResult = DatabaseManager.getChildren(args) + rawResult = wrapper.getChildren(args) } case "getInstances" => { - rawResult = DatabaseManager.getInstances(args) + rawResult = wrapper.getInstances(args) } case "getUserFeeds" => { - rawResult = DatabaseManager.getUserFeeds(args) + rawResult = wrapper.getUserFeeds(args) } case "setLabel" => { - rawResult = DatabaseManager.setLabel(args) + rawResult = wrapper.setLabel(args) } case "deleteLabel" => { - rawResult = DatabaseManager.deleteLabel(args) + rawResult = wrapper.deleteLabel(args) } case "setProperties" => { - rawResult = DatabaseManager.setProperties(args) + rawResult = wrapper.setProperties(args) } case "deleteProperties" => { - rawResult = DatabaseManager.deleteProperties(args) + rawResult = wrapper.deleteProperties(args) + } + case "setRelationshipProperties" => { + rawResult = wrapper.setRelationshipProperties(args) + } + case "deleteRelationshipProperties" => { + rawResult = wrapper.deleteRelationshipProperties(args) } case "createModelNodes" => { - rawResult = DatabaseManager.createModelNodes(args) + rawResult = wrapper.createModelNodes(args) } case "createNodes" => { - rawResult = DatabaseManager.createNodes(args) + rawResult = wrapper.createNodes(args) } case "deleteNodes" => { - rawResult = DatabaseManager.deleteNodes(args) + rawResult = wrapper.deleteNodes(args) } case "createRelationships" => { - rawResult = DatabaseManager.createRelationships(args) + rawResult = wrapper.createRelationships(args) } - case "deleteRelationships" => { - rawResult = DatabaseManager.deleteRelationships(args) + case "createUniqueRelationships" => { + rawResult = wrapper.createUniqueRelationships(args) } - case "setRelationshipProperties" => { - rawResult = DatabaseManager.setRelationshipProperties(args) + case "deleteRelationships" => { + rawResult = wrapper.deleteRelationships(args) } - case "deleteRelationshipProperties" => { - rawResult = DatabaseManager.deleteRelationshipProperties(args) + case "popRelationships" => { + rawResult = wrapper.popRelationships(args) } case _ => throw new NoSuchMethodException(methodName) } @@ -186,19 +212,21 @@ class RequestHandler extends Actor { case e: Exception => { log.error(s"Failed to execute a sequence. Error message: $e") } - null + List() } } - def handle(request: Map[String, Any]): Any = { - // Process request + override def processRequest(request: Request): Any = { + val requestData = request.request + + // Processes request try { var result: Any = null - val requestType = request("type").asInstanceOf[String] + val requestType = requestData("type").asInstanceOf[String] if (requestType == "sequence") { - result = executeSequence(request) + result = executeSequence(requestData) } else { - result = executeBatch(request) + result = executeBatch(requestData) } result @@ -206,14 +234,14 @@ class RequestHandler extends Actor { case e: Exception => { log.error(s"Failed to process a request. Error message: $e") } - null + List() } } def receive = { - case Request(connectionUuid, request) => { - val result = handle(request) - sender ! Response(connectionUuid, result) + case req @ Request(connectionUuid, request) => { + val result = processRequest(req) + sender ! Response(connectionUuid, req, result) } } } diff --git a/lionfish/src/main/scala/com/lionfish/workers/Master.scala b/lionfish/src/main/scala/com/lionfish/workers/Master.scala new file mode 100755 index 0000000..9b598d3 --- /dev/null +++ b/lionfish/src/main/scala/com/lionfish/workers/Master.scala @@ -0,0 +1,30 @@ +package com.lionfish.workers + +import akka.actor.{Actor, ActorRef} +import akka.event.Logging +import com.lionfish.utils.Config +import com.lionfish.messages._ + +class Master extends Actor { + private val log = Logging(context.system, this) + + private val cacheWorkerSystemPort = Config.cacheWorkerSystemPort + private var senderMap: Map[String, ActorRef] = Map() + + // Cache worker pool system + private val cacheWorkerPath = + s"akka.tcp://cacheWorkerSystem@localhost:$cacheWorkerSystemPort/user/cacheWorkerPool" + private val cacheWorkerPool = context.actorSelection(cacheWorkerPath) + + def receive = { + case req @ Request(connectionUuid, request) => { + senderMap += connectionUuid -> sender + cacheWorkerPool ! req + } + case Response(connectionUuid, request, result) => { + // TODO: error handling + senderMap(connectionUuid) ! result + senderMap -= connectionUuid + } + } +} diff --git a/lionfish/src/main/scala/com/lionfish/workers/RequestHandler.scala b/lionfish/src/main/scala/com/lionfish/workers/RequestHandler.scala new file mode 100644 index 0000000..663049c --- /dev/null +++ b/lionfish/src/main/scala/com/lionfish/workers/RequestHandler.scala @@ -0,0 +1,57 @@ +package com.lionfish.workers + +import java.net.Socket +import java.util.UUID +import scala.concurrent.Await +import scala.concurrent.duration._ +import akka.actor._ +import akka.util.Timeout +import akka.pattern.ask +import com.lionfish.utils.{Config, IO} +import com.lionfish.messages._ +import com.lionfish.logging.Logging + +class RequestHandler extends Actor { + private val log = Logging + private implicit val timeout = Timeout(600 seconds) + private val masterSystemPort = Config.masterSystemPort + + // Master worker + private val masterPath = + s"akka.tcp://masterSystem@localhost:$masterSystemPort/user/master" + private val master = context.actorSelection(masterPath) + + private def disconnect(connectionUuid: String, socket: Socket) = { + try { + log.info(s"Closing connection $connectionUuid.") + socket.close() + } catch { + case e: Exception => { + log.error(s"Connection failed to disconnect. Error message: $e") + } + } + } + + def handleConnection(connectionUuid: String)(implicit socket: Socket) = { + log.info(s"New connection $connectionUuid.") + + // Process requests + var request: Map[String, Any] = null + while ({request = IO.receive[Map[String, Any]](); request} != null) { + try { + val future = master ? Request(connectionUuid, request) + val response = Await.result[Any](future, timeout.duration) + IO.send(response) + } + } + + disconnect(connectionUuid, socket) + } + + def receive = { + case Connection(socket) => { + val connectionUuid = UUID.randomUUID().toString + handleConnection(connectionUuid)(socket) + } + } +} diff --git a/lionfish/src/main/scala/com/lionfish/workers/Worker.scala b/lionfish/src/main/scala/com/lionfish/workers/Worker.scala new file mode 100644 index 0000000..11fbc9b --- /dev/null +++ b/lionfish/src/main/scala/com/lionfish/workers/Worker.scala @@ -0,0 +1,7 @@ +package com.lionfish.workers + +import com.lionfish.messages.Request + +trait Worker { + def processRequest(request: Request): Any +} diff --git a/lionfish/src/main/scala/com/lionfish/wrappers/DatabaseWrapper.scala b/lionfish/src/main/scala/com/lionfish/wrappers/DatabaseWrapper.scala new file mode 100644 index 0000000..d5e8696 --- /dev/null +++ b/lionfish/src/main/scala/com/lionfish/wrappers/DatabaseWrapper.scala @@ -0,0 +1,36 @@ +package com.lionfish.wrappers + +import org.neo4j.graphdb.{Relationship, Node} + +trait DatabaseWrapper { + def init() + + protected def parseMap(node: Node): Map[String, Any] + protected def parseMap(rel: Relationship): Map[String, Any] + protected def parseSet(node: Node): Set[(String, Any)] + protected def parseSet(rel: Relationship): Set[(String, Any)] + + def executeQuery(args: List[Map[String, Any]]): List[Any] + def getByUuid(args: List[Map[String, Any]]): List[Any] + def getByLink(args: List[Map[String, Any]]): List[Any] + def getByTag(args: List[Map[String, Any]]): List[Any] + def getByUsername(args: List[Map[String, Any]]): List[Any] + def getByLabel(args: List[Map[String, Any]]): List[Any] + def getModelNodes(args: List[Map[String, Any]]): List[Any] + def getChildren(args: List[Map[String, Any]]): List[Any] + def getInstances(args: List[Map[String, Any]]): List[Any] + def getUserFeeds(args: List[Map[String, Any]]): List[Any] + def setLabel(args: List[Map[String, Any]]): List[Any] + def deleteLabel(args: List[Map[String, Any]]): List[Any] + def setProperties(args: List[Map[String, Any]]): List[Any] + def deleteProperties(args: List[Map[String, Any]]): List[Any] + def setRelationshipProperties(args: List[Map[String, Any]]): List[Any] + def deleteRelationshipProperties(args: List[Map[String, Any]]): List[Any] + def createModelNodes(args: List[Map[String, Any]]): List[Any] + def createNodes(args: List[Map[String, Any]]): List[Any] + def deleteNodes(args: List[Map[String, Any]]): List[Any] + def createRelationships(args: List[Map[String, Any]]): List[Any] + def createUniqueRelationships(args: List[Map[String, Any]]): List[Any] + def deleteRelationships(args: List[Map[String, Any]]): List[Any] + def popRelationships(args: List[Map[String, Any]]): List[Any] +} diff --git a/lionfish/src/main/scala/com/lionfish/server/DatabaseManager.scala b/lionfish/src/main/scala/com/lionfish/wrappers/Neo4jWrapper.scala similarity index 61% rename from lionfish/src/main/scala/com/lionfish/server/DatabaseManager.scala rename to lionfish/src/main/scala/com/lionfish/wrappers/Neo4jWrapper.scala index 3eba076..d7a98cc 100755 --- a/lionfish/src/main/scala/com/lionfish/server/DatabaseManager.scala +++ b/lionfish/src/main/scala/com/lionfish/wrappers/Neo4jWrapper.scala @@ -1,4 +1,4 @@ -package com.lionfish.server +package com.lionfish.wrappers import java.util.UUID import scala.collection.mutable.ListBuffer @@ -6,54 +6,41 @@ import org.neo4j.graphdb.factory.GraphDatabaseFactory import org.neo4j.graphdb._ import org.neo4j.cypher.{ExecutionEngine, ExecutionResult} import org.neo4j.tooling.GlobalGraphOperations -import org.neo4j.server.WrappingNeoServerBootstrapper -import org.neo4j.kernel.GraphDatabaseAPI import org.neo4j.kernel._ import org.neo4j.server._ import org.neo4j.server.configuration._ -import org.neo4j.server.database._ -import org.neo4j.server.preflight._ import com.lionfish.utils.Config +import com.lionfish.logging.Logging // TODO: logging, nicer way of handling errors - -object DatabaseManager { - val databasePath = "/data/graph.db" - var neo4jPath = Config.defaultNeo4jPath - var neo4jConsolePort = Config.defaultNeo4jConsolePort - val graphDB = new GraphDatabaseFactory().newEmbeddedDatabase(neo4jPath + databasePath) - - val globalOperations = GlobalGraphOperations.at(graphDB) - val cypherEngine = new ExecutionEngine(graphDB) - var cypherResult: ExecutionResult = null - - def initNeo4jConsole(){ - val config = new ServerConfigurator(graphDB.asInstanceOf[GraphDatabaseAPI]) - config.configuration().setProperty( - Configurator.WEBSERVER_PORT_PROPERTY_KEY, neo4jConsolePort - ) - - config.configuration().setProperty( - Configurator.HTTP_LOGGING, Configurator.DEFAULT_HTTP_LOGGING - ) - - val srv = new WrappingNeoServerBootstrapper(graphDB.asInstanceOf[GraphDatabaseAPI], config) - srv.start() - } - - // Simple cache of model nodes - //private var modelNodes: Map[String, Node] = Map() - //initCache() - - def setNeo4jPath(path: String) = { - neo4jPath = path - } - - def setNeo4jConsolePort(port: Int) = { - neo4jConsolePort = port +// TODO: add status to all the responses! + +class Neo4jWrapper extends DatabaseWrapper { + private val log = Logging + private val databasePath = "/data/graph.db" + private val neo4jPath = Config.neo4jPath + private val neo4jConsolePort = Config.neo4jConsolePort + private val graphDB = new GraphDatabaseFactory().newEmbeddedDatabase(neo4jPath + databasePath) + + private val globalOperations = GlobalGraphOperations.at(graphDB) + private val cypherEngine = new ExecutionEngine(graphDB) + private var cypherResult: ExecutionResult = null + + def init() { + val config = new ServerConfigurator(graphDB.asInstanceOf[GraphDatabaseAPI]) + config.configuration().setProperty( + Configurator.WEBSERVER_PORT_PROPERTY_KEY, neo4jConsolePort + ) + + config.configuration().setProperty( + Configurator.HTTP_LOGGING, Configurator.DEFAULT_HTTP_LOGGING + ) + + val srv = new WrappingNeoServerBootstrapper(graphDB.asInstanceOf[GraphDatabaseAPI], config) + srv.start() } - private def parseMap(node: Node): Map[String, Any] = { + protected def parseMap(node: Node): Map[String, Any] = { try { val keys = node.getPropertyKeys var map: Map[String, Any] = Map() @@ -66,13 +53,13 @@ object DatabaseManager { } catch { case e: Exception => { val line = e.getStackTrace()(2).getLineNumber - println(s"Parsing node to map failed at line $line. Error message: $e") + log.error(s"Parsing node to map failed at line $line. Error message: $e") } - null + null } } - private def parseMap(rel: Relationship): Map[String, Any] = { + protected def parseMap(rel: Relationship): Map[String, Any] = { try { val keys = rel.getPropertyKeys var map: Map[String, Any] = Map() @@ -85,13 +72,13 @@ object DatabaseManager { } catch { case e: Exception => { val line = e.getStackTrace()(2).getLineNumber - println(s"Parsing node to map failed at line $line. Error message: $e") + log.error(s"Parsing node to map failed at line $line. Error message: $e") } null } } - private def parseSet(node: Node): Set[(String, Any)] = { + protected def parseSet(node: Node): Set[(String, Any)] = { try { val keys = node.getPropertyKeys var set: Set[(String, Any)] = Set() @@ -104,13 +91,13 @@ object DatabaseManager { } catch { case e: Exception => { val line = e.getStackTrace()(2).getLineNumber - println(s"Parsing node to set failed at line $line. Error message: $e") + log.error(s"Parsing node to set failed at line $line. Error message: $e") } null } } - private def parseSet(rel: Relationship): Set[(String, Any)] = { + protected def parseSet(rel: Relationship): Set[(String, Any)] = { try { val keys = rel.getPropertyKeys var set: Set[(String, Any)] = Set() @@ -123,21 +110,33 @@ object DatabaseManager { } catch { case e: Exception => { val line = e.getStackTrace()(2).getLineNumber - println(s"Parsing node to set failed at line $line. Error message: $e") + log.error(s"Parsing node to set failed at line $line. Error message: $e") } null } } private def executeCypher(query: String, params: Map[String, Any] = Map()): List[List[Any]] = { + val tx = graphDB.beginTx() try { cypherResult = cypherEngine.execute(query, params) + tx.success() + var parsedResult: ListBuffer[List[Any]] = ListBuffer() for (row: Map[String, Any] <- cypherResult) { var rowItems: ListBuffer[Any] = ListBuffer() for (column <- row) { - // TODO: Do not assume that every value is Node - rowItems += parseMap(column._2.asInstanceOf[Node]) + column._2 match { + case node: Node => { + rowItems += parseMap(node) + } + case rel: Relationship => { + rowItems += parseMap(rel) + } + case sth: Any => { + rowItems += sth + } + } } parsedResult += rowItems.toList } @@ -146,33 +145,45 @@ object DatabaseManager { } catch { case e: Exception => { val line = e.getStackTrace()(2).getLineNumber - println(s"Executing Cypher script failed at line $line. Error message: $e") + log.error(s"Executing Cypher query failed at line $line. Error message: $e") } - null + tx.failure() + null + } finally { + tx.close() } } - /*private def initCache() = { + def executeQuery(args: List[Map[String, Any]]): List[Any] = { + var result: List[Any] = null + + val tx = graphDB.beginTx() try { - // Simply gets model nodes - val tx = graphDB.beginTx() - val rawResult = globalOperations.getAllNodesWithLabel(DynamicLabel.label("Model")) - tx.success() + val rawResult: ListBuffer[Any] = ListBuffer() - // Saves result - val it = rawResult.iterator() - while (it.hasNext) { - val node = it.next() - modelNodes += node.getProperty("model_name").asInstanceOf[String] -> node + for (item <- args) { + val query = item("query").asInstanceOf[String] + val params = item("parameters").asInstanceOf[Map[String, Any]] + + // Executes query + val returnedData = executeCypher(query, params) + rawResult += returnedData } - it.close() + tx.success() + result = rawResult.toList } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Initialising cache failed at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } + tx.failure() + result = List() + } finally { + tx.close() } - }*/ + + result + } def getByUuid(args: List[Map[String, Any]]): List[Any] = { var result: List[Any] = null @@ -200,8 +211,8 @@ object DatabaseManager { result = rawResult.toList } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() result = List() @@ -238,8 +249,8 @@ object DatabaseManager { result = rawResult.toList } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() result = List() @@ -276,8 +287,46 @@ object DatabaseManager { result = rawResult.toList } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") + } + tx.failure() + result = List() + } finally { + tx.close() + } + + result + } + + def getByUsername(args: List[Map[String, Any]]): List[Any] = { + var result: List[Any] = null + + val tx = graphDB.beginTx() + try { + val rawResult: ListBuffer[Any] = ListBuffer() + val label = DynamicLabel.label("NeoUser") + + // Gets nodes by uuid + for (item <- args) { + // Extracts result + val username = item("username").asInstanceOf[String] + val rawNode = graphDB.findNodesByLabelAndProperty(label, "username", username) + + val it = rawNode.iterator() + if (it.hasNext) { + rawResult += parseMap(it.next()) + } else { + rawResult += null + } + it.close() + } + tx.success() + result = rawResult.toList + } catch { + case e: Exception => { + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() result = List() @@ -315,8 +364,8 @@ object DatabaseManager { result = rawResult.toList } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() result = List() @@ -348,8 +397,8 @@ object DatabaseManager { result = List.fill[Any](args.length)(rawResult.toList) } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() result = List() @@ -391,6 +440,8 @@ object DatabaseManager { .toSet[(String, Any)] } + val limit = item("limit").asInstanceOf[Int] + val it = rawParentNode.iterator() if (it.hasNext) { val childrenOfOneNode: ListBuffer[Map[String, Any]] = ListBuffer() @@ -401,14 +452,15 @@ object DatabaseManager { val relList = parentNode.getRelationships(relType, Direction.OUTGOING).iterator() // Gets children and extracts partial result - while (relList.hasNext) { + var count = 0 + while (relList.hasNext && (limit == 0 || (limit > 0 && count < limit))) { val rel = relList.next() val node = parseSet(rel.getEndNode) // TODO: make it more efficient - val e = parseSet(rel) if (childrenProps.subsetOf(node) && relProps.subsetOf(parseSet(rel))) { childrenOfOneNode += node.toMap[String, Any] + count += 1 } } @@ -422,8 +474,8 @@ object DatabaseManager { result = rawResult.toList } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() result = List() @@ -465,6 +517,8 @@ object DatabaseManager { .toSet[(String, Any)] } + val limit = item("limit").asInstanceOf[Int] + val it = rawParentNode.iterator() if (it.hasNext) { val instancesOfOneNode: ListBuffer[Map[String, Any]] = ListBuffer() @@ -475,13 +529,15 @@ object DatabaseManager { val relList = parentNode.getRelationships(relType, Direction.OUTGOING).iterator() // Gets children and extracts partial result - while (relList.hasNext) { + var count = 0 + while (relList.hasNext && (limit == 0 || (limit > 0 && count < limit))) { val rel = relList.next() val node = parseSet(rel.getEndNode) // TODO: make it more efficient if (childrenProps.subsetOf(node) && relProps.subsetOf(parseSet(rel))) { instancesOfOneNode += node.toMap[String, Any] + count += 1 } } @@ -495,8 +551,8 @@ object DatabaseManager { result = rawResult.toList } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() result = List() @@ -523,6 +579,8 @@ object DatabaseManager { item("uuid").asInstanceOf[String] ) + val limit = item("limit").asInstanceOf[Int] + val it = rawParentNode.iterator() if (it.hasNext) { val feedsOfOneNode: ListBuffer[Map[String, Any]] = ListBuffer() @@ -533,10 +591,12 @@ object DatabaseManager { val relList = user.getRelationships(relType, Direction.OUTGOING).iterator() // Gets feeds and extracts partial result - while (relList.hasNext) { + var count = 0 + while (relList.hasNext && (limit == 0 || (limit > 0 && count < limit))) { val rel = relList.next() val node = parseSet(rel.getEndNode) feedsOfOneNode += node.toMap[String, Any] + count += 1 } rawResult += feedsOfOneNode.toList @@ -549,8 +609,8 @@ object DatabaseManager { result = rawResult.toList } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() result = List() @@ -567,28 +627,28 @@ object DatabaseManager { val nodeLabel = DynamicLabel.label("Node") for (item <- args) { - // Gets each node as an instance of Node - val rawNode = graphDB.findNodesByLabelAndProperty( - nodeLabel, - "uuid", - item("uuid").asInstanceOf[String] - ) + // Gets each node as an instance of Node + val rawNode = graphDB.findNodesByLabelAndProperty( + nodeLabel, + "uuid", + item("uuid").asInstanceOf[String] + ) - val it = rawNode.iterator() - if (it.hasNext) { - val node = it.next() + val it = rawNode.iterator() + if (it.hasNext) { + val node = it.next() - // Sets label to the node - val label = DynamicLabel.label(item("label").asInstanceOf[String]) - node.addLabel(label) - } - it.close() + // Sets label to the node + val label = DynamicLabel.label(item("label").asInstanceOf[String]) + node.addLabel(label) + } + it.close() } tx.success() } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() } finally { @@ -624,8 +684,8 @@ object DatabaseManager { tx.success() } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() } finally { @@ -666,8 +726,8 @@ object DatabaseManager { tx.success() } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() } finally { @@ -708,8 +768,110 @@ object DatabaseManager { tx.success() } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") + } + tx.failure() + } finally { + tx.close() + } + + null + } + + def setRelationshipProperties(args: List[Map[String, Any]]): List[Any] = { + val tx = graphDB.beginTx() + try { + val nodeLabel = DynamicLabel.label("Node") + + for (item <- args) { + // Gets each start node as an instance of Node + val rawStartNode = graphDB.findNodesByLabelAndProperty( + nodeLabel, + "uuid", + item("startNodeUuid").asInstanceOf[String] + ) + + val it = rawStartNode.iterator() + if (it.hasNext) { + val startNode = it.next() + val endNodeUuid = item("endNodeUuid").asInstanceOf[String] + val props = item("props").asInstanceOf[Map[String, Any]] + + if (props != null) { + // Looks through a list of relationships to delete a proper one + val relList = startNode.getRelationships(Direction.OUTGOING).iterator() + var break = false + while (!break && relList.hasNext) { + val rel = relList.next() + if (endNodeUuid == rel.getEndNode.getProperty("uuid").asInstanceOf[String]) { + // Sets properties to the relationship + for ((key, value) <- props) { + rel.setProperty(key, value) + } + break = true + } + } + } + } + it.close() + } + tx.success() + } catch { + case e: Exception => { + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") + } + tx.failure() + } finally { + tx.close() + } + + null + } + + def deleteRelationshipProperties(args: List[Map[String, Any]]): List[Any] = { + val tx = graphDB.beginTx() + try { + val nodeLabel = DynamicLabel.label("Node") + + for (item <- args) { + // Gets each start node as an instance of Node + val rawStartNode = graphDB.findNodesByLabelAndProperty( + nodeLabel, + "uuid", + item("startNodeUuid").asInstanceOf[String] + ) + + val it = rawStartNode.iterator() + if (it.hasNext) { + val startNode = it.next() + val endNodeUuid = item("endNodeUuid").asInstanceOf[String] + val propKeys = item("propKeys").asInstanceOf[List[String]] + + if (propKeys != null) { + // Looks through a list of relationships to delete a proper one + val relList = startNode.getRelationships(Direction.OUTGOING).iterator() + var break = false + while (!break && relList.hasNext) { + val rel = relList.next() + if (endNodeUuid == rel.getEndNode.getProperty("uuid").asInstanceOf[String]) { + // Delete relationship's properties + for (key <- propKeys) { + rel.removeProperty(key) + } + break = true + } + } + } + } + it.close() + } + tx.success() + } catch { + case e: Exception => { + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() } finally { @@ -735,6 +897,11 @@ object DatabaseManager { val it = rawRoot.iterator() if (it.hasNext) { root = it.next() + } else { + // TODO: for development purposes + val nodeLabel = DynamicLabel.label("Node") + root = graphDB.createNode(rootLabel, nodeLabel) + root.setProperty("uuid", "root") } it.close() @@ -762,17 +929,23 @@ object DatabaseManager { val rel = DynamicRelationshipType.withName("<>") root.createRelationshipTo(modelNode, rel) - rawResult += Map("uuid" -> modelProps("uuid")) + rawResult += Map( + "status" -> true, + "uuid" -> modelProps("uuid") + ) } tx.success() result = rawResult.toList } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() - result = List() + result = List.fill(args.length)(Map( + "status" -> false, + "uuid" -> null + )) } finally { tx.close() } @@ -793,7 +966,7 @@ object DatabaseManager { val modelLabel = DynamicLabel.label("Model") val rawModelResult = globalOperations.getAllNodesWithLabel(modelLabel) - // Saves result + // Saves model nodes val it = rawModelResult.iterator() while (it.hasNext) { val node = it.next() @@ -808,7 +981,10 @@ object DatabaseManager { if (props != null && !props.isEmpty) { props += "uuid" -> uuid - rawResult += Map("uuid" -> uuid) + rawResult += Map( + "status" -> true, + "uuid" -> uuid + ) val node = graphDB.createNode() for ((key, value) <- props) { @@ -822,18 +998,24 @@ object DatabaseManager { val relType = DynamicRelationshipType.withName(params("relType").asInstanceOf[String]) modelNodes(modelName).createRelationshipTo(node, relType) } else { - rawResult += Map("uuid" -> null) + rawResult += Map( + "status" -> false, + "uuid" -> null + ) } } tx.success() result = rawResult.toList } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() - result = List() + result = List.fill(args.length)(Map( + "status" -> false, + "uuid" -> null + )) } finally { tx.close() } @@ -842,37 +1024,88 @@ object DatabaseManager { } def deleteNodes(args: List[Map[String, Any]]): List[Any] = { - // Prepares params - var nodeUuidList: ListBuffer[String] = ListBuffer() - for (item <- args) { - nodeUuidList += item("uuid").asInstanceOf[String] - } + var result: List[Map[String, Any]] = null - val tx = graphDB.beginTx() + var tx = graphDB.beginTx() try { - // Builds query and executes - val query = - "MATCH (e:Node)-[r]-() " + - "WHERE e.uuid IN {uuid_list} " + - "DELETE e, r" - executeCypher(query, Map("uuid_list" -> nodeUuidList.toList)) + val rawNodeList: ListBuffer[Node] = ListBuffer() + val rawResult: ListBuffer[Map[String, Any]] = ListBuffer() + val nodeLabel = DynamicLabel.label("Node") + + for (item <- args) { + // Gets each node as an instance of Node + if (item("uuid") != null) { + val rawNode = graphDB.findNodesByLabelAndProperty( + nodeLabel, + "uuid", + item("uuid").asInstanceOf[String] + ) + + val it = rawNode.iterator() + if (it.hasNext) { + val node = it.next() + rawNodeList += node + } else { + rawNodeList += null + } + it.close() + } else { + rawNodeList += null + } + } + + for (node <- rawNodeList) { + if (node != null) { + // Looks through a list of relationships to be deleted + val outgoingRelList = node.getRelationships(Direction.OUTGOING).iterator() + while (outgoingRelList.hasNext) { + val rel = outgoingRelList.next() + rel.delete() + } + + val incomingRelList = node.getRelationships(Direction.INCOMING).iterator() + while (incomingRelList.hasNext) { + val rel = incomingRelList.next() + rel.delete() + } + } + } + tx.success() + tx.close() + + tx = graphDB.beginTx() + for (node <- rawNodeList) { + if (node != null) { + // Finally deletes the node + node.delete() + result = rawResult.toList + + rawResult += Map("status" -> true) + } else { + rawResult += Map("status" -> false) + } + } tx.success() } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() + result = List.fill(args.length)(Map("status" -> false)) } finally { tx.close() } - null + result } def createRelationships(args: List[Map[String, Any]]): List[Any] = { + var result: List[Map[String, Any]] = null + val tx = graphDB.beginTx() try { + val rawResult: ListBuffer[Map[String, Any]] = ListBuffer() val nodeLabel = DynamicLabel.label("Node") for (item <- args) { @@ -889,86 +1122,129 @@ object DatabaseManager { item("endNodeUuid").asInstanceOf[String] ) + val relType = item("type").asInstanceOf[String] + val it1 = rawStartNode.iterator() val it2 = rawEndNode.iterator() if (it1.hasNext && it2.hasNext) { val startNode = it1.next() val endNode = it2.next() - val relType = DynamicRelationshipType.withName(item("type").asInstanceOf[String]) + val dynamiceRelType = DynamicRelationshipType.withName(relType) // Creates a relationship of a given type - val rel = startNode.createRelationshipTo(endNode, relType) + val rel = startNode.createRelationshipTo(endNode, dynamiceRelType) // Sets properties to the relationship for ((key, value) <- item("props").asInstanceOf[Map[String, Any]]) { rel.setProperty(key, value) } + + rawResult += Map("status" -> true) + } else { + rawResult += Map("status" -> false) } it1.close() it2.close() } tx.success() + result = rawResult.toList } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() + result = List.fill(args.length)(Map("status" -> false)) } finally { tx.close() } - null + result } - def deleteRelationships(args: List[Map[String, Any]]): List[Any] = { + def createUniqueRelationships(args: List[Map[String, Any]]): List[Any] = { + var result: List[Map[String, Any]] = null + val tx = graphDB.beginTx() try { + val rawResult: ListBuffer[Map[String, Any]] = ListBuffer() val nodeLabel = DynamicLabel.label("Node") for (item <- args) { - // Gets each start node as an instance of Node + // Gets each pair of nodes as instances of Node val rawStartNode = graphDB.findNodesByLabelAndProperty( nodeLabel, "uuid", item("startNodeUuid").asInstanceOf[String] ) - val it = rawStartNode.iterator() - if (it.hasNext) { - val startNode = it.next() - val endNodeUuid = item("endNodeUuid").asInstanceOf[String] + val rawEndNode = graphDB.findNodesByLabelAndProperty( + nodeLabel, + "uuid", + item("endNodeUuid").asInstanceOf[String] + ) - // Looks through a list of relationships to delete a proper one - val relList = startNode.getRelationships(Direction.OUTGOING).iterator() - var break = false - while (!break && relList.hasNext) { - val rel = relList.next() - if (endNodeUuid == rel.getEndNode.getProperty("uuid").asInstanceOf[String]) { - rel.delete() - break = true + val relType = item("type").asInstanceOf[String] + + val it1 = rawStartNode.iterator() + val it2 = rawEndNode.iterator() + if (it1.hasNext && it2.hasNext) { + val startNode = it1.next() + val endNode = it2.next() + val dynamiceRelType = DynamicRelationshipType.withName(relType) + + // Checks if the relationship is unique + var isUnique = true + val checkedRels = startNode.getRelationships(Direction.OUTGOING) + val it3 = checkedRels.iterator() + while (it3.hasNext) { + val checkedRel = it3.next() + if (checkedRel.getEndNode.getId == endNode.getId && checkedRel.getType.name() == relType) { + isUnique = false } } + + if (isUnique) { + // Creates a relationship of a given type + val rel = startNode.createRelationshipTo(endNode, dynamiceRelType) + + // Sets properties to the relationship + for ((key, value) <- item("props").asInstanceOf[Map[String, Any]]) { + rel.setProperty(key, value) + } + + rawResult += Map("status" -> true) + } else { + rawResult += Map("status" -> false) + } + } else { + rawResult += Map("status" -> false) } - it.close() + it1.close() + it2.close() } tx.success() + result = rawResult.toList } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() + result = List.fill(args.length)(Map("status" -> false)) } finally { tx.close() } - null + result } - def setRelationshipProperties(args: List[Map[String, Any]]): List[Any] = { + def deleteRelationships(args: List[Map[String, Any]]): List[Any] = { + var result: List[Map[String, Any]] = null + val tx = graphDB.beginTx() try { + val rawResult: ListBuffer[Map[String, Any]] = ListBuffer() val nodeLabel = DynamicLabel.label("Node") for (item <- args) { @@ -983,43 +1259,46 @@ object DatabaseManager { if (it.hasNext) { val startNode = it.next() val endNodeUuid = item("endNodeUuid").asInstanceOf[String] - val props = item("props").asInstanceOf[Map[String, Any]] - if (props != null) { - // Looks through a list of relationships to delete a proper one - val relList = startNode.getRelationships(Direction.OUTGOING).iterator() - var break = false - while (!break && relList.hasNext) { - val rel = relList.next() - if (endNodeUuid == rel.getEndNode.getProperty("uuid").asInstanceOf[String]) { - // Sets properties to the relationship - for ((key, value) <- props) { - rel.setProperty(key, value) - } - break = true - } + // Looks through a list of relationships to delete a proper one + val relList = startNode.getRelationships(Direction.OUTGOING).iterator() + var isDeleted = false + while (!isDeleted && relList.hasNext) { + val rel = relList.next() + if (endNodeUuid == rel.getEndNode.getProperty("uuid").asInstanceOf[String]) { + rel.delete() + isDeleted = true } } + + rawResult += Map("status" -> isDeleted) + } else { + rawResult += Map("status" -> false) } it.close() } tx.success() + result = rawResult.toList } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() + result = List.fill(args.length)(Map("status" -> false)) } finally { tx.close() } - null + result } - def deleteRelationshipProperties(args: List[Map[String, Any]]): List[Any] = { + def popRelationships(args: List[Map[String, Any]]): List[Any] = { + var result: List[Map[String, Any]] = null + val tx = graphDB.beginTx() try { + val rawResult: ListBuffer[Map[String, Any]] = ListBuffer() val nodeLabel = DynamicLabel.label("Node") for (item <- args) { @@ -1033,38 +1312,49 @@ object DatabaseManager { val it = rawStartNode.iterator() if (it.hasNext) { val startNode = it.next() - val endNodeUuid = item("endNodeUuid").asInstanceOf[String] - val propKeys = item("propKeys").asInstanceOf[List[String]] + val relType = item("relType").asInstanceOf[String] - if (propKeys != null) { - // Looks through a list of relationships to delete a proper one - val relList = startNode.getRelationships(Direction.OUTGOING).iterator() - var break = false - while (!break && relList.hasNext) { - val rel = relList.next() - if (endNodeUuid == rel.getEndNode.getProperty("uuid").asInstanceOf[String]) { - // Delete relationship's properties - for (key <- propKeys) { - rel.removeProperty(key) - } - break = true - } + // Looks through a list of relationships to delete a proper one + val relList = startNode.getRelationships(Direction.OUTGOING).iterator() + var isDeleted = false + var endNode: Map[String, Any] = null + while (!isDeleted && relList.hasNext) { + val rel = relList.next() + if (relType == rel.getType.name()) { + endNode = parseMap(rel.getEndNode) + rel.delete() + isDeleted = true } } + + rawResult += Map( + "status" -> isDeleted, + "node" -> endNode + ) + } else { + rawResult += Map( + "status" -> false, + "node" -> null + ) } it.close() } tx.success() + result = rawResult.toList } catch { case e: Exception => { - val line = e.getStackTrace()(2).getLineNumber - println(s"Failed to execute the function at line $line. Error message: $e") + val methodName = Thread.currentThread().getStackTrace()(1).getMethodName + log.error(s"Failed to execute $methodName. Error message: $e") } tx.failure() + result = List.fill(args.length)(Map( + "status" -> false, + "node" -> null + )) } finally { tx.close() } - null + result } } diff --git a/lionfish/src/test/scala/com/lionfish/correctness/Set1.scala b/lionfish/src/test/scala/com/lionfish/correctness/Set1.scala index 0ff931a..6ca1dd1 100755 --- a/lionfish/src/test/scala/com/lionfish/correctness/Set1.scala +++ b/lionfish/src/test/scala/com/lionfish/correctness/Set1.scala @@ -4,22 +4,17 @@ import scala.collection.mutable.ListBuffer import org.scalatest.{FlatSpec, BeforeAndAfterAll} import com.lionfish.server.{Server, Launcher} import com.lionfish.client._ -import com.lionfish.utils.Config +import com.lionfish.utils.{Model, Config} class Set1 extends FlatSpec with BeforeAndAfterAll { private var seqStream: Stream = null private var batchStream: Stream = null override def beforeAll() { - val address = Config.debugServerAddress - val port = Config.debugServerPort Launcher.main(Array("--debug")) - Database.setServerAddress(address) - Database.setServerPort(port) - Server.debugLock.acquire() - seqStream = Database.getSequenceStream - batchStream = Database.getBatchStream + Database.setServerAddress(Config.serverAddress) + Database.setServerPort(Config.serverPort) Server.debugLock.release() } @@ -27,44 +22,57 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { // not using batch, non-empty output "getByUuid" should "return a map" in { - val modelName = "NeoUser" + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val relType = "<>" val props: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") - val uuid = (seqStream !! Database.createNode(modelName, relType, props)) - .asInstanceOf[Map[String, String]]("uuid") + val uuid = (seqStream !! Database.createNode(Model.NEO_USER, relType, props)) + .asInstanceOf[List[Map[String, String]]](0)("uuid") var validNode = props validNode += "uuid" -> uuid val testedNode = (seqStream !! Database.getByUuid(uuid)) - .asInstanceOf[Map[String, Any]] + .asInstanceOf[List[Map[String, Any]]](0) assert(testedNode != null) assert(testedNode.equals(validNode)) seqStream !! Database.deleteNode(uuid) + + seqStream.close() + batchStream.close() } // not using batch, empty output it should "return null" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val nonExistingUuid = "" val testedNode = (seqStream !! Database.getByUuid(nonExistingUuid)) - .asInstanceOf[Map[String, Any]] + .asInstanceOf[List[Map[String, Any]]](0) assert(testedNode == null) + + seqStream.close() + batchStream.close() } // using batch, non-empty output it should "return a list of not null maps" in { - val modelName = "NeoUser" + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) - seqStream << Database.createNode(modelName, relType, props0) - seqStream << Database.createNode(modelName, relType, props1) + seqStream << Database.createNode(Model.NEO_USER, relType, props0) + seqStream << Database.createNode(Model.NEO_USER, relType, props1) val uuidList = seqStream.execute() .asInstanceOf[List[Map[String, String]]] @@ -74,7 +82,8 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { batchStream << Database.getByUuid(uuidList(0)("uuid")) batchStream << Database.getByUuid(uuidList(1)("uuid")) - val testedNodeList = batchStream.execute().asInstanceOf[List[Map[String, Any]]] + val testedNodeList = batchStream.execute() + .asInstanceOf[List[Map[String, Any]]] assert(testedNodeList != null) assert(testedNodeList.length == 2) @@ -85,16 +94,22 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream !! Database.deleteNode(uuidList(0)("uuid")) seqStream !! Database.deleteNode(uuidList(1)("uuid")) + + seqStream.close() + batchStream.close() } // using batch, empty output it should "return a list of mixed not null and null maps" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "NeoUser" val relType = "<>" val props: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") val uuid = (seqStream !! Database.createNode(modelName, relType, props)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") val nonExistingUuid = "" var validNode = props @@ -111,6 +126,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { assert(testedNodeList(0).equals(validNode)) seqStream !! Database.deleteNode(uuid) + + seqStream.close() + batchStream.close() } @@ -119,44 +137,58 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { // not using batch, non-empty output "getByLink" should "return a map" in { - val modelName = "ContentSource" + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val relType = "<>" val props: Map[String, Any] = Map("key0" -> 1, "link" -> "http://example.com") - val uuid = (seqStream !! Database.createNode(modelName, relType, props)) - .asInstanceOf[Map[String, String]]("uuid") + val uuid = (seqStream !! Database.createNode(Model.CONTENT_SOURCE, relType, props)) + .asInstanceOf[List[Map[String, String]]](0)("uuid") val validNode = (seqStream !! Database.getByUuid(uuid)) - .asInstanceOf[Map[String, Any]] + .asInstanceOf[List[Map[String, Any]]](0) - val testedNode = (seqStream !! Database.getByLink(modelName, props("link").asInstanceOf[String])) - .asInstanceOf[Map[String, Any]] + val testedNode = (seqStream !! Database.getByLink(Model.CONTENT_SOURCE, props("link").asInstanceOf[String])) + .asInstanceOf[List[Map[String, Any]]](0) assert(testedNode != null) assert(testedNode.equals(validNode)) seqStream !! Database.deleteNode(uuid) + + seqStream.close() + batchStream.close() } // not using batch, empty output it should "return null" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val nonExistingLink = "*abc([)*" val testedNode = (seqStream !! Database.getByLink("Content", nonExistingLink)) - .asInstanceOf[Map[String, Any]] + .asInstanceOf[List[Map[String, Any]]](0) assert(testedNode == null) + + seqStream.close() + batchStream.close() } // using batch, non-empty output it should "return a list of not null maps" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "link" -> "http://example2.com") val props1: Map[String, Any] = Map("key0" -> "abc", "link" -> "http://example3.com") val uuid0 = (seqStream !! Database.createNode(modelName, relType, props0)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") val uuid1 = (seqStream !! Database.createNode(modelName, relType, props1)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") batchStream << Database.getByUuid(uuid0) batchStream << Database.getByUuid(uuid1) @@ -177,20 +209,26 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream !! Database.deleteNode(uuid0) seqStream !! Database.deleteNode(uuid1) + + seqStream.close() + batchStream.close() } // using batch, empty output it should "return a list of mixed not null and null maps" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" val relType = "<>" val props: Map[String, Any] = Map("key0" -> 1, "link" -> "http://example4.com") val uuid = (seqStream !! Database.createNode(modelName, relType, props)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") val nonExistingLink = "*abc([)*" val validNode = (seqStream !! Database.getByUuid(uuid)) - .asInstanceOf[Map[String, Any]] + .asInstanceOf[List[Map[String, Any]]](0) batchStream << Database.getByLink("Content", props("link").asInstanceOf[String]) batchStream << Database.getByLink("Content", nonExistingLink) @@ -202,6 +240,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { assert(testedNodeList(0).equals(validNode)) seqStream !! Database.deleteNode(uuid) + + seqStream.close() + batchStream.close() } @@ -210,8 +251,11 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { // not using batch, non-empty output "getModelNodes" should "return a list of maps" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val testedNodeList = (seqStream !! Database.getModelNodes()) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(testedNodeList != null) @@ -223,6 +267,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { .asInstanceOf[List[Map[String, Any]]] assert(testedNodeList.equals(validNodeList)) + + seqStream.close() + batchStream.close() } // not using batch, empty output @@ -232,6 +279,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { // using batch, non-empty output it should "return a list of not null lists of maps" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + batchStream << Database.getModelNodes() batchStream << Database.getModelNodes() @@ -251,6 +301,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { for (item <- testedNodeList) { assert(item.equals(validNodeList)) } + + seqStream.close() + batchStream.close() } // using batch, empty output @@ -264,6 +317,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { // not using batch, non-empty output, empty props "getChildren" should "return a list of maps" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "NeoUser" val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") @@ -272,7 +328,7 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { var modelUuid = "" val modelNodeList = (seqStream !! Database.getModelNodes()) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) for (item <- modelNodeList) { if (item("model_name").asInstanceOf[String] == modelName) { @@ -281,9 +337,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { } val uuid0 = (seqStream !! Database.createNode(modelName, relType, props0)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") val uuid1 = (seqStream !! Database.createNode(modelName, relType, props1)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") batchStream << Database.getByUuid(uuid0) batchStream << Database.getByUuid(uuid1) @@ -291,7 +347,7 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { .asInstanceOf[List[Map[String, Any]]] val testedNodeList = (seqStream !! Database.getChildren(modelUuid, relType)) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(testedNodeList != null) assert(testedNodeList.length == 2) @@ -310,23 +366,35 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream !! Database.deleteNode(uuid0) seqStream !! Database.deleteNode(uuid1) + + seqStream.close() + batchStream.close() } // not using batch, empty output, non-empty props it should "return an empty list" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val nonExistingUuid = "*abc([)*" val relType = "<>" val childrenProps: Map[String, Any] = Map("key0" -> 1) val testedNodeList = (seqStream !! Database.getChildren(nonExistingUuid, relType, childrenProps)) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(testedNodeList != null) assert(testedNodeList.length == 0) + + seqStream.close() + batchStream.close() } // using batch, non-empty output, non-empty props it should "return a list of lists of not null maps" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") @@ -337,7 +405,7 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { var modelUuid = "" val modelNodeList = (seqStream !! Database.getModelNodes()) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) for (item <- modelNodeList) { if (item("model_name").asInstanceOf[String] == modelName) { @@ -346,9 +414,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { } val uuid0 = (seqStream !! Database.createNode(modelName, relType, props0)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") val uuid1 = (seqStream !! Database.createNode(modelName, relType, props1)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") batchStream << Database.getByUuid(uuid0) batchStream << Database.getByUuid(uuid1) @@ -371,10 +439,16 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream !! Database.deleteNode(uuid0) seqStream !! Database.deleteNode(uuid1) + + seqStream.close() + batchStream.close() } // using batch, empty output, empty props it should "return a list of mixed non-empty and empty lists of maps" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") @@ -384,7 +458,7 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { val nonExistingUuid = "*abc([)*" val modelNodeList = (seqStream !! Database.getModelNodes()) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) for (item <- modelNodeList) { if (item("model_name").asInstanceOf[String] == modelName) { @@ -393,9 +467,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { } val uuid0 = (seqStream !! Database.createNode(modelName, relType, props0)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") val uuid1 = (seqStream !! Database.createNode(modelName, relType, props1)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") batchStream << Database.getByUuid(uuid0) batchStream << Database.getByUuid(uuid1) @@ -407,7 +481,6 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { val testedNodeList = batchStream.execute() .asInstanceOf[List[List[Map[String, Any]]]] - //println(s"$testedNodeList") assert(testedNodeList != null) assert(testedNodeList.length == 2) assert(testedNodeList(0) != null) @@ -429,6 +502,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream !! Database.deleteNode(uuid0) seqStream !! Database.deleteNode(uuid1) + + seqStream.close() + batchStream.close() } @@ -437,15 +513,18 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { // not using batch, non-empty output, empty props "getInstances" should "return a list of maps" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "NeoUser" val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) val uuid0 = (seqStream !! Database.createNode(modelName, relType, props0)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") val uuid1 = (seqStream !! Database.createNode(modelName, relType, props1)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") batchStream << Database.getByUuid(uuid0) batchStream << Database.getByUuid(uuid1) @@ -453,7 +532,7 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { .asInstanceOf[List[Map[String, Any]]] val testedNodeList = (seqStream !! Database.getInstances(modelName)) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(testedNodeList != null) assert(testedNodeList.length >= 2) @@ -473,22 +552,34 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { batchStream << Database.deleteNode(uuid0) batchStream << Database.deleteNode(uuid1) batchStream.execute() + + seqStream.close() + batchStream.close() } // not using batch, empty output, non-empty props it should "return an empty list" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val nonExistingModelName = "*abc([)*" val childrenProps: Map[String, Any] = Map("key0" -> 1) val testedNodeList = (seqStream !! Database.getInstances(nonExistingModelName, childrenProps)) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(testedNodeList != null) assert(testedNodeList.length == 0) + + seqStream.close() + batchStream.close() } // using batch, non-empty output, non-empty props it should "return a list of lists of not null maps" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") @@ -498,9 +589,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { val childrenProps1: Map[String, Any] = Map("key0" -> "abc") val uuid0 = (seqStream !! Database.createNode(modelName, relType, props0)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") val uuid1 = (seqStream !! Database.createNode(modelName, relType, props1)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") batchStream << Database.getByUuid(uuid0) batchStream << Database.getByUuid(uuid1) @@ -538,10 +629,16 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { batchStream << Database.deleteNode(uuid0) batchStream << Database.deleteNode(uuid1) batchStream.execute() + + seqStream.close() + batchStream.close() } // using batch, empty output, empty props it should "return a list of mixed non-empty and empty lists of maps" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") @@ -550,9 +647,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { val nonExistingModelName = "*abc([)*" val uuid0 = (seqStream !! Database.createNode(modelName, relType, props0)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") val uuid1 = (seqStream !! Database.createNode(modelName, relType, props1)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") batchStream << Database.getByUuid(uuid0) batchStream << Database.getByUuid(uuid1) @@ -585,6 +682,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream !! Database.deleteNode(uuid0) seqStream !! Database.deleteNode(uuid1) + + seqStream.close() + batchStream.close() } @@ -593,6 +693,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { // not using batch, correct input "setProperties" should "set properties to a node" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "ContentSource" val relType = "<>" val props: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) @@ -601,7 +704,7 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream << Database.createNode(modelName, relType, props) val uuid = seqStream.execute() - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") seqStream !! Database.setProperties(uuid, propsToSet) @@ -609,16 +712,22 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream << Database.getByUuid(uuid) val testedNode = seqStream.execute() - .asInstanceOf[Map[String, Any]] + .asInstanceOf[List[Map[String, Any]]](0) assert(testedNode != null) assert(testedNode.equals(validNode)) seqStream !! Database.deleteNode(uuid) + + seqStream.close() + batchStream.close() } // not using batch, incorrect input it should "not set properties to a node" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "ContentSource" val relType = "<>" val props: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) @@ -627,7 +736,7 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream << Database.createNode(modelName, relType, props) val uuid = seqStream.execute() - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") var validNode = props validNode += "uuid" -> uuid @@ -636,16 +745,22 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream << Database.getByUuid(uuid) val testedNode = seqStream.execute() - .asInstanceOf[Map[String, Any]] + .asInstanceOf[List[Map[String, Any]]](0) assert(testedNode != null) assert(testedNode.equals(validNode)) seqStream !! Database.deleteNode(uuid) + + seqStream.close() + batchStream.close() } // using batch, correct input it should "set properties to exactly two nodes" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") @@ -655,9 +770,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { val propsToSet1: Map[String, Any] = Map("key1" -> 0, "key2" -> "") val uuid0 = (seqStream !! Database.createNode(modelName, relType, props0)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") val uuid1 = (seqStream !! Database.createNode(modelName, relType, props1)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") val validNodeList = List( Map("uuid" -> uuid0, "key0" -> 1, "key1" -> 55, "key2" -> 12), @@ -680,10 +795,16 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream !! Database.deleteNode(uuid0) seqStream !! Database.deleteNode(uuid1) + + seqStream.close() + batchStream.close() } // using batch, incorrect input it should "set properties only to one node" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "NeoUser" val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") @@ -693,9 +814,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { val propsToSet1: Map[String, Any] = Map("key1" -> 0, "key2" -> "") val uuid0 = (seqStream !! Database.createNode(modelName, relType, props0)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") val uuid1 = (seqStream !! Database.createNode(modelName, relType, props1)) - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") val validNodeList = List( Map("uuid" -> uuid0, "key0" -> 1, "key1" -> "string"), @@ -718,6 +839,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream !! Database.deleteNode(uuid0) seqStream !! Database.deleteNode(uuid1) + + seqStream.close() + batchStream.close() } @@ -726,6 +850,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { // not using batch, correct input "deleteProperties" should "delete node's properties" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "ContentSource" val relType = "<>" val props: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) @@ -734,7 +861,7 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream << Database.createNode(modelName, relType, props) val uuid = seqStream.execute() - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") seqStream !! Database.deleteProperties(uuid, propsToDelete) @@ -742,16 +869,22 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream << Database.getByUuid(uuid) val testedNode = seqStream.execute() - .asInstanceOf[Map[String, Any]] + .asInstanceOf[List[Map[String, Any]]](0) assert(testedNode != null) assert(testedNode.equals(validNode)) seqStream !! Database.deleteNode(uuid) + + seqStream.close() + batchStream.close() } // not using batch, incorrect input it should "not delete node's properties" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "ContentSource" val relType = "<>" val props: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) @@ -760,7 +893,7 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream << Database.createNode(modelName, relType, props) val uuid = seqStream.execute() - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") var validNode = props validNode += "uuid" -> uuid @@ -769,16 +902,22 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream << Database.getByUuid(uuid) val testedNode = seqStream.execute() - .asInstanceOf[Map[String, Any]] + .asInstanceOf[List[Map[String, Any]]](0) assert(testedNode != null) assert(testedNode.equals(validNode)) seqStream !! Database.deleteNode(uuid) + + seqStream.close() + batchStream.close() } // using batch, correct input it should "delete properties of exactly two nodes" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") @@ -813,10 +952,16 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream !! Database.deleteNode(uuidList(0)("uuid")) seqStream !! Database.deleteNode(uuidList(1)("uuid")) + + seqStream.close() + batchStream.close() } // using batch, incorrect input it should "delete properties of only one node" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "NeoUser" val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") @@ -851,145 +996,578 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream !! Database.deleteNode(uuidList(0)("uuid")) seqStream !! Database.deleteNode(uuidList(1)("uuid")) + + seqStream.close() + batchStream.close() } - // =================== CREATE NODE =================== + // =================== SET RELATIONSHIP PROPERTIES =================== // not using batch, correct input - "createNode" should "create a node with properties" in { - val modelName = "Content" - val relType = "<>" - val props: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) - - seqStream << Database.createNode(modelName, relType, props) - val uuid = seqStream.execute() - .asInstanceOf[Map[String, String]]("uuid") - - var validNode = props - validNode += "uuid" -> uuid - - seqStream << Database.getByUuid(uuid) - val testedNode = seqStream.execute() - .asInstanceOf[Map[String, Any]] - - assert(testedNode != null) - assert(testedNode.equals(validNode)) - - seqStream !! Database.deleteNode(uuid) - } - - // not using batch, incorrect input - it should "not create any node" in { - val modelName = "Content" - val relType = "<>" - val props: Map[String, Any] = Map() - - seqStream << Database.createNode(modelName, relType, props) - val uuid = seqStream.execute() - .asInstanceOf[Map[String, String]]("uuid") - - assert(uuid == null) - } + "setRelationshipProperties" should "set properties to a relationship" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream - // using batch, correct input - it should "create exactly two nodes with properties" in { val modelName = "Content" - val relType = "<>" + val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) - var modelUuid = "" - - seqStream << Database.getModelNodes() - val modelNodeList = seqStream.execute() - .asInstanceOf[List[Map[String, Any]]] - - for (item <- modelNodeList) { - if (item("model_name").asInstanceOf[String] == modelName) { - modelUuid = item("uuid").asInstanceOf[String] - } - } + val propsToSet: Map[String, Any] = Map("relKey" -> 92) batchStream << Database.createNode(modelName, relType, props0) batchStream << Database.createNode(modelName, relType, props1) val uuidList = batchStream.execute() .asInstanceOf[List[Map[String, String]]] - assert(uuidList != null) - assert(uuidList.length == 2) + var validNode = props1 + validNode += "uuid" -> uuidList(1)("uuid") - val validNodeList = ListBuffer(props0, props1) - validNodeList(0) += "uuid" -> uuidList(0)("uuid") - validNodeList(1) += "uuid" -> uuidList(1)("uuid") + seqStream !! Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2") + seqStream !! Database.setRelationshipProperties(uuidList(0)("uuid"), uuidList(1)("uuid"), propsToSet) - seqStream << Database.getChildren(modelUuid, relType) + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2") + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), propsToSet) val testedNodeList = seqStream.execute() - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]] - assert(testedNodeList != null) - assert(testedNodeList.length == 2) + assert(testedNodeList(0) != null) + assert(testedNodeList(0).length == 1) + assert(testedNodeList(0)(0).equals(validNode)) - val foundList = ListBuffer(0, 0) - for (item <- testedNodeList) { - if (item.equals(validNodeList(0))) { - foundList(0) += 1 - } else if (item.equals(validNodeList(1))) { - foundList(1) += 1 - } - } + assert(testedNodeList(0).equals(testedNodeList(1))) - assert(foundList(0) == 1) - assert(foundList(1) == 1) + batchStream << Database.deleteNode(uuidList(0)("uuid")) + batchStream << Database.deleteNode(uuidList(1)("uuid")) + batchStream.execute() - seqStream !! Database.deleteNode(uuidList(0)("uuid")) - seqStream !! Database.deleteNode(uuidList(1)("uuid")) + seqStream.close() + batchStream.close() } - // using batch, incorrect input - it should "create only one node with properties" in { + // not using batch, incorrect input + it should "not set properties to a relationship" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "ContentSource" - val relType = "<>" + val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") - val props1: Map[String, Any] = null - - var modelUuid = "" - - seqStream << Database.getModelNodes() - val modelNodeList = seqStream.execute() - .asInstanceOf[List[Map[String, Any]]] + val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) - for (item <- modelNodeList) { - if (item("model_name").asInstanceOf[String] == modelName) { - modelUuid = item("uuid").asInstanceOf[String] - } - } + val nonExistingUuid = "*abc([)*" + val relProps: Map[String, Any] = Map("keyA" -> 5, "keyB" -> "aaa") + val propsToSet: Map[String, Any] = Map("relKey" -> 92) batchStream << Database.createNode(modelName, relType, props0) batchStream << Database.createNode(modelName, relType, props1) val uuidList = batchStream.execute() - .asInstanceOf[List[Map[String, Any]]] - - assert(uuidList != null) - assert(uuidList.length == 2) - assert(uuidList(0) != null) - assert(uuidList(1) != null) - assert(uuidList(0)("uuid") != null) - assert(uuidList(1)("uuid") == null) + .asInstanceOf[List[Map[String, String]]] - var validNode = props0 - validNode += "uuid" -> uuidList(0)("uuid") + seqStream !! Database.createRelationship(uuidList(0)("uuid"), nonExistingUuid, relType + "2", relProps) + seqStream !! Database.setRelationshipProperties(uuidList(0)("uuid"), nonExistingUuid, propsToSet) + seqStream !! Database.setRelationshipProperties(uuidList(0)("uuid"), uuidList(1)("uuid"), null) - seqStream << Database.getChildren(modelUuid, relType) + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", propsToSet) val testedNodeList = seqStream.execute() - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(testedNodeList != null) - assert(testedNodeList.length == 1) + assert(testedNodeList.length == 0) - var found = 0 - for (item <- testedNodeList) { + batchStream << Database.deleteNode(uuidList(0)("uuid")) + batchStream << Database.deleteNode(uuidList(1)("uuid")) + batchStream.execute() + + seqStream.close() + batchStream.close() + } + + // using batch, correct input + it should "set properties to exactly two relationships" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + + val modelName = "Content" + val relType = "<>" + val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") + val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) + val props2: Map[String, Any] = Map("key0" -> "aaa", "key1" -> 15) + + val relPropsToSet0: Map[String, Any] = Map("relKey" -> 92) + val relPropsToSet1: Map[String, Any] = Map("relKey" -> 78) + + batchStream << Database.createNode(modelName, relType, props0) + batchStream << Database.createNode(modelName, relType, props1) + batchStream << Database.createNode(modelName, relType, props2) + val uuidList = batchStream.execute() + .asInstanceOf[List[Map[String, String]]] + + val validNodeList = ListBuffer(props1, props2) + validNodeList(0) += "uuid" -> uuidList(1)("uuid") + validNodeList(1) += "uuid" -> uuidList(2)("uuid") + + batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2") + batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(2)("uuid"), relType + "2") + batchStream.execute() + + batchStream << Database.setRelationshipProperties(uuidList(0)("uuid"), uuidList(1)("uuid"), relPropsToSet0) + batchStream << Database.setRelationshipProperties(uuidList(0)("uuid"), uuidList(2)("uuid"), relPropsToSet1) + batchStream.execute() + + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), relPropsToSet0) + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), relPropsToSet1) + val testedNodeList = seqStream.execute() + .asInstanceOf[List[List[Map[String, Any]]]] + + assert(testedNodeList(0) != null) + assert(testedNodeList(0).length == 1) + assert(testedNodeList(0)(0).equals(validNodeList(0))) + + assert(testedNodeList(1) != null) + assert(testedNodeList(1).length == 1) + assert(testedNodeList(1)(0).equals(validNodeList(1))) + + batchStream << Database.deleteNode(uuidList(0)("uuid")) + batchStream << Database.deleteNode(uuidList(1)("uuid")) + batchStream << Database.deleteNode(uuidList(2)("uuid")) + batchStream.execute() + + seqStream.close() + batchStream.close() + } + + // using batch, incorrect input + it should "set properties only to one relationship" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + + val modelName = "NeoUser" + val relType = "<>" + val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") + val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) + val props2: Map[String, Any] = Map("key0" -> "aaa", "key1" -> 15) + + val relPropsToSet0: Map[String, Any] = Map("relKey" -> 92) + val relPropsToSet1: Map[String, Any] = null + + batchStream << Database.createNode(modelName, relType, props0) + batchStream << Database.createNode(modelName, relType, props1) + batchStream << Database.createNode(modelName, relType, props2) + val uuidList = batchStream.execute() + .asInstanceOf[List[Map[String, String]]] + + val validNodeList = ListBuffer(props1, props2) + validNodeList(0) += "uuid" -> uuidList(1)("uuid") + validNodeList(1) += "uuid" -> uuidList(2)("uuid") + + batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2") + batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(2)("uuid"), relType + "2") + batchStream.execute() + + batchStream << Database.setRelationshipProperties(uuidList(0)("uuid"), uuidList(1)("uuid"), relPropsToSet0) + batchStream << Database.setRelationshipProperties(uuidList(0)("uuid"), uuidList(2)("uuid"), relPropsToSet1) + batchStream.execute() + + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), relPropsToSet0) + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), relPropsToSet1) + val testedNodeList = seqStream.execute() + .asInstanceOf[List[List[Map[String, Any]]]] + + assert(testedNodeList(0) != null) + assert(testedNodeList(0).length == 1) + assert(testedNodeList(0)(0).equals(validNodeList(0))) + + assert(testedNodeList(1) != null) + assert(testedNodeList(1).length == 2) + + batchStream << Database.deleteNode(uuidList(0)("uuid")) + batchStream << Database.deleteNode(uuidList(1)("uuid")) + batchStream << Database.deleteNode(uuidList(2)("uuid")) + batchStream.execute() + + seqStream.close() + batchStream.close() + } + + + + // =================== DELETE RELATIONSHIP PROPERTIES =================== + + // not using batch, correct input + "deleteRelationshipProperties" should "delete relationship's properties" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + + val modelName = "Content" + val relType = "<>" + val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") + val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) + + val relProps: Map[String, Any] = Map("keyA" -> 5, "keyB" -> "aaa") + val propsToDelete: List[String] = List("keyB") + + batchStream << Database.createNode(modelName, relType, props0) + batchStream << Database.createNode(modelName, relType, props1) + val uuidList = batchStream.execute() + .asInstanceOf[List[Map[String, String]]] + + var validNode = props1 + validNode += "uuid" -> uuidList(1)("uuid") + + seqStream !! Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2", relProps) + seqStream !! Database.deleteRelationshipProperties(uuidList(0)("uuid"), uuidList(1)("uuid"), propsToDelete) + + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2") + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), relProps) + val testedNodeList = seqStream.execute() + .asInstanceOf[List[List[Map[String, Any]]]] + + assert(testedNodeList(0) != null) + assert(testedNodeList(0).length == 1) + assert(testedNodeList(0)(0).equals(validNode)) + + assert(testedNodeList(1) != null) + assert(testedNodeList(1).length == 0) + + batchStream << Database.deleteNode(uuidList(0)("uuid")) + batchStream << Database.deleteNode(uuidList(1)("uuid")) + batchStream.execute() + + seqStream.close() + batchStream.close() + } + + // not using batch, incorrect input + it should "not delete relationship's properties" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + + val modelName = "ContentSource" + val relType = "<>" + val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") + val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) + + val nonExistingUuid = "*abc([)*" + val relProps: Map[String, Any] = Map("keyA" -> 5, "keyB" -> "aaa") + val propsToDelete: List[String] = List("keyB") + + batchStream << Database.createNode(modelName, relType, props0) + batchStream << Database.createNode(modelName, relType, props1) + val uuidList = batchStream.execute() + .asInstanceOf[List[Map[String, String]]] + + seqStream !! Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2", relProps) + + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), relProps) + val testedNodeList = seqStream.execute() + .asInstanceOf[List[Map[String, Any]]] + + seqStream !! Database.deleteRelationshipProperties(uuidList(0)("uuid"), nonExistingUuid, propsToDelete) + seqStream !! Database.deleteRelationshipProperties(uuidList(0)("uuid"), uuidList(1)("uuid"), null) + + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), relProps) + val testedNodeList2 = seqStream.execute() + .asInstanceOf[List[Map[String, Any]]] + + assert(testedNodeList != null) + assert(testedNodeList.length == 1) + + assert(testedNodeList2 != null) + assert(testedNodeList2.length == 1) + assert(testedNodeList.equals(testedNodeList2)) + + batchStream << Database.deleteNode(uuidList(0)("uuid")) + batchStream << Database.deleteNode(uuidList(1)("uuid")) + batchStream.execute() + + seqStream.close() + batchStream.close() + } + + // using batch, correct input + it should "delete properties of exactly two relationships" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + + val modelName = "Content" + val relType = "<>" + val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") + val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) + val props2: Map[String, Any] = Map("key0" -> "aaa", "key1" -> 15) + + val relProps0: Map[String, Any] = Map("keyA" -> 5, "keyB" -> "aaa") + val relProps1: Map[String, Any] = Map("keyA" -> 5, "keyB" -> "bca") + + val relPropsToDelete0: List[String] = List("keyA") + val relPropsToDelete1: List[String] = List("keyB") + + batchStream << Database.createNode(modelName, relType, props0) + batchStream << Database.createNode(modelName, relType, props1) + batchStream << Database.createNode(modelName, relType, props2) + val uuidList = batchStream.execute() + .asInstanceOf[List[Map[String, String]]] + + val validNodeList = ListBuffer(props1, props2) + validNodeList(0) += "uuid" -> uuidList(1)("uuid") + validNodeList(1) += "uuid" -> uuidList(2)("uuid") + + val validProps0: Map[String, Any] = Map("keyB" -> "aaa") + val validProps1: Map[String, Any] = Map("keyA" -> 5) + + batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2", relProps0) + batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(2)("uuid"), relType + "2", relProps1) + batchStream.execute() + + batchStream << Database.deleteRelationshipProperties(uuidList(0)("uuid"), uuidList(1)("uuid"), relPropsToDelete0) + batchStream << Database.deleteRelationshipProperties(uuidList(0)("uuid"), uuidList(2)("uuid"), relPropsToDelete1) + batchStream.execute() + + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), validProps0) + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), validProps1) + val testedNodeList = seqStream.execute() + .asInstanceOf[List[List[Map[String, Any]]]] + + assert(testedNodeList(0) != null) + assert(testedNodeList(0).length == 1) + assert(testedNodeList(0)(0).equals(validNodeList(0))) + + assert(testedNodeList(1) != null) + assert(testedNodeList(1).length == 1) + assert(testedNodeList(1)(0).equals(validNodeList(1))) + + batchStream << Database.deleteNode(uuidList(0)("uuid")) + batchStream << Database.deleteNode(uuidList(1)("uuid")) + batchStream << Database.deleteNode(uuidList(2)("uuid")) + batchStream.execute() + + seqStream.close() + batchStream.close() + } + + // using batch, incorrect input + it should "delete properties of only one relationship" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + + val modelName = "NeoUser" + val relType = "<>" + val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") + val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) + val props2: Map[String, Any] = Map("key0" -> "aaa", "key1" -> 15) + + val relProps0: Map[String, Any] = Map("keyA" -> 5, "keyB" -> "aaa") + val relProps1: Map[String, Any] = Map("keyA" -> 5, "keyB" -> "bca") + + val relPropsToDelete0: List[String] = null + val relPropsToDelete1: List[String] = List("keyB") + + batchStream << Database.createNode(modelName, relType, props0) + batchStream << Database.createNode(modelName, relType, props1) + batchStream << Database.createNode(modelName, relType, props2) + val uuidList = batchStream.execute() + .asInstanceOf[List[Map[String, String]]] + + val validNodeList = ListBuffer(props1, props2) + validNodeList(0) += "uuid" -> uuidList(1)("uuid") + validNodeList(1) += "uuid" -> uuidList(2)("uuid") + + val validProps1: Map[String, Any] = Map("keyA" -> 5) + + batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2", relProps0) + batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(2)("uuid"), relType + "2", relProps1) + batchStream.execute() + + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map()) + val testedNodeList = seqStream.execute() + .asInstanceOf[List[List[Map[String, Any]]]](0) + + batchStream << Database.deleteRelationshipProperties(uuidList(0)("uuid"), uuidList(1)("uuid"), relPropsToDelete0) + batchStream << Database.deleteRelationshipProperties(uuidList(0)("uuid"), uuidList(2)("uuid"), relPropsToDelete1) + batchStream.execute() + + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), relProps0) + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), validProps1) + val testedNodeList2 = seqStream.execute() + .asInstanceOf[List[List[Map[String, Any]]]] + + assert(testedNodeList2(0) != null) + assert(testedNodeList2(0).length == 1) + assert(testedNodeList2(0)(0).equals(validNodeList(0))) + + assert(testedNodeList2(1) != null) + assert(testedNodeList2(1).length == 2) + assert(testedNodeList.equals(testedNodeList2(1))) + + batchStream << Database.deleteNode(uuidList(0)("uuid")) + batchStream << Database.deleteNode(uuidList(1)("uuid")) + batchStream << Database.deleteNode(uuidList(2)("uuid")) + batchStream.execute() + + seqStream.close() + batchStream.close() + } + + + + // =================== CREATE NODE =================== + + // not using batch, correct input + "createNode" should "create a node with properties" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + + val modelName = "Content" + val relType = "<>" + val props: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) + + seqStream << Database.createNode(modelName, relType, props) + val uuid = seqStream.execute() + .asInstanceOf[List[Map[String, String]]](0)("uuid") + + var validNode = props + validNode += "uuid" -> uuid + + seqStream << Database.getByUuid(uuid) + val testedNode = seqStream.execute() + .asInstanceOf[List[Map[String, Any]]](0) + + assert(testedNode != null) + assert(testedNode.equals(validNode)) + + seqStream !! Database.deleteNode(uuid) + + seqStream.close() + batchStream.close() + } + + // not using batch, incorrect input + it should "not create any node" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + + val modelName = "Content" + val relType = "<>" + val props: Map[String, Any] = Map() + + seqStream << Database.createNode(modelName, relType, props) + val uuid = seqStream.execute() + .asInstanceOf[List[Map[String, String]]](0)("uuid") + + assert(uuid == null) + + seqStream.close() + batchStream.close() + } + + // using batch, correct input + it should "create exactly two nodes with properties" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + + val modelName = "Content" + val relType = "<>" + val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") + val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) + + var modelUuid = "" + + seqStream << Database.getModelNodes() + val modelNodeList = seqStream.execute() + .asInstanceOf[List[List[Map[String, Any]]]](0) + + for (item <- modelNodeList) { + if (item("model_name").asInstanceOf[String] == modelName) { + modelUuid = item("uuid").asInstanceOf[String] + } + } + + batchStream << Database.createNode(modelName, relType, props0) + batchStream << Database.createNode(modelName, relType, props1) + val uuidList = batchStream.execute() + .asInstanceOf[List[Map[String, String]]] + + assert(uuidList != null) + assert(uuidList.length == 2) + + val validNodeList = ListBuffer(props0, props1) + validNodeList(0) += "uuid" -> uuidList(0)("uuid") + validNodeList(1) += "uuid" -> uuidList(1)("uuid") + + seqStream << Database.getChildren(modelUuid, relType) + val testedNodeList = seqStream.execute() + .asInstanceOf[List[List[Map[String, Any]]]](0) + + assert(testedNodeList != null) + assert(testedNodeList.length == 2) + + val foundList = ListBuffer(0, 0) + for (item <- testedNodeList) { + if (item.equals(validNodeList(0))) { + foundList(0) += 1 + } else if (item.equals(validNodeList(1))) { + foundList(1) += 1 + } + } + + assert(foundList(0) == 1) + assert(foundList(1) == 1) + + seqStream !! Database.deleteNode(uuidList(0)("uuid")) + seqStream !! Database.deleteNode(uuidList(1)("uuid")) + + seqStream.close() + batchStream.close() + } + + // using batch, incorrect input + it should "create only one node with properties" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + + val modelName = "ContentSource" + val relType = "<>" + val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") + val props1: Map[String, Any] = null + + var modelUuid = "" + + seqStream << Database.getModelNodes() + val modelNodeList = seqStream.execute() + .asInstanceOf[List[List[Map[String, Any]]]](0) + + for (item <- modelNodeList) { + if (item("model_name").asInstanceOf[String] == modelName) { + modelUuid = item("uuid").asInstanceOf[String] + } + } + + batchStream << Database.createNode(modelName, relType, props0) + batchStream << Database.createNode(modelName, relType, props1) + val uuidList = batchStream.execute() + .asInstanceOf[List[Map[String, Any]]] + + assert(uuidList != null) + assert(uuidList.length == 2) + assert(uuidList(0) != null) + assert(uuidList(1) != null) + assert(uuidList(0)("uuid") != null) + assert(uuidList(1)("uuid") == null) + + var validNode = props0 + validNode += "uuid" -> uuidList(0)("uuid") + + seqStream << Database.getChildren(modelUuid, relType) + val testedNodeList = seqStream.execute() + .asInstanceOf[List[List[Map[String, Any]]]](0) + + assert(testedNodeList != null) + assert(testedNodeList.length == 1) + + var found = 0 + for (item <- testedNodeList) { if (item.equals(validNode)) { found += 1 } @@ -999,6 +1577,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream !! Database.deleteNode(uuidList(0)("uuid").asInstanceOf[String]) seqStream !! Database.deleteNode(uuidList(1)("uuid").asInstanceOf[String]) + + seqStream.close() + batchStream.close() } @@ -1007,21 +1588,27 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { // not using batch, correct input "deleteNode" should "delete a node" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" val relType = "<>" val props: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) seqStream << Database.createNode(modelName, relType, props) val uuid = seqStream.execute() - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") seqStream !! Database.deleteNode(uuid) seqStream << Database.getByUuid(uuid) val testedNode = seqStream.execute() - .asInstanceOf[Map[String, Any]] + .asInstanceOf[List[Map[String, Any]]](0) assert(testedNode == null) + + seqStream.close() + batchStream.close() } // not using batch, incorrect input @@ -1031,6 +1618,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { // using batch, correct input it should "delete exactly two nodes" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") @@ -1040,7 +1630,7 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream << Database.getModelNodes() val modelNodeList = seqStream.execute() - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) for (item <- modelNodeList) { if (item("model_name").asInstanceOf[String] == modelName) { @@ -1063,10 +1653,13 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream << Database.getChildren(modelUuid, relType) val testedNodeList = seqStream.execute() - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(testedNodeList != null) assert(testedNodeList.length == 0) + + seqStream.close() + batchStream.close() } // using batch, incorrect input @@ -1080,6 +1673,9 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { // not using batch, correct input, empty props "createRelationship" should "create a relationship without properties" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") @@ -1097,7 +1693,7 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2") val testedNodeList = seqStream.execute() - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(testedNodeList != null) assert(testedNodeList.length == 1) @@ -1106,10 +1702,16 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { batchStream << Database.deleteNode(uuidList(0)("uuid")) batchStream << Database.deleteNode(uuidList(1)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } // not using batch, incorrect input, non-empty props it should "not create any relationship" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" val relType = "<>" val props: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") @@ -1119,22 +1721,28 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream << Database.createNode(modelName, relType, props) val uuid = seqStream.execute() - .asInstanceOf[Map[String, String]]("uuid") + .asInstanceOf[List[Map[String, String]]](0)("uuid") seqStream !! Database.createRelationship(uuid, nonExistingUuid, relType + "2", relProps) seqStream << Database.getChildren(uuid, relType + "2") val testedNodeList = seqStream.execute() - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(testedNodeList != null) assert(testedNodeList.length == 0) seqStream !! Database.deleteNode(uuid) + + seqStream.close() + batchStream.close() } // using batch, correct input, non-empty props it should "create exactly two relationships with properties" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") @@ -1160,7 +1768,7 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2") val testedNodeList = seqStream.execute() - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(testedNodeList != null) assert(testedNodeList.length == 2) @@ -1181,80 +1789,18 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { batchStream << Database.deleteNode(uuidList(1)("uuid")) batchStream << Database.deleteNode(uuidList(2)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } // using batch, incorrect input, empty props it should "create only one relationship without properties" in { - val modelName = "Content" - val relType = "<>" - val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") - val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) - - val nonExistingUuid = "*abc([)*" - - batchStream << Database.createNode(modelName, relType, props0) - batchStream << Database.createNode(modelName, relType, props1) - val uuidList = batchStream.execute() - .asInstanceOf[List[Map[String, String]]] - - var validNode = props1 - validNode += "uuid" -> uuidList(1)("uuid") - - batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2") - batchStream << Database.createRelationship(uuidList(0)("uuid"), nonExistingUuid, relType + "2") - batchStream.execute() - - seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2") - val testedNodeList = seqStream.execute() - .asInstanceOf[List[Map[String, Any]]] - - assert(testedNodeList != null) - assert(testedNodeList.length == 1) - assert(testedNodeList(0).equals(validNode)) - - batchStream << Database.deleteNode(uuidList(0)("uuid")) - batchStream << Database.deleteNode(uuidList(1)("uuid")) - batchStream.execute() - } - - - - // =================== DELETE RELATIONSHIP =================== - - // not using batch, correct input - "deleteRelationship" should "delete a relationship" in { - val modelName = "Content" - val relType = "<>" - val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") - val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) - - batchStream << Database.createNode(modelName, relType, props0) - batchStream << Database.createNode(modelName, relType, props1) - val uuidList = batchStream.execute() - .asInstanceOf[List[Map[String, String]]] - - var validNode = props1 - validNode += "uuid" -> uuidList(1)("uuid") - - seqStream !! Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2") - seqStream !! Database.deleteRelationship(uuidList(0)("uuid"), uuidList(1)("uuid")) - - seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2") - val testedNodeList = seqStream.execute() - .asInstanceOf[List[Map[String, Any]]] - - assert(testedNodeList != null) - assert(testedNodeList.length == 0) - - batchStream << Database.deleteNode(uuidList(0)("uuid")) - batchStream << Database.deleteNode(uuidList(1)("uuid")) - batchStream.execute() - } + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream - // not using batch, incorrect input - it should "not delete any relationship" in { val modelName = "Content" - val relType = "<>" + val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) @@ -1268,116 +1814,40 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { var validNode = props1 validNode += "uuid" -> uuidList(1)("uuid") - seqStream !! Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2") - seqStream !! Database.deleteRelationship(uuidList(0)("uuid"), nonExistingUuid) - - seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2") - val testedNodeList = seqStream.execute() - .asInstanceOf[List[Map[String, Any]]] - - assert(testedNodeList != null) - assert(testedNodeList.length == 1) - assert(testedNodeList(0).equals(validNode)) - - batchStream << Database.deleteNode(uuidList(0)("uuid")) - batchStream << Database.deleteNode(uuidList(1)("uuid")) - batchStream.execute() - } - - // using batch, correct input - it should "delete exactly two relationships" in { - val modelName = "Content" - val relType = "<>" - val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") - val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) - val props2: Map[String, Any] = Map("key0" -> "aaa", "key1" -> 15) - - batchStream << Database.createNode(modelName, relType, props0) - batchStream << Database.createNode(modelName, relType, props1) - batchStream << Database.createNode(modelName, relType, props2) - val uuidList = batchStream.execute() - .asInstanceOf[List[Map[String, String]]] - - val validNodeList = ListBuffer(props1, props2) - validNodeList(0) += "uuid" -> uuidList(1)("uuid") - validNodeList(1) += "uuid" -> uuidList(2)("uuid") - - batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2") - batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(2)("uuid"), relType + "2") - batchStream.execute() - - batchStream << Database.deleteRelationship(uuidList(0)("uuid"), uuidList(1)("uuid")) - batchStream << Database.deleteRelationship(uuidList(0)("uuid"), uuidList(2)("uuid")) - batchStream.execute() - - seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2") - val testedNodeList = seqStream.execute() - .asInstanceOf[List[Map[String, Any]]] - - assert(testedNodeList != null) - assert(testedNodeList.length == 0) - - batchStream << Database.deleteNode(uuidList(0)("uuid")) - batchStream << Database.deleteNode(uuidList(1)("uuid")) - batchStream << Database.deleteNode(uuidList(2)("uuid")) - batchStream.execute() - } - - // using batch, incorrect input - it should "delete only one relationship" in { - val modelName = "Content" - val relType = "<>" - val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") - val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) - val props2: Map[String, Any] = Map("key0" -> "aaa", "key1" -> 15) - - val nonExistingUuid = "*abc([)*" - - batchStream << Database.createNode(modelName, relType, props0) - batchStream << Database.createNode(modelName, relType, props1) - batchStream << Database.createNode(modelName, relType, props2) - val uuidList = batchStream.execute() - .asInstanceOf[List[Map[String, String]]] - - val validNodeList = ListBuffer(props1, props2) - validNodeList(0) += "uuid" -> uuidList(1)("uuid") - validNodeList(1) += "uuid" -> uuidList(2)("uuid") - batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2") - batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(2)("uuid"), relType + "2") - batchStream.execute() - - batchStream << Database.deleteRelationship(uuidList(0)("uuid"), uuidList(1)("uuid")) - batchStream << Database.deleteRelationship(uuidList(0)("uuid"), nonExistingUuid) + batchStream << Database.createRelationship(uuidList(0)("uuid"), nonExistingUuid, relType + "2") batchStream.execute() seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2") val testedNodeList = seqStream.execute() - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(testedNodeList != null) assert(testedNodeList.length == 1) - assert(testedNodeList(0).equals(validNodeList(1))) + assert(testedNodeList(0).equals(validNode)) batchStream << Database.deleteNode(uuidList(0)("uuid")) batchStream << Database.deleteNode(uuidList(1)("uuid")) - batchStream << Database.deleteNode(uuidList(2)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } - // =================== SET RELATIONSHIP PROPERTIES =================== + // =================== DELETE RELATIONSHIP =================== // not using batch, correct input - "setRelationshipProperties" should "set properties to a relationship" in { + "deleteRelationship" should "delete the relationship" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" - val relType = "<>" + val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) - val propsToSet: Map[String, Any] = Map("relKey" -> 92) - batchStream << Database.createNode(modelName, relType, props0) batchStream << Database.createNode(modelName, relType, props1) val uuidList = batchStream.execute() @@ -1387,67 +1857,73 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { validNode += "uuid" -> uuidList(1)("uuid") seqStream !! Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2") - seqStream !! Database.setRelationshipProperties(uuidList(0)("uuid"), uuidList(1)("uuid"), propsToSet) + seqStream !! Database.deleteRelationship(uuidList(0)("uuid"), uuidList(1)("uuid")) seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2") - seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), propsToSet) val testedNodeList = seqStream.execute() - .asInstanceOf[List[List[Map[String, Any]]]] - - assert(testedNodeList(0) != null) - assert(testedNodeList(0).length == 1) - assert(testedNodeList(0)(0).equals(validNode)) + .asInstanceOf[List[List[Map[String, Any]]]](0) - assert(testedNodeList(0).equals(testedNodeList(1))) + assert(testedNodeList != null) + assert(testedNodeList.length == 0) batchStream << Database.deleteNode(uuidList(0)("uuid")) batchStream << Database.deleteNode(uuidList(1)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } // not using batch, incorrect input - it should "not set properties to a relationship" in { - val modelName = "ContentSource" - val relType = "<>" + it should "not delete any relationship" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + + val modelName = "Content" + val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) val nonExistingUuid = "*abc([)*" - val relProps: Map[String, Any] = Map("keyA" -> 5, "keyB" -> "aaa") - val propsToSet: Map[String, Any] = Map("relKey" -> 92) batchStream << Database.createNode(modelName, relType, props0) batchStream << Database.createNode(modelName, relType, props1) val uuidList = batchStream.execute() .asInstanceOf[List[Map[String, String]]] - seqStream !! Database.createRelationship(uuidList(0)("uuid"), nonExistingUuid, relType + "2", relProps) - seqStream !! Database.setRelationshipProperties(uuidList(0)("uuid"), nonExistingUuid, propsToSet) - seqStream !! Database.setRelationshipProperties(uuidList(0)("uuid"), uuidList(1)("uuid"), null) + var validNode = props1 + validNode += "uuid" -> uuidList(1)("uuid") - seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", propsToSet) + seqStream !! Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2") + seqStream !! Database.deleteRelationship(uuidList(0)("uuid"), nonExistingUuid) + + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2") val testedNodeList = seqStream.execute() - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(testedNodeList != null) - assert(testedNodeList.length == 0) + assert(testedNodeList.length == 1) + assert(testedNodeList(0).equals(validNode)) batchStream << Database.deleteNode(uuidList(0)("uuid")) batchStream << Database.deleteNode(uuidList(1)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } // using batch, correct input - it should "set properties to exactly two relationships" in { + it should "delete exactly two relationships" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" - val relType = "<>" + val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) val props2: Map[String, Any] = Map("key0" -> "aaa", "key1" -> 15) - val relPropsToSet0: Map[String, Any] = Map("relKey" -> 92) - val relPropsToSet1: Map[String, Any] = Map("relKey" -> 78) - batchStream << Database.createNode(modelName, relType, props0) batchStream << Database.createNode(modelName, relType, props1) batchStream << Database.createNode(modelName, relType, props2) @@ -1462,39 +1938,38 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(2)("uuid"), relType + "2") batchStream.execute() - batchStream << Database.setRelationshipProperties(uuidList(0)("uuid"), uuidList(1)("uuid"), relPropsToSet0) - batchStream << Database.setRelationshipProperties(uuidList(0)("uuid"), uuidList(2)("uuid"), relPropsToSet1) + batchStream << Database.deleteRelationship(uuidList(0)("uuid"), uuidList(1)("uuid")) + batchStream << Database.deleteRelationship(uuidList(0)("uuid"), uuidList(2)("uuid")) batchStream.execute() - seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), relPropsToSet0) - seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), relPropsToSet1) + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2") val testedNodeList = seqStream.execute() - .asInstanceOf[List[List[Map[String, Any]]]] - - assert(testedNodeList(0) != null) - assert(testedNodeList(0).length == 1) - assert(testedNodeList(0)(0).equals(validNodeList(0))) + .asInstanceOf[List[List[Map[String, Any]]]](0) - assert(testedNodeList(1) != null) - assert(testedNodeList(1).length == 1) - assert(testedNodeList(1)(0).equals(validNodeList(1))) + assert(testedNodeList != null) + assert(testedNodeList.length == 0) batchStream << Database.deleteNode(uuidList(0)("uuid")) batchStream << Database.deleteNode(uuidList(1)("uuid")) batchStream << Database.deleteNode(uuidList(2)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } // using batch, incorrect input - it should "set properties only to one relationship" in { - val modelName = "NeoUser" - val relType = "<>" + it should "delete only one relationship" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + + val modelName = "Content" + val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) val props2: Map[String, Any] = Map("key0" -> "aaa", "key1" -> 15) - val relPropsToSet0: Map[String, Any] = Map("relKey" -> 92) - val relPropsToSet1: Map[String, Any] = null + val nonExistingUuid = "*abc([)*" batchStream << Database.createNode(modelName, relType, props0) batchStream << Database.createNode(modelName, relType, props1) @@ -1510,125 +1985,135 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(2)("uuid"), relType + "2") batchStream.execute() - batchStream << Database.setRelationshipProperties(uuidList(0)("uuid"), uuidList(1)("uuid"), relPropsToSet0) - batchStream << Database.setRelationshipProperties(uuidList(0)("uuid"), uuidList(2)("uuid"), relPropsToSet1) + batchStream << Database.deleteRelationship(uuidList(0)("uuid"), uuidList(1)("uuid")) + batchStream << Database.deleteRelationship(uuidList(0)("uuid"), nonExistingUuid) batchStream.execute() - seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), relPropsToSet0) - seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), relPropsToSet1) + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2") val testedNodeList = seqStream.execute() - .asInstanceOf[List[List[Map[String, Any]]]] - - assert(testedNodeList(0) != null) - assert(testedNodeList(0).length == 1) - assert(testedNodeList(0)(0).equals(validNodeList(0))) + .asInstanceOf[List[List[Map[String, Any]]]](0) - assert(testedNodeList(1) != null) - assert(testedNodeList(1).length == 2) + assert(testedNodeList != null) + assert(testedNodeList.length == 1) + assert(testedNodeList(0).equals(validNodeList(1))) batchStream << Database.deleteNode(uuidList(0)("uuid")) batchStream << Database.deleteNode(uuidList(1)("uuid")) batchStream << Database.deleteNode(uuidList(2)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } - // =================== DELETE RELATIONSHIP PROPERTIES =================== + // =================== POP RELATIONSHIP =================== // not using batch, correct input - "deleteRelationshipProperties" should "delete relationship's properties" in { + "popRelationship" should "delete the relationship and return end node" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" - val relType = "<>" + val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) - - val relProps: Map[String, Any] = Map("keyA" -> 5, "keyB" -> "aaa") - val propsToDelete: List[String] = List("keyB") + val props2: Map[String, Any] = Map("key0" -> "def", "key1" -> 68) batchStream << Database.createNode(modelName, relType, props0) batchStream << Database.createNode(modelName, relType, props1) + batchStream << Database.createNode(modelName, relType, props2) val uuidList = batchStream.execute() .asInstanceOf[List[Map[String, String]]] - var validNode = props1 - validNode += "uuid" -> uuidList(1)("uuid") + val validNodeList = ListBuffer(props1, props2) + validNodeList(0) += "uuid" -> uuidList(1)("uuid") + validNodeList(1) += "uuid" -> uuidList(2)("uuid") - seqStream !! Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2", relProps) - seqStream !! Database.deleteRelationshipProperties(uuidList(0)("uuid"), uuidList(1)("uuid"), propsToDelete) + seqStream !! Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2") + seqStream !! Database.createRelationship(uuidList(0)("uuid"), uuidList(2)("uuid"), relType + "2") + + seqStream << Database.popRelationship(uuidList(0)("uuid"), relType + "2") + val testedResult = seqStream.execute() + .asInstanceOf[List[Map[String, Any]]](0) seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2") - seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), relProps) val testedNodeList = seqStream.execute() - .asInstanceOf[List[List[Map[String, Any]]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) - assert(testedNodeList(0) != null) - assert(testedNodeList(0).length == 1) - assert(testedNodeList(0)(0).equals(validNode)) + assert(testedResult != null) + assert(testedResult("node") != null) + assert(testedResult("node").asInstanceOf[Map[String, Any]].equals(validNodeList(0)) || + testedResult("node").asInstanceOf[Map[String, Any]].equals(validNodeList(1))) - assert(testedNodeList(1) != null) - assert(testedNodeList(1).length == 0) + assert(testedNodeList != null) + assert(testedNodeList.length == 1) batchStream << Database.deleteNode(uuidList(0)("uuid")) batchStream << Database.deleteNode(uuidList(1)("uuid")) + batchStream << Database.deleteNode(uuidList(2)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } // not using batch, incorrect input - it should "not delete relationship's properties" in { - val modelName = "ContentSource" - val relType = "<>" + it should "not delete any relationship" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + + val modelName = "Content" + val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) - val nonExistingUuid = "*abc([)*" - val relProps: Map[String, Any] = Map("keyA" -> 5, "keyB" -> "aaa") - val propsToDelete: List[String] = List("keyB") + val nonExistingRelType = "*abc([)*" batchStream << Database.createNode(modelName, relType, props0) batchStream << Database.createNode(modelName, relType, props1) val uuidList = batchStream.execute() .asInstanceOf[List[Map[String, String]]] - seqStream !! Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2", relProps) + var validNode = props1 + validNode += "uuid" -> uuidList(1)("uuid") - seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), relProps) - val testedNodeList = seqStream.execute() - .asInstanceOf[List[Map[String, Any]]] + seqStream !! Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2") + seqStream << Database.popRelationship(uuidList(0)("uuid"), nonExistingRelType) + val testedResult = seqStream.execute() + .asInstanceOf[List[Map[String, Any]]](0) - seqStream !! Database.deleteRelationshipProperties(uuidList(0)("uuid"), nonExistingUuid, propsToDelete) - seqStream !! Database.deleteRelationshipProperties(uuidList(0)("uuid"), uuidList(1)("uuid"), null) + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2") + val testedNodeList = seqStream.execute() + .asInstanceOf[List[List[Map[String, Any]]]](0) - seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), relProps) - val testedNodeList2 = seqStream.execute() - .asInstanceOf[List[Map[String, Any]]] + assert(testedResult != null) + assert(testedResult("node") == null) assert(testedNodeList != null) assert(testedNodeList.length == 1) - - assert(testedNodeList2 != null) - assert(testedNodeList2.length == 1) - assert(testedNodeList.equals(testedNodeList2)) + assert(testedNodeList(0).equals(validNode)) batchStream << Database.deleteNode(uuidList(0)("uuid")) batchStream << Database.deleteNode(uuidList(1)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } // using batch, correct input - it should "delete properties of exactly two relationships" in { + it should "delete exactly two relationships" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" - val relType = "<>" + val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) val props2: Map[String, Any] = Map("key0" -> "aaa", "key1" -> 15) - val relProps0: Map[String, Any] = Map("keyA" -> 5, "keyB" -> "aaa") - val relProps1: Map[String, Any] = Map("keyA" -> 5, "keyB" -> "bca") - - val relPropsToDelete0: List[String] = List("keyA") - val relPropsToDelete1: List[String] = List("keyB") - batchStream << Database.createNode(modelName, relType, props0) batchStream << Database.createNode(modelName, relType, props1) batchStream << Database.createNode(modelName, relType, props2) @@ -1639,49 +2124,52 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { validNodeList(0) += "uuid" -> uuidList(1)("uuid") validNodeList(1) += "uuid" -> uuidList(2)("uuid") - val validProps0: Map[String, Any] = Map("keyB" -> "aaa") - val validProps1: Map[String, Any] = Map("keyA" -> 5) - - batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2", relProps0) - batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(2)("uuid"), relType + "2", relProps1) + batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2") + batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(2)("uuid"), relType + "2") batchStream.execute() - batchStream << Database.deleteRelationshipProperties(uuidList(0)("uuid"), uuidList(1)("uuid"), relPropsToDelete0) - batchStream << Database.deleteRelationshipProperties(uuidList(0)("uuid"), uuidList(2)("uuid"), relPropsToDelete1) - batchStream.execute() + batchStream << Database.popRelationship(uuidList(0)("uuid"), relType + "2") + batchStream << Database.popRelationship(uuidList(0)("uuid"), relType + "2") + val testedResultList = batchStream.execute() + .asInstanceOf[List[Map[String, Any]]] - seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), validProps0) - seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), validProps1) + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2") val testedNodeList = seqStream.execute() - .asInstanceOf[List[List[Map[String, Any]]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) - assert(testedNodeList(0) != null) - assert(testedNodeList(0).length == 1) - assert(testedNodeList(0)(0).equals(validNodeList(0))) + val condition1 = testedResultList(0)("node").asInstanceOf[Map[String, Any]].equals(validNodeList(0)) + val condition2 = testedResultList(0)("node").asInstanceOf[Map[String, Any]].equals(validNodeList(1)) + val condition3 = testedResultList(1)("node").asInstanceOf[Map[String, Any]].equals(validNodeList(0)) + val condition4 = testedResultList(1)("node").asInstanceOf[Map[String, Any]].equals(validNodeList(1)) - assert(testedNodeList(1) != null) - assert(testedNodeList(1).length == 1) - assert(testedNodeList(1)(0).equals(validNodeList(1))) + assert(testedResultList != null) + assert(testedResultList.length == 2) + assert((condition1 && condition4) || (condition2 && condition3)) + + assert(testedNodeList != null) + assert(testedNodeList.length == 0) batchStream << Database.deleteNode(uuidList(0)("uuid")) batchStream << Database.deleteNode(uuidList(1)("uuid")) batchStream << Database.deleteNode(uuidList(2)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } // using batch, incorrect input - it should "delete properties of only one relationship" in { - val modelName = "NeoUser" - val relType = "<>" + it should "delete only one relationship" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + + val modelName = "Content" + val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) val props2: Map[String, Any] = Map("key0" -> "aaa", "key1" -> 15) - val relProps0: Map[String, Any] = Map("keyA" -> 5, "keyB" -> "aaa") - val relProps1: Map[String, Any] = Map("keyA" -> 5, "keyB" -> "bca") - - val relPropsToDelete0: List[String] = null - val relPropsToDelete1: List[String] = List("keyB") + val nonExistingRelType = "*abc([)*" batchStream << Database.createNode(modelName, relType, props0) batchStream << Database.createNode(modelName, relType, props1) @@ -1693,36 +2181,35 @@ class Set1 extends FlatSpec with BeforeAndAfterAll { validNodeList(0) += "uuid" -> uuidList(1)("uuid") validNodeList(1) += "uuid" -> uuidList(2)("uuid") - val validProps1: Map[String, Any] = Map("keyA" -> 5) - - batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2", relProps0) - batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(2)("uuid"), relType + "2", relProps1) + batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "2") + batchStream << Database.createRelationship(uuidList(0)("uuid"), uuidList(2)("uuid"), relType + "2") batchStream.execute() - seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map()) - val testedNodeList = seqStream.execute() + batchStream << Database.popRelationship(uuidList(0)("uuid"), relType + "2") + batchStream << Database.popRelationship(uuidList(0)("uuid"), nonExistingRelType) + val testedResultList = batchStream.execute() .asInstanceOf[List[Map[String, Any]]] - batchStream << Database.deleteRelationshipProperties(uuidList(0)("uuid"), uuidList(1)("uuid"), relPropsToDelete0) - batchStream << Database.deleteRelationshipProperties(uuidList(0)("uuid"), uuidList(2)("uuid"), relPropsToDelete1) - batchStream.execute() - - seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), relProps0) - seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2", Map(), validProps1) - val testedNodeList2 = seqStream.execute() - .asInstanceOf[List[List[Map[String, Any]]]] + seqStream << Database.getChildren(uuidList(0)("uuid"), relType + "2") + val testedNodeList = seqStream.execute() + .asInstanceOf[List[List[Map[String, Any]]]](0) - assert(testedNodeList2(0) != null) - assert(testedNodeList2(0).length == 1) - assert(testedNodeList2(0)(0).equals(validNodeList(0))) + assert(testedResultList != null) + assert(testedResultList.length == 2) + assert(testedResultList(0)("node").asInstanceOf[Map[String, Any]].equals(validNodeList(0)) + || testedResultList(0)("node").asInstanceOf[Map[String, Any]].equals(validNodeList(1))) + assert(testedResultList(1)("status").asInstanceOf[Boolean] == false) - assert(testedNodeList2(1) != null) - assert(testedNodeList2(1).length == 2) - assert(testedNodeList.equals(testedNodeList2(1))) + assert(testedNodeList != null) + assert(testedNodeList.length == 1) + assert(testedNodeList(0).equals(validNodeList(1))) batchStream << Database.deleteNode(uuidList(0)("uuid")) batchStream << Database.deleteNode(uuidList(1)("uuid")) batchStream << Database.deleteNode(uuidList(2)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } } diff --git a/lionfish/src/test/scala/com/lionfish/correctness/Set2.scala b/lionfish/src/test/scala/com/lionfish/correctness/Set2.scala index 34279c0..22f8644 100755 --- a/lionfish/src/test/scala/com/lionfish/correctness/Set2.scala +++ b/lionfish/src/test/scala/com/lionfish/correctness/Set2.scala @@ -10,23 +10,19 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { private var batchStream: Stream = null override def beforeAll() { - val address = Config.debugServerAddress - val port = Config.debugServerPort Launcher.main(Array("--debug")) - Database.setServerAddress(address) - Database.setServerPort(port) - - Server.debugLock.acquire() - seqStream = Database.getSequenceStream - batchStream = Database.getBatchStream - Server.debugLock.release() + Database.setServerAddress(Config.serverAddress) + Database.setServerPort(Config.serverPort) } // =================== SET 2.1 =================== "set 2.1" should "accept mixed getModelNodes, getChildren, getInstances, createNode, createRelationship and deleteNode" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelNodeList = (seqStream !! Database.getModelNodes()) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(modelNodeList != null) assert(modelNodeList.length > 0) @@ -46,15 +42,15 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { .asInstanceOf[List[Map[String, String]]] val children = (seqStream !! Database.getChildren(modelUuid, relType, childrenProps)) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) val instances = (seqStream !! Database.getInstances(modelName, childrenProps)) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) seqStream !! Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "-2") val children2 = (seqStream !! Database.getChildren(uuidList(0)("uuid"), relType + "-2")) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(children != null) assert(children.length == 1) @@ -68,9 +64,15 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { batchStream << Database.deleteNode(uuidList(0)("uuid")) batchStream << Database.deleteNode(uuidList(1)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } it should "accept mixed getByUuid, getInstances, createRelationship and deleteNode" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "NeoUser" val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") @@ -82,7 +84,7 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { .asInstanceOf[List[Map[String, String]]] val instances = (seqStream !! Database.getInstances(modelName)) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) for (item <- instances) { batchStream << Database.getByUuid(item("uuid").asInstanceOf[String]) @@ -100,7 +102,7 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { seqStream !! Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "-2") val children2 = (seqStream !! Database.getChildren(uuidList(0)("uuid"), relType + "-2")) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(children2 != null) assert(children2.length == 1) @@ -108,16 +110,22 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { batchStream << Database.deleteNode(uuidList(0)("uuid")) batchStream << Database.deleteNode(uuidList(1)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } it should "accept mixed getByLink, getInstances and deleteRelationship" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "ContentSource" val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "link" -> "http://www.example1.com") val props1: Map[String, Any] = Map("key0" -> "abc", "link" -> "http://www.example2.com") val modelNodeList = (seqStream !! Database.getModelNodes()) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(modelNodeList != null) assert(modelNodeList.length > 0) @@ -137,7 +145,7 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { .asInstanceOf[List[Map[String, String]]] val instances = (seqStream !! Database.getInstances(modelName)) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) for (item <- instances) { batchStream << Database.getByLink(modelName, item("link").asInstanceOf[String]) @@ -148,7 +156,7 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { seqStream !! Database.deleteRelationship(modelUuid, uuidList(0)("uuid")) val instances2 = (seqStream !! Database.getInstances(modelName)) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(instances != null) assert(instances.length > 0) @@ -163,11 +171,17 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { batchStream << Database.deleteNode(uuidList(0)("uuid")) batchStream << Database.deleteNode(uuidList(1)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } it should "accept mixed getByUuid, getByLink, getModelNodes, getChildren, deleteNode and deleteRelationship" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelNodeList = (seqStream !! Database.getModelNodes()) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(modelNodeList != null) assert(modelNodeList.length > 0) @@ -194,7 +208,7 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { .asInstanceOf[List[Map[String, String]]] val children = (seqStream !! Database.getChildren(modelUuid, relType)) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) for (item <- children) { batchStream << Database.getByUuid(item("uuid").asInstanceOf[String]) @@ -211,7 +225,7 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { seqStream !! Database.deleteRelationship(modelUuid, uuidList(0)("uuid")) val children2 = (seqStream !! Database.getChildren(modelUuid, relType)) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(children != null) assert(children.length > 0) @@ -230,11 +244,17 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { batchStream << Database.deleteNode(uuidList(0)("uuid")) batchStream << Database.deleteNode(uuidList(1)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } it should "accept mixed getModelNodes, getChildren, createNode and deleteRelationship" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelNodeList = (seqStream !! Database.getModelNodes()) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) val rootUuid = "root" val nonExistingUuid = "*abc([)*" @@ -243,7 +263,7 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { seqStream !! Database.deleteRelationship(rootUuid, nonExistingUuid) val children = (seqStream !! Database.getChildren(rootUuid, relType)) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(modelNodeList != null) assert(modelNodeList.length > 0) @@ -254,16 +274,22 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { for (model <- modelNodeList) { assert(children.contains(model)) } + + seqStream.close() + batchStream.close() } it should "accept mixed getByUuid, getByLink, getInstances, deleteNode and deleteRelationship" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "ContentSource" val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "link" -> "http://www.example5.com") val props1: Map[String, Any] = Map("key0" -> "abc", "link" -> "http://www.example6.com") val modelNodeList = (seqStream !! Database.getModelNodes()) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(modelNodeList != null) assert(modelNodeList.length > 0) @@ -283,7 +309,7 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { .asInstanceOf[List[Map[String, String]]] val instances = (seqStream !! Database.getInstances(modelName)) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) for (item <- instances) { batchStream << Database.getByUuid(item("uuid").asInstanceOf[String]) @@ -300,7 +326,7 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { seqStream !! Database.deleteRelationship(modelUuid, uuidList(0)("uuid")) val instances2 = (seqStream !! Database.getInstances(modelName)) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(instances != null) assert(instances.length > 0) @@ -319,9 +345,15 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { batchStream << Database.deleteNode(uuidList(0)("uuid")) batchStream << Database.deleteNode(uuidList(1)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } it should "accept mixed getByUuid, getByLink, createNode, createRelationship and deleteRelationship" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "ContentSource" val relType = "<>" val props0: Map[String, Any] = Map("key0" -> 1, "link" -> "http://www.example7.com") @@ -345,7 +377,7 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { seqStream !! Database.createRelationship(uuidList(0)("uuid"), uuidList(1)("uuid"), relType + "-2") val children = (seqStream !! Database.getChildren(uuidList(0)("uuid"), relType + "-2")) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(nodeByUuidList != null) assert(nodeByUuidList.length == 2) @@ -361,6 +393,9 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { batchStream << Database.deleteNode(uuidList(0)("uuid")) batchStream << Database.deleteNode(uuidList(1)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } @@ -368,13 +403,16 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { // =================== SET 2.2 =================== "set 2.2" should "accept mixed getChildren and setProperties" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" val relType = "<>" var props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") val props1: Map[String, Any] = Map("key0" -> "abc", "key1" -> 33) val modelNodeList = (seqStream !! Database.getModelNodes()) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(modelNodeList != null) assert(modelNodeList.length > 0) @@ -396,13 +434,13 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { props0 += "uuid" -> uuidList(0)("uuid") val children = (seqStream !! Database.getChildren(modelUuid, relType)) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) var propsToSet: Map[String, Any] = Map("key1" -> "def", "key2" -> 56) seqStream !! Database.setProperties(uuidList(0)("uuid"), propsToSet) val children2 = (seqStream !! Database.getChildren(modelUuid, relType)) - .asInstanceOf[List[Map[String, Any]]] + .asInstanceOf[List[List[Map[String, Any]]]](0) assert(children != null) assert(children.length == 2) @@ -437,9 +475,15 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { batchStream << Database.deleteNode(uuidList(0)("uuid")) batchStream << Database.deleteNode(uuidList(1)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } it should "accept mixed getByUuid and setProperties" in { + seqStream = Database.getSequenceStream + batchStream = Database.getBatchStream + val modelName = "Content" val relType = "<>" var props0: Map[String, Any] = Map("key0" -> 1, "key1" -> "string") @@ -453,13 +497,13 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { props0 += "uuid" -> uuidList(0)("uuid") val testedNode = (seqStream !! Database.getByUuid(uuidList(0)("uuid"))) - .asInstanceOf[Map[String, Any]] + .asInstanceOf[List[Map[String, Any]]](0) var propsToSet: Map[String, Any] = Map("key1" -> "def", "key2" -> 56) seqStream !! Database.setProperties(uuidList(0)("uuid"), propsToSet) val testedNode2 = (seqStream !! Database.getByUuid(uuidList(0)("uuid"))) - .asInstanceOf[Map[String, Any]] + .asInstanceOf[List[Map[String, Any]]](0) assert(testedNode != null) assert(testedNode2 != null) @@ -474,5 +518,8 @@ class Set2 extends FlatSpec with BeforeAndAfterAll { batchStream << Database.deleteNode(uuidList(0)("uuid")) batchStream << Database.deleteNode(uuidList(1)("uuid")) batchStream.execute() + + seqStream.close() + batchStream.close() } } diff --git a/scripts/ocean_exemplary_data.py b/scripts/ocean_exemplary_data.py index 1814f8b..79c4fe3 100755 --- a/scripts/ocean_exemplary_data.py +++ b/scripts/ocean_exemplary_data.py @@ -14,13 +14,14 @@ from py2neo import neo4j sys.path.append(os.path.join(os.path.dirname(__file__), '../don_corleone/')) +sys.path.append(os.path.join(os.path.dirname(__file__), '../lionfish/python_lionfish/client/')) from don_utils import get_configuration sys.path.append('../graph_workers/') lib_path = os.path.abspath('./graph_workers') sys.path.append(lib_path) from graph_workers.graph_defines import * -from odm_client import ODMClient +from client import Client SOURCE_FILE = '../data/contentsource_nodes_exemplary' @@ -67,7 +68,7 @@ print '(You are permitted to run whole system too during this process)' enter = raw_input() - odm_client = ODMClient() + odm_client = Client('localhost', 7777) odm_client.connect() odm_batch = odm_client.get_batch() @@ -97,6 +98,7 @@ try: cs_node = eval(unicode(cs)) cs_node['last_updated'] = 0 + cs_node['description'] = cs_node['description'].encode('utf-8') odm_batch.append( odm_client.create_node, diff --git a/scripts/ocean_init_graph.py b/scripts/ocean_init_graph.py index 4f50c1a..7115c44 100755 --- a/scripts/ocean_init_graph.py +++ b/scripts/ocean_init_graph.py @@ -115,7 +115,6 @@ def run_and_return_type_list(): ) print 'Graph populated successfully.' - print 'NOTE: Remember to restart Lionfish ODM server.' return type_list diff --git a/scripts/ocean_small_exemplary_data.py b/scripts/ocean_small_exemplary_data.py index 8b141b0..a9ad417 100755 --- a/scripts/ocean_small_exemplary_data.py +++ b/scripts/ocean_small_exemplary_data.py @@ -267,5 +267,4 @@ batch.submit() print 'Graph populated successfully!' - print 'Remember to (RE)START Lionfish server!' diff --git a/tests/spidercrab_integrity_test.py b/tests/spidercrab_integrity_test.py index 9003f7d..6923ac3 100755 --- a/tests/spidercrab_integrity_test.py +++ b/tests/spidercrab_integrity_test.py @@ -46,7 +46,7 @@ def check_lionfish_communication(): lionfish_client = Client(lionfish_host, lionfish_port) lionfish_client.connect() - lionfish_client.create_model('spidercrab_integrity_test') + lionfish_client.create_model_node('spidercrab_integrity_test') found_instances = lionfish_client.get_model_nodes() model_instance = None model_uuid = ''