Example #1
0
class TestRollups(IonIntegrationTestCase):
    def setUp(self):
        # Start container
        #print 'instantiating container'
        self._start_container()
        #container = Container()
        #print 'starting container'
        #container.start()

        #print 'started container'

        self.container.start_rel_from_url('res/deploy/r2deploy.yml')
        self.RR = ResourceRegistryServiceClient(node=self.container.node)
        self.IMS = InstrumentManagementServiceClient(node=self.container.node)
        self.OMS = ObservatoryManagementServiceClient(node=self.container.node)
        self.RR2 = EnhancedResourceRegistryClient(self.RR)

        self._setup_statuses()

    def _make_status(self, bad_items_dict=None):
        if bad_items_dict is None:
            bad_items_dict = {}
        ret = {}
        for k in reverse_mapping.values():
            if k in bad_items_dict:
                ret[k] = bad_items_dict[k]
            else:
                ret[k] = DeviceStatusType.STATUS_OK

        return ret

    def _setup_statuses(self):
        # set up according to https://docs.google.com/drawings/d/1kZ_L4xr4Be0OdqMDX6tiI50hROgvLHU4HcnD7e_NIKE/pub?w=1200z
        # https://confluence.oceanobservatories.org/display/syseng/CIAD+SA+OV+Observatory+Status+and+Events

        device_agents = {}

        ms = self._make_status

        # override the default "get agent" function and resource registyr
        IMS_SVC = self._get_svc(InstrumentManagementService)
        OMS_SVC = self._get_svc(ObservatoryManagementService)
        self.IMS_ASB = self._get_specific_attr(IMS_SVC, AgentStatusBuilder)
        self.OMS_ASB = self._get_specific_attr(OMS_SVC, AgentStatusBuilder)
        assert self.IMS_ASB
        assert self.OMS_ASB
        self.IMS_ASB.RR2 = IMS_SVC.RR2
        self.OMS_ASB.RR2 = OMS_SVC.RR2

        # create org
        org_id = self.OMS.create_marine_facility(any_old(RT.Org))
        obs_id = self.OMS.create_observatory(any_old(RT.Observatory), org_id)

        # create instrument and platform devices and sites
        pst = dict([(i + 1, self.RR2.create(any_old(RT.PlatformSite)))
                    for i in range(8)])
        pdv = dict([(i + 1, self.RR2.create(any_old(RT.PlatformDevice)))
                    for i in range(11)])
        ist = dict([(i + 1, self.RR2.create(any_old(RT.InstrumentSite)))
                    for i in range(6)])
        idv = dict([(i + 1, self.RR2.create(any_old(RT.InstrumentDevice)))
                    for i in range(6)])

        # create associations
        has_site = [
            (obs_id, pst[2]),
            (pst[2], pst[1]),
            (pst[1], ist[1]),
            (pst[2], pst[3]),
            (pst[3], ist[2]),
            (pst[3], ist[3]),
            (obs_id, pst[4]),
            (pst[4], pst[5]),
            (pst[4], pst[6]),
            (pst[6], pst[7]),
            (pst[7], ist[4]),
            (pst[6], pst[8]),
            (pst[8], ist[5]),
            (pst[8], ist[6]),
        ]

        has_device = [
            (pst[2], pdv[2]),
            (pst[1], pdv[1]),
            (ist[1], idv[1]),
            (pst[3], pdv[3]),
            (pdv[3], idv[2]),
            (pdv[3], idv[3]),
            (ist[2], idv[2]),
            (ist[3], idv[3]),
            (pst[4], pdv[4]),
            (pdv[4], pdv[5]),
            (pdv[5], pdv[6]),
            (pdv[5], pdv[7]),
            (pdv[7], idv[4]),
            (pst[6], pdv[5]),
            (pst[7], pdv[6]),
            (pst[8], pdv[7]),
            (ist[5], idv[4]),
            (pdv[8], pdv[9]),
            (pdv[9], pdv[10]),
            (pdv[10], idv[5]),
            (pdv[9], pdv[11]),
            (pdv[11], idv[6]),
        ]

        for (s, o) in has_site:
            self.RR2.create_association(s, PRED.hasSite, o)
            self.assertIn(
                o, self.RR2.find_objects(s, PRED.hasSite, None, id_only=True))

        for (s, o) in has_device:
            self.RR2.create_association(s, PRED.hasDevice, o)
            self.assertIn(
                o, self.RR2.find_objects(s, PRED.hasDevice, None,
                                         id_only=True))

        self.assertEqual(
            pdv[1],
            self.RR2.find_platform_device_id_of_platform_site_using_has_device(
                pst[1]))

        # preparing to create fake agents, shortcut to status names
        o = DeviceStatusType.STATUS_OK
        w = DeviceStatusType.STATUS_WARNING
        c = DeviceStatusType.STATUS_CRITICAL

        # expected status for instruments and platforms
        idv_stat = ["ignore", c, o, w, o, w, c]

        # make the fake instrument agents, with their statuses
        for i, id in idv.iteritems():
            idv_agent = FakeAgent()
            idv_agent.set_agent(
                "aggstatus",
                ms({AggregateStatusType.AGGREGATE_DATA: idv_stat[i]}))
            device_agents[id] = idv_agent

        # create fake agents for platforms

        pdv1_agent = FakeAgent()
        pdv1_agent.set_agent("aggstatus", ms())
        pdv1_agent.set_agent("child_agg_status", {})
        device_agents[pdv[1]] = pdv1_agent

        pdv2_agent = FakeAgent()
        pdv2_agent.set_agent(
            "aggstatus",
            ms({
                AggregateStatusType.AGGREGATE_DATA:
                DeviceStatusType.STATUS_WARNING
            }))
        pdv2_agent.set_agent("child_agg_status", {})
        device_agents[pdv[2]] = pdv2_agent

        pdv3_agent = FakeAgent()
        pdv3_agent.set_agent("aggstatus", ms())
        pdv3_agent.set_agent(
            "child_agg_status", {
                idv[2]:
                ms(),
                idv[3]:
                ms({
                    AggregateStatusType.AGGREGATE_DATA:
                    DeviceStatusType.STATUS_WARNING
                }),
            })
        device_agents[pdv[3]] = pdv3_agent

        pdv4_agent = FakeAgent()
        pdv4_agent.set_agent("aggstatus", ms())
        pdv4_agent.set_agent(
            "child_agg_status", {
                pdv[5]:
                ms(),
                pdv[6]:
                ms(),
                pdv[7]:
                ms({
                    AggregateStatusType.AGGREGATE_DATA:
                    DeviceStatusType.STATUS_WARNING
                }),
                idv[4]:
                ms(),
            })
        device_agents[pdv[4]] = pdv4_agent

        pdv5_agent = FakeAgent()
        pdv5_agent.set_agent("aggstatus", ms())
        pdv5_agent.set_agent(
            "child_agg_status", {
                pdv[6]:
                ms(),
                pdv[7]:
                ms({
                    AggregateStatusType.AGGREGATE_DATA:
                    DeviceStatusType.STATUS_WARNING
                }),
                idv[4]:
                ms(),
            })
        device_agents[pdv[5]] = pdv5_agent

        pdv6_agent = FakeAgent()
        pdv6_agent.set_agent("aggstatus", ms())
        pdv6_agent.set_agent("child_agg_status", {})
        device_agents[pdv[6]] = pdv6_agent

        pdv7_agent = FakeAgent()
        pdv7_agent.set_agent(
            "aggstatus",
            ms({
                AggregateStatusType.AGGREGATE_DATA:
                DeviceStatusType.STATUS_WARNING
            }))
        pdv7_agent.set_agent("child_agg_status", {
            idv[4]: ms(),
        })
        device_agents[pdv[7]] = pdv7_agent

        pdv8_agent = FakeAgent()
        pdv8_agent.set_agent("aggstatus", ms())
        pdv8_agent.set_agent(
            "child_agg_status", {
                pdv[9]:
                ms(),
                pdv[10]:
                ms(),
                idv[5]:
                ms({
                    AggregateStatusType.AGGREGATE_DATA:
                    DeviceStatusType.STATUS_WARNING
                }),
                pdv[11]:
                ms(),
                idv[6]:
                ms({
                    AggregateStatusType.AGGREGATE_DATA:
                    DeviceStatusType.STATUS_CRITICAL
                }),
            })
        device_agents[pdv[8]] = pdv8_agent

        pdv9_agent = FakeAgent()
        pdv9_agent.set_agent("aggstatus", ms())
        pdv9_agent.set_agent(
            "child_agg_status", {
                pdv[10]:
                ms(),
                idv[5]:
                ms({
                    AggregateStatusType.AGGREGATE_DATA:
                    DeviceStatusType.STATUS_WARNING
                }),
                pdv[11]:
                ms(),
                idv[6]:
                ms({
                    AggregateStatusType.AGGREGATE_DATA:
                    DeviceStatusType.STATUS_CRITICAL
                }),
            })
        device_agents[pdv[9]] = pdv9_agent

        pdv10_agent = FakeAgent()
        pdv10_agent.set_agent("aggstatus", ms())
        pdv10_agent.set_agent(
            "child_agg_status", {
                idv[5]:
                ms({
                    AggregateStatusType.AGGREGATE_DATA:
                    DeviceStatusType.STATUS_WARNING
                }),
            })
        device_agents[pdv[10]] = pdv10_agent

        pdv11_agent = FakeAgent()
        pdv11_agent.set_agent("aggstatus", ms())
        pdv11_agent.set_agent(
            "child_agg_status", {
                idv[6]:
                ms({
                    AggregateStatusType.AGGREGATE_DATA:
                    DeviceStatusType.STATUS_CRITICAL
                }),
            })
        device_agents[pdv[8]] = pdv11_agent

        self.device_agents = device_agents

        self.IMS_ASB._get_agent_client = self.my_get_agent_client
        self.OMS_ASB._get_agent_client = self.my_get_agent_client

        # save created ids
        self.org_id = org_id
        self.obs_id = obs_id
        self.pst = pst
        self.pdv = pdv
        self.ist = ist
        self.idv = idv

        log.info("org ID:                 %s", org_id)
        log.info("observatory ID:         %s", obs_id)
        for k, v in self.pst.iteritems():
            log.info("platform site ID %s:     %s", k, v)
        for k, v in self.ist.iteritems():
            log.info("instrument site ID %s:   %s", k, v)
        for k, v in self.pdv.iteritems():
            log.info("platform device ID %s:   %s", k, v)
        for k, v in self.idv.iteritems():
            log.info("instrument device ID %s: %s", k, v)

    # define a function to get the agent client, using our fake agents
    def my_get_agent_client(self, device_id, **kwargs):
        try:
            return self.device_agents[device_id]
        except KeyError:
            raise BadRequest(
                "Tried to retrieve status for undefined device '%s'" %
                device_id)

    # some quick checks to help us debug the structure and statuses, to isolate problems
    def check_structure_assumptions(self):
        # check that all objects exist in the RR
        for adict in [self.pst, self.pdv, self.ist, self.idv]:
            for id in adict:
                assert id

        # pst1 should have status critical, pdev1 should be ok, and idv1/ist1 should be critical
        self.assertEqual(
            self.pdv[1],
            self.RR2.find_platform_device_id_of_platform_site_using_has_device(
                self.pst[1]))
        self.assertEqual(
            self.ist[1],
            self.RR2.find_instrument_site_id_of_platform_site_using_has_site(
                self.pst[1]))
        self.assertEqual(
            self.idv[1],
            self.RR2.
            find_instrument_device_id_of_instrument_site_using_has_device(
                self.ist[1]))
        self.assertEqual(
            DeviceStatusType.STATUS_CRITICAL,
            self.my_get_agent_client(self.idv[1]).get_agent([
                "aggstatus"
            ])["aggstatus"][AggregateStatusType.AGGREGATE_DATA])

        # pdv4 should have status warning, coming from pdv7
        self.assertEqual(
            self.pdv[5],
            self.RR2.
            find_platform_device_id_of_platform_device_using_has_device(
                self.pdv[4]))
        self.assertIn(
            self.pdv[6],
            self.RR2.
            find_platform_device_ids_of_platform_device_using_has_device(
                self.pdv[5]))
        self.assertIn(
            self.pdv[7],
            self.RR2.
            find_platform_device_ids_of_platform_device_using_has_device(
                self.pdv[5]))
        self.assertEqual(
            self.idv[4],
            self.RR2.
            find_instrument_device_id_of_platform_device_using_has_device(
                self.pdv[7]))
        self.assertEqual(
            DeviceStatusType.STATUS_OK,
            self.my_get_agent_client(self.idv[4]).get_agent([
                "aggstatus"
            ])["aggstatus"][AggregateStatusType.AGGREGATE_DATA])
        self.assertEqual(
            DeviceStatusType.STATUS_WARNING,
            self.my_get_agent_client(self.pdv[7]).get_agent([
                "aggstatus"
            ])["aggstatus"][AggregateStatusType.AGGREGATE_DATA])

    @unittest.skip("errors in outil prevent this from passing")
    def test_complex_rollup_structure(self):

        self.check_structure_assumptions()

        o = DeviceStatusType.STATUS_OK
        u = DeviceStatusType.STATUS_UNKNOWN
        w = DeviceStatusType.STATUS_WARNING
        c = DeviceStatusType.STATUS_CRITICAL

        pst_stat = ["ignore", c, c, w, w, u, w, o, w]
        pdv_stat = ["ignore", o, w, w, w, w, o, w, c, c, w, c]
        ist_stat = ["ignore", c, o, w, u, o, u]
        idv_stat = ["ignore", c, o, w, o, w, c]

        for i, id in self.idv.iteritems():
            label = "InstrumentDevice %s" % i
            log.info("Checking rollup of %s", label)
            self.assertProperRollup(
                label, self.IMS.get_instrument_device_extension(id),
                idv_stat[i])

        for i, id in self.ist.iteritems():
            label = "InstrumentSite %s" % i
            log.info("Checking rollup of %s", label)
            self.assertProperRollup(label, self.OMS.get_site_extension(id),
                                    ist_stat[i])

        for i, id in self.pdv.iteritems():
            label = "PlatformDevice %s" % i
            log.info("Checking rollup of %s", label)
            self.assertProperRollup(label,
                                    self.IMS.get_platform_device_extension(id),
                                    pdv_stat[i])

        for i, id in self.pst.iteritems():
            label = "PlatformSite %s" % i
            log.info("Checking rollup of %s", label)
            self.assertProperRollup(label, self.OMS.get_site_extension(id),
                                    pst_stat[i])

        #TODO: check observatory and org rollups!

    #TODO: REMOVE THIS TEST when test_complex_rollup_structure is fixed
    #@unittest.skip("phasing out")
    def test_complex_rollup_structure_partially(self):

        o = DeviceStatusType.STATUS_OK
        u = DeviceStatusType.STATUS_UNKNOWN
        w = DeviceStatusType.STATUS_WARNING
        c = DeviceStatusType.STATUS_CRITICAL

        idv_stat = ["ignore", c, o, w, o, w, c]
        ist_stat = ["ignore", c, o, w, u, o, u]

        for i, id in self.idv.iteritems():
            label = "InstrumentDevice %s" % i
            log.info("Checking rollup of %s", label)
            self.assertProperRollup(
                label, self.IMS.get_instrument_device_extension(id),
                idv_stat[i])

        for i, id in self.ist.iteritems():
            label = "InstrumentSite %s" % i
            log.info("Checking rollup of %s", label)
            self.assertProperRollup(label, self.OMS.get_site_extension(id),
                                    ist_stat[i])

    def assertProperRollup(self, label, extended_resource, status):
        m = DeviceStatusType._str_map
        s = extended_resource.computed.data_status_roll_up.status
        v = extended_resource.computed.data_status_roll_up.value
        self.assertEqual(ComputedValueAvailability.PROVIDED, s)
        message = "Expected rollup status of %s to be %s but got %s" % (
            label, m[status], m.get(v, "?? %s" % v))
        self.assertEqual(status, v, message)

    # get an object of a specific type from within another python object
    def _get_specific_attr(self, parent_obj, attrtype):
        for d in dir(parent_obj):
            a = getattr(parent_obj, d)
            if isinstance(a, attrtype):
                return a

        return None

    # get a service of a given type from the capability container
    def _get_svc(self, service_cls):
        # get service from container proc manager
        relevant_services = [
            item[1] for item in self.container.proc_manager.procs.items()
            if isinstance(item[1], service_cls)
        ]

        assert (0 < len(relevant_services)),\
        "no services of type '%s' found running in container!" % service_cls

        service_itself = relevant_services[0]
        assert service_itself
        return service_itself
class TestObservatoryManagementServiceIntegration(IonIntegrationTestCase):

    def setUp(self):
        # Start container
        #print 'instantiating container'
        self._start_container()
        #container = Container()
        #print 'starting container'
        #container.start()
        #print 'started container'

        self.container.start_rel_from_url('res/deploy/r2deploy.yml')
        self.RR = ResourceRegistryServiceClient(node=self.container.node)
        self.RR2 = EnhancedResourceRegistryClient(self.RR)
        self.OMS = ObservatoryManagementServiceClient(node=self.container.node)
        self.org_management_service = OrgManagementServiceClient(node=self.container.node)
        self.IMS =  InstrumentManagementServiceClient(node=self.container.node)
        self.dpclient = DataProductManagementServiceClient(node=self.container.node)
        self.pubsubcli =  PubsubManagementServiceClient(node=self.container.node)
        self.damsclient = DataAcquisitionManagementServiceClient(node=self.container.node)
        self.dataset_management = DatasetManagementServiceClient()
        #print 'TestObservatoryManagementServiceIntegration: started services'

        self.event_publisher = EventPublisher()

#    @unittest.skip('this exists only for debugging the launch process')
#    def test_just_the_setup(self):
#        return

    def destroy(self, resource_ids):
        self.OMS.force_delete_observatory(resource_ids.observatory_id)
        self.OMS.force_delete_subsite(resource_ids.subsite_id)
        self.OMS.force_delete_subsite(resource_ids.subsite2_id)
        self.OMS.force_delete_subsite(resource_ids.subsiteb_id)
        self.OMS.force_delete_subsite(resource_ids.subsitez_id)
        self.OMS.force_delete_platform_site(resource_ids.platform_site_id)
        self.OMS.force_delete_platform_site(resource_ids.platform_siteb_id)
        self.OMS.force_delete_platform_site(resource_ids.platform_siteb2_id)
        self.OMS.force_delete_platform_site(resource_ids.platform_site3_id)
        self.OMS.force_delete_instrument_site(resource_ids.instrument_site_id)
        self.OMS.force_delete_instrument_site(resource_ids.instrument_site2_id)
        self.OMS.force_delete_instrument_site(resource_ids.instrument_siteb3_id)
        self.OMS.force_delete_instrument_site(resource_ids.instrument_site4_id)

    #@unittest.skip('targeting')
    def test_observatory_management(self):
        resources = self._make_associations()

        self._do_test_find_related_sites(resources)

        self._do_test_get_sites_devices_status(resources)

        self._do_test_find_site_data_products(resources)

        self._do_test_find_related_frames_of_reference(resources)

        self._do_test_create_geospatial_point_center(resources)

        self._do_test_find_observatory_org(resources)

        self.destroy(resources)

    def _do_test_find_related_sites(self, resources):

        site_resources, site_children = self.OMS.find_related_sites(resources.org_id)

        #import sys, pprint
        #print >> sys.stderr, pprint.pformat(site_resources)
        #print >> sys.stderr, pprint.pformat(site_children)

        #self.assertIn(resources.org_id, site_resources)
        self.assertIn(resources.observatory_id, site_resources)
        self.assertIn(resources.subsite_id, site_resources)
        self.assertIn(resources.subsite_id, site_resources)
        self.assertIn(resources.subsite2_id, site_resources)
        self.assertIn(resources.platform_site_id, site_resources)
        self.assertIn(resources.instrument_site_id, site_resources)
        self.assertEquals(len(site_resources), 13)

        self.assertEquals(site_resources[resources.observatory_id].type_, RT.Observatory)

        self.assertIn(resources.org_id, site_children)
        self.assertIn(resources.observatory_id, site_children)
        self.assertIn(resources.subsite_id, site_children)
        self.assertIn(resources.subsite_id, site_children)
        self.assertIn(resources.subsite2_id, site_children)
        self.assertIn(resources.platform_site_id, site_children)
        self.assertNotIn(resources.instrument_site_id, site_children)
        self.assertEquals(len(site_children), 9)

        self.assertIsInstance(site_children[resources.subsite_id], list)
        self.assertEquals(len(site_children[resources.subsite_id]), 2)

    def _do_test_get_sites_devices_status(self, resources):

        result_dict = self.OMS.get_sites_devices_status(resources.org_id)

        site_resources = result_dict.get("site_resources", None)
        site_children = result_dict.get("site_children", None)

        self.assertEquals(len(site_resources), 14)
        self.assertEquals(len(site_children), 9)

        result_dict = self.OMS.get_sites_devices_status(resources.org_id, include_devices=True, include_status=True)

        log.debug("RESULT DICT: %s", result_dict.keys())
        site_resources = result_dict.get("site_resources", None)
        site_children = result_dict.get("site_children", None)
        site_status = result_dict.get("site_status", None)

        self.assertEquals(len(site_resources), 14)
        self.assertEquals(len(site_children), 9)


        result_dict = self.OMS.get_sites_devices_status(resources.observatory_id, include_devices=True, include_status=True)

        site_resources = result_dict.get("site_resources")
        site_children = result_dict.get("site_children")
        site_status = result_dict.get("site_status")

        self.assertEquals(len(site_resources), 13)
        self.assertEquals(len(site_children), 8)


    def _do_test_find_site_data_products(self, resources):
        res_dict = self.OMS.find_site_data_products(resources.org_id)

        #import sys, pprint
        #print >> sys.stderr, pprint.pformat(res_dict)

        self.assertIsNone(res_dict['data_product_resources'])
        self.assertIn(resources.platform_device_id, res_dict['device_data_products'])
        self.assertIn(resources.instrument_device_id, res_dict['device_data_products'])

    #@unittest.skip('targeting')
    def _do_test_find_related_frames_of_reference(self, stuff):
        # finding subordinates gives a dict of obj lists, convert objs to ids
        def idify(adict):
            ids = {}
            for k, v in adict.iteritems():
                ids[k] = []
                for obj in v:
                    ids[k].append(obj._id)

            return ids

        # a short version of the function we're testing, with id-ify
        def short(resource_id, output_types):
            ret = self.OMS.find_related_frames_of_reference(resource_id,
                                                            output_types)
            return idify(ret)
            
            
        #set up associations first
        stuff = self._make_associations()
        #basic traversal of tree from instrument to platform
        ids = short(stuff.instrument_site_id, [RT.PlatformSite])
        self.assertIn(RT.PlatformSite, ids)
        self.assertIn(stuff.platform_site_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_siteb_id, ids[RT.PlatformSite])
        self.assertNotIn(stuff.platform_siteb2_id, ids[RT.PlatformSite])

        #since this is the first search, just make sure the input inst_id got stripped
        if RT.InstrumentSite in ids:
            self.assertNotIn(stuff.instrument_site_id, ids[RT.InstrumentSite])

        #basic traversal of tree from platform to instrument
        ids = short(stuff.platform_siteb_id, [RT.InstrumentSite])
        self.assertIn(RT.InstrumentSite, ids)
        self.assertIn(stuff.instrument_site_id, ids[RT.InstrumentSite])
        self.assertNotIn(stuff.instrument_site2_id, ids[RT.InstrumentSite])


        #full traversal of tree from observatory down to instrument
        ids = short(stuff.observatory_id, [RT.InstrumentSite])
        self.assertIn(RT.InstrumentSite, ids)
        self.assertIn(stuff.instrument_site_id, ids[RT.InstrumentSite])


        #full traversal of tree from instrument to observatory
        ids = short(stuff.instrument_site_id, [RT.Observatory])
        self.assertIn(RT.Observatory, ids)
        self.assertIn(stuff.observatory_id, ids[RT.Observatory])


        #partial traversal, only down to platform
        ids = short(stuff.observatory_id, [RT.Subsite, RT.PlatformSite])
        self.assertIn(RT.PlatformSite, ids)
        self.assertIn(RT.Subsite, ids)
        self.assertIn(stuff.platform_site_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_siteb_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_siteb2_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_site3_id, ids[RT.PlatformSite])
        self.assertIn(stuff.subsite_id, ids[RT.Subsite])
        self.assertIn(stuff.subsite2_id, ids[RT.Subsite])
        self.assertIn(stuff.subsitez_id, ids[RT.Subsite])
        self.assertIn(stuff.subsiteb_id, ids[RT.Subsite])
        self.assertNotIn(RT.InstrumentSite, ids)


        #partial traversal, only down to platform
        ids = short(stuff.instrument_site_id, [RT.Subsite, RT.PlatformSite])
        self.assertIn(RT.PlatformSite, ids)
        self.assertIn(RT.Subsite, ids)
        self.assertIn(stuff.platform_siteb_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_site_id, ids[RT.PlatformSite])
        self.assertIn(stuff.subsite_id, ids[RT.Subsite])
        self.assertIn(stuff.subsiteb_id, ids[RT.Subsite])
        self.assertNotIn(stuff.subsite2_id, ids[RT.Subsite])
        self.assertNotIn(stuff.subsitez_id, ids[RT.Subsite])
        self.assertNotIn(stuff.platform_siteb2_id, ids[RT.PlatformSite])
        self.assertNotIn(RT.Observatory, ids)

        self.destroy(stuff)

    def _make_associations(self):
        """
        create one of each resource and association used by OMS
        to guard against problems in ion-definitions
        """

        #raise unittest.SkipTest("https://jira.oceanobservatories.org/tasks/browse/CISWCORE-41")
        

        """
        the tree we're creating (observatory, sites, platforms, instruments)

        rows are lettered, colums numbered.  
         - first row is implied a
         - first column is implied 1
         - site Z, just because 

        O--Sz
        |
        S--S2--P3--I4
        |
        Sb-Pb2-Ib3
        |
        P--I2 <- PlatformDevice, InstrumentDevice2
        |
        Pb <- PlatformDevice b
        |
        I <- InstrumentDevice

        """

        org_id = self.OMS.create_marine_facility(any_old(RT.Org))

        def create_under_org(resource_type, extra_fields=None):
            obj = any_old(resource_type, extra_fields)

            if RT.InstrumentDevice == resource_type:
                resource_id = self.IMS.create_instrument_device(obj)
            else:
                resource_id, _ = self.RR.create(obj)

            self.OMS.assign_resource_to_observatory_org(resource_id=resource_id, org_id=org_id)
            return resource_id

        #stuff we control
        observatory_id          = create_under_org(RT.Observatory)
        subsite_id              = create_under_org(RT.Subsite)
        subsite2_id             = create_under_org(RT.Subsite)
        subsiteb_id             = create_under_org(RT.Subsite)
        subsitez_id             = create_under_org(RT.Subsite)
        platform_site_id        = create_under_org(RT.PlatformSite)
        platform_siteb_id       = create_under_org(RT.PlatformSite)
        platform_siteb2_id      = create_under_org(RT.PlatformSite)
        platform_site3_id       = create_under_org(RT.PlatformSite)
        instrument_site_id      = create_under_org(RT.InstrumentSite)
        instrument_site2_id     = create_under_org(RT.InstrumentSite)
        instrument_siteb3_id    = create_under_org(RT.InstrumentSite)
        instrument_site4_id     = create_under_org(RT.InstrumentSite)

        #stuff we associate to
        instrument_device_id    = create_under_org(RT.InstrumentDevice)
        instrument_device2_id   = create_under_org(RT.InstrumentDevice)
        platform_device_id      = create_under_org(RT.PlatformDevice)
        platform_deviceb_id     = create_under_org(RT.PlatformDevice)
        instrument_model_id, _  = self.RR.create(any_old(RT.InstrumentModel))
        platform_model_id, _    = self.RR.create(any_old(RT.PlatformModel))
        deployment_id, _        = self.RR.create(any_old(RT.Deployment))

        #observatory
        self.RR.create_association(observatory_id, PRED.hasSite, subsite_id)
        self.RR.create_association(observatory_id, PRED.hasSite, subsitez_id)

        #site
        self.RR.create_association(subsite_id, PRED.hasSite, subsite2_id)
        self.RR.create_association(subsite_id, PRED.hasSite, subsiteb_id)
        self.RR.create_association(subsite2_id, PRED.hasSite, platform_site3_id)
        self.RR.create_association(subsiteb_id, PRED.hasSite, platform_siteb2_id)
        self.RR.create_association(subsiteb_id, PRED.hasSite, platform_site_id)
        
        #platform_site(s)
        self.RR.create_association(platform_site3_id, PRED.hasSite, instrument_site4_id)
        self.RR.create_association(platform_siteb2_id, PRED.hasSite, instrument_siteb3_id)
        self.RR.create_association(platform_site_id, PRED.hasSite, instrument_site2_id)
        self.RR.create_association(platform_site_id, PRED.hasSite, platform_siteb_id)
        self.RR.create_association(platform_siteb_id, PRED.hasSite, instrument_site_id)

        self.RR.create_association(platform_siteb_id, PRED.hasDevice, platform_deviceb_id)
        #test network parent link
        self.OMS.assign_device_to_network_parent(platform_device_id, platform_deviceb_id)

        self.RR.create_association(platform_site_id, PRED.hasModel, platform_model_id)
        self.RR.create_association(platform_site_id, PRED.hasDevice, platform_device_id)
        self.RR.create_association(platform_site_id, PRED.hasDeployment, deployment_id)

        #instrument_site(s)
        self.RR.create_association(instrument_site_id, PRED.hasModel, instrument_model_id)
        self.RR.create_association(instrument_site_id, PRED.hasDevice, instrument_device_id)
        self.RR.create_association(instrument_site_id, PRED.hasDeployment, deployment_id)

        self.RR.create_association(instrument_site2_id, PRED.hasDevice, instrument_device2_id)

        #platform_device
        self.RR.create_association(platform_device_id, PRED.hasModel, platform_model_id)

        #instrument_device
        self.RR.create_association(instrument_device_id, PRED.hasModel, instrument_model_id)
        self.RR.create_association(instrument_device2_id, PRED.hasModel, instrument_model_id)

        ret = DotDict()
        ret.org_id                = org_id
        ret.observatory_id        = observatory_id
        ret.subsite_id            = subsite_id
        ret.subsite2_id           = subsite2_id
        ret.subsiteb_id           = subsiteb_id
        ret.subsitez_id           = subsitez_id
        ret.platform_site_id      = platform_site_id
        ret.platform_siteb_id     = platform_siteb_id
        ret.platform_siteb2_id    = platform_siteb2_id
        ret.platform_site3_id     = platform_site3_id
        ret.instrument_site_id    = instrument_site_id
        ret.instrument_site2_id   = instrument_site2_id
        ret.instrument_siteb3_id  = instrument_siteb3_id
        ret.instrument_site4_id   = instrument_site4_id

        ret.instrument_device_id  = instrument_device_id
        ret.instrument_device2_id = instrument_device2_id
        ret.platform_device_id    = platform_device_id
        ret.platform_deviceb_id    = platform_deviceb_id
        ret.instrument_model_id   = instrument_model_id
        ret.platform_model_id     = platform_model_id
        ret.deployment_id         = deployment_id

        return ret

    #@unittest.skip("targeting")
    def test_create_observatory(self):
        observatory_obj = IonObject(RT.Observatory,
                                        name='TestFacility',
                                        description='some new mf')
        observatory_id = self.OMS.create_observatory(observatory_obj)
        self.OMS.force_delete_observatory(observatory_id)

    #@unittest.skip("targeting")
    def _do_test_create_geospatial_point_center(self, resources):
        platformsite_obj = IonObject(RT.PlatformSite,
                                        name='TestPlatformSite',
                                        description='some new TestPlatformSite')
        geo_index_obj = IonObject(OT.GeospatialBounds)
        geo_index_obj.geospatial_latitude_limit_north = 20.0
        geo_index_obj.geospatial_latitude_limit_south = 10.0
        geo_index_obj.geospatial_longitude_limit_east = 15.0
        geo_index_obj.geospatial_longitude_limit_west = 20.0
        platformsite_obj.constraint_list = [geo_index_obj]

        platformsite_id = self.OMS.create_platform_site(platformsite_obj)

        # now get the dp back to see if it was updated
        platformsite_obj = self.OMS.read_platform_site(platformsite_id)
        self.assertEquals('some new TestPlatformSite', platformsite_obj.description)
        self.assertAlmostEqual(15.0, platformsite_obj.geospatial_point_center.lat, places=1)


        #now adjust a few params
        platformsite_obj.description = 'some old TestPlatformSite'
        geo_index_obj = IonObject(OT.GeospatialBounds)
        geo_index_obj.geospatial_latitude_limit_north = 30.0
        geo_index_obj.geospatial_latitude_limit_south = 20.0
        platformsite_obj.constraint_list = [geo_index_obj]
        update_result = self.OMS.update_platform_site(platformsite_obj)

        # now get the dp back to see if it was updated
        platformsite_obj = self.OMS.read_platform_site(platformsite_id)
        self.assertEquals('some old TestPlatformSite', platformsite_obj.description)
        self.assertAlmostEqual(25.0, platformsite_obj.geospatial_point_center.lat, places=1)

        self.OMS.force_delete_platform_site(platformsite_id)


    #@unittest.skip("targeting")
    def _do_test_find_observatory_org(self, resources):
        log.debug("Make TestOrg")
        org_obj = IonObject(RT.Org,
                            name='TestOrg',
                            description='some new mf org')

        org_id =  self.OMS.create_marine_facility(org_obj)

        log.debug("Make Observatory")
        observatory_obj = IonObject(RT.Observatory,
                                        name='TestObservatory',
                                        description='some new obs')
        observatory_id = self.OMS.create_observatory(observatory_obj)

        log.debug("assign observatory to org")
        self.OMS.assign_resource_to_observatory_org(observatory_id, org_id)


        log.debug("verify assigment")
        org_objs = self.OMS.find_org_by_observatory(observatory_id)
        self.assertEqual(1, len(org_objs))
        self.assertEqual(org_id, org_objs[0]._id)
        log.debug("org_id=<" + org_id + ">")

        log.debug("create a subsite with parent Observatory")
        subsite_obj =  IonObject(RT.Subsite,
                                name= 'TestSubsite',
                                description = 'sample subsite')
        subsite_id = self.OMS.create_subsite(subsite_obj, observatory_id)
        self.assertIsNotNone(subsite_id, "Subsite not created.")

        log.debug("verify that Subsite is linked to Observatory")
        mf_subsite_assoc = self.RR.get_association(observatory_id, PRED.hasSite, subsite_id)
        self.assertIsNotNone(mf_subsite_assoc, "Subsite not connected to Observatory.")


        log.debug("add the Subsite as a resource of this Observatory")
        self.OMS.assign_resource_to_observatory_org(resource_id=subsite_id, org_id=org_id)
        log.debug("verify that Subsite is linked to Org")
        org_subsite_assoc = self.RR.get_association(org_id, PRED.hasResource, subsite_id)
        self.assertIsNotNone(org_subsite_assoc, "Subsite not connected as resource to Org.")


        log.debug("create a logical platform with parent Subsite")
        platform_site_obj =  IonObject(RT.PlatformSite,
                                name= 'TestPlatformSite',
                                description = 'sample logical platform')
        platform_site_id = self.OMS.create_platform_site(platform_site_obj, subsite_id)
        self.assertIsNotNone(platform_site_id, "PlatformSite not created.")

        log.debug("verify that PlatformSite is linked to Site")
        site_lp_assoc = self.RR.get_association(subsite_id, PRED.hasSite, platform_site_id)
        self.assertIsNotNone(site_lp_assoc, "PlatformSite not connected to Site.")


        log.debug("add the PlatformSite as a resource of this Observatory")
        self.OMS.assign_resource_to_observatory_org(resource_id=platform_site_id, org_id=org_id)
        log.debug("verify that PlatformSite is linked to Org")
        org_lp_assoc = self.RR.get_association(org_id, PRED.hasResource, platform_site_id)
        self.assertIsNotNone(org_lp_assoc, "PlatformSite not connected as resource to Org.")



        log.debug("create a logical instrument with parent logical platform")
        instrument_site_obj =  IonObject(RT.InstrumentSite,
                                name= 'TestInstrumentSite',
                                description = 'sample logical instrument')
        instrument_site_id = self.OMS.create_instrument_site(instrument_site_obj, platform_site_id)
        self.assertIsNotNone(instrument_site_id, "InstrumentSite not created.")


        log.debug("verify that InstrumentSite is linked to PlatformSite")
        li_lp_assoc = self.RR.get_association(platform_site_id, PRED.hasSite, instrument_site_id)
        self.assertIsNotNone(li_lp_assoc, "InstrumentSite not connected to PlatformSite.")


        log.debug("add the InstrumentSite as a resource of this Observatory")
        self.OMS.assign_resource_to_observatory_org(resource_id=instrument_site_id, org_id=org_id)
        log.debug("verify that InstrumentSite is linked to Org")
        org_li_assoc = self.RR.get_association(org_id, PRED.hasResource, instrument_site_id)
        self.assertIsNotNone(org_li_assoc, "InstrumentSite not connected as resource to Org.")


        log.debug("remove the InstrumentSite as a resource of this Observatory")
        self.OMS.unassign_resource_from_observatory_org(instrument_site_id, org_id)
        log.debug("verify that InstrumentSite is linked to Org")
        assocs,_ = self.RR.find_objects(org_id, PRED.hasResource, RT.InstrumentSite, id_only=True )
        self.assertEqual(0, len(assocs))

        log.debug("remove the InstrumentSite, association should drop automatically")
        self.OMS.delete_instrument_site(instrument_site_id)
        assocs, _ = self.RR.find_objects(platform_site_id, PRED.hasSite, RT.InstrumentSite, id_only=True )
        self.assertEqual(0, len(assocs))


        log.debug("remove the PlatformSite as a resource of this Observatory")
        self.OMS.unassign_resource_from_observatory_org(platform_site_id, org_id)
        log.debug("verify that PlatformSite is linked to Org")
        assocs,_ = self.RR.find_objects(org_id, PRED.hasResource, RT.PlatformSite, id_only=True )
        self.assertEqual(0, len(assocs))


        log.debug("remove the Site as a resource of this Observatory")
        self.OMS.unassign_resource_from_observatory_org(subsite_id, org_id)
        log.debug("verify that Site is linked to Org")
        assocs,_ = self.RR.find_objects(org_id, PRED.hasResource, RT.Subsite, id_only=True )
        self.assertEqual(0, len(assocs))

        self.RR.delete(org_id)
        self.OMS.force_delete_observatory(observatory_id)
        self.OMS.force_delete_subsite(subsite_id)
        self.OMS.force_delete_platform_site(platform_site_id)
        self.OMS.force_delete_instrument_site(instrument_site_id)


    @attr('EXT')
    def test_observatory_extensions(self):



        obs_id = self.RR2.create(any_old(RT.Observatory))
        pss_id = self.RR2.create(any_old(RT.PlatformSite, dict(alt_resource_type="StationSite")))
        pas_id = self.RR2.create(any_old(RT.PlatformSite, dict(alt_resource_type="PlatformAssemblySite")))
        pcs_id = self.RR2.create(any_old(RT.PlatformSite, dict(alt_resource_type="PlatformComponentSite")))
        ins_id = self.RR2.create(any_old(RT.InstrumentSite))

        obs_obj = self.RR2.read(obs_id)
        pss_obj = self.RR2.read(pss_id)
        pas_obj = self.RR2.read(pas_id)
        pcs_obj = self.RR2.read(pcs_id)
        ins_obj = self.RR2.read(ins_id)

        self.RR2.create_association(obs_id, PRED.hasSite, pss_id)
        self.RR2.create_association(pss_id, PRED.hasSite, pas_id)
        self.RR2.create_association(pas_id, PRED.hasSite, pcs_id)
        self.RR2.create_association(pcs_id, PRED.hasSite, ins_id)

        extended_obs = self.OMS.get_observatory_site_extension(obs_id, user_id=12345)
        self.assertEqual([pss_obj], extended_obs.computed.platform_station_sites.value)
        self.assertEqual(ComputedValueAvailability.PROVIDED, extended_obs.computed.platform_station_sites.status)
        self.assertEqual([pas_obj], extended_obs.computed.platform_assembly_sites.value)
        self.assertEqual(ComputedValueAvailability.PROVIDED, extended_obs.computed.platform_assembly_sites.status)
        self.assertEqual([pcs_obj], extended_obs.computed.platform_component_sites.value)
        self.assertEqual(ComputedValueAvailability.PROVIDED, extended_obs.computed.platform_component_sites.status)
        self.assertEqual([ins_obj], extended_obs.computed.instrument_sites.value)

        extended_pss = self.OMS.get_observatory_site_extension(obs_id, user_id=12345)
        self.assertEqual([pas_obj], extended_pss.computed.platform_assembly_sites.value)
        self.assertEqual([pcs_obj], extended_pss.computed.platform_component_sites.value)
        self.assertEqual([ins_obj], extended_pss.computed.instrument_sites.value)

        extended_pas = self.OMS.get_observatory_site_extension(pas_id, user_id=12345)
        self.assertEqual([pcs_obj], extended_pas.computed.platform_component_sites.value)
        self.assertEqual([ins_obj], extended_pas.computed.instrument_sites.value)

        extended_pcs = self.OMS.get_platform_component_site_extension(pcs_id, user_id=12345)
        self.assertEqual([ins_obj], extended_pcs.computed.instrument_sites.value)


    #@unittest.skip("in development...")
    @attr('EXT')
    @attr('EXT1')
    def test_observatory_org_extended(self):

        stuff = self._make_associations()

        parsed_pdict_id = self.dataset_management.read_parameter_dictionary_by_name('ctd_parsed_param_dict',
                                                                                    id_only=True)

        parsed_stream_def_id = self.pubsubcli.create_stream_definition(name='parsed',
                                                                       parameter_dictionary_id=parsed_pdict_id)
        tdom, sdom = time_series_domain()
        sdom = sdom.dump()
        tdom = tdom.dump()
        dp_obj = IonObject(RT.DataProduct,
            name='the parsed data',
            description='ctd stream test',
            temporal_domain = tdom,
            spatial_domain = sdom)


        data_product_id1 = self.dpclient.create_data_product(data_product=dp_obj,
                                                             stream_definition_id=parsed_stream_def_id)
        self.damsclient.assign_data_product(input_resource_id=stuff.instrument_device_id,
                                            data_product_id=data_product_id1)


        #Create a  user to be used as regular member
        member_actor_obj = IonObject(RT.ActorIdentity, name='org member actor')
        member_actor_id,_ = self.RR.create(member_actor_obj)
        assert(member_actor_id)
        member_actor_header = get_actor_header(member_actor_id)


        member_user_obj = IonObject(RT.UserInfo, name='org member user')
        member_user_id,_ = self.RR.create(member_user_obj)
        assert(member_user_id)

        self.RR.create_association(subject=member_actor_id, predicate=PRED.hasInfo, object=member_user_id)


        #Build the Service Agreement Proposal to enroll a user actor
        sap = IonObject(OT.EnrollmentProposal,consumer=member_actor_id, provider=stuff.org_id )

        sap_response = self.org_management_service.negotiate(sap, headers=member_actor_header )

        #enroll the member without using negotiation
        self.org_management_service.enroll_member(org_id=stuff.org_id, actor_id=member_actor_id)

        #--------------------------------------------------------------------------------
        # Get the extended Site (platformSite)
        #--------------------------------------------------------------------------------


        try:
            extended_site = self.OMS.get_site_extension(stuff.platform_site_id)
        except:
            log.error('failed to get extended site', exc_info=True)
            raise
        log.debug("extended_site:  %r ", extended_site)
        self.assertEqual(1, len(extended_site.platform_devices))
        self.assertEqual(1, len(extended_site.platform_models))
        self.assertEqual(stuff.platform_device_id, extended_site.platform_devices[0]._id)
        self.assertEqual(stuff.platform_model_id, extended_site.platform_models[0]._id)

        log.debug("verify that PlatformDeviceb is linked to PlatformDevice with hasNetworkParent link")
        associations = self.RR.find_associations(subject=stuff.platform_deviceb_id, predicate=PRED.hasNetworkParent, object=stuff.platform_device_id, id_only=True)
        self.assertIsNotNone(associations, "PlatformDevice child not connected to PlatformDevice parent.")


        #--------------------------------------------------------------------------------
        # Get the extended Org
        #--------------------------------------------------------------------------------
        #test the extended resource
        extended_org = self.OMS.get_marine_facility_extension(stuff.org_id)
        log.debug("test_observatory_org_extended: extended_org:  %s ", str(extended_org))
        #self.assertEqual(2, len(extended_org.instruments_deployed) )
        #self.assertEqual(1, len(extended_org.platforms_not_deployed) )
        self.assertEqual(2, extended_org.number_of_platforms)
        self.assertEqual(2, len(extended_org.platform_models) )

        self.assertEqual(2, extended_org.number_of_instruments)
        self.assertEqual(2, len(extended_org.instrument_models) )

        self.assertEqual(1, len(extended_org.members))
        self.assertNotEqual(extended_org.members[0]._id, member_actor_id)
        self.assertEqual(extended_org.members[0]._id, member_user_id)

        self.assertEqual(1, len(extended_org.open_requests))

        self.assertTrue(len(extended_site.deployments)>0)
        self.assertEqual(len(extended_site.deployments), len(extended_site.deployment_info))

        #test the extended resource of the ION org
        ion_org_id = self.org_management_service.find_org()
        extended_org = self.OMS.get_marine_facility_extension(ion_org_id._id, user_id=12345)
        log.debug("test_observatory_org_extended: extended_ION_org:  %s ", str(extended_org))
        self.assertEqual(1, len(extended_org.members))
        self.assertEqual(0, extended_org.number_of_platforms)
        #self.assertEqual(1, len(extended_org.sites))


        #--------------------------------------------------------------------------------
        # Get the extended Site
        #--------------------------------------------------------------------------------

        #create device state events to use for op /non-op filtering in extended
        t = get_ion_ts()
        self.event_publisher.publish_event(  ts_created= t,  event_type = 'ResourceAgentStateEvent',
            origin = stuff.instrument_device_id, state=ResourceAgentState.STREAMING  )

        self.event_publisher.publish_event( ts_created= t,   event_type = 'ResourceAgentStateEvent',
            origin = stuff.instrument_device2_id, state=ResourceAgentState.INACTIVE )
        extended_site =  self.OMS.get_site_extension(stuff.instrument_site2_id)


        log.debug("test_observatory_org_extended: extended_site:  %s ", str(extended_site))

        self.dpclient.delete_data_product(data_product_id1)
