예제 #1
0
    def setUp(self):
        # Start container
        self._start_container()
        self.container.start_rel_from_url('res/deploy/r2deploy.yml')

        self.rrclient = ResourceRegistryServiceClient(node=self.container.node)
        self.omsclient = ObservatoryManagementServiceClient(node=self.container.node)
        self.imsclient = InstrumentManagementServiceClient(node=self.container.node)
        self.dmpsclient = DataProductManagementServiceClient(node=self.container.node)
        self.damsclient = DataAcquisitionManagementServiceClient(node=self.container.node)
        self.psmsclient = PubsubManagementServiceClient(node=self.container.node)
        self.dataset_management = DatasetManagementServiceClient()

        self.c = DotDict()
        self.c.resource_registry = self.rrclient
        self.resource_impl = ResourceImpl(self.c)
예제 #2
0
class TestDeployment(IonIntegrationTestCase):

    def setUp(self):
        # Start container
        self._start_container()
        self.container.start_rel_from_url('res/deploy/r2deploy.yml')

        self.rrclient = ResourceRegistryServiceClient(node=self.container.node)
        self.omsclient = ObservatoryManagementServiceClient(node=self.container.node)
        self.imsclient = InstrumentManagementServiceClient(node=self.container.node)
        self.dmpsclient = DataProductManagementServiceClient(node=self.container.node)
        self.damsclient = DataAcquisitionManagementServiceClient(node=self.container.node)
        self.psmsclient = PubsubManagementServiceClient(node=self.container.node)
        self.dataset_management = DatasetManagementServiceClient()

        self.c = DotDict()
        self.c.resource_registry = self.rrclient
        self.resource_impl = ResourceImpl(self.c)


    #@unittest.skip("targeting")
    def test_create_deployment(self):

        #create a deployment with metadata and an initial site and device
        platform_site__obj = IonObject(RT.PlatformSite,
                                        name='PlatformSite1',
                                        description='test platform site')
        site_id = self.omsclient.create_platform_site(platform_site__obj)

        platform_device__obj = IonObject(RT.PlatformDevice,
                                        name='PlatformDevice1',
                                        description='test platform device')
        device_id = self.imsclient.create_platform_device(platform_device__obj)

        start = IonTime(datetime.datetime(2013,1,1))
        end = IonTime(datetime.datetime(2014,1,1))
        temporal_bounds = IonObject(OT.TemporalBounds, name='planned', start_datetime=start.to_string(), end_datetime=end.to_string())
        deployment_obj = IonObject(RT.Deployment,
                                        name='TestDeployment',
                                        description='some new deployment',
                                        constraint_list=[temporal_bounds])
        deployment_id = self.omsclient.create_deployment(deployment_obj)
        self.omsclient.deploy_platform_site(site_id, deployment_id)
        self.imsclient.deploy_platform_device(device_id, deployment_id)

        log.debug("test_create_deployment: created deployment id: %s ", str(deployment_id) )

        #retrieve the deployment objects and check that the assoc site and device are attached
        read_deployment_obj = self.omsclient.read_deployment(deployment_id)
        log.debug("test_create_deployment: created deployment obj: %s ", str(read_deployment_obj) )

        site_ids, _ = self.rrclient.find_subjects(RT.PlatformSite, PRED.hasDeployment, deployment_id, True)
        self.assertEqual(len(site_ids), 1)

        device_ids, _ = self.rrclient.find_subjects(RT.PlatformDevice, PRED.hasDeployment, deployment_id, True)
        self.assertEqual(len(device_ids), 1)

        #delete the deployment
        self.resource_impl.pluck(deployment_id)
        self.omsclient.force_delete_deployment(deployment_id)
        # now try to get the deleted dp object
        try:
            deployment_obj = self.omsclient.read_deployment(deployment_id)
        except NotFound:
            pass
        else:
            self.fail("deleted deployment was found during read")




    #@unittest.skip("targeting")
    def test_activate_deployment(self):

        #-------------------------------------------------------------------------------------
        # Create platform site, platform device, platform model
        #-------------------------------------------------------------------------------------

        platform_site__obj = IonObject(RT.PlatformSite,
                                        name='PlatformSite1',
                                        description='test platform site')
        site_id = self.omsclient.create_platform_site(platform_site__obj)

        platform_device_obj = IonObject(RT.PlatformDevice,
                                        name='PlatformDevice1',
                                        description='test platform device')
        platform_device_id = self.imsclient.create_platform_device(platform_device_obj)

        platform_model__obj = IonObject(RT.PlatformModel,
                                        name='PlatformModel1',
                                        description='test platform model')
        model_id = self.imsclient.create_platform_model(platform_model__obj)

        #-------------------------------------------------------------------------------------
        # Assign platform model to platform device and site
        #-------------------------------------------------------------------------------------

        self.imsclient.assign_platform_model_to_platform_device(model_id, platform_device_id)
        self.omsclient.assign_platform_model_to_platform_site(model_id, site_id)


        #-------------------------------------------------------------------------------------
        # Create instrument site
        #-------------------------------------------------------------------------------------

        instrument_site_obj = IonObject(RT.InstrumentSite,
                                        name='InstrumentSite1',
                                        description='test instrument site')
        instrument_site_id = self.omsclient.create_instrument_site(instrument_site_obj, site_id)

        pdict_id = self.dataset_management.read_parameter_dictionary_by_name('ctd_parsed_param_dict', id_only=True)
        ctd_stream_def_id = self.psmsclient.create_stream_definition(name='SBE37_CDM', parameter_dictionary_id=pdict_id)


        # Construct temporal and spatial Coordinate Reference System objects
        tdom, sdom = time_series_domain()

        sdom = sdom.dump()
        tdom = tdom.dump()



        dp_obj = IonObject(RT.DataProduct,
            name='Log Data Product',
            description='some new dp',
            temporal_domain = tdom,
            spatial_domain = sdom)

        out_log_data_product_id = self.dmpsclient.create_data_product(dp_obj, ctd_stream_def_id)

        #----------------------------------------------------------------------------------------------------
        # Start the transform (a logical transform) that acts as an instrument site
        #----------------------------------------------------------------------------------------------------

        self.omsclient.create_site_data_product(    site_id= instrument_site_id,
                                                    data_product_id =  out_log_data_product_id)


        #----------------------------------------------------------------------------------------------------
        # Create an instrument device
        #----------------------------------------------------------------------------------------------------

        instrument_device_obj = IonObject(RT.InstrumentDevice,
                                        name='InstrumentDevice1',
                                        description='test instrument device')
        instrument_device_id = self.imsclient.create_instrument_device(instrument_device_obj)
        self.rrclient.create_association(platform_device_id, PRED.hasDevice, instrument_device_id)


        dp_obj = IonObject(RT.DataProduct,
            name='Instrument Data Product',
            description='some new dp',
            temporal_domain = tdom,
            spatial_domain = sdom)

        inst_data_product_id = self.dmpsclient.create_data_product(dp_obj, ctd_stream_def_id)

        #assign data products appropriately
        self.damsclient.assign_data_product(input_resource_id=instrument_device_id,
                                            data_product_id=inst_data_product_id)
        #----------------------------------------------------------------------------------------------------
        # Create an instrument model
        #----------------------------------------------------------------------------------------------------

        instrument_model_obj = IonObject(RT.InstrumentModel,
                                        name='InstrumentModel1',
                                        description='test instrument model')
        instrument_model_id = self.imsclient.create_instrument_model(instrument_model_obj)
        self.imsclient.assign_instrument_model_to_instrument_device(instrument_model_id, instrument_device_id)
        self.omsclient.assign_instrument_model_to_instrument_site(instrument_model_id, instrument_site_id)

        #----------------------------------------------------------------------------------------------------
        # Create a deployment object
        #----------------------------------------------------------------------------------------------------

        start = IonTime(datetime.datetime(2013,1,1))
        end = IonTime(datetime.datetime(2014,1,1))
        temporal_bounds = IonObject(OT.TemporalBounds, name='planned', start_datetime=start.to_string(), end_datetime=end.to_string())
        deployment_obj = IonObject(RT.Deployment,
                                        name='TestDeployment',
                                        description='some new deployment',
                                        constraint_list=[temporal_bounds])
        deployment_id = self.omsclient.create_deployment(deployment_obj)
        self.omsclient.deploy_instrument_site(instrument_site_id, deployment_id)
        self.imsclient.deploy_instrument_device(instrument_device_id, deployment_id)

        log.debug("test_create_deployment: created deployment id: %s ", str(deployment_id) )

        self.omsclient.activate_deployment(deployment_id)
예제 #3
0
    def template_tst_deployment_context(self, context=None):
        """
        Creates a minimal deployment: 1 instrument, 1 site.  deployment context must be provided
        """
        c = self.client

        c2 = DotDict()
        c2.resource_registry = self.client.RR
        instrument_site_impl = InstrumentSiteImpl(c2)
        resource_impl = ResourceImpl(c2)

        log.info("Create a instrument model")
        instrument_model_id = self.generic_fcruf_script(RT.InstrumentModel,
                                                      "instrument_model",
                                                      self.client.IMS,
                                                      True)

        log.info("Create an instrument device")
        instrument_device_id = self.generic_fcruf_script(RT.InstrumentDevice,
                                                         "instrument_device",
                                                         self.client.IMS,
                                                         False)

        log.info("Create instrument site")
        instrument_site_id = self.generic_fcruf_script(RT.InstrumentSite,
                                                       "instrument_site",
                                                       self.client.OMS,
                                                       True)

        log.info("Associate instrument model with instrument site")
        self.generic_association_script(c.OMS.assign_instrument_model_to_instrument_site,
                                        instrument_site_impl.find_having_model,
                                        instrument_site_impl.find_stemming_model,
                                        instrument_site_id,
                                        instrument_model_id)


        log.info("Associate instrument model with instrument device")
        self.generic_association_script(c.IMS.assign_instrument_model_to_instrument_device,
                                        c.IMS.find_instrument_device_by_instrument_model,
                                        c.IMS.find_instrument_model_by_instrument_device,
                                        instrument_device_id,
                                        instrument_model_id)


        log.info("Create a stream definition for the data from the ctd simulator")
        pdict_id = self.dataset_management.read_parameter_dictionary_by_name('ctd_parsed_param_dict', id_only=True)
        ctd_stream_def_id = self.client.PSMS.create_stream_definition(name='Simulated CTD data', parameter_dictionary_id=pdict_id)

        log.info("Create an IonObject for a data products")
        dp_obj = self.create_data_product_obj()

        dp_obj.name = create_unique_identifier('Inst Data Product')
        inst_data_product_id = c.DPMS.create_data_product(dp_obj, ctd_stream_def_id)

        dp_obj.name = create_unique_identifier('Log Data Product')
        log_data_product_id = c.DPMS.create_data_product(dp_obj, ctd_stream_def_id)

        #assign data products appropriately
        c.DAMS.assign_data_product(input_resource_id=instrument_device_id,
                                   data_product_id=inst_data_product_id)
        c.OMS.create_site_data_product(instrument_site_id, log_data_product_id)


        deployment_obj = any_old(RT.Deployment, dict(context=context))
        deployment_id = c.OMS.create_deployment(deployment_obj)

        c.OMS.deploy_instrument_site(instrument_site_id, deployment_id)
        c.IMS.deploy_instrument_device(instrument_device_id, deployment_id)

        c.OMS.activate_deployment(deployment_id, True)

        # cleanup
        resource_impl.pluck(instrument_model_id)
        resource_impl.pluck(deployment_id)
        resource_impl.pluck(instrument_device_id)
        c.IMS.force_delete_instrument_model(instrument_model_id)
        c.IMS.force_delete_instrument_device(instrument_device_id)
        c.OMS.force_delete_instrument_site(instrument_site_id)
        c.OMS.force_delete_deployment(deployment_id)
    def test_resources_associations_extensions(self):
        """
        create one of each resource and association used by IMS
        to guard against problems in ion-definitions
        """
        
        #stuff we control
        instrument_agent_instance_id, _ =  self.RR.create(any_old(RT.InstrumentAgentInstance))
        instrument_agent_id, _ =           self.RR.create(any_old(RT.InstrumentAgent))
        instrument_model_id, _ =           self.RR.create(any_old(RT.InstrumentModel))
        instrument_device_id, _ =          self.RR.create(any_old(RT.InstrumentDevice))
        platform_agent_instance_id, _ =    self.RR.create(any_old(RT.PlatformAgentInstance))
        platform_agent_id, _ =             self.RR.create(any_old(RT.PlatformAgent))
        platform_device_id, _ =            self.RR.create(any_old(RT.PlatformDevice))
        platform_model_id, _ =             self.RR.create(any_old(RT.PlatformModel))
        sensor_device_id, _ =              self.RR.create(any_old(RT.SensorDevice))
        sensor_model_id, _ =               self.RR.create(any_old(RT.SensorModel))

        #stuff we associate to
        data_producer_id, _      = self.RR.create(any_old(RT.DataProducer))
        org_id, _ =                self.RR.create(any_old(RT.Org))

        #instrument_agent_instance_id #is only a target
        
        #instrument_agent
        self.RR.create_association(instrument_agent_id, PRED.hasModel, instrument_model_id)
        self.RR.create_association(instrument_agent_instance_id, PRED.hasAgentDefinition, instrument_agent_id)

        #instrument_device
        self.RR.create_association(instrument_device_id, PRED.hasModel, instrument_model_id)
        self.RR.create_association(instrument_device_id, PRED.hasAgentInstance, instrument_agent_instance_id)
        self.RR.create_association(instrument_device_id, PRED.hasDataProducer, data_producer_id)
        self.RR.create_association(instrument_device_id, PRED.hasDevice, sensor_device_id)
        self.RR.create_association(org_id, PRED.hasResource, instrument_device_id)


        instrument_model_id #is only a target

        platform_agent_instance_id #is only a target
        
        #platform_agent
        self.RR.create_association(platform_agent_id, PRED.hasModel, platform_model_id)
        self.RR.create_association(platform_agent_instance_id, PRED.hasAgentDefinition, platform_agent_id)

        #platform_device
        self.RR.create_association(platform_device_id, PRED.hasModel, platform_model_id)
        self.RR.create_association(platform_device_id, PRED.hasAgentInstance, platform_agent_instance_id)
        self.RR.create_association(platform_device_id, PRED.hasDevice, instrument_device_id)

        platform_model_id #is only a target

        #sensor_device
        self.RR.create_association(sensor_device_id, PRED.hasModel, sensor_model_id)
        self.RR.create_association(sensor_device_id, PRED.hasDevice, instrument_device_id)

        sensor_model_id #is only a target

        #create a parsed product for this instrument output
        tdom, sdom = time_series_domain()
        tdom = tdom.dump()
        sdom = sdom.dump()
        dp_obj = IonObject(RT.DataProduct,
            name='the parsed data',
            description='ctd stream test',
            processing_level_code='Parsed_Canonical',
            temporal_domain = tdom,
            spatial_domain = sdom)
        pdict_id = self.DSC.read_parameter_dictionary_by_name('ctd_parsed_param_dict', id_only=True)
        parsed_stream_def_id = self.PSC.create_stream_definition(name='parsed', parameter_dictionary_id=pdict_id)
        data_product_id1 = self.DP.create_data_product(data_product=dp_obj, stream_definition_id=parsed_stream_def_id)
        log.debug( 'new dp_id = %s', data_product_id1)

        self.DAMS.assign_data_product(input_resource_id=instrument_device_id, data_product_id=data_product_id1)


        def addInstOwner(inst_id, subject):

            actor_identity_obj = any_old(RT.ActorIdentity, {"name": subject})
            user_id = self.IDS.create_actor_identity(actor_identity_obj)
            user_info_obj = any_old(RT.UserInfo)
            user_info_id = self.IDS.create_user_info(user_id, user_info_obj)

            self.RR.create_association(inst_id, PRED.hasOwner, user_id)


        #Testing multiple instrument owners
        addInstOwner(instrument_device_id, "/DC=org/DC=cilogon/C=US/O=ProtectNetwork/CN=Roger Unwin A254")
        addInstOwner(instrument_device_id, "/DC=org/DC=cilogon/C=US/O=ProtectNetwork/CN=Bob Cumbers A256")

        extended_instrument = self.IMS.get_instrument_device_extension(instrument_device_id)

        self.assertEqual(instrument_device_id, extended_instrument._id)
        self.assertEqual(len(extended_instrument.owners), 2)
        self.assertEqual(extended_instrument.instrument_model._id, instrument_model_id)


        #check model
        inst_model_obj = self.RR.read(instrument_model_id)
        self.assertEqual(inst_model_obj.name, extended_instrument.instrument_model.name)

        #check agent instance
        inst_agent_instance_obj = self.RR.read(instrument_agent_instance_id)
        self.assertEqual(inst_agent_instance_obj.name, extended_instrument.agent_instance.name)

        #check agent
        inst_agent_obj = self.RR.read(instrument_agent_id)
        #compound assoc return list of lists so check the first element
        self.assertEqual(inst_agent_obj.name, extended_instrument.instrument_agent[0].name)

        #check platform device
        plat_device_obj = self.RR.read(platform_device_id)
        self.assertEqual(plat_device_obj.name, extended_instrument.platform_device.name)

        #check sensor devices
        self.assertEqual(1, len(extended_instrument.sensor_devices))

        #check data_product_parameters_set
        self.assertEqual(ComputedValueAvailability.PROVIDED,
                         extended_instrument.computed.data_product_parameters_set.status)
        self.assertTrue( 'Parsed_Canonical' in extended_instrument.computed.data_product_parameters_set.value)
        # the ctd parameters should include 'temp'
        self.assertTrue( 'temp' in extended_instrument.computed.data_product_parameters_set.value['Parsed_Canonical'])

        #none of these will work because there is no agent
        self.assertEqual(ComputedValueAvailability.NOTAVAILABLE,
                         extended_instrument.computed.firmware_version.status)
        self.assertEqual(ComputedValueAvailability.NOTAVAILABLE,
                         extended_instrument.computed.operational_state.status)
        self.assertEqual(ComputedValueAvailability.PROVIDED,
                         extended_instrument.computed.power_status_roll_up.status)
        self.assertEqual(ComputedValueAvailability.PROVIDED,
                         extended_instrument.computed.communications_status_roll_up.status)
        self.assertEqual(ComputedValueAvailability.PROVIDED,
                         extended_instrument.computed.data_status_roll_up.status)
        self.assertEqual(StatusType.STATUS_OK,
                        extended_instrument.computed.data_status_roll_up.value)
        self.assertEqual(ComputedValueAvailability.PROVIDED,
                         extended_instrument.computed.location_status_roll_up.status)

