| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.atlas.web.integration; |
| |
| import com.sun.jersey.api.client.ClientResponse; |
| import com.sun.jersey.core.util.MultivaluedMapImpl; |
| import org.apache.atlas.AtlasClient; |
| import org.apache.atlas.AtlasServiceException; |
| import org.apache.atlas.model.typedef.AtlasBaseTypeDef; |
| import org.apache.atlas.v1.model.instance.Id; |
| import org.apache.atlas.v1.model.instance.Referenceable; |
| import org.apache.atlas.v1.model.instance.Struct; |
| import org.apache.atlas.v1.model.typedef.*; |
| import org.apache.atlas.v1.typesystem.types.utils.TypesUtil; |
| import org.codehaus.jettison.json.JSONArray; |
| import org.codehaus.jettison.json.JSONObject; |
| import org.testng.Assert; |
| import org.testng.annotations.BeforeClass; |
| import org.testng.annotations.Test; |
| |
| import javax.ws.rs.core.MultivaluedMap; |
| import java.util.Collections; |
| import java.util.List; |
| |
| import static org.testng.Assert.assertEquals; |
| import static org.testng.Assert.assertNotNull; |
| import static org.testng.Assert.fail; |
| |
| /** |
| * Search Integration Tests. |
| */ |
| public class MetadataDiscoveryJerseyResourceIT extends BaseResourceIT { |
| |
| private String tagName; |
| private String dbName; |
| |
| @BeforeClass |
| public void setUp() throws Exception { |
| super.setUp(); |
| dbName = "db"+randomString(); |
| createTypes(); |
| createInstance( createHiveDBInstanceV1(dbName) ); |
| } |
| |
| @Test |
| public void testSearchByDSL() throws Exception { |
| String dslQuery = "from "+ DATABASE_TYPE + " name=\"" + dbName + "\""; |
| MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); |
| queryParams.add("query", dslQuery); |
| JSONObject response = atlasClientV1.callAPIWithQueryParams(AtlasClient.API_V1.SEARCH_DSL, queryParams); |
| |
| Assert.assertNotNull(response); |
| Assert.assertNotNull(response.get(AtlasClient.REQUEST_ID)); |
| |
| assertEquals(response.getString("query"), dslQuery); |
| assertEquals(response.getString("queryType"), "dsl"); |
| |
| JSONArray results = response.getJSONArray(AtlasClient.RESULTS); |
| assertNotNull(results); |
| assertEquals(results.length(), 1); |
| |
| int numRows = response.getInt(AtlasClient.COUNT); |
| assertEquals(numRows, 1); |
| } |
| |
| @Test |
| public void testSearchDSLLimits() throws Exception { |
| |
| //search without new parameters of limit and offset should work |
| String dslQuery = "from "+ DATABASE_TYPE + " name=\"" + dbName + "\""; |
| MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); |
| queryParams.add("query", dslQuery); |
| JSONObject response = atlasClientV1.callAPIWithQueryParams(AtlasClient.API_V1.SEARCH_DSL, queryParams); |
| assertNotNull(response); |
| |
| //higher limit, all results returned |
| JSONArray results = atlasClientV1.searchByDSL(dslQuery, 10, 0); |
| assertEquals(results.length(), 1); |
| |
| //default limit and offset -1, all results returned |
| results = atlasClientV1.searchByDSL(dslQuery, -1, -1); |
| assertEquals(results.length(), 1); |
| |
| //uses the limit parameter passed |
| results = atlasClientV1.searchByDSL(dslQuery, 1, 0); |
| assertEquals(results.length(), 1); |
| |
| //uses the offset parameter passed |
| results = atlasClientV1.searchByDSL(dslQuery, 10, 1); |
| assertEquals(results.length(), 0); |
| |
| //limit > 0 |
| try { |
| atlasClientV1.searchByDSL(dslQuery, 0, 10); |
| fail("Expected BAD_REQUEST"); |
| } catch (AtlasServiceException e) { |
| assertEquals(e.getStatus(), ClientResponse.Status.BAD_REQUEST, "Got " + e.getStatus()); |
| } |
| |
| //limit > maxlimit |
| try { |
| atlasClientV1.searchByDSL(dslQuery, Integer.MAX_VALUE, 10); |
| fail("Expected BAD_REQUEST"); |
| } catch (AtlasServiceException e) { |
| assertEquals(e.getStatus(), ClientResponse.Status.BAD_REQUEST, "Got " + e.getStatus()); |
| } |
| |
| //offset >= 0 |
| try { |
| atlasClientV1.searchByDSL(dslQuery, 10, -2); |
| fail("Expected BAD_REQUEST"); |
| } catch (AtlasServiceException e) { |
| assertEquals(e.getStatus(), ClientResponse.Status.BAD_REQUEST, "Got " + e.getStatus()); |
| } |
| } |
| |
| @Test(expectedExceptions = AtlasServiceException.class) |
| public void testSearchByDSLForUnknownType() throws Exception { |
| String dslQuery = "from blah"; |
| MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); |
| queryParams.add("query", dslQuery); |
| atlasClientV1.callAPIWithQueryParams(AtlasClient.API_V1.SEARCH_DSL, queryParams); |
| } |
| |
| @Test |
| public void testSearchUsingGremlin() throws Exception { |
| String query = "g.V.has('type', '" + BaseResourceIT.HIVE_TABLE_TYPE + "').toList()"; |
| MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); |
| queryParams.add("query", query); |
| |
| JSONObject response = atlasClientV1.callAPIWithQueryParams(AtlasClient.API_V1.GREMLIN_SEARCH, queryParams); |
| |
| assertNotNull(response); |
| assertNotNull(response.get(AtlasClient.REQUEST_ID)); |
| |
| assertEquals(response.getString("query"), query); |
| assertEquals(response.getString("queryType"), "gremlin"); |
| } |
| |
| @Test |
| public void testSearchUsingDSL() throws Exception { |
| //String query = "from dsl_test_type"; |
| String query = "from "+ DATABASE_TYPE + " name=\"" + dbName +"\""; |
| MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); |
| queryParams.add("query", query); |
| JSONObject response = atlasClientV1.callAPIWithQueryParams(AtlasClient.API_V1.SEARCH, queryParams); |
| |
| Assert.assertNotNull(response); |
| Assert.assertNotNull(response.get(AtlasClient.REQUEST_ID)); |
| |
| assertEquals(response.getString("query"), query); |
| assertEquals(response.getString("queryType"), "dsl"); |
| } |
| |
| @Test |
| public void testSearchFullTextOnDSLFailure() throws Exception { |
| String query = "*"; |
| MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); |
| queryParams.add("query", query); |
| JSONObject response = atlasClientV1.callAPIWithQueryParams(AtlasClient.API_V1.SEARCH, queryParams); |
| |
| Assert.assertNotNull(response); |
| Assert.assertNotNull(response.get(AtlasClient.REQUEST_ID)); |
| |
| assertEquals(response.getString("query"), query); |
| assertEquals(response.getString("queryType"), "full-text"); |
| } |
| |
| @Test(dependsOnMethods = "testSearchDSLLimits") |
| public void testSearchUsingFullText() throws Exception { |
| JSONObject response = atlasClientV1.searchByFullText(dbName, 10, 0); |
| assertNotNull(response.get(AtlasClient.REQUEST_ID)); |
| |
| assertEquals(response.getString("query"), dbName); |
| assertEquals(response.getString("queryType"), "full-text"); |
| |
| JSONArray results = response.getJSONArray(AtlasClient.RESULTS); |
| assertEquals(results.length(), 1, "Results: " + results); |
| |
| JSONObject row = results.getJSONObject(0); |
| assertNotNull(row.get("guid")); |
| assertEquals(row.getString("typeName"), DATABASE_TYPE); |
| assertNotNull(row.get("score")); |
| |
| int numRows = response.getInt(AtlasClient.COUNT); |
| assertEquals(numRows, 1); |
| |
| //API works without limit and offset |
| String query = dbName; |
| MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); |
| queryParams.add("query", query); |
| response = atlasClientV1.callAPIWithQueryParams(AtlasClient.API_V1.SEARCH_FULL_TEXT, queryParams); |
| results = response.getJSONArray(AtlasClient.RESULTS); |
| assertEquals(results.length(), 1); |
| |
| //verify passed in limits and offsets are used |
| //higher limit and 0 offset returns all results |
| results = atlasClientV1.searchByFullText(query, 10, 0).getJSONArray(AtlasClient.RESULTS); |
| assertEquals(results.length(), 1); |
| |
| //offset is used |
| results = atlasClientV1.searchByFullText(query, 10, 1).getJSONArray(AtlasClient.RESULTS); |
| assertEquals(results.length(), 0); |
| |
| //limit is used |
| results = atlasClientV1.searchByFullText(query, 1, 0).getJSONArray(AtlasClient.RESULTS); |
| assertEquals(results.length(), 1); |
| |
| //higher offset returns 0 results |
| results = atlasClientV1.searchByFullText(query, 1, 2).getJSONArray(AtlasClient.RESULTS); |
| assertEquals(results.length(), 0); |
| } |
| |
| private void createTypes() throws Exception { |
| createTypeDefinitionsV1(); |
| |
| ClassTypeDefinition dslTestTypeDefinition = TypesUtil |
| .createClassTypeDef("dsl_test_type", null, Collections.<String>emptySet(), |
| TypesUtil.createUniqueRequiredAttrDef("name", AtlasBaseTypeDef.ATLAS_TYPE_STRING), |
| TypesUtil.createRequiredAttrDef("description", AtlasBaseTypeDef.ATLAS_TYPE_STRING)); |
| |
| TraitTypeDefinition classificationTraitDefinition = TypesUtil |
| .createTraitTypeDef("Classification", null, Collections.<String>emptySet(), |
| TypesUtil.createRequiredAttrDef("tag", AtlasBaseTypeDef.ATLAS_TYPE_STRING)); |
| TypesDef typesDef = new TypesDef(Collections.<EnumTypeDefinition>emptyList(), Collections.<StructTypeDefinition>emptyList(), |
| Collections.singletonList(classificationTraitDefinition), Collections.singletonList(dslTestTypeDefinition)); |
| createType(typesDef); |
| } |
| |
| private Id createInstance() throws Exception { |
| Referenceable entityInstance = new Referenceable("dsl_test_type", "Classification"); |
| entityInstance.set("name", randomString()); |
| entityInstance.set("description", randomString()); |
| |
| |
| Struct traitInstance = (Struct) entityInstance.getTrait("Classification"); |
| tagName = randomString(); |
| traitInstance.set("tag", tagName); |
| |
| List<String> traits = entityInstance.getTraitNames(); |
| assertEquals(traits.size(), 1); |
| |
| return createInstance(entityInstance); |
| } |
| } |