def setUp(self):
        self._start_container()
        self.container.start_rel_from_url('res/deploy/r2dm.yml')

        self.ims_cli = IndexManagementServiceClient()
        self.rr_cli = ResourceRegistryServiceClient()
        self.index_name = 'test_index'
示例#2
0
    def setUp(self):
        super(DiscoveryIntTest, self).setUp()

        self._start_container()
        self.addCleanup(DiscoveryIntTest.es_cleanup)
        self.container.start_rel_from_url('res/deploy/r2dm.yml')

        self.discovery = DiscoveryServiceClient()
        self.catalog   = CatalogManagementServiceClient()
        self.ims       = IndexManagementServiceClient()
        self.rr        = ResourceRegistryServiceClient()

        if use_es:
            self.es_host   = CFG.get_safe('server.elasticsearch.host', 'localhost')
            self.es_port   = CFG.get_safe('server.elasticsearch.port', '9200')
            CFG.server.elasticsearch.shards         = 1
            CFG.server.elasticsearch.replicas       = 0
            CFG.server.elasticsearch.river_shards   = 1
            CFG.server.elasticsearch.river_replicas = 0
            self.es = ep.ElasticSearch(
                host=self.es_host,
                port=self.es_port,
                timeout=10,
                verbose=True
            )
            op = DotDict(CFG)
            op.op = 'clean_bootstrap'
            self.container.spawn_process('index_bootstrap','ion.processes.bootstrap.index_bootstrap','IndexBootStrap', op)
    def setUp(self):
        self._start_container()
        self.container.start_rel_from_url("res/deploy/r2dm.yml")

        self.ims_cli = IndexManagementServiceClient()
        self.rr_cli = ResourceRegistryServiceClient()
        self.index_name = "test_index"
示例#4
0
    def setUp(self):
        super(DiscoveryIntTest, self).setUp()

        self._start_container()
        self.addCleanup(DiscoveryIntTest.es_cleanup)
        self.container.start_rel_from_url('res/deploy/r2dm.yml')

        self.discovery = DiscoveryServiceClient()
        self.catalog   = CatalogManagementServiceClient()
        self.ims       = IndexManagementServiceClient()
        self.rr        = ResourceRegistryServiceClient()

        if use_es:
            self.es_host   = CFG.get_safe('server.elasticsearch.host', 'localhost')
            self.es_port   = CFG.get_safe('server.elasticsearch.port', '9200')
            CFG.server.elasticsearch.shards         = 1
            CFG.server.elasticsearch.replicas       = 0
            CFG.server.elasticsearch.river_shards   = 1
            CFG.server.elasticsearch.river_replicas = 0
            self.es = ep.ElasticSearch(
                host=self.es_host,
                port=self.es_port,
                timeout=10,
                verbose=True
            )
            op = DotDict(CFG)
            op.op = 'clean_bootstrap'
            self.container.spawn_process('index_bootstrap','ion.processes.bootstrap.index_bootstrap','IndexBootStrap', op)
    def setUp(self):
        super(DiscoveryIntTest, self).setUp()
        config = DotDict()
        config.bootstrap.use_es = True

        self._start_container()
        self.addCleanup(DiscoveryIntTest.es_cleanup)
        self.container.start_rel_from_url('res/deploy/r2dm.yml', config)

        self.discovery = DiscoveryServiceClient()
        self.catalog   = CatalogManagementServiceClient()
        self.ims       = IndexManagementServiceClient()
        self.rr        = ResourceRegistryServiceClient()
    def setUp(self):
        raise SkipTest("Not yet ported to Postgres")

        super(DiscoveryIntTest, self).setUp()
        config = DotDict()

        self._start_container()
        self.container.start_rel_from_url('res/deploy/r2deploy.yml', config)

        self.discovery               = DiscoveryServiceClient()
        self.catalog                 = CatalogManagementServiceClient()
        self.ims                     = IndexManagementServiceClient()
        self.rr                      = ResourceRegistryServiceClient()
        self.dataset_management      = DatasetManagementServiceClient()
        self.pubsub_management       = PubsubManagementServiceClient()
        self.data_product_management = DataProductManagementServiceClient()
