rtcryo.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # -*- Python -*-
00003 # -*- coding: utf-8 -*-
00004 
00005 '''rtshell
00006 
00007 Copyright (C) 2009-2014
00008     Geoffrey Biggs
00009     RT-Synthesis Research Group
00010     Intelligent Systems Research Institute,
00011     National Institute of Advanced Industrial Science and Technology (AIST),
00012     Japan
00013     All rights reserved.
00014 Licensed under the Eclipse Public License -v 1.0 (EPL)
00015 http://www.opensource.org/licenses/eclipse-1.0.txt
00016 
00017 rtcryo library.
00018 
00019 '''
00020 
00021 
00022 import datetime
00023 import optparse
00024 import os.path
00025 import rtctree.tree
00026 import rtctree.path
00027 import rtsprofile
00028 import rtsprofile.rts_profile
00029 import rtsprofile.component
00030 import rtsprofile.config_set
00031 import rtsprofile.exec_context
00032 import rtsprofile.port_connectors
00033 import rtsprofile.ports
00034 import rtsprofile.targets
00035 import sys
00036 import traceback
00037 
00038 import option_store
00039 import rtshell
00040 
00041 
00042 def clean_props(props):
00043     '''Clean properties of dangerous values and wrong data types.
00044 
00045     Make sure the properties don't have IORs or similar in them, because
00046     they will confuse the notify_connect calls.
00047 
00048     Make sure that all keys are not unicode.
00049 
00050     '''
00051     new_props = {}
00052     for p in props:
00053         if p == 'dataport.corba_cdr.inport_ior':
00054             continue
00055         if p == 'dataport.corba_cdr.inport_ref':
00056             continue
00057         if p == 'dataport.corba_cdr.outport_ior':
00058             continue
00059         if p == 'dataport.corba_cdr.outport_ref':
00060             continue
00061         new_props[str(p)] = str(props[p])
00062     return new_props
00063 
00064 
00065 def make_comp_id(comp):
00066     return 'RTC:{0}:{1}:{2}:{3}'.format(comp.vendor, comp.category,
00067                                         comp.type_name, comp.version)
00068 
00069 
00070 def find_all_used_components(tree):
00071     # Finds all component nodes in the tree
00072     def get_node(node, args):
00073         return node
00074     def is_in_dir(node):
00075         if node.parent.is_manager:
00076             return False
00077         return True
00078     return [c for c in tree.iterate(get_node,
00079                                        filter=['is_component', is_in_dir]) \
00080               if c.connected_ports]
00081 
00082 
00083 def find_unique_connectors(tree, components):
00084     # Finds all unique connections between the components
00085     data_connectors = []
00086     seen_svc_connectors = []
00087     svc_connectors = []
00088     def in_svc_list(conn):
00089         for c in svc_connectors:
00090             if c.connector_id == conn.id:
00091                 return True
00092         return False
00093 
00094     for comp in components:
00095         for op in comp.connected_outports:
00096             for conn in op.connections:
00097                 name = comp.instance_name + '.' + op.name
00098                 source_port = rtsprofile.targets.TargetPort(
00099                         component_id=make_comp_id(comp),
00100                         instance_name=comp.instance_name, port_name=name)
00101                 source_port.properties['COMPONENT_PATH_ID'] = \
00102                         comp.full_path_str[1:]
00103                 # Get the list of ports this connection goes to
00104                 dest_ports = [name for name, p in conn.ports \
00105                                    if not comp.get_port_by_ref(p.object)]
00106                 # Assume the first is the destination and find its component
00107                 path = rtctree.path.parse_path(dest_ports[0])
00108                 dest_comp = tree.get_node(path[0])
00109                 # Now have all the info we need to make the target
00110                 name = dest_comp.instance_name + '.' + path[1]
00111                 dest_port = rtsprofile.targets.TargetPort(
00112                         component_id=make_comp_id(dest_comp),
00113                         instance_name=dest_comp.instance_name, port_name=name)
00114                 dest_port.properties['COMPONENT_PATH_ID'] = \
00115                         dest_comp.full_path_str[1:]
00116                 # Check if the data type is known (see issue 13)
00117                 if 'dataport.data_type' in conn.properties:
00118                     data_type = conn.properties['dataport.data_type']
00119                 else:
00120                     data_type = dest_port.port_name
00121                 rts_conn = rtsprofile.port_connectors.DataPortConnector(
00122                         connector_id=conn.id, name=conn.name,
00123                         data_type=data_type,
00124                         interface_type=conn.properties['dataport.interface_type'],
00125                         data_flow_type=conn.properties['dataport.dataflow_type'],
00126                         subscription_type=conn.properties['dataport.subscription_type'],
00127                         source_data_port=source_port,
00128                         target_data_port=dest_port)
00129                 rts_conn.properties = clean_props(conn.properties)
00130                 data_connectors.append(rts_conn)
00131 
00132         for sp in comp.connected_svcports:
00133             for conn in sp.connections:
00134                 if in_svc_list(conn):
00135                     continue;
00136                 seen_svc_connectors.append(conn)
00137                 name = comp.instance_name + '.' + sp.name
00138                 source_port = rtsprofile.targets.TargetPort(
00139                         component_id=make_comp_id(comp),
00140                         instance_name=comp.instance_name, port_name=name)
00141                 source_port.properties['COMPONENT_PATH_ID'] = \
00142                         comp.full_path_str[1:]
00143                 # Get the list of ports this connection goes to
00144                 dest_ports = [name for name, p in conn.ports \
00145                                    if not comp.get_port_by_ref(p.object)]
00146                 if not dest_ports:
00147                     # Skip ports with no or unknown connections
00148                     # (Unknown connections cannot be preserved)
00149                     # See issue 13
00150                     continue
00151                 # Assume the first is the destination and find its component
00152                 path = rtctree.path.parse_path(dest_ports[0])
00153                 dest_comp = tree.get_node(path[0])
00154                 # Now have all the info we need to make the target
00155                 name = dest_comp.instance_name + '.' + path[1]
00156                 dest_port = rtsprofile.targets.TargetPort(
00157                         component_id=make_comp_id(dest_comp),
00158                         instance_name=dest_comp.instance_name, port_name=name)
00159                 dest_port.properties['COMPONENT_PATH_ID'] = \
00160                         dest_comp.full_path_str[1:]
00161                 rts_conn = rtsprofile.port_connectors.ServicePortConnector(
00162                         connector_id=conn.id, name=conn.name,
00163                         source_service_port=source_port,
00164                         target_service_port=dest_port)
00165                 rts_conn.properties = clean_props(conn.properties)
00166                 svc_connectors.append(rts_conn)
00167     return data_connectors, svc_connectors
00168 
00169 
00170 def tree_comps_to_rts_comps(components):
00171     rts_comps = []
00172     for comp in components:
00173         active_conf_set = comp.active_conf_set_name if comp.active_conf_set \
00174                                                     else ''
00175         new_rtsc = rtsprofile.component.Component(id=make_comp_id(comp),
00176                 path_uri=comp.full_path_str[1:],
00177                 active_configuration_set=active_conf_set,
00178                 instance_name=comp.instance_name,
00179                 composite_type=rtsprofile.composite_type.NONE,
00180                 is_required=True)
00181         for dp in comp.inports:
00182             new_rtsc.data_ports.append(rtsprofile.ports.DataPort(dp.name))
00183         for dp in comp.outports:
00184             new_rtsc.data_ports.append(rtsprofile.ports.DataPort(dp.name))
00185         for sp in comp.svcports:
00186             new_rtsc.service_ports.append(rtsprofile.ports.ServicePort(sp.name))
00187         for cs in comp.conf_sets:
00188             new_cs = rtsprofile.config_set.ConfigurationSet(id=cs)
00189             for param in comp.conf_sets[cs].data:
00190                 new_cs.configuration_data.append(
00191                         rtsprofile.config_set.ConfigurationData(name=param,
00192                             data=comp.conf_sets[cs].data[param]))
00193             new_rtsc.configuration_sets.append(new_cs)
00194         for ec in comp.owned_ecs:
00195             new_rtsc.execution_contexts.append(
00196                     rtsprofile.exec_context.ExecutionContext(
00197                         id=str(ec.handle),
00198                         kind=ec.kind_as_string(add_colour=False).upper(),
00199                         rate=ec.rate))
00200         new_rtsc.properties['IOR'] = \
00201                 comp.nameserver.orb.object_to_string(comp.object)
00202         rts_comps.append(new_rtsc)
00203     return rts_comps
00204 
00205 
00206 def data_conns_to_rts_conns(connectors):
00207     result = []
00208     for conn in connectors:
00209         source_port = rtsprofile.targets.TargetPort()
00210         dest_port = rtsprofile.targets.TargetPort()
00211     return result
00212 
00213 
00214 def freeze_dry(servers, dest='-', xml=True, abstract='', vendor='', sysname='',
00215         version='', tree=None):
00216     if not tree:
00217         tree = rtctree.tree.RTCTree(servers=servers)
00218     # Run through the tree finding component names and connections to
00219     # preserve.
00220     components = find_all_used_components(tree)
00221     # Create a list of objects for the profile
00222     rts_components = tree_comps_to_rts_comps(components)
00223     data_connectors, svc_connectors = find_unique_connectors(tree,
00224             components)
00225     # Create an empty RTSProfile and add the information to it
00226     rtsp = rtsprofile.rts_profile.RtsProfile()
00227     rtsp.abstract = abstract
00228     today = datetime.datetime.today()
00229     today = today.replace(microsecond=0)
00230     rtsp.creation_date = today.isoformat()
00231     rtsp.update_date = today.isoformat()
00232     rtsp.version = rtsprofile.RTSPROFILE_SPEC_VERSION
00233     rtsp.id = 'RTSystem :{0}.{1}.{2}'.format(vendor, sysname, version)
00234     rtsp.components = rts_components
00235     rtsp.data_port_connectors = data_connectors
00236     rtsp.service_port_connectors = svc_connectors
00237 
00238     if dest == '-':
00239         # Write XML to stdout
00240         if xml:
00241             sys.stdout.write(rtsp.save_to_xml())
00242         else:
00243             sys.stdout.write(rtsp.save_to_yaml())
00244     else:
00245         # Write to a file
00246         f = open(dest, 'w')
00247         if xml:
00248             f.write(rtsp.save_to_xml())
00249         else:
00250             f.write(rtsp.save_to_yaml())
00251         f.close()
00252 
00253 
00254 def main(argv=None, tree=None):
00255     usage = '''Usage: %prog [options] [name servers]
00256 Record a running RT System in an RTSProfile specification.'''
00257     parser = optparse.OptionParser(usage=usage, version=rtshell.RTSH_VERSION)
00258     parser.add_option('-a', '--abstract', dest='abstract', action='store',
00259             type='string', default='RT System created by rtcryo.',
00260             help='Brief description of the RT System.')
00261     parser.add_option('-n', '--system-name', dest='sysname', action='store',
00262             type='string', default='RTSystem',
00263             help='Name of the RT System. [Default: %default]')
00264     parser.add_option('-o', '--output', dest='output', action='store',
00265             type='string', default='-',
00266             help='Output file name. [Default: standard out]')
00267     parser.add_option('-v', '--system-version', dest='version', action='store',
00268             type='string', default='0',
00269             help='Version of the RT System. [Default: %default]')
00270     parser.add_option('-e', '--vendor', dest='vendor', action='store',
00271             type='string', default='Me',
00272             help='Vendor of the RT System. [Default: %default]')
00273     parser.add_option('-x', '--xml', dest='xml', action='store_true',
00274             default=True, help='Use XML output format. [Default: True]')
00275     parser.add_option('-y', '--yaml', dest='xml', action='store_false',
00276             help='Use YAML output format. [Default: False]')
00277     parser.add_option('--verbose', dest='verbose', action='store_true',
00278             default=False, help='Verbose output. [Default: %default]')
00279 
00280     if argv:
00281         sys.argv = [sys.argv[0]] + argv
00282     try:
00283         options, args = parser.parse_args()
00284     except optparse.OptionError, e:
00285         print >>sys.stderr, 'OptionError: ', e
00286         return 1
00287     option_store.OptionStore().verbose = options.verbose
00288 
00289     try:
00290         freeze_dry(args, dest=options.output, xml=options.xml,
00291                 abstract=options.abstract, vendor=options.vendor,
00292                 sysname=options.sysname, version=options.version, tree=tree)
00293     except Exception, e:
00294         if options.verbose:
00295             traceback.print_exc()
00296         print >>sys.stderr, '{0}: {1}'.format(sys.argv[0], e)
00297         return 1
00298     return 0
00299 
00300 
00301 # vim: tw=79
00302 


rtshell
Author(s): Geoffrey Biggs
autogenerated on Fri Aug 28 2015 12:55:12