00001
00002
00003
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 rtresurrect library.
00018
00019 '''
00020
00021
00022 import optparse
00023 import os
00024 import os.path
00025 import rtctree.path
00026 import rtctree.tree
00027 import rtsprofile.rts_profile
00028 import sys
00029 import traceback
00030
00031 import actions
00032 import option_store
00033 import rtshell
00034
00035
00036 def check_required_component_actions(rtsprofile):
00037 checks = []
00038
00039
00040 for comp in [c for c in rtsprofile.components if c.is_required]:
00041 checks.append(actions.CheckForRequiredCompAct('/' + comp.path_uri,
00042 comp.id, comp.instance_name,
00043 callbacks=[actions.RequiredActionCB()]))
00044 return checks
00045
00046
00047 def get_data_conn_props(conn):
00048 return {'dataport.dataflow_type': str(conn.data_flow_type),
00049 'dataport.interface_type': str(conn.interface_type),
00050 'dataport.subscription_type': str(conn.subscription_type),
00051 'dataport.data_type': str(conn.data_type)}
00052
00053
00054 def clean_props(props):
00055 '''Clean properties of dangerous values and wrong data types.
00056
00057 Make sure the properties don't have IORs or similar in them, because
00058 they will confuse the notify_connect calls.
00059
00060 Make sure that all keys are not unicode.
00061
00062 '''
00063 new_props = {}
00064 for p in props:
00065 if p == 'dataport.corba_cdr.inport_ior':
00066 continue
00067 if p == 'dataport.corba_cdr.inport_ref':
00068 continue
00069 if p == 'dataport.corba_cdr.outport_ior':
00070 continue
00071 if p == 'dataport.corba_cdr.outport_ref':
00072 continue
00073 new_props[str(p)] = str(props[p])
00074 return new_props
00075
00076
00077 def data_connection_actions(rtsprofile):
00078
00079
00080 checks = []
00081 make_connections = []
00082 for conn in rtsprofile.required_data_connections():
00083 source_comp = rtsprofile.find_comp_by_target(conn.source_data_port)
00084 source_path = '/' + source_comp.path_uri
00085 source_port = conn.source_data_port.port_name
00086 prefix = source_comp.instance_name + '.'
00087 if source_port.startswith(prefix):
00088 source_port = source_port[len(prefix):]
00089 dest_comp = rtsprofile.find_comp_by_target(conn.target_data_port)
00090 dest_path = '/' + dest_comp.path_uri
00091 dest_port = conn.target_data_port.port_name
00092 prefix = dest_comp.instance_name + '.'
00093 if dest_port.startswith(prefix):
00094 dest_port = dest_port[len(prefix):]
00095 checks.append(actions.CheckForPortAct(source_path, source_port,
00096 callbacks=[actions.RequiredActionCB()]))
00097 checks.append(actions.CheckForPortAct(dest_path, dest_port,
00098 callbacks=[actions.RequiredActionCB()]))
00099 props = get_data_conn_props(conn)
00100 props.update(conn.properties)
00101 props = clean_props(props)
00102 make_connections.append(actions.ConnectPortsAct(source_path,
00103 source_port, dest_path, dest_port, str(conn.name),
00104 str(conn.connector_id), props,
00105 callbacks=[actions.RequiredActionCB()]))
00106
00107
00108 for conn in rtsprofile.optional_data_connections():
00109 source_comp = rtsprofile.find_comp_by_target(conn.source_data_port)
00110 source_path = '/' + source_comp.path_uri
00111 source_port = conn.source_data_port.port_name
00112 prefix = source_comp.instance_name + '.'
00113 if source_port.startswith(prefix):
00114 source_port = source_port[len(prefix):]
00115 dest_comp = rtsprofile.find_comp_by_target(conn.target_data_port)
00116 dest_path = '/' + dest_comp.path_uri
00117 dest_port = conn.target_data_port.port_name
00118 prefix = dest_comp.instance_name + '.'
00119 if dest_port.startswith(prefix):
00120 dest_port = dest_port[len(prefix):]
00121 props = get_data_conn_props(conn)
00122 props.update(conn.properties)
00123 props = clean_props(props)
00124 make_connections.append(actions.ConnectPortsAct(source_path,
00125 source_port, dest_path, dest_port, str(conn.name),
00126 str(conn.connector_id), props))
00127
00128 return checks, make_connections
00129
00130
00131 def service_connection_actions(rtsprofile):
00132
00133
00134 checks = []
00135 make_connections = []
00136 for conn in rtsprofile.required_service_connections():
00137 source_comp = rtsprofile.find_comp_by_target(conn.source_service_port)
00138 source_path = '/' + source_comp.path_uri
00139 source_port = conn.source_service_port.port_name
00140 prefix = source_comp.instance_name + '.'
00141 if source_port.startswith(prefix):
00142 source_port = source_port[len(prefix):]
00143 dest_comp = rtsprofile.find_comp_by_target(conn.target_service_port)
00144 dest_path = '/' + dest_comp.path_uri
00145 dest_port =conn.target_service_port.port_name
00146 prefix = dest_comp.instance_name + '.'
00147 if dest_port.startswith(prefix):
00148 dest_port = dest_port[len(prefix):]
00149 checks.append(actions.CheckForPortAct(source_path, source_port,
00150 callbacks=[actions.RequiredActionCB()]))
00151 checks.append(actions.CheckForPortAct(dest_path, dest_port,
00152 callbacks=[actions.RequiredActionCB()]))
00153 make_connections.append(actions.ConnectPortsAct(source_path,
00154 source_port, dest_path, dest_port, str(conn.name),
00155 str(conn.connector_id), {},
00156 callbacks=[actions.RequiredActionCB()]))
00157
00158
00159 for conn in rtsprofile.optional_service_connections():
00160 source_comp = rtsprofile.find_comp_by_target(conn.source_service_port)
00161 source_path = '/' + source_comp.path_uri
00162 source_port = conn.source_service_port.port_name
00163 prefix = source_comp.instance_name + '.'
00164 if source_port.startswith(prefix):
00165 source_port = source_port[len(prefix):]
00166 dest_comp = rtsprofile.find_comp_by_target(conn.target_service_port)
00167 dest_path = '/' + dest_comp.path_uri
00168 dest_port =conn.target_service_port.port_name
00169 prefix = dest_comp.instance_name + '.'
00170 if dest_port.startswith(prefix):
00171 dest_port = dest_port[len(prefix):]
00172 make_connections.append(actions.ConnectPortsAct(source_path,
00173 source_port, dest_path, dest_port, str(conn.name),
00174 str(conn.connector_id), {}))
00175
00176 return checks, make_connections
00177
00178
00179 def config_set_actions(rtsprofile):
00180 set_active = []
00181
00182 for comp in rtsprofile.components:
00183 if comp.active_configuration_set:
00184 set_active.append(actions.SetActiveConfigSetAct(
00185 '/' + comp.path_uri, comp.active_configuration_set))
00186
00187 set_values = []
00188 for comp in rtsprofile.components:
00189 for cs in comp.configuration_sets:
00190 for p in cs.configuration_data:
00191 set_values.append(actions.SetConfigParamValueAct(
00192 '/' + comp.path_uri, cs.id, p.name, p.data))
00193
00194 return set_values + set_active
00195
00196
00197 def rebuild_system_actions(rtsprofile):
00198 checks = check_required_component_actions(rtsprofile)
00199 data_conn_checks, data_connections = data_connection_actions(rtsprofile)
00200 svc_conn_checks, svc_connections = service_connection_actions(rtsprofile)
00201 config_actions = config_set_actions(rtsprofile)
00202
00203 return checks + data_conn_checks + svc_conn_checks + data_connections + \
00204 svc_connections + config_actions
00205
00206
00207 def resurrect(profile=None, xml=True, dry_run=False, tree=None):
00208
00209 if profile:
00210
00211 with open(profile) as f:
00212 if xml:
00213 rtsp = rtsprofile.rts_profile.RtsProfile(xml_spec=f)
00214 else:
00215 rtsp = rtsprofile.rts_profile.RtsProfile(yaml_spec=f)
00216 else:
00217
00218 lines = sys.stdin.read()
00219 if xml:
00220 rtsp = rtsprofile.rts_profile.RtsProfile(xml_spec=lines)
00221 else:
00222 rtsp = rtsprofile.rts_profile.RtsProfile(yaml_spec=lines)
00223
00224
00225 actions = rebuild_system_actions(rtsp)
00226 if dry_run:
00227 for a in actions:
00228 print a
00229 else:
00230 if not tree:
00231
00232 tree = rtctree.tree.RTCTree(paths=[rtctree.path.parse_path(
00233 '/' + c.path_uri)[0] for c in rtsp.components])
00234 for a in actions:
00235 a(tree)
00236
00237
00238 def main(argv=None, tree=None):
00239 usage = '''Usage: %prog [options] <RTSProfile file>
00240 Recreate an RT system using an RTSProfile.'''
00241 parser = optparse.OptionParser(usage=usage, version=rtshell.RTSH_VERSION)
00242 parser.add_option('--dry-run', dest='dry_run', action='store_true',
00243 default=False, help="Print what will be done but don't actually "
00244 "do anything. [Default: %default]")
00245 parser.add_option('-v', '--verbose', dest='verbose', action='store_true',
00246 default=False,
00247 help='Output verbose information. [Default: %default]')
00248 parser.add_option('-x', '--xml', dest='xml', action='store_true',
00249 default=True, help='Use XML input format. [Default: True]')
00250 parser.add_option('-y', '--yaml', dest='xml', action='store_false',
00251 help='Use YAML input format. [Default: False]')
00252
00253 if argv:
00254 sys.argv = [sys.argv[0]] + argv
00255 try:
00256 options, args = parser.parse_args()
00257 except optparse.OptionError, e:
00258 print >>sys.stderr, 'OptionError: ', e
00259 return 1
00260 option_store.OptionStore().verbose = options.verbose
00261
00262 if not args:
00263 profile = None
00264 elif len(args) == 1:
00265 profile = args[0]
00266 else:
00267 print >>sys.stderr, usage
00268 return 1
00269
00270 try:
00271 resurrect(profile=profile, xml=options.xml, dry_run=options.dry_run,
00272 tree=tree)
00273 except Exception, e:
00274 if options.verbose:
00275 traceback.print_exc()
00276 print >>sys.stderr, '{0}: {1}'.format(os.path.basename(sys.argv[0]), e)
00277 return 1
00278 return 0
00279
00280
00281