class IndexManagementIntTest(IonIntegrationTestCase):
    def setUp(self):
        self._start_container()
        self.container.start_rel_from_url("res/deploy/r2dm.yml")

        self.ims_cli = IndexManagementServiceClient()
        self.rr_cli = ResourceRegistryServiceClient()
        self.index_name = "test_index"

    def test_create_elasticsearch_index(self):
        index_name = self.index_name
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        options = SearchOptions()
        options.attribute_match = ["test_field"]
        index_id = ims_cli.create_index(
            name=index_name, content_type=IndexManagementService.ELASTICSEARCH_INDEX, options=options
        )

        index_result = self.rr_cli.read(index_id)
        self.assertIsInstance(index_result, ElasticSearchIndex)
        self.assertTrue(index_result.name == index_name)

        # ======================================
        # Clean up
        # ======================================
        rr_cli.delete(index_id)

    def test_create_couchdb_index(self):
        index_name = self.index_name
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        options = SearchOptions()
        options.attribute_match = ["name"]

        index_id = ims_cli.create_index(
            index_name,
            content_type=IndexManagementService.COUCHDB_INDEX,
            options=options,
            datastore_name="fake",
            view_name="fake/by_fake",
        )
        index_result = self.rr_cli.read(index_id)
        self.assertIsInstance(index_result, CouchDBIndex)
        self.assertTrue(index_result.name == index_name)
        # ======================================
        # Clean up
        # ======================================
        rr_cli.delete(index_id)

    def test_read_index(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        index_name = self.index_name
        index_res = Index(name=index_name)
        index_id, _ = rr_cli.create(index_res)

        index = ims_cli.read_index(index_id)
        self.assertIsInstance(index, Index)
        self.assertTrue(index.name == index_name)

        rr_cli.delete(index_id)

    def test_delete_index(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        index_name = self.index_name
        index_res = Index(name=index_name)
        index_id, _ = rr_cli.create(index_res)

        ims_cli.delete_index(index_id)

        with self.assertRaises(NotFound):
            rr_cli.delete(index_id)

    def test_update_index(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        index_name = self.index_name
        index_res = Index(name=index_name)
        index_id, _ = rr_cli.create(index_res)

        index = ims_cli.read_index(index_id)
        index.name = "another"
        ims_cli.update_index(index)

        index = rr_cli.read(index_id)
        self.assertTrue(index.name == "another")

    def test_find_indexes(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        index_name = self.index_name

        # ======================================
        # Index Pool
        # ======================================

        indexes = [Index(name="first"), Index(name="second"), Index(name="third")]
        id_pool = list()
        for index in indexes:
            id_pool.append(rr_cli.create(index)[0])

        index_id = ims_cli.find_indexes(index_name="second")
        index = ims_cli.read_index(index_id)
        self.assertTrue(index.name == "second")

        # ======================================
        # Clean up
        # ======================================

        for index_id in id_pool:
            rr_cli.delete(index_id)

    def test_list_indexes(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        index_name = self.index_name

        # ======================================
        # Index Pool
        # ======================================

        indexes = [Index(name="first"), Index(name="second"), Index(name="third")]
        id_pool = list()
        for index in indexes:
            id_pool.append(rr_cli.create(index)[0])

        names = set(ims_cli.list_indexes().keys())
        self.assertTrue(names == set(["first", "second", "third"]))

        # ======================================
        # Clean up
        # ======================================

        for index_id in id_pool:
            rr_cli.delete(index_id)

    def test_create_collection(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        with self.assertRaises(BadRequest):
            ims_cli.create_collection("failing_collection")

        resources = [Resource(), Resource(), Resource()]
        resources = [rr_cli.create(i)[0] for i in resources]

        collection_id = ims_cli.create_collection("working_collection", resources)

        collection = rr_cli.read(collection_id)
        collection_resources = ims_cli.list_collection_resources(collection_id, id_only=True)
        self.assertTrue(
            set(collection_resources) == set(resources), "%s != %s" % (set(collection_resources), set(resources))
        )

    def test_read_collection(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        collection = Collection(name="working_collection")
        collection_id, _ = rr_cli.create(collection)
        collection = ims_cli.read_collection(collection_id)
        self.assertTrue(collection.name == "working_collection")

    def test_update_collection(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli

        collection = Collection(name="useful_collection")
        collection_id, _ = rr_cli.create(collection)
        collection = rr_cli.read(collection_id)
        collection.name = "nub"
        ims_cli.update_collection(collection)
        collection = rr_cli.read(collection_id)
        self.assertTrue(collection.name == "nub")

    def test_delete_collection(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        res = Resource()
        res_id, rev = rr_cli.create(res)

        collection_id = ims_cli.create_collection(name="test_collection", resources=[res_id])

        ims_cli.delete_collection(collection_id)

        with self.assertRaises(NotFound):
            rr_cli.read(collection_id)

    def test_list_collection_resources(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        # ========================================
        # Resource Pool
        # ========================================
        resources = [
            InformationResource(name="bean_counter"),
            InformationResource(name="lunar_rock"),
            InformationResource("aperature"),
            InformationResource("lemons"),
        ]

        resources = [rr_cli.create(i)[0] for i in resources]

        collection = Collection(name="park_bench")

        collection_id = ims_cli.create_collection(name="park_bench", resources=resources)
        retval = ims_cli.list_collection_resources(collection_id, id_only=True)

        retval.sort()
        resources.sort()

        self.assertTrue(retval == resources, "%s != %s" % (retval, resources))

    def test_find_collection(self):
        res_id, _ = self.rr_cli.create(Resource(name="test_res"))
        collection_id = self.ims_cli.create_collection("test", [res_id])

        retval = self.ims_cli.find_collection(collection_name="test")
        self.assertTrue(retval[0] == collection_id)

        retval = self.ims_cli.find_collection(resource_ids=[res_id])
        self.assertTrue(retval[0] == collection_id)
class IndexManagementIntTest(IonIntegrationTestCase):
    def setUp(self):
        self._start_container()
        self.container.start_rel_from_url('res/deploy/r2dm.yml')

        self.ims_cli = IndexManagementServiceClient()
        self.rr_cli  = ResourceRegistryServiceClient()
        self.index_name = 'test_index'

    def test_create_elasticsearch_index(self):
        index_name = self.index_name
        ims_cli    = self.ims_cli
        rr_cli     = self.rr_cli
        options = SearchOptions()
        options.attribute_match = ['test_field']
        index_id = ims_cli.create_index(
           name=index_name,
           content_type=IndexManagementService.ELASTICSEARCH_INDEX,
           options=options
       )
        
        index_result = self.rr_cli.read(index_id)
        self.assertIsInstance(index_result,ElasticSearchIndex)
        self.assertTrue(index_result.name == index_name)

        #======================================
        # Clean up
        #======================================
        rr_cli.delete(index_id)

    def test_create_couchdb_index(self):
        index_name = self.index_name
        ims_cli    = self.ims_cli
        rr_cli     = self.rr_cli
        options = SearchOptions()
        options.attribute_match = ['name']

        index_id = ims_cli.create_index(
            index_name, 
            content_type=IndexManagementService.COUCHDB_INDEX,
            options=options,
            datastore_name='fake',
            view_name='fake/by_fake'
        )
        index_result = self.rr_cli.read(index_id)
        self.assertIsInstance(index_result,CouchDBIndex)
        self.assertTrue(index_result.name==index_name)
        #======================================
        # Clean up
        #======================================
        rr_cli.delete(index_id)
        
    def test_read_index(self):
        ims_cli = self.ims_cli
        rr_cli  = self.rr_cli
        index_name  = self.index_name
        index_res   = Index(name=index_name)
        index_id, _ = rr_cli.create(index_res)

        index = ims_cli.read_index(index_id)
        self.assertIsInstance(index,Index)
        self.assertTrue(index.name==index_name)

        rr_cli.delete(index_id)

    def test_delete_index(self):
        ims_cli = self.ims_cli
        rr_cli  = self.rr_cli
        index_name  = self.index_name
        index_res   = Index(name=index_name)
        index_id, _ = rr_cli.create(index_res)

        ims_cli.delete_index(index_id)

        with self.assertRaises(NotFound):
            rr_cli.delete(index_id)

    def test_update_index(self):
        ims_cli = self.ims_cli
        rr_cli  = self.rr_cli
        index_name  = self.index_name
        index_res   = Index(name=index_name)
        index_id, _ = rr_cli.create(index_res)

        index = ims_cli.read_index(index_id)
        index.name = 'another'
        ims_cli.update_index(index)

        index = rr_cli.read(index_id)
        self.assertTrue(index.name == 'another')

    def test_find_indexes(self):
        ims_cli = self.ims_cli
        rr_cli  = self.rr_cli
        index_name  = self.index_name
        
        #======================================
        # Index Pool
        #======================================
        
        indexes = [
            Index(name='first'),
            Index(name='second'),
            Index(name='third')
        ]
        id_pool = list()
        for index in indexes:
            id_pool.append(rr_cli.create(index)[0])

        index_id = ims_cli.find_indexes(index_name='second')
        index = ims_cli.read_index(index_id)
        self.assertTrue(index.name=='second')

        
        #======================================
        # Clean up
        #======================================

        for index_id in id_pool:
            rr_cli.delete(index_id)

    def test_create_collection(self):
        ims_cli = self.ims_cli
        rr_cli  = self.rr_cli
        with self.assertRaises(BadRequest):
            ims_cli.create_collection('failing_collection')

        resources = [ Resource(), Resource(), Resource() ]
        resources = [ rr_cli.create(i)[0] for i in resources ] 
        

        collection_id = ims_cli.create_collection('working_collection',resources)

        collection = rr_cli.read(collection_id)
        collection_resources = ims_cli.list_collection_resources(collection_id, id_only=True)
        self.assertTrue(set(collection_resources) == set(resources), '%s != %s' % (set(collection_resources) , set(resources)))

    def test_read_collection(self):
        ims_cli = self.ims_cli
        rr_cli  = self.rr_cli
        collection = Collection(name='working_collection')
        collection_id, _  = rr_cli.create(collection)
        collection = ims_cli.read_collection(collection_id)
        self.assertTrue(collection.name == 'working_collection')

    def test_update_collection(self):
       ims_cli = self.ims_cli
       rr_cli  = self.rr_cli

       collection = Collection(name='useful_collection')
       collection_id, _ = rr_cli.create(collection)
       collection = rr_cli.read(collection_id)
       collection.name = 'nub'
       ims_cli.update_collection(collection)
       collection = rr_cli.read(collection_id)
       self.assertTrue(collection.name=='nub')

    def test_delete_collection(self):
        ims_cli = self.ims_cli
        rr_cli  = self.rr_cli
        res = Resource()
        res_id, rev = rr_cli.create(res)

        collection_id = ims_cli.create_collection(name='test_collection', resources=[res_id])

        ims_cli.delete_collection(collection_id)

        with self.assertRaises(NotFound):
            rr_cli.read(collection_id)

    def test_list_collection_resources(self):
        ims_cli = self.ims_cli
        rr_cli  = self.rr_cli
        #========================================
        # Resource Pool
        #========================================
        resources = [ InformationResource(name='bean_counter'), InformationResource(name='lunar_rock'), InformationResource('aperature'), InformationResource('lemons') ] 

        resources = [ rr_cli.create(i)[0] for i in resources ]

        collection = Collection(name='park_bench')

        collection_id = ims_cli.create_collection(name='park_bench', resources=resources)
        retval = ims_cli.list_collection_resources(collection_id, id_only=True)

        retval.sort()
        resources.sort()

        self.assertTrue(retval == resources, '%s != %s' %(retval , resources))

    def test_find_collection(self):
        res_id, _  = self.rr_cli.create(Resource(name='test_res'))
        collection_id = self.ims_cli.create_collection('test', [res_id])

        retval = self.ims_cli.find_collection(collection_name='test')
        self.assertTrue(retval[0] == collection_id)

        retval = self.ims_cli.find_collection(resource_ids=[res_id])
        self.assertTrue(retval[0] == collection_id)
class DiscoveryIntTest(IonIntegrationTestCase):
    def setUp(self):
        super(DiscoveryIntTest, self).setUp()
        config = DotDict()
        config.bootstrap.use_es = True

        self._start_container()
        self.addCleanup(DiscoveryIntTest.es_cleanup)
        self.container.start_rel_from_url('res/deploy/r2deploy.yml', config)

        self.discovery               = DiscoveryServiceClient()
        self.catalog                 = CatalogManagementServiceClient()
        self.ims                     = IndexManagementServiceClient()
        self.rr                      = ResourceRegistryServiceClient()
        self.dataset_management      = DatasetManagementServiceClient()
        self.pubsub_management       = PubsubManagementServiceClient()
        self.data_product_management = DataProductManagementServiceClient()

    @staticmethod
    def es_cleanup():
        es_host = CFG.get_safe('server.elasticsearch.host', 'localhost')
        es_port = CFG.get_safe('server.elasticsearch.port', '9200')
        es = ep.ElasticSearch(
            host=es_host,
            port=es_port,
            timeout=10
        )
        indexes = STD_INDEXES.keys()
        indexes.append('%s_resources_index' % get_sys_name().lower())
        indexes.append('%s_events_index' % get_sys_name().lower())

        for index in indexes:
            IndexManagementService._es_call(es.river_couchdb_delete,index)
            IndexManagementService._es_call(es.index_delete,index)


    def poll(self, tries, callback, *args, **kwargs):
        '''
        Polling wrapper for queries
        Elasticsearch may not index and cache the changes right away so we may need 
        a couple of tries and a little time to go by before the results show.
        '''
        for i in xrange(tries):
            retval = callback(*args, **kwargs)
            if retval:
                return retval
            time.sleep(0.2)
        return None


    def test_traversal(self):
        dp        = DataProcess()
        transform = Transform()
        pd        = ProcessDefinition()

        dp_id, _        = self.rr.create(dp)
        transform_id, _ = self.rr.create(transform)
        pd_id, _        = self.rr.create(pd)

        self.rr.create_association(subject=dp_id, object=transform_id, predicate=PRED.hasTransform)
        self.rr.create_association(subject=transform_id, object=pd_id, predicate=PRED.hasProcessDefinition)

        results = self.discovery.traverse(dp_id)
        results.sort()
        correct = [pd_id, transform_id]
        correct.sort()
        self.assertTrue(results == correct, '%s' % results)

    def test_iterative_traversal(self):
        dp        = DataProcess()
        transform = Transform()
        pd        = ProcessDefinition()

        dp_id, _        = self.rr.create(dp)
        transform_id, _ = self.rr.create(transform)
        pd_id, _        = self.rr.create(pd)

        self.rr.create_association(subject=dp_id, object=transform_id, predicate=PRED.hasTransform)
        self.rr.create_association(subject=transform_id, object=pd_id, predicate=PRED.hasProcessDefinition)

        results = self.discovery.iterative_traverse(dp_id)
        results.sort()
        correct = [transform_id]
        self.assertTrue(results == correct)

        results = self.discovery.iterative_traverse(dp_id, 1)
        results.sort()
        correct = [transform_id, pd_id]
        correct.sort()
        self.assertTrue(results == correct)
    
    @skipIf(not use_es, 'No ElasticSearch')
    def test_view_crud(self):
        view_id = self.discovery.create_view('big_view',fields=['name'])
        catalog_id = self.discovery.list_catalogs(view_id)[0]
        index_ids = self.catalog.list_indexes(catalog_id)
        self.assertTrue(len(index_ids))

        view = self.discovery.read_view(view_id)
        self.assertIsInstance(view,View)
        self.assertTrue(view.name == 'big_view')

        view.name = 'not_so_big_view'

        self.discovery.update_view(view)

        view = self.discovery.read_view(view_id)
        self.assertTrue(view.name == 'not_so_big_view')

        self.discovery.delete_view(view_id)
        with self.assertRaises(NotFound):
            self.discovery.read_view(view_id)

    def test_view_best_match(self):
        #---------------------------------------------------------------
        # Matches the best catalog available OR creates a new one
        #---------------------------------------------------------------
        catalog_id = self.catalog.create_catalog('dev', keywords=['name','model'])
        view_id    = self.discovery.create_view('exact_view', fields=['name','model'])
        catalog_ids = self.discovery.list_catalogs(view_id)
        self.assertTrue(catalog_ids == [catalog_id])

        view_id = self.discovery.create_view('another_view', fields=['name','model'])
        catalog_ids = self.discovery.list_catalogs(view_id)
        self.assertTrue(catalog_ids == [catalog_id])

        view_id = self.discovery.create_view('big_view', fields=['name'])
        catalog_ids = self.discovery.list_catalogs(view_id)
        self.assertTrue(catalog_ids != [catalog_id])

    @skipIf(not use_es, 'No ElasticSearch')
    def test_basic_searching(self):

        #- - - - - - - - - - - - - - - - - 
        # set up the fake resources
        #- - - - - - - - - - - - - - - - - 

        instrument_pool = [
            InstrumentDevice(name='sonobuoy1', firmware_version='1'),
            InstrumentDevice(name='sonobuoy2', firmware_version='2'),
            InstrumentDevice(name='sonobuoy3', firmware_version='3')
        ]
        for instrument in instrument_pool:
            self.rr.create(instrument)

        view_id = self.discovery.create_view('devices', fields=['firmware_version'])

        search_string = "search 'firmware_version' is '2' from '%s'"%view_id
        results = self.poll(5, self.discovery.parse,search_string)
        result  = results[0]['_source']
        self.assertIsInstance(result, InstrumentDevice)
        self.assertTrue(result.name == 'sonobuoy2')
        self.assertTrue(result.firmware_version == '2')


    @skipIf(not use_es, 'No ElasticSearch')
    def test_associative_searching(self):

        dp_id,_ = self.rr.create(DataProduct('test_foo'))
        ds_id,_ = self.rr.create(Dataset('test_bar', registered=True))
        self.rr.create_association(subject=dp_id, object=ds_id, predicate='hasDataset')

        search_string = "search 'type_' is 'Dataset' from 'resources_index' and belongs to '%s'" % dp_id

        results = self.poll(5, self.discovery.parse,search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(ds_id in results)

    def test_iterative_associative_searching(self):
        #--------------------------------------------------------------------------------
        # Tests the ability to limit the iterations
        #--------------------------------------------------------------------------------
        dp        = DataProcess()
        transform = Transform()
        pd        = ProcessDefinition()

        dp_id, _        = self.rr.create(dp)
        transform_id, _ = self.rr.create(transform)
        pd_id, _        = self.rr.create(pd)

        self.rr.create_association(subject=dp_id, object=transform_id, predicate=PRED.hasTransform)
        self.rr.create_association(subject=transform_id, object=pd_id, predicate=PRED.hasProcessDefinition)

        search_string = "belongs to '%s' depth 1" % dp_id
        results = self.poll(5, self.discovery.parse,search_string)
        results = list([i._id for i in results])
        correct = [transform_id]
        self.assertTrue(results == correct, '%s' % results)

        search_string = "belongs to '%s' depth 2" % dp_id
        results = self.poll(5, self.discovery.parse,search_string)
        results = list([i._id for i in results])
        results.sort()
        correct = [transform_id, pd_id]
        correct.sort()
        self.assertTrue(results == correct)


    @skipIf(not use_es, 'No ElasticSearch')
    def test_ranged_value_searching(self):
        discovery = self.discovery
        rr        = self.rr
        
        view_id = discovery.create_view('bank_view', fields=['cash_balance'])
        bank_id, _ = rr.create(BankAccount(name='broke', cash_balance=10))

        search_string = "search 'cash_balance' values from 0 to 100 from '%s'" % view_id

        results = self.poll(5, discovery.parse, search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == bank_id)
        
        bank_id, _ = rr.create(BankAccount(name='broke', cash_balance=90))

        search_string = "search 'cash_balance' values from 80 from '%s'" % view_id

        results = self.poll(5, discovery.parse, search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == bank_id)

    @skipIf(not use_es, 'No ElasticSearch')
    def test_collections_searching(self):

        site_id, _ = self.rr.create(Site(name='black_mesa'))
        view_id    = self.discovery.create_view('big', fields=['name'])

        # Add the site to a new collection
        collection_id = self.ims.create_collection('resource_collection', [site_id])

        search_string = "search 'name' is '*' from '%s' and in '%s'" %(view_id, collection_id)

        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0] == site_id, '%s' % results)

    @skipIf(not use_es, 'No ElasticSearch')
    def test_search_by_name(self):
        inst_dev = InstrumentDevice(name='test_dev',serial_number='ABC123')

        dev_id, _ = self.rr.create(inst_dev)
        self.discovery.create_view('devs',fields=['name','serial_number'])

        search_string = "search 'serial_number' is 'abc*' from 'devs'"
        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dev_id)

    @skipIf(not use_es, 'No ElasticSearch')
    def test_search_by_name_index(self):
        inst_dev = InstrumentDevice(name='test_dev',serial_number='ABC123')

        dev_id, _ = self.rr.create(inst_dev)
        search_string = "search 'serial_number' is 'abc*' from 'resources_index'"
        
        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dev_id)

        bank_acc = BankAccount(name='blah', cash_balance=10)
        res_id , _ = self.rr.create(bank_acc)

        search_string = "search 'cash_balance' values from 0 to 100 from 'resources_index'"

        results = self.poll(9, self.discovery.parse,search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == res_id)

    #@skipIf(not use_es, 'No ElasticSearch')
    @skip('Skip until time to refactor, data_format is removed from DataProduct resource')
    def test_data_product_search(self):

        # Create the dataproduct
        dp = DataProduct(name='test_product')
        dp.data_format.name = 'test_signal'
        dp.data_format.description = 'test signal'
        dp.data_format.character_set = 'utf8'
        dp.data_format.nominal_sampling_rate_maximum = '44000'
        dp.data_format.nominal_sampling_rate_minimum = '44000'
        dp.CDM_data_type = 'basic'
        dp_id, _ = self.rr.create(dp)

        search_string = "search 'data_format.name' is 'test_signal' from 'data_products_index'"
        results = self.poll(9, self.discovery.parse, search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)

        search_string = "search 'CDM_data_type' is 'basic' from 'data_products_index'"
        results = self.poll(9, self.discovery.parse, search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)
        
        search_string = "search 'data_format.character_set' is 'utf8' from 'data_products_index'"
        results = self.poll(9, self.discovery.parse, search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)

    @skipIf(not use_es, 'No ElasticSearch')
    def test_events_search(self):
        # Create a resource to force a new event

        dp = DataProcess()
        dp_id, rev = self.rr.create(dp)

        search_string = "SEARCH 'origin' IS '%s' FROM 'events_index'" % dp_id

        results = self.poll(9, self.discovery.parse,search_string)
        origin_type = results[0]['_source'].origin_type
        origin_id = results[0]['_source'].origin

        self.assertTrue(origin_type == RT.DataProcess)
        self.assertTrue(origin_id == dp_id)

    @skipIf(not use_es, 'No ElasticSearch')
    def test_geo_distance_search(self):

        pd = PlatformDevice(name='test_dev')

        pd_id, _ = self.rr.create(pd)

        search_string = "search 'index_location' geo distance 20 km from lat 0 lon 0 from 'devices_index'"

        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')

        self.assertTrue(results[0]['_id'] == pd_id)
        self.assertTrue(results[0]['_source'].name == 'test_dev')
   
    @skipIf(not use_es, 'No ElasticSearch')
    def test_geo_bbox_search(self):

        pd = PlatformDevice(name='test_dev')
        pd.index_location.lat = 5
        pd.index_location.lon = 5

        pd_id, _ = self.rr.create(pd)

        search_string = "search 'index_location' geo box top-left lat 10 lon 0 bottom-right lat 0 lon 10 from 'devices_index'"

        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')

        self.assertTrue(results[0]['_id'] == pd_id)
        self.assertTrue(results[0]['_source'].name == 'test_dev')


    @skipIf(not use_es, 'No ElasticSearch')
    def test_time_search(self):
        today     = date.today()
        yesterday = today - timedelta(days=1)
        tomorrow  = today + timedelta(days=1)

        data_product = DataProduct()
        dp_id, _ = self.rr.create(data_product)
        
        search_string = "search 'ts_created' time from '%s' to '%s' from 'data_products_index'" % (yesterday, tomorrow)

        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results,'Results not found')

        self.assertTrue(results[0]['_id'] == dp_id)
        
        search_string = "search 'ts_created' time from '%s' from 'data_products_index'" % yesterday

        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results,'Results not found')

        self.assertTrue(results[0]['_id'] == dp_id)

        
    @skipIf(not use_es, 'No ElasticSearch')
    def test_user_search(self):
        user = UserInfo()
        user.name = 'test'
        user.contact.phones.append('5551212')

        user_id, _ = self.rr.create(user)

        search_string = 'search "name" is "test" from "users_index"'

        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')

        self.assertTrue(results[0]['_id'] == user_id)
        self.assertTrue(results[0]['_source'].name == 'test')

        search_string = 'search "contact.phones" is "5551212" from "users_index"'
        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')

        self.assertTrue(results[0]['_id'] == user_id)
        self.assertTrue(results[0]['_source'].name == 'test')


    @skipIf(not use_es, 'No ElasticSearch')
    def test_subobject_search(self):
        contact = ContactInformation()
        contact.email = '*****@*****.**'
        contact.individual_name_family = 'Tester'
        contact.individual_names_given = 'Intern'

        dp = DataProduct(name='example')
        dp.contacts.append(contact)

        dp_id,_ = self.rr.create(dp)

        #--------------------------------------------------------------------------------
        # Example using the full field name
        #--------------------------------------------------------------------------------
        search_string = 'search "contacts.email" is "*****@*****.**" from "data_products"'
        results = self.poll(9, self.discovery.parse, search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)
        self.assertEquals(results[0]['_source'].name, 'example')

        #--------------------------------------------------------------------------------
        # Example using a sub-object's field name (ambiguous searching)
        #--------------------------------------------------------------------------------
        search_string = 'search "individual_names_given" is "Intern" from "data_products"'
        results = self.poll(9, self.discovery.parse, search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)
        self.assertEquals(results[0]['_source'].name, 'example')

    @skipIf(not use_es, 'No ElasticSearch')
    def test_descriptive_phrase_search(self):
        dp = DataProduct(name='example', description='This is simply a description for this data product')
        dp_id, _ = self.rr.create(dp)

        search_string = 'search "description" like "description for" from "data_products"'
        results = self.poll(9, self.discovery.parse, search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)
        self.assertEquals(results[0]['_source'].name, 'example')


    @skipIf(not use_es, 'No ElasticSearch')
    def test_ownership_searching(self):
        # Create two data products so that there is competition to the search, one is parsed 
        # (with conductivity as a parameter) and the other is raw
        dp = DataProduct(name='example dataproduct')
        pdict_id = self.dataset_management.read_parameter_dictionary_by_name('ctd_parsed_param_dict')
        stream_def_id = self.pubsub_management.create_stream_definition('ctd parsed', parameter_dictionary_id=pdict_id)
        tdom, sdom = time_series_domain()
        dp.spatial_domain = sdom.dump()
        dp.temporal_domain = tdom.dump()
        dp_id = self.data_product_management.create_data_product(dp, stream_definition_id=stream_def_id, exchange_point='xp1')

        pdict_id = self.dataset_management.read_parameter_dictionary_by_name('ctd_raw_param_dict')
        stream_def_id = self.pubsub_management.create_stream_definition('ctd raw', parameter_dictionary_id=pdict_id)
        dp = DataProduct(name='WRONG')
        dp.spatial_domain = sdom.dump()
        dp.temporal_domain = tdom.dump()
        self.data_product_management.create_data_product(dp, stream_definition_id=stream_def_id, exchange_point='xp1')

        parameter_search = 'search "name" is "conductivity" from "resources_index"'
        results = self.poll(9, self.discovery.parse, parameter_search)
        param_id = results[0]['_id']

        data_product_search = 'search "name" is "*" from "data_products_index" and has "%s"' % param_id
        results = self.poll(9, self.discovery.parse, data_product_search)
        print results
        self.assertEquals(results[0], dp_id)
示例#10
0
class DiscoveryIntTest(IonIntegrationTestCase):
    def setUp(self):
        super(DiscoveryIntTest, self).setUp()

        self._start_container()
        self.addCleanup(DiscoveryIntTest.es_cleanup)
        self.container.start_rel_from_url('res/deploy/r2dm.yml')

        self.discovery = DiscoveryServiceClient()
        self.catalog   = CatalogManagementServiceClient()
        self.ims       = IndexManagementServiceClient()
        self.rr        = ResourceRegistryServiceClient()

        if use_es:
            self.es_host   = CFG.get_safe('server.elasticsearch.host', 'localhost')
            self.es_port   = CFG.get_safe('server.elasticsearch.port', '9200')
            CFG.server.elasticsearch.shards         = 1
            CFG.server.elasticsearch.replicas       = 0
            CFG.server.elasticsearch.river_shards   = 1
            CFG.server.elasticsearch.river_replicas = 0
            self.es = ep.ElasticSearch(
                host=self.es_host,
                port=self.es_port,
                timeout=10,
                verbose=True
            )
            op = DotDict(CFG)
            op.op = 'clean_bootstrap'
            self.container.spawn_process('index_bootstrap','ion.processes.bootstrap.index_bootstrap','IndexBootStrap', op)

    @staticmethod
    def es_cleanup():
        es_host = CFG.get_safe('server.elasticsearch.host', 'localhost')
        es_port = CFG.get_safe('server.elasticsearch.port', '9200')
        es = ep.ElasticSearch(
            host=es_host,
            port=es_port,
            timeout=10
        )
        indexes = STD_INDEXES.keys()
        indexes.append('%s_resources_index' % get_sys_name().lower())
        indexes.append('%s_events_index' % get_sys_name().lower())

        for index in indexes:
            IndexManagementService._es_call(es.river_couchdb_delete,index)
            IndexManagementService._es_call(es.index_delete,index)


    def poll(self, tries, callback, *args, **kwargs):
        '''
        Polling wrapper for queries
        Elasticsearch may not index and cache the changes right away so we may need 
        a couple of tries and a little time to go by before the results show.
        '''
        for i in xrange(tries):
            retval = callback(*args, **kwargs)
            if retval:
                return retval
            time.sleep(0.2)
        return None


    def test_traversal(self):
        dp        = DataProcess()
        transform = Transform()
        pd        = ProcessDefinition()

        dp_id, _        = self.rr.create(dp)
        transform_id, _ = self.rr.create(transform)
        pd_id, _        = self.rr.create(pd)

        self.rr.create_association(subject=dp_id, object=transform_id, predicate=PRED.hasTransform)
        self.rr.create_association(subject=transform_id, object=pd_id, predicate=PRED.hasProcessDefinition)

        results = self.discovery.traverse(dp_id)
        results.sort()
        correct = [pd_id, transform_id]
        correct.sort()
        self.assertTrue(results == correct, '%s' % results)

    def test_iterative_traversal(self):
        dp        = DataProcess()
        transform = Transform()
        pd        = ProcessDefinition()

        dp_id, _        = self.rr.create(dp)
        transform_id, _ = self.rr.create(transform)
        pd_id, _        = self.rr.create(pd)

        self.rr.create_association(subject=dp_id, object=transform_id, predicate=PRED.hasTransform)
        self.rr.create_association(subject=transform_id, object=pd_id, predicate=PRED.hasProcessDefinition)

        results = self.discovery.iterative_traverse(dp_id)
        results.sort()
        correct = [transform_id]
        self.assertTrue(results == correct)

        results = self.discovery.iterative_traverse(dp_id, 1)
        results.sort()
        correct = [transform_id, pd_id]
        correct.sort()
        self.assertTrue(results == correct)
    
    @skipIf(not use_es, 'No ElasticSearch')
    def test_view_crud(self):
        view_id = self.discovery.create_view('big_view',fields=['name'])
        catalog_id = self.discovery.list_catalogs(view_id)[0]
        index_ids = self.catalog.list_indexes(catalog_id)
        self.assertTrue(len(index_ids))

        view = self.discovery.read_view(view_id)
        self.assertIsInstance(view,View)
        self.assertTrue(view.name == 'big_view')

        view.name = 'not_so_big_view'

        self.discovery.update_view(view)

        view = self.discovery.read_view(view_id)
        self.assertTrue(view.name == 'not_so_big_view')

        self.discovery.delete_view(view_id)
        with self.assertRaises(NotFound):
            self.discovery.read_view(view_id)

    def test_view_best_match(self):
        #---------------------------------------------------------------
        # Matches the best catalog available OR creates a new one
        #---------------------------------------------------------------
        catalog_id = self.catalog.create_catalog('dev', keywords=['name','model'])
        view_id    = self.discovery.create_view('exact_view', fields=['name','model'])
        catalog_ids = self.discovery.list_catalogs(view_id)
        self.assertTrue(catalog_ids == [catalog_id])

        view_id = self.discovery.create_view('another_view', fields=['name','model'])
        catalog_ids = self.discovery.list_catalogs(view_id)
        self.assertTrue(catalog_ids == [catalog_id])

        view_id = self.discovery.create_view('big_view', fields=['name'])
        catalog_ids = self.discovery.list_catalogs(view_id)
        self.assertTrue(catalog_ids != [catalog_id])

    @skipIf(not use_es, 'No ElasticSearch')
    def test_basic_searching(self):

        #- - - - - - - - - - - - - - - - - 
        # set up the fake resources
        #- - - - - - - - - - - - - - - - - 

        instrument_pool = [
            InstrumentDevice(name='sonobuoy1', hardware_version='1'),
            InstrumentDevice(name='sonobuoy2', hardware_version='2'),
            InstrumentDevice(name='sonobuoy3', hardware_version='3')
        ]
        for instrument in instrument_pool:
            self.rr.create(instrument)

        view_id = self.discovery.create_view('devices', fields=['hardware_version'])

        search_string = "search 'hardware_version' is '2' from '%s'"%view_id
        results = self.poll(5, self.discovery.parse,search_string)
        result  = results[0]['_source']
        self.assertIsInstance(result, InstrumentDevice)
        self.assertTrue(result.name == 'sonobuoy2')
        self.assertTrue(result.hardware_version == '2')


    @skipIf(not use_es, 'No ElasticSearch')
    def test_associative_searching(self):

        view_id = self.discovery.create_view('devices', fields=['model'])
        site_id,_ = self.rr.create(Site('my_site'))
        pd_id, _  = self.rr.create(PlatformDevice('my_device', model='abc123'))
        self.rr.create_association(subject=site_id, object=pd_id, predicate=PRED.hasDevice)

        search_string = "search 'model' is 'abc*' from '%s' and belongs to '%s'"%(view_id, site_id)

        results = self.poll(5, self.discovery.parse,search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(pd_id in results)

    def test_iterative_associative_searching(self):
        #--------------------------------------------------------------------------------
        # Tests the ability to limit the iterations
        #--------------------------------------------------------------------------------
        dp        = DataProcess()
        transform = Transform()
        pd        = ProcessDefinition()

        dp_id, _        = self.rr.create(dp)
        transform_id, _ = self.rr.create(transform)
        pd_id, _        = self.rr.create(pd)

        self.rr.create_association(subject=dp_id, object=transform_id, predicate=PRED.hasTransform)
        self.rr.create_association(subject=transform_id, object=pd_id, predicate=PRED.hasProcessDefinition)

        search_string = "belongs to '%s' depth 1" % dp_id
        results = self.poll(5, self.discovery.parse,search_string)
        results = list([i._id for i in results])
        correct = [transform_id]
        self.assertTrue(results == correct, '%s' % results)

        search_string = "belongs to '%s' depth 2" % dp_id
        results = self.poll(5, self.discovery.parse,search_string)
        results = list([i._id for i in results])
        results.sort()
        correct = [transform_id, pd_id]
        correct.sort()
        self.assertTrue(results == correct)


    @skipIf(not use_es, 'No ElasticSearch')
    def test_ranged_value_searching(self):
        discovery = self.discovery
        rr        = self.rr
        
        view_id = discovery.create_view('bank_view', fields=['cash_balance'])
        bank_id, _ = rr.create(BankAccount(name='broke', cash_balance=10))

        search_string = "search 'cash_balance' values from 0 to 100 from '%s'" % view_id

        results = self.poll(5, discovery.parse, search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == bank_id)

    @skipIf(not use_es, 'No ElasticSearch')
    def test_collections_searching(self):

        site_id, _ = self.rr.create(Site(name='black_mesa'))
        view_id    = self.discovery.create_view('big', fields=['name'])

        # Add the site to a new collection
        collection_id = self.ims.create_collection('resource_collection', [site_id])

        search_string = "search 'name' is '*' from '%s' and in '%s'" %(view_id, collection_id)

        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0] == site_id, '%s' % results)

    @skipIf(not use_es, 'No ElasticSearch')
    def test_search_by_name(self):
        inst_dev = InstrumentDevice(name='test_dev',serial_number='ABC123')

        dev_id, _ = self.rr.create(inst_dev)
        self.discovery.create_view('devs',fields=['name','serial_number'])

        search_string = "search 'serial_number' is 'abc*' from 'devs'"
        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dev_id)

    @skipIf(not use_es, 'No ElasticSearch')
    def test_search_by_name_index(self):
        inst_dev = InstrumentDevice(name='test_dev',serial_number='ABC123')

        dev_id, _ = self.rr.create(inst_dev)
        search_string = "search 'serial_number' is 'abc*' from 'resources_index'"
        
        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dev_id)

        bank_acc = BankAccount(name='blah', cash_balance=10)
        res_id , _ = self.rr.create(bank_acc)

        search_string = "search 'cash_balance' values from 0 to 100 from 'resources_index'"

        results = self.poll(9, self.discovery.parse,search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == res_id)

    @skipIf(not use_es, 'No ElasticSearch')
    def test_data_product_search(self):

        # Create the dataproduct
        dp = DataProduct(name='test_product')
        dp.data_format.name = 'test_signal'
        dp.data_format.description = 'test signal'
        dp.data_format.character_set = 'utf8'
        dp.data_format.nominal_sampling_rate_maximum = '44000'
        dp.data_format.nominal_sampling_rate_minimum = '44000'
        dp.data_product_level = 'basic'
        dp_id, _ = self.rr.create(dp)

        search_string = "search 'data_format.name' is 'test_signal' from 'data_products_index'"
        results = self.poll(9, self.discovery.parse, search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)

        search_string = "search 'data_product_level' is 'basic' from 'data_products_index'"
        results = self.poll(9, self.discovery.parse, search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)
        
        search_string = "search 'data_format.character_set' is 'utf8' from 'data_products_index'"
        results = self.poll(9, self.discovery.parse, search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)

    @skipIf(not use_es, 'No ElasticSearch')
    def test_events_search(self):
        # Create a resource to force a new event

        dp = DataProcess()
        dp_id, rev = self.rr.create(dp)

        search_string = "SEARCH 'origin' IS '%s' FROM 'events_index'" % dp_id

        results = self.poll(9, self.discovery.parse,search_string)
        origin_type = results[0]['_source'].origin_type
        origin_id = results[0]['_source'].origin

        self.assertTrue(origin_type == RT.DataProcess)
        self.assertTrue(origin_id == dp_id)

    @skipIf(not use_es, 'No ElasticSearch')
    def test_geo_distance_search(self):

        pd = PlatformDevice(name='test_dev')

        pd_id, _ = self.rr.create(pd)

        search_string = "search 'nominal_location' geo distance 20 km from lat 0 lon 0 from 'devices_index'"

        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')

        self.assertTrue(results[0]['_id'] == pd_id)
        self.assertTrue(results[0]['_source'].name == 'test_dev')
   
    @skipIf(not use_es, 'No ElasticSearch')
    def test_geo_bbox_search(self):

        pd = PlatformDevice(name='test_dev')
        pd.nominal_location.lat = 5
        pd.nominal_location.lon = 5

        pd_id, _ = self.rr.create(pd)

        search_string = "search 'nominal_location' geo box top-left lat 10 lon 0 bottom-right lat 0 lon 10 from 'devices_index'"

        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')

        self.assertTrue(results[0]['_id'] == pd_id)
        self.assertTrue(results[0]['_source'].name == 'test_dev')
        
    @skipIf(not use_es, 'No ElasticSearch')
    def test_user_search(self):
        user = UserInfo()
        user.name = 'test'
        user.contact.phone = '5551212'

        user_id, _ = self.rr.create(user)

        search_string = 'search "name" is "test" from "users_index"'

        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')

        self.assertTrue(results[0]['_id'] == user_id)
        self.assertTrue(results[0]['_source'].name == 'test')

        search_string = 'search "contact.phone" is "5551212" from "users_index"'
        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')

        self.assertTrue(results[0]['_id'] == user_id)
        self.assertTrue(results[0]['_source'].name == 'test')
示例#11
0
    def index_bootstrap(self):
        '''
        Creates the initial set of desired indexes based on a standard definition
        '''

        #=======================================================================================
        # Create the _river index based on the cluster configurations
        #=======================================================================================
        IndexManagementService._es_call(
            self.es.index_create,
            '_river',
            number_of_shards = self.river_shards, 
            number_of_replicas = self.river_replicas
        )

        filters = {
            '_id' : '_design/filters',
            'filters' : {
            }
        }
        #=======================================================================================
        # For each of the resource types in the list of values for each standard index,
        # create a mapping and a context type in ElasticSearch based on the searchable fields.
        #=======================================================================================

        for k,v in STD_INDEXES.iteritems():
            response = IndexManagementService._es_call(
                self.es.index_create,
                k,
                number_of_shards=self.index_shards,
                number_of_replicas=self.index_replicas
            )
            IndexManagementService._check_response(response)
            
            body = 'function(doc, req) { switch(doc.type_) { default: return false; }}'
            for res in v:
                body = re.sub(r'default:', 'case "%s": return true; default:' % res, body)
                mappings = self.es_mapping(res)
                response = IndexManagementService._es_call(self.es.raw,'%s/%s/_mapping' %(k,res), 'POST', mappings)
                IndexManagementService._check_response(response)

            filters['filters'][k] = body
        
        #=======================================================================================
        # Get an instance of the datastore instance used to create the CouchDB filters
        # in support of the ElasticSearch river's filter
        #  - Allows us to filter based on resource type
        #=======================================================================================
       
        cc = self.container
        db = cc.datastore_manager.get_datastore('resources')
        datastore_name = db.datastore_name
        db = db.server[datastore_name]

        db.create(filters)

        #--------------------------------------------------------------------------------
        # Create the river connection between CouchDB and ElasticSearch
        #--------------------------------------------------------------------------------

        for k,v in STD_INDEXES.iteritems():
            response = IndexManagementService._es_call(self.es.river_couchdb_create,
                index_name = k,
                couchdb_db = datastore_name,
                couchdb_host = CFG.server.couchdb.host,
                couchdb_port = CFG.server.couchdb.port, 
                couchdb_user = CFG.server.couchdb.username,
                couchdb_password = CFG.server.couchdb.password,
                couchdb_filter = 'filters/%s' % k,
                script= ELASTICSEARCH_CONTEXT_SCRIPT
            )
            IndexManagementService._check_response(response)

        #=======================================================================================
        # Create and map the edge indexes
        #=======================================================================================

        #--------------------------------------------------------------------------------
        # Resources Index
        #--------------------------------------------------------------------------------

        response = IndexManagementService._es_call(self.es.index_create,'%s_resources_index' % self.sysname,
            number_of_shards=self.index_shards,
            number_of_replicas=self.index_replicas
        )
        IndexManagementService._check_response(response)
        for t in RT.values():
            mappings = self.es_mapping(t)
            response = IndexManagementService._es_call(self.es.raw,'%s_resources_index/%s/_mapping' % (self.sysname,t), 'POST', mappings)
            IndexManagementService._check_response(response)

        response = IndexManagementService._es_call(self.es.river_couchdb_create,
            index_name = '%s_resources_index' % self.sysname,
            couchdb_db = datastore_name,
            couchdb_host = CFG.server.couchdb.host,
            couchdb_port = CFG.server.couchdb.port,
            couchdb_user = CFG.server.couchdb.username,
            couchdb_password = CFG.server.couchdb.password,
            script= ELASTICSEARCH_CONTEXT_SCRIPT
        )
        IndexManagementService._check_response(response)

        #--------------------------------------------------------------------------------
        # Events Index
        #--------------------------------------------------------------------------------

        response = IndexManagementService._es_call(self.es.index_create,'%s_events_index' % self.sysname,
            number_of_shards=self.index_shards,
            number_of_replicas=self.index_replicas
        )
        IndexManagementService._check_response(response)
        for event in get_events():
            mappings = self.es_mapping(event)
            response = IndexManagementService._es_call(self.es.raw, '%s_events_index/%s/_mapping' % (self.sysname, event), 'POST', mappings)
            IndexManagementService._check_response(response)

        response = IndexManagementService._es_call(self.es.river_couchdb_create,
            index_name = '%s_events_index' % self.sysname,
            couchdb_db = '%s_events' % self.sysname,
            couchdb_host = CFG.server.couchdb.host,
            couchdb_port = CFG.server.couchdb.port,
            couchdb_user = CFG.server.couchdb.username,
            couchdb_password = CFG.server.couchdb.password,
            script= ELASTICSEARCH_CONTEXT_SCRIPT
        )
        IndexManagementService._check_response(response)




        #=======================================================================================
        # Construct the resources
        #=======================================================================================

        ims_cli = IndexManagementServiceClient()

        #--------------------------------------------------------------------------------
        # Standard Indexes
        #--------------------------------------------------------------------------------

        for index,resources in STD_INDEXES.iteritems():
            ims_cli.create_index(
                name=index,
                description='%s ElasticSearch Index Resource' % index,
                content_type=IndexManagementService.ELASTICSEARCH_INDEX,
                options=self.attr_mapping(resources)
            )

        #--------------------------------------------------------------------------------
        # CouchDB Indexes
        #--------------------------------------------------------------------------------
        
        for index,datastore in COUCHDB_INDEXES.iteritems():
            ims_cli.create_index(
                name=index,
                description='%s CouchDB Index Resource' % index,
                content_type=IndexManagementService.COUCHDB_INDEX,
                datastore_name=datastore
            )

        #--------------------------------------------------------------------------------
        # Edge Indexes
        #--------------------------------------------------------------------------------

        ims_cli.create_index(
            name='%s_resources_index' % self.sysname,
            description='Resources Index',
            content_type=IndexManagementService.ELASTICSEARCH_INDEX,
            options=self.attr_mapping(RT.keys())
        )

        ims_cli.create_index(
            name='%s_events_index' % self.sysname,
            description='Events Index',
            content_type=IndexManagementService.ELASTICSEARCH_INDEX,
            options=self.attr_mapping(get_events())
        )
class IndexManagementIntTest(IonIntegrationTestCase):
    def setUp(self):
        self._start_container()
        self.container.start_rel_from_url('res/deploy/r2dm.yml')

        self.ims_cli = IndexManagementServiceClient()
        self.rr_cli = ResourceRegistryServiceClient()
        self.index_name = 'test_index'

    def test_create_datastore_index(self):
        index_name = self.index_name
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        options = SearchOptions()
        options.attribute_match = ['test_field']
        index_id = ims_cli.create_index(
            name=index_name,
            content_type=IndexManagementService.DATASTORE_INDEX,
            options=options)

        index_result = self.rr_cli.read(index_id)
        self.assertIsInstance(index_result, ElasticSearchIndex)
        self.assertTrue(index_result.name == index_name)

        #======================================
        # Clean up
        #======================================
        rr_cli.delete(index_id)

    def test_read_index(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        index_name = self.index_name
        index_res = Index(name=index_name)
        index_id, _ = rr_cli.create(index_res)

        index = ims_cli.read_index(index_id)
        self.assertIsInstance(index, Index)
        self.assertTrue(index.name == index_name)

        rr_cli.delete(index_id)

    def test_delete_index(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        index_name = self.index_name
        index_res = Index(name=index_name)
        index_id, _ = rr_cli.create(index_res)

        ims_cli.delete_index(index_id)

        with self.assertRaises(NotFound):
            rr_cli.delete(index_id)

    def test_update_index(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        index_name = self.index_name
        index_res = Index(name=index_name)
        index_id, _ = rr_cli.create(index_res)

        index = ims_cli.read_index(index_id)
        index.name = 'another'
        ims_cli.update_index(index)

        index = rr_cli.read(index_id)
        self.assertTrue(index.name == 'another')

    def test_find_indexes(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        index_name = self.index_name

        #======================================
        # Index Pool
        #======================================

        indexes = [
            Index(name='first'),
            Index(name='second'),
            Index(name='third')
        ]
        id_pool = list()
        for index in indexes:
            id_pool.append(rr_cli.create(index)[0])

        index_id = ims_cli.find_indexes(index_name='second')
        index = ims_cli.read_index(index_id)
        self.assertTrue(index.name == 'second')

        #======================================
        # Clean up
        #======================================

        for index_id in id_pool:
            rr_cli.delete(index_id)

    def test_create_collection(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        with self.assertRaises(BadRequest):
            ims_cli.create_collection('failing_collection')

        resources = [Resource(), Resource(), Resource()]
        resources = [rr_cli.create(i)[0] for i in resources]

        collection_id = ims_cli.create_collection('working_collection',
                                                  resources)

        collection = rr_cli.read(collection_id)
        collection_resources = ims_cli.list_collection_resources(collection_id,
                                                                 id_only=True)
        self.assertTrue(
            set(collection_resources) == set(resources),
            '%s != %s' % (set(collection_resources), set(resources)))

    def test_read_collection(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        collection = Collection(name='working_collection')
        collection_id, _ = rr_cli.create(collection)
        collection = ims_cli.read_collection(collection_id)
        self.assertTrue(collection.name == 'working_collection')

    def test_update_collection(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli

        collection = Collection(name='useful_collection')
        collection_id, _ = rr_cli.create(collection)
        collection = rr_cli.read(collection_id)
        collection.name = 'nub'
        ims_cli.update_collection(collection)
        collection = rr_cli.read(collection_id)
        self.assertTrue(collection.name == 'nub')

    def test_delete_collection(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        res = Resource()
        res_id, rev = rr_cli.create(res)

        collection_id = ims_cli.create_collection(name='test_collection',
                                                  resources=[res_id])

        ims_cli.delete_collection(collection_id)

        with self.assertRaises(NotFound):
            rr_cli.read(collection_id)

    def test_list_collection_resources(self):
        ims_cli = self.ims_cli
        rr_cli = self.rr_cli
        #========================================
        # Resource Pool
        #========================================
        resources = [
            InformationResource(name='bean_counter'),
            InformationResource(name='lunar_rock'),
            InformationResource('aperature'),
            InformationResource('lemons')
        ]

        resources = [rr_cli.create(i)[0] for i in resources]

        collection = Collection(name='park_bench')

        collection_id = ims_cli.create_collection(name='park_bench',
                                                  resources=resources)
        retval = ims_cli.list_collection_resources(collection_id, id_only=True)

        retval.sort()
        resources.sort()

        self.assertTrue(retval == resources, '%s != %s' % (retval, resources))

    def test_find_collection(self):
        res_id, _ = self.rr_cli.create(Resource(name='test_res'))
        collection_id = self.ims_cli.create_collection('test', [res_id])

        retval = self.ims_cli.find_collection(collection_name='test')
        self.assertTrue(retval[0] == collection_id)

        retval = self.ims_cli.find_collection(resource_ids=[res_id])
        self.assertTrue(retval[0] == collection_id)
示例#13
0
    def index_bootstrap(self):
        '''
        Creates the initial set of desired indexes based on a standard definition
        '''

        #=======================================================================================
        # Create the _river index based on the cluster configurations
        #=======================================================================================
        IndexManagementService._es_call(self.es.index_create,
                                        '_river',
                                        number_of_shards=self.river_shards,
                                        number_of_replicas=self.river_replicas)

        filters = {'_id': '_design/filters', 'filters': {}}
        #=======================================================================================
        # For each of the resource types in the list of values for each standard index,
        # create a mapping and a context type in ElasticSearch based on the searchable fields.
        #=======================================================================================

        for k, v in STD_INDEXES.iteritems():
            response = IndexManagementService._es_call(
                self.es.index_create,
                k,
                number_of_shards=self.index_shards,
                number_of_replicas=self.index_replicas)
            IndexManagementService._check_response(response)

            body = 'function(doc, req) { switch(doc.type_) { default: return false; }}'
            for res in v:
                body = re.sub(r'default:',
                              'case "%s": return true; default:' % res, body)
                mappings = self.es_mapping(res)
                response = IndexManagementService._es_call(
                    self.es.raw, '%s/%s/_mapping' % (k, res), 'POST', mappings)
                IndexManagementService._check_response(response)

            filters['filters'][k] = body

        #=======================================================================================
        # Get an instance of the datastore instance used to create the CouchDB filters
        # in support of the ElasticSearch river's filter
        #  - Allows us to filter based on resource type
        #=======================================================================================

        cc = self.container
        db = cc.datastore_manager.get_datastore('resources')
        datastore_name = db.datastore_name
        db = db.server[datastore_name]

        db.create(filters)

        #--------------------------------------------------------------------------------
        # Create the river connection between CouchDB and ElasticSearch
        #--------------------------------------------------------------------------------

        for k, v in STD_INDEXES.iteritems():
            response = IndexManagementService._es_call(
                self.es.river_couchdb_create,
                index_name=k,
                couchdb_db=datastore_name,
                couchdb_host=CFG.server.couchdb.host,
                couchdb_port=CFG.server.couchdb.port,
                couchdb_user=CFG.server.couchdb.username,
                couchdb_password=CFG.server.couchdb.password,
                couchdb_filter='filters/%s' % k,
                script=ELASTICSEARCH_CONTEXT_SCRIPT)
            IndexManagementService._check_response(response)

        #=======================================================================================
        # Create and map the edge indexes
        #=======================================================================================

        #--------------------------------------------------------------------------------
        # Resources Index
        #--------------------------------------------------------------------------------

        response = IndexManagementService._es_call(
            self.es.index_create,
            '%s_resources_index' % self.sysname,
            number_of_shards=self.index_shards,
            number_of_replicas=self.index_replicas)
        IndexManagementService._check_response(response)
        for t in RT.values():
            mappings = self.es_mapping(t)
            response = IndexManagementService._es_call(
                self.es.raw,
                '%s_resources_index/%s/_mapping' % (self.sysname, t), 'POST',
                mappings)
            IndexManagementService._check_response(response)

        response = IndexManagementService._es_call(
            self.es.river_couchdb_create,
            index_name='%s_resources_index' % self.sysname,
            couchdb_db=datastore_name,
            couchdb_host=CFG.server.couchdb.host,
            couchdb_port=CFG.server.couchdb.port,
            couchdb_user=CFG.server.couchdb.username,
            couchdb_password=CFG.server.couchdb.password,
            script=ELASTICSEARCH_CONTEXT_SCRIPT)
        IndexManagementService._check_response(response)

        #--------------------------------------------------------------------------------
        # Events Index
        #--------------------------------------------------------------------------------

        response = IndexManagementService._es_call(
            self.es.index_create,
            '%s_events_index' % self.sysname,
            number_of_shards=self.index_shards,
            number_of_replicas=self.index_replicas)
        IndexManagementService._check_response(response)
        for event in get_events():
            mappings = self.es_mapping(event)
            response = IndexManagementService._es_call(
                self.es.raw,
                '%s_events_index/%s/_mapping' % (self.sysname, event), 'POST',
                mappings)
            IndexManagementService._check_response(response)

        response = IndexManagementService._es_call(
            self.es.river_couchdb_create,
            index_name='%s_events_index' % self.sysname,
            couchdb_db='%s_events' % self.sysname,
            couchdb_host=CFG.server.couchdb.host,
            couchdb_port=CFG.server.couchdb.port,
            couchdb_user=CFG.server.couchdb.username,
            couchdb_password=CFG.server.couchdb.password,
            script=ELASTICSEARCH_CONTEXT_SCRIPT)
        IndexManagementService._check_response(response)

        #=======================================================================================
        # Construct the resources
        #=======================================================================================

        ims_cli = IndexManagementServiceClient()

        #--------------------------------------------------------------------------------
        # Standard Indexes
        #--------------------------------------------------------------------------------

        for index, resources in STD_INDEXES.iteritems():
            ims_cli.create_index(
                name=index,
                description='%s ElasticSearch Index Resource' % index,
                content_type=IndexManagementService.ELASTICSEARCH_INDEX,
                options=self.attr_mapping(resources))

        #--------------------------------------------------------------------------------
        # CouchDB Indexes
        #--------------------------------------------------------------------------------

        for index, datastore in COUCHDB_INDEXES.iteritems():
            ims_cli.create_index(
                name=index,
                description='%s CouchDB Index Resource' % index,
                content_type=IndexManagementService.COUCHDB_INDEX,
                datastore_name=datastore)

        #--------------------------------------------------------------------------------
        # Edge Indexes
        #--------------------------------------------------------------------------------

        ims_cli.create_index(
            name='%s_resources_index' % self.sysname,
            description='Resources Index',
            content_type=IndexManagementService.ELASTICSEARCH_INDEX,
            options=self.attr_mapping(RT.keys()))

        ims_cli.create_index(
            name='%s_events_index' % self.sysname,
            description='Events Index',
            content_type=IndexManagementService.ELASTICSEARCH_INDEX,
            options=self.attr_mapping(get_events()))
示例#14
0
class DiscoveryIntTest(IonIntegrationTestCase):
    def setUp(self):
        super(DiscoveryIntTest, self).setUp()

        self._start_container()
        self.addCleanup(DiscoveryIntTest.es_cleanup)
        self.container.start_rel_from_url('res/deploy/r2dm.yml')

        self.discovery = DiscoveryServiceClient()
        self.catalog   = CatalogManagementServiceClient()
        self.ims       = IndexManagementServiceClient()
        self.rr        = ResourceRegistryServiceClient()

        if use_es:
            self.es_host   = CFG.get_safe('server.elasticsearch.host', 'localhost')
            self.es_port   = CFG.get_safe('server.elasticsearch.port', '9200')
            CFG.server.elasticsearch.shards         = 1
            CFG.server.elasticsearch.replicas       = 0
            CFG.server.elasticsearch.river_shards   = 1
            CFG.server.elasticsearch.river_replicas = 0
            self.es = ep.ElasticSearch(
                host=self.es_host,
                port=self.es_port,
                timeout=10,
                verbose=True
            )
            op = DotDict(CFG)
            op.op = 'clean_bootstrap'
            self.container.spawn_process('index_bootstrap','ion.processes.bootstrap.index_bootstrap','IndexBootStrap', op)

    @staticmethod
    def es_cleanup():
        es_host = CFG.get_safe('server.elasticsearch.host', 'localhost')
        es_port = CFG.get_safe('server.elasticsearch.port', '9200')
        es = ep.ElasticSearch(
            host=es_host,
            port=es_port,
            timeout=10
        )
        indexes = STD_INDEXES.keys()
        indexes.append('%s_resources_index' % get_sys_name().lower())
        indexes.append('%s_events_index' % get_sys_name().lower())

        for index in indexes:
            IndexManagementService._es_call(es.river_couchdb_delete,index)
            IndexManagementService._es_call(es.index_delete,index)


    def poll(self, tries, callback, *args, **kwargs):
        '''
        Polling wrapper for queries
        Elasticsearch may not index and cache the changes right away so we may need 
        a couple of tries and a little time to go by before the results show.
        '''
        for i in xrange(tries):
            retval = callback(*args, **kwargs)
            if retval:
                return retval
            time.sleep(0.2)
        return None


    def test_traversal(self):
        dp        = DataProcess()
        transform = Transform()
        pd        = ProcessDefinition()

        dp_id, _        = self.rr.create(dp)
        transform_id, _ = self.rr.create(transform)
        pd_id, _        = self.rr.create(pd)

        self.rr.create_association(subject=dp_id, object=transform_id, predicate=PRED.hasTransform)
        self.rr.create_association(subject=transform_id, object=pd_id, predicate=PRED.hasProcessDefinition)

        results = self.discovery.traverse(dp_id)
        results.sort()
        correct = [pd_id, transform_id]
        correct.sort()
        self.assertTrue(results == correct, '%s' % results)

    def test_iterative_traversal(self):
        dp        = DataProcess()
        transform = Transform()
        pd        = ProcessDefinition()

        dp_id, _        = self.rr.create(dp)
        transform_id, _ = self.rr.create(transform)
        pd_id, _        = self.rr.create(pd)

        self.rr.create_association(subject=dp_id, object=transform_id, predicate=PRED.hasTransform)
        self.rr.create_association(subject=transform_id, object=pd_id, predicate=PRED.hasProcessDefinition)

        results = self.discovery.iterative_traverse(dp_id)
        results.sort()
        correct = [transform_id]
        self.assertTrue(results == correct)

        results = self.discovery.iterative_traverse(dp_id, 1)
        results.sort()
        correct = [transform_id, pd_id]
        correct.sort()
        self.assertTrue(results == correct)
    
    @skipIf(not use_es, 'No ElasticSearch')
    def test_view_crud(self):
        view_id = self.discovery.create_view('big_view',fields=['name'])
        catalog_id = self.discovery.list_catalogs(view_id)[0]
        index_ids = self.catalog.list_indexes(catalog_id)
        self.assertTrue(len(index_ids))

        view = self.discovery.read_view(view_id)
        self.assertIsInstance(view,View)
        self.assertTrue(view.name == 'big_view')

        view.name = 'not_so_big_view'

        self.discovery.update_view(view)

        view = self.discovery.read_view(view_id)
        self.assertTrue(view.name == 'not_so_big_view')

        self.discovery.delete_view(view_id)
        with self.assertRaises(NotFound):
            self.discovery.read_view(view_id)

    def test_view_best_match(self):
        #---------------------------------------------------------------
        # Matches the best catalog available OR creates a new one
        #---------------------------------------------------------------
        catalog_id = self.catalog.create_catalog('dev', keywords=['name','model'])
        view_id    = self.discovery.create_view('exact_view', fields=['name','model'])
        catalog_ids = self.discovery.list_catalogs(view_id)
        self.assertTrue(catalog_ids == [catalog_id])

        view_id = self.discovery.create_view('another_view', fields=['name','model'])
        catalog_ids = self.discovery.list_catalogs(view_id)
        self.assertTrue(catalog_ids == [catalog_id])

        view_id = self.discovery.create_view('big_view', fields=['name'])
        catalog_ids = self.discovery.list_catalogs(view_id)
        self.assertTrue(catalog_ids != [catalog_id])

    @skipIf(not use_es, 'No ElasticSearch')
    def test_basic_searching(self):

        #- - - - - - - - - - - - - - - - - 
        # set up the fake resources
        #- - - - - - - - - - - - - - - - - 

        instrument_pool = [
            InstrumentDevice(name='sonobuoy1', hardware_version='1'),
            InstrumentDevice(name='sonobuoy2', hardware_version='2'),
            InstrumentDevice(name='sonobuoy3', hardware_version='3')
        ]
        for instrument in instrument_pool:
            self.rr.create(instrument)

        view_id = self.discovery.create_view('devices', fields=['hardware_version'])

        search_string = "search 'hardware_version' is '2' from '%s'"%view_id
        results = self.poll(5, self.discovery.parse,search_string)
        result  = results[0]['_source']
        self.assertIsInstance(result, InstrumentDevice)
        self.assertTrue(result.name == 'sonobuoy2')
        self.assertTrue(result.hardware_version == '2')


    @skipIf(not use_es, 'No ElasticSearch')
    def test_associative_searching(self):

        view_id = self.discovery.create_view('devices', fields=['model'])
        site_id,_ = self.rr.create(Site('my_site'))
        pd_id, _  = self.rr.create(PlatformDevice('my_device', model='abc123'))
        self.rr.create_association(subject=site_id, object=pd_id, predicate=PRED.hasDevice)

        search_string = "search 'model' is 'abc*' from '%s' and belongs to '%s'"%(view_id, site_id)

        results = self.poll(5, self.discovery.parse,search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(pd_id in results)

    def test_iterative_associative_searching(self):
        #--------------------------------------------------------------------------------
        # Tests the ability to limit the iterations
        #--------------------------------------------------------------------------------
        dp        = DataProcess()
        transform = Transform()
        pd        = ProcessDefinition()

        dp_id, _        = self.rr.create(dp)
        transform_id, _ = self.rr.create(transform)
        pd_id, _        = self.rr.create(pd)

        self.rr.create_association(subject=dp_id, object=transform_id, predicate=PRED.hasTransform)
        self.rr.create_association(subject=transform_id, object=pd_id, predicate=PRED.hasProcessDefinition)

        search_string = "belongs to '%s' depth 1" % dp_id
        results = self.poll(5, self.discovery.parse,search_string)
        results = list([i._id for i in results])
        correct = [transform_id]
        self.assertTrue(results == correct, '%s' % results)

        search_string = "belongs to '%s' depth 2" % dp_id
        results = self.poll(5, self.discovery.parse,search_string)
        results = list([i._id for i in results])
        results.sort()
        correct = [transform_id, pd_id]
        correct.sort()
        self.assertTrue(results == correct)


    @skipIf(not use_es, 'No ElasticSearch')
    def test_ranged_value_searching(self):
        discovery = self.discovery
        rr        = self.rr
        
        view_id = discovery.create_view('bank_view', fields=['cash_balance'])
        bank_id, _ = rr.create(BankAccount(name='broke', cash_balance=10))

        search_string = "search 'cash_balance' values from 0 to 100 from '%s'" % view_id

        results = self.poll(5, discovery.parse, search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == bank_id)

    @skipIf(not use_es, 'No ElasticSearch')
    def test_collections_searching(self):

        site_id, _ = self.rr.create(Site(name='black_mesa'))
        view_id    = self.discovery.create_view('big', fields=['name'])

        # Add the site to a new collection
        collection_id = self.ims.create_collection('resource_collection', [site_id])

        search_string = "search 'name' is '*' from '%s' and in '%s'" %(view_id, collection_id)

        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0] == site_id, '%s' % results)

    @skipIf(not use_es, 'No ElasticSearch')
    def test_search_by_name(self):
        inst_dev = InstrumentDevice(name='test_dev',serial_number='ABC123')

        dev_id, _ = self.rr.create(inst_dev)
        self.discovery.create_view('devs',fields=['name','serial_number'])

        search_string = "search 'serial_number' is 'abc*' from 'devs'"
        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dev_id)

    @skipIf(not use_es, 'No ElasticSearch')
    def test_search_by_name_index(self):
        inst_dev = InstrumentDevice(name='test_dev',serial_number='ABC123')

        dev_id, _ = self.rr.create(inst_dev)
        search_string = "search 'serial_number' is 'abc*' from 'resources_index'"
        
        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dev_id)

        bank_acc = BankAccount(name='blah', cash_balance=10)
        res_id , _ = self.rr.create(bank_acc)

        search_string = "search 'cash_balance' values from 0 to 100 from 'resources_index'"

        results = self.poll(9, self.discovery.parse,search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == res_id)

    @skipIf(not use_es, 'No ElasticSearch')
    def test_data_product_search(self):

        # Create the dataproduct
        dp = DataProduct(name='test_product')
        dp.data_format.name = 'test_signal'
        dp.data_format.description = 'test signal'
        dp.data_format.character_set = 'utf8'
        dp.data_format.nominal_sampling_rate_maximum = '44000'
        dp.data_format.nominal_sampling_rate_minimum = '44000'
        dp.data_product_level = 'basic'
        dp_id, _ = self.rr.create(dp)

        search_string = "search 'data_format.name' is 'test_signal' from 'data_products_index'"
        results = self.poll(9, self.discovery.parse, search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)

        search_string = "search 'data_product_level' is 'basic' from 'data_products_index'"
        results = self.poll(9, self.discovery.parse, search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)
        
        search_string = "search 'data_format.character_set' is 'utf8' from 'data_products_index'"
        results = self.poll(9, self.discovery.parse, search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)

    @skipIf(not use_es, 'No ElasticSearch')
    def test_events_search(self):
        # Create a resource to force a new event

        dp = DataProcess()
        dp_id, rev = self.rr.create(dp)

        search_string = "SEARCH 'origin' IS '%s' FROM 'events_index'" % dp_id

        results = self.poll(9, self.discovery.parse,search_string)
        origin_type = results[0]['_source'].origin_type
        origin_id = results[0]['_source'].origin

        self.assertTrue(origin_type == RT.DataProcess)
        self.assertTrue(origin_id == dp_id)

    @skipIf(not use_es, 'No ElasticSearch')
    def test_geo_distance_search(self):

        pd = PlatformDevice(name='test_dev')

        pd_id, _ = self.rr.create(pd)

        search_string = "search 'nominal_location' geo distance 20 km from lat 0 lon 0 from 'devices_index'"

        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')

        self.assertTrue(results[0]['_id'] == pd_id)
        self.assertTrue(results[0]['_source'].name == 'test_dev')
   
    @skipIf(not use_es, 'No ElasticSearch')
    def test_geo_bbox_search(self):

        pd = PlatformDevice(name='test_dev')
        pd.nominal_location.lat = 5
        pd.nominal_location.lon = 5

        pd_id, _ = self.rr.create(pd)

        search_string = "search 'nominal_location' geo box top-left lat 10 lon 0 bottom-right lat 0 lon 10 from 'devices_index'"

        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')

        self.assertTrue(results[0]['_id'] == pd_id)
        self.assertTrue(results[0]['_source'].name == 'test_dev')
class DiscoveryIntTest(IonIntegrationTestCase):
    def setUp(self):
        raise SkipTest("Not yet ported to Postgres")

        super(DiscoveryIntTest, self).setUp()
        config = DotDict()

        self._start_container()
        self.container.start_rel_from_url('res/deploy/r2deploy.yml', config)

        self.discovery               = DiscoveryServiceClient()
        self.catalog                 = CatalogManagementServiceClient()
        self.ims                     = IndexManagementServiceClient()
        self.rr                      = ResourceRegistryServiceClient()
        self.dataset_management      = DatasetManagementServiceClient()
        self.pubsub_management       = PubsubManagementServiceClient()
        self.data_product_management = DataProductManagementServiceClient()


    def test_geo_distance_search(self):

        pd = PlatformDevice(name='test_dev')

        pd_id, _ = self.rr.create(pd)

        search_string = "search 'index_location' geo distance 20 km from lat 0 lon 0 from 'devices_index'"

        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')

        self.assertTrue(results[0]['_id'] == pd_id)
        self.assertTrue(results[0]['_source'].name == 'test_dev')


    def test_ranged_value_searching(self):
        discovery = self.discovery
        rr        = self.rr
        
        view_id = discovery.create_view('bank_view', fields=['cash_balance'])
        bank_id, _ = rr.create(BankAccount(name='broke', cash_balance=10))

        search_string = "search 'cash_balance' values from 0 to 100 from '%s'" % view_id

        results = self.poll(5, discovery.parse, search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == bank_id)
        
        bank_id, _ = rr.create(BankAccount(name='broke', cash_balance=90))

        search_string = "search 'cash_balance' values from 80 from '%s'" % view_id

        results = self.poll(5, discovery.parse, search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == bank_id)

    def test_collections_searching(self):
        site_id, _ = self.rr.create(Site(name='black_mesa'))
        view_id    = self.discovery.create_view('big', fields=['name'])

        # Add the site to a new collection
        collection_id = self.ims.create_collection('resource_collection', [site_id])

        search_string = "search 'name' is '*' from '%s' and in '%s'" %(view_id, collection_id)

        results = self.poll(9, self.discovery.parse,search_string,id_only=True)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0] == site_id, '%s' % results)

    def test_search_by_name_index(self):
        inst_dev = InstrumentDevice(name='test_dev',serial_number='ABC123')

        dev_id, _ = self.rr.create(inst_dev)
        search_string = "search 'serial_number' is 'abc*' from 'resources_index'"
        
        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dev_id)

        bank_acc = BankAccount(name='blah', cash_balance=10)
        res_id , _ = self.rr.create(bank_acc)

        search_string = "search 'cash_balance' values from 0 to 100 from 'resources_index'"

        results = self.poll(9, self.discovery.parse,search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == res_id)

    def test_data_product_search(self):
        # Create the dataproduct
        dp = DataProduct(name='test_product')
        dp.data_format.name = 'test_signal'
        dp.data_format.description = 'test signal'
        dp.data_format.character_set = 'utf8'
        dp.data_format.nominal_sampling_rate_maximum = '44000'
        dp.data_format.nominal_sampling_rate_minimum = '44000'
        dp.CDM_data_type = 'basic'
        dp_id, _ = self.rr.create(dp)

        search_string = "search 'data_format.name' is 'test_signal' from 'data_products_index'"
        results = self.poll(9, self.discovery.parse, search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)

        search_string = "search 'CDM_data_type' is 'basic' from 'data_products_index'"
        results = self.poll(9, self.discovery.parse, search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)
        
        search_string = "search 'data_format.character_set' is 'utf8' from 'data_products_index'"
        results = self.poll(9, self.discovery.parse, search_string)

        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)


    def test_events_search(self):
        # Create a resource to force a new event

        dp = DataProcess()
        dp_id, rev = self.rr.create(dp)

        search_string = "SEARCH 'origin' IS '%s' FROM 'events_index'" % dp_id

        results = self.poll(9, self.discovery.parse,search_string)
        origin_type = results[0]['_source'].origin_type
        origin_id = results[0]['_source'].origin

        self.assertTrue(origin_type == RT.DataProcess)
        self.assertTrue(origin_id == dp_id)



    def test_time_search(self):
        today     = date.today()
        past = today - timedelta(days=2)
        future  = today + timedelta(days=2)

        data_product = DataProduct()
        dp_id, _ = self.rr.create(data_product)
        
        search_string = "search 'type_' is 'DataProduct' from 'data_products_index' and search 'ts_created' time from '%s' to '%s' from 'data_products_index'" % (past, future)

        results = self.poll(9, self.discovery.parse,search_string,id_only=True)

        self.assertIsNotNone(results,'Results not found')

        self.assertIn(dp_id, results)
        
        search_string = "search 'type_' is 'DataProduct' from 'data_products_index' and search 'ts_created' time from '%s' from 'data_products_index'" % past

        results = self.poll(9, self.discovery.parse,search_string,id_only=True)

        self.assertIsNotNone(results,'Results not found')

        self.assertIn(dp_id, results)

        
    def test_user_search(self):
        user = UserInfo()
        user.name = 'test'
        user.contact.phones.append('5551212')

        user_id, _ = self.rr.create(user)

        search_string = 'search "name" is "test" from "users_index"'

        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')

        self.assertTrue(results[0]['_id'] == user_id)
        self.assertTrue(results[0]['_source'].name == 'test')

        search_string = 'search "contact.phones" is "5551212" from "users_index"'
        results = self.poll(9, self.discovery.parse,search_string)

        self.assertIsNotNone(results, 'Results not found')

        self.assertTrue(results[0]['_id'] == user_id)
        self.assertTrue(results[0]['_source'].name == 'test')


    def test_subobject_search(self):
        contact = ContactInformation()
        contact.email = '*****@*****.**'
        contact.individual_name_family = 'Tester'
        contact.individual_names_given = 'Intern'

        dp = DataProduct(name='example')
        dp.contacts.append(contact)

        dp_id,_ = self.rr.create(dp)

        #--------------------------------------------------------------------------------
        # Example using the full field name
        #--------------------------------------------------------------------------------
        search_string = 'search "contacts.email" is "*****@*****.**" from "data_products"'
        results = self.poll(9, self.discovery.parse, search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)
        self.assertEquals(results[0]['_source'].name, 'example')

        #--------------------------------------------------------------------------------
        # Example using a sub-object's field name (ambiguous searching)
        #--------------------------------------------------------------------------------
        search_string = 'search "individual_names_given" is "Intern" from "data_products"'
        results = self.poll(9, self.discovery.parse, search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)
        self.assertEquals(results[0]['_source'].name, 'example')

    def test_descriptive_phrase_search(self):
        dp = DataProduct(name='example', description='This is simply a description for this data product')
        dp_id, _ = self.rr.create(dp)

        search_string = 'search "description" like "description for" from "data_products"'
        results = self.poll(9, self.discovery.parse, search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)
        self.assertEquals(results[0]['_source'].name, 'example')
    
    def test_match_search(self):
        dp = DataProduct(name='example', description='This is simply a description for this data product')
        dp_id, _ = self.rr.create(dp)

        search_string = 'search "description" match "this data product" from "data_products"'
        results = self.poll(9, self.discovery.parse, search_string)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(results[0]['_id'] == dp_id)
        self.assertEquals(results[0]['_source'].name, 'example')

    def test_expected_match_results(self):
        names = [
            'Instrument for site1',
            'Instrument for simulator',
            'CTD1',
            'SBE37',
            'SSN-719',
            'Submerssible Expendable Bathyothermograph',
            'VELPT',
            'VELO',
            'Safire2 169'
            ]
        for name in names:
            res_id, _ = self.rr.create(InstrumentDevice(name=name))
            self.addCleanup(self.rr.delete, res_id)

        search_string = 'search "name" match "expendable" from "devices"'
        results = self.poll(9, self.discovery.parse, search_string)
        self.assertIsNotNone(results, 'Results not found')

        self.assertEquals(len(results),1)
        self.assertEquals(results[0]['_source'].name, 'Submerssible Expendable Bathyothermograph')


        search_string = 'search "name" match "instrument for" from "devices"'
        results = self.poll(9, self.discovery.parse, search_string)
        self.assertIsNotNone(results, 'Results not found')

        self.assertEquals(len(results),2)
        self.assertTrue('Instrument for' in results[0]['_source'].name)
        self.assertTrue('Instrument for' in results[1]['_source'].name)


        search_string = 'search "name" match "velo for" from "devices"'
        results = self.poll(9, self.discovery.parse, search_string)
        self.assertIsNotNone(results, 'Results not found')

        self.assertEquals(len(results),1)
        self.assertEquals(results[0]['_source'].name, 'VELO')


    def test_ownership_searching(self):
        # Create two data products so that there is competition to the search, one is parsed 
        # (with conductivity as a parameter) and the other is raw
        dp = DataProduct(name='example dataproduct')
        pdict_id = self.dataset_management.read_parameter_dictionary_by_name('ctd_parsed_param_dict')
        stream_def_id = self.pubsub_management.create_stream_definition('ctd parsed', parameter_dictionary_id=pdict_id)
        dp_id = self.data_product_management.create_data_product(dp, stream_definition_id=stream_def_id, exchange_point='xp1')

        pdict_id = self.dataset_management.read_parameter_dictionary_by_name('ctd_raw_param_dict')
        stream_def_id = self.pubsub_management.create_stream_definition('ctd raw', parameter_dictionary_id=pdict_id)
        dp = DataProduct(name='WRONG')
        self.data_product_management.create_data_product(dp, stream_definition_id=stream_def_id, exchange_point='xp1')

        parameter_search = 'search "name" is "conductivity" from "resources_index"'
        results = self.poll(9, self.discovery.parse, parameter_search)
        param_id = results[0]['_id']

        data_product_search = 'search "name" is "*" from "data_products_index" and has "%s"' % param_id
        results = self.poll(9, self.discovery.parse, data_product_search,id_only=True)
        self.assertIn(dp_id, results)
        #self.assertEquals(results[0], dp_id)

    def test_associative_searching(self):
        dp_id,_ = self.rr.create(DataProduct('test_foo'))
        ds_id,_ = self.rr.create(Dataset('test_bar', registered=True))
        self.rr.create_association(subject=dp_id, object=ds_id, predicate='hasDataset')

        search_string = "search 'type_' is 'Dataset' from 'resources_index' and belongs to '%s'" % dp_id

        results = self.poll(5, self.discovery.parse, search_string, id_only=True)
        self.assertIsNotNone(results, 'Results not found')
        self.assertTrue(ds_id in results)

    def test_iterative_associative_searching(self):
        #--------------------------------------------------------------------------------
        # Tests the ability to limit the iterations
        #--------------------------------------------------------------------------------
        dp        = DataProcess()
        transform = Transform()
        pd        = ProcessDefinition()

        dp_id, _        = self.rr.create(dp)
        transform_id, _ = self.rr.create(transform)
        pd_id, _        = self.rr.create(pd)

        self.rr.create_association(subject=dp_id, object=transform_id, predicate=PRED.hasTransform)
        self.rr.create_association(subject=transform_id, object=pd_id, predicate=PRED.hasProcessDefinition)

        search_string = "belongs to '%s' depth 1" % dp_id
        results = self.poll(5, self.discovery.parse,search_string)
        results = list([i._id for i in results])
        correct = [transform_id]
        self.assertTrue(results == correct, '%s' % results)

        search_string = "belongs to '%s' depth 2" % dp_id
        results = self.poll(5, self.discovery.parse,search_string)
        results = list([i._id for i in results])
        results.sort()
        correct = [transform_id, pd_id]
        correct.sort()
        self.assertTrue(results == correct)