Example #1
0
 def get_builtin_view(self, view_name):
     view_obj = View(name=view_name)
     if view_name == "resources_index":
         rq = ResourceQuery()
         view_obj.view_definition = rq.get_query()
         return view_obj
     elif view_name == "events_index":
         eq = EventQuery()
         view_obj.view_definition = eq.get_query()
         return view_obj
Example #2
0
 def get_builtin_view(self, view_name):
     view_obj = View(name=view_name)
     if view_name == "resources_index":
         rq = ResourceQuery()
         view_obj.view_definition = rq.get_query()
         return view_obj
     elif view_name == "events_index":
         eq = EventQuery()
         view_obj.view_definition = eq.get_query()
         return view_obj
Example #3
0
    def get_distinct_values(self, restype='', attr_list=None, res_filter=None):
        """Returns a list of distinct values for given resource type and list of attribute names.
        Only supports simple types for the attribute values.
        Returns a sorted list of values or tuples of values.
        """
        if not restype or type(restype) != str:
            raise BadRequest("Illegal value for argument restype")
        if not hasattr(interface.objects, restype):
            raise BadRequest("Given restype is not a resource type")
        if not attr_list or not type(attr_list) in (list, tuple):
            raise BadRequest("Illegal value for argument attr_list")
        type_cls = getattr(interface.objects, restype)
        try:
            if not all(type_cls._schema[an]["type"] in {"str", "int", "float"} for an in attr_list):
                raise BadRequest("Attribute in attr_list if invalid type")
        except KeyError:
            raise BadRequest("Attribute in attr_list unknown")
        if res_filter and type(res_filter) not in (list, tuple):
            raise BadRequest("Illegal value for argument res_filter")

        # NOTE: This can alternatively be implemented as a SELECT DISTINCT query, but this is not
        # supported by the underlying datastore interface.
        rq = ResourceQuery()
        if res_filter:
            rq.set_filter(rq.eq(rq.ATT_TYPE, restype), res_filter)
        else:
            rq.set_filter(rq.eq(rq.ATT_TYPE, restype))
        res_list = self.clients.resource_registry.find_resources_ext(query=rq.get_query(), id_only=False)

        log.debug("Found %s resources of type %s", len(res_list), restype)
        att_values = sorted({tuple(getattr(res, an) for an in attr_list) for res in res_list})

        log.debug("Found %s distinct vales for attribute(s): %s", len(att_values), attr_list)

        return att_values
Example #4
0
 def _get_user_by_email(self, email):
     user_objs_rq = ResourceQuery()
     user_objs_rq.set_filter(
         user_objs_rq.filter_type(RT.ActorIdentity),
         user_objs_rq.filter_attribute('details.contact.email', email))
     users = self.rr.find_resources_ext(query=user_objs_rq.get_query(),
                                        id_only=False)
     if users:
         return users[0]
     return None
 def get_builtin_view(self, view_name):
     view_obj = View(name=view_name)
     if view_name == "resources_index":
         rq = ResourceQuery()
         view_obj.view_definition = rq.get_query()
         return view_obj
     elif view_name == "data_products_index":
         rq = ResourceQuery()
         rq.set_filter(rq.filter_type(["DataProduct", "DataProcess", "Deployment", "InstrumentDevice", "InstrumentModel",
                         "InstrumentAgentInstance", "InstrumentAgent", "PlatformDevice", "PlatformModel",
                         "PlatformAgentInstance", "PlatformAgent", "PlatformSite", "Observatory", "UserRole",
                         "Org", "Attachment", "ExternalDatasetAgent", "ExternalDatasetAgentInstance"]))
         view_obj.view_definition = rq.get_query()
         return view_obj
     elif view_name == "events_index":
         eq = EventQuery()
         view_obj.view_definition = eq.get_query()
         return view_obj
Example #6
0
 def _get_user_by_email(self, email):
     user_objs_rq = ResourceQuery()
     user_objs_rq.set_filter(
         user_objs_rq.filter_type(RT.ActorIdentity),
         user_objs_rq.filter_attribute('details.contact.email', email))
     users = self.rr.find_resources_ext(query=user_objs_rq.get_query(), id_only=False)
     if users:
         return users[0]
     return None
Example #7
0
    def on_restart(self, process, config, **kwargs):
        # Delete leftover Service and associated Process resources
        svc_ids, _ = process.container.resource_registry.find_resources(restype=RT.Service, id_only=True)

        if svc_ids:
            rq = ResourceQuery()
            rq.set_filter(rq.filter_type(RT.Process),
                          rq.filter_associated_from_subject(svc_ids, predicate=PRED.hasProcess))
            proc_ids = process.container.resource_registry.find_resources_ext(query=rq.get_query(), id_only=True)

            log.info("Deleting %s Service resources", len(svc_ids))
            process.container.resource_registry.rr_store.delete_mult(svc_ids)

            if proc_ids:
                log.info("Deleting %s Procvess resources", len(proc_ids))
                process.container.resource_registry.rr_store.delete_mult(proc_ids)