Example #3
0
class TestRollups(IonIntegrationTestCase):

    def setUp(self):
        # Start container
        #print 'instantiating container'
        self._start_container()
        #container = Container()
        #print 'starting container'
        #container.start()

        #print 'started container'

        self.container.start_rel_from_url('res/deploy/r2deploy.yml')
        self.RR   = ResourceRegistryServiceClient(node=self.container.node)
        self.IMS  = InstrumentManagementServiceClient(node=self.container.node)
        self.OMS = ObservatoryManagementServiceClient(node=self.container.node)
        self.RR2 = EnhancedResourceRegistryClient(self.RR)


        self._setup_statuses()


    def _make_status(self, bad_items_dict=None):
        if bad_items_dict is None:
            bad_items_dict = {}
        ret = {}
        for k in reverse_mapping.values():
            if k in bad_items_dict:
                ret[k] = bad_items_dict[k]
            else:
                ret[k] = DeviceStatusType.STATUS_OK

        return ret


    def _setup_statuses(self):
        # set up according to https://docs.google.com/drawings/d/1kZ_L4xr4Be0OdqMDX6tiI50hROgvLHU4HcnD7e_NIKE/pub?w=1200z
        # https://confluence.oceanobservatories.org/display/syseng/CIAD+SA+OV+Observatory+Status+and+Events

        device_agents = {}

        ms = self._make_status

        # override the default "get agent" function and resource registyr
        IMS_SVC = self._get_svc(InstrumentManagementService)
        OMS_SVC = self._get_svc(ObservatoryManagementService)
        self.IMS_ASB = self._get_specific_attr(IMS_SVC, AgentStatusBuilder)
        self.OMS_ASB = self._get_specific_attr(OMS_SVC, AgentStatusBuilder)
        assert self.IMS_ASB
        assert self.OMS_ASB
        self.IMS_ASB.RR2 = IMS_SVC.RR2
        self.OMS_ASB.RR2 = OMS_SVC.RR2

        # create org
        org_id = self.OMS.create_marine_facility(any_old(RT.Org))
        obs_id = self.OMS.create_observatory(any_old(RT.Observatory), org_id)

        # create instrument and platform devices and sites
        pst = dict([(i + 1, self.RR2.create(any_old(RT.PlatformSite))) for i in range(8)])
        pdv = dict([(i + 1, self.RR2.create(any_old(RT.PlatformDevice))) for i in range(11)])
        ist = dict([(i + 1, self.RR2.create(any_old(RT.InstrumentSite))) for i in range(6)])
        idv = dict([(i + 1, self.RR2.create(any_old(RT.InstrumentDevice))) for i in range(6)])

        # create associations
        has_site = [
            (obs_id, pst[2]),
            (pst[2], pst[1]),
            (pst[1], ist[1]),
            (pst[2], pst[3]),
            (pst[3], ist[2]),
            (pst[3], ist[3]),
            (obs_id, pst[4]),
            (pst[4], pst[5]),
            (pst[4], pst[6]),
            (pst[6], pst[7]),
            (pst[7], ist[4]),
            (pst[6], pst[8]),
            (pst[8], ist[5]),
            (pst[8], ist[6]),
        ]

        has_device = [
            (pst[2], pdv[2]),
            (pst[1], pdv[1]),
            (ist[1], idv[1]),
            (pst[3], pdv[3]),
            (pdv[3], idv[2]),
            (pdv[3], idv[3]),
            (ist[2], idv[2]),
            (ist[3], idv[3]),
            (pst[4], pdv[4]),
            (pdv[4], pdv[5]),
            (pdv[5], pdv[6]),
            (pdv[5], pdv[7]),
            (pdv[7], idv[4]),
            (pst[6], pdv[5]),
            (pst[7], pdv[6]),
            (pst[8], pdv[7]),
            (ist[5], idv[4]),
            (pdv[8], pdv[9]),
            (pdv[9], pdv[10]),
            (pdv[10], idv[5]),
            (pdv[9], pdv[11]),
            (pdv[11], idv[6]),
        ]

        for (s, o) in has_site:
            self.RR2.create_association(s, PRED.hasSite, o)
            self.assertIn(o, self.RR2.find_objects(s, PRED.hasSite, None, id_only=True))

        for (s, o) in has_device:
            self.RR2.create_association(s, PRED.hasDevice, o)
            self.assertIn(o, self.RR2.find_objects(s, PRED.hasDevice, None, id_only=True))

        self.assertEqual(pdv[1], self.RR2.find_platform_device_id_of_platform_site_using_has_device(pst[1]))


        # preparing to create fake agents, shortcut to status names
        o = DeviceStatusType.STATUS_OK
        w = DeviceStatusType.STATUS_WARNING
        c = DeviceStatusType.STATUS_CRITICAL

        # expected status for instruments and platforms
        idv_stat = ["ignore", c, o, w, o, w, c]

        # make the fake instrument agents, with their statuses
        for i, id in idv.iteritems():
            idv_agent = FakeAgent()
            idv_agent.set_agent("aggstatus", ms({AggregateStatusType.AGGREGATE_DATA: idv_stat[i]}))
            device_agents[id] = idv_agent


        # create fake agents for platforms

        pdv1_agent = FakeAgent()
        pdv1_agent.set_agent("aggstatus", ms())
        pdv1_agent.set_agent("child_agg_status", {})
        device_agents[pdv[1]] = pdv1_agent

        pdv2_agent = FakeAgent()
        pdv2_agent.set_agent("aggstatus", ms({AggregateStatusType.AGGREGATE_DATA: DeviceStatusType.STATUS_WARNING}))
        pdv2_agent.set_agent("child_agg_status", {})
        device_agents[pdv[2]] = pdv2_agent

        pdv3_agent = FakeAgent()
        pdv3_agent.set_agent("aggstatus", ms())
        pdv3_agent.set_agent("child_agg_status",
                {
                idv[2]: ms(),
                idv[3]: ms({AggregateStatusType.AGGREGATE_DATA: DeviceStatusType.STATUS_WARNING}),
            })
        device_agents[pdv[3]] = pdv3_agent

        pdv4_agent = FakeAgent()
        pdv4_agent.set_agent("aggstatus", ms())
        pdv4_agent.set_agent("child_agg_status",
                {
                pdv[5]: ms(),
                pdv[6]: ms(),
                pdv[7]: ms({AggregateStatusType.AGGREGATE_DATA: DeviceStatusType.STATUS_WARNING}),
                idv[4]: ms(),
                })
        device_agents[pdv[4]] = pdv4_agent

        pdv5_agent = FakeAgent()
        pdv5_agent.set_agent("aggstatus", ms())
        pdv5_agent.set_agent("child_agg_status",
                {
                pdv[6]: ms(),
                pdv[7]: ms({AggregateStatusType.AGGREGATE_DATA: DeviceStatusType.STATUS_WARNING}),
                idv[4]: ms(),
                })
        device_agents[pdv[5]] = pdv5_agent

        pdv6_agent = FakeAgent()
        pdv6_agent.set_agent("aggstatus", ms())
        pdv6_agent.set_agent("child_agg_status", {})
        device_agents[pdv[6]] = pdv6_agent

        pdv7_agent = FakeAgent()
        pdv7_agent.set_agent("aggstatus", ms({AggregateStatusType.AGGREGATE_DATA: DeviceStatusType.STATUS_WARNING}))
        pdv7_agent.set_agent("child_agg_status",
                {
                idv[4]: ms(),
                })
        device_agents[pdv[7]] = pdv7_agent

        pdv8_agent = FakeAgent()
        pdv8_agent.set_agent("aggstatus", ms())
        pdv8_agent.set_agent("child_agg_status",
                {
                pdv[9]: ms(),
                pdv[10]: ms(),
                idv[5]: ms({AggregateStatusType.AGGREGATE_DATA: DeviceStatusType.STATUS_WARNING}),
                pdv[11]: ms(),
                idv[6]: ms({AggregateStatusType.AGGREGATE_DATA: DeviceStatusType.STATUS_CRITICAL}),
                })
        device_agents[pdv[8]] = pdv8_agent

        pdv9_agent = FakeAgent()
        pdv9_agent.set_agent("aggstatus", ms())
        pdv9_agent.set_agent("child_agg_status",
                {
                pdv[10]: ms(),
                idv[5]: ms({AggregateStatusType.AGGREGATE_DATA: DeviceStatusType.STATUS_WARNING}),
                pdv[11]: ms(),
                idv[6]: ms({AggregateStatusType.AGGREGATE_DATA: DeviceStatusType.STATUS_CRITICAL}),
                })
        device_agents[pdv[9]] = pdv9_agent

        pdv10_agent = FakeAgent()
        pdv10_agent.set_agent("aggstatus", ms())
        pdv10_agent.set_agent("child_agg_status",
                {
                idv[5]: ms({AggregateStatusType.AGGREGATE_DATA: DeviceStatusType.STATUS_WARNING}),
                })
        device_agents[pdv[10]] = pdv10_agent

        pdv11_agent = FakeAgent()
        pdv11_agent.set_agent("aggstatus", ms())
        pdv11_agent.set_agent("child_agg_status",
                {
                idv[6]: ms({AggregateStatusType.AGGREGATE_DATA: DeviceStatusType.STATUS_CRITICAL}),
                })
        device_agents[pdv[8]] = pdv11_agent

        self.device_agents = device_agents

        self.IMS_ASB._get_agent_client = self.my_get_agent_client
        self.OMS_ASB._get_agent_client = self.my_get_agent_client

        # save created ids
        self.org_id = org_id
        self.obs_id = obs_id
        self.pst = pst
        self.pdv = pdv
        self.ist = ist
        self.idv = idv

        log.info("org ID:                 %s", org_id)
        log.info("observatory ID:         %s", obs_id)
        for k, v in self.pst.iteritems():
            log.info("platform site ID %s:     %s", k, v)
        for k, v in self.ist.iteritems():
            log.info("instrument site ID %s:   %s", k, v)
        for k, v in self.pdv.iteritems():
            log.info("platform device ID %s:   %s", k, v)
        for k, v in self.idv.iteritems():
            log.info("instrument device ID %s: %s", k, v)



    # define a function to get the agent client, using our fake agents
    def my_get_agent_client(self, device_id, **kwargs):
        try:
            return self.device_agents[device_id]
        except KeyError:
            raise BadRequest("Tried to retrieve status for undefined device '%s'" % device_id)


    # some quick checks to help us debug the structure and statuses, to isolate problems
    def check_structure_assumptions(self):
        # check that all objects exist in the RR
        for adict in [self.pst, self.pdv, self.ist, self.idv]:
            for id in adict: assert id

        # pst1 should have status critical, pdev1 should be ok, and idv1/ist1 should be critical
        self.assertEqual(self.pdv[1], self.RR2.find_platform_device_id_of_platform_site_using_has_device(self.pst[1]))
        self.assertEqual(self.ist[1], self.RR2.find_instrument_site_id_of_platform_site_using_has_site(self.pst[1]))
        self.assertEqual(self.idv[1], self.RR2.find_instrument_device_id_of_instrument_site_using_has_device(self.ist[1]))
        self.assertEqual(DeviceStatusType.STATUS_CRITICAL,
                         self.my_get_agent_client(self.idv[1]).get_agent(["aggstatus"])["aggstatus"][AggregateStatusType.AGGREGATE_DATA])

        # pdv4 should have status warning, coming from pdv7
        self.assertEqual(self.pdv[5], self.RR2.find_platform_device_id_of_platform_device_using_has_device(self.pdv[4]))
        self.assertIn(self.pdv[6], self.RR2.find_platform_device_ids_of_platform_device_using_has_device(self.pdv[5]))
        self.assertIn(self.pdv[7], self.RR2.find_platform_device_ids_of_platform_device_using_has_device(self.pdv[5]))
        self.assertEqual(self.idv[4], self.RR2.find_instrument_device_id_of_platform_device_using_has_device(self.pdv[7]))
        self.assertEqual(DeviceStatusType.STATUS_OK,
                         self.my_get_agent_client(self.idv[4]).get_agent(["aggstatus"])["aggstatus"][AggregateStatusType.AGGREGATE_DATA])
        self.assertEqual(DeviceStatusType.STATUS_WARNING,
                         self.my_get_agent_client(self.pdv[7]).get_agent(["aggstatus"])["aggstatus"][AggregateStatusType.AGGREGATE_DATA])


    @unittest.skip("errors in outil prevent this from passing")
    def test_complex_rollup_structure(self):

        self.check_structure_assumptions()

        o = DeviceStatusType.STATUS_OK
        u = DeviceStatusType.STATUS_UNKNOWN
        w = DeviceStatusType.STATUS_WARNING
        c = DeviceStatusType.STATUS_CRITICAL

        pst_stat = ["ignore", c, c, w, w, u, w, o, w]
        pdv_stat = ["ignore", o, w, w, w, w, o, w, c, c, w, c]
        ist_stat = ["ignore", c, o, w, u, o, u]
        idv_stat = ["ignore", c, o, w, o, w, c]

        for i, id in self.idv.iteritems():
            label = "InstrumentDevice %s" % i
            log.info("Checking rollup of %s", label)
            self.assertProperRollup(label, self.IMS.get_instrument_device_extension(id), idv_stat[i])

        for i, id in self.ist.iteritems():
            label = "InstrumentSite %s" % i
            log.info("Checking rollup of %s", label)
            self.assertProperRollup(label, self.OMS.get_site_extension(id), ist_stat[i])

        for i, id in self.pdv.iteritems():
            label = "PlatformDevice %s" % i
            log.info("Checking rollup of %s", label)
            self.assertProperRollup(label, self.IMS.get_platform_device_extension(id), pdv_stat[i])

        for i, id in self.pst.iteritems():
            label = "PlatformSite %s" % i
            log.info("Checking rollup of %s", label)
            self.assertProperRollup(label, self.OMS.get_site_extension(id), pst_stat[i])

        #TODO: check observatory and org rollups!



    #TODO: REMOVE THIS TEST when test_complex_rollup_structure is fixed
    #@unittest.skip("phasing out")
    def test_complex_rollup_structure_partially(self):

        o = DeviceStatusType.STATUS_OK
        u = DeviceStatusType.STATUS_UNKNOWN
        w = DeviceStatusType.STATUS_WARNING
        c = DeviceStatusType.STATUS_CRITICAL

        idv_stat = ["ignore", c, o, w, o, w, c]
        ist_stat = ["ignore", c, o, w, u, o, u]

        for i, id in self.idv.iteritems():
            label = "InstrumentDevice %s" % i
            log.info("Checking rollup of %s", label)
            self.assertProperRollup(label, self.IMS.get_instrument_device_extension(id), idv_stat[i])

        for i, id in self.ist.iteritems():
            label = "InstrumentSite %s" % i
            log.info("Checking rollup of %s", label)
            self.assertProperRollup(label, self.OMS.get_site_extension(id), ist_stat[i])



    def assertProperRollup(self, label, extended_resource, status):
        m = DeviceStatusType._str_map
        s = extended_resource.computed.data_status_roll_up.status
        v = extended_resource.computed.data_status_roll_up.value
        self.assertEqual(ComputedValueAvailability.PROVIDED, s)
        message = "Expected rollup status of %s to be %s but got %s" % (label, m[status], m.get(v, "?? %s" % v))
        self.assertEqual(status, v, message)

    # get an object of a specific type from within another python object
    def _get_specific_attr(self, parent_obj, attrtype):
        for d in dir(parent_obj):
            a = getattr(parent_obj, d)
            if isinstance(a, attrtype):
                return a

        return None


    # get a service of a given type from the capability container
    def _get_svc(self, service_cls):
        # get service from container proc manager
        relevant_services = [
        item[1] for item in self.container.proc_manager.procs.items()
        if isinstance(item[1], service_cls)
        ]

        assert (0 < len(relevant_services)),\
        "no services of type '%s' found running in container!" % service_cls

        service_itself = relevant_services[0]
        assert service_itself
        return service_itself
class TestObservatoryManagementServiceIntegration(IonIntegrationTestCase):

    def setUp(self):
        # Start container
        #print 'instantiating container'
        self._start_container()
        #container = Container()
        #print 'starting container'
        #container.start()
        #print 'started container'

        self.container.start_rel_from_url('res/deploy/r2deploy.yml')
        self.RR = ResourceRegistryServiceClient(node=self.container.node)
        self.OMS = ObservatoryManagementServiceClient(node=self.container.node)
        self.org_management_service = OrgManagementServiceClient(node=self.container.node)
        self.IMS =  InstrumentManagementServiceClient(node=self.container.node)
        self.dpclient = DataProductManagementServiceClient(node=self.container.node)
        self.pubsubcli =  PubsubManagementServiceClient(node=self.container.node)
        self.damsclient = DataAcquisitionManagementServiceClient(node=self.container.node)
        self.dataset_management = DatasetManagementServiceClient()
        #print 'TestObservatoryManagementServiceIntegration: started services'

        self.event_publisher = EventPublisher()

#    @unittest.skip('this exists only for debugging the launch process')
#    def test_just_the_setup(self):
#        return


    def destroy(self, resource_ids):
        self.OMS.force_delete_observatory(resource_ids.observatory_id)
        self.OMS.force_delete_subsite(resource_ids.subsite_id)
        self.OMS.force_delete_subsite(resource_ids.subsite2_id)
        self.OMS.force_delete_subsite(resource_ids.subsiteb_id)
        self.OMS.force_delete_subsite(resource_ids.subsitez_id)
        self.OMS.force_delete_platform_site(resource_ids.platform_site_id)
        self.OMS.force_delete_platform_site(resource_ids.platform_siteb_id)
        self.OMS.force_delete_platform_site(resource_ids.platform_siteb2_id)
        self.OMS.force_delete_platform_site(resource_ids.platform_site3_id)
        self.OMS.force_delete_instrument_site(resource_ids.instrument_site_id)
        self.OMS.force_delete_instrument_site(resource_ids.instrument_site2_id)
        self.OMS.force_delete_instrument_site(resource_ids.instrument_siteb3_id)
        self.OMS.force_delete_instrument_site(resource_ids.instrument_site4_id)

    #@unittest.skip('targeting')
    def test_resources_associations(self):
        resources = self._make_associations()
        self.destroy(resources)

    #@unittest.skip('targeting')
    def test_find_related_frames_of_reference(self):
        # finding subordinates gives a dict of obj lists, convert objs to ids
        def idify(adict):
            ids = {}
            for k, v in adict.iteritems():
                ids[k] = []
                for obj in v:
                    ids[k].append(obj._id)

            return ids

        # a short version of the function we're testing, with id-ify
        def short(resource_id, output_types):
            ret = self.OMS.find_related_frames_of_reference(resource_id,
                                                            output_types)
            return idify(ret)
            
            
        #set up associations first
        stuff = self._make_associations()
        #basic traversal of tree from instrument to platform
        ids = short(stuff.instrument_site_id, [RT.PlatformSite])
        self.assertIn(RT.PlatformSite, ids)
        self.assertIn(stuff.platform_site_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_siteb_id, ids[RT.PlatformSite])
        self.assertNotIn(stuff.platform_siteb2_id, ids[RT.PlatformSite])

        #since this is the first search, just make sure the input inst_id got stripped
        if RT.InstrumentSite in ids:
            self.assertNotIn(stuff.instrument_site_id, ids[RT.InstrumentSite])

        #basic traversal of tree from platform to instrument
        ids = short(stuff.platform_siteb_id, [RT.InstrumentSite])
        self.assertIn(RT.InstrumentSite, ids)
        self.assertIn(stuff.instrument_site_id, ids[RT.InstrumentSite])
        self.assertNotIn(stuff.instrument_site2_id, ids[RT.InstrumentSite])


        #full traversal of tree from observatory down to instrument
        ids = short(stuff.observatory_id, [RT.InstrumentSite])
        self.assertIn(RT.InstrumentSite, ids)
        self.assertIn(stuff.instrument_site_id, ids[RT.InstrumentSite])


        #full traversal of tree from instrument to observatory
        ids = short(stuff.instrument_site_id, [RT.Observatory])
        self.assertIn(RT.Observatory, ids)
        self.assertIn(stuff.observatory_id, ids[RT.Observatory])


        #partial traversal, only down to platform
        ids = short(stuff.observatory_id, [RT.Subsite, RT.PlatformSite])
        self.assertIn(RT.PlatformSite, ids)
        self.assertIn(RT.Subsite, ids)
        self.assertIn(stuff.platform_site_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_siteb_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_siteb2_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_site3_id, ids[RT.PlatformSite])
        self.assertIn(stuff.subsite_id, ids[RT.Subsite])
        self.assertIn(stuff.subsite2_id, ids[RT.Subsite])
        self.assertIn(stuff.subsitez_id, ids[RT.Subsite])
        self.assertIn(stuff.subsiteb_id, ids[RT.Subsite])
        self.assertNotIn(RT.InstrumentSite, ids)


        #partial traversal, only down to platform
        ids = short(stuff.instrument_site_id, [RT.Subsite, RT.PlatformSite])
        self.assertIn(RT.PlatformSite, ids)
        self.assertIn(RT.Subsite, ids)
        self.assertIn(stuff.platform_siteb_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_site_id, ids[RT.PlatformSite])
        self.assertIn(stuff.subsite_id, ids[RT.Subsite])
        self.assertIn(stuff.subsiteb_id, ids[RT.Subsite])
        self.assertNotIn(stuff.subsite2_id, ids[RT.Subsite])
        self.assertNotIn(stuff.subsitez_id, ids[RT.Subsite])
        self.assertNotIn(stuff.platform_siteb2_id, ids[RT.PlatformSite])
        self.assertNotIn(RT.Observatory, ids)

        self.destroy(stuff)

    def _make_associations(self):
        """
        create one of each resource and association used by OMS
        to guard against problems in ion-definitions
        """

        #raise unittest.SkipTest("https://jira.oceanobservatories.org/tasks/browse/CISWCORE-41")
        

        """
        the tree we're creating (observatory, sites, platforms, instruments)

        rows are lettered, colums numbered.  
         - first row is implied a
         - first column is implied 1
         - site Z, just because 

        O--Sz
        |
        S--S2--P3--I4
        |
        Sb-Pb2-Ib3
        |
        P--I2 <- PlatformDevice, InstrumentDevice2
        |
        Pb <- PlatformDevice b
        |
        I <- InstrumentDevice

        """

        org_id = self.OMS.create_marine_facility(any_old(RT.Org))

        def create_under_org(resource_type):
            obj = any_old(resource_type)

            if RT.InstrumentDevice == resource_type:
                resource_id = self.IMS.create_instrument_device(obj)
            else:
                resource_id, _ = self.RR.create(obj)

            self.OMS.assign_resource_to_observatory_org(resource_id=resource_id, org_id=org_id)
            return resource_id

        #stuff we control
        observatory_id          = create_under_org(RT.Observatory)
        subsite_id              = create_under_org(RT.Subsite)
        subsite2_id             = create_under_org(RT.Subsite)
        subsiteb_id             = create_under_org(RT.Subsite)
        subsitez_id             = create_under_org(RT.Subsite)
        platform_site_id        = create_under_org(RT.PlatformSite)
        platform_siteb_id       = create_under_org(RT.PlatformSite)
        platform_siteb2_id      = create_under_org(RT.PlatformSite)
        platform_site3_id       = create_under_org(RT.PlatformSite)
        instrument_site_id      = create_under_org(RT.InstrumentSite)
        instrument_site2_id     = create_under_org(RT.InstrumentSite)
        instrument_siteb3_id    = create_under_org(RT.InstrumentSite)
        instrument_site4_id     = create_under_org(RT.InstrumentSite)

        #stuff we associate to
        instrument_device_id    = create_under_org(RT.InstrumentDevice)
        instrument_device2_id   = create_under_org(RT.InstrumentDevice)
        platform_device_id      = create_under_org(RT.PlatformDevice)
        platform_deviceb_id     = create_under_org(RT.PlatformDevice)
        instrument_model_id, _  = self.RR.create(any_old(RT.InstrumentModel))
        platform_model_id, _    = self.RR.create(any_old(RT.PlatformModel))
        deployment_id, _        = self.RR.create(any_old(RT.Deployment))

        #observatory
        self.RR.create_association(observatory_id, PRED.hasSite, subsite_id)
        self.RR.create_association(observatory_id, PRED.hasSite, subsitez_id)

        #site
        self.RR.create_association(subsite_id, PRED.hasSite, subsite2_id)
        self.RR.create_association(subsite_id, PRED.hasSite, subsiteb_id)
        self.RR.create_association(subsite2_id, PRED.hasSite, platform_site3_id)
        self.RR.create_association(subsiteb_id, PRED.hasSite, platform_siteb2_id)
        self.RR.create_association(subsiteb_id, PRED.hasSite, platform_site_id)
        
        #platform_site(s)
        self.RR.create_association(platform_site3_id, PRED.hasSite, instrument_site4_id)
        self.RR.create_association(platform_siteb2_id, PRED.hasSite, instrument_siteb3_id)
        self.RR.create_association(platform_site_id, PRED.hasSite, instrument_site2_id)
        self.RR.create_association(platform_site_id, PRED.hasSite, platform_siteb_id)
        self.RR.create_association(platform_siteb_id, PRED.hasSite, instrument_site_id)

        self.RR.create_association(platform_siteb_id, PRED.hasDevice, platform_deviceb_id)

        self.RR.create_association(platform_site_id, PRED.hasModel, platform_model_id)
        self.RR.create_association(platform_site_id, PRED.hasDevice, platform_device_id)
        self.RR.create_association(platform_site_id, PRED.hasDeployment, deployment_id)

        #instrument_site(s)
        self.RR.create_association(instrument_site_id, PRED.hasModel, instrument_model_id)
        self.RR.create_association(instrument_site_id, PRED.hasDevice, instrument_device_id)
        self.RR.create_association(instrument_site_id, PRED.hasDeployment, deployment_id)

        self.RR.create_association(instrument_site2_id, PRED.hasDevice, instrument_device2_id)

        #platform_device
        self.RR.create_association(platform_device_id, PRED.hasModel, platform_model_id)

        #instrument_device
        self.RR.create_association(instrument_device_id, PRED.hasModel, instrument_model_id)
        self.RR.create_association(instrument_device2_id, PRED.hasModel, instrument_model_id)

        ret = DotDict()
        ret.org_id                = org_id
        ret.observatory_id        = observatory_id
        ret.subsite_id            = subsite_id
        ret.subsite2_id           = subsite2_id
        ret.subsiteb_id           = subsiteb_id
        ret.subsitez_id           = subsitez_id
        ret.platform_site_id      = platform_site_id
        ret.platform_siteb_id     = platform_siteb_id
        ret.platform_siteb2_id    = platform_siteb2_id
        ret.platform_site3_id     = platform_site3_id
        ret.instrument_site_id    = instrument_site_id
        ret.instrument_site2_id   = instrument_site2_id
        ret.instrument_siteb3_id  = instrument_siteb3_id
        ret.instrument_site4_id   = instrument_site4_id

        ret.instrument_device_id  = instrument_device_id
        ret.instrument_device2_id = instrument_device2_id
        ret.platform_device_id    = platform_device_id
        ret.platform_deviceb_id    = platform_deviceb_id
        ret.instrument_model_id   = instrument_model_id
        ret.platform_model_id     = platform_model_id
        ret.deployment_id         = deployment_id

        return ret

    #@unittest.skip("targeting")
    def test_create_observatory(self):
        observatory_obj = IonObject(RT.Observatory,
                                        name='TestFacility',
                                        description='some new mf')
        observatory_id = self.OMS.create_observatory(observatory_obj)
        self.OMS.force_delete_observatory(observatory_id)


    #@unittest.skip("targeting")
    def test_find_observatory_org(self):
        org_obj = IonObject(RT.Org,
                            name='TestOrg',
                            description='some new mf org')

        org_id =  self.OMS.create_marine_facility(org_obj)

        observatory_obj = IonObject(RT.Observatory,
                                        name='TestObservatory',
                                        description='some new obs')
        observatory_id = self.OMS.create_observatory(observatory_obj)

        #make association
        
        self.OMS.assign_resource_to_observatory_org(observatory_id, org_id)


        #find association

        org_objs = self.OMS.find_org_by_observatory(observatory_id)
        self.assertEqual(1, len(org_objs))
        self.assertEqual(org_id, org_objs[0]._id)
        print("org_id=<" + org_id + ">")

        #create a subsite with parent Observatory
        subsite_obj =  IonObject(RT.Subsite,
                                name= 'TestSubsite',
                                description = 'sample subsite')
        subsite_id = self.OMS.create_subsite(subsite_obj, observatory_id)
        self.assertIsNotNone(subsite_id, "Subsite not created.")

        # verify that Subsite is linked to Observatory
        mf_subsite_assoc = self.RR.get_association(observatory_id, PRED.hasSite, subsite_id)
        self.assertIsNotNone(mf_subsite_assoc, "Subsite not connected to Observatory.")


        # add the Subsite as a resource of this Observatory
        self.OMS.assign_resource_to_observatory_org(resource_id=subsite_id, org_id=org_id)
        # verify that Subsite is linked to Org
        org_subsite_assoc = self.RR.get_association(org_id, PRED.hasResource, subsite_id)
        self.assertIsNotNone(org_subsite_assoc, "Subsite not connected as resource to Org.")


        #create a logical platform with parent Subsite
        platform_site_obj =  IonObject(RT.PlatformSite,
                                name= 'TestPlatformSite',
                                description = 'sample logical platform')
        platform_site_id = self.OMS.create_platform_site(platform_site_obj, subsite_id)
        self.assertIsNotNone(platform_site_id, "PlatformSite not created.")

        # verify that PlatformSite is linked to Site
        site_lp_assoc = self.RR.get_association(subsite_id, PRED.hasSite, platform_site_id)
        self.assertIsNotNone(site_lp_assoc, "PlatformSite not connected to Site.")


        # add the PlatformSite as a resource of this Observatory
        self.OMS.assign_resource_to_observatory_org(resource_id=platform_site_id, org_id=org_id)
        # verify that PlatformSite is linked to Org
        org_lp_assoc = self.RR.get_association(org_id, PRED.hasResource, platform_site_id)
        self.assertIsNotNone(org_lp_assoc, "PlatformSite not connected as resource to Org.")



        #create a logical instrument with parent logical platform
        instrument_site_obj =  IonObject(RT.InstrumentSite,
                                name= 'TestInstrumentSite',
                                description = 'sample logical instrument')
        instrument_site_id = self.OMS.create_instrument_site(instrument_site_obj, platform_site_id)
        self.assertIsNotNone(instrument_site_id, "InstrumentSite not created.")


        # verify that InstrumentSite is linked to PlatformSite
        li_lp_assoc = self.RR.get_association(platform_site_id, PRED.hasSite, instrument_site_id)
        self.assertIsNotNone(li_lp_assoc, "InstrumentSite not connected to PlatformSite.")


        # add the InstrumentSite as a resource of this Observatory
        self.OMS.assign_resource_to_observatory_org(resource_id=instrument_site_id, org_id=org_id)
        # verify that InstrumentSite is linked to Org
        org_li_assoc = self.RR.get_association(org_id, PRED.hasResource, instrument_site_id)
        self.assertIsNotNone(org_li_assoc, "InstrumentSite not connected as resource to Org.")


        # remove the InstrumentSite as a resource of this Observatory
        self.OMS.unassign_resource_from_observatory_org(instrument_site_id, org_id)
        # verify that InstrumentSite is linked to Org
        assocs,_ = self.RR.find_objects(org_id, PRED.hasResource, RT.InstrumentSite, id_only=True )
        self.assertEqual(len(assocs), 0)

        # remove the InstrumentSite
        self.OMS.delete_instrument_site(instrument_site_id)
        assocs, _ = self.RR.find_objects(platform_site_id, PRED.hasSite, RT.InstrumentSite, id_only=True )
        self.assertEqual(len(assocs), 1)
        #todo: remove the dangling association


        # remove the PlatformSite as a resource of this Observatory
        self.OMS.unassign_resource_from_observatory_org(platform_site_id, org_id)
        # verify that PlatformSite is linked to Org
        assocs,_ = self.RR.find_objects(org_id, PRED.hasResource, RT.PlatformSite, id_only=True )
        self.assertEqual(len(assocs), 0)


        # remove the Site as a resource of this Observatory
        self.OMS.unassign_resource_from_observatory_org(subsite_id, org_id)
        # verify that Site is linked to Org
        assocs,_ = self.RR.find_objects(org_id, PRED.hasResource, RT.Subsite, id_only=True )
        self.assertEqual(len(assocs), 0)

        self.RR.delete(org_id)
        self.OMS.force_delete_observatory(observatory_id)
        self.OMS.force_delete_subsite(subsite_id)
        self.OMS.force_delete_platform_site(platform_site_id)
        self.OMS.force_delete_instrument_site(instrument_site_id)


    #@unittest.skip("in development...")
    @attr('EXT')
    def test_observatory_org_extended(self):

        stuff = self._make_associations()

        parsed_pdict_id = self.dataset_management.read_parameter_dictionary_by_name('ctd_parsed_param_dict',
                                                                                    id_only=True)
        parsed_stream_def_id = self.pubsubcli.create_stream_definition(name='parsed',
                                                                       parameter_dictionary_id=parsed_pdict_id)
        tdom, sdom = time_series_domain()
        sdom = sdom.dump()
        tdom = tdom.dump()
        dp_obj = IonObject(RT.DataProduct,
            name='the parsed data',
            description='ctd stream test',
            temporal_domain = tdom,
            spatial_domain = sdom)

        data_product_id1 = self.dpclient.create_data_product(data_product=dp_obj,
                                                             stream_definition_id=parsed_stream_def_id)
        self.damsclient.assign_data_product(input_resource_id=stuff.instrument_device_id,
                                            data_product_id=data_product_id1)


        #--------------------------------------------------------------------------------
        # Get the extended Site (platformSite)
        #--------------------------------------------------------------------------------

        extended_site = self.OMS.get_site_extension(stuff.platform_site_id)
        log.debug("extended_site:  %s ", str(extended_site))
        self.assertEqual(1, len(extended_site.platform_devices))
        self.assertEqual(1, len(extended_site.platform_models))
        self.assertEqual(stuff.platform_device_id, extended_site.platform_devices[0]._id)
        self.assertEqual(stuff.platform_model_id, extended_site.platform_models[0]._id)

        #--------------------------------------------------------------------------------
        # Get the extended Org
        #--------------------------------------------------------------------------------
        #test the extended resource
        extended_org = self.org_management_service.get_marine_facility_extension(stuff.org_id)
        log.debug("test_observatory_org_extended: extended_org:  %s ", str(extended_org))
        #self.assertEqual(2, len(extended_org.instruments_deployed) )
        #self.assertEqual(1, len(extended_org.platforms_not_deployed) )
        self.assertEqual(2, extended_org.number_of_platforms)
        self.assertEqual(2, len(extended_org.platform_models) )

        self.assertEqual(2, extended_org.number_of_instruments)
        self.assertEqual(2, len(extended_org.instrument_models) )

        #test the extended resource of the ION org
        ion_org_id = self.org_management_service.find_org()
        extended_org = self.org_management_service.get_marine_facility_extension(ion_org_id._id)
        log.debug("test_observatory_org_extended: extended_ION_org:  %s ", str(extended_org))
        self.assertEqual(0, len(extended_org.members))
        self.assertEqual(0, extended_org.number_of_platforms)
        #self.assertEqual(1, len(extended_org.sites))



        #--------------------------------------------------------------------------------
        # Get the extended Site
        #--------------------------------------------------------------------------------

        #create device state events to use for op /non-op filtering in extended
        t = get_ion_ts()
        self.event_publisher.publish_event(  ts_created= t,  event_type = 'ResourceAgentStateEvent',
            origin = stuff.instrument_device_id, state=ResourceAgentState.STREAMING  )

        self.event_publisher.publish_event( ts_created= t,   event_type = 'ResourceAgentStateEvent',
            origin = stuff.instrument_device2_id, state=ResourceAgentState.INACTIVE )
        extended_site =  self.OMS.get_site_extension(stuff.instrument_site2_id)


        log.debug("test_observatory_org_extended: extended_site:  %s ", str(extended_site))

        self.dpclient.delete_data_product(data_product_id1)
class TestRegisterAndActivate(IonIntegrationTestCase):
    """
    Integration test cases to confirm registration and activation services
    for marine device resources.
    """

    def setUp(self):
        """
        Test setup.
        """

        # Resources used in the tests.
        # General resources.
        self.actor_id = None
        self.user_info_id = None
        self.org_id = None
        self.obs_id = None

        # Cabled infrastructure.
        self.cabled_platform_model_id = None
        self.cabled_platform_site_id = None
        self.cabled_platform_device_id = None
        self.cabled_platform_agent_id = None
        self.cabled_platform_agent_instance_id = None
        self.cabled_platform_deployment_id = None
        self.cabled_instrument_deployment_id = None
        self.cabled_instrument_model_id = None
        self.cabled_instrument_site_id = None
        self.cabled_instrument_device_id = None
        self.cabled_instrument_agent_id = None
        self.cabled_instrument_agent_instance_id = None
        self.cabled_instrument_deployment_id = None

        # Uncabled infrastructure.
        self.uncabled_platform_model_id = None
        self.uncabled_platform_site_id = None
        self.uncabled_platform_device_id = None
        self.uncabled_platform_agent_id = None
        self.uncabled_platform_agent_instance_id = None
        self.uncabled_instrument_model_id = None
        self.uncabled_instrument_site_id = None
        self.uncabled_instrument_device_id = None
        self.uncabled_instrument_agent_id = None
        self.uncabled_instrument_agent_instance_id = None
        self.uncabled_site_deployment_id = None

        # Start container.
        log.info('Staring capability container.')
        self._start_container()

        # Bring up services in a deploy file (no need to message)
        log.info('Staring deploy services.')
        self.container.start_rel_from_url('res/deploy/r2deploy.yml')

        # Setup service clients.
        self.idms = IdentityManagementServiceClient(node=self.container.node)
        self.oms = ObservatoryManagementServiceClient(node=self.container.node)

        # Add generic resources.
        self._load_system_actors()
        self._create_user()
        self._create_org()
        self._create_observatory()

        # Add cleanup routine.
        self.addCleanup(self._cleanup_resources)


    def _cleanup_resources(self):
        """
        Delete resources created by the tests.
        """

        # Check and clean up cabled resources.
        if self.cabled_instrument_model_id:
            self.oms.unassign_instrument_model_from_instrument_site(
                self.cabled_instrument_model_id, self.cabled_instrument_site_id)
            self.ims.delete_instrument_model(self.cabled_instrument_model_id)
            self.cabled_instrument_model_id = None

        if self.cabled_platform_model_id:
            self.oms.unassign_platform_model_from_platform_site(
                self.cabled_platform_model_id, self.cabled_platform_site_id)
            self.ims.delete_platform_model(self.cabled_platform_model_id)
            self.cabled_platform_model_id = None

        if self.cabled_instrument_site_id:
            self.oms.unassign_site_from_site(self.cabled_instrument_site_id,
                                             self.cabled_platform_site_id)
            self.oms.delete_instrument_site(self.cabled_instrument_site_id)
            self.cabled_instrument_site_id = None

        if self.cabled_platform_site_id:
            self.oms.unassign_site_from_site(self.cabled_platform_site_id,
                                             self.obs_id)
            self.oms.delete_platform_site(self.cabled_platform_site_id)
            self.cabled_platform_site_id = None

        # Check and clean up unclabled resources.
        # TODO

        # Clean up generic resources.
        if self.user_info_id:
            self.idms.delete_user_info(self.user_info_id)
            self.user_info_id = None

        if self.actor_id:
            self.idms.delete_actor_identity(self.actor_id)
            self.actor_id = None

        if self.obs_id:
            self.oms.delete_observatory(self.obs_id)
            self.obs_id = None

        if self.org_id:
            self.container.resource_registry.delete(self.org_id)
            self.org_id = None


    def _load_system_actors(self):
        """
        Retrieve system and webauth actors and headers for later use.
        """

        # Retrieve and store system actor and headers.
        system_actor, _ = self.container.resource_registry.find_resources(
            RT.ActorIdentity,
            name=CFG.system.system_actor,
            id_only=False)
        self.system_actor = system_actor[0] if system_actor else None
        self.system_actor_id = system_actor[0]._id if system_actor \
            else 'anonymous'
        self.system_actor_headers = {
            'ion-actor-id': self.system_actor_id,
            'ion-actor-roles': {'ION': ['ION_MANAGER', 'ORG_MANAGER']},
            'expiry':'0'
        }

        # Retrieve and store webauth actor and headers.
        webauth_actor, _ = self.container.resource_registry.find_resources(
            RT.ActorIdentity,
            name=CFG.get_safe("system.web_authentication_actor",
                              "web_authentication"), id_only=False)
        self.webauth_actor = webauth_actor[0] if webauth_actor else None
        self.webauth_actor_id = webauth_actor[0]._id if webauth_actor \
            else 'anonymous'
        self.webauth_actor_headers = {
            'ion-actor-id': self.webauth_actor_id,
            'ion-actor-roles': {'ION': ['ION_MANAGER', 'ORG_MANAGER']},
            'expiry':'0'
        }


    def _create_user(self):
        """
        Create user resources that serve as device owners.
        This test user does not have contact information,
        user credentials or notification preferences.
        Results in these objects:
        ActorIdentity({'_rev': '1',
            '_id': '07f92986b34e426bba0fca00b73cf4a5',
            'lcstate': 'DEPLOYED',
            'alt_ids': [],
            'description': '',
            'ts_updated': '1391542388312',
            'actor_type': 1,
            'addl': {},
            'ts_created': '1391542388312',
            'availability': 'AVAILABLE',
            'name': 'Identity for Adam Activationtest'})
        UserInfo({'_rev': '1',
            '_id': 'ac8d368e6ea247d996fd60dd0f9c7f89',
            'lcstate': 'DEPLOYED',
            'alt_ids': [],
            'description': 'Activation Test User',
            'tokens': [],
            'ts_updated': '1391542388345',
            'contact': ContactInformation({'individual_names_given': '',
                'city': '', 'roles': [], 'administrative_area': '', 'url': '',
                'country': '', 'variables': [{'name': '', 'value': ''}],
                'organization_name': '', 'postal_code': '',
                'individual_name_family': '', 'phones': [], 'position_name': '',
                'email': '', 'street_address': ''}),
            'variables': [{'name': '', 'value': ''}],
            'addl': {},
            'ts_created': '1391542388345',
            'availability': 'AVAILABLE',
            'name': 'Adam Activationtest'})
        """

        # Basic user attributes for test user.
        user_attrs = {
            'name' : 'Adam Activationtest',
            'description' : 'Activation Test User'
        }

        # Create ActorIdentity.
        actor_name = "Identity for %s" % user_attrs['name']
        actor_identity_obj = IonObject("ActorIdentity", name=actor_name)
        log.trace("creating user %s with headers: %r", user_attrs['name'],
                  self.webauth_actor_headers)
        self.actor_id = self.idms.create_actor_identity(actor_identity_obj,
                                            headers=self.webauth_actor_headers)

        # Create UserInfo.
        user_info_obj = IonObject("UserInfo", **user_attrs)
        self.user_info_id = self.idms.create_user_info(self.actor_id,
                            user_info_obj,headers=self.webauth_actor_headers)


    def _create_org(self):
        """
        Create an org that contains all test infrastructure.
        Results in this object:
        Org({'message_controllable': True,
            '_rev': '1',
            '_id': '9ff82d9f6c7b41f886c6137f54a3086c',
            'lcstate': 'DEPLOYED',
            'alt_ids': [],
            'url': '',
            'description':
            'An Org for Activation Tests',
            'contacts': [],
            'org_governance_name': 'ActiveOrg',
            'institution': Institution({'website': '', 'phone': '',
                'name': '', 'email': ''}),
            'ts_updated': '1391542388395',
            'monitorable': True,
            'org_type': 2,
            'addl': {},
            'ts_created': '1391542388395',
            'availability': 'AVAILABLE',
            'name': 'ActiveOrg'})
        """

        org_attrs = {
            'name' : 'ActiveOrg',
            'description' : 'An Org for Activation Tests',
            'org_type' : OrgTypeEnum.MARINE_FACILITY
        }
        org_obj = IonObject('Org', **org_attrs)
        self.org_id = self.oms.create_marine_facility(org_obj,
                                headers=self.system_actor_headers)


    def _create_observatory(self):
        """
        Create a top level obsevaotry site for the tests.
        Results in this object:
        Observatory({'reference_designator': '',
            'spatial_area_name': '',
            '_id': 'fdcda51901464575913858f98aaf0f41',
            '_rev': '1',
            'lcstate': 'DEPLOYED',
            'alt_ids': [],
            'url': '',
            'description': 'An Observatory for Activation Tests',
            'coordinate_reference_system': GeospatialCoordinateReferenceSystem(
                {'geospatial_latitude_units': '',
                'geospatial_vertical_crs': '',
                'geospatial_geodetic_crs': '',
                'geospatial_vertical_positive': '',
                'geospatial_vertical_units': '',
                'geospatial_longitude_units': ''}),
            'constraint_list': [],
            'environment': 1,
            'ts_updated': '1391544601340',
            'local_name': '',
            'geospatial_point_center': GeospatialIndex({'lat': 0.0, 'lon': 0.0}),
            'addl': {},
            'ts_created': '1391544601340',
            'availability': 'AVAILABLE',
            'name': 'ActiveObservatory'})
        """
        obs_attrs = {
            'name': 'ActiveObservatory',
            'description' : 'An Observatory for Activation Tests'
        }
        obs_obj = IonObject('Observatory', **obs_attrs)
        self.obs_id = self.oms.create_observatory(obs_obj, self.org_id)


    def _create_cabled_resources(self):
        """
        Create preexisting infrastructure for the cabled test environment:
        sites, deployments, models. These are resources that already
        exist in the system due to preload or incremental preload updates.
        PlatformModel
        InstrumentModel
        PlatformSite
        InstrumentSite
        """
        platform_model_attrs = {
            'name' : 'LP Jbox',
            'description' : 'Node Type: LJ',
            'manufacturer' : 'University of Washington',
            'platform_type' : 'Cable Node',
            'platform_family' : 'Low Power JBox',
            'ci_onboard' : False,
            'shore_networked' : True
        }

        instrument_model_attrs = {
            'name': 'Diffuse Vent Fluid 3-D Temperature Array (TMPSF-A)',
            'description': 'Measures temperatures of diffuse flow across the seafloor',
            'reference_designator': 'TMPSFA',
            'class_name': 'Temperature seafloor',
            'mixed_sampling_mode': True,
            'integrated_inductive_modem_available': True,
            'internal_battery': True,
            'addl': {'comments': '', 'connector': '',
                     'makemodel_description': 'XR-420',
                     'input_voltage_range': '',
                     'interface': '',
                     'output_description': '',
                     'class_long_name': 'Temperature_seafloor'},
            'ooi_make_model': 'XR-420',
            'series_name': 'TMPSF Series A',
            'inline_management': True,
            'series_id': 'TMPSFA',
            'subseries_name': 'TMPSF Series A Sub 01',
            'primary_interface': 1,
            'manufacturer': 'RBR Global',
            'family_name': 'Seafloor Properties',
            'class_description': 'Measures temperatures of diffuse flow across the seafloor',
            'class_alternate_name': 'Diffuse Vent Fluid 3-D Temperature Array',
            'subseries_id': 'TMPSFA01',
            'class_id': 'TMPSF',
            'family_id': 'SFL',
            'has_clock': True
        }

        platform_site_attrs = {
            'name' : 'Cabled LP JBOX Platform Site',
            'description' : 'Test Site for a Cabled LP JBOX Platform'
        }

        instrument_site_attrs = {
            'name' : 'Cabled TMPSF Instrument Site',
            'description' : 'Test Site for a Cabled TMPSF Instrument'
        }

        # Create the cabled model preloaded resources.
        platform_model = IonObject('PlatformModel', **platform_model_attrs)
        self.cabled_platform_model_id = self.ims.create_platform_model(platform_model)
        instrument_model = IonObject('InstrumentModel', **instrument_model_attrs)
        self.cabled_instrument_model_id = self.ims.create_instrument_model(
            instrument_model)

        # Create the cabled sites and link them appropriately.
        platform_site = IonObject('', **platform_site_attrs)
        self.cabled_platform_site_id = self.oms.create_platform_site(platform_site)
        self.oms.assign_site_to_site(self.cabled_platform_site_id, self.obs_id)
        instrument_site = IonObject('', **instrument_site_attrs)
        self.cabled_instrument_site_id = self.oms.create_instrument_site(instrument_site)
        self.oms.assign_site_to_site(self.cabled_instrument_site_id, self.cabled_platform_site_id)

        # Assign models to available sites.
        self.oms.assign_platform_model_to_platform_site(
            self.cabled_platform_model_id, self.cabled_platform_site_id)
        self.oms.assign_instrument_model_to_instrument_site(
            self.cabled_instrument_model_id, self.cabled_instrument_site_id)


    def _create_uncabled_resources(self):
        """
        Create preexisting infrastructure for the uncabled test environment:
        sites, deployments, models.
        """
        pass


    def test_cabled_device_activation(self):
        """
        Test registration and activation of cabled device infrastructure.
        """
        pass


    def test_uncabled_device_activation(self):
        """
        Test registration and activation of uncabled device infrastructure.
        """
        pass
class TestObservatoryManagementServiceIntegration(IonIntegrationTestCase):

    def setUp(self):
        # Start container
        #print 'instantiating container'
        self._start_container()
        #container = Container()
        #print 'starting container'
        #container.start()
        #print 'started container'

        self.container.start_rel_from_url('res/deploy/r2deploy.yml')
        self.RR = ResourceRegistryServiceClient(node=self.container.node)
        self.OMS = ObservatoryManagementServiceClient(node=self.container.node)
        #print 'TestObservatoryManagementServiceIntegration: started services'

#    @unittest.skip('this exists only for debugging the launch process')
#    def test_just_the_setup(self):
#        return

    #@unittest.skip('targeting')
    def test_resources_associations(self):
        self._make_associations()


    #@unittest.skip('targeting')    
    def test_find_related_frames_of_reference(self):
        # finding subordinates gives a dict of obj lists, convert objs to ids
        def idify(adict):
            ids = {}
            for k, v in adict.iteritems():
                ids[k] = []
                for obj in v:
                    ids[k].append(obj._id)

            return ids

        # a short version of the function we're testing, with id-ify
        def short(resource_id, output_types):
            ret = self.OMS.find_related_frames_of_reference(resource_id,
                                                            output_types)
            return idify(ret)
            
            
        #set up associations first
        stuff = self._make_associations()
        #basic traversal of tree from instrument to platform
        ids = short(stuff.instrument_site_id, [RT.PlatformSite])
        self.assertIn(RT.PlatformSite, ids)
        self.assertIn(stuff.platform_site_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_siteb_id, ids[RT.PlatformSite])
        self.assertNotIn(stuff.platform_siteb2_id, ids[RT.PlatformSite])

        #since this is the first search, just make sure the input inst_id got stripped
        if RT.InstrumentSite in ids:
            self.assertNotIn(stuff.instrument_site_id, ids[RT.InstrumentSite])

        #basic traversal of tree from platform to instrument
        ids = short(stuff.platform_siteb_id, [RT.InstrumentSite])
        self.assertIn(RT.InstrumentSite, ids)
        self.assertIn(stuff.instrument_site_id, ids[RT.InstrumentSite])
        self.assertNotIn(stuff.instrument_site2_id, ids[RT.InstrumentSite])


        #full traversal of tree from observatory down to instrument
        ids = short(stuff.observatory_id, [RT.InstrumentSite])
        self.assertIn(RT.InstrumentSite, ids)
        self.assertIn(stuff.instrument_site_id, ids[RT.InstrumentSite])


        #full traversal of tree from instrument to observatory
        ids = short(stuff.instrument_site_id, [RT.Observatory])
        self.assertIn(RT.Observatory, ids)
        self.assertIn(stuff.observatory_id, ids[RT.Observatory])


        #partial traversal, only down to platform
        ids = short(stuff.observatory_id, [RT.Subsite, RT.PlatformSite])
        self.assertIn(RT.PlatformSite, ids)
        self.assertIn(RT.Subsite, ids)
        self.assertIn(stuff.platform_site_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_siteb_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_siteb2_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_site3_id, ids[RT.PlatformSite])
        self.assertIn(stuff.subsite_id, ids[RT.Subsite])
        self.assertIn(stuff.subsite2_id, ids[RT.Subsite])
        self.assertIn(stuff.subsitez_id, ids[RT.Subsite])
        self.assertIn(stuff.subsiteb_id, ids[RT.Subsite])
        self.assertNotIn(RT.InstrumentSite, ids)


        #partial traversal, only down to platform
        ids = short(stuff.instrument_site_id, [RT.Subsite, RT.PlatformSite])
        self.assertIn(RT.PlatformSite, ids)
        self.assertIn(RT.Subsite, ids)
        self.assertIn(stuff.platform_siteb_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_site_id, ids[RT.PlatformSite])
        self.assertIn(stuff.subsite_id, ids[RT.Subsite])
        self.assertIn(stuff.subsiteb_id, ids[RT.Subsite])
        self.assertNotIn(stuff.subsite2_id, ids[RT.Subsite])
        self.assertNotIn(stuff.subsitez_id, ids[RT.Subsite])
        self.assertNotIn(stuff.platform_siteb2_id, ids[RT.PlatformSite])
        self.assertNotIn(RT.Observatory, ids)
        

    def _make_associations(self):
        """
        create one of each resource and association used by OMS
        to guard against problems in ion-definitions
        """

        #raise unittest.SkipTest("https://jira.oceanobservatories.org/tasks/browse/CISWCORE-41")
        

        """
        the tree we're creating (observatory, sites, platforms, instruments)

        rows are lettered, colums numbered.  
         - first row is implied a
         - first column is implied 1
         - site Z, just because 

        O--Sz
        |
        S--S2--P3--I4
        |
        Sb-Pb2-Ib3
        |
        P--I2
        |
        Pb
        |
        I

        """

        #stuff we control
        observatory_id, _       = self.RR.create(any_old(RT.Observatory))
        subsite_id, _           = self.RR.create(any_old(RT.Subsite))
        subsite2_id, _          = self.RR.create(any_old(RT.Subsite))
        subsiteb_id, _          = self.RR.create(any_old(RT.Subsite))
        subsitez_id, _          = self.RR.create(any_old(RT.Subsite))
        platform_site_id, _     = self.RR.create(any_old(RT.PlatformSite))
        platform_siteb_id, _    = self.RR.create(any_old(RT.PlatformSite))
        platform_siteb2_id, _   = self.RR.create(any_old(RT.PlatformSite))
        platform_site3_id, _    = self.RR.create(any_old(RT.PlatformSite))
        instrument_site_id, _   = self.RR.create(any_old(RT.InstrumentSite))
        instrument_site2_id, _  = self.RR.create(any_old(RT.InstrumentSite))
        instrument_siteb3_id, _ = self.RR.create(any_old(RT.InstrumentSite))
        instrument_site4_id, _  = self.RR.create(any_old(RT.InstrumentSite))

        #stuff we associate to
        instrument_model_id, _  = self.RR.create(any_old(RT.InstrumentModel))
        instrument_device_id, _ = self.RR.create(any_old(RT.InstrumentDevice))
        platform_model_id, _    = self.RR.create(any_old(RT.PlatformModel))
        platform_device_id, _   = self.RR.create(any_old(RT.PlatformDevice))
        deployment_id, _        = self.RR.create(any_old(RT.Deployment))

        #observatory
        self.RR.create_association(observatory_id, PRED.hasSite, subsite_id)
        self.RR.create_association(observatory_id, PRED.hasSite, subsitez_id)

        #site
        self.RR.create_association(subsite_id, PRED.hasSite, subsite2_id)
        self.RR.create_association(subsite_id, PRED.hasSite, subsiteb_id)
        self.RR.create_association(subsite2_id, PRED.hasSite, platform_site3_id)
        self.RR.create_association(subsiteb_id, PRED.hasSite, platform_siteb2_id)
        self.RR.create_association(subsiteb_id, PRED.hasSite, platform_site_id)
        
        #platform_site
        self.RR.create_association(platform_site3_id, PRED.hasSite, instrument_site4_id)
        self.RR.create_association(platform_siteb2_id, PRED.hasSite, instrument_siteb3_id)
        self.RR.create_association(platform_site_id, PRED.hasSite, instrument_site2_id)
        self.RR.create_association(platform_site_id, PRED.hasSite, platform_siteb_id)
        self.RR.create_association(platform_siteb_id, PRED.hasSite, instrument_site_id)

        self.RR.create_association(platform_site_id, PRED.hasModel, platform_model_id)
        self.RR.create_association(platform_site_id, PRED.hasDevice, platform_device_id)
        self.RR.create_association(platform_site_id, PRED.hasDeployment, deployment_id)

        #instrument_site
        self.RR.create_association(instrument_site_id, PRED.hasModel, instrument_model_id)
        self.RR.create_association(instrument_site_id, PRED.hasDevice, instrument_device_id)
        self.RR.create_association(instrument_site_id, PRED.hasDeployment, deployment_id)


        ret = DotDict()
        ret.observatory_id        = observatory_id
        ret.subsite_id            = subsite_id
        ret.subsite2_id           = subsite2_id
        ret.subsiteb_id           = subsiteb_id
        ret.subsitez_id           = subsitez_id
        ret.platform_site_id      = platform_site_id
        ret.platform_siteb_id     = platform_siteb_id
        ret.platform_siteb2_id    = platform_siteb2_id
        ret.platform_site3_id     = platform_site3_id
        ret.instrument_site_id    = instrument_site_id
        ret.instrument_site2_id   = instrument_site2_id
        ret.instrument_siteb3_id  = instrument_siteb3_id
        ret.instrument_site4_id   = instrument_site4_id

        
        return ret

    #@unittest.skip("targeting")
    def test_create_observatory(self):
        observatory_obj = IonObject(RT.Observatory,
                                        name='TestFacility',
                                        description='some new mf')
        self.OMS.create_observatory(observatory_obj)

    #@unittest.skip("targeting")
    def test_find_observatory_org(self):
        org_obj = IonObject(RT.Org,
                            name='TestOrg',
                            description='some new mf org')

        org_id =  self.OMS.create_marine_facility(org_obj)

        observatory_obj = IonObject(RT.Observatory,
                                        name='TestObservatory',
                                        description='some new obs')
        observatory_id = self.OMS.create_observatory(observatory_obj)

        #make association
        
        self.OMS.assign_resource_to_observatory_org(observatory_id, org_id)


        #find association

        org_objs = self.OMS.find_org_by_observatory(observatory_id)
        self.assertEqual(1, len(org_objs))
        self.assertEqual(org_id, org_objs[0]._id)
        print("org_id=<" + org_id + ">")

        #create a subsite with parent Observatory
        subsite_obj =  IonObject(RT.Subsite,
                                name= 'TestSubsite',
                                description = 'sample subsite')
        subsite_id = self.OMS.create_subsite(subsite_obj, observatory_id)
        self.assertIsNotNone(subsite_id, "Subsite not created.")


        # verify that Subsite is linked to Observatory
        mf_subsite_assoc = self.RR.get_association(observatory_id, PRED.hasSite, subsite_id)
        self.assertIsNotNone(mf_subsite_assoc, "Subsite not connected to Observatory.")


        # add the Subsite as a resource of this Observatory
        self.OMS.assign_resource_to_observatory_org(resource_id=subsite_id, org_id=org_id)
        # verify that Subsite is linked to Org
        org_subsite_assoc = self.RR.get_association(org_id, PRED.hasResource, subsite_id)
        self.assertIsNotNone(org_subsite_assoc, "Subsite not connected as resource to Org.")


        #create a logical platform with parent Subsite
        platform_site_obj =  IonObject(RT.PlatformSite,
                                name= 'TestPlatformSite',
                                description = 'sample logical platform')
        platform_site_id = self.OMS.create_platform_site(platform_site_obj, subsite_id)
        self.assertIsNotNone(platform_site_id, "PlatformSite not created.")


        # verify that PlatformSite is linked to Site
        site_lp_assoc = self.RR.get_association(subsite_id, PRED.hasSite, platform_site_id)
        self.assertIsNotNone(site_lp_assoc, "PlatformSite not connected to Site.")


        # add the PlatformSite as a resource of this Observatory
        self.OMS.assign_resource_to_observatory_org(resource_id=platform_site_id, org_id=org_id)
        # verify that PlatformSite is linked to Org
        org_lp_assoc = self.RR.get_association(org_id, PRED.hasResource, platform_site_id)
        self.assertIsNotNone(org_lp_assoc, "PlatformSite not connected as resource to Org.")



        #create a logical instrument with parent logical platform
        instrument_site_obj =  IonObject(RT.InstrumentSite,
                                name= 'TestInstrumentSite',
                                description = 'sample logical instrument')
        instrument_site_id = self.OMS.create_instrument_site(instrument_site_obj, platform_site_id)
        self.assertIsNotNone(instrument_site_id, "InstrumentSite not created.")


        # verify that InstrumentSite is linked to PlatformSite
        li_lp_assoc = self.RR.get_association(platform_site_id, PRED.hasSite, instrument_site_id)
        self.assertIsNotNone(li_lp_assoc, "InstrumentSite not connected to PlatformSite.")


        # add the InstrumentSite as a resource of this Observatory
        self.OMS.assign_resource_to_observatory_org(resource_id=instrument_site_id, org_id=org_id)
        # verify that InstrumentSite is linked to Org
        org_li_assoc = self.RR.get_association(org_id, PRED.hasResource, instrument_site_id)
        self.assertIsNotNone(org_li_assoc, "InstrumentSite not connected as resource to Org.")


        # remove the InstrumentSite as a resource of this Observatory
        self.OMS.unassign_resource_from_observatory_org(instrument_site_id, org_id)
        # verify that InstrumentSite is linked to Org
        assocs,_ = self.RR.find_objects(org_id, PRED.hasResource, RT.InstrumentSite, id_only=True )
        self.assertEqual(len(assocs), 0)

        # remove the InstrumentSite
        self.OMS.delete_instrument_site(instrument_site_id)
        assocs, _ = self.RR.find_objects(platform_site_id, PRED.hasSite, RT.InstrumentSite, id_only=True )
        self.assertEqual(len(assocs), 1)
        #todo: remove the dangling association


        # remove the PlatformSite as a resource of this Observatory
        self.OMS.unassign_resource_from_observatory_org(platform_site_id, org_id)
        # verify that PlatformSite is linked to Org
        assocs,_ = self.RR.find_objects(org_id, PRED.hasResource, RT.PlatformSite, id_only=True )
        self.assertEqual(len(assocs), 0)


        # remove the Site as a resource of this Observatory
        self.OMS.unassign_resource_from_observatory_org(subsite_id, org_id)
        # verify that Site is linked to Org
        assocs,_ = self.RR.find_objects(org_id, PRED.hasResource, RT.Subsite, id_only=True )
        self.assertEqual(len(assocs), 0)
Example #7
0
class TestObservatoryManagementServiceIntegration(IonIntegrationTestCase):
    def setUp(self):
        # Start container
        #print 'instantiating container'
        self._start_container()
        #container = Container()
        #print 'starting container'
        #container.start()
        #print 'started container'

        self.container.start_rel_from_url('res/deploy/r2deploy.yml')
        self.RR = ResourceRegistryServiceClient(node=self.container.node)
        self.RR2 = EnhancedResourceRegistryClient(self.RR)
        self.OMS = ObservatoryManagementServiceClient(node=self.container.node)
        self.org_management_service = OrgManagementServiceClient(
            node=self.container.node)
        self.IMS = InstrumentManagementServiceClient(node=self.container.node)
        self.dpclient = DataProductManagementServiceClient(
            node=self.container.node)
        self.pubsubcli = PubsubManagementServiceClient(
            node=self.container.node)
        self.damsclient = DataAcquisitionManagementServiceClient(
            node=self.container.node)
        self.dataset_management = DatasetManagementServiceClient()
        #print 'TestObservatoryManagementServiceIntegration: started services'

        self.event_publisher = EventPublisher()

#    @unittest.skip('this exists only for debugging the launch process')
#    def test_just_the_setup(self):
#        return

    def destroy(self, resource_ids):
        self.OMS.force_delete_observatory(resource_ids.observatory_id)
        self.OMS.force_delete_subsite(resource_ids.subsite_id)
        self.OMS.force_delete_subsite(resource_ids.subsite2_id)
        self.OMS.force_delete_subsite(resource_ids.subsiteb_id)
        self.OMS.force_delete_subsite(resource_ids.subsitez_id)
        self.OMS.force_delete_platform_site(resource_ids.platform_site_id)
        self.OMS.force_delete_platform_site(resource_ids.platform_siteb_id)
        self.OMS.force_delete_platform_site(resource_ids.platform_siteb2_id)
        self.OMS.force_delete_platform_site(resource_ids.platform_site3_id)
        self.OMS.force_delete_instrument_site(resource_ids.instrument_site_id)
        self.OMS.force_delete_instrument_site(resource_ids.instrument_site2_id)
        self.OMS.force_delete_instrument_site(
            resource_ids.instrument_siteb3_id)
        self.OMS.force_delete_instrument_site(resource_ids.instrument_site4_id)

    #@unittest.skip('targeting')
    def test_observatory_management(self):
        resources = self._make_associations()

        self._do_test_find_related_sites(resources)

        self._do_test_get_sites_devices_status(resources)

        self._do_test_find_site_data_products(resources)

        self._do_test_find_related_frames_of_reference(resources)

        self._do_test_create_geospatial_point_center(resources)

        self._do_test_find_observatory_org(resources)

        self.destroy(resources)

    def _do_test_find_related_sites(self, resources):

        site_resources, site_children, _, _ = self.OMS.find_related_sites(
            resources.org_id)

        #import sys, pprint
        #print >> sys.stderr, pprint.pformat(site_resources)
        #print >> sys.stderr, pprint.pformat(site_children)

        #self.assertIn(resources.org_id, site_resources)
        self.assertIn(resources.observatory_id, site_resources)
        self.assertIn(resources.subsite_id, site_resources)
        self.assertIn(resources.subsite_id, site_resources)
        self.assertIn(resources.subsite2_id, site_resources)
        self.assertIn(resources.platform_site_id, site_resources)
        self.assertIn(resources.instrument_site_id, site_resources)
        self.assertEquals(len(site_resources), 13)

        self.assertEquals(site_resources[resources.observatory_id].type_,
                          RT.Observatory)

        self.assertIn(resources.org_id, site_children)
        self.assertIn(resources.observatory_id, site_children)
        self.assertIn(resources.subsite_id, site_children)
        self.assertIn(resources.subsite_id, site_children)
        self.assertIn(resources.subsite2_id, site_children)
        self.assertIn(resources.platform_site_id, site_children)
        self.assertNotIn(resources.instrument_site_id, site_children)
        self.assertEquals(len(site_children), 9)

        self.assertIsInstance(site_children[resources.subsite_id], list)
        self.assertEquals(len(site_children[resources.subsite_id]), 2)

    def _do_test_get_sites_devices_status(self, resources):
        #bin/nosetests -s -v --nologcapture ion/services/sa/observatory/test/test_observatory_management_service_integration.py:TestObservatoryManagementServiceIntegration.test_observatory_management

        full_result_dict = self.OMS.get_sites_devices_status(
            parent_resource_ids=[resources.org_id], include_sites=True)

        result_dict = full_result_dict[resources.org_id]

        site_resources = result_dict.get("site_resources", None)
        site_children = result_dict.get("site_children", None)

        self.assertEquals(len(site_resources), 14)
        self.assertEquals(len(site_children), 9)

        full_result_dict = self.OMS.get_sites_devices_status(
            parent_resource_ids=[resources.org_id],
            include_sites=True,
            include_devices=True,
            include_status=True)

        result_dict = full_result_dict[resources.org_id]

        log.debug("RESULT DICT: %s", result_dict.keys())
        site_resources = result_dict.get("site_resources", None)
        site_children = result_dict.get("site_children", None)
        site_status = result_dict.get("site_status", None)

        self.assertEquals(len(site_resources), 14)
        self.assertEquals(len(site_children), 9)

        full_result_dict = self.OMS.get_sites_devices_status(
            parent_resource_ids=[resources.observatory_id],
            include_sites=True,
            include_devices=True,
            include_status=True)

        result_dict = full_result_dict[resources.observatory_id]

        site_resources = result_dict.get("site_resources")
        site_children = result_dict.get("site_children")
        site_status = result_dict.get("site_status")

        self.assertEquals(len(site_resources), 13)
        self.assertEquals(len(site_children), 8)

    def _do_test_find_site_data_products(self, resources):
        res_dict = self.OMS.find_site_data_products(resources.org_id)

        #import sys, pprint
        #print >> sys.stderr, pprint.pformat(res_dict)

        self.assertIsNone(res_dict['data_product_resources'])
        self.assertIn(resources.platform_device_id,
                      res_dict['device_data_products'])
        self.assertIn(resources.instrument_device_id,
                      res_dict['device_data_products'])

    #@unittest.skip('targeting')
    def _do_test_find_related_frames_of_reference(self, stuff):
        # finding subordinates gives a dict of obj lists, convert objs to ids
        def idify(adict):
            ids = {}
            for k, v in adict.iteritems():
                ids[k] = []
                for obj in v:
                    ids[k].append(obj._id)

            return ids

        # a short version of the function we're testing, with id-ify
        def short(resource_id, output_types):
            ret = self.OMS.find_related_frames_of_reference(
                resource_id, output_types)
            return idify(ret)

        #set up associations first
        stuff = self._make_associations()
        #basic traversal of tree from instrument to platform
        ids = short(stuff.instrument_site_id, [RT.PlatformSite])
        self.assertIn(RT.PlatformSite, ids)
        self.assertIn(stuff.platform_site_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_siteb_id, ids[RT.PlatformSite])
        self.assertNotIn(stuff.platform_siteb2_id, ids[RT.PlatformSite])

        #since this is the first search, just make sure the input inst_id got stripped
        if RT.InstrumentSite in ids:
            self.assertNotIn(stuff.instrument_site_id, ids[RT.InstrumentSite])

        #basic traversal of tree from platform to instrument
        ids = short(stuff.platform_siteb_id, [RT.InstrumentSite])
        self.assertIn(RT.InstrumentSite, ids)
        self.assertIn(stuff.instrument_site_id, ids[RT.InstrumentSite])
        self.assertNotIn(stuff.instrument_site2_id, ids[RT.InstrumentSite])

        #full traversal of tree from observatory down to instrument
        ids = short(stuff.observatory_id, [RT.InstrumentSite])
        self.assertIn(RT.InstrumentSite, ids)
        self.assertIn(stuff.instrument_site_id, ids[RT.InstrumentSite])

        #full traversal of tree from instrument to observatory
        ids = short(stuff.instrument_site_id, [RT.Observatory])
        self.assertIn(RT.Observatory, ids)
        self.assertIn(stuff.observatory_id, ids[RT.Observatory])

        #partial traversal, only down to platform
        ids = short(stuff.observatory_id, [RT.Subsite, RT.PlatformSite])
        self.assertIn(RT.PlatformSite, ids)
        self.assertIn(RT.Subsite, ids)
        self.assertIn(stuff.platform_site_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_siteb_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_siteb2_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_site3_id, ids[RT.PlatformSite])
        self.assertIn(stuff.subsite_id, ids[RT.Subsite])
        self.assertIn(stuff.subsite2_id, ids[RT.Subsite])
        self.assertIn(stuff.subsitez_id, ids[RT.Subsite])
        self.assertIn(stuff.subsiteb_id, ids[RT.Subsite])
        self.assertNotIn(RT.InstrumentSite, ids)

        #partial traversal, only down to platform
        ids = short(stuff.instrument_site_id, [RT.Subsite, RT.PlatformSite])
        self.assertIn(RT.PlatformSite, ids)
        self.assertIn(RT.Subsite, ids)
        self.assertIn(stuff.platform_siteb_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_site_id, ids[RT.PlatformSite])
        self.assertIn(stuff.subsite_id, ids[RT.Subsite])
        self.assertIn(stuff.subsiteb_id, ids[RT.Subsite])
        self.assertNotIn(stuff.subsite2_id, ids[RT.Subsite])
        self.assertNotIn(stuff.subsitez_id, ids[RT.Subsite])
        self.assertNotIn(stuff.platform_siteb2_id, ids[RT.PlatformSite])
        self.assertNotIn(RT.Observatory, ids)

        self.destroy(stuff)

    def _make_associations(self):
        """
        create one of each resource and association used by OMS
        to guard against problems in ion-definitions
        """

        #raise unittest.SkipTest("https://jira.oceanobservatories.org/tasks/browse/CISWCORE-41")
        """
        the tree we're creating (observatory, sites, platforms, instruments)

        rows are lettered, colums numbered.  
         - first row is implied a
         - first column is implied 1
         - site Z, just because 

        O--Sz
        |
        S--S2--P3--I4
        |
        Sb-Pb2-Ib3
        |
        P--I2 <- PlatformDevice, InstrumentDevice2
        |
        Pb <- PlatformDevice b
        |
        I <- InstrumentDevice

        """

        org_id = self.OMS.create_marine_facility(any_old(RT.Org))

        def create_under_org(resource_type, extra_fields=None):
            obj = any_old(resource_type, extra_fields)

            if RT.InstrumentDevice == resource_type:
                resource_id = self.IMS.create_instrument_device(obj)
            else:
                resource_id, _ = self.RR.create(obj)

            self.OMS.assign_resource_to_observatory_org(
                resource_id=resource_id, org_id=org_id)
            return resource_id

        #stuff we control
        observatory_id = create_under_org(RT.Observatory)
        subsite_id = create_under_org(RT.Subsite)
        subsite2_id = create_under_org(RT.Subsite)
        subsiteb_id = create_under_org(RT.Subsite)
        subsitez_id = create_under_org(RT.Subsite)
        platform_site_id = create_under_org(RT.PlatformSite)
        platform_siteb_id = create_under_org(RT.PlatformSite)
        platform_siteb2_id = create_under_org(RT.PlatformSite)
        platform_site3_id = create_under_org(RT.PlatformSite)
        instrument_site_id = create_under_org(RT.InstrumentSite)
        instrument_site2_id = create_under_org(RT.InstrumentSite)
        instrument_siteb3_id = create_under_org(RT.InstrumentSite)
        instrument_site4_id = create_under_org(RT.InstrumentSite)

        #stuff we associate to
        instrument_device_id = create_under_org(RT.InstrumentDevice)
        instrument_device2_id = create_under_org(RT.InstrumentDevice)
        platform_device_id = create_under_org(RT.PlatformDevice)
        platform_deviceb_id = create_under_org(RT.PlatformDevice)
        instrument_model_id, _ = self.RR.create(any_old(RT.InstrumentModel))
        platform_model_id, _ = self.RR.create(any_old(RT.PlatformModel))
        deployment_id, _ = self.RR.create(any_old(RT.Deployment))

        # marine tracking resources
        asset_id = create_under_org(RT.Asset)
        asset_type_id = create_under_org(RT.AssetType)
        event_duration_id = create_under_org(RT.EventDuration)
        event_duration_type_id = create_under_org(RT.EventDurationType)

        #observatory
        self.RR.create_association(observatory_id, PRED.hasSite, subsite_id)
        self.RR.create_association(observatory_id, PRED.hasSite, subsitez_id)

        #site
        self.RR.create_association(subsite_id, PRED.hasSite, subsite2_id)
        self.RR.create_association(subsite_id, PRED.hasSite, subsiteb_id)
        self.RR.create_association(subsite2_id, PRED.hasSite,
                                   platform_site3_id)
        self.RR.create_association(subsiteb_id, PRED.hasSite,
                                   platform_siteb2_id)
        self.RR.create_association(subsiteb_id, PRED.hasSite, platform_site_id)

        #platform_site(s)
        self.RR.create_association(platform_site3_id, PRED.hasSite,
                                   instrument_site4_id)
        self.RR.create_association(platform_siteb2_id, PRED.hasSite,
                                   instrument_siteb3_id)
        self.RR.create_association(platform_site_id, PRED.hasSite,
                                   instrument_site2_id)
        self.RR.create_association(platform_site_id, PRED.hasSite,
                                   platform_siteb_id)
        self.RR.create_association(platform_siteb_id, PRED.hasSite,
                                   instrument_site_id)

        self.RR.create_association(platform_siteb_id, PRED.hasDevice,
                                   platform_deviceb_id)
        #test network parent link
        self.OMS.assign_device_to_network_parent(platform_device_id,
                                                 platform_deviceb_id)

        self.RR.create_association(platform_site_id, PRED.hasModel,
                                   platform_model_id)
        self.RR.create_association(platform_site_id, PRED.hasDevice,
                                   platform_device_id)
        self.RR.create_association(platform_site_id, PRED.hasDeployment,
                                   deployment_id)

        #instrument_site(s)
        self.RR.create_association(instrument_site_id, PRED.hasModel,
                                   instrument_model_id)
        self.RR.create_association(instrument_site_id, PRED.hasDevice,
                                   instrument_device_id)
        self.RR.create_association(instrument_site_id, PRED.hasDeployment,
                                   deployment_id)

        self.RR.create_association(instrument_site2_id, PRED.hasDevice,
                                   instrument_device2_id)

        #platform_device
        self.RR.create_association(platform_device_id, PRED.hasModel,
                                   platform_model_id)

        #instrument_device
        self.RR.create_association(instrument_device_id, PRED.hasModel,
                                   instrument_model_id)
        self.RR.create_association(instrument_device2_id, PRED.hasModel,
                                   instrument_model_id)

        ret = DotDict()
        ret.org_id = org_id
        ret.observatory_id = observatory_id
        ret.subsite_id = subsite_id
        ret.subsite2_id = subsite2_id
        ret.subsiteb_id = subsiteb_id
        ret.subsitez_id = subsitez_id
        ret.platform_site_id = platform_site_id
        ret.platform_siteb_id = platform_siteb_id
        ret.platform_siteb2_id = platform_siteb2_id
        ret.platform_site3_id = platform_site3_id
        ret.instrument_site_id = instrument_site_id
        ret.instrument_site2_id = instrument_site2_id
        ret.instrument_siteb3_id = instrument_siteb3_id
        ret.instrument_site4_id = instrument_site4_id

        ret.instrument_device_id = instrument_device_id
        ret.instrument_device2_id = instrument_device2_id
        ret.platform_device_id = platform_device_id
        ret.platform_deviceb_id = platform_deviceb_id
        ret.instrument_model_id = instrument_model_id
        ret.platform_model_id = platform_model_id
        ret.deployment_id = deployment_id

        ret.asset_id = asset_id
        ret.asset_type_id = asset_type_id
        ret.event_duration_id = event_duration_id
        ret.event_duration_type_id = event_duration_type_id

        return ret

    #@unittest.skip("targeting")
    def test_create_observatory(self):
        observatory_obj = IonObject(RT.Observatory,
                                    name='TestFacility',
                                    description='some new mf')
        observatory_id = self.OMS.create_observatory(observatory_obj)
        self.OMS.force_delete_observatory(observatory_id)

    #@unittest.skip("targeting")
    def _do_test_create_geospatial_point_center(self, resources):
        platformsite_obj = IonObject(RT.PlatformSite,
                                     name='TestPlatformSite',
                                     description='some new TestPlatformSite')
        geo_index_obj = IonObject(OT.GeospatialBounds)
        geo_index_obj.geospatial_latitude_limit_north = 20.0
        geo_index_obj.geospatial_latitude_limit_south = 10.0
        geo_index_obj.geospatial_longitude_limit_east = 15.0
        geo_index_obj.geospatial_longitude_limit_west = 20.0
        platformsite_obj.constraint_list = [geo_index_obj]

        platformsite_id = self.OMS.create_platform_site(platformsite_obj)

        # now get the dp back to see if it was updated
        platformsite_obj = self.OMS.read_platform_site(platformsite_id)
        self.assertEquals('some new TestPlatformSite',
                          platformsite_obj.description)
        self.assertAlmostEqual(15.0,
                               platformsite_obj.geospatial_point_center.lat,
                               places=1)

        #now adjust a few params
        platformsite_obj.description = 'some old TestPlatformSite'
        geo_index_obj = IonObject(OT.GeospatialBounds)
        geo_index_obj.geospatial_latitude_limit_north = 30.0
        geo_index_obj.geospatial_latitude_limit_south = 20.0
        platformsite_obj.constraint_list = [geo_index_obj]
        update_result = self.OMS.update_platform_site(platformsite_obj)

        # now get the dp back to see if it was updated
        platformsite_obj = self.OMS.read_platform_site(platformsite_id)
        self.assertEquals('some old TestPlatformSite',
                          platformsite_obj.description)
        self.assertAlmostEqual(25.0,
                               platformsite_obj.geospatial_point_center.lat,
                               places=1)

        self.OMS.force_delete_platform_site(platformsite_id)

    #@unittest.skip("targeting")
    def _do_test_find_observatory_org(self, resources):
        log.debug("Make TestOrg")
        org_obj = IonObject(RT.Org,
                            name='TestOrg',
                            description='some new mf org')

        org_id = self.OMS.create_marine_facility(org_obj)

        log.debug("Make Observatory")
        observatory_obj = IonObject(RT.Observatory,
                                    name='TestObservatory',
                                    description='some new obs')
        observatory_id = self.OMS.create_observatory(observatory_obj)

        log.debug("assign observatory to org")
        self.OMS.assign_resource_to_observatory_org(observatory_id, org_id)

        log.debug("verify assigment")
        org_objs = self.OMS.find_org_by_observatory(observatory_id)
        self.assertEqual(1, len(org_objs))
        self.assertEqual(org_id, org_objs[0]._id)
        log.debug("org_id=<" + org_id + ">")

        log.debug("create a subsite with parent Observatory")
        subsite_obj = IonObject(RT.Subsite,
                                name='TestSubsite',
                                description='sample subsite')
        subsite_id = self.OMS.create_subsite(subsite_obj, observatory_id)
        self.assertIsNotNone(subsite_id, "Subsite not created.")

        log.debug("verify that Subsite is linked to Observatory")
        mf_subsite_assoc = self.RR.get_association(observatory_id,
                                                   PRED.hasSite, subsite_id)
        self.assertIsNotNone(mf_subsite_assoc,
                             "Subsite not connected to Observatory.")

        log.debug("add the Subsite as a resource of this Observatory")
        self.OMS.assign_resource_to_observatory_org(resource_id=subsite_id,
                                                    org_id=org_id)
        log.debug("verify that Subsite is linked to Org")
        org_subsite_assoc = self.RR.get_association(org_id, PRED.hasResource,
                                                    subsite_id)
        self.assertIsNotNone(org_subsite_assoc,
                             "Subsite not connected as resource to Org.")

        log.debug("create a logical platform with parent Subsite")
        platform_site_obj = IonObject(RT.PlatformSite,
                                      name='TestPlatformSite',
                                      description='sample logical platform')
        platform_site_id = self.OMS.create_platform_site(
            platform_site_obj, subsite_id)
        self.assertIsNotNone(platform_site_id, "PlatformSite not created.")

        log.debug("verify that PlatformSite is linked to Site")
        site_lp_assoc = self.RR.get_association(subsite_id, PRED.hasSite,
                                                platform_site_id)
        self.assertIsNotNone(site_lp_assoc,
                             "PlatformSite not connected to Site.")

        log.debug("add the PlatformSite as a resource of this Observatory")
        self.OMS.assign_resource_to_observatory_org(
            resource_id=platform_site_id, org_id=org_id)
        log.debug("verify that PlatformSite is linked to Org")
        org_lp_assoc = self.RR.get_association(org_id, PRED.hasResource,
                                               platform_site_id)
        self.assertIsNotNone(org_lp_assoc,
                             "PlatformSite not connected as resource to Org.")

        log.debug("create a logical instrument with parent logical platform")
        instrument_site_obj = IonObject(
            RT.InstrumentSite,
            name='TestInstrumentSite',
            description='sample logical instrument')
        instrument_site_id = self.OMS.create_instrument_site(
            instrument_site_obj, platform_site_id)
        self.assertIsNotNone(instrument_site_id, "InstrumentSite not created.")

        log.debug("verify that InstrumentSite is linked to PlatformSite")
        li_lp_assoc = self.RR.get_association(platform_site_id, PRED.hasSite,
                                              instrument_site_id)
        self.assertIsNotNone(li_lp_assoc,
                             "InstrumentSite not connected to PlatformSite.")

        log.debug("add the InstrumentSite as a resource of this Observatory")
        self.OMS.assign_resource_to_observatory_org(
            resource_id=instrument_site_id, org_id=org_id)
        log.debug("verify that InstrumentSite is linked to Org")
        org_li_assoc = self.RR.get_association(org_id, PRED.hasResource,
                                               instrument_site_id)
        self.assertIsNotNone(
            org_li_assoc, "InstrumentSite not connected as resource to Org.")

        log.debug(
            "remove the InstrumentSite as a resource of this Observatory")
        self.OMS.unassign_resource_from_observatory_org(
            instrument_site_id, org_id)
        log.debug("verify that InstrumentSite is linked to Org")
        assocs, _ = self.RR.find_objects(org_id,
                                         PRED.hasResource,
                                         RT.InstrumentSite,
                                         id_only=True)
        self.assertEqual(0, len(assocs))

        log.debug(
            "remove the InstrumentSite, association should drop automatically")
        self.OMS.delete_instrument_site(instrument_site_id)
        assocs, _ = self.RR.find_objects(platform_site_id,
                                         PRED.hasSite,
                                         RT.InstrumentSite,
                                         id_only=True)
        self.assertEqual(0, len(assocs))

        log.debug("remove the PlatformSite as a resource of this Observatory")
        self.OMS.unassign_resource_from_observatory_org(
            platform_site_id, org_id)
        log.debug("verify that PlatformSite is linked to Org")
        assocs, _ = self.RR.find_objects(org_id,
                                         PRED.hasResource,
                                         RT.PlatformSite,
                                         id_only=True)
        self.assertEqual(0, len(assocs))

        log.debug("remove the Site as a resource of this Observatory")
        self.OMS.unassign_resource_from_observatory_org(subsite_id, org_id)
        log.debug("verify that Site is linked to Org")
        assocs, _ = self.RR.find_objects(org_id,
                                         PRED.hasResource,
                                         RT.Subsite,
                                         id_only=True)
        self.assertEqual(0, len(assocs))

        self.RR.delete(org_id)
        self.OMS.force_delete_observatory(observatory_id)
        self.OMS.force_delete_subsite(subsite_id)
        self.OMS.force_delete_platform_site(platform_site_id)
        self.OMS.force_delete_instrument_site(instrument_site_id)

    @attr('EXT')
    @unittest.skipIf(os.getenv(
        'CEI_LAUNCH_TEST', False
    ), 'Skip test while in CEI LAUNCH mode as it depends on modifying CFG on service side'
                     )
    def test_observatory_extensions(self):
        self.patch_cfg(CFG["container"],
                       {"extended_resources": {
                           "strip_results": False
                       }})

        obs_id = self.RR2.create(any_old(RT.Observatory))
        pss_id = self.RR2.create(
            any_old(RT.PlatformSite, dict(alt_resource_type="StationSite")))
        pas_id = self.RR2.create(
            any_old(RT.PlatformSite,
                    dict(alt_resource_type="PlatformAssemblySite")))
        pcs_id = self.RR2.create(
            any_old(RT.PlatformSite,
                    dict(alt_resource_type="PlatformComponentSite")))
        ins_id = self.RR2.create(any_old(RT.InstrumentSite))

        obs_obj = self.RR2.read(obs_id)
        pss_obj = self.RR2.read(pss_id)
        pas_obj = self.RR2.read(pas_id)
        pcs_obj = self.RR2.read(pcs_id)
        ins_obj = self.RR2.read(ins_id)

        self.RR2.create_association(obs_id, PRED.hasSite, pss_id)
        self.RR2.create_association(pss_id, PRED.hasSite, pas_id)
        self.RR2.create_association(pas_id, PRED.hasSite, pcs_id)
        self.RR2.create_association(pcs_id, PRED.hasSite, ins_id)

        extended_obs = self.OMS.get_observatory_site_extension(obs_id,
                                                               user_id=12345)
        self.assertEqual([pss_obj], extended_obs.platform_station_sites)
        self.assertEqual([pas_obj], extended_obs.platform_assembly_sites)
        self.assertEqual([pcs_obj], extended_obs.platform_component_sites)
        self.assertEqual([ins_obj], extended_obs.instrument_sites)

        extended_pss = self.OMS.get_observatory_site_extension(obs_id,
                                                               user_id=12345)
        self.assertEqual([pas_obj], extended_pss.platform_assembly_sites)
        self.assertEqual([pcs_obj], extended_pss.platform_component_sites)
        self.assertEqual([ins_obj], extended_pss.instrument_sites)

        extended_pas = self.OMS.get_observatory_site_extension(pas_id,
                                                               user_id=12345)
        self.assertEqual([pcs_obj], extended_pas.platform_component_sites)
        self.assertEqual([ins_obj], extended_pas.instrument_sites)

        extended_pcs = self.OMS.get_platform_component_site_extension(
            pcs_id, user_id=12345)
        self.assertEqual([ins_obj], extended_pcs.instrument_sites)

    #@unittest.skip("in development...")
    @attr('EXT')
    @attr('EXT1')
    @unittest.skipIf(os.getenv(
        'CEI_LAUNCH_TEST', False
    ), 'Skip test while in CEI LAUNCH mode as it depends on modifying CFG on service side'
                     )
    def test_observatory_org_extended(self):
        self.patch_cfg(CFG["container"],
                       {"extended_resources": {
                           "strip_results": False
                       }})

        stuff = self._make_associations()

        parsed_pdict_id = self.dataset_management.read_parameter_dictionary_by_name(
            'ctd_parsed_param_dict', id_only=True)

        parsed_stream_def_id = self.pubsubcli.create_stream_definition(
            name='parsed', parameter_dictionary_id=parsed_pdict_id)
        dp_obj = IonObject(RT.DataProduct,
                           name='the parsed data',
                           description='ctd stream test')

        data_product_id1 = self.dpclient.create_data_product(
            data_product=dp_obj, stream_definition_id=parsed_stream_def_id)
        self.damsclient.assign_data_product(
            input_resource_id=stuff.instrument_device_id,
            data_product_id=data_product_id1)

        #Create a  user to be used as regular member
        member_actor_obj = IonObject(RT.ActorIdentity, name='org member actor')
        member_actor_id, _ = self.RR.create(member_actor_obj)
        assert (member_actor_id)
        member_actor_header = get_actor_header(member_actor_id)

        member_user_obj = IonObject(RT.UserInfo, name='org member user')
        member_user_id, _ = self.RR.create(member_user_obj)
        assert (member_user_id)

        self.RR.create_association(subject=member_actor_id,
                                   predicate=PRED.hasInfo,
                                   object=member_user_id)

        #Build the Service Agreement Proposal to enroll a user actor
        sap = IonObject(OT.EnrollmentProposal,
                        consumer=member_actor_id,
                        provider=stuff.org_id)

        sap_response = self.org_management_service.negotiate(
            sap, headers=member_actor_header)

        #enroll the member without using negotiation
        self.org_management_service.enroll_member(org_id=stuff.org_id,
                                                  actor_id=member_actor_id)

        #--------------------------------------------------------------------------------
        # Get the extended Site (platformSite)
        #--------------------------------------------------------------------------------

        try:
            extended_site = self.OMS.get_site_extension(stuff.platform_site_id)
        except:
            log.error('failed to get extended site', exc_info=True)
            raise
        log.debug("extended_site:  %r ", extended_site)
        self.assertEquals(stuff.subsiteb_id, extended_site.parent_site._id)
        self.assertEqual(2, len(extended_site.sites))
        self.assertEqual(2, len(extended_site.platform_devices))
        self.assertEqual(2, len(extended_site.platform_models))
        self.assertIn(stuff.platform_device_id,
                      [o._id for o in extended_site.platform_devices])
        self.assertIn(
            stuff.platform_model_id,
            [o._id for o in extended_site.platform_models if o is not None])

        log.debug(
            "verify that PlatformDeviceb is linked to PlatformDevice with hasNetworkParent link"
        )
        associations = self.RR.find_associations(
            subject=stuff.platform_deviceb_id,
            predicate=PRED.hasNetworkParent,
            object=stuff.platform_device_id,
            id_only=True)
        self.assertIsNotNone(
            associations,
            "PlatformDevice child not connected to PlatformDevice parent.")

        #--------------------------------------------------------------------------------
        # Get the extended Org
        #--------------------------------------------------------------------------------
        #test the extended resource
        extended_org = self.OMS.get_marine_facility_extension(stuff.org_id)
        log.debug("test_observatory_org_extended: extended_org:  %s ",
                  str(extended_org))
        #self.assertEqual(2, len(extended_org.instruments_deployed) )
        #self.assertEqual(1, len(extended_org.platforms_not_deployed) )
        self.assertEqual(2, extended_org.number_of_platforms)
        self.assertEqual(2, len(extended_org.platform_models))

        self.assertEqual(2, extended_org.number_of_instruments)
        self.assertEqual(2, len(extended_org.instrument_models))

        self.assertEqual(1, len(extended_org.members))
        self.assertNotEqual(extended_org.members[0]._id, member_actor_id)
        self.assertEqual(extended_org.members[0]._id, member_user_id)

        self.assertEqual(1, len(extended_org.open_requests))

        self.assertTrue(len(extended_site.deployments) > 0)
        self.assertEqual(len(extended_site.deployments),
                         len(extended_site.deployment_info))

        self.assertEqual(1, extended_org.number_of_assets)
        self.assertEqual(1, extended_org.number_of_asset_types)
        self.assertEqual(1, extended_org.number_of_event_durations)
        self.assertEqual(1, extended_org.number_of_event_duration_types)

        #test the extended resource of the ION org
        ion_org_id = self.org_management_service.find_org()
        extended_org = self.OMS.get_marine_facility_extension(ion_org_id._id,
                                                              user_id=12345)
        log.debug("test_observatory_org_extended: extended_ION_org:  %s ",
                  str(extended_org))
        self.assertEqual(1, len(extended_org.members))
        self.assertEqual(0, extended_org.number_of_platforms)
        #self.assertEqual(1, len(extended_org.sites))

        #--------------------------------------------------------------------------------
        # Get the extended Site
        #--------------------------------------------------------------------------------

        #create device state events to use for op /non-op filtering in extended
        t = get_ion_ts()
        self.event_publisher.publish_event(
            ts_created=t,
            event_type='ResourceAgentStateEvent',
            origin=stuff.instrument_device_id,
            state=ResourceAgentState.STREAMING)

        self.event_publisher.publish_event(
            ts_created=t,
            event_type='ResourceAgentStateEvent',
            origin=stuff.instrument_device2_id,
            state=ResourceAgentState.INACTIVE)
        extended_site = self.OMS.get_site_extension(stuff.instrument_site2_id)

        log.debug("test_observatory_org_extended: extended_site:  %s ",
                  str(extended_site))

        self.dpclient.delete_data_product(data_product_id1)
Example #8
0
class TestObservatoryManagementServiceIntegration(IonIntegrationTestCase):

    def setUp(self):
        # Start container
        #print 'instantiating container'
        self._start_container()
        #container = Container()
        #print 'starting container'
        #container.start()
        #print 'started container'

        self.container.start_rel_from_url('res/deploy/r2deploy.yml')
        self.RR = ResourceRegistryServiceClient(node=self.container.node)
        self.OMS = ObservatoryManagementServiceClient(node=self.container.node)
        self.org_management_service = OrgManagementServiceClient(node=self.container.node)
        self.IMS =  InstrumentManagementServiceClient(node=self.container.node)
        self.dpclient = DataProductManagementServiceClient(node=self.container.node)
        self.pubsubcli =  PubsubManagementServiceClient(node=self.container.node)
        self.damsclient = DataAcquisitionManagementServiceClient(node=self.container.node)
        self.dataset_management = DatasetManagementServiceClient()
        #print 'TestObservatoryManagementServiceIntegration: started services'

        self.event_publisher = EventPublisher()

#    @unittest.skip('this exists only for debugging the launch process')
#    def test_just_the_setup(self):
#        return


    def destroy(self, resource_ids):
        self.OMS.force_delete_observatory(resource_ids.observatory_id)
        self.OMS.force_delete_subsite(resource_ids.subsite_id)
        self.OMS.force_delete_subsite(resource_ids.subsite2_id)
        self.OMS.force_delete_subsite(resource_ids.subsiteb_id)
        self.OMS.force_delete_subsite(resource_ids.subsitez_id)
        self.OMS.force_delete_platform_site(resource_ids.platform_site_id)
        self.OMS.force_delete_platform_site(resource_ids.platform_siteb_id)
        self.OMS.force_delete_platform_site(resource_ids.platform_siteb2_id)
        self.OMS.force_delete_platform_site(resource_ids.platform_site3_id)
        self.OMS.force_delete_instrument_site(resource_ids.instrument_site_id)
        self.OMS.force_delete_instrument_site(resource_ids.instrument_site2_id)
        self.OMS.force_delete_instrument_site(resource_ids.instrument_siteb3_id)
        self.OMS.force_delete_instrument_site(resource_ids.instrument_site4_id)

    #@unittest.skip('targeting')
    def test_resources_associations(self):
        resources = self._make_associations()
        self.destroy(resources)

    #@unittest.skip('targeting')
    def test_find_related_frames_of_reference(self):
        # finding subordinates gives a dict of obj lists, convert objs to ids
        def idify(adict):
            ids = {}
            for k, v in adict.iteritems():
                ids[k] = []
                for obj in v:
                    ids[k].append(obj._id)

            return ids

        # a short version of the function we're testing, with id-ify
        def short(resource_id, output_types):
            ret = self.OMS.find_related_frames_of_reference(resource_id,
                                                            output_types)
            return idify(ret)
            
            
        #set up associations first
        stuff = self._make_associations()
        #basic traversal of tree from instrument to platform
        ids = short(stuff.instrument_site_id, [RT.PlatformSite])
        self.assertIn(RT.PlatformSite, ids)
        self.assertIn(stuff.platform_site_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_siteb_id, ids[RT.PlatformSite])
        self.assertNotIn(stuff.platform_siteb2_id, ids[RT.PlatformSite])

        #since this is the first search, just make sure the input inst_id got stripped
        if RT.InstrumentSite in ids:
            self.assertNotIn(stuff.instrument_site_id, ids[RT.InstrumentSite])

        #basic traversal of tree from platform to instrument
        ids = short(stuff.platform_siteb_id, [RT.InstrumentSite])
        self.assertIn(RT.InstrumentSite, ids)
        self.assertIn(stuff.instrument_site_id, ids[RT.InstrumentSite])
        self.assertNotIn(stuff.instrument_site2_id, ids[RT.InstrumentSite])


        #full traversal of tree from observatory down to instrument
        ids = short(stuff.observatory_id, [RT.InstrumentSite])
        self.assertIn(RT.InstrumentSite, ids)
        self.assertIn(stuff.instrument_site_id, ids[RT.InstrumentSite])


        #full traversal of tree from instrument to observatory
        ids = short(stuff.instrument_site_id, [RT.Observatory])
        self.assertIn(RT.Observatory, ids)
        self.assertIn(stuff.observatory_id, ids[RT.Observatory])


        #partial traversal, only down to platform
        ids = short(stuff.observatory_id, [RT.Subsite, RT.PlatformSite])
        self.assertIn(RT.PlatformSite, ids)
        self.assertIn(RT.Subsite, ids)
        self.assertIn(stuff.platform_site_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_siteb_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_siteb2_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_site3_id, ids[RT.PlatformSite])
        self.assertIn(stuff.subsite_id, ids[RT.Subsite])
        self.assertIn(stuff.subsite2_id, ids[RT.Subsite])
        self.assertIn(stuff.subsitez_id, ids[RT.Subsite])
        self.assertIn(stuff.subsiteb_id, ids[RT.Subsite])
        self.assertNotIn(RT.InstrumentSite, ids)


        #partial traversal, only down to platform
        ids = short(stuff.instrument_site_id, [RT.Subsite, RT.PlatformSite])
        self.assertIn(RT.PlatformSite, ids)
        self.assertIn(RT.Subsite, ids)
        self.assertIn(stuff.platform_siteb_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_site_id, ids[RT.PlatformSite])
        self.assertIn(stuff.subsite_id, ids[RT.Subsite])
        self.assertIn(stuff.subsiteb_id, ids[RT.Subsite])
        self.assertNotIn(stuff.subsite2_id, ids[RT.Subsite])
        self.assertNotIn(stuff.subsitez_id, ids[RT.Subsite])
        self.assertNotIn(stuff.platform_siteb2_id, ids[RT.PlatformSite])
        self.assertNotIn(RT.Observatory, ids)

        self.destroy(stuff)

    def _make_associations(self):
        """
        create one of each resource and association used by OMS
        to guard against problems in ion-definitions
        """

        #raise unittest.SkipTest("https://jira.oceanobservatories.org/tasks/browse/CISWCORE-41")
        

        """
        the tree we're creating (observatory, sites, platforms, instruments)

        rows are lettered, colums numbered.  
         - first row is implied a
         - first column is implied 1
         - site Z, just because 

        O--Sz
        |
        S--S2--P3--I4
        |
        Sb-Pb2-Ib3
        |
        P--I2 <- PlatformDevice, InstrumentDevice2
        |
        Pb <- PlatformDevice b
        |
        I <- InstrumentDevice

        """

        org_id = self.OMS.create_marine_facility(any_old(RT.Org))

        def create_under_org(resource_type):
            obj = any_old(resource_type)

            if RT.InstrumentDevice == resource_type:
                resource_id = self.IMS.create_instrument_device(obj)
            else:
                resource_id, _ = self.RR.create(obj)

            self.OMS.assign_resource_to_observatory_org(resource_id=resource_id, org_id=org_id)
            return resource_id

        #stuff we control
        observatory_id          = create_under_org(RT.Observatory)
        subsite_id              = create_under_org(RT.Subsite)
        subsite2_id             = create_under_org(RT.Subsite)
        subsiteb_id             = create_under_org(RT.Subsite)
        subsitez_id             = create_under_org(RT.Subsite)
        platform_site_id        = create_under_org(RT.PlatformSite)
        platform_siteb_id       = create_under_org(RT.PlatformSite)
        platform_siteb2_id      = create_under_org(RT.PlatformSite)
        platform_site3_id       = create_under_org(RT.PlatformSite)
        instrument_site_id      = create_under_org(RT.InstrumentSite)
        instrument_site2_id     = create_under_org(RT.InstrumentSite)
        instrument_siteb3_id    = create_under_org(RT.InstrumentSite)
        instrument_site4_id     = create_under_org(RT.InstrumentSite)

        #stuff we associate to
        instrument_device_id    = create_under_org(RT.InstrumentDevice)
        instrument_device2_id   = create_under_org(RT.InstrumentDevice)
        platform_device_id      = create_under_org(RT.PlatformDevice)
        platform_deviceb_id     = create_under_org(RT.PlatformDevice)
        instrument_model_id, _  = self.RR.create(any_old(RT.InstrumentModel))
        platform_model_id, _    = self.RR.create(any_old(RT.PlatformModel))
        deployment_id, _        = self.RR.create(any_old(RT.Deployment))

        #observatory
        self.RR.create_association(observatory_id, PRED.hasSite, subsite_id)
        self.RR.create_association(observatory_id, PRED.hasSite, subsitez_id)

        #site
        self.RR.create_association(subsite_id, PRED.hasSite, subsite2_id)
        self.RR.create_association(subsite_id, PRED.hasSite, subsiteb_id)
        self.RR.create_association(subsite2_id, PRED.hasSite, platform_site3_id)
        self.RR.create_association(subsiteb_id, PRED.hasSite, platform_siteb2_id)
        self.RR.create_association(subsiteb_id, PRED.hasSite, platform_site_id)
        
        #platform_site(s)
        self.RR.create_association(platform_site3_id, PRED.hasSite, instrument_site4_id)
        self.RR.create_association(platform_siteb2_id, PRED.hasSite, instrument_siteb3_id)
        self.RR.create_association(platform_site_id, PRED.hasSite, instrument_site2_id)
        self.RR.create_association(platform_site_id, PRED.hasSite, platform_siteb_id)
        self.RR.create_association(platform_siteb_id, PRED.hasSite, instrument_site_id)

        self.RR.create_association(platform_siteb_id, PRED.hasDevice, platform_deviceb_id)

        self.RR.create_association(platform_site_id, PRED.hasModel, platform_model_id)
        self.RR.create_association(platform_site_id, PRED.hasDevice, platform_device_id)
        self.RR.create_association(platform_site_id, PRED.hasDeployment, deployment_id)

        #instrument_site(s)
        self.RR.create_association(instrument_site_id, PRED.hasModel, instrument_model_id)
        self.RR.create_association(instrument_site_id, PRED.hasDevice, instrument_device_id)
        self.RR.create_association(instrument_site_id, PRED.hasDeployment, deployment_id)

        self.RR.create_association(instrument_site2_id, PRED.hasDevice, instrument_device2_id)

        #platform_device
        self.RR.create_association(platform_device_id, PRED.hasModel, platform_model_id)

        #instrument_device
        self.RR.create_association(instrument_device_id, PRED.hasModel, instrument_model_id)
        self.RR.create_association(instrument_device2_id, PRED.hasModel, instrument_model_id)

        ret = DotDict()
        ret.org_id                = org_id
        ret.observatory_id        = observatory_id
        ret.subsite_id            = subsite_id
        ret.subsite2_id           = subsite2_id
        ret.subsiteb_id           = subsiteb_id
        ret.subsitez_id           = subsitez_id
        ret.platform_site_id      = platform_site_id
        ret.platform_siteb_id     = platform_siteb_id
        ret.platform_siteb2_id    = platform_siteb2_id
        ret.platform_site3_id     = platform_site3_id
        ret.instrument_site_id    = instrument_site_id
        ret.instrument_site2_id   = instrument_site2_id
        ret.instrument_siteb3_id  = instrument_siteb3_id
        ret.instrument_site4_id   = instrument_site4_id

        ret.instrument_device_id  = instrument_device_id
        ret.instrument_device2_id = instrument_device2_id
        ret.platform_device_id    = platform_device_id
        ret.platform_deviceb_id    = platform_deviceb_id
        ret.instrument_model_id   = instrument_model_id
        ret.platform_model_id     = platform_model_id
        ret.deployment_id         = deployment_id

        return ret

    #@unittest.skip("targeting")
    def test_create_observatory(self):
        observatory_obj = IonObject(RT.Observatory,
                                        name='TestFacility',
                                        description='some new mf')
        observatory_id = self.OMS.create_observatory(observatory_obj)
        self.OMS.force_delete_observatory(observatory_id)


    #@unittest.skip("targeting")
    def test_find_observatory_org(self):
        org_obj = IonObject(RT.Org,
                            name='TestOrg',
                            description='some new mf org')

        org_id =  self.OMS.create_marine_facility(org_obj)

        observatory_obj = IonObject(RT.Observatory,
                                        name='TestObservatory',
                                        description='some new obs')
        observatory_id = self.OMS.create_observatory(observatory_obj)

        #make association
        
        self.OMS.assign_resource_to_observatory_org(observatory_id, org_id)


        #find association

        org_objs = self.OMS.find_org_by_observatory(observatory_id)
        self.assertEqual(1, len(org_objs))
        self.assertEqual(org_id, org_objs[0]._id)
        print("org_id=<" + org_id + ">")

        #create a subsite with parent Observatory
        subsite_obj =  IonObject(RT.Subsite,
                                name= 'TestSubsite',
                                description = 'sample subsite')
        subsite_id = self.OMS.create_subsite(subsite_obj, observatory_id)
        self.assertIsNotNone(subsite_id, "Subsite not created.")

        # verify that Subsite is linked to Observatory
        mf_subsite_assoc = self.RR.get_association(observatory_id, PRED.hasSite, subsite_id)
        self.assertIsNotNone(mf_subsite_assoc, "Subsite not connected to Observatory.")


        # add the Subsite as a resource of this Observatory
        self.OMS.assign_resource_to_observatory_org(resource_id=subsite_id, org_id=org_id)
        # verify that Subsite is linked to Org
        org_subsite_assoc = self.RR.get_association(org_id, PRED.hasResource, subsite_id)
        self.assertIsNotNone(org_subsite_assoc, "Subsite not connected as resource to Org.")


        #create a logical platform with parent Subsite
        platform_site_obj =  IonObject(RT.PlatformSite,
                                name= 'TestPlatformSite',
                                description = 'sample logical platform')
        platform_site_id = self.OMS.create_platform_site(platform_site_obj, subsite_id)
        self.assertIsNotNone(platform_site_id, "PlatformSite not created.")

        # verify that PlatformSite is linked to Site
        site_lp_assoc = self.RR.get_association(subsite_id, PRED.hasSite, platform_site_id)
        self.assertIsNotNone(site_lp_assoc, "PlatformSite not connected to Site.")


        # add the PlatformSite as a resource of this Observatory
        self.OMS.assign_resource_to_observatory_org(resource_id=platform_site_id, org_id=org_id)
        # verify that PlatformSite is linked to Org
        org_lp_assoc = self.RR.get_association(org_id, PRED.hasResource, platform_site_id)
        self.assertIsNotNone(org_lp_assoc, "PlatformSite not connected as resource to Org.")



        #create a logical instrument with parent logical platform
        instrument_site_obj =  IonObject(RT.InstrumentSite,
                                name= 'TestInstrumentSite',
                                description = 'sample logical instrument')
        instrument_site_id = self.OMS.create_instrument_site(instrument_site_obj, platform_site_id)
        self.assertIsNotNone(instrument_site_id, "InstrumentSite not created.")


        # verify that InstrumentSite is linked to PlatformSite
        li_lp_assoc = self.RR.get_association(platform_site_id, PRED.hasSite, instrument_site_id)
        self.assertIsNotNone(li_lp_assoc, "InstrumentSite not connected to PlatformSite.")


        # add the InstrumentSite as a resource of this Observatory
        self.OMS.assign_resource_to_observatory_org(resource_id=instrument_site_id, org_id=org_id)
        # verify that InstrumentSite is linked to Org
        org_li_assoc = self.RR.get_association(org_id, PRED.hasResource, instrument_site_id)
        self.assertIsNotNone(org_li_assoc, "InstrumentSite not connected as resource to Org.")


        # remove the InstrumentSite as a resource of this Observatory
        self.OMS.unassign_resource_from_observatory_org(instrument_site_id, org_id)
        # verify that InstrumentSite is linked to Org
        assocs,_ = self.RR.find_objects(org_id, PRED.hasResource, RT.InstrumentSite, id_only=True )
        self.assertEqual(len(assocs), 0)

        # remove the InstrumentSite
        self.OMS.delete_instrument_site(instrument_site_id)
        assocs, _ = self.RR.find_objects(platform_site_id, PRED.hasSite, RT.InstrumentSite, id_only=True )
        self.assertEqual(len(assocs), 1)
        #todo: remove the dangling association


        # remove the PlatformSite as a resource of this Observatory
        self.OMS.unassign_resource_from_observatory_org(platform_site_id, org_id)
        # verify that PlatformSite is linked to Org
        assocs,_ = self.RR.find_objects(org_id, PRED.hasResource, RT.PlatformSite, id_only=True )
        self.assertEqual(len(assocs), 0)


        # remove the Site as a resource of this Observatory
        self.OMS.unassign_resource_from_observatory_org(subsite_id, org_id)
        # verify that Site is linked to Org
        assocs,_ = self.RR.find_objects(org_id, PRED.hasResource, RT.Subsite, id_only=True )
        self.assertEqual(len(assocs), 0)

        self.RR.delete(org_id)
        self.OMS.force_delete_observatory(observatory_id)
        self.OMS.force_delete_subsite(subsite_id)
        self.OMS.force_delete_platform_site(platform_site_id)
        self.OMS.force_delete_instrument_site(instrument_site_id)


    #@unittest.skip("in development...")
    @attr('EXT')
    def test_observatory_org_extended(self):

        stuff = self._make_associations()

        parsed_pdict_id = self.dataset_management.read_parameter_dictionary_by_name('ctd_parsed_param_dict',
                                                                                    id_only=True)
        parsed_stream_def_id = self.pubsubcli.create_stream_definition(name='parsed',
                                                                       parameter_dictionary_id=parsed_pdict_id)
        tdom, sdom = time_series_domain()
        sdom = sdom.dump()
        tdom = tdom.dump()
        dp_obj = IonObject(RT.DataProduct,
            name='the parsed data',
            description='ctd stream test',
            temporal_domain = tdom,
            spatial_domain = sdom)

        data_product_id1 = self.dpclient.create_data_product(data_product=dp_obj,
                                                             stream_definition_id=parsed_stream_def_id)
        self.damsclient.assign_data_product(input_resource_id=stuff.instrument_device_id,
                                            data_product_id=data_product_id1)


        #--------------------------------------------------------------------------------
        # Get the extended Site (platformSite)
        #--------------------------------------------------------------------------------

        extended_site = self.OMS.get_site_extension(stuff.platform_site_id)
        log.debug("extended_site:  %s ", str(extended_site))
        self.assertEqual(1, len(extended_site.platform_devices))
        self.assertEqual(1, len(extended_site.platform_models))
        self.assertEqual(stuff.platform_device_id, extended_site.platform_devices[0]._id)
        self.assertEqual(stuff.platform_model_id, extended_site.platform_models[0]._id)

        #--------------------------------------------------------------------------------
        # Get the extended Org
        #--------------------------------------------------------------------------------
        #test the extended resource
        extended_org = self.org_management_service.get_marine_facility_extension(stuff.org_id)
        log.debug("test_observatory_org_extended: extended_org:  %s ", str(extended_org))
        #self.assertEqual(2, len(extended_org.instruments_deployed) )
        #self.assertEqual(1, len(extended_org.platforms_not_deployed) )
        self.assertEqual(2, extended_org.number_of_platforms)
        self.assertEqual(2, len(extended_org.platform_models) )

        self.assertEqual(2, extended_org.number_of_instruments)
        self.assertEqual(2, len(extended_org.instrument_models) )

        #test the extended resource of the ION org
        ion_org_id = self.org_management_service.find_org()
        extended_org = self.org_management_service.get_marine_facility_extension(ion_org_id._id, user_id=12345)
        log.debug("test_observatory_org_extended: extended_ION_org:  %s ", str(extended_org))
        self.assertEqual(0, len(extended_org.members))
        self.assertEqual(0, extended_org.number_of_platforms)
        #self.assertEqual(1, len(extended_org.sites))



        #--------------------------------------------------------------------------------
        # Get the extended Site
        #--------------------------------------------------------------------------------

        #create device state events to use for op /non-op filtering in extended
        t = get_ion_ts()
        self.event_publisher.publish_event(  ts_created= t,  event_type = 'ResourceAgentStateEvent',
            origin = stuff.instrument_device_id, state=ResourceAgentState.STREAMING  )

        self.event_publisher.publish_event( ts_created= t,   event_type = 'ResourceAgentStateEvent',
            origin = stuff.instrument_device2_id, state=ResourceAgentState.INACTIVE )
        extended_site =  self.OMS.get_site_extension(stuff.instrument_site2_id)


        log.debug("test_observatory_org_extended: extended_site:  %s ", str(extended_site))

        self.dpclient.delete_data_product(data_product_id1)
Example #9
0
class TestObservatoryManagementServiceIntegration(IonIntegrationTestCase):
    def setUp(self):
        # Start container
        #print 'instantiating container'
        self._start_container()
        #container = Container()
        #print 'starting container'
        #container.start()
        #print 'started container'

        self.container.start_rel_from_url('res/deploy/r2deploy.yml')
        self.RR = ResourceRegistryServiceClient(node=self.container.node)
        self.OMS = ObservatoryManagementServiceClient(node=self.container.node)
        #print 'TestObservatoryManagementServiceIntegration: started services'

    @unittest.skip('this exists only for debugging the launch process')
    def test_just_the_setup(self):
        return

    #@unittest.skip('targeting')
    def test_resources_associations(self):
        self._make_associations()

    #@unittest.skip('targeting')
    def test_find_related_frames_of_reference(self):
        # finding subordinates gives a dict of obj lists, convert objs to ids
        def idify(adict):
            ids = {}
            for k, v in adict.iteritems():
                ids[k] = []
                for obj in v:
                    ids[k].append(obj._id)

            return ids

        # a short version of the function we're testing, with id-ify
        def short(resource_id, output_types):
            ret = self.OMS.find_related_frames_of_reference(
                resource_id, output_types)
            return idify(ret)

        #set up associations first
        stuff = self._make_associations()
        #basic traversal of tree from instrument to platform
        ids = short(stuff.instrument_site_id, [RT.PlatformSite])
        self.assertIn(RT.PlatformSite, ids)
        self.assertIn(stuff.platform_site_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_siteb_id, ids[RT.PlatformSite])
        self.assertNotIn(stuff.platform_siteb2_id, ids[RT.PlatformSite])

        #since this is the first search, just make sure the input inst_id got stripped
        if RT.InstrumentSite in ids:
            self.assertNotIn(stuff.instrument_site_id, ids[RT.InstrumentSite])

        #basic traversal of tree from platform to instrument
        ids = short(stuff.platform_siteb_id, [RT.InstrumentSite])
        self.assertIn(RT.InstrumentSite, ids)
        self.assertIn(stuff.instrument_site_id, ids[RT.InstrumentSite])
        self.assertNotIn(stuff.instrument_site2_id, ids[RT.InstrumentSite])

        #full traversal of tree from observatory down to instrument
        ids = short(stuff.observatory_id, [RT.InstrumentSite])
        self.assertIn(RT.InstrumentSite, ids)
        self.assertIn(stuff.instrument_site_id, ids[RT.InstrumentSite])

        #full traversal of tree from instrument to observatory
        ids = short(stuff.instrument_site_id, [RT.Observatory])
        self.assertIn(RT.Observatory, ids)
        self.assertIn(stuff.observatory_id, ids[RT.Observatory])

        #partial traversal, only down to platform
        ids = short(stuff.observatory_id, [RT.Subsite, RT.PlatformSite])
        self.assertIn(RT.PlatformSite, ids)
        self.assertIn(RT.Subsite, ids)
        self.assertIn(stuff.platform_site_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_siteb_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_siteb2_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_site3_id, ids[RT.PlatformSite])
        self.assertIn(stuff.subsite_id, ids[RT.Subsite])
        self.assertIn(stuff.subsite2_id, ids[RT.Subsite])
        self.assertIn(stuff.subsitez_id, ids[RT.Subsite])
        self.assertIn(stuff.subsiteb_id, ids[RT.Subsite])
        self.assertNotIn(RT.InstrumentSite, ids)

        #partial traversal, only down to platform
        ids = short(stuff.instrument_site_id, [RT.Subsite, RT.PlatformSite])
        self.assertIn(RT.PlatformSite, ids)
        self.assertIn(RT.Subsite, ids)
        self.assertIn(stuff.platform_siteb_id, ids[RT.PlatformSite])
        self.assertIn(stuff.platform_site_id, ids[RT.PlatformSite])
        self.assertIn(stuff.subsite_id, ids[RT.Subsite])
        self.assertIn(stuff.subsiteb_id, ids[RT.Subsite])
        self.assertNotIn(stuff.subsite2_id, ids[RT.Subsite])
        self.assertNotIn(stuff.subsitez_id, ids[RT.Subsite])
        self.assertNotIn(stuff.platform_siteb2_id, ids[RT.PlatformSite])
        self.assertNotIn(RT.Observatory, ids)

    def _make_associations(self):
        """
        create one of each resource and association used by OMS
        to guard against problems in ion-definitions
        """

        #raise unittest.SkipTest("https://jira.oceanobservatories.org/tasks/browse/CISWCORE-41")
        """
        the tree we're creating (observatory, sites, platforms, instruments)

        rows are lettered, colums numbered.  
         - first row is implied a
         - first column is implied 1
         - site Z, just because 

        O--Sz
        |
        S--S2--P3--I4
        |
        Sb-Pb2-Ib3
        |
        P--I2
        |
        Pb
        |
        I

        """

        #stuff we control
        observatory_id, _ = self.RR.create(any_old(RT.Observatory))
        subsite_id, _ = self.RR.create(any_old(RT.Subsite))
        subsite2_id, _ = self.RR.create(any_old(RT.Subsite))
        subsiteb_id, _ = self.RR.create(any_old(RT.Subsite))
        subsitez_id, _ = self.RR.create(any_old(RT.Subsite))
        platform_site_id, _ = self.RR.create(any_old(RT.PlatformSite))
        platform_siteb_id, _ = self.RR.create(any_old(RT.PlatformSite))
        platform_siteb2_id, _ = self.RR.create(any_old(RT.PlatformSite))
        platform_site3_id, _ = self.RR.create(any_old(RT.PlatformSite))
        instrument_site_id, _ = self.RR.create(any_old(RT.InstrumentSite))
        instrument_site2_id, _ = self.RR.create(any_old(RT.InstrumentSite))
        instrument_siteb3_id, _ = self.RR.create(any_old(RT.InstrumentSite))
        instrument_site4_id, _ = self.RR.create(any_old(RT.InstrumentSite))

        #stuff we associate to
        instrument_model_id, _ = self.RR.create(any_old(RT.InstrumentModel))
        instrument_device_id, _ = self.RR.create(any_old(RT.InstrumentDevice))
        platform_model_id, _ = self.RR.create(any_old(RT.PlatformModel))
        platform_device_id, _ = self.RR.create(any_old(RT.PlatformDevice))
        deployment_id, _ = self.RR.create(any_old(RT.Deployment))

        #observatory
        self.RR.create_association(observatory_id, PRED.hasSite, subsite_id)
        self.RR.create_association(observatory_id, PRED.hasSite, subsitez_id)

        #site
        self.RR.create_association(subsite_id, PRED.hasSite, subsite2_id)
        self.RR.create_association(subsite_id, PRED.hasSite, subsiteb_id)
        self.RR.create_association(subsite2_id, PRED.hasSite,
                                   platform_site3_id)
        self.RR.create_association(subsiteb_id, PRED.hasSite,
                                   platform_siteb2_id)
        self.RR.create_association(subsiteb_id, PRED.hasSite, platform_site_id)

        #platform_site
        self.RR.create_association(platform_site3_id, PRED.hasSite,
                                   instrument_site4_id)
        self.RR.create_association(platform_siteb2_id, PRED.hasSite,
                                   instrument_siteb3_id)
        self.RR.create_association(platform_site_id, PRED.hasSite,
                                   instrument_site2_id)
        self.RR.create_association(platform_site_id, PRED.hasSite,
                                   platform_siteb_id)
        self.RR.create_association(platform_siteb_id, PRED.hasSite,
                                   instrument_site_id)

        self.RR.create_association(platform_site_id, PRED.hasModel,
                                   platform_model_id)
        self.RR.create_association(platform_site_id, PRED.hasDevice,
                                   platform_device_id)
        self.RR.create_association(platform_site_id, PRED.hasDeployment,
                                   deployment_id)

        #instrument_site
        self.RR.create_association(instrument_site_id, PRED.hasModel,
                                   instrument_model_id)
        self.RR.create_association(instrument_site_id, PRED.hasDevice,
                                   instrument_device_id)
        self.RR.create_association(instrument_site_id, PRED.hasDeployment,
                                   deployment_id)

        ret = DotDict()
        ret.observatory_id = observatory_id
        ret.subsite_id = subsite_id
        ret.subsite2_id = subsite2_id
        ret.subsiteb_id = subsiteb_id
        ret.subsitez_id = subsitez_id
        ret.platform_site_id = platform_site_id
        ret.platform_siteb_id = platform_siteb_id
        ret.platform_siteb2_id = platform_siteb2_id
        ret.platform_site3_id = platform_site3_id
        ret.instrument_site_id = instrument_site_id
        ret.instrument_site2_id = instrument_site2_id
        ret.instrument_siteb3_id = instrument_siteb3_id
        ret.instrument_site4_id = instrument_site4_id

        return ret

    #@unittest.skip("targeting")
    def test_create_observatory(self):
        observatory_obj = IonObject(RT.Observatory,
                                    name='TestFacility',
                                    description='some new mf')
        self.OMS.create_observatory(observatory_obj)

    #@unittest.skip('targeting')
    def test_find_observatory_org(self):
        org_obj = IonObject(RT.Org,
                            name='TestOrg',
                            description='some new mf org')

        org_id = self.OMS.create_marine_facility(org_obj)

        observatory_obj = IonObject(RT.Observatory,
                                    name='TestObservatory',
                                    description='some new obs')
        observatory_id = self.OMS.create_observatory(observatory_obj)

        #make association

        self.OMS.assign_resource_to_observatory_org(observatory_id, org_id)

        #find association

        org_objs = self.OMS.find_org_by_observatory(observatory_id)
        self.assertEqual(1, len(org_objs))
        self.assertEqual(org_id, org_objs[0]._id)
        print("org_id=<" + org_id + ">")

        #create a subsite with parent Observatory
        subsite_obj = IonObject(RT.Subsite,
                                name='TestSubsite',
                                description='sample subsite')
        subsite_id = self.OMS.create_subsite(subsite_obj, observatory_id)
        self.assertIsNotNone(subsite_id, "Subsite not created.")

        # verify that Subsite is linked to Observatory
        mf_subsite_assoc = self.RR.get_association(observatory_id,
                                                   PRED.hasSite, subsite_id)
        self.assertIsNotNone(mf_subsite_assoc,
                             "Subsite not connected to Observatory.")

        # add the Subsite as a resource of this Observatory
        self.OMS.assign_resource_to_observatory_org(resource_id=subsite_id,
                                                    org_id=org_id)
        # verify that Subsite is linked to Org
        org_subsite_assoc = self.RR.get_association(org_id, PRED.hasResource,
                                                    subsite_id)
        self.assertIsNotNone(org_subsite_assoc,
                             "Subsite not connected as resource to Org.")

        #create a logical platform with parent Subsite
        platform_site_obj = IonObject(RT.PlatformSite,
                                      name='TestPlatformSite',
                                      description='sample logical platform')
        platform_site_id = self.OMS.create_platform_site(
            platform_site_obj, subsite_id)
        self.assertIsNotNone(platform_site_id, "PlatformSite not created.")

        # verify that PlatformSite is linked to Site
        site_lp_assoc = self.RR.get_association(subsite_id, PRED.hasSite,
                                                platform_site_id)
        self.assertIsNotNone(site_lp_assoc,
                             "PlatformSite not connected to Site.")

        # add the PlatformSite as a resource of this Observatory
        self.OMS.assign_resource_to_observatory_org(
            resource_id=platform_site_id, org_id=org_id)
        # verify that PlatformSite is linked to Org
        org_lp_assoc = self.RR.get_association(org_id, PRED.hasResource,
                                               platform_site_id)
        self.assertIsNotNone(org_lp_assoc,
                             "PlatformSite not connected as resource to Org.")

        #create a logical instrument with parent logical platform
        instrument_site_obj = IonObject(
            RT.InstrumentSite,
            name='TestInstrumentSite',
            description='sample logical instrument')
        instrument_site_id = self.OMS.create_instrument_site(
            instrument_site_obj, platform_site_id)
        self.assertIsNotNone(instrument_site_id, "InstrumentSite not created.")

        # verify that InstrumentSite is linked to PlatformSite
        li_lp_assoc = self.RR.get_association(platform_site_id, PRED.hasSite,
                                              instrument_site_id)
        self.assertIsNotNone(li_lp_assoc,
                             "InstrumentSite not connected to PlatformSite.")

        # add the InstrumentSite as a resource of this Observatory
        self.OMS.assign_resource_to_observatory_org(
            resource_id=instrument_site_id, org_id=org_id)
        # verify that InstrumentSite is linked to Org
        org_li_assoc = self.RR.get_association(org_id, PRED.hasResource,
                                               instrument_site_id)
        self.assertIsNotNone(
            org_li_assoc, "InstrumentSite not connected as resource to Org.")

        # remove the InstrumentSite as a resource of this Observatory
        self.OMS.unassign_resource_from_observatory_org(
            instrument_site_id, org_id)
        # verify that InstrumentSite is linked to Org
        assocs, _ = self.RR.find_objects(org_id,
                                         PRED.hasResource,
                                         RT.InstrumentSite,
                                         id_only=True)
        self.assertEqual(len(assocs), 0)

        # remove the InstrumentSite
        self.OMS.delete_instrument_site(instrument_site_id)
        assocs, _ = self.RR.find_objects(platform_site_id,
                                         PRED.hasInstrument,
                                         RT.InstrumentSite,
                                         id_only=True)
        self.assertEqual(len(assocs), 0)

        # remove the PlatformSite as a resource of this Observatory
        self.OMS.unassign_resource_from_observatory_org(
            platform_site_id, org_id)
        # verify that PlatformSite is linked to Org
        assocs, _ = self.RR.find_objects(org_id,
                                         PRED.hasResource,
                                         RT.PlatformSite,
                                         id_only=True)
        self.assertEqual(len(assocs), 0)

        # remove the Site as a resource of this Observatory
        self.OMS.unassign_resource_from_observatory_org(subsite_id, org_id)
        # verify that Site is linked to Org
        assocs, _ = self.RR.find_objects(org_id,
                                         PRED.hasResource,
                                         RT.Subsite,
                                         id_only=True)
        self.assertEqual(len(assocs), 0)