Commit e06b1ee2 by Shwetha GS

ATLAS-398 Delete trait that exists but not linked to entity results in "400 Bad…

ATLAS-398 Delete trait that exists but not linked to entity results in "400 Bad request". It should result "404 not found" (ndjouhr via shwethags)
parent 21b403bb
...@@ -7,6 +7,7 @@ ATLAS-409 Atlas will not import avro tables with schema read from a file (dosset ...@@ -7,6 +7,7 @@ ATLAS-409 Atlas will not import avro tables with schema read from a file (dosset
ATLAS-379 Create sqoop and falcon metadata addons (venkatnrangan,bvellanki,sowmyaramesh via shwethags) ATLAS-379 Create sqoop and falcon metadata addons (venkatnrangan,bvellanki,sowmyaramesh via shwethags)
ALL CHANGES: ALL CHANGES:
ATLAS-398 Delete trait that exists but not linked to entity results in "400 Bad request". It should result "404 not found" (ndjouhr via shwethags)
ATLAS-372 Expose entity deletion through REST API (dkantor via shwethags) ATLAS-372 Expose entity deletion through REST API (dkantor via shwethags)
ATLAS-452 Exceptions while running HiveHookIT#testAlterTableRename (shwethags) ATLAS-452 Exceptions while running HiveHookIT#testAlterTableRename (shwethags)
ATLAS-388 UI : On creating Tag, the page to be reset for creating new Tag (Anilg via shwethags) ATLAS-388 UI : On creating Tag, the page to be reset for creating new Tag (Anilg via shwethags)
......
...@@ -23,6 +23,7 @@ import org.apache.atlas.typesystem.ITypedReferenceableInstance; ...@@ -23,6 +23,7 @@ import org.apache.atlas.typesystem.ITypedReferenceableInstance;
import org.apache.atlas.typesystem.ITypedStruct; import org.apache.atlas.typesystem.ITypedStruct;
import org.apache.atlas.typesystem.exception.EntityExistsException; import org.apache.atlas.typesystem.exception.EntityExistsException;
import org.apache.atlas.typesystem.exception.EntityNotFoundException; import org.apache.atlas.typesystem.exception.EntityNotFoundException;
import org.apache.atlas.typesystem.exception.TraitNotFoundException;
import org.apache.atlas.typesystem.types.AttributeInfo; import org.apache.atlas.typesystem.types.AttributeInfo;
import org.apache.atlas.typesystem.types.IDataType; import org.apache.atlas.typesystem.types.IDataType;
import org.apache.atlas.typesystem.types.TypeUtils; import org.apache.atlas.typesystem.types.TypeUtils;
...@@ -140,7 +141,7 @@ public interface MetadataRepository { ...@@ -140,7 +141,7 @@ public interface MetadataRepository {
* @param traitNameToBeDeleted name of the trait * @param traitNameToBeDeleted name of the trait
* @throws RepositoryException * @throws RepositoryException
*/ */
void deleteTrait(String guid, String traitNameToBeDeleted) throws EntityNotFoundException, RepositoryException; void deleteTrait(String guid, String traitNameToBeDeleted) throws TraitNotFoundException, EntityNotFoundException, RepositoryException;
/** /**
* Adds/Updates the property to the entity that corresponds to the GUID * Adds/Updates the property to the entity that corresponds to the GUID
......
...@@ -34,6 +34,7 @@ import org.apache.atlas.typesystem.ITypedReferenceableInstance; ...@@ -34,6 +34,7 @@ import org.apache.atlas.typesystem.ITypedReferenceableInstance;
import org.apache.atlas.typesystem.ITypedStruct; import org.apache.atlas.typesystem.ITypedStruct;
import org.apache.atlas.typesystem.exception.EntityExistsException; import org.apache.atlas.typesystem.exception.EntityExistsException;
import org.apache.atlas.typesystem.exception.EntityNotFoundException; import org.apache.atlas.typesystem.exception.EntityNotFoundException;
import org.apache.atlas.typesystem.exception.TraitNotFoundException;
import org.apache.atlas.typesystem.types.AttributeInfo; import org.apache.atlas.typesystem.types.AttributeInfo;
import org.apache.atlas.typesystem.types.ClassType; import org.apache.atlas.typesystem.types.ClassType;
import org.apache.atlas.typesystem.types.IDataType; import org.apache.atlas.typesystem.types.IDataType;
...@@ -239,17 +240,20 @@ public class GraphBackedMetadataRepository implements MetadataRepository { ...@@ -239,17 +240,20 @@ public class GraphBackedMetadataRepository implements MetadataRepository {
*/ */
@Override @Override
@GraphTransaction @GraphTransaction
public void deleteTrait(String guid, String traitNameToBeDeleted) throws EntityNotFoundException, RepositoryException { public void deleteTrait(String guid, String traitNameToBeDeleted) throws TraitNotFoundException, EntityNotFoundException, RepositoryException {
LOG.info("Deleting trait={} from entity={}", traitNameToBeDeleted, guid); LOG.info("Deleting trait={} from entity={}", traitNameToBeDeleted, guid);
try {
Vertex instanceVertex = graphHelper.getVertexForGUID(guid); Vertex instanceVertex = graphHelper.getVertexForGUID(guid);
List<String> traitNames = GraphHelper.getTraitNames(instanceVertex); List<String> traitNames = GraphHelper.getTraitNames(instanceVertex);
if (!traitNames.contains(traitNameToBeDeleted)) { if (!traitNames.contains(traitNameToBeDeleted)) {
throw new EntityNotFoundException( throw new TraitNotFoundException(
"Could not find trait=" + traitNameToBeDeleted + " in the repository for entity: " + guid); "Could not find trait=" + traitNameToBeDeleted + " in the repository for entity: " + guid);
} }
try {
final String entityTypeName = GraphHelper.getTypeName(instanceVertex); final String entityTypeName = GraphHelper.getTypeName(instanceVertex);
String relationshipLabel = GraphHelper.getTraitLabel(entityTypeName, traitNameToBeDeleted); String relationshipLabel = GraphHelper.getTraitLabel(entityTypeName, traitNameToBeDeleted);
Iterator<Edge> results = instanceVertex.getEdges(Direction.OUT, relationshipLabel).iterator(); Iterator<Edge> results = instanceVertex.getEdges(Direction.OUT, relationshipLabel).iterator();
......
...@@ -37,6 +37,7 @@ import org.apache.atlas.typesystem.ITypedStruct; ...@@ -37,6 +37,7 @@ import org.apache.atlas.typesystem.ITypedStruct;
import org.apache.atlas.typesystem.Referenceable; import org.apache.atlas.typesystem.Referenceable;
import org.apache.atlas.typesystem.Struct; import org.apache.atlas.typesystem.Struct;
import org.apache.atlas.typesystem.exception.EntityNotFoundException; import org.apache.atlas.typesystem.exception.EntityNotFoundException;
import org.apache.atlas.typesystem.exception.TraitNotFoundException;
import org.apache.atlas.typesystem.persistence.Id; import org.apache.atlas.typesystem.persistence.Id;
import org.apache.atlas.typesystem.types.ClassType; import org.apache.atlas.typesystem.types.ClassType;
import org.apache.atlas.typesystem.types.DataTypes; import org.apache.atlas.typesystem.types.DataTypes;
...@@ -337,13 +338,13 @@ public class GraphBackedMetadataRepositoryTest { ...@@ -337,13 +338,13 @@ public class GraphBackedMetadataRepositoryTest {
Assert.assertTrue(modificationTimestampPostUpdate > modificationTimestampPreUpdate); Assert.assertTrue(modificationTimestampPostUpdate > modificationTimestampPreUpdate);
} }
@Test(expectedExceptions = RepositoryException.class) @Test(expectedExceptions = EntityNotFoundException.class)
public void testDeleteTraitForNonExistentEntity() throws Exception { public void testDeleteTraitForNonExistentEntity() throws Exception {
repositoryService.deleteTrait(UUID.randomUUID().toString(), TestUtils.PII); repositoryService.deleteTrait(UUID.randomUUID().toString(), TestUtils.PII);
Assert.fail(); Assert.fail();
} }
@Test(expectedExceptions = RepositoryException.class) @Test(expectedExceptions = TraitNotFoundException.class)
public void testDeleteTraitForNonExistentTrait() throws Exception { public void testDeleteTraitForNonExistentTrait() throws Exception {
final String aGUID = getGUID(); final String aGUID = getGUID();
repositoryService.deleteTrait(aGUID, "PCI"); repositoryService.deleteTrait(aGUID, "PCI");
......
/**
* 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.typesystem.exception;
import org.apache.atlas.AtlasException;
/**
* A simple wrapper for 404.
* Thrown when a requested trait can not be found.
*/
public class TraitNotFoundException extends AtlasException{
public TraitNotFoundException() {
}
public TraitNotFoundException(String message) {
super(message);
}
public TraitNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public TraitNotFoundException(Throwable cause) {
super(cause);
}
public TraitNotFoundException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
...@@ -26,6 +26,7 @@ import org.apache.atlas.typesystem.Referenceable; ...@@ -26,6 +26,7 @@ import org.apache.atlas.typesystem.Referenceable;
import org.apache.atlas.typesystem.exception.EntityExistsException; import org.apache.atlas.typesystem.exception.EntityExistsException;
import org.apache.atlas.typesystem.exception.EntityNotFoundException; import org.apache.atlas.typesystem.exception.EntityNotFoundException;
import org.apache.atlas.typesystem.exception.TypeNotFoundException; import org.apache.atlas.typesystem.exception.TypeNotFoundException;
import org.apache.atlas.typesystem.exception.TraitNotFoundException;
import org.apache.atlas.typesystem.json.InstanceSerialization; import org.apache.atlas.typesystem.json.InstanceSerialization;
import org.apache.atlas.typesystem.types.ValueConversionException; import org.apache.atlas.typesystem.types.ValueConversionException;
import org.apache.atlas.utils.ParamChecker; import org.apache.atlas.utils.ParamChecker;
...@@ -566,6 +567,9 @@ public class EntityResource { ...@@ -566,6 +567,9 @@ public class EntityResource {
} catch (EntityNotFoundException | TypeNotFoundException e) { } catch (EntityNotFoundException | TypeNotFoundException e) {
LOG.error("An entity with GUID={} does not exist", guid, e); LOG.error("An entity with GUID={} does not exist", guid, e);
throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.NOT_FOUND)); throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.NOT_FOUND));
} catch (TraitNotFoundException e) {
LOG.error("The trait name={} for entity={} does not exist.", traitName, guid, e);
throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.NOT_FOUND));
} catch (AtlasException | IllegalArgumentException e) { } catch (AtlasException | IllegalArgumentException e) {
LOG.error("Unable to delete trait name={} for entity={}", traitName, guid, e); LOG.error("Unable to delete trait name={} for entity={}", traitName, guid, e);
throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.BAD_REQUEST)); throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.BAD_REQUEST));
......
...@@ -69,6 +69,7 @@ import java.util.UUID; ...@@ -69,6 +69,7 @@ import java.util.UUID;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail; import static org.testng.Assert.fail;
/** /**
* Integration tests for Entity Jersey Resource. * Integration tests for Entity Jersey Resource.
*/ */
...@@ -594,7 +595,32 @@ public class EntityJerseyResourceIT extends BaseResourceIT { ...@@ -594,7 +595,32 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
"trait=" + traitName + " should be defined in type system before it can be deleted"); "trait=" + traitName + " should be defined in type system before it can be deleted");
Assert.assertNotNull(response.get(AtlasClient.STACKTRACE)); Assert.assertNotNull(response.get(AtlasClient.STACKTRACE));
} }
@Test(dependsOnMethods = "testSubmitEntity()")
public void testDeleteExistentTraitNonExistentForEntity() throws Exception {
final String guid = tableId._getId();
final String traitName = "PII_Trait" + randomString();
HierarchicalTypeDefinition<TraitType> piiTrait = TypesUtil
.createTraitTypeDef(traitName, ImmutableList.<String>of(),
TypesUtil.createRequiredAttrDef("type", DataTypes.STRING_TYPE));
String traitDefinitionAsJSON = TypesSerialization$.MODULE$.toJson(piiTrait, true);
createType(traitDefinitionAsJSON);
ClientResponse clientResponse = service.path(ENTITIES).path(guid).path(TRAITS).path(traitName)
.accept(Servlets.JSON_MEDIA_TYPE).type(Servlets.JSON_MEDIA_TYPE)
.method(HttpMethod.DELETE, ClientResponse.class);
Assert.assertEquals(clientResponse.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
String responseAsString = clientResponse.getEntity(String.class);
Assert.assertNotNull(responseAsString);
JSONObject response = new JSONObject(responseAsString);
Assert.assertNotNull(response.get(AtlasClient.ERROR));
Assert.assertNotNull(response.get(AtlasClient.STACKTRACE));
}
private String random() { private String random() {
return RandomStringUtils.random(10); return RandomStringUtils.random(10);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment