예제 #1
0
def main(database=None, config_file=None):
    """
    Connects to OrientDB database, discovers the 'TxOp' Children of 'RadioLinks', and modifies the start and end times
    :param (str) database: the name of the OrientDB database
    :param (str) config_file: path to the config file for OrientDB
    :return:
    """
    print(
        '****************       Update RadioLink Schedule         ****************'
    )

    processor = BrassOrientDBHelper(database, config_file)
    processor.open_database(over_write=False)

    select_radio = sql.select_sql('RadioLink')
    RadioLink_nodes = processor.run_query(select_radio)
    for node in RadioLink_nodes:
        print('>>>>>>> {0} : {1}'.format(node._rid, node.Name))
        printOrientRecord(node)
    select_radio = '(' + select_radio + ')'
    traverse_radio = sql.traverse_sql(select_radio,
                                      direction='in',
                                      edgetype='Containment')
    TxOp_conditional = sql.condition_str(lh='class', rh='TxOp', op='=')
    TxOp_select = sql.select_sql(traverse_radio, [TxOp_conditional])
    TxOp_nodes = processor.run_query(TxOp_select)

    # TxOp_nodes = processor.get_nodes_by_type('TxOp')

    for node in TxOp_nodes:
        print(node)
        new_startusec = sql.condition_str('StartUSec',
                                          str(int(node.StartUSec) + 105), '=')
        new_stopusec = sql.condition_str('StopUSec',
                                         str(int(node.StopUSec) + 105), '=')
        processor.update_node(node._rid, new_startusec, new_stopusec)
    print('Post Modification')
    TxOp_nodes = processor.get_nodes_by_type('TxOp')

    for node in TxOp_nodes:
        print(node)
    processor.close_database()
예제 #2
0
class OrientDBXMLImporter(object):
    """
    Class responsible for importing mdl xml files into an orientdb database.
    :param      databaseName:
    :param      mdlFile:
    :param      configFile:
    """
    def __init__(self, databaseName, mdlFile, configFile = 'config.json'):

        self.loadrObject = []
        self.uniqueIdentifiers = {}

        self.orientDB_helper = BrassOrientDBHelper(database_name=databaseName, config_file=configFile)
        self.mdlFile = mdlFile
        self.orientDB_helper.open_database(over_write=True)
        self.preprocessor = None
        self._schema = None


    def import_xml(self):
        """
        Main function called to start the import process.
        A temporary copy of the xml file is saved with attributes removed from the
        root tag, ie <MDLRoot> or <VCL>.
        The temporary xml file is then valided against schema and parsed.
        Lastly the temporary xml file is removed.
        :param:
        :return:
        """


        self.preprocessor = preprocess.create_preprocessor(self.mdlFile)
        self.preprocessor.preprocess_xml()
        self.parseXML(self.preprocessor.orientdb_xml_file)
        self.preprocessor.remove_orientdb_xml()


    def parseXML(self, xmlFile):
        """
        Parses passed in xmlFile and calls functions to create nodes and edges in
        orientdb.

        :param str xmlFile:         xml file to import
        :return:
        :raises BrassException:     catches any parsing error and rethrows as BrassException

        """
        # this is a stack we maintain when traversing the xml tree
        attribute_stack = []

        # after we decide something should be a vertex we add it to the vertex list
        vertices = []

        # a list of the vertices names (which could also be derived from vertices)
        #     so we know what OrientDB classes to create
        verticesNames = []

        # the two types of edges
        containmentEdges = []
        referenceEdges = []

        for event, elem in etree.iterparse(xmlFile, events=('start', 'end')):
            # at the beginning, add everything on the stack
            # the event can contain attributes eg:<QoSPolicy ID="GR1_to_TA1_MissionSLP"> (in which case we want to get them)
            #      or not <TestMission>
            if event == 'start':
                item = {}
                item[elem.tag] = elem.text if elem.text else ''
                for el in elem.attrib.keys():
                    item[el] = elem.attrib[el]
                attribute_stack.append({elem.tag: item})

                # the hardest part is at the end
                # we are trying to decide if the event closed out a vertex or something that should be an attribute of a vertex
                # eg:
                ''' <TestMission>
                       <Name>Test Mission 1</Name>
                       <Description>Test Mission 1: Frequency change</Description>
                       <TmNSCompleteness>true</TmNSCompleteness>
                       <TmNSCompletenessDescription>Complete</TmNSCompletenessDescription>
                    </TestMission>
                '''
                # in this example the algoritm should detect that TestMission should be a vertex
                # and Name, Description, TmNSCompleteness, TmNSCompletenessDescription should be attributes of TestMission
            elif event == 'end':

                # if the last attribute on the stack contains more than one thing, it's a vertex
                if len(attribute_stack[-1][list(attribute_stack[-1])[0]].keys()) > 1:
                    try:
                        elemText = attribute_stack[-1][list(attribute_stack[-1])[0]][list(attribute_stack[-1])[0]]
                        if elemText.isspace():
                            attribute_stack[-1][list(attribute_stack[-1])[0]].pop(list(attribute_stack[-1])[0])
                    except:
                        pass

                    a = attribute_stack.pop()
                    # if it doesn't have a unique identifier, will assign and also assign uid for the parent
                    if self.uidAlreadyAssigned(a) == 0:
                        a[list(a)[0]]['uid'] = self.assignUniqueId(list(a)[0])
                    try:
                        if self.uidAlreadyAssigned(attribute_stack[-1]) == 0:
                            attribute_stack[-1][list(attribute_stack[-1])[0]]['uid'] = self.assignUniqueId(
                                list(attribute_stack[-1])[0])
                    except:
                        pass

                    # adding to the vertices list
                    vertices.append(a)
                    verticesNames.append(list(a)[0])
                    try:

                        # creating a containment edge
                        containmentEdges.append(
                            [a[list(a)[0]]['uid'], attribute_stack[-1][list(attribute_stack[-1])[0]]['uid']])
                    except:
                        pass

                    try:
                        if len(attribute_stack) > 1:
                            if self.uidAlreadyAssigned(attribute_stack[-2]) == 0:
                                attribute_stack[-2][list(attribute_stack[-2])[0]]['uid'] = self.assignUniqueId(
                                    list(attribute_stack[-2])[0])
                    except:
                        raise BrassException(sys.exc_info()[0], 'MDLImporter.parseXML')

                # if it doesn't contain more than one thing, it's an attribute and will need to add it to the vertex right above on the stack
                else:
                    tmp_idx_1_attribute_stack_keys = list(attribute_stack[-1])
                    tmp_idx_2_attribute_stack_keys = list(attribute_stack[-2])

                    #attribute_stack[-2][tmp_idx_2_attribute_stack_keys[0]] = dict(
                    #    attribute_stack[-2][tmp_idx_2_attribute_stack_keys[0]].items()| attribute_stack[-1][
                    #        tmp_idx_1_attribute_stack_keys[0]].items())

                    attribute_stack[-2][tmp_idx_2_attribute_stack_keys[0]] = self.merge_attribute_map(
                                                                                                        attribute_stack[-2][tmp_idx_2_attribute_stack_keys[0]],
                                                                                                        attribute_stack[-1][tmp_idx_1_attribute_stack_keys[0]]
                                                                                                      )

                    if 'uid' not in attribute_stack[-2][tmp_idx_2_attribute_stack_keys[0]].keys():
                        attribute_stack[-2][tmp_idx_2_attribute_stack_keys[0]]['uid'] = self.assignUniqueId(
                            tmp_idx_2_attribute_stack_keys[0])
                    attribute_stack.pop()

        orientdbRestrictedIdentifier = []
        for s in set(verticesNames):
            try:
                self.orientDB_helper.create_node_class(s)
            except:
                self.orientDB_helper.create_node_class(s + '_a')

                # certain names are reserved keywords in orientdb eg: Limit, so we need to do things a little different
                orientdbRestrictedIdentifier.append(s)


        # this is the part where we add the vertices one by one to orientdb
        for e in vertices:
            # print e
            try:
                classToInsertInto = list(e)[0]
                if classToInsertInto in orientdbRestrictedIdentifier:
                    classToInsertInto += '_a'

                if classToInsertInto == 'MDLRoot':
                    e[list(e)[0]]['schema'] = self._schema

                print(f"create_node({classToInsertInto}, {e[list(e)[0]]})")
                self.orientDB_helper.create_node(classToInsertInto, e[list(e)[0]])


            except:
                raise BrassException(sys.exc_info()[1], 'MDLImporter.parseXML')
                #print "insert into " + e.keys()[0] + " (" + columns + ") values (" + values + ")"



        self.orientDB_helper.create_edge_class('Containment')

        # adding containment edges
        for edge in containmentEdges:
            # print  "create edge Containment from (SELECT FROM V WHERE uid = '"+edge[0]+"') TO (SELECT FROM V WHERE uid = '"+edge[1]+"')"
            try:
                child = [condition_str('uid', edge[0])]
                parent = [condition_str('uid', edge[1])]
                self.orientDB_helper.set_containment_relationship(
                    parent_conditions=parent,
                    child_conditions=child
                )
            except:
                raise BrassException(sys.exc_info()[0], 'MDLImporter.parseXML')
                # print edge[0], edge[1]


        self.orientDB_helper.create_edge_class('Reference')

        # for some stupid reason columns are case sensitive in orientdb

        for idref in self.orientDB_helper.run_query(select_sql('V', data_to_extract=['distinct(IDREF) as idref'])):

            # sometimes we have orphans so we need to escape them.
            try:


                reference_condition = [condition_str('IDREF', idref.idref)]
                referent_condition = [condition_str('ID', idref.idref)]
                self.orientDB_helper.set_reference_relationship(
                    referent_condition=referent_condition,
                    reference_condition=reference_condition
                )
            except:
                pass

    def assignUniqueId(self, entityType):
        """
        Creates a unique id based on the entityType.

        :param str entityType:        name of the entity (ie TestMissions, RadioLinks, MDLRoot, etc)
        :return:                      a unique id in string
        """
        uniqId = ''
        if entityType in self.uniqueIdentifiers.keys():
            self.uniqueIdentifiers[entityType] += 1
        else:
            self.uniqueIdentifiers[entityType] = 0
        uniqId = entityType + '-' + str(self.uniqueIdentifiers[entityType])
        return uniqId


    def uidAlreadyAssigned(self, element):
        """
        Checks if the element already has a unique id.
        :param element:         element to check
        :return:                True or False

        """
        if 'uid' in element[list(element)[0]].keys():
            return 1
        return 0


    def merge_attribute_map(self, src_map, dest_map):
        attribute_map = dict(src_map)

        for i in dest_map:
            if i in attribute_map:
                if type(attribute_map[i]) is list:
                    attribute_map[i].append(dest_map[i])
                else:
                    attribute_map[i] = list((attribute_map[i], dest_map[i]))
            else:
                attribute_map[i] = dest_map[i]

        return attribute_map