Example #8
0
    def on_restart(self, process, config, **kwargs):
        # Delete leftover Service and associated Process resources
        svc_ids, _ = process.container.resource_registry.find_resources(restype=RT.Service, id_only=True)

        if svc_ids:
            rq = ResourceQuery()
            rq.set_filter(
                rq.filter_type(RT.Process), rq.filter_associated_from_subject(svc_ids, predicate=PRED.hasProcess)
            )
            proc_ids = process.container.resource_registry.find_resources_ext(query=rq.get_query(), id_only=True)

            log.info("Deleting %s Service resources", len(svc_ids))
            process.container.resource_registry.rr_store.delete_mult(svc_ids)

            if proc_ids:
                log.info("Deleting %s Procvess resources", len(proc_ids))
                process.container.resource_registry.rr_store.delete_mult(proc_ids)
    def get_active_process_operation_preconditions(self, process_key='', op='', org_name=''):
        """Generates the set of all enabled precondition policies for the specified process operation
        within the specified Org. If the org_name is not provided, then the root ION Org will be assumed.
        """
        # TODO - extend to handle Org specific service policies at some point.
        if not process_key:
            raise BadRequest("The process_key argument is missing")

        rq = ResourceQuery()
        rq.set_filter(rq.filter_type(RT.Policy),
                      rq.filter_attribute("enabled", True),
                      rq.filter_attribute("policy_type", PolicyTypeEnum.PROC_OP_PRECOND),
                      rq.filter_attribute("details.process_key", process_key))
        if op:
            rq.add_filter(rq.filter_attribute("details.op", op))
        policy_list = self.clients.resource_registry.find_resources_ext(query=rq.get_query(), id_only=False)
        policy_list.sort(key=lambda o: (o.ordinal, o.ts_created))

        return policy_list
    def get_active_service_access_policy_rules(self, service_name='', org_name=''):
        """Generates the set of all enabled access policies for the specified service within
        the specified Org. If the org_name is not provided, then the root ION Org will be assumed.
        """
        # TODO - extend to handle Org specific service policies at some point.
        rq = ResourceQuery()
        rq.set_filter(rq.filter_type(RT.Policy),
                      rq.filter_attribute("enabled", True))
        if service_name:
            rq.add_filter(rq.or_(rq.filter_attribute("policy_type", PolicyTypeEnum.COMMON_SERVICE_ACCESS),
                                 rq.and_(rq.filter_attribute("policy_type", [PolicyTypeEnum.SERVICE_ACCESS, PolicyTypeEnum.SERVICE_OP_PRECOND]),
                                         rq.filter_attribute("details.service_name", service_name))))
        else:
            rq.add_filter(rq.filter_attribute("policy_type", PolicyTypeEnum.COMMON_SERVICE_ACCESS))
        policy_list = self.clients.resource_registry.find_resources_ext(query=rq.get_query(), id_only=False)

        policy_list.sort(key=lambda o: (o.ordinal, o.ts_created))

        return policy_list
    def get_active_process_operation_preconditions(self,
                                                   process_key='',
                                                   op='',
                                                   org_name=''):
        """Generates the set of all enabled precondition policies for the specified process operation
        within the specified Org. If the org_name is not provided, then the root ION Org will be assumed.
        """
        # TODO - extend to handle Org specific service policies at some point.
        if not process_key:
            raise BadRequest("The process_key argument is missing")

        rq = ResourceQuery()
        rq.set_filter(
            rq.filter_type(RT.Policy), rq.filter_attribute("enabled", True),
            rq.filter_attribute("policy_type", PolicyTypeEnum.PROC_OP_PRECOND),
            rq.filter_attribute("details.process_key", process_key))
        if op:
            rq.add_filter(rq.filter_attribute("details.op", op))
        policy_list = self.clients.resource_registry.find_resources_ext(
            query=rq.get_query(), id_only=False)
        policy_list.sort(key=lambda o: (o.ordinal, o.ts_created))

        return policy_list
    def get_active_service_access_policy_rules(self,
                                               service_name='',
                                               org_name=''):
        """Generates the set of all enabled access policies for the specified service within
        the specified Org. If the org_name is not provided, then the root ION Org will be assumed.
        """
        # TODO - extend to handle Org specific service policies at some point.
        rq = ResourceQuery()
        rq.set_filter(rq.filter_type(RT.Policy),
                      rq.filter_attribute("enabled", True))
        if service_name:
            rq.add_filter(
                rq.or_(
                    rq.filter_attribute("policy_type",
                                        PolicyTypeEnum.COMMON_SERVICE_ACCESS),
                    rq.and_(
                        rq.filter_attribute("policy_type", [
                            PolicyTypeEnum.SERVICE_ACCESS,
                            PolicyTypeEnum.SERVICE_OP_PRECOND
                        ]),
                        rq.filter_attribute("details.service_name",
                                            service_name))))
        else:
            rq.add_filter(
                rq.filter_attribute("policy_type",
                                    PolicyTypeEnum.COMMON_SERVICE_ACCESS))
        policy_list = self.clients.resource_registry.find_resources_ext(
            query=rq.get_query(), id_only=False)

        policy_list.sort(key=lambda o: (o.ordinal, o.ts_created))

        return policy_list
    def test_complex_queries(self):
        res_objs = [
            dict(res=IonObject(RT.ActorIdentity, name="Act1")),
            dict(res=IonObject(RT.ActorIdentity, name="Act2")),

            dict(res=IonObject(RT.Org, name="Org1"), act="Act1"),
            dict(res=IonObject(RT.TestSite, name="Obs1"), act="Act1", org="Org1"),
            dict(res=IonObject(RT.TestSite, name="PS1"), act="Act1", org="Org1"),
            dict(res=IonObject(RT.TestSite, name="PSC1"), act="Act1", org="Org1"),
            dict(res=IonObject(RT.TestSite, name="IS1"), act="Act1", org="Org1"),
            dict(res=IonObject(RT.TestDeviceModel, name="PM1", manufacturer="CGSN"), act="Act1", org="Org1"),
            dict(res=IonObject(RT.TestDeviceModel, name="PMC1", manufacturer="Bluefin"), act="Act1", org="Org1"),
            dict(res=IonObject(RT.TestDeviceModel, name="PM2", manufacturer="Webb"), act="Act1", org="Org1"),
            dict(res=IonObject(RT.TestDeviceModel, name="IM1", manufacturer="SeaBird"), act="Act1", org="Org1"),
            dict(res=IonObject(RT.TestDeviceModel, name="IM2", manufacturer="Teledyne"), act="Act1", org="Org1"),
            dict(res=IonObject(RT.TestPlatform, name="PD1"), act="Act1", org="Org1", lcstate=LCS.DEPLOYED),
            dict(res=IonObject(RT.TestPlatform, name="PDC1"), act="Act1", org="Org1", lcstate=LCS.INTEGRATED),
            dict(res=IonObject(RT.TestInstrument, name="ID1", firmware_version='A1'), act="Act1", org="Org1", lcstate=LCS.DEPLOYED),
            dict(res=IonObject(RT.TestInstrument, name="ID2", firmware_version='A2'), act="Act1", org="Org1", lcstate=LCS.INTEGRATED),

            dict(res=IonObject(RT.Org, name="Org2"), act="Act2"),
            dict(res=IonObject(RT.TestSite, name="Obs2"), act="Act2", org="Org2"),
            dict(res=IonObject(RT.TestSite, name="PS2"), act="Act2", org="Org2"),
            dict(res=IonObject(RT.TestPlatform, name="PD2"), act="Act2", org="Org2"),
            dict(res=IonObject(RT.TestInstrument, name="ID3", lcstate=LCS.DEPLOYED, firmware_version='A3'), act="Act2", org="Org2"),
            dict(res=IonObject(RT.Stream, name="Stream1")),
        ]
        assocs = [
            ("Obs1", PRED.hasTestSite, "PS1"),
            ("PS1", PRED.hasTestSite, "PSC1"),
            ("PSC1", PRED.hasTestSite, "IS1"),
            ("PS1", PRED.hasTestDevice, "PD1"),
            ("PSC1", PRED.hasTestDevice, "PDC1"),
            ("IS1", PRED.hasTestDevice, "ID1"),
            ("PD1", PRED.hasTestDevice, "PDC1"),
            ("PDC1", PRED.hasTestDevice, "ID1"),

            ("PS1", PRED.hasTestModel, "PM1"),
            ("PSC1", PRED.hasTestModel, "PMC1"),
            ("IS1", PRED.hasTestModel, "IM1"),
            ("PD1", PRED.hasTestModel, "PM1"),
            ("PDC1", PRED.hasTestModel, "PMC1"),
            ("ID1", PRED.hasTestModel, "IM1"),
            ("PD2", PRED.hasTestModel, "PM2"),
            ("ID2", PRED.hasTestModel, "IM2"),

        ]
        res_by_name = create_dummy_resources(res_objs, assocs)

        log.info("TEST: Query for all resources owned by actor Act1")
        rq = ResourceQuery()
        rq.set_filter(rq.filter_associated_from_object(res_by_name["Act1"], None, "hasOwner"))
        result = self.discovery.query(rq.get_query(), id_only=False)
        self.assertEquals(len(result), 14)

        log.info("TEST: Query for all Site descendants of TestSite Obs1")
        rq = ResourceQuery()
        rq.set_filter(rq.filter_object_descendants(res_by_name["Obs1"], [RT.TestSite, RT.TestSite], PRED.hasTestSite))
        result = self.discovery.query(rq.get_query(), id_only=False)
        # import pprint
        # pprint.pprint(rq.get_query())
        self.assertEquals(len(result), 3)

        log.info("TEST: Query for all resources belonging to Org Org1")
        rq = ResourceQuery()
        rq.set_filter(rq.filter_associated_from_subject(res_by_name["Org1"], None, "hasResource"))
        result = self.discovery.query(rq.get_query(), id_only=False)
        self.assertEquals(len(result), 13)

        log.info("TEST: Query for all resources belonging to Org Org1 AND of type TestInstrument")
        rq = ResourceQuery()
        rq.set_filter(rq.filter_associated_from_subject(res_by_name["Org1"], None, "hasResource"),
                      rq.filter_type(RT.TestInstrument))
        result = self.discovery.query(rq.get_query(), id_only=False)
        self.assertEquals(len(result), 2)

        log.info("TEST: Query for instruments whose platform parent has a name of PDC1")
        rq = ResourceQuery()
        rq.set_filter(rq.filter_type(RT.TestInstrument),
                      rq.filter_associated_from_subject(subject_type=RT.TestPlatform, predicate=PRED.hasTestDevice, target_filter=rq.filter_name("PDC1")))
        result = self.discovery.query(rq.get_query(), id_only=False)
        self.assertEquals(len(result), 1)
        self.assertEquals(result[0].name, "ID1")

        log.info("TEST: Query for instruments in Org1 whose platform parent has a specific attribute set")
        rq = ResourceQuery()
        rq.set_filter(rq.filter_type(RT.TestInstrument),
                      rq.filter_associated_from_subject(res_by_name["Org1"], None, "hasResource"),
                      rq.filter_associated_from_subject(subject_type=RT.TestPlatform, predicate=PRED.hasTestDevice, target_filter=rq.filter_name("PDC1")))
        result = self.discovery.query(rq.get_query(), id_only=False)
        self.assertEquals(len(result), 1)
        self.assertEquals(result[0].name, "ID1")

        log.info("TEST: Query for instruments in Org1 that are lcstate INTEGRATED")
        rq = ResourceQuery()
        rq.set_filter(rq.filter_type(RT.TestInstrument),
                      rq.filter_lcstate(LCS.INTEGRATED),
                      rq.filter_associated_from_subject(res_by_name["Org1"], None, "hasResource"))
        result = self.discovery.query(rq.get_query(), id_only=False)
        self.assertEquals(len(result), 1)
        self.assertEquals(result[0].name, "ID2")

        log.info("TEST: Query for instruments in Org1 that are lcstate INTEGRATED OR platforms in Org1 that are lcstate DEPLOYED")
        rq = ResourceQuery()
        rq.set_filter(rq.filter_or(rq.filter_and(rq.filter_type(RT.TestInstrument),
                                                 rq.filter_lcstate(LCS.INTEGRATED)),
                                   rq.filter_and(rq.filter_type(RT.TestPlatform),
                                                 rq.filter_lcstate(LCS.DEPLOYED))),
                      rq.filter_associated_from_subject(res_by_name["Org1"], None, "hasResource"))
        result = self.discovery.query(rq.get_query(), id_only=False)
        self.assertEquals(len(result), 2)
    def test_query_view(self):
        res_objs = [
            (IonObject(RT.ActorIdentity, name="Act1"), ),
            (IonObject(RT.ActorIdentity, name="Act2"), ),

            (IonObject(RT.TestInstrument, name="ID1", lcstate=LCS.DEPLOYED, firmware_version='A1'), "Act1"),
            (IonObject(RT.TestInstrument, name="ID2", lcstate=LCS.INTEGRATED, firmware_version='A2'), "Act2"),

            (IonObject(RT.TestPlatform, name="PD1"), ),
            (IonObject(RT.TestPlatform, name="PD2"), ),

            (IonObject(RT.TestSite, name="Site1", lcstate=LCS.DEPLOYED), ),
        ]
        assocs = [
            ("PD1", PRED.hasTestDevice, "ID1"),
            ("PD2", PRED.hasTestDevice, "ID2"),

        ]
        res_by_name = create_dummy_resources(res_objs, assocs)

        # ----------------------------------------------------
        # Resource attribute search

        rq = ResourceQuery()
        rq.set_filter(rq.filter_type(RT.TestInstrument))
        view_obj = View(name="All TestInstrument resources", view_definition=rq.get_query())
        view_id = self.discovery.create_view(view_obj)

        # TEST: View by ID
        result = self.discovery.query_view(view_id, id_only=False)
        self.assertEquals(len(result), 2)
        self.assertTrue(all(True for ro in result if ro.type_ == RT.TestInstrument))

        # TEST: View by Name
        result = self.discovery.query_view(view_name="All TestInstrument resources", id_only=False)
        self.assertEquals(len(result), 2)
        self.assertTrue(all(True for ro in result if ro.type_ == RT.TestInstrument))

        # TEST: View plus ext_query
        rq = ResourceQuery()
        rq.set_filter(rq.filter_name("ID1"))
        result = self.discovery.query_view(view_id, id_only=False, ext_query=rq.get_query())
        self.assertEquals(len(result), 1)
        self.assertEquals(result[0].name, "ID1")

        # TEST: View with params (anonymous)
        rq = ResourceQuery()
        rq.set_filter(rq.filter_type(RT.TestInstrument),
                      rq.filter_attribute("firmware_version", "$(firmware_version)"))
        view_obj = View(name="TestInstrument resources with a specific firmware - parameterized",
                        view_definition=rq.get_query())
        view_id = self.discovery.create_view(view_obj)

        view_params = {"firmware_version": "A2"}
        result = self.discovery.query_view(view_id, id_only=False, search_args=view_params)
        self.assertEquals(len(result), 1)
        self.assertEquals(result[0].name, "ID2")

        # TEST: View with params (anonymous) - no values provided
        result = self.discovery.query_view(view_id, id_only=False)
        self.assertEquals(len(result), 0)

        # View with params (with definitions and defaults)
        view_param_def = [CustomAttribute(name="firmware_version",
                                          type="str",
                                          default="A1")]
        view_obj = View(name="TestInstrument resources with a specific firmware - parameterized with defaults",
                        view_definition=rq.get_query(),
                        view_parameters=view_param_def)
        view_id = self.discovery.create_view(view_obj)

        # TEST: Definition defaults
        result = self.discovery.query_view(view_id, id_only=False)
        self.assertEquals(len(result), 1)
        self.assertEquals(result[0].name, "ID1")

        # TEST: Parameterized values
        result = self.discovery.query_view(view_id, id_only=False, search_args=view_params)
        self.assertEquals(len(result), 1)
        self.assertEquals(result[0].name, "ID2")

        # TEST: Parameterized association query for resource owner
        rq = ResourceQuery()
        rq.set_filter(rq.filter_associated_from_object("$(owner)"))
        view_obj = View(name="Resources owned by actor - parameterized", view_definition=rq.get_query())
        view_id = self.discovery.create_view(view_obj)
        view_params = {"owner": res_by_name["Act2"]}
        result = self.discovery.query_view(view_id, id_only=False, search_args=view_params)
        self.assertEquals(len(result), 1)
        self.assertEquals(result[0].name, "ID2")

        # TEST: Parameterized association query for resource owner with parameter value
        view_params = {"owner": res_by_name["Act2"], "query_info": True}
        result = self.discovery.query_view(view_id, id_only=False, search_args=view_params)
        self.assertEquals(len(result), 2)
        self.assertEquals(result[0].name, "ID2")
        self.assertIn("_query_info", result[1])
        self.assertIn("statement_sql", result[1])

        # TEST: Builtin views
        rq = ResourceQuery()
        rq.set_filter(rq.filter_type(RT.TestSite))
        result = self.discovery.query_view(view_name="resources_index", id_only=False, ext_query=rq.get_query())
        self.assertEquals(len(result), 1)
        self.assertEquals(result[0].name, "Site1")


        # --- Events setup

        from interface.objects import ResourceOperatorEvent, ResourceCommandEvent
        t0 = 136304640000
        events = [
            ("RME1", ResourceCommandEvent(origin="O1", origin_type="OT1", sub_type="ST1", ts_created=str(t0))),
            ("RME2", ResourceCommandEvent(origin="O2", origin_type="OT1", sub_type="ST2", ts_created=str(t0+1))),
            ("RME3", ResourceCommandEvent(origin="O2", origin_type="OT2", sub_type="ST3", ts_created=str(t0+2))),

            ("RLE1", ResourceOperatorEvent(origin="O1", origin_type="OT3", sub_type="ST4", ts_created=str(t0+3))),
            ("RLE2", ResourceOperatorEvent(origin="O3", origin_type="OT3", sub_type="ST5", ts_created=str(t0+4))),
            ("RLE3", ResourceOperatorEvent(origin="O3", origin_type="OT2", sub_type="ST6", ts_created=str(t0+5))),

        ]
        ev_by_alias = create_dummy_events(events)

        # TEST: Event query with views
        eq = EventQuery()
        eq.set_filter(eq.filter_type(OT.ResourceCommandEvent))
        view_obj = View(name="All ResourceCommandEvent events", view_definition=eq.get_query())
        view_id = self.discovery.create_view(view_obj)
        result = self.discovery.query_view(view_id, id_only=False)
        self.assertEquals(len(result), 3)
        self.assertTrue(all(True for eo in result if eo.type_ == OT.ResourceCommandEvent))

        # TEST: Event query with views - stripped format
        result = self.discovery.query_view(view_id, id_only=False, search_args=dict(attribute_filter=["origin"]))
        self.assertEquals(len(result), 3)
        self.assertTrue(all(True for eo in result if isinstance(eo, dict)))
        self.assertTrue(all(True for eo in result if "origin" in eo))
        self.assertTrue(all(True for eo in result if len(eo) <= 4))

        # TEST: Builtin views
        eq = EventQuery()
        eq.set_filter(eq.filter_type(OT.ResourceCommandEvent))
        result = self.discovery.query_view(view_name="events_index", id_only=False, ext_query=eq.get_query())
        self.assertEquals(len(result), 3)
    def test_complex_queries(self):
        res_objs = [
            dict(res=IonObject(RT.ActorIdentity, name="Act1")),
            dict(res=IonObject(RT.ActorIdentity, name="Act2")),
            dict(res=IonObject(RT.Org, name="Org1"), act="Act1"),
            dict(res=IonObject(RT.TestSite, name="Obs1"),
                 act="Act1",
                 org="Org1"),
            dict(res=IonObject(RT.TestSite, name="PS1"),
                 act="Act1",
                 org="Org1"),
            dict(res=IonObject(RT.TestSite, name="PSC1"),
                 act="Act1",
                 org="Org1"),
            dict(res=IonObject(RT.TestSite, name="IS1"),
                 act="Act1",
                 org="Org1"),
            dict(res=IonObject(RT.TestDeviceModel,
                               name="PM1",
                               manufacturer="CGSN"),
                 act="Act1",
                 org="Org1"),
            dict(res=IonObject(RT.TestDeviceModel,
                               name="PMC1",
                               manufacturer="Bluefin"),
                 act="Act1",
                 org="Org1"),
            dict(res=IonObject(RT.TestDeviceModel,
                               name="PM2",
                               manufacturer="Webb"),
                 act="Act1",
                 org="Org1"),
            dict(res=IonObject(RT.TestDeviceModel,
                               name="IM1",
                               manufacturer="SeaBird"),
                 act="Act1",
                 org="Org1"),
            dict(res=IonObject(RT.TestDeviceModel,
                               name="IM2",
                               manufacturer="Teledyne"),
                 act="Act1",
                 org="Org1"),
            dict(res=IonObject(RT.TestPlatform, name="PD1"),
                 act="Act1",
                 org="Org1",
                 lcstate=LCS.DEPLOYED),
            dict(res=IonObject(RT.TestPlatform, name="PDC1"),
                 act="Act1",
                 org="Org1",
                 lcstate=LCS.INTEGRATED),
            dict(res=IonObject(RT.TestInstrument,
                               name="ID1",
                               firmware_version='A1'),
                 act="Act1",
                 org="Org1",
                 lcstate=LCS.DEPLOYED),
            dict(res=IonObject(RT.TestInstrument,
                               name="ID2",
                               firmware_version='A2'),
                 act="Act1",
                 org="Org1",
                 lcstate=LCS.INTEGRATED),
            dict(res=IonObject(RT.Org, name="Org2"), act="Act2"),
            dict(res=IonObject(RT.TestSite, name="Obs2"),
                 act="Act2",
                 org="Org2"),
            dict(res=IonObject(RT.TestSite, name="PS2"),
                 act="Act2",
                 org="Org2"),
            dict(res=IonObject(RT.TestPlatform, name="PD2"),
                 act="Act2",
                 org="Org2"),
            dict(res=IonObject(RT.TestInstrument,
                               name="ID3",
                               lcstate=LCS.DEPLOYED,
                               firmware_version='A3'),
                 act="Act2",
                 org="Org2"),
            dict(res=IonObject(RT.Stream, name="Stream1")),
        ]
        assocs = [
            ("Obs1", PRED.hasTestSite, "PS1"),
            ("PS1", PRED.hasTestSite, "PSC1"),
            ("PSC1", PRED.hasTestSite, "IS1"),
            ("PS1", PRED.hasTestDevice, "PD1"),
            ("PSC1", PRED.hasTestDevice, "PDC1"),
            ("IS1", PRED.hasTestDevice, "ID1"),
            ("PD1", PRED.hasTestDevice, "PDC1"),
            ("PDC1", PRED.hasTestDevice, "ID1"),
            ("PS1", PRED.hasTestModel, "PM1"),
            ("PSC1", PRED.hasTestModel, "PMC1"),
            ("IS1", PRED.hasTestModel, "IM1"),
            ("PD1", PRED.hasTestModel, "PM1"),
            ("PDC1", PRED.hasTestModel, "PMC1"),
            ("ID1", PRED.hasTestModel, "IM1"),
            ("PD2", PRED.hasTestModel, "PM2"),
            ("ID2", PRED.hasTestModel, "IM2"),
        ]
        res_by_name = create_dummy_resources(res_objs, assocs)

        log.info("TEST: Query for all resources owned by actor Act1")
        rq = ResourceQuery()
        rq.set_filter(
            rq.filter_associated_from_object(res_by_name["Act1"], None,
                                             "hasOwner"))
        result = self.discovery.query(rq.get_query(), id_only=False)
        self.assertEquals(len(result), 14)

        log.info("TEST: Query for all Site descendants of TestSite Obs1")
        rq = ResourceQuery()
        rq.set_filter(
            rq.filter_object_descendants(res_by_name["Obs1"],
                                         [RT.TestSite, RT.TestSite],
                                         PRED.hasTestSite))
        result = self.discovery.query(rq.get_query(), id_only=False)
        # import pprint
        # pprint.pprint(rq.get_query())
        self.assertEquals(len(result), 3)

        log.info("TEST: Query for all resources belonging to Org Org1")
        rq = ResourceQuery()
        rq.set_filter(
            rq.filter_associated_from_subject(res_by_name["Org1"], None,
                                              "hasResource"))
        result = self.discovery.query(rq.get_query(), id_only=False)
        self.assertEquals(len(result), 13)

        log.info(
            "TEST: Query for all resources belonging to Org Org1 AND of type TestInstrument"
        )
        rq = ResourceQuery()
        rq.set_filter(
            rq.filter_associated_from_subject(res_by_name["Org1"], None,
                                              "hasResource"),
            rq.filter_type(RT.TestInstrument))
        result = self.discovery.query(rq.get_query(), id_only=False)
        self.assertEquals(len(result), 2)

        log.info(
            "TEST: Query for instruments whose platform parent has a name of PDC1"
        )
        rq = ResourceQuery()
        rq.set_filter(
            rq.filter_type(RT.TestInstrument),
            rq.filter_associated_from_subject(
                subject_type=RT.TestPlatform,
                predicate=PRED.hasTestDevice,
                target_filter=rq.filter_name("PDC1")))
        result = self.discovery.query(rq.get_query(), id_only=False)
        self.assertEquals(len(result), 1)
        self.assertEquals(result[0].name, "ID1")

        log.info(
            "TEST: Query for instruments in Org1 whose platform parent has a specific attribute set"
        )
        rq = ResourceQuery()
        rq.set_filter(
            rq.filter_type(RT.TestInstrument),
            rq.filter_associated_from_subject(res_by_name["Org1"], None,
                                              "hasResource"),
            rq.filter_associated_from_subject(
                subject_type=RT.TestPlatform,
                predicate=PRED.hasTestDevice,
                target_filter=rq.filter_name("PDC1")))
        result = self.discovery.query(rq.get_query(), id_only=False)
        self.assertEquals(len(result), 1)
        self.assertEquals(result[0].name, "ID1")

        log.info(
            "TEST: Query for instruments in Org1 that are lcstate INTEGRATED")
        rq = ResourceQuery()
        rq.set_filter(
            rq.filter_type(RT.TestInstrument),
            rq.filter_lcstate(LCS.INTEGRATED),
            rq.filter_associated_from_subject(res_by_name["Org1"], None,
                                              "hasResource"))
        result = self.discovery.query(rq.get_query(), id_only=False)
        self.assertEquals(len(result), 1)
        self.assertEquals(result[0].name, "ID2")

        log.info(
            "TEST: Query for instruments in Org1 that are lcstate INTEGRATED OR platforms in Org1 that are lcstate DEPLOYED"
        )
        rq = ResourceQuery()
        rq.set_filter(
            rq.filter_or(
                rq.filter_and(rq.filter_type(RT.TestInstrument),
                              rq.filter_lcstate(LCS.INTEGRATED)),
                rq.filter_and(rq.filter_type(RT.TestPlatform),
                              rq.filter_lcstate(LCS.DEPLOYED))),
            rq.filter_associated_from_subject(res_by_name["Org1"], None,
                                              "hasResource"))
        result = self.discovery.query(rq.get_query(), id_only=False)
        self.assertEquals(len(result), 2)
    def test_query_view(self):
        res_objs = [
            (IonObject(RT.ActorIdentity, name="Act1"), ),
            (IonObject(RT.ActorIdentity, name="Act2"), ),
            (IonObject(RT.TestInstrument,
                       name="ID1",
                       lcstate=LCS.DEPLOYED,
                       firmware_version='A1'), "Act1"),
            (IonObject(RT.TestInstrument,
                       name="ID2",
                       lcstate=LCS.INTEGRATED,
                       firmware_version='A2'), "Act2"),
            (IonObject(RT.TestPlatform, name="PD1"), ),
            (IonObject(RT.TestPlatform, name="PD2"), ),
            (IonObject(RT.TestSite, name="Site1", lcstate=LCS.DEPLOYED), ),
        ]
        assocs = [
            ("PD1", PRED.hasTestDevice, "ID1"),
            ("PD2", PRED.hasTestDevice, "ID2"),
        ]
        res_by_name = create_dummy_resources(res_objs, assocs)

        # ----------------------------------------------------
        # Resource attribute search

        rq = ResourceQuery()
        rq.set_filter(rq.filter_type(RT.TestInstrument))
        view_obj = View(name="All TestInstrument resources",
                        view_definition=rq.get_query())
        view_id = self.discovery.create_view(view_obj)

        # TEST: View by ID
        result = self.discovery.query_view(view_id, id_only=False)
        self.assertEquals(len(result), 2)
        self.assertTrue(
            all(True for ro in result if ro.type_ == RT.TestInstrument))

        # TEST: View by Name
        result = self.discovery.query_view(
            view_name="All TestInstrument resources", id_only=False)
        self.assertEquals(len(result), 2)
        self.assertTrue(
            all(True for ro in result if ro.type_ == RT.TestInstrument))

        # TEST: View plus ext_query
        rq = ResourceQuery()
        rq.set_filter(rq.filter_name("ID1"))
        result = self.discovery.query_view(view_id,
                                           id_only=False,
                                           ext_query=rq.get_query())
        self.assertEquals(len(result), 1)
        self.assertEquals(result[0].name, "ID1")

        # TEST: View with params (anonymous)
        rq = ResourceQuery()
        rq.set_filter(
            rq.filter_type(RT.TestInstrument),
            rq.filter_attribute("firmware_version", "$(firmware_version)"))
        view_obj = View(
            name=
            "TestInstrument resources with a specific firmware - parameterized",
            view_definition=rq.get_query())
        view_id = self.discovery.create_view(view_obj)

        view_params = {"firmware_version": "A2"}
        result = self.discovery.query_view(view_id,
                                           id_only=False,
                                           search_args=view_params)
        self.assertEquals(len(result), 1)
        self.assertEquals(result[0].name, "ID2")

        # TEST: View with params (anonymous) - no values provided
        result = self.discovery.query_view(view_id, id_only=False)
        self.assertEquals(len(result), 0)

        # View with params (with definitions and defaults)
        view_param_def = [
            CustomAttribute(name="firmware_version", type="str", default="A1")
        ]
        view_obj = View(
            name=
            "TestInstrument resources with a specific firmware - parameterized with defaults",
            view_definition=rq.get_query(),
            view_parameters=view_param_def)
        view_id = self.discovery.create_view(view_obj)

        # TEST: Definition defaults
        result = self.discovery.query_view(view_id, id_only=False)
        self.assertEquals(len(result), 1)
        self.assertEquals(result[0].name, "ID1")

        # TEST: Parameterized values
        result = self.discovery.query_view(view_id,
                                           id_only=False,
                                           search_args=view_params)
        self.assertEquals(len(result), 1)
        self.assertEquals(result[0].name, "ID2")

        # TEST: Parameterized association query for resource owner
        rq = ResourceQuery()
        rq.set_filter(rq.filter_associated_from_object("$(owner)"))
        view_obj = View(name="Resources owned by actor - parameterized",
                        view_definition=rq.get_query())
        view_id = self.discovery.create_view(view_obj)
        view_params = {"owner": res_by_name["Act2"]}
        result = self.discovery.query_view(view_id,
                                           id_only=False,
                                           search_args=view_params)
        self.assertEquals(len(result), 1)
        self.assertEquals(result[0].name, "ID2")

        # TEST: Parameterized association query for resource owner with parameter value
        view_params = {"owner": res_by_name["Act2"], "query_info": True}
        result = self.discovery.query_view(view_id,
                                           id_only=False,
                                           search_args=view_params)
        self.assertEquals(len(result), 2)
        self.assertEquals(result[0].name, "ID2")
        self.assertIn("_query_info", result[1])
        self.assertIn("statement_sql", result[1])

        # TEST: Builtin views
        rq = ResourceQuery()
        rq.set_filter(rq.filter_type(RT.TestSite))
        result = self.discovery.query_view(view_name="resources_index",
                                           id_only=False,
                                           ext_query=rq.get_query())
        self.assertEquals(len(result), 1)
        self.assertEquals(result[0].name, "Site1")

        # --- Events setup

        from interface.objects import ResourceOperatorEvent, ResourceCommandEvent
        t0 = 136304640000
        events = [
            ("RME1",
             ResourceCommandEvent(origin="O1",
                                  origin_type="OT1",
                                  sub_type="ST1",
                                  ts_created=str(t0))),
            ("RME2",
             ResourceCommandEvent(origin="O2",
                                  origin_type="OT1",
                                  sub_type="ST2",
                                  ts_created=str(t0 + 1))),
            ("RME3",
             ResourceCommandEvent(origin="O2",
                                  origin_type="OT2",
                                  sub_type="ST3",
                                  ts_created=str(t0 + 2))),
            ("RLE1",
             ResourceOperatorEvent(origin="O1",
                                   origin_type="OT3",
                                   sub_type="ST4",
                                   ts_created=str(t0 + 3))),
            ("RLE2",
             ResourceOperatorEvent(origin="O3",
                                   origin_type="OT3",
                                   sub_type="ST5",
                                   ts_created=str(t0 + 4))),
            ("RLE3",
             ResourceOperatorEvent(origin="O3",
                                   origin_type="OT2",
                                   sub_type="ST6",
                                   ts_created=str(t0 + 5))),
        ]
        ev_by_alias = create_dummy_events(events)

        # TEST: Event query with views
        eq = EventQuery()
        eq.set_filter(eq.filter_type(OT.ResourceCommandEvent))
        view_obj = View(name="All ResourceCommandEvent events",
                        view_definition=eq.get_query())
        view_id = self.discovery.create_view(view_obj)
        result = self.discovery.query_view(view_id, id_only=False)
        self.assertEquals(len(result), 3)
        self.assertTrue(
            all(True for eo in result if eo.type_ == OT.ResourceCommandEvent))

        # TEST: Event query with views - stripped format
        result = self.discovery.query_view(
            view_id,
            id_only=False,
            search_args=dict(attribute_filter=["origin"]))
        self.assertEquals(len(result), 3)
        self.assertTrue(all(True for eo in result if isinstance(eo, dict)))
        self.assertTrue(all(True for eo in result if "origin" in eo))
        self.assertTrue(all(True for eo in result if len(eo) <= 4))

        # TEST: Builtin views
        eq = EventQuery()
        eq.set_filter(eq.filter_type(OT.ResourceCommandEvent))
        result = self.discovery.query_view(view_name="events_index",
                                           id_only=False,
                                           ext_query=eq.get_query())
        self.assertEquals(len(result), 3)