def setUp(self): # Start container self._start_container() self.container.start_rel_from_url('res/deploy/r2coi.yml') # Now create client to service self.service_gateway_service = ServiceGatewayServiceClient(node=self.container.node) log.debug('stopping Gateway web server') # Stop the web server as it is not needed. self.service_gateway_service.stop_service() self.test_app = TestApp(app)
def setUp(self): DMTestCase.setUp(self) # clients needed (NOTE:most inherited from DMTestCase) self.object_store = self.container.object_store self.service_gateway_service = ServiceGatewayServiceClient( node=self.container.node) self.parameter_helper = self.ph # rename so know exactly what it is below # create a TestApp instance against the ServiceGatewayService self.testapp = TestApp(service_gateway_app)
def setUp(self): # Start container self._start_container() self.container.start_rel_from_url("res/deploy/r2deploy.yml") # Now create client to service self.service_gateway_service = ServiceGatewayServiceClient() log.debug("stopping Gateway web server") # Stop the web server as it is not needed. self.service_gateway_service.stop_service() self.test_app = TestApp(service_gateway_app)
def setUp(self): # Start container self._start_container() # Establish endpoint with container container_client = ContainerAgentClient(node=self.container.node, name=self.container.name) container_client.start_rel_from_url('res/deploy/r2coi.yml') # Now create client to service self.service_gateway_service = ServiceGatewayServiceClient(node=self.container.node) log.debug('stopping Gateway web server') # Stop the web server as it is not needed. self.service_gateway_service.stop_service() self.test_app = TestApp(app)
class TestServiceGatewayServiceInt(IonIntegrationTestCase): def setUp(self): # Start container self._start_container() self.container.start_rel_from_url("res/deploy/r2deploy.yml") # Now create client to service self.service_gateway_service = ServiceGatewayServiceClient() log.debug("stopping Gateway web server") # Stop the web server as it is not needed. self.service_gateway_service.stop_service() self.test_app = TestApp(service_gateway_app) def tearDown(self): self._stop_container() # Common SGS Response header check def check_response_headers(self, response): self.assertEqual(response.content_type, "application/json") self.assertEqual(len(response.json), 1) self.assertIn("data", response.json) def test_list_resource_types(self): response = self.test_app.get("/ion-service/list_resource_types") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) expected_type_list = getextends("Resource") self.assertEqual(len(response.json["data"][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json["data"][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get("/ion-service/list_resource_types?type=InformationResource") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) expected_type_list = getextends("InformationResource") self.assertEqual(len(response.json["data"][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json["data"][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get("/ion-service/list_resource_types?type=TaskableResource") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) expected_type_list = getextends("TaskableResource") self.assertEqual(len(response.json["data"][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json["data"][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get("/ion-service/list_resource_types?type=MyFakeResource") self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json["data"]) self.assertIn("KeyError", response.json["data"][GATEWAY_ERROR][GATEWAY_ERROR_EXCEPTION]) self.assertIn("MyFakeResource", response.json["data"][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone(response.json["data"][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def create_data_product_resource(self): geospatial_bounds = { "geospatial_latitude_limit_north": 1.0, "geospatial_latitude_limit_south": 1.0, "geospatial_longitude_limit_east": 1.0, "geospatial_longitude_limit_west": 1.0, "geospatial_vertical_min": 1.0, "geospatial_vertical_max": 1.0, } data_product_create_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "create", "params": { "object": { "type_": "DataProduct", "lcstate": "DRAFT", "description": DATA_PRODUCT_DESCRIPTION, "name": DATA_PRODUCT_NAME, "geospatial_bounds": geospatial_bounds, } }, } } response = self.test_app.post( "/ion-service/resource_registry/create", {"payload": simplejson.dumps(data_product_create_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) data_product_id = convert_unicode(response_data[0]) return data_product_id def create_data_product_resource_full(self): geospatial_bounds = { "geospatial_latitude_limit_north": 1.0, "geospatial_latitude_limit_south": 1.0, "geospatial_longitude_limit_east": 1.0, "geospatial_longitude_limit_west": 1.0, "geospatial_vertical_min": 1.0, "geospatial_vertical_max": 1.0, } # create a paramter dictionary the a stream definition for this data product DICTIONARY_NAME = "ctd_parsed_param_dict" response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=" + convert_unicode(DICTIONARY_NAME) + "&id_only=True&user_id=123abc456" ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] param_dictionary_id = convert_unicode(response_data[0]) test = str(param_dictionary_id[0]) log.debug("create_data_product_resource_full param_dictionary_id: %s", param_dictionary_id) log.debug("create_data_product_resource_full test: %s", test) response = self.test_app.get( "/ion-service/pubsub_management/create_stream_definition?name=CTDData¶meter_dictionary_id=" + convert_unicode(param_dictionary_id[0]) ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] log.debug("create_data_product_resource_full response_data: %s", response_data) stream_definition_id = convert_unicode(response_data) log.debug("create_data_product_resource_full stream_definition_id: %s", stream_definition_id) data_product_create_request = { "serviceRequest": { "serviceName": "data_product_management", "serviceOp": "create_data_product", "params": { "data_product": { "type_": "DataProduct", "lcstate": "DRAFT", "description": DATA_PRODUCT_DESCRIPTION, "name": DATA_PRODUCT_NAME, "geospatial_bounds": geospatial_bounds, }, "stream_definition_id": stream_definition_id, }, } } response = self.test_app.post( "/ion-service/data_product_management/create_data_product", {"payload": simplejson.dumps(data_product_create_request)}, ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] log.debug("create_data_product_resource_full create_data_product response_data: %s", response_data) # self.assertEqual(len(response_data), 2 ) data_product_id = convert_unicode(response_data) return data_product_id def delete_data_product_resource(self, data_product_id): data_product_delete_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "delete", "params": {"object_id": data_product_id}, } } response = self.test_app.post( "/ion-service/resource_registry/delete", {"payload": simplejson.dumps(data_product_delete_request)} ) self.check_response_headers(response) return response def create_policy_resource(self): policy_create_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "create", "params": { "object": { "definition": {}, "name": POLICY_NAME, "description": POLICY_DESCRIPTION, "lcstate": "DRAFT", "required": True, "enabled": True, "type_": "Policy", "policy_type": { "policy_rule": POLICY_RULE, "service_name": "user_notification", "type_": "ServiceAccessPolicy", }, } }, } } response = self.test_app.post( "/ion-service/resource_registry/create", {"payload": simplejson.dumps(policy_create_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) policy_id = convert_unicode(response_data[0]) return policy_id @attr("SMOKE") def test_anonymous_resource_registry_operations_through_gateway(self): """ This test ensures that requests make through the service gateway through messaging to the Resource Registry and back; including the support of unicode characters. """ response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=" + convert_unicode(DATA_PRODUCT_NAME) + "&id_only=True&user_id=123abc456" ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 0) data_product_id = self.create_data_product_resource() data_product_read_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "read", "params": {"object_id": data_product_id}, } } response = self.test_app.post( "/ion-service/resource_registry/read", {"payload": simplejson.dumps(data_product_read_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) data_product_obj = convert_unicode(response.json["data"][GATEWAY_RESPONSE]) # Verify the the name and description fields containing unicode characters match all the way through couch and the messaging self.assertEqual(data_product_obj["name"], convert_unicode(DATA_PRODUCT_NAME)) self.assertEqual(data_product_obj["description"], convert_unicode(DATA_PRODUCT_DESCRIPTION)) updated_description_text = data_product_obj["description"] + "---Updated!!" # modify some fields in the data for testing update data_product_obj["description"] = updated_description_text data_product_update_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "update", "params": {"object": data_product_obj}, } } response = self.test_app.post( "/ion-service/resource_registry/update", {"payload": simplejson.dumps(data_product_update_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response = self.test_app.post( "/ion-service/resource_registry/read", {"payload": simplejson.dumps(data_product_read_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) updated_data_product_obj = convert_unicode(response.json["data"][GATEWAY_RESPONSE]) self.assertEqual(updated_data_product_obj["description"], updated_description_text) differ = DictDiffer(updated_data_product_obj, data_product_obj) self.assertEqual( len(differ.changed()), 2 ) # Only the _rev and ts_updated fields should be different after an update response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=" + convert_unicode(DATA_PRODUCT_NAME) + "&id_only=True" ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 1) response = self.delete_data_product_resource(data_product_id) self.assertIsNone(response.json["data"][GATEWAY_RESPONSE]) response = self.test_app.post( "/ion-service/resource_registry/read", {"payload": simplejson.dumps(data_product_read_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json["data"]) self.assertIn("does not exist", response.json["data"][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=" + convert_unicode(DATA_PRODUCT_NAME) + "&id_only=True" ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 0) response = self.delete_data_product_resource(data_product_id) self.assertIn(GATEWAY_ERROR, response.json["data"]) self.assertIn("does not exist", response.json["data"][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone(response.json["data"][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) # Now try creating a policy object which has an internal object of a different type policy_id = self.create_policy_resource() policy_read_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "read", "params": {"object_id": policy_id}, } } response = self.test_app.post( "/ion-service/resource_registry/read", {"payload": simplejson.dumps(policy_read_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) policy_obj = convert_unicode(response.json["data"][GATEWAY_RESPONSE]) # Verify the the name and description fields containing unicode characters match all the way through couch and the messaging self.assertEqual(policy_obj["name"], convert_unicode(POLICY_NAME)) self.assertEqual(policy_obj["description"], convert_unicode(POLICY_DESCRIPTION)) self.assertEqual(policy_obj["policy_type"]["policy_rule"], convert_unicode(POLICY_RULE)) updated_policy_rule = policy_obj["policy_type"]["policy_rule"] + "---Updated!!" # modify some fields in the data for testing update policy_obj["policy_type"]["policy_rule"] = updated_policy_rule policy_update_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "update", "params": {"object": policy_obj}, } } response = self.test_app.post( "/ion-service/resource_registry/update", {"payload": simplejson.dumps(policy_update_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response = self.test_app.post( "/ion-service/resource_registry/read", {"payload": simplejson.dumps(policy_read_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) updated_policy_obj = convert_unicode(response.json["data"][GATEWAY_RESPONSE]) self.assertEqual(updated_policy_obj["policy_type"]["policy_rule"], updated_policy_rule) # Now testing the generic get_resource_extension with optional user_id parameter response = self.test_app.get("/ion-service/resource_registry/find_resources?name=ionsystem") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] actor_id = response_data[0][0]["_id"] response = self.test_app.get( "/ion-service/resource_registry/get_resource_extension?resource_id=" + actor_id + "&resource_extension=TestExtendedInformationResource" ) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(convert_unicode(response_data["user_id"]), "") response = self.test_app.get( "/ion-service/resource_registry/get_resource_extension?resource_id=" + actor_id + "&resource_extension=TestExtendedInformationResource&user_id=123abc456" ) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(convert_unicode(response_data["user_id"]), "123abc456") def test_non_anonymous_resource_registry_operations_through_gateway(self): id_client = IdentityManagementServiceClient() actor_id, valid_until, registered = id_client.signon(USER1_CERTIFICATE, True) response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=" + actor_id ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 0) id_client.delete_actor_identity(actor_id) def test_non_anonymous_resource_registry_operations_with_token(self): rr = self.container.resource_registry id_client = IdentityManagementServiceClient() create_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "create", "params": {"object": {"name": "Instrument1", "type_": "InstrumentDevice"}}, } } # Create without actor response = self.test_app.post( "/ion-service/resource_registry/create", {"payload": simplejson.dumps(create_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertGreaterEqual(len(response_data[0]), 20) # This is a resource_id inst_id = str(response_data[0]) inst_obj = rr.read(inst_id) self.assertEquals(inst_obj.type_, RT.InstrumentDevice) self.assertEquals(inst_obj.name, "Instrument1") self.assertEquals(inst_obj.visibility, ResourceVisibilityEnum.PUBLIC) act_objs, assocs = rr.find_objects(inst_id, PRED.hasOwner, RT.ActorIdentity, id_only=False) self.assertEquals(len(act_objs), 0) # Anonymous query shows PUBLIC visibility resource anymore response = self.test_app.get("/ion-service/resource_registry/find_resources?name=Instrument1&id_only=True") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 1) self.assertEqual(len(response_data[1]), 1) self.assertEqual(response_data[0][0], inst_id) inst_obj.visibility = ResourceVisibilityEnum.OWNER rr.update(inst_obj) # Now the anonymous query should not show the resource anymore response = self.test_app.get("/ion-service/resource_registry/find_resources?name=Instrument1&id_only=True") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 0) rr.delete(inst_id) # Create with actor actor_id, valid_until, registered = id_client.signon(USER1_CERTIFICATE, True) create_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "create", "requester": actor_id, "params": { "object": { "name": "Instrument1", "type_": "InstrumentDevice", "visibility": ResourceVisibilityEnum.OWNER, } }, } } response = self.test_app.post( "/ion-service/resource_registry/create", {"payload": simplejson.dumps(create_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertGreaterEqual(len(response_data[0]), 20) # This is a resource_id inst_id = str(response_data[0]) inst_obj = rr.read(inst_id) self.assertEquals(inst_obj.type_, RT.InstrumentDevice) self.assertEquals(inst_obj.name, "Instrument1") self.assertEquals(inst_obj.visibility, ResourceVisibilityEnum.OWNER) act_objs, assocs = rr.find_objects(inst_id, PRED.hasOwner, RT.ActorIdentity, id_only=False) self.assertEquals(len(act_objs), 1) self.assertEquals(act_objs[0]._id, actor_id) # Anonymous query should not show the resource anymore response = self.test_app.get("/ion-service/resource_registry/find_resources?name=Instrument1&id_only=True") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 0) # Authenticated request with owner shows resource response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=Instrument1&id_only=True&requester=" + actor_id ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 1) self.assertEqual(len(response_data[1]), 1) self.assertEqual(response_data[0][0], inst_id) token_str = id_client.create_authentication_token(actor_id, validity=2) # Request with authentication token for owner shows resource response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=Instrument1&id_only=True&authtoken=" + token_str ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 1) self.assertEqual(len(response_data[1]), 1) self.assertEqual(response_data[0][0], inst_id) gevent.sleep(2.1) # Request with expired authentication token for owner does not show resource (no error though) response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=Instrument1&id_only=True&authtoken=" + token_str ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 0) # Request with valid authentication token for different user does not show resource actor_id2, _ = rr.create(IonObject(RT.ActorIdentity, name="Actor2")) token_str2 = id_client.create_authentication_token(actor_id2, validity=2) response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=Instrument1&id_only=True&authtoken=" + token_str2 ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 0) token_str3 = id_client.create_authentication_token(actor_id, validity=2) # Request with new authentication token for owner shows resource response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=Instrument1&id_only=True&authtoken=" + token_str3 ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 1) self.assertEqual(len(response_data[1]), 1) self.assertEqual(response_data[0][0], inst_id) id_client.invalidate_authentication_token(token_str3) response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=Instrument1&id_only=True&authtoken=" + token_str3 ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 0) # Cleanup rr.delete(inst_id) rr.delete(actor_id2) id_client.delete_actor_identity(actor_id) def test_get_resource_schema(self): response = self.test_app.get("/ion-service/resource_type_schema/Org") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) org_obj = convert_unicode(response.json["data"][GATEWAY_RESPONSE]) self.assertTrue(isinstance(org_obj, dict)) self.assertIn("object", org_obj) self.assertIn("schemas", org_obj) self.assertIn("Org", org_obj["schemas"]) self.assertIn("OrgTypeEnum", org_obj["schemas"]) self.assertIn("Institution", org_obj["schemas"]) response = self.test_app.get("/ion-service/resource_type_schema/InstrumentModel") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) model_obj = convert_unicode(response.json["data"][GATEWAY_RESPONSE]) self.assertTrue(isinstance(org_obj, dict)) self.assertIn("object", model_obj) self.assertIn("schemas", model_obj) self.assertIn("InstrumentModel", model_obj["schemas"]) self.assertIn("PrimaryInterface", model_obj["schemas"]) response = self.test_app.get("/ion-service/resource_type_schema/DataProduct") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) data_product_obj = convert_unicode(response.json["data"][GATEWAY_RESPONSE]) self.assertTrue(isinstance(data_product_obj, dict)) self.assertIn("object", data_product_obj) self.assertIn("schemas", data_product_obj) self.assertIn("DataProduct", data_product_obj["schemas"]) self.assertIn("GeospatialBounds", data_product_obj["schemas"]) self.assertIn("GeospatialCoordinateReferenceSystem", data_product_obj["schemas"]) response = self.test_app.get("/ion-service/resource_type_schema/DataProduct123") self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json["data"]) self.assertIn("No matching class found", response.json["data"][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone(response.json["data"][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def test_get_resource(self): data_product_id = self.create_data_product_resource() response = self.test_app.get("/ion-resources/resource/" + data_product_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertNotIn("does not exist", response_data) data_product_obj = convert_unicode(response_data) self.assertEqual(data_product_id, data_product_obj["_id"]) self.delete_data_product_resource(data_product_id) def test_list_resources_by_type(self): data_product_id = self.create_data_product_resource() response = self.test_app.get("/ion-resources/find_resources/DataProduct") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 1) data_product_obj = convert_unicode(response_data[0]) self.assertEqual(data_product_id, data_product_obj["_id"]) self.delete_data_product_resource(data_product_id) def test_list_org_roles(self): response = self.test_app.get("/ion-service/resource_registry/find_resources?name=ionsystem") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] actor_id = response_data[0][0]["_id"] response = self.test_app.get("/ion-service/org_roles/" + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertIn("ION", response_data) self.assertEqual(len(response_data["ION"]), 3) self.assertIn("ION_MANAGER", response_data["ION"]) self.assertIn("ORG_MANAGER", response_data["ION"]) self.assertIn("ORG_MEMBER", response_data["ION"]) def test_user_role_cache(self): # Create a user id_client = IdentityManagementServiceClient() actor_id, valid_until, registered = id_client.signon(USER1_CERTIFICATE, True) # Make a request with this new user to get it into the cache response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=" + actor_id ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) # Check the contents of the user role cache for this user service_gateway_user_role_cache = self.container.proc_manager.procs_by_name["service_gateway"].user_role_cache self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), True) role_header = service_gateway_user_role_cache.get(actor_id) self.assertIn("ION", role_header) self.assertEqual(len(role_header["ION"]), 1) self.assertIn("ORG_MEMBER", role_header["ION"]) org_client = OrgManagementServiceClient() ion_org = org_client.find_org() manager_role = org_client.find_org_role_by_name(org_id=ion_org._id, role_name="ORG_MANAGER") org_client.grant_role(org_id=ion_org._id, actor_id=actor_id, role_name="ORG_MANAGER") # Just allow some time for event processing on slower platforms gevent.sleep(2) # The user should be evicted from the cache due to a change in roles self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), False) # Do it again to check for new roles response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=" + actor_id ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) # Check the contents of the user role cache for this user self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), True) role_header = service_gateway_user_role_cache.get(actor_id) self.assertIn("ION", role_header) self.assertEqual(len(role_header["ION"]), 2) self.assertIn("ORG_MEMBER", role_header["ION"]) self.assertIn("ORG_MANAGER", role_header["ION"]) # Now flush the user_role_cache and make sure it was flushed event_publisher = EventPublisher() event_publisher.publish_event(event_type=OT.UserRoleCacheResetEvent) # Just allow some time for event processing on slower platforms gevent.sleep(2) self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), False) self.assertEqual(service_gateway_user_role_cache.size(), 0) # Change the role once again and see if it is there again org_client.revoke_role(org_id=ion_org._id, actor_id=actor_id, role_name="ORG_MANAGER") # Just allow some time for event processing on slower platforms gevent.sleep(2) # The user should still not be there self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), False) # Do it again to check for new roles response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=" + actor_id ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) # Check the contents of the user role cache for this user self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), True) role_header = service_gateway_user_role_cache.get(actor_id) self.assertIn("ION", role_header) self.assertEqual(len(role_header["ION"]), 1) self.assertIn("ORG_MEMBER", role_header["ION"]) id_client.delete_actor_identity(actor_id) def test_data_provenance_retrieve(self): data_product_id = self.create_data_product_resource_full() get_parameter_provenance_visualization_image_request = { "serviceRequest": { "serviceName": "service_gateway", "serviceOp": "get_parameter_provenance_visualization_image", "params": {"data_product_id": data_product_id, "parameter_name": "temp"}, } } # call the gateway service intermeditary operation to get the image from the data product mgmt svc response = self.test_app.post( "/ion-service/get_parameter_provenance_visualization_image", {"payload": simplejson.dumps(get_parameter_provenance_visualization_image_request)}, ) # log.debug('test_data_provenance_retrieve response: %s', response) self.assertIsNotNone(response)
class TestServiceGatewayServiceInt(IonIntegrationTestCase): def setUp(self): # Start container self._start_container() self.container.start_rel_from_url('res/deploy/r2coi.yml') # Now create client to service self.service_gateway_service = ServiceGatewayServiceClient(node=self.container.node) log.debug('stopping Gateway web server') # Stop the web server as it is not needed. self.service_gateway_service.stop_service() self.test_app = TestApp(app) def tearDown(self): self._stop_container() #Common SGS Response header check def check_response_headers(self, response): self.assertEqual(response.content_type, "application/json") self.assertEqual(len(response.json), 1) self.assertIn('data',response.json) def test_list_resource_types(self): response = self.test_app.get('/ion-service/list_resource_types') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) expected_type_list = getextends('Resource') self.assertEqual(len(response.json['data'][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json['data'][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get('/ion-service/list_resource_types?type=InformationResource') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) expected_type_list = getextends('InformationResource') self.assertEqual(len(response.json['data'][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json['data'][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get('/ion-service/list_resource_types?type=TaskableResource') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) expected_type_list = getextends('TaskableResource') self.assertEqual(len(response.json['data'][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json['data'][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get('/ion-service/list_resource_types?type=MyFakeResource') self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn('KeyError', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_EXCEPTION]) self.assertIn('MyFakeResource', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone(response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def create_data_product_resource(self): data_product_create_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "create", "params": { "object": { "type_": "DataProduct", "provider_project": "Integration Test", "lcstate": "DRAFT", "description": "A test data product", "name": "TestDataProduct", "contact": { "name": "Test User", "phone": "858-555-1212", "city": "San Diego", "postalcode": "92093" } } } } } response = self.test_app.post('/ion-service/resource_registry/create', {'payload': json.dumps(data_product_create_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2 ) data_product_id = convert_unicode(response_data[0]) return data_product_id def delete_data_product_resource(self, data_product_id): data_product_delete_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "delete", "params": { "object_id": data_product_id } } } response = self.test_app.post('/ion-service/resource_registry/delete', {'payload': simplejson.dumps(data_product_delete_request) }) self.check_response_headers(response) return response def test_resource_registry_operations_through_gateway(self): response = self.test_app.get('/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data),2 ) self.assertEqual(len(response_data[0]), 0 ) data_product_id = self.create_data_product_resource() data_product_read_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "read", "params": { "object_id": data_product_id } } } response = self.test_app.post('/ion-service/resource_registry/read', {'payload': simplejson.dumps(data_product_read_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) data_product_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) #modify some fields in the data for testing update data_product_obj['description'] = 'An updated description for test data' data_product_obj['contact']['postalcode'] = '12345' data_product_update_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "update", "params": { "object": data_product_obj } } } response = self.test_app.post('/ion-service/resource_registry/update', {'payload': simplejson.dumps(data_product_update_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response = self.test_app.post('/ion-service/resource_registry/read', {'payload': simplejson.dumps(data_product_read_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) updated_data_product_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) self.assertEqual(updated_data_product_obj['description'], 'An updated description for test data', ) self.assertEqual(updated_data_product_obj['contact']['postalcode'], '12345') differ = DictDiffer(updated_data_product_obj, data_product_obj) self.assertEqual(len(differ.changed()), 2) # Only the _rev and ts_updated fields should be different after an update response = self.test_app.get('/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data),2 ) self.assertEqual(len(response_data[0]), 1 ) response = self.delete_data_product_resource(data_product_id) self.assertIsNone(response.json['data'][GATEWAY_RESPONSE]) response = self.test_app.post('/ion-service/resource_registry/read', {'payload': simplejson.dumps(data_product_read_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn('does not exist', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) response = self.test_app.get('/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data),2 ) self.assertEqual(len(response_data[0]), 0 ) response = self.delete_data_product_resource(data_product_id) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn('does not exist', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone(response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def test_get_resource_schema(self): response = self.test_app.get('/ion-service/resource_type_schema/DataProduct') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) data_product_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) self.assertTrue(isinstance(data_product_obj, dict)) response = self.test_app.get('/ion-service/resource_type_schema/DataProduct123') self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn('No matching class found', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone(response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def test_get_resource(self): data_product_id = self.create_data_product_resource() response = self.test_app.get('/ion-service/rest/resource/' + data_product_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertNotIn('does not exist', response_data) data_product_obj = convert_unicode(response_data) self.assertEqual(data_product_id, data_product_obj['_id']) self.delete_data_product_resource(data_product_id) def test_list_resources_by_type(self): data_product_id = self.create_data_product_resource() response = self.test_app.get('/ion-service/rest/find_resources/DataProduct') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data),1 ) data_product_obj = convert_unicode(response_data[0]) self.assertEqual(data_product_id, data_product_obj['_id']) self.delete_data_product_resource(data_product_id)
class TestServiceGatewayServiceInt(IonIntegrationTestCase): def setUp(self): # Start container self._start_container() self.container.start_rel_from_url("res/deploy/r2deploy.yml") # Now create client to service self.service_gateway_service = ServiceGatewayServiceClient(node=self.container.node) log.debug("stopping Gateway web server") # Stop the web server as it is not needed. self.service_gateway_service.stop_service() self.test_app = TestApp(service_gateway_app) def tearDown(self): self._stop_container() # Common SGS Response header check def check_response_headers(self, response): self.assertEqual(response.content_type, "application/json") self.assertEqual(len(response.json), 1) self.assertIn("data", response.json) def test_list_resource_types(self): response = self.test_app.get("/ion-service/list_resource_types") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) expected_type_list = getextends("Resource") self.assertEqual(len(response.json["data"][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json["data"][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get("/ion-service/list_resource_types?type=InformationResource") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) expected_type_list = getextends("InformationResource") self.assertEqual(len(response.json["data"][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json["data"][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get("/ion-service/list_resource_types?type=TaskableResource") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) expected_type_list = getextends("TaskableResource") self.assertEqual(len(response.json["data"][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json["data"][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get("/ion-service/list_resource_types?type=MyFakeResource") self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json["data"]) self.assertIn("KeyError", response.json["data"][GATEWAY_ERROR][GATEWAY_ERROR_EXCEPTION]) self.assertIn("MyFakeResource", response.json["data"][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone(response.json["data"][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def create_data_product_resource(self): geospatial_bounds = { "geospatial_latitude_limit_north": 1.0, "geospatial_latitude_limit_south": 1.0, "geospatial_longitude_limit_east": 1.0, "geospatial_longitude_limit_west": 1.0, "geospatial_vertical_min": 1.0, "geospatial_vertical_max": 1.0, } data_product_create_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "create", "params": { "object": { "type_": "DataProduct", "lcstate": "DRAFT", "description": DATA_PRODUCT_DESCRIPTION, "name": DATA_PRODUCT_NAME, "geospatial_bounds": geospatial_bounds, "temporal_domain": TEMPORAL_DOMAIN, } }, } } response = self.test_app.post( "/ion-service/resource_registry/create", {"payload": simplejson.dumps(data_product_create_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) data_product_id = convert_unicode(response_data[0]) return data_product_id def delete_data_product_resource(self, data_product_id): data_product_delete_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "delete", "params": {"object_id": data_product_id}, } } response = self.test_app.post( "/ion-service/resource_registry/delete", {"payload": simplejson.dumps(data_product_delete_request)} ) self.check_response_headers(response) return response def create_policy_resource(self): policy_create_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "create", "params": { "object": { "definition": {}, "name": POLICY_NAME, "description": POLICY_DESCRIPTION, "lcstate": "DRAFT", "required": True, "enabled": True, "type_": "Policy", "policy_type": { "policy_rule": POLICY_RULE, "service_name": "user_notification", "type_": "ServiceAccessPolicy", }, } }, } } response = self.test_app.post( "/ion-service/resource_registry/create", {"payload": simplejson.dumps(policy_create_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) policy_id = convert_unicode(response_data[0]) return policy_id @attr("SMOKE") def test_anonymous_resource_registry_operations_through_gateway(self): """ This test ensures that requests make through the service gateway through messaging to the Resource Registry and back; including the support of unicode characters. @return: """ response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=" + convert_unicode(DATA_PRODUCT_NAME) + "&id_only=True&user_id=123abc456" ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 0) data_product_id = self.create_data_product_resource() data_product_read_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "read", "params": {"object_id": data_product_id}, } } response = self.test_app.post( "/ion-service/resource_registry/read", {"payload": simplejson.dumps(data_product_read_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) data_product_obj = convert_unicode(response.json["data"][GATEWAY_RESPONSE]) # Verify the the name and description fields containing unicode characters match all the way through couch and the messaging self.assertEqual(data_product_obj["name"], convert_unicode(DATA_PRODUCT_NAME)) self.assertEqual(data_product_obj["description"], convert_unicode(DATA_PRODUCT_DESCRIPTION)) updated_description_text = data_product_obj["description"] + "---Updated!!" # modify some fields in the data for testing update data_product_obj["description"] = updated_description_text data_product_update_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "update", "params": {"object": data_product_obj}, } } response = self.test_app.post( "/ion-service/resource_registry/update", {"payload": simplejson.dumps(data_product_update_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response = self.test_app.post( "/ion-service/resource_registry/read", {"payload": simplejson.dumps(data_product_read_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) updated_data_product_obj = convert_unicode(response.json["data"][GATEWAY_RESPONSE]) self.assertEqual(updated_data_product_obj["description"], updated_description_text) differ = DictDiffer(updated_data_product_obj, data_product_obj) self.assertEqual( len(differ.changed()), 2 ) # Only the _rev and ts_updated fields should be different after an update response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=" + convert_unicode(DATA_PRODUCT_NAME) + "&id_only=True" ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 1) response = self.delete_data_product_resource(data_product_id) self.assertIsNone(response.json["data"][GATEWAY_RESPONSE]) response = self.test_app.post( "/ion-service/resource_registry/read", {"payload": simplejson.dumps(data_product_read_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json["data"]) self.assertIn("does not exist", response.json["data"][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=" + convert_unicode(DATA_PRODUCT_NAME) + "&id_only=True" ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 0) response = self.delete_data_product_resource(data_product_id) self.assertIn(GATEWAY_ERROR, response.json["data"]) self.assertIn("does not exist", response.json["data"][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone(response.json["data"][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) # Now try creating a policy object which has an internal object of a different type policy_id = self.create_policy_resource() policy_read_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "read", "params": {"object_id": policy_id}, } } response = self.test_app.post( "/ion-service/resource_registry/read", {"payload": simplejson.dumps(policy_read_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) policy_obj = convert_unicode(response.json["data"][GATEWAY_RESPONSE]) # Verify the the name and description fields containing unicode characters match all the way through couch and the messaging self.assertEqual(policy_obj["name"], convert_unicode(POLICY_NAME)) self.assertEqual(policy_obj["description"], convert_unicode(POLICY_DESCRIPTION)) self.assertEqual(policy_obj["policy_type"]["policy_rule"], convert_unicode(POLICY_RULE)) updated_policy_rule = policy_obj["policy_type"]["policy_rule"] + "---Updated!!" # modify some fields in the data for testing update policy_obj["policy_type"]["policy_rule"] = updated_policy_rule policy_update_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "update", "params": {"object": policy_obj}, } } response = self.test_app.post( "/ion-service/resource_registry/update", {"payload": simplejson.dumps(policy_update_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response = self.test_app.post( "/ion-service/resource_registry/read", {"payload": simplejson.dumps(policy_read_request)} ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) updated_policy_obj = convert_unicode(response.json["data"][GATEWAY_RESPONSE]) self.assertEqual(updated_policy_obj["policy_type"]["policy_rule"], updated_policy_rule) # Now testing the generic get_resource_extension with optional user_id parameter response = self.test_app.get("/ion-service/resource_registry/find_resources?name=ionsystem") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] actor_id = response_data[0][0]["_id"] response = self.test_app.get( "/ion-service/resource_registry/get_resource_extension?resource_id=" + actor_id + "&resource_extension=TestExtendedInformationResource" ) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(convert_unicode(response_data["user_id"]), "") response = self.test_app.get( "/ion-service/resource_registry/get_resource_extension?resource_id=" + actor_id + "&resource_extension=TestExtendedInformationResource&user_id=123abc456" ) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(convert_unicode(response_data["user_id"]), "123abc456") def test_non_anonymous_resource_registry_operations_through_gateway(self): id_client = IdentityManagementServiceClient(node=self.container.node) actor_id, valid_until, registered = id_client.signon(USER1_CERTIFICATE, True) response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=" + actor_id ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 0) id_client.delete_actor_identity(actor_id) def test_get_resource_schema(self): response = self.test_app.get("/ion-service/resource_type_schema/Org") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) org_obj = convert_unicode(response.json["data"][GATEWAY_RESPONSE]) self.assertTrue(isinstance(org_obj, dict)) self.assertIn("object", org_obj) self.assertIn("schemas", org_obj) self.assertIn("Org", org_obj["schemas"]) self.assertIn("OrgTypeEnum", org_obj["schemas"]) self.assertIn("Institution", org_obj["schemas"]) response = self.test_app.get("/ion-service/resource_type_schema/InstrumentModel") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) model_obj = convert_unicode(response.json["data"][GATEWAY_RESPONSE]) self.assertTrue(isinstance(org_obj, dict)) self.assertIn("object", model_obj) self.assertIn("schemas", model_obj) self.assertIn("InstrumentModel", model_obj["schemas"]) self.assertIn("PrimaryInterface", model_obj["schemas"]) response = self.test_app.get("/ion-service/resource_type_schema/DataProduct") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) data_product_obj = convert_unicode(response.json["data"][GATEWAY_RESPONSE]) self.assertTrue(isinstance(data_product_obj, dict)) self.assertIn("object", data_product_obj) self.assertIn("schemas", data_product_obj) self.assertIn("DataProduct", data_product_obj["schemas"]) self.assertIn("GeospatialBounds", data_product_obj["schemas"]) self.assertIn("GeospatialCoordinateReferenceSystem", data_product_obj["schemas"]) response = self.test_app.get("/ion-service/resource_type_schema/DataProduct123") self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json["data"]) self.assertIn("No matching class found", response.json["data"][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone(response.json["data"][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def test_get_resource(self): data_product_id = self.create_data_product_resource() response = self.test_app.get("/ion-resources/resource/" + data_product_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertNotIn("does not exist", response_data) data_product_obj = convert_unicode(response_data) self.assertEqual(data_product_id, data_product_obj["_id"]) self.delete_data_product_resource(data_product_id) def test_list_resources_by_type(self): data_product_id = self.create_data_product_resource() response = self.test_app.get("/ion-resources/find_resources/DataProduct") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 1) data_product_obj = convert_unicode(response_data[0]) self.assertEqual(data_product_id, data_product_obj["_id"]) self.delete_data_product_resource(data_product_id) def test_list_org_roles(self): response = self.test_app.get("/ion-service/resource_registry/find_resources?name=ionsystem") self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] actor_id = response_data[0][0]["_id"] response = self.test_app.get("/ion-service/org_roles/" + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) response_data = response.json["data"][GATEWAY_RESPONSE] self.assertIn("ION", response_data) self.assertEqual(len(response_data["ION"]), 3) self.assertIn("ION_MANAGER", response_data["ION"]) self.assertIn("ORG_MANAGER", response_data["ION"]) self.assertIn("ORG_MEMBER", response_data["ION"]) def test_user_role_cache(self): # Create a user id_client = IdentityManagementServiceClient(node=self.container.node) actor_id, valid_until, registered = id_client.signon(USER1_CERTIFICATE, True) # Make a request with this new user to get it into the cache response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=" + actor_id ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) # Check the contents of the user role cache for this user service_gateway_user_role_cache = self.container.proc_manager.procs_by_name["service_gateway"].user_role_cache self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), True) role_header = service_gateway_user_role_cache.get(actor_id) self.assertIn("ION", role_header) self.assertEqual(len(role_header["ION"]), 1) self.assertIn("ORG_MEMBER", role_header["ION"]) org_client = OrgManagementServiceClient(node=self.container.node) ion_org = org_client.find_org() manager_role = org_client.find_org_role_by_name(org_id=ion_org._id, role_name="ORG_MANAGER") org_client.grant_role(org_id=ion_org._id, actor_id=actor_id, role_name="ORG_MANAGER") # Just allow some time for event processing on slower platforms gevent.sleep(2) # The user should be evicted from the cache due to a change in roles self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), False) # Do it again to check for new roles response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=" + actor_id ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) # Check the contents of the user role cache for this user self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), True) role_header = service_gateway_user_role_cache.get(actor_id) self.assertIn("ION", role_header) self.assertEqual(len(role_header["ION"]), 2) self.assertIn("ORG_MEMBER", role_header["ION"]) self.assertIn("ORG_MANAGER", role_header["ION"]) # Now flush the user_role_cache and make sure it was flushed event_publisher = EventPublisher() event_publisher.publish_event(event_type=OT.UserRoleCacheResetEvent) # Just allow some time for event processing on slower platforms gevent.sleep(2) self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), False) self.assertEqual(service_gateway_user_role_cache.size(), 0) # Change the role once again and see if it is there again org_client.revoke_role(org_id=ion_org._id, actor_id=actor_id, role_name="ORG_MANAGER") # Just allow some time for event processing on slower platforms gevent.sleep(2) # The user should still not be there self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), False) # Do it again to check for new roles response = self.test_app.get( "/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=" + actor_id ) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json["data"]) # Check the contents of the user role cache for this user self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), True) role_header = service_gateway_user_role_cache.get(actor_id) self.assertIn("ION", role_header) self.assertEqual(len(role_header["ION"]), 1) self.assertIn("ORG_MEMBER", role_header["ION"]) id_client.delete_actor_identity(actor_id)
class TestServiceGatewayServiceInt(IonIntegrationTestCase): def setUp(self): # Start container self._start_container() self.container.start_rel_from_url('res/deploy/r2deploy.yml') # Now create client to service self.service_gateway_service = ServiceGatewayServiceClient(node=self.container.node) log.debug('stopping Gateway web server') # Stop the web server as it is not needed. self.service_gateway_service.stop_service() self.test_app = TestApp(service_gateway_app) def tearDown(self): self._stop_container() #Common SGS Response header check def check_response_headers(self, response): self.assertEqual(response.content_type, "application/json") self.assertEqual(len(response.json), 1) self.assertIn('data',response.json) def test_list_resource_types(self): response = self.test_app.get('/ion-service/list_resource_types') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) expected_type_list = getextends('Resource') self.assertEqual(len(response.json['data'][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json['data'][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get('/ion-service/list_resource_types?type=InformationResource') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) expected_type_list = getextends('InformationResource') self.assertEqual(len(response.json['data'][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json['data'][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get('/ion-service/list_resource_types?type=TaskableResource') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) expected_type_list = getextends('TaskableResource') self.assertEqual(len(response.json['data'][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json['data'][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get('/ion-service/list_resource_types?type=MyFakeResource') self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn('KeyError', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_EXCEPTION]) self.assertIn('MyFakeResource', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone(response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def create_data_product_resource(self): geospatial_bounds = { "geospatial_latitude_limit_north": 1.0, "geospatial_latitude_limit_south": 1.0, "geospatial_longitude_limit_east": 1.0, "geospatial_longitude_limit_west": 1.0, "geospatial_vertical_min": 1.0, "geospatial_vertical_max": 1.0 } data_product_create_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "create", "params": { "object": { "type_": "DataProduct", "lcstate": "DRAFT", "description": DATA_PRODUCT_DESCRIPTION, "name": DATA_PRODUCT_NAME, 'geospatial_bounds': geospatial_bounds, 'temporal_domain': TEMPORAL_DOMAIN } } } } response = self.test_app.post('/ion-service/resource_registry/create', {'payload': simplejson.dumps(data_product_create_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2 ) data_product_id = convert_unicode(response_data[0]) return data_product_id def create_data_product_resource_full(self): geospatial_bounds = { "geospatial_latitude_limit_north": 1.0, "geospatial_latitude_limit_south": 1.0, "geospatial_longitude_limit_east": 1.0, "geospatial_longitude_limit_west": 1.0, "geospatial_vertical_min": 1.0, "geospatial_vertical_max": 1.0 } #create a paramter dictionary the a stream definition for this data product DICTIONARY_NAME='ctd_parsed_param_dict' response = self.test_app.get('/ion-service/resource_registry/find_resources?name=' + convert_unicode(DICTIONARY_NAME) + '&id_only=True&user_id=123abc456') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] param_dictionary_id = convert_unicode(response_data[0]) test = str(param_dictionary_id[0]) log.debug('create_data_product_resource_full param_dictionary_id: %s', param_dictionary_id) log.debug('create_data_product_resource_full test: %s', test) response = self.test_app.get('/ion-service/pubsub_management/create_stream_definition?name=CTDData¶meter_dictionary_id='+ convert_unicode(param_dictionary_id[0])) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] log.debug('create_data_product_resource_full response_data: %s', response_data) stream_definition_id = convert_unicode(response_data) log.debug('create_data_product_resource_full stream_definition_id: %s', stream_definition_id) data_product_create_request = { "serviceRequest": { "serviceName": "data_product_management", "serviceOp": "create_data_product", "params": { "data_product": { "type_": "DataProduct", "lcstate": "DRAFT", "description": DATA_PRODUCT_DESCRIPTION, "name": DATA_PRODUCT_NAME, 'geospatial_bounds': geospatial_bounds, 'temporal_domain': TEMPORAL_DOMAIN }, "stream_definition_id": stream_definition_id } } } response = self.test_app.post('/ion-service/data_product_management/create_data_product', {'payload': simplejson.dumps(data_product_create_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] log.debug('create_data_product_resource_full create_data_product response_data: %s', response_data) #self.assertEqual(len(response_data), 2 ) data_product_id = convert_unicode(response_data) return data_product_id def delete_data_product_resource(self, data_product_id): data_product_delete_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "delete", "params": { "object_id": data_product_id } } } response = self.test_app.post('/ion-service/resource_registry/delete', {'payload': simplejson.dumps(data_product_delete_request) }) self.check_response_headers(response) return response def create_policy_resource(self): policy_create_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "create", "params": { "object": { "definition": {}, "name": POLICY_NAME, "description": POLICY_DESCRIPTION, "lcstate": "DRAFT", "required": True, "enabled": True, "type_": "Policy", "policy_type": { "policy_rule" : POLICY_RULE, "service_name": "user_notification", "type_": "ServiceAccessPolicy" } } } } } response = self.test_app.post('/ion-service/resource_registry/create', {'payload': simplejson.dumps(policy_create_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2 ) policy_id = convert_unicode(response_data[0]) return policy_id @attr('SMOKE') def test_anonymous_resource_registry_operations_through_gateway(self): """ This test ensures that requests make through the service gateway through messaging to the Resource Registry and back; including the support of unicode characters. @return: """ response = self.test_app.get('/ion-service/resource_registry/find_resources?name=' + convert_unicode(DATA_PRODUCT_NAME) + '&id_only=True&user_id=123abc456') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data),2 ) self.assertEqual(len(response_data[0]), 0 ) data_product_id = self.create_data_product_resource() data_product_read_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "read", "params": { "object_id": data_product_id } } } response = self.test_app.post('/ion-service/resource_registry/read', {'payload': simplejson.dumps(data_product_read_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) data_product_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) #Verify the the name and description fields containing unicode characters match all the way through couch and the messaging self.assertEqual(data_product_obj['name'], convert_unicode(DATA_PRODUCT_NAME)) self.assertEqual(data_product_obj['description'], convert_unicode(DATA_PRODUCT_DESCRIPTION)) updated_description_text = data_product_obj['description'] + '---Updated!!' #modify some fields in the data for testing update data_product_obj['description'] = updated_description_text data_product_update_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "update", "params": { "object": data_product_obj } } } response = self.test_app.post('/ion-service/resource_registry/update', {'payload': simplejson.dumps(data_product_update_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response = self.test_app.post('/ion-service/resource_registry/read', {'payload': simplejson.dumps(data_product_read_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) updated_data_product_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) self.assertEqual(updated_data_product_obj['description'], updated_description_text ) differ = DictDiffer(updated_data_product_obj, data_product_obj) self.assertEqual(len(differ.changed()), 2) # Only the _rev and ts_updated fields should be different after an update response = self.test_app.get('/ion-service/resource_registry/find_resources?name=' + convert_unicode(DATA_PRODUCT_NAME) + '&id_only=True') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data),2 ) self.assertEqual(len(response_data[0]), 1 ) response = self.delete_data_product_resource(data_product_id) self.assertIsNone(response.json['data'][GATEWAY_RESPONSE]) response = self.test_app.post('/ion-service/resource_registry/read', {'payload': simplejson.dumps(data_product_read_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn('does not exist', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) response = self.test_app.get('/ion-service/resource_registry/find_resources?name=' + convert_unicode(DATA_PRODUCT_NAME) + '&id_only=True') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data),2 ) self.assertEqual(len(response_data[0]), 0 ) response = self.delete_data_product_resource(data_product_id) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn('does not exist', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone(response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) #Now try creating a policy object which has an internal object of a different type policy_id = self.create_policy_resource() policy_read_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "read", "params": { "object_id": policy_id } } } response = self.test_app.post('/ion-service/resource_registry/read', {'payload': simplejson.dumps(policy_read_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) policy_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) #Verify the the name and description fields containing unicode characters match all the way through couch and the messaging self.assertEqual(policy_obj['name'], convert_unicode(POLICY_NAME)) self.assertEqual(policy_obj['description'], convert_unicode(POLICY_DESCRIPTION)) self.assertEqual(policy_obj['policy_type']['policy_rule'], convert_unicode(POLICY_RULE)) updated_policy_rule = policy_obj['policy_type']['policy_rule'] + '---Updated!!' #modify some fields in the data for testing update policy_obj['policy_type']['policy_rule'] = updated_policy_rule policy_update_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "update", "params": { "object": policy_obj } } } response = self.test_app.post('/ion-service/resource_registry/update', {'payload': simplejson.dumps(policy_update_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response = self.test_app.post('/ion-service/resource_registry/read', {'payload': simplejson.dumps(policy_read_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) updated_policy_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) self.assertEqual(updated_policy_obj['policy_type']['policy_rule'], updated_policy_rule ) #Now testing the generic get_resource_extension with optional user_id parameter response = self.test_app.get('/ion-service/resource_registry/find_resources?name=ionsystem') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] actor_id = response_data[0][0]['_id'] response = self.test_app.get('/ion-service/resource_registry/get_resource_extension?resource_id=' + actor_id + '&resource_extension=TestExtendedInformationResource') self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(convert_unicode(response_data['user_id']), '') response = self.test_app.get('/ion-service/resource_registry/get_resource_extension?resource_id=' + actor_id + '&resource_extension=TestExtendedInformationResource&user_id=123abc456') self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(convert_unicode(response_data['user_id']), '123abc456') def test_non_anonymous_resource_registry_operations_through_gateway(self): id_client = IdentityManagementServiceClient(node=self.container.node) actor_id, valid_until, registered = id_client.signon(USER1_CERTIFICATE, True) response = self.test_app.get('/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data),2 ) self.assertEqual(len(response_data[0]), 0 ) id_client.delete_actor_identity(actor_id) def test_get_resource_schema(self): response = self.test_app.get('/ion-service/resource_type_schema/Org') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) org_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) self.assertTrue(isinstance(org_obj, dict)) self.assertIn('object', org_obj) self.assertIn('schemas', org_obj) self.assertIn('Org', org_obj['schemas']) self.assertIn('OrgTypeEnum', org_obj['schemas']) self.assertIn('Institution', org_obj['schemas']) response = self.test_app.get('/ion-service/resource_type_schema/InstrumentModel') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) model_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) self.assertTrue(isinstance(org_obj, dict)) self.assertIn('object', model_obj) self.assertIn('schemas', model_obj) self.assertIn('InstrumentModel', model_obj['schemas']) self.assertIn('PrimaryInterface', model_obj['schemas']) response = self.test_app.get('/ion-service/resource_type_schema/DataProduct') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) data_product_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) self.assertTrue(isinstance(data_product_obj, dict)) self.assertIn('object', data_product_obj) self.assertIn('schemas', data_product_obj) self.assertIn('DataProduct', data_product_obj['schemas']) self.assertIn('GeospatialBounds', data_product_obj['schemas']) self.assertIn('GeospatialCoordinateReferenceSystem', data_product_obj['schemas']) response = self.test_app.get('/ion-service/resource_type_schema/DataProduct123') self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn('No matching class found', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone(response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def test_get_resource(self): data_product_id = self.create_data_product_resource() response = self.test_app.get('/ion-resources/resource/' + data_product_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertNotIn('does not exist', response_data) data_product_obj = convert_unicode(response_data) self.assertEqual(data_product_id, data_product_obj['_id']) self.delete_data_product_resource(data_product_id) def test_list_resources_by_type(self): data_product_id = self.create_data_product_resource() response = self.test_app.get('/ion-resources/find_resources/DataProduct') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data),1 ) data_product_obj = convert_unicode(response_data[0]) self.assertEqual(data_product_id, data_product_obj['_id']) self.delete_data_product_resource(data_product_id) def test_list_org_roles(self): response = self.test_app.get('/ion-service/resource_registry/find_resources?name=ionsystem') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] actor_id = response_data[0][0]['_id'] response = self.test_app.get('/ion-service/org_roles/' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertIn('ION', response_data) self.assertEqual(len(response_data['ION']), 3) self.assertIn('ION_MANAGER', response_data['ION']) self.assertIn('ORG_MANAGER', response_data['ION']) self.assertIn('ORG_MEMBER', response_data['ION']) def test_user_role_cache(self): #Create a user id_client = IdentityManagementServiceClient(node=self.container.node) actor_id, valid_until, registered = id_client.signon(USER1_CERTIFICATE, True) #Make a request with this new user to get it into the cache response = self.test_app.get('/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) #Check the contents of the user role cache for this user service_gateway_user_role_cache = self.container.proc_manager.procs_by_name['service_gateway'].user_role_cache self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), True) role_header = service_gateway_user_role_cache.get(actor_id) self.assertIn('ION', role_header) self.assertEqual(len(role_header['ION']), 1) self.assertIn('ORG_MEMBER', role_header['ION']) org_client = OrgManagementServiceClient(node=self.container.node) ion_org = org_client.find_org() manager_role = org_client.find_org_role_by_name(org_id=ion_org._id, role_name='ORG_MANAGER') org_client.grant_role(org_id=ion_org._id, actor_id=actor_id, role_name='ORG_MANAGER') #Just allow some time for event processing on slower platforms gevent.sleep(2) #The user should be evicted from the cache due to a change in roles self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), False) #Do it again to check for new roles response = self.test_app.get('/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) #Check the contents of the user role cache for this user self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), True) role_header = service_gateway_user_role_cache.get(actor_id) self.assertIn('ION', role_header) self.assertEqual(len(role_header['ION']), 2) self.assertIn('ORG_MEMBER', role_header['ION']) self.assertIn('ORG_MANAGER', role_header['ION']) #Now flush the user_role_cache and make sure it was flushed event_publisher = EventPublisher() event_publisher.publish_event(event_type=OT.UserRoleCacheResetEvent) #Just allow some time for event processing on slower platforms gevent.sleep(2) self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), False) self.assertEqual(service_gateway_user_role_cache.size(), 0) #Change the role once again and see if it is there again org_client.revoke_role(org_id=ion_org._id, actor_id=actor_id, role_name='ORG_MANAGER') #Just allow some time for event processing on slower platforms gevent.sleep(2) #The user should still not be there self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), False) #Do it again to check for new roles response = self.test_app.get('/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) #Check the contents of the user role cache for this user self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), True) role_header = service_gateway_user_role_cache.get(actor_id) self.assertIn('ION', role_header) self.assertEqual(len(role_header['ION']), 1) self.assertIn('ORG_MEMBER', role_header['ION']) id_client.delete_actor_identity(actor_id) def test_data_provenance_retrieve(self): data_product_id = self.create_data_product_resource_full() get_parameter_provenance_visualization_image_request = { "serviceRequest": { "serviceName": "service_gateway", "serviceOp": "get_parameter_provenance_visualization_image", "params": { "data_product_id": data_product_id, "parameter_name" : "temp" } } } #call the gateway service intermeditary operation to get the image from the data product mgmt svc response = self.test_app.post('/ion-service/get_parameter_provenance_visualization_image', {'payload': simplejson.dumps(get_parameter_provenance_visualization_image_request) }) #log.debug('test_data_provenance_retrieve response: %s', response) self.assertIsNotNone(response)
class TestServiceGatewayServiceInt(IonIntegrationTestCase): def setUp(self): # Start container self._start_container() self.container.start_rel_from_url('res/deploy/r2coi.yml') # Now create client to service self.service_gateway_service = ServiceGatewayServiceClient(node=self.container.node) log.debug('stopping Gateway web server') # Stop the web server as it is not needed. self.service_gateway_service.stop_service() self.test_app = TestApp(service_gateway_app) def tearDown(self): self._stop_container() #Common SGS Response header check def check_response_headers(self, response): self.assertEqual(response.content_type, "application/json") self.assertEqual(len(response.json), 1) self.assertIn('data',response.json) def test_list_resource_types(self): response = self.test_app.get('/ion-service/list_resource_types') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) expected_type_list = getextends('Resource') self.assertEqual(len(response.json['data'][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json['data'][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get('/ion-service/list_resource_types?type=InformationResource') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) expected_type_list = getextends('InformationResource') self.assertEqual(len(response.json['data'][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json['data'][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get('/ion-service/list_resource_types?type=TaskableResource') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) expected_type_list = getextends('TaskableResource') self.assertEqual(len(response.json['data'][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json['data'][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get('/ion-service/list_resource_types?type=MyFakeResource') self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn('KeyError', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_EXCEPTION]) self.assertIn('MyFakeResource', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone(response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def create_data_product_resource(self): data_product_create_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "create", "params": { "object": { "type_": "DataProduct", "lcstate": "DRAFT", "description": "A test data product", "name": "TestDataProduct" } } } } response = self.test_app.post('/ion-service/resource_registry/create', {'payload': json.dumps(data_product_create_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2 ) data_product_id = convert_unicode(response_data[0]) return data_product_id def delete_data_product_resource(self, data_product_id): data_product_delete_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "delete", "params": { "object_id": data_product_id } } } response = self.test_app.post('/ion-service/resource_registry/delete', {'payload': simplejson.dumps(data_product_delete_request) }) self.check_response_headers(response) return response @attr('SMOKE') def test_anonymous_resource_registry_operations_through_gateway(self): response = self.test_app.get('/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data),2 ) self.assertEqual(len(response_data[0]), 0 ) data_product_id = self.create_data_product_resource() data_product_read_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "read", "params": { "object_id": data_product_id } } } response = self.test_app.post('/ion-service/resource_registry/read', {'payload': simplejson.dumps(data_product_read_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) data_product_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) #modify some fields in the data for testing update data_product_obj['description'] = 'An updated description for test data' data_product_update_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "update", "params": { "object": data_product_obj } } } response = self.test_app.post('/ion-service/resource_registry/update', {'payload': simplejson.dumps(data_product_update_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response = self.test_app.post('/ion-service/resource_registry/read', {'payload': simplejson.dumps(data_product_read_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) updated_data_product_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) self.assertEqual(updated_data_product_obj['description'], 'An updated description for test data', ) differ = DictDiffer(updated_data_product_obj, data_product_obj) self.assertEqual(len(differ.changed()), 2) # Only the _rev and ts_updated fields should be different after an update response = self.test_app.get('/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data),2 ) self.assertEqual(len(response_data[0]), 1 ) response = self.delete_data_product_resource(data_product_id) self.assertIsNone(response.json['data'][GATEWAY_RESPONSE]) response = self.test_app.post('/ion-service/resource_registry/read', {'payload': simplejson.dumps(data_product_read_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn('does not exist', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) response = self.test_app.get('/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data),2 ) self.assertEqual(len(response_data[0]), 0 ) response = self.delete_data_product_resource(data_product_id) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn('does not exist', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone(response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def test_non_anonymous_resource_registry_operations_through_gateway(self): id_client = IdentityManagementServiceClient(node=self.container.node) actor_id, valid_until, registered = id_client.signon(USER1_CERTIFICATE, True) response = self.test_app.get('/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data),2 ) self.assertEqual(len(response_data[0]), 0 ) id_client.delete_actor_identity(actor_id) def test_get_resource_schema(self): response = self.test_app.get('/ion-service/resource_type_schema/DataProduct') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) data_product_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) self.assertTrue(isinstance(data_product_obj, dict)) response = self.test_app.get('/ion-service/resource_type_schema/DataProduct123') self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn('No matching class found', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone(response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def test_get_resource(self): data_product_id = self.create_data_product_resource() response = self.test_app.get('/ion-service/rest/resource/' + data_product_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertNotIn('does not exist', response_data) data_product_obj = convert_unicode(response_data) self.assertEqual(data_product_id, data_product_obj['_id']) self.delete_data_product_resource(data_product_id) def test_list_resources_by_type(self): data_product_id = self.create_data_product_resource() response = self.test_app.get('/ion-service/rest/find_resources/DataProduct') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data),1 ) data_product_obj = convert_unicode(response_data[0]) self.assertEqual(data_product_id, data_product_obj['_id']) self.delete_data_product_resource(data_product_id) def test_list_org_roles(self): response = self.test_app.get('/ion-service/resource_registry/find_resources?name=ionsystem') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] actor_id = response_data[0][0]['_id'] response = self.test_app.get('/ion-service/org_roles/' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertIn('ION', response_data) self.assertEqual(len(response_data['ION']), 3) self.assertIn('ION_MANAGER', response_data['ION']) self.assertIn('ORG_MANAGER', response_data['ION']) self.assertIn('ORG_MEMBER', response_data['ION']) def test_user_role_cache(self): #Create a user id_client = IdentityManagementServiceClient(node=self.container.node) actor_id, valid_until, registered = id_client.signon(USER1_CERTIFICATE, True) #Make a request with this new user to get it into the cache response = self.test_app.get('/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) #Check the contents of the user role cache for this user service_gateway_user_cache = self.container.proc_manager.procs_by_name['service_gateway'].user_data_cache self.assertEqual(service_gateway_user_cache.has_key(actor_id), True) role_header = service_gateway_user_cache.get(actor_id) self.assertIn('ION', role_header) self.assertEqual(len(role_header['ION']), 1) self.assertIn('ORG_MEMBER', role_header['ION']) org_client = OrgManagementServiceClient(node=self.container.node) ion_org = org_client.find_org() manager_role = org_client.find_org_role_by_name(org_id=ion_org._id, role_name='ORG_MANAGER') org_client.grant_role(org_id=ion_org._id, user_id=actor_id, role_name='ORG_MANAGER') #Just allow some time for event processing on slower platforms gevent.sleep(2) #The user should be evicted from the cache due to a change in roles self.assertEqual(service_gateway_user_cache.has_key(actor_id), False) #Do it again to check for new roles response = self.test_app.get('/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) #Check the contents of the user role cache for this user self.assertEqual(service_gateway_user_cache.has_key(actor_id), True) role_header = service_gateway_user_cache.get(actor_id) self.assertIn('ION', role_header) self.assertEqual(len(role_header['ION']), 2) self.assertIn('ORG_MEMBER', role_header['ION']) self.assertIn('ORG_MANAGER', role_header['ION']) #Now flush the user_role_cache and make sure it was flushed event_publisher = EventPublisher() event_publisher.publish_event(event_type=OT.UserRoleCacheResetEvent) #Just allow some time for event processing on slower platforms gevent.sleep(2) self.assertEqual(service_gateway_user_cache.has_key(actor_id), False) self.assertEqual(service_gateway_user_cache.size(), 0) #Change the role once again and see if it is there again org_client.revoke_role(org_id=ion_org._id, user_id=actor_id, role_name='ORG_MANAGER') #Just allow some time for event processing on slower platforms gevent.sleep(2) #The user should still not be there self.assertEqual(service_gateway_user_cache.has_key(actor_id), False) #Do it again to check for new roles response = self.test_app.get('/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) #Check the contents of the user role cache for this user self.assertEqual(service_gateway_user_cache.has_key(actor_id), True) role_header = service_gateway_user_cache.get(actor_id) self.assertIn('ION', role_header) self.assertEqual(len(role_header['ION']), 1) self.assertIn('ORG_MEMBER', role_header['ION']) id_client.delete_actor_identity(actor_id)
class TestServiceGatewayServiceInt(IonIntegrationTestCase): def setUp(self): # Start container self._start_container() self.container.start_rel_from_url('res/deploy/r2coi.yml') # Now create client to service self.service_gateway_service = ServiceGatewayServiceClient(node=self.container.node) log.debug('stopping Gateway web server') # Stop the web server as it is not needed. self.service_gateway_service.stop_service() self.test_app = TestApp(app) def tearDown(self): self._stop_container() #Common SGS Response header check def check_response_headers(self, response): self.assertEqual(response.content_type, "application/json") self.assertEqual(len(response.json), 1) self.assertIn('data',response.json) def test_list_resource_types(self): response = self.test_app.get('/ion-service/list_resource_types') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) expected_type_list = getextends('Resource') self.assertEqual(len(response.json['data'][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json['data'][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get('/ion-service/list_resource_types?type=InformationResource') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) expected_type_list = getextends('InformationResource') self.assertEqual(len(response.json['data'][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json['data'][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get('/ion-service/list_resource_types?type=TaskableResource') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) expected_type_list = getextends('TaskableResource') self.assertEqual(len(response.json['data'][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json['data'][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get('/ion-service/list_resource_types?type=MyFakeResource') self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn('KeyError', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_EXCEPTION]) self.assertIn('MyFakeResource', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone(response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def create_data_product_resource(self): data_product_create_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "create", "params": { "object": { "type_": "DataProduct", "provider_project": "Integration Test", "lcstate": "DRAFT", "description": "A test data product", "name": "TestDataProduct", "contact": { "name": "Test User", "phone": "858-555-1212", "city": "San Diego", "postalcode": "92093" } } } } } response = self.test_app.post('/ion-service/resource_registry/create', {'payload': json.dumps(data_product_create_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2 ) data_product_id = convert_unicode(response_data[0]) return data_product_id def delete_data_product_resource(self, data_product_id): data_product_delete_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "delete", "params": { "object_id": data_product_id } } } response = self.test_app.post('/ion-service/resource_registry/delete', {'payload': simplejson.dumps(data_product_delete_request) }) self.check_response_headers(response) return response def test_resource_registry_operations_through_gateway(self): response = self.test_app.get('/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data),2 ) self.assertEqual(len(response_data[0]), 0 ) data_product_id = self.create_data_product_resource() data_product_read_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "read", "params": { "object_id": data_product_id } } } response = self.test_app.post('/ion-service/resource_registry/read', {'payload': simplejson.dumps(data_product_read_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) data_product_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) #modify some fields in the data for testing update data_product_obj['description'] = 'An updated description for test data' data_product_obj['contact']['postalcode'] = '12345' data_product_update_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "update", "params": { "object": data_product_obj } } } response = self.test_app.post('/ion-service/resource_registry/update', {'payload': simplejson.dumps(data_product_update_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response = self.test_app.post('/ion-service/resource_registry/read', {'payload': simplejson.dumps(data_product_read_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) updated_data_product_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) self.assertEqual(updated_data_product_obj['description'], 'An updated description for test data', ) self.assertEqual(updated_data_product_obj['contact']['postalcode'], '12345') differ = DictDiffer(updated_data_product_obj, data_product_obj) self.assertEqual(len(differ.changed()), 2) # Only the _rev and ts_updated fields should be different after an update response = self.test_app.get('/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data),2 ) self.assertEqual(len(response_data[0]), 1 ) response = self.delete_data_product_resource(data_product_id) self.assertIsNone(response.json['data'][GATEWAY_RESPONSE]) response = self.test_app.post('/ion-service/resource_registry/read', {'payload': simplejson.dumps(data_product_read_request) }) self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn('does not exist', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) response = self.test_app.get('/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data),2 ) self.assertEqual(len(response_data[0]), 0 ) response = self.delete_data_product_resource(data_product_id) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn('does not exist', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone(response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def test_get_resource_schema(self): response = self.test_app.get('/ion-service/resource_type_schema/DataProduct') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) data_product_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) self.assertTrue(isinstance(data_product_obj, dict)) response = self.test_app.get('/ion-service/resource_type_schema/DataProduct123') self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn('No matching class found', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone(response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def test_get_resource(self): data_product_id = self.create_data_product_resource() response = self.test_app.get('/ion-service/rest/resource/' + data_product_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertNotIn('does not exist', response_data) data_product_obj = convert_unicode(response_data) self.assertEqual(data_product_id, data_product_obj['_id']) self.delete_data_product_resource(data_product_id) def test_list_resources_by_type(self): data_product_id = self.create_data_product_resource() response = self.test_app.get('/ion-service/rest/find_resources/DataProduct') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data),1 ) data_product_obj = convert_unicode(response_data[0]) self.assertEqual(data_product_id, data_product_obj['_id']) self.delete_data_product_resource(data_product_id)
class TestServiceGatewayServiceInt(IonIntegrationTestCase): def setUp(self): # Start container self._start_container() self.container.start_rel_from_url('res/deploy/r2coi.yml') # Now create client to service self.service_gateway_service = ServiceGatewayServiceClient( node=self.container.node) log.debug('stopping Gateway web server') # Stop the web server as it is not needed. self.service_gateway_service.stop_service() self.test_app = TestApp(service_gateway_app) def tearDown(self): self._stop_container() #Common SGS Response header check def check_response_headers(self, response): self.assertEqual(response.content_type, "application/json") self.assertEqual(len(response.json), 1) self.assertIn('data', response.json) def test_list_resource_types(self): response = self.test_app.get('/ion-service/list_resource_types') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) expected_type_list = getextends('Resource') self.assertEqual(len(response.json['data'][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json['data'][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get( '/ion-service/list_resource_types?type=InformationResource') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) expected_type_list = getextends('InformationResource') self.assertEqual(len(response.json['data'][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json['data'][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get( '/ion-service/list_resource_types?type=TaskableResource') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) expected_type_list = getextends('TaskableResource') self.assertEqual(len(response.json['data'][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json['data'][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get( '/ion-service/list_resource_types?type=MyFakeResource') self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn( 'KeyError', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_EXCEPTION]) self.assertIn( 'MyFakeResource', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone( response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def create_data_product_resource(self): data_product_create_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "create", "params": { "object": { "type_": "DataProduct", "lcstate": "DRAFT", "description": DATA_PRODUCT_DESCRIPTION, "name": DATA_PRODUCT_NAME } } } } response = self.test_app.post( '/ion-service/resource_registry/create', {'payload': simplejson.dumps(data_product_create_request)}) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) data_product_id = convert_unicode(response_data[0]) return data_product_id def delete_data_product_resource(self, data_product_id): data_product_delete_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "delete", "params": { "object_id": data_product_id } } } response = self.test_app.post( '/ion-service/resource_registry/delete', {'payload': simplejson.dumps(data_product_delete_request)}) self.check_response_headers(response) return response @attr('SMOKE') def test_anonymous_resource_registry_operations_through_gateway(self): """ This test ensures that requests make through the service gateway through messaging to the Resource Registry and back; including the support of unicode characters. @return: """ response = self.test_app.get( '/ion-service/resource_registry/find_resources?name=' + convert_unicode(DATA_PRODUCT_NAME) + '&id_only=True') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 0) data_product_id = self.create_data_product_resource() data_product_read_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "read", "params": { "object_id": data_product_id } } } response = self.test_app.post( '/ion-service/resource_registry/read', {'payload': simplejson.dumps(data_product_read_request)}) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) data_product_obj = convert_unicode( response.json['data'][GATEWAY_RESPONSE]) #Verify the the name and description fields containing unicode characters match all the way through couch and the messaging self.assertEqual(data_product_obj['name'], convert_unicode(DATA_PRODUCT_NAME)) self.assertEqual(data_product_obj['description'], convert_unicode(DATA_PRODUCT_DESCRIPTION)) updated_description_text = data_product_obj[ 'description'] + '---Updated!!' #modify some fields in the data for testing update data_product_obj['description'] = updated_description_text data_product_update_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "update", "params": { "object": data_product_obj } } } response = self.test_app.post( '/ion-service/resource_registry/update', {'payload': simplejson.dumps(data_product_update_request)}) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response = self.test_app.post( '/ion-service/resource_registry/read', {'payload': simplejson.dumps(data_product_read_request)}) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) updated_data_product_obj = convert_unicode( response.json['data'][GATEWAY_RESPONSE]) self.assertEqual(updated_data_product_obj['description'], updated_description_text) differ = DictDiffer(updated_data_product_obj, data_product_obj) self.assertEqual( len(differ.changed()), 2 ) # Only the _rev and ts_updated fields should be different after an update response = self.test_app.get( '/ion-service/resource_registry/find_resources?name=' + convert_unicode(DATA_PRODUCT_NAME) + '&id_only=True') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 1) response = self.delete_data_product_resource(data_product_id) self.assertIsNone(response.json['data'][GATEWAY_RESPONSE]) response = self.test_app.post( '/ion-service/resource_registry/read', {'payload': simplejson.dumps(data_product_read_request)}) self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn( 'does not exist', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) response = self.test_app.get( '/ion-service/resource_registry/find_resources?name=' + convert_unicode(DATA_PRODUCT_NAME) + '&id_only=True') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 0) response = self.delete_data_product_resource(data_product_id) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn( 'does not exist', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone( response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def test_non_anonymous_resource_registry_operations_through_gateway(self): id_client = IdentityManagementServiceClient(node=self.container.node) actor_id, valid_until, registered = id_client.signon( USER1_CERTIFICATE, True) response = self.test_app.get( '/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 0) id_client.delete_actor_identity(actor_id) def test_get_resource_schema(self): response = self.test_app.get('/ion-service/resource_type_schema/Org') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) org_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) self.assertTrue(isinstance(org_obj, dict)) self.assertIn('object', org_obj) self.assertIn('schemas', org_obj) self.assertIn('Org', org_obj['schemas']) self.assertIn('OrgTypeEnum', org_obj['schemas']) self.assertIn('Institution', org_obj['schemas']) response = self.test_app.get( '/ion-service/resource_type_schema/InstrumentModel') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) model_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) self.assertTrue(isinstance(org_obj, dict)) self.assertIn('object', model_obj) self.assertIn('schemas', model_obj) self.assertIn('InstrumentModel', model_obj['schemas']) self.assertIn('PrimaryInterface', model_obj['schemas']) response = self.test_app.get( '/ion-service/resource_type_schema/DataProduct') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) data_product_obj = convert_unicode( response.json['data'][GATEWAY_RESPONSE]) self.assertTrue(isinstance(data_product_obj, dict)) self.assertIn('object', data_product_obj) self.assertIn('schemas', data_product_obj) self.assertIn('DataProduct', data_product_obj['schemas']) self.assertIn('GeospatialBounds', data_product_obj['schemas']) self.assertIn('GeospatialCoordinateReferenceSystem', data_product_obj['schemas']) response = self.test_app.get( '/ion-service/resource_type_schema/DataProduct123') self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn( 'No matching class found', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone( response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def test_get_resource(self): data_product_id = self.create_data_product_resource() response = self.test_app.get('/ion-resources/resource/' + data_product_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertNotIn('does not exist', response_data) data_product_obj = convert_unicode(response_data) self.assertEqual(data_product_id, data_product_obj['_id']) self.delete_data_product_resource(data_product_id) def test_list_resources_by_type(self): data_product_id = self.create_data_product_resource() response = self.test_app.get( '/ion-resources/find_resources/DataProduct') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 1) data_product_obj = convert_unicode(response_data[0]) self.assertEqual(data_product_id, data_product_obj['_id']) self.delete_data_product_resource(data_product_id) def test_list_org_roles(self): response = self.test_app.get( '/ion-service/resource_registry/find_resources?name=ionsystem') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] actor_id = response_data[0][0]['_id'] response = self.test_app.get('/ion-service/org_roles/' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertIn('ION', response_data) self.assertEqual(len(response_data['ION']), 3) self.assertIn('ION_MANAGER', response_data['ION']) self.assertIn('ORG_MANAGER', response_data['ION']) self.assertIn('ORG_MEMBER', response_data['ION']) def test_user_role_cache(self): #Create a user id_client = IdentityManagementServiceClient(node=self.container.node) actor_id, valid_until, registered = id_client.signon( USER1_CERTIFICATE, True) #Make a request with this new user to get it into the cache response = self.test_app.get( '/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) #Check the contents of the user role cache for this user service_gateway_user_cache = self.container.proc_manager.procs_by_name[ 'service_gateway'].user_data_cache self.assertEqual(service_gateway_user_cache.has_key(actor_id), True) role_header = service_gateway_user_cache.get(actor_id) self.assertIn('ION', role_header) self.assertEqual(len(role_header['ION']), 1) self.assertIn('ORG_MEMBER', role_header['ION']) org_client = OrgManagementServiceClient(node=self.container.node) ion_org = org_client.find_org() manager_role = org_client.find_org_role_by_name( org_id=ion_org._id, role_name='ORG_MANAGER') org_client.grant_role(org_id=ion_org._id, user_id=actor_id, role_name='ORG_MANAGER') #Just allow some time for event processing on slower platforms gevent.sleep(2) #The user should be evicted from the cache due to a change in roles self.assertEqual(service_gateway_user_cache.has_key(actor_id), False) #Do it again to check for new roles response = self.test_app.get( '/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) #Check the contents of the user role cache for this user self.assertEqual(service_gateway_user_cache.has_key(actor_id), True) role_header = service_gateway_user_cache.get(actor_id) self.assertIn('ION', role_header) self.assertEqual(len(role_header['ION']), 2) self.assertIn('ORG_MEMBER', role_header['ION']) self.assertIn('ORG_MANAGER', role_header['ION']) #Now flush the user_role_cache and make sure it was flushed event_publisher = EventPublisher() event_publisher.publish_event(event_type=OT.UserRoleCacheResetEvent) #Just allow some time for event processing on slower platforms gevent.sleep(2) self.assertEqual(service_gateway_user_cache.has_key(actor_id), False) self.assertEqual(service_gateway_user_cache.size(), 0) #Change the role once again and see if it is there again org_client.revoke_role(org_id=ion_org._id, user_id=actor_id, role_name='ORG_MANAGER') #Just allow some time for event processing on slower platforms gevent.sleep(2) #The user should still not be there self.assertEqual(service_gateway_user_cache.has_key(actor_id), False) #Do it again to check for new roles response = self.test_app.get( '/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) #Check the contents of the user role cache for this user self.assertEqual(service_gateway_user_cache.has_key(actor_id), True) role_header = service_gateway_user_cache.get(actor_id) self.assertIn('ION', role_header) self.assertEqual(len(role_header['ION']), 1) self.assertIn('ORG_MEMBER', role_header['ION']) id_client.delete_actor_identity(actor_id)
class TestServiceGatewayServiceInt(IonIntegrationTestCase): def setUp(self): # Start container self._start_container() self.container.start_rel_from_url('res/deploy/r2deploy.yml') # Now create client to service self.service_gateway_service = ServiceGatewayServiceClient( node=self.container.node) log.debug('stopping Gateway web server') # Stop the web server as it is not needed. self.service_gateway_service.stop_service() self.test_app = TestApp(service_gateway_app) def tearDown(self): self._stop_container() #Common SGS Response header check def check_response_headers(self, response): self.assertEqual(response.content_type, "application/json") self.assertEqual(len(response.json), 1) self.assertIn('data', response.json) def test_list_resource_types(self): response = self.test_app.get('/ion-service/list_resource_types') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) expected_type_list = getextends('Resource') self.assertEqual(len(response.json['data'][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json['data'][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get( '/ion-service/list_resource_types?type=InformationResource') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) expected_type_list = getextends('InformationResource') self.assertEqual(len(response.json['data'][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json['data'][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get( '/ion-service/list_resource_types?type=TaskableResource') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) expected_type_list = getextends('TaskableResource') self.assertEqual(len(response.json['data'][GATEWAY_RESPONSE]), len(expected_type_list)) result_set = set(response.json['data'][GATEWAY_RESPONSE]) expected_type_set = set(expected_type_list) intersect_result = expected_type_set.intersection(result_set) self.assertEqual(len(intersect_result), len(expected_type_list)) response = self.test_app.get( '/ion-service/list_resource_types?type=MyFakeResource') self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn( 'KeyError', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_EXCEPTION]) self.assertIn( 'MyFakeResource', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone( response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def create_data_product_resource(self): geospatial_bounds = { "geospatial_latitude_limit_north": 1.0, "geospatial_latitude_limit_south": 1.0, "geospatial_longitude_limit_east": 1.0, "geospatial_longitude_limit_west": 1.0, "geospatial_vertical_min": 1.0, "geospatial_vertical_max": 1.0 } data_product_create_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "create", "params": { "object": { "type_": "DataProduct", "lcstate": "DRAFT", "description": DATA_PRODUCT_DESCRIPTION, "name": DATA_PRODUCT_NAME, 'geospatial_bounds': geospatial_bounds, 'temporal_domain': TEMPORAL_DOMAIN } } } } response = self.test_app.post( '/ion-service/resource_registry/create', {'payload': simplejson.dumps(data_product_create_request)}) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) data_product_id = convert_unicode(response_data[0]) return data_product_id def create_data_product_resource_full(self): geospatial_bounds = { "geospatial_latitude_limit_north": 1.0, "geospatial_latitude_limit_south": 1.0, "geospatial_longitude_limit_east": 1.0, "geospatial_longitude_limit_west": 1.0, "geospatial_vertical_min": 1.0, "geospatial_vertical_max": 1.0 } #create a paramter dictionary the a stream definition for this data product DICTIONARY_NAME = 'ctd_parsed_param_dict' response = self.test_app.get( '/ion-service/resource_registry/find_resources?name=' + convert_unicode(DICTIONARY_NAME) + '&id_only=True&user_id=123abc456') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] param_dictionary_id = convert_unicode(response_data[0]) test = str(param_dictionary_id[0]) log.debug( 'create_data_product_resource_full param_dictionary_id: %s', param_dictionary_id) log.debug('create_data_product_resource_full test: %s', test) response = self.test_app.get( '/ion-service/pubsub_management/create_stream_definition?name=CTDData¶meter_dictionary_id=' + convert_unicode(param_dictionary_id[0])) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] log.debug('create_data_product_resource_full response_data: %s', response_data) stream_definition_id = convert_unicode(response_data) log.debug( 'create_data_product_resource_full stream_definition_id: %s', stream_definition_id) data_product_create_request = { "serviceRequest": { "serviceName": "data_product_management", "serviceOp": "create_data_product", "params": { "data_product": { "type_": "DataProduct", "lcstate": "DRAFT", "description": DATA_PRODUCT_DESCRIPTION, "name": DATA_PRODUCT_NAME, 'geospatial_bounds': geospatial_bounds, 'temporal_domain': TEMPORAL_DOMAIN }, "stream_definition_id": stream_definition_id } } } response = self.test_app.post( '/ion-service/data_product_management/create_data_product', {'payload': simplejson.dumps(data_product_create_request)}) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] log.debug( 'create_data_product_resource_full create_data_product response_data: %s', response_data) #self.assertEqual(len(response_data), 2 ) data_product_id = convert_unicode(response_data) return data_product_id def delete_data_product_resource(self, data_product_id): data_product_delete_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "delete", "params": { "object_id": data_product_id } } } response = self.test_app.post( '/ion-service/resource_registry/delete', {'payload': simplejson.dumps(data_product_delete_request)}) self.check_response_headers(response) return response def create_policy_resource(self): policy_create_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "create", "params": { "object": { "definition": {}, "name": POLICY_NAME, "description": POLICY_DESCRIPTION, "lcstate": "DRAFT", "required": True, "enabled": True, "type_": "Policy", "policy_type": { "policy_rule": POLICY_RULE, "service_name": "user_notification", "type_": "ServiceAccessPolicy" } } } } } response = self.test_app.post( '/ion-service/resource_registry/create', {'payload': simplejson.dumps(policy_create_request)}) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) policy_id = convert_unicode(response_data[0]) return policy_id @attr('SMOKE') def test_anonymous_resource_registry_operations_through_gateway(self): """ This test ensures that requests make through the service gateway through messaging to the Resource Registry and back; including the support of unicode characters. @return: """ response = self.test_app.get( '/ion-service/resource_registry/find_resources?name=' + convert_unicode(DATA_PRODUCT_NAME) + '&id_only=True&user_id=123abc456') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 0) data_product_id = self.create_data_product_resource() data_product_read_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "read", "params": { "object_id": data_product_id } } } response = self.test_app.post( '/ion-service/resource_registry/read', {'payload': simplejson.dumps(data_product_read_request)}) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) data_product_obj = convert_unicode( response.json['data'][GATEWAY_RESPONSE]) #Verify the the name and description fields containing unicode characters match all the way through couch and the messaging self.assertEqual(data_product_obj['name'], convert_unicode(DATA_PRODUCT_NAME)) self.assertEqual(data_product_obj['description'], convert_unicode(DATA_PRODUCT_DESCRIPTION)) updated_description_text = data_product_obj[ 'description'] + '---Updated!!' #modify some fields in the data for testing update data_product_obj['description'] = updated_description_text data_product_update_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "update", "params": { "object": data_product_obj } } } response = self.test_app.post( '/ion-service/resource_registry/update', {'payload': simplejson.dumps(data_product_update_request)}) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response = self.test_app.post( '/ion-service/resource_registry/read', {'payload': simplejson.dumps(data_product_read_request)}) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) updated_data_product_obj = convert_unicode( response.json['data'][GATEWAY_RESPONSE]) self.assertEqual(updated_data_product_obj['description'], updated_description_text) differ = DictDiffer(updated_data_product_obj, data_product_obj) self.assertEqual( len(differ.changed()), 2 ) # Only the _rev and ts_updated fields should be different after an update response = self.test_app.get( '/ion-service/resource_registry/find_resources?name=' + convert_unicode(DATA_PRODUCT_NAME) + '&id_only=True') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 1) response = self.delete_data_product_resource(data_product_id) self.assertIsNone(response.json['data'][GATEWAY_RESPONSE]) response = self.test_app.post( '/ion-service/resource_registry/read', {'payload': simplejson.dumps(data_product_read_request)}) self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn( 'does not exist', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) response = self.test_app.get( '/ion-service/resource_registry/find_resources?name=' + convert_unicode(DATA_PRODUCT_NAME) + '&id_only=True') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 0) response = self.delete_data_product_resource(data_product_id) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn( 'does not exist', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone( response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) #Now try creating a policy object which has an internal object of a different type policy_id = self.create_policy_resource() policy_read_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "read", "params": { "object_id": policy_id } } } response = self.test_app.post( '/ion-service/resource_registry/read', {'payload': simplejson.dumps(policy_read_request)}) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) policy_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) #Verify the the name and description fields containing unicode characters match all the way through couch and the messaging self.assertEqual(policy_obj['name'], convert_unicode(POLICY_NAME)) self.assertEqual(policy_obj['description'], convert_unicode(POLICY_DESCRIPTION)) self.assertEqual(policy_obj['policy_type']['policy_rule'], convert_unicode(POLICY_RULE)) updated_policy_rule = policy_obj['policy_type'][ 'policy_rule'] + '---Updated!!' #modify some fields in the data for testing update policy_obj['policy_type']['policy_rule'] = updated_policy_rule policy_update_request = { "serviceRequest": { "serviceName": "resource_registry", "serviceOp": "update", "params": { "object": policy_obj } } } response = self.test_app.post( '/ion-service/resource_registry/update', {'payload': simplejson.dumps(policy_update_request)}) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response = self.test_app.post( '/ion-service/resource_registry/read', {'payload': simplejson.dumps(policy_read_request)}) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) updated_policy_obj = convert_unicode( response.json['data'][GATEWAY_RESPONSE]) self.assertEqual(updated_policy_obj['policy_type']['policy_rule'], updated_policy_rule) #Now testing the generic get_resource_extension with optional user_id parameter response = self.test_app.get( '/ion-service/resource_registry/find_resources?name=ionsystem') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] actor_id = response_data[0][0]['_id'] response = self.test_app.get( '/ion-service/resource_registry/get_resource_extension?resource_id=' + actor_id + '&resource_extension=TestExtendedInformationResource') self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(convert_unicode(response_data['user_id']), '') response = self.test_app.get( '/ion-service/resource_registry/get_resource_extension?resource_id=' + actor_id + '&resource_extension=TestExtendedInformationResource&user_id=123abc456' ) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(convert_unicode(response_data['user_id']), '123abc456') def test_non_anonymous_resource_registry_operations_through_gateway(self): id_client = IdentityManagementServiceClient(node=self.container.node) actor_id, valid_until, registered = id_client.signon( USER1_CERTIFICATE, True) response = self.test_app.get( '/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 2) self.assertEqual(len(response_data[0]), 0) id_client.delete_actor_identity(actor_id) def test_get_resource_schema(self): response = self.test_app.get('/ion-service/resource_type_schema/Org') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) org_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) self.assertTrue(isinstance(org_obj, dict)) self.assertIn('object', org_obj) self.assertIn('schemas', org_obj) self.assertIn('Org', org_obj['schemas']) self.assertIn('OrgTypeEnum', org_obj['schemas']) self.assertIn('Institution', org_obj['schemas']) response = self.test_app.get( '/ion-service/resource_type_schema/InstrumentModel') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) model_obj = convert_unicode(response.json['data'][GATEWAY_RESPONSE]) self.assertTrue(isinstance(org_obj, dict)) self.assertIn('object', model_obj) self.assertIn('schemas', model_obj) self.assertIn('InstrumentModel', model_obj['schemas']) self.assertIn('PrimaryInterface', model_obj['schemas']) response = self.test_app.get( '/ion-service/resource_type_schema/DataProduct') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) data_product_obj = convert_unicode( response.json['data'][GATEWAY_RESPONSE]) self.assertTrue(isinstance(data_product_obj, dict)) self.assertIn('object', data_product_obj) self.assertIn('schemas', data_product_obj) self.assertIn('DataProduct', data_product_obj['schemas']) self.assertIn('GeospatialBounds', data_product_obj['schemas']) self.assertIn('GeospatialCoordinateReferenceSystem', data_product_obj['schemas']) response = self.test_app.get( '/ion-service/resource_type_schema/DataProduct123') self.check_response_headers(response) self.assertIn(GATEWAY_ERROR, response.json['data']) self.assertIn( 'No matching class found', response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_MESSAGE]) self.assertIsNotNone( response.json['data'][GATEWAY_ERROR][GATEWAY_ERROR_TRACE]) def test_get_resource(self): data_product_id = self.create_data_product_resource() response = self.test_app.get('/ion-resources/resource/' + data_product_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertNotIn('does not exist', response_data) data_product_obj = convert_unicode(response_data) self.assertEqual(data_product_id, data_product_obj['_id']) self.delete_data_product_resource(data_product_id) def test_list_resources_by_type(self): data_product_id = self.create_data_product_resource() response = self.test_app.get( '/ion-resources/find_resources/DataProduct') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertEqual(len(response_data), 1) data_product_obj = convert_unicode(response_data[0]) self.assertEqual(data_product_id, data_product_obj['_id']) self.delete_data_product_resource(data_product_id) def test_list_org_roles(self): response = self.test_app.get( '/ion-service/resource_registry/find_resources?name=ionsystem') self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] actor_id = response_data[0][0]['_id'] response = self.test_app.get('/ion-service/org_roles/' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) response_data = response.json['data'][GATEWAY_RESPONSE] self.assertIn('ION', response_data) self.assertEqual(len(response_data['ION']), 3) self.assertIn('ION_MANAGER', response_data['ION']) self.assertIn('ORG_MANAGER', response_data['ION']) self.assertIn('ORG_MEMBER', response_data['ION']) def test_user_role_cache(self): #Create a user id_client = IdentityManagementServiceClient(node=self.container.node) actor_id, valid_until, registered = id_client.signon( USER1_CERTIFICATE, True) #Make a request with this new user to get it into the cache response = self.test_app.get( '/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) #Check the contents of the user role cache for this user service_gateway_user_role_cache = self.container.proc_manager.procs_by_name[ 'service_gateway'].user_role_cache self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), True) role_header = service_gateway_user_role_cache.get(actor_id) self.assertIn('ION', role_header) self.assertEqual(len(role_header['ION']), 1) self.assertIn('ORG_MEMBER', role_header['ION']) org_client = OrgManagementServiceClient(node=self.container.node) ion_org = org_client.find_org() manager_role = org_client.find_org_role_by_name( org_id=ion_org._id, role_name='ORG_MANAGER') org_client.grant_role(org_id=ion_org._id, actor_id=actor_id, role_name='ORG_MANAGER') #Just allow some time for event processing on slower platforms gevent.sleep(2) #The user should be evicted from the cache due to a change in roles self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), False) #Do it again to check for new roles response = self.test_app.get( '/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) #Check the contents of the user role cache for this user self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), True) role_header = service_gateway_user_role_cache.get(actor_id) self.assertIn('ION', role_header) self.assertEqual(len(role_header['ION']), 2) self.assertIn('ORG_MEMBER', role_header['ION']) self.assertIn('ORG_MANAGER', role_header['ION']) #Now flush the user_role_cache and make sure it was flushed event_publisher = EventPublisher() event_publisher.publish_event(event_type=OT.UserRoleCacheResetEvent) #Just allow some time for event processing on slower platforms gevent.sleep(2) self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), False) self.assertEqual(service_gateway_user_role_cache.size(), 0) #Change the role once again and see if it is there again org_client.revoke_role(org_id=ion_org._id, actor_id=actor_id, role_name='ORG_MANAGER') #Just allow some time for event processing on slower platforms gevent.sleep(2) #The user should still not be there self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), False) #Do it again to check for new roles response = self.test_app.get( '/ion-service/resource_registry/find_resources?name=TestDataProduct&id_only=True&requester=' + actor_id) self.check_response_headers(response) self.assertIn(GATEWAY_RESPONSE, response.json['data']) #Check the contents of the user role cache for this user self.assertEqual(service_gateway_user_role_cache.has_key(actor_id), True) role_header = service_gateway_user_role_cache.get(actor_id) self.assertIn('ION', role_header) self.assertEqual(len(role_header['ION']), 1) self.assertIn('ORG_MEMBER', role_header['ION']) id_client.delete_actor_identity(actor_id) def test_data_provenance_retrieve(self): data_product_id = self.create_data_product_resource_full() get_parameter_provenance_visualization_image_request = { "serviceRequest": { "serviceName": "service_gateway", "serviceOp": "get_parameter_provenance_visualization_image", "params": { "data_product_id": data_product_id, "parameter_name": "temp" } } } #call the gateway service intermeditary operation to get the image from the data product mgmt svc response = self.test_app.post( '/ion-service/get_parameter_provenance_visualization_image', { 'payload': simplejson.dumps( get_parameter_provenance_visualization_image_request) }) #log.debug('test_data_provenance_retrieve response: %s', response) self.assertIsNotNone(response)