#        self.assertEqual(ComputedValueAvailability.PROVIDED,
#                         extended_instrument.computed.recent_events.status)
#        self.assertEqual([], extended_instrument.computed.recent_events.value)


        # cleanup
        c = DotDict()
        c.resource_registry = self.RR
        resource_impl = ResourceImpl(c)
        resource_impl.pluck(instrument_agent_id)
        resource_impl.pluck(instrument_model_id)
        resource_impl.pluck(instrument_device_id)
        resource_impl.pluck(platform_agent_id)
        self.IMS.force_delete_instrument_agent(instrument_agent_id)
        self.IMS.force_delete_instrument_model(instrument_model_id)
        self.IMS.force_delete_instrument_device(instrument_device_id)
        self.IMS.force_delete_platform_agent_instance(platform_agent_instance_id)
        self.IMS.force_delete_platform_agent(platform_agent_id)
        self.IMS.force_delete_platform_device(platform_device_id)
        self.IMS.force_delete_platform_model(platform_model_id)
        self.IMS.force_delete_sensor_device(sensor_device_id)
        self.IMS.force_delete_sensor_model(sensor_model_id)

        #stuff we associate to
        self.RR.delete(data_producer_id)
        self.RR.delete(org_id)
예제 #5
0
    def test_observatory_structure(self):
        """

        """

        c = self.client

        c2 = DotDict()
        c2.resource_registry = self.client.RR

        instrument_site_impl    = InstrumentSiteImpl(c2)
        platform_site_impl      = PlatformSiteImpl(c2)
        platform_agent_impl     = PlatformAgentImpl(c2)
        instrument_device_impl  = InstrumentDeviceImpl(c2)
        sensor_device_impl      = SensorDeviceImpl(c2)
        resource_impl           = ResourceImpl(c2)


        #generate a function that finds direct associations, using the more complex one in the service
        def gen_find_oms_association(output_type):
            def freeze():
                def finder_fun(obj_id):
                    ret = c.OMS.find_related_frames_of_reference(obj_id, [output_type])
                    return ret[output_type]
                return finder_fun
            
            return freeze()


        #resource_ids = self._low_level_init()


        ###############################################
        #
        # Assumptions or Order of Events for R2 Preloaded resources
        #
        # - orgs
        # - sites
        # - models
        # - agents
        # - devices
        # - instances
        # - attachments
        #
        ###############################################


        ###############################################
        #
        # orgs
        #
        ###############################################


        ###############################################
        #
        # sites
        #
        ###############################################

        log.info("Create an observatory")
        observatory_id = self.generic_fcruf_script(RT.Observatory, 
                                          "observatory", 
                                          self.client.OMS, 
                                          True)

        log.info("Create a subsite")
        subsite_id = self.generic_fcruf_script(RT.Subsite,
                                            "subsite",
                                            self.client.OMS,
                                            True)

        log.info("Create a platform site")
        platform_site_id = self.generic_fcruf_script(RT.PlatformSite,
                                                     "platform_site",
                                                     self.client.OMS,
                                                     True)
        
        log.info("Create instrument site")
        instrument_site_id = self.generic_fcruf_script(RT.InstrumentSite,
                                                       "instrument_site",
                                                       self.client.OMS,
                                                       True)
        
        ###############################################
        #
        # models
        #
        ###############################################

        log.info("Create a platform model")
        platform_model_id = self.generic_fcruf_script(RT.PlatformModel, 
                                                     "platform_model", 
                                                     self.client.IMS, 
                                                     True)

        log.info("Create instrument model")
        instModel_obj = IonObject(RT.InstrumentModel,
                                  name='SBE37IMModel',
                                  description="SBE37IMModel",
                                  custom_attributes= {'streams':{'raw': 'ctd_raw_param_dict' ,
                                                                 'parsed': 'ctd_parsed_param_dict' }})
        instrument_model_id = self.generic_fcruf_script(RT.InstrumentModel,
                                                        "instrument_model", 
                                                        self.client.IMS, 
                                                        True,
                                                        actual_obj=instModel_obj)

        log.info("Create sensor model")
        sensor_model_id = self.generic_fcruf_script(RT.SensorModel, 
                                                        "sensor_model", 
                                                        self.client.IMS, 
                                                        True)


        ###############################################
        #
        # agents
        #
        ###############################################

        log.info("Create platform agent")
        platform_agent_id = self.generic_fcruf_script(RT.PlatformAgent, 
                                                      "platform_agent", 
                                                      self.client.IMS, 
                                                      False)
        
        log.info("Create instrument agent")
        instAgent_obj = IonObject(RT.InstrumentAgent,
                                  name='agent007',
                                  description="SBE37IMAgent",
                                  driver_module="mi.instrument.seabird.sbe37smb.ooicore.driver",
                                  driver_class="SBE37Driver" )
        instrument_agent_id = self.generic_fcruf_script(RT.InstrumentAgent,
                                                        "instrument_agent", 
                                                        self.client.IMS, 
                                                        False,
                                                        actual_obj=instAgent_obj)


        ###############################################
        #
        # devices
        #
        ###############################################

        log.info("Create a platform device")
        platform_device_id = self.generic_fcruf_script(RT.PlatformDevice, 
                                                    "platform_device", 
                                                    self.client.IMS, 
                                                    False)
        log.info("Create an instrument device")
        instrument_device_id = self.generic_fcruf_script(RT.InstrumentDevice, 
                                                         "instrument_device", 
                                                         self.client.IMS, 
                                                         False)

        log.info("Create a sensor device")
        sensor_device_id = self.generic_fcruf_script(RT.SensorDevice, 
                                                         "sensor_device", 
                                                         self.client.IMS, 
                                                         False)




        ###############################################
        #
        # instances
        #
        ###############################################

        # we create instrument agent instance below, to verify some lcs checks


        ###############################################
        #
        #
        # attachments and LCS stuff
        #
        #
        ###############################################
        
        #----------------------------------------------
        #
        # orgs
        #
        #----------------------------------------------
        
        #----------------------------------------------
        #
        # sites
        #
        #----------------------------------------------

        log.info("Associate subsite with observatory")
        self.generic_association_script(c.OMS.assign_site_to_site,
                                        gen_find_oms_association(RT.Observatory),
                                        gen_find_oms_association(RT.Subsite),
                                        observatory_id,
                                        subsite_id)

        log.info("Associate platform site with subsite")
        self.generic_association_script(c.OMS.assign_site_to_site,
                                        gen_find_oms_association(RT.Subsite),
                                        gen_find_oms_association(RT.PlatformSite),
                                        subsite_id,
                                        platform_site_id)

        log.info("Associate instrument site with platform site")
        self.generic_association_script(c.OMS.assign_site_to_site,
                                        gen_find_oms_association(RT.PlatformSite),
                                        gen_find_oms_association(RT.InstrumentSite),
                                        platform_site_id,
                                        instrument_site_id)

        
        
        #----------------------------------------------
        #
        # models
        #
        #----------------------------------------------
        
        log.info("Associate platform model with platform site")
        self.generic_association_script(c.OMS.assign_platform_model_to_platform_site,
                                        platform_site_impl.find_having_model,
                                        platform_site_impl.find_stemming_model,
                                        platform_site_id,
                                        platform_model_id)

        log.info("Associate instrument model with instrument site")
        self.generic_association_script(c.OMS.assign_instrument_model_to_instrument_site,
                                        instrument_site_impl.find_having_model,
                                        instrument_site_impl.find_stemming_model,
                                        instrument_site_id,
                                        instrument_model_id)


        #----------------------------------------------
        #
        # agents
        #
        # - model required for DEVELOP
        # - egg required for INTEGRATE
        # - certification required for DEPLOY 
        #----------------------------------------------
        
        self.generic_lcs_pass(self.client.IMS, "platform_agent", platform_agent_id, LCE.PLAN, LCS.PLANNED)
        self.generic_lcs_fail(self.client.IMS, "platform_agent", platform_agent_id, LCE.DEVELOP)
        log.info("Associate platform model with platform agent")
        self.generic_association_script(c.IMS.assign_platform_model_to_platform_agent,
                                        platform_agent_impl.find_having_model,
                                        platform_agent_impl.find_stemming_model,
                                        platform_agent_id,
                                        platform_model_id)
        self.generic_lcs_pass(self.client.IMS, "platform_agent", platform_agent_id, LCE.DEVELOP, LCS.DEVELOPED)
        self.generic_lcs_fail(self.client.IMS, "platform_agent", platform_agent_id, LCE.INTEGRATE)
        add_keyworded_attachment(self.client.RR, platform_agent_id, [KeywordFlag.EGG_URL])
        self.generic_lcs_pass(self.client.IMS, "platform_agent", platform_agent_id, LCE.INTEGRATE, LCS.INTEGRATED)
        self.generic_lcs_fail(self.client.IMS, "platform_agent", platform_agent_id, LCE.DEPLOY)
        add_keyworded_attachment(self.client.RR, platform_agent_id, [KeywordFlag.CERTIFICATION, "platform attachment"])
        self.generic_lcs_pass(self.client.IMS, "platform_agent", platform_agent_id, LCE.DEPLOY, LCS.DEPLOYED)


        self.generic_lcs_pass(self.client.IMS, "instrument_agent", instrument_agent_id, LCE.PLAN, LCS.PLANNED)
        self.generic_lcs_fail(self.client.IMS, "instrument_agent", instrument_agent_id, LCE.DEVELOP)
        log.info("Associate instrument model with instrument agent")
        self.generic_association_script(c.IMS.assign_instrument_model_to_instrument_agent,
                                        c.IMS.find_instrument_agent_by_instrument_model,
                                        c.IMS.find_instrument_model_by_instrument_agent,
                                        instrument_agent_id,
                                        instrument_model_id)
        self.generic_lcs_pass(self.client.IMS, "instrument_agent", instrument_agent_id, LCE.DEVELOP, LCS.DEVELOPED)

        self.generic_lcs_fail(self.client.IMS, "instrument_agent", instrument_agent_id, LCE.INTEGRATE)
        add_keyworded_attachment(self.client.RR, instrument_agent_id, [KeywordFlag.EGG_URL])
        self.generic_lcs_pass(self.client.IMS, "instrument_agent", instrument_agent_id, LCE.INTEGRATE, LCS.INTEGRATED)
        self.generic_lcs_fail(self.client.IMS, "instrument_agent", instrument_agent_id, LCE.DEPLOY)
        add_keyworded_attachment(self.client.RR, instrument_agent_id, [KeywordFlag.CERTIFICATION])
        self.generic_lcs_pass(self.client.IMS, "instrument_agent", instrument_agent_id, LCE.DEPLOY, LCS.DEPLOYED)


        #----------------------------------------------
        #
        # devices
        #
        #----------------------------------------------

        log.info("LCS plan")
        self.generic_lcs_pass(self.client.IMS, "platform_device", platform_device_id, LCE.PLAN, LCS.PLANNED)

        log.info("LCS develop")
        self.generic_lcs_fail(self.client.IMS, "platform_device", platform_device_id, LCE.DEVELOP)
        x = self.client.IMS.read_platform_device(platform_device_id)
        x.serial_number = "12345"
        self.client.IMS.update_platform_device(x)
        self.generic_lcs_fail(self.client.IMS, "platform_device", platform_device_id, LCE.DEVELOP)
        log.info("Associate platform model with platform device")
        self.generic_lcs_fail(self.client.IMS, "platform_device", platform_device_id, LCE.DEVELOP)
        self.generic_association_script(c.IMS.assign_platform_model_to_platform_device,
                                        c.IMS.find_platform_device_by_platform_model,
                                        c.IMS.find_platform_model_by_platform_device,
                                        platform_device_id,
                                        platform_model_id)
        self.generic_lcs_fail(self.client.IMS, "platform_device", platform_device_id, LCE.DEVELOP)
        add_keyworded_attachment(self.client.RR, platform_device_id, [KeywordFlag.VENDOR_TEST_RESULTS])
        self.generic_lcs_pass(self.client.IMS, "platform_device", platform_device_id, LCE.DEVELOP, LCS.DEVELOPED)

        log.info("LCS integrate")
        self.generic_lcs_fail(self.client.IMS, "platform_device", platform_device_id, LCE.INTEGRATE)
        add_keyworded_attachment(self.client.RR, platform_device_id, [KeywordFlag.VENDOR_TEST_RESULTS])
        self.generic_lcs_fail(self.client.IMS, "platform_device", platform_device_id, LCE.INTEGRATE)
        platform_agent_instance_id = self.create_plat_agent_instance(platform_agent_id, platform_device_id)
        self.generic_lcs_pass(self.client.IMS, "platform_device", platform_device_id, LCE.INTEGRATE, LCS.INTEGRATED)


        log.info("LCS deploy")
        self.generic_lcs_fail(self.client.IMS, "platform_device", platform_device_id, LCE.DEPLOY)




        log.info("LCS plan")
        self.generic_lcs_pass(self.client.IMS, "instrument_device", instrument_device_id, LCE.PLAN, LCS.PLANNED)

        log.info("LCS develop")
        self.generic_lcs_fail(self.client.IMS, "instrument_device", instrument_device_id, LCE.DEVELOP)
        x = self.client.IMS.read_instrument_device(instrument_device_id)
        x.serial_number = "12345"
        self.client.IMS.update_instrument_device(x)
        self.generic_lcs_fail(self.client.IMS, "instrument_device", instrument_device_id, LCE.DEVELOP)
        log.info("Associate instrument model with instrument device")
        self.generic_association_script(c.IMS.assign_instrument_model_to_instrument_device,
                                        c.IMS.find_instrument_device_by_instrument_model,
                                        c.IMS.find_instrument_model_by_instrument_device,
                                        instrument_device_id,
                                        instrument_model_id)
        self.generic_lcs_fail(self.client.IMS, "instrument_device", instrument_device_id, LCE.DEVELOP)
        add_keyworded_attachment(self.client.RR, instrument_device_id, [KeywordFlag.VENDOR_TEST_RESULTS])
        self.generic_lcs_pass(self.client.IMS, "instrument_device", instrument_device_id, LCE.DEVELOP, LCS.DEVELOPED)

        log.info("LCS integrate")
        self.generic_lcs_fail(self.client.IMS, "instrument_device", instrument_device_id, LCE.INTEGRATE)
        log.info("Associate instrument device with platform device")
        self.generic_association_script(c.IMS.assign_instrument_device_to_platform_device,
                                        c.IMS.find_platform_device_by_instrument_device,
                                        c.IMS.find_instrument_device_by_platform_device,
                                        platform_device_id,
                                        instrument_device_id)
        self.generic_lcs_fail(self.client.IMS, "instrument_device", instrument_device_id, LCE.INTEGRATE)
        log.info("Create instrument agent instance")
        instrument_agent_instance_id = self.create_inst_agent_instance(instrument_agent_id, instrument_device_id)
        self.generic_lcs_pass(self.client.IMS, "instrument_device", instrument_device_id, LCE.INTEGRATE, LCS.INTEGRATED)

        log.info("LCS deploy")
        self.generic_lcs_fail(self.client.IMS, "instrument_device", instrument_device_id, LCE.DEPLOY)





        log.info("Associate sensor model with sensor device")
        self.generic_association_script(c.IMS.assign_sensor_model_to_sensor_device,
                                        sensor_device_impl.find_having_model,
                                        sensor_device_impl.find_stemming_model,
                                        sensor_device_id,
                                        sensor_model_id)



        log.info("Associate sensor device with instrument device")
        self.generic_association_script(c.IMS.assign_sensor_device_to_instrument_device,
                                        instrument_device_impl.find_having_device,
                                        instrument_device_impl.find_stemming_device,
                                        instrument_device_id,
                                        sensor_device_id)


        #----------------------------------------------
        #
        # instances
        #
        #----------------------------------------------






        #----------------------------------------------
        #
        # data production chain and swapping
        #
        #----------------------------------------------

        #------------------------------------------------------------------------------------------------
        # create a stream definition for the data from the ctd simulator
        #------------------------------------------------------------------------------------------------
        pdict_id = self.dataset_management.read_parameter_dictionary_by_name('ctd_parsed_param_dict', id_only=True)
        ctd_stream_def_id = self.client.PSMS.create_stream_definition(name='Simulated CTD data', parameter_dictionary_id=pdict_id)
        log.debug("Created stream def id %s", ctd_stream_def_id)


        #create data products for instrument data

        dp_obj = self.create_data_product_obj()

        log.debug("Created an IonObject for a data product: %s", dp_obj)

        #------------------------------------------------------------------------------------------------
        # Create a set of ParameterContext objects to define the parameters in the coverage, add each to the ParameterDictionary
        #------------------------------------------------------------------------------------------------

        dp_obj.name = 'Data Product'
        inst_data_product_id = c.DPMS.create_data_product(dp_obj, ctd_stream_def_id)

        dp_obj.name = 'Log Data Product'
        log_data_product_id = c.DPMS.create_data_product(dp_obj, ctd_stream_def_id)

        #assign data products appropriately
        c.DAMS.assign_data_product(input_resource_id=instrument_device_id,
                                   data_product_id=inst_data_product_id)
        c.OMS.create_site_data_product(instrument_site_id, log_data_product_id)

        deployment_id = self.generic_fcruf_script(RT.Deployment, "deployment", c.OMS, False)

        c.OMS.deploy_platform_site(platform_site_id, deployment_id)
        c.IMS.deploy_platform_device(platform_device_id, deployment_id)

        c.OMS.deploy_instrument_site(instrument_site_id, deployment_id)
        c.IMS.deploy_instrument_device(instrument_device_id, deployment_id)

        c.OMS.activate_deployment(deployment_id, True)
        self.assertLess(0, len(instrument_site_impl.find_having_device(instrument_device_id)))
        self.assertLess(0, len(instrument_site_impl.find_stemming_device(instrument_site_id)))
        self.assertLess(0, len(platform_site_impl.find_having_device(platform_device_id)))
        self.assertLess(0, len(platform_site_impl.find_stemming_device(platform_site_id)))

        self.generic_lcs_pass(self.client.IMS, "platform_device", platform_device_id, LCE.DEPLOY, LCS.DEPLOYED)
        self.generic_lcs_pass(self.client.IMS, "instrument_device", instrument_device_id, LCE.DEPLOY, LCS.DEPLOYED)

        #now along comes a new device
        log.info("Create instrument device 2")
        instrument_device_id2 = self.generic_fcruf_script(RT.InstrumentDevice,
                                                         "instrument_device",
                                                         self.client.IMS,
                                                         False)
        log.info("Associate instrument model with instrument device 2")
        self.generic_association_script(c.IMS.assign_instrument_model_to_instrument_device,
                                        c.IMS.find_instrument_device_by_instrument_model,
                                        c.IMS.find_instrument_model_by_instrument_device,
                                        instrument_device_id2,
                                        instrument_model_id)
        log.info("Associate instrument device with platform device 2")
        self.generic_association_script(c.IMS.assign_instrument_device_to_platform_device,
                                    c.IMS.find_platform_device_by_instrument_device,
                                    c.IMS.find_instrument_device_by_platform_device,
                                    platform_device_id,
                                    instrument_device_id2)
        dp_obj.name = 'Instrument Data Product 2'
        inst_data_product_id2 = c.DPMS.create_data_product(dp_obj, ctd_stream_def_id)
        c.DAMS.assign_data_product(input_resource_id=instrument_device_id2,
                                   data_product_id=inst_data_product_id2)

        # create a new deployment for the new device
        deployment_id2 = self.generic_fcruf_script(RT.Deployment, "deployment", c.OMS, False)
        log.debug("Associating instrument site with new deployment")
        c.OMS.deploy_instrument_site(instrument_site_id, deployment_id2)
        log.debug("Associating instrument device with new deployment")
        c.IMS.deploy_instrument_device(instrument_device_id2, deployment_id2)

        # activate the new deployment -- changing the primary device -- but don't switch subscription
        log.debug("Activating new deployment")
        c.OMS.activate_deployment(deployment_id2, False)
        #todo: assert site hasDevice instrument_device_id2
        assocs = self.client.RR.find_associations(instrument_site_id, PRED.hasDevice, instrument_device_id2, id_only=True)
        self.assertIsNotNone(assocs)

        log.debug("L4-CI-SA-RQ-334 DEPLOY: Proposed change - Instrument activation shall support transition to the active state for instruments")

        log.debug("Transferring site subscriptions")
        c.OMS.transfer_site_subscription(instrument_site_id)

        #----------------------------------------------
        #
        # generic find ops
        #
        #----------------------------------------------



        log.info("Find an instrument site by observatory")

        entities = c.OMS.find_related_frames_of_reference(observatory_id, [RT.InstrumentSite])
        self.assertIn(RT.InstrumentSite, entities)
        inst_sites = entities[RT.InstrumentSite]
        self.assertEqual(1, len(inst_sites))
        self.assertEqual(instrument_site_id, inst_sites[0]._id)

        c.IMS.delete_instrument_agent(instrument_agent_id)
        instr_agent_obj_read = self.client.RR.read(instrument_agent_id)
        self.assertEquals(instr_agent_obj_read.lcstate,LCS.RETIRED)
        log.debug("L4-CI-SA-RQ-382: Proposed change - Instrument activation shall manage the life cycle of Instrument Agents")

        c.IMS.delete_instrument_device(instrument_device_id)
        # Check whether the instrument device has been retired
        instrument_obj_read = self.client.RR.read(instrument_device_id)
        log.debug("The instruments lcs state has been set to %s after the delete operation" % instrument_obj_read.lcstate)
        self.assertEquals(instrument_obj_read.lcstate, LCS.RETIRED)
        log.debug("L4-CI-SA-RQ-334 RETIRE")
        log.debug("L4-CI-SA-RQ-335: Instrument activation shall support transition to the retired state of instruments")

        #----------------------------------------------
        #
        # force_deletes
        #
        #----------------------------------------------

        # need to "pluck" some resources out of associations
        resource_impl.pluck(instrument_model_id)
        resource_impl.pluck(platform_model_id)
        resource_impl.pluck(instrument_agent_id)
        resource_impl.pluck(platform_agent_id)
        resource_impl.pluck(deployment_id)
        resource_impl.pluck(deployment_id2)

        self.generic_fd_script(observatory_id, "observatory", c.OMS)
        self.generic_fd_script(subsite_id, "subsite", c.OMS)
        self.generic_fd_script(platform_site_id, "platform_site", c.OMS)
        self.generic_fd_script(instrument_site_id, "instrument_site", c.OMS)
        self.generic_fd_script(platform_model_id, "platform_model", c.IMS)
        self.generic_fd_script(instrument_model_id, "instrument_model", c.IMS)
        self.generic_fd_script(sensor_model_id, "sensor_model", c.IMS)
        self.generic_fd_script(platform_agent_id, "platform_agent", c.IMS)
        self.generic_fd_script(instrument_agent_id, "instrument_agent", c.IMS)
        self.generic_fd_script(platform_device_id, "platform_device", c.IMS)
        self.generic_fd_script(instrument_device_id, "instrument_device", c.IMS)
        self.generic_fd_script(sensor_device_id, "sensor_device", c.IMS)
        self.generic_fd_script(platform_agent_instance_id, "platform_agent_instance", c.IMS)
        self.generic_fd_script(instrument_agent_instance_id, "instrument_agent_instance", c.IMS)
        self.generic_fd_script(deployment_id, "deployment", c.OMS)
        self.generic_fd_script(deployment_id2, "deployment", c.OMS)