Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
atlas
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
dataplatform
atlas
Commits
765d556c
Commit
765d556c
authored
Feb 17, 2017
by
Sarath Subramanian
Committed by
Madhan Neethiraj
Feb 24, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ATLAS-1564: EntityResource v1 updated to route its calls to v2 EntityREST
Signed-off-by:
Madhan Neethiraj
<
madhan@apache.org
>
parent
c7900f25
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
372 additions
and
62 deletions
+372
-62
AtlasClient.java
client/src/main/java/org/apache/atlas/AtlasClient.java
+4
-4
AtlasErrorCode.java
intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
+1
-0
AtlasFormatConverter.java
...che/atlas/repository/converters/AtlasFormatConverter.java
+5
-1
AtlasInstanceConverter.java
...e/atlas/repository/converters/AtlasInstanceConverter.java
+104
-7
AtlasEntityStore.java
...apache/atlas/repository/store/graph/AtlasEntityStore.java
+20
-0
AtlasEntityStoreV1.java
...e/atlas/repository/store/graph/v1/AtlasEntityStoreV1.java
+75
-4
DefaultMetadataService.java
...ava/org/apache/atlas/services/DefaultMetadataService.java
+2
-1
MetadataService.java
.../main/java/org/apache/atlas/services/MetadataService.java
+8
-0
EntityResource.java
...n/java/org/apache/atlas/web/resources/EntityResource.java
+98
-30
EntityREST.java
...p/src/main/java/org/apache/atlas/web/rest/EntityREST.java
+18
-1
EntityResourceTest.java
...va/org/apache/atlas/web/resources/EntityResourceTest.java
+37
-14
No files found.
client/src/main/java/org/apache/atlas/AtlasClient.java
View file @
765d556c
...
...
@@ -270,12 +270,12 @@ public class AtlasClient extends AtlasBaseClient {
}
public
EntityResult
(
List
<
String
>
created
,
List
<
String
>
updated
,
List
<
String
>
deleted
)
{
add
(
OP_CREATED
,
created
);
add
(
OP_UPDATED
,
updated
);
add
(
OP_DELETED
,
deleted
);
set
(
OP_CREATED
,
created
);
set
(
OP_UPDATED
,
updated
);
set
(
OP_DELETED
,
deleted
);
}
p
rivate
void
add
(
String
type
,
List
<
String
>
list
)
{
p
ublic
void
set
(
String
type
,
List
<
String
>
list
)
{
if
(
list
!=
null
&&
list
.
size
()
>
0
)
{
entities
.
put
(
type
,
list
);
}
...
...
intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
View file @
765d556c
...
...
@@ -66,6 +66,7 @@ public enum AtlasErrorCode {
SYSTEM_TYPE
(
400
,
"ATLAS40035E"
,
"{0} is a System-type"
),
INVALID_STRUCT_VALUE
(
400
,
"ATLAS40036E"
,
"not a valid struct value {0}"
),
INSTANCE_LINEAGE_INVALID_PARAMS
(
400
,
"ATLAS40037E"
,
"Invalid lineage query parameters passed {0}: {1}"
),
ATTRIBUTE_UPDATE_NOT_SUPPORTED
(
400
,
"ATLAS40038E"
,
"{0}.{1} : attribute update not supported"
),
// All Not found enums go here
TYPE_NAME_NOT_FOUND
(
404
,
"ATLAS4041E"
,
"Given typename {0} was invalid"
),
...
...
repository/src/main/java/org/apache/atlas/repository/converters/AtlasFormatConverter.java
View file @
765d556c
...
...
@@ -34,7 +34,7 @@ public interface AtlasFormatConverter {
class
ConverterContext
{
private
AtlasEntit
y
.
AtlasEntit
iesWithExtInfo
entities
=
null
;
private
AtlasEntitiesWithExtInfo
entities
=
null
;
public
void
addEntity
(
AtlasEntity
entity
)
{
if
(
entities
==
null
)
{
...
...
@@ -61,6 +61,10 @@ public interface AtlasFormatConverter {
public
boolean
entityExists
(
String
guid
)
{
return
entities
!=
null
&&
entities
.
hasEntity
(
guid
);
}
public
AtlasEntitiesWithExtInfo
getEntities
()
{
if
(
entities
!=
null
)
{
entities
.
compact
();
}
return
entities
;
}
}
...
...
repository/src/main/java/org/apache/atlas/repository/converters/AtlasInstanceConverter.java
View file @
765d556c
...
...
@@ -20,6 +20,7 @@ package org.apache.atlas.repository.converters;
import
com.google.inject.Inject
;
import
com.google.inject.Singleton
;
import
org.apache.atlas.AtlasClient
;
import
org.apache.atlas.AtlasClient.EntityResult
;
import
org.apache.atlas.AtlasErrorCode
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.CreateUpdateEntitiesResult
;
...
...
@@ -27,9 +28,11 @@ import org.apache.atlas.exception.AtlasBaseException;
import
org.apache.atlas.model.TypeCategory
;
import
org.apache.atlas.model.instance.AtlasClassification
;
import
org.apache.atlas.model.instance.AtlasEntity
;
import
org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo
;
import
org.apache.atlas.model.instance.AtlasEntityHeader
;
import
org.apache.atlas.model.instance.EntityMutationResponse
;
import
org.apache.atlas.model.instance.EntityMutations
;
import
org.apache.atlas.model.instance.EntityMutations.EntityOperation
;
import
org.apache.atlas.model.instance.GuidMapping
;
import
org.apache.atlas.services.MetadataService
;
import
org.apache.atlas.type.AtlasClassificationType
;
...
...
@@ -45,12 +48,17 @@ import org.apache.atlas.typesystem.Struct;
import
org.apache.atlas.typesystem.exception.EntityNotFoundException
;
import
org.apache.atlas.typesystem.exception.TraitNotFoundException
;
import
org.apache.atlas.typesystem.exception.TypeNotFoundException
;
import
org.apache.atlas.repository.converters.AtlasFormatConverter.ConverterContext
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.collections.MapUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
@Singleton
public
class
AtlasInstanceConverter
{
...
...
@@ -100,10 +108,10 @@ public class AtlasInstanceConverter {
}
}
public
Referenceable
getReferenceable
(
AtlasEntity
entity
,
final
AtlasFormatConverter
.
ConverterContext
ctx
)
throws
AtlasBaseException
{
public
Referenceable
getReferenceable
(
AtlasEntity
entity
,
final
ConverterContext
ctx
)
throws
AtlasBaseException
{
AtlasFormatConverter
converter
=
instanceFormatters
.
getConverter
(
TypeCategory
.
ENTITY
);
AtlasType
entityType
=
typeRegistry
.
getType
(
entity
.
getTypeName
());
Referenceable
ref
=
(
Referenceable
)
converter
.
fromV2ToV1
(
entity
,
entityType
,
ctx
);
Referenceable
ref
=
(
Referenceable
)
converter
.
fromV2ToV1
(
entity
,
entityType
,
ctx
);
return
ref
;
}
...
...
@@ -111,7 +119,7 @@ public class AtlasInstanceConverter {
public
ITypedStruct
getTrait
(
AtlasClassification
classification
)
throws
AtlasBaseException
{
AtlasFormatConverter
converter
=
instanceFormatters
.
getConverter
(
TypeCategory
.
CLASSIFICATION
);
AtlasType
classificationType
=
typeRegistry
.
getType
(
classification
.
getTypeName
());
Struct
trait
=
(
Struct
)
converter
.
fromV2ToV1
(
classification
,
classificationType
,
new
AtlasFormatConverter
.
ConverterContext
());
Struct
trait
=
(
Struct
)
converter
.
fromV2ToV1
(
classification
,
classificationType
,
new
ConverterContext
());
try
{
return
metadataService
.
createTraitInstance
(
trait
);
...
...
@@ -132,8 +140,7 @@ public class AtlasInstanceConverter {
return
ret
;
}
public
AtlasEntity
.
AtlasEntitiesWithExtInfo
toAtlasEntity
(
IReferenceableInstance
referenceable
)
throws
AtlasBaseException
{
public
AtlasEntitiesWithExtInfo
toAtlasEntity
(
IReferenceableInstance
referenceable
)
throws
AtlasBaseException
{
AtlasEntityFormatConverter
converter
=
(
AtlasEntityFormatConverter
)
instanceFormatters
.
getConverter
(
TypeCategory
.
ENTITY
);
AtlasEntityType
entityType
=
typeRegistry
.
getEntityTypeByName
(
referenceable
.
getTypeName
());
...
...
@@ -141,9 +148,9 @@ public class AtlasInstanceConverter {
throw
new
AtlasBaseException
(
AtlasErrorCode
.
TYPE_NAME_INVALID
,
TypeCategory
.
ENTITY
.
name
(),
referenceable
.
getTypeName
());
}
AtlasFormatConverter
.
ConverterContext
ctx
=
new
AtlasFormatConverter
.
ConverterContext
();
ConverterContext
ctx
=
new
ConverterContext
();
AtlasEntity
entity
=
converter
.
fromV1ToV2
(
referenceable
,
entityType
,
ctx
);
ctx
.
addEntity
(
entity
);
return
ctx
.
getEntities
();
...
...
@@ -212,6 +219,31 @@ public class AtlasInstanceConverter {
return
context
.
getEntities
();
}
public
AtlasEntitiesWithExtInfo
toAtlasEntities
(
String
entitiesJson
)
throws
AtlasBaseException
,
AtlasException
{
ITypedReferenceableInstance
[]
referenceables
=
metadataService
.
deserializeClassInstances
(
entitiesJson
);
AtlasEntityFormatConverter
converter
=
(
AtlasEntityFormatConverter
)
instanceFormatters
.
getConverter
(
TypeCategory
.
ENTITY
);
ConverterContext
context
=
new
ConverterContext
();
AtlasEntitiesWithExtInfo
ret
=
null
;
if
(
referenceables
!=
null
)
{
for
(
IReferenceableInstance
referenceable
:
referenceables
)
{
AtlasEntityType
entityType
=
typeRegistry
.
getEntityTypeByName
(
referenceable
.
getTypeName
());
if
(
entityType
==
null
)
{
throw
new
AtlasBaseException
(
AtlasErrorCode
.
TYPE_NAME_INVALID
,
TypeCategory
.
ENTITY
.
name
(),
referenceable
.
getTypeName
());
}
AtlasEntity
entity
=
converter
.
fromV1ToV2
(
referenceable
,
entityType
,
context
);
context
.
addEntity
(
entity
);
}
ret
=
context
.
getEntities
();
}
return
ret
;
}
private
AtlasEntity
fromV1toV2Entity
(
Referenceable
referenceable
,
AtlasFormatConverter
.
ConverterContext
context
)
throws
AtlasBaseException
{
if
(
LOG
.
isDebugEnabled
())
{
LOG
.
debug
(
"==> fromV1toV2Entity"
);
...
...
@@ -227,4 +259,69 @@ public class AtlasInstanceConverter {
return
entity
;
}
public
CreateUpdateEntitiesResult
toCreateUpdateEntitiesResult
(
EntityMutationResponse
reponse
)
{
CreateUpdateEntitiesResult
ret
=
null
;
if
(
reponse
!=
null
)
{
Map
<
EntityOperation
,
List
<
AtlasEntityHeader
>>
mutatedEntities
=
reponse
.
getMutatedEntities
();
Map
<
String
,
String
>
guidAssignments
=
reponse
.
getGuidAssignments
();
ret
=
new
CreateUpdateEntitiesResult
();
if
(
MapUtils
.
isNotEmpty
(
guidAssignments
))
{
ret
.
setGuidMapping
(
new
GuidMapping
(
guidAssignments
));
}
if
(
MapUtils
.
isNotEmpty
(
mutatedEntities
))
{
EntityResult
entityResult
=
new
EntityResult
();
for
(
Map
.
Entry
<
EntityOperation
,
List
<
AtlasEntityHeader
>>
e
:
mutatedEntities
.
entrySet
())
{
switch
(
e
.
getKey
())
{
case
CREATE:
List
<
AtlasEntityHeader
>
createdEntities
=
mutatedEntities
.
get
(
EntityOperation
.
CREATE
);
if
(
CollectionUtils
.
isNotEmpty
(
createdEntities
))
{
entityResult
.
set
(
EntityResult
.
OP_CREATED
,
getGuids
(
createdEntities
));
}
break
;
case
UPDATE:
List
<
AtlasEntityHeader
>
updatedEntities
=
mutatedEntities
.
get
(
EntityOperation
.
UPDATE
);
if
(
CollectionUtils
.
isNotEmpty
(
updatedEntities
))
{
entityResult
.
set
(
EntityResult
.
OP_UPDATED
,
getGuids
(
updatedEntities
));
}
break
;
case
PARTIAL_UPDATE:
List
<
AtlasEntityHeader
>
partialUpdatedEntities
=
mutatedEntities
.
get
(
EntityOperation
.
PARTIAL_UPDATE
);
if
(
CollectionUtils
.
isNotEmpty
(
partialUpdatedEntities
))
{
entityResult
.
set
(
EntityResult
.
OP_UPDATED
,
getGuids
(
partialUpdatedEntities
));
}
break
;
case
DELETE:
List
<
AtlasEntityHeader
>
deletedEntities
=
mutatedEntities
.
get
(
EntityOperation
.
DELETE
);
if
(
CollectionUtils
.
isNotEmpty
(
deletedEntities
))
{
entityResult
.
set
(
EntityResult
.
OP_DELETED
,
getGuids
(
deletedEntities
));
}
break
;
}
}
ret
.
setEntityResult
(
entityResult
);
}
}
return
ret
;
}
public
List
<
String
>
getGuids
(
List
<
AtlasEntityHeader
>
entities
)
{
List
<
String
>
ret
=
null
;
if
(
CollectionUtils
.
isNotEmpty
(
entities
))
{
ret
=
new
ArrayList
<>();
for
(
AtlasEntityHeader
entity
:
entities
)
{
ret
.
add
(
entity
.
getGuid
());
}
}
return
ret
;
}
}
repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java
View file @
765d556c
...
...
@@ -89,6 +89,26 @@ public interface AtlasEntityStore {
AtlasEntity
entity
)
throws
AtlasBaseException
;
/**
* Partial update a single entity using its guid.
* @param entityType type of the entity
* @param guid Entity guid
* @return EntityMutationResponse details of the updates performed by this call
* @throws AtlasBaseException
*
*/
EntityMutationResponse
updateByGuid
(
AtlasEntityType
entityType
,
String
guid
,
AtlasEntity
entity
)
throws
AtlasBaseException
;
/**
* Partial update entities attribute using its guid.
* @param guid Entity guid
* @param attrName attribute name to be updated
* @param attrValue updated attribute value
* @return EntityMutationResponse details of the updates performed by this call
* @throws AtlasBaseException
*/
EntityMutationResponse
updateEntityAttributeByGuid
(
String
guid
,
String
attrName
,
Object
attrValue
)
throws
AtlasBaseException
;
/**
* Delete an entity by its guid
* @param guid
* @return
...
...
repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1.java
View file @
765d556c
...
...
@@ -21,15 +21,16 @@ package org.apache.atlas.repository.store.graph.v1;
import
com.google.inject.Inject
;
import
com.google.inject.Singleton
;
import
org.apache.atlas.AtlasErrorCode
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.GraphTransaction
;
import
org.apache.atlas.RequestContextV1
;
import
org.apache.atlas.exception.AtlasBaseException
;
import
org.apache.atlas.model.impexp.AtlasImportResult
;
import
org.apache.atlas.model.instance.AtlasClassification
;
import
org.apache.atlas.model.instance.AtlasEntity
;
import
org.apache.atlas.model.instance.AtlasEntityHeader
;
import
org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo
;
import
org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo
;
import
org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo
;
import
org.apache.atlas.model.instance.AtlasEntityHeader
;
import
org.apache.atlas.model.instance.AtlasObjectId
;
import
org.apache.atlas.model.instance.EntityMutationResponse
;
import
org.apache.atlas.repository.graphdb.AtlasVertex
;
...
...
@@ -37,17 +38,28 @@ import org.apache.atlas.repository.store.graph.AtlasEntityStore;
import
org.apache.atlas.repository.store.graph.EntityGraphDiscovery
;
import
org.apache.atlas.repository.store.graph.EntityGraphDiscoveryContext
;
import
org.apache.atlas.type.AtlasEntityType
;
import
org.apache.atlas.type.AtlasStructType
;
import
org.apache.atlas.type.AtlasStructType.AtlasAttribute
;
import
org.apache.atlas.type.AtlasType
;
import
org.apache.atlas.type.AtlasTypeRegistry
;
import
org.apache.atlas.type.AtlasTypeUtil
;
import
org.apache.atlas.typesystem.persistence.Id
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.collections.MapUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.util.*
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
static
org
.
apache
.
atlas
.
model
.
instance
.
EntityMutations
.
EntityOperation
.*;
import
static
org
.
apache
.
atlas
.
model
.
instance
.
EntityMutations
.
EntityOperation
.
DELETE
;
import
static
org
.
apache
.
atlas
.
model
.
instance
.
EntityMutations
.
EntityOperation
.
UPDATE
;
@Singleton
...
...
@@ -245,6 +257,65 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
return
createOrUpdate
(
new
AtlasEntityStream
(
updatedEntity
),
true
);
}
@Override
@GraphTransaction
public
EntityMutationResponse
updateByGuid
(
AtlasEntityType
entityType
,
String
guid
,
AtlasEntity
updatedEntity
)
throws
AtlasBaseException
{
if
(
LOG
.
isDebugEnabled
())
{
LOG
.
debug
(
"==> updateByUniqueAttributes({}, {})"
,
entityType
.
getTypeName
(),
guid
);
}
if
(
updatedEntity
==
null
)
{
throw
new
AtlasBaseException
(
AtlasErrorCode
.
INVALID_PARAMETERS
,
"no entity to update."
);
}
updatedEntity
.
setGuid
(
guid
);
return
createOrUpdate
(
new
AtlasEntityStream
(
updatedEntity
),
true
);
}
@Override
@GraphTransaction
public
EntityMutationResponse
updateEntityAttributeByGuid
(
String
guid
,
String
attrName
,
Object
attrValue
)
throws
AtlasBaseException
{
if
(
LOG
.
isDebugEnabled
())
{
LOG
.
debug
(
"==> updateEntityAttributeByGuid({}, {}, {})"
,
guid
,
attrName
,
attrValue
);
}
AtlasEntityWithExtInfo
entityInfo
=
getById
(
guid
);
if
(
entityInfo
==
null
||
entityInfo
.
getEntity
()
==
null
)
{
throw
new
AtlasBaseException
(
AtlasErrorCode
.
INSTANCE_GUID_NOT_FOUND
,
guid
);
}
AtlasEntity
entity
=
entityInfo
.
getEntity
();
AtlasEntityType
entityType
=
(
AtlasEntityType
)
typeRegistry
.
getType
(
entity
.
getTypeName
());
AtlasAttribute
attr
=
entityType
.
getAttribute
(
attrName
);
if
(
attr
==
null
)
{
throw
new
AtlasBaseException
(
AtlasErrorCode
.
UNKNOWN_ATTRIBUTE
,
attrName
,
entity
.
getTypeName
());
}
AtlasType
attrType
=
attr
.
getAttributeType
();
AtlasEntity
updateEntity
=
new
AtlasEntity
();
updateEntity
.
setGuid
(
guid
);
updateEntity
.
setTypeName
(
entity
.
getTypeName
());
switch
(
attrType
.
getTypeCategory
())
{
case
PRIMITIVE:
case
OBJECT_ID_TYPE:
updateEntity
.
setAttribute
(
attrName
,
attrValue
);
break
;
default
:
throw
new
AtlasBaseException
(
AtlasErrorCode
.
ATTRIBUTE_UPDATE_NOT_SUPPORTED
,
attrName
,
attrType
.
getTypeName
());
}
return
createOrUpdate
(
new
AtlasEntityStream
(
updateEntity
),
true
);
}
@GraphTransaction
public
EntityMutationResponse
deleteById
(
final
String
guid
)
throws
AtlasBaseException
{
...
...
repository/src/main/java/org/apache/atlas/services/DefaultMetadataService.java
View file @
765d556c
...
...
@@ -308,7 +308,8 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
return
result
;
}
private
ITypedReferenceableInstance
[]
deserializeClassInstances
(
String
entityInstanceDefinition
)
throws
AtlasException
{
@Override
public
ITypedReferenceableInstance
[]
deserializeClassInstances
(
String
entityInstanceDefinition
)
throws
AtlasException
{
return
GraphHelper
.
deserializeClassInstances
(
typeSystem
,
entityInstanceDefinition
);
}
...
...
server-api/src/main/java/org/apache/atlas/services/MetadataService.java
View file @
765d556c
...
...
@@ -301,4 +301,12 @@ public interface MetadataService {
* @return
*/
List
<
EntityAuditEvent
>
getAuditEvents
(
String
guid
,
String
startKey
,
short
count
)
throws
AtlasException
;
/**
* Deserializes entity instances into ITypedReferenceableInstance array.
* @param entityInstanceDefinition
* @return ITypedReferenceableInstance[]
* @throws AtlasException
*/
ITypedReferenceableInstance
[]
deserializeClassInstances
(
String
entityInstanceDefinition
)
throws
AtlasException
;
}
webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java
View file @
765d556c
...
...
@@ -20,16 +20,28 @@ package org.apache.atlas.web.resources;
import
com.google.common.annotations.VisibleForTesting
;
import
com.google.common.base.Preconditions
;
import
com.sun.jersey.api.core.ResourceContext
;
import
org.apache.atlas.AtlasClient
;
import
org.apache.atlas.AtlasConstants
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.CreateUpdateEntitiesResult
;
import
org.apache.atlas.EntityAuditEvent
;
import
org.apache.atlas.AtlasClient.EntityResult
;
import
org.apache.atlas.exception.AtlasBaseException
;
import
org.apache.atlas.model.instance.AtlasEntity
;
import
org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo
;
import
org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo
;
import
org.apache.atlas.model.instance.EntityMutationResponse
;
import
org.apache.atlas.model.instance.GuidMapping
;
import
org.apache.atlas.repository.converters.AtlasFormatConverter.ConverterContext
;
import
org.apache.atlas.repository.converters.AtlasInstanceConverter
;
import
org.apache.atlas.repository.store.graph.AtlasEntityStore
;
import
org.apache.atlas.services.MetadataService
;
import
org.apache.atlas.type.AtlasType
;
import
org.apache.atlas.type.AtlasEntityType
;
import
org.apache.atlas.type.AtlasTypeRegistry
;
import
org.apache.atlas.typesystem.IStruct
;
import
org.apache.atlas.typesystem.ITypedReferenceableInstance
;
import
org.apache.atlas.typesystem.Referenceable
;
import
org.apache.atlas.typesystem.exception.EntityExistsException
;
import
org.apache.atlas.typesystem.exception.EntityNotFoundException
;
...
...
@@ -39,6 +51,7 @@ import org.apache.atlas.typesystem.json.InstanceSerialization;
import
org.apache.atlas.typesystem.types.ValueConversionException
;
import
org.apache.atlas.utils.AtlasPerfTracer
;
import
org.apache.atlas.utils.ParamChecker
;
import
org.apache.atlas.web.rest.EntityREST
;
import
org.apache.atlas.web.util.Servlets
;
import
org.apache.commons.lang.StringUtils
;
import
org.codehaus.jettison.json.JSONArray
;
...
...
@@ -59,7 +72,9 @@ import javax.ws.rs.core.UriInfo;
import
java.net.URI
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
/**
...
...
@@ -78,10 +93,16 @@ public class EntityResource {
private
static
final
String
TRAIT_NAME
=
"traitName"
;
private
final
MetadataService
metadataService
;
private
final
AtlasInstanceConverter
restAdapters
;
private
final
AtlasEntityStore
entitiesStore
;
private
final
AtlasTypeRegistry
typeRegistry
;
@Context
UriInfo
uriInfo
;
@Context
private
ResourceContext
resourceContext
;
/**
* Created by the Guice ServletModule and injected with the
* configured MetadataService.
...
...
@@ -89,8 +110,11 @@ public class EntityResource {
* @param metadataService metadata service handle
*/
@Inject
public
EntityResource
(
MetadataService
metadataService
)
{
public
EntityResource
(
MetadataService
metadataService
,
AtlasInstanceConverter
restAdapters
,
AtlasEntityStore
entitiesStore
,
AtlasTypeRegistry
typeRegistry
)
{
this
.
metadataService
=
metadataService
;
this
.
restAdapters
=
restAdapters
;
this
.
entitiesStore
=
entitiesStore
;
this
.
typeRegistry
=
typeRegistry
;
}
/**
...
...
@@ -131,14 +155,19 @@ public class EntityResource {
LOG
.
debug
(
"submitting entities {} "
,
entityJson
);
}
final
CreateUpdateEntitiesResult
result
=
metadataService
.
createEntities
(
entities
);
final
List
<
String
>
guids
=
result
.
getEntityResult
().
getCreatedEntities
();
EntityREST
entityREST
=
resourceContext
.
getResource
(
EntityREST
.
class
);
AtlasEntitiesWithExtInfo
entitiesInfo
=
restAdapters
.
toAtlasEntities
(
entities
);
EntityMutationResponse
mutationResponse
=
entityREST
.
createOrUpdate
(
entitiesInfo
);
final
List
<
String
>
guids
=
restAdapters
.
getGuids
(
mutationResponse
.
getCreatedEntities
());
if
(
LOG
.
isDebugEnabled
())
{
LOG
.
debug
(
"Created entities {}"
,
guids
);
}
JSONObject
response
=
getResponse
(
result
);
final
CreateUpdateEntitiesResult
result
=
restAdapters
.
toCreateUpdateEntitiesResult
(
mutationResponse
);
JSONObject
response
=
getResponse
(
result
);
URI
locationURI
=
getLocationURI
(
guids
);
return
Response
.
created
(
locationURI
).
entity
(
response
).
build
();
...
...
@@ -165,7 +194,6 @@ public class EntityResource {
}
}
@VisibleForTesting
public
URI
getLocationURI
(
List
<
String
>
guids
)
{
URI
locationURI
=
null
;
...
...
@@ -235,7 +263,10 @@ public class EntityResource {
LOG
.
info
(
"updating entities {} "
,
entityJson
);
}
CreateUpdateEntitiesResult
result
=
metadataService
.
updateEntities
(
entities
);
EntityREST
entityREST
=
resourceContext
.
getResource
(
EntityREST
.
class
);
AtlasEntitiesWithExtInfo
entitiesInfo
=
restAdapters
.
toAtlasEntities
(
entities
);
EntityMutationResponse
mutationResponse
=
entityREST
.
createOrUpdate
(
entitiesInfo
);
CreateUpdateEntitiesResult
result
=
restAdapters
.
toCreateUpdateEntitiesResult
(
mutationResponse
);
if
(
LOG
.
isDebugEnabled
())
{
LOG
.
debug
(
"Updated entities: {}"
,
result
.
getEntityResult
());
...
...
@@ -317,11 +348,19 @@ public class EntityResource {
LOG
.
debug
(
"Partially updating entity by unique attribute {} {} {} {} "
,
entityType
,
attribute
,
value
,
entityJson
);
}
Referenceable
updatedEntity
=
InstanceSerialization
.
fromJsonReferenceable
(
entityJson
,
true
);
Referenceable
updatedEntity
=
InstanceSerialization
.
fromJsonReferenceable
(
entityJson
,
true
);
CreateUpdateEntitiesResult
result
=
metadataService
.
updateEntityByUniqueAttribute
(
entityType
,
attribute
,
value
,
updatedEntity
);
entityType
=
ParamChecker
.
notEmpty
(
entityType
,
"Entity type cannot be null"
);
attribute
=
ParamChecker
.
notEmpty
(
attribute
,
"attribute name cannot be null"
);
value
=
ParamChecker
.
notEmpty
(
value
,
"attribute value cannot be null"
);
Map
<
String
,
Object
>
attributes
=
new
HashMap
<>();
attributes
.
put
(
attribute
,
value
);
AtlasEntitiesWithExtInfo
entitiesInfo
=
restAdapters
.
toAtlasEntity
(
updatedEntity
);
AtlasEntity
entity
=
entitiesInfo
.
getEntity
(
updatedEntity
.
getId
().
_getId
());
EntityMutationResponse
mutationResponse
=
entitiesStore
.
updateByUniqueAttributes
(
getEntityType
(
entityType
),
attributes
,
entity
);
CreateUpdateEntitiesResult
result
=
restAdapters
.
toCreateUpdateEntitiesResult
(
mutationResponse
);
if
(
LOG
.
isDebugEnabled
())
{
LOG
.
debug
(
"Updated entities: {}"
,
result
.
getEntityResult
());
...
...
@@ -379,9 +418,9 @@ public class EntityResource {
}
if
(
StringUtils
.
isEmpty
(
attribute
))
{
return
updateEntityPartial
ByGuid
(
guid
,
request
);
return
partialUpdateEntity
ByGuid
(
guid
,
request
);
}
else
{
return
updateEntityAttribute
ByGuid
(
guid
,
attribute
,
request
);
return
partialUpdateEntityAttr
ByGuid
(
guid
,
attribute
,
request
);
}
}
finally
{
AtlasPerfTracer
.
log
(
perf
);
...
...
@@ -392,7 +431,7 @@ public class EntityResource {
}
}
private
Response
updateEntityPartial
ByGuid
(
String
guid
,
HttpServletRequest
request
)
{
private
Response
partialUpdateEntity
ByGuid
(
String
guid
,
HttpServletRequest
request
)
{
String
entityJson
=
null
;
try
{
guid
=
ParamChecker
.
notEmpty
(
guid
,
"Guid property cannot be null"
);
...
...
@@ -402,10 +441,11 @@ public class EntityResource {
LOG
.
debug
(
"partially updating entity for guid {} : {} "
,
guid
,
entityJson
);
}
Referenceable
updatedEntity
=
InstanceSerialization
.
fromJsonReferenceable
(
entityJson
,
true
);
CreateUpdateEntitiesResult
result
=
metadataService
.
updateEntityPartialByGuid
(
guid
,
updatedEntity
);
Referenceable
updatedEntity
=
InstanceSerialization
.
fromJsonReferenceable
(
entityJson
,
true
);
AtlasEntitiesWithExtInfo
entitiesInfo
=
restAdapters
.
toAtlasEntity
(
updatedEntity
);
AtlasEntity
entity
=
entitiesInfo
.
getEntity
(
updatedEntity
.
getId
().
_getId
());
EntityMutationResponse
mutationResponse
=
entitiesStore
.
updateByGuid
(
getEntityType
(
updatedEntity
.
getTypeName
()),
guid
,
entity
);
CreateUpdateEntitiesResult
result
=
restAdapters
.
toCreateUpdateEntitiesResult
(
mutationResponse
);
if
(
LOG
.
isDebugEnabled
())
{
LOG
.
debug
(
"Updated entities: {}"
,
result
.
getEntityResult
());
...
...
@@ -435,7 +475,7 @@ public class EntityResource {
* @postbody property's value
* @return response payload as json
*/
private
Response
updateEntityAttribute
ByGuid
(
String
guid
,
String
property
,
HttpServletRequest
request
)
{
private
Response
partialUpdateEntityAttr
ByGuid
(
String
guid
,
String
property
,
HttpServletRequest
request
)
{
String
value
=
null
;
try
{
Preconditions
.
checkNotNull
(
property
,
"Entity property cannot be null"
);
...
...
@@ -446,7 +486,8 @@ public class EntityResource {
LOG
.
debug
(
"Updating entity {} for property {} = {}"
,
guid
,
property
,
value
);
}
CreateUpdateEntitiesResult
result
=
metadataService
.
updateEntityAttributeByGuid
(
guid
,
property
,
value
);
EntityMutationResponse
mutationResponse
=
entitiesStore
.
updateEntityAttributeByGuid
(
guid
,
property
,
value
);
CreateUpdateEntitiesResult
result
=
restAdapters
.
toCreateUpdateEntitiesResult
(
mutationResponse
);
if
(
LOG
.
isDebugEnabled
())
{
LOG
.
debug
(
"Updated entities: {}"
,
result
.
getEntityResult
());
...
...
@@ -482,8 +523,8 @@ public class EntityResource {
@Produces
(
Servlets
.
JSON_MEDIA_TYPE
)
public
Response
deleteEntities
(
@QueryParam
(
"guid"
)
List
<
String
>
guids
,
@QueryParam
(
"type"
)
String
entityType
,
@QueryParam
(
"property"
)
String
attribute
,
@QueryParam
(
"value"
)
String
value
)
{
@QueryParam
(
"property"
)
final
String
attribute
,
@QueryParam
(
"value"
)
final
String
value
)
{
if
(
LOG
.
isDebugEnabled
())
{
LOG
.
debug
(
"==> EntityResource.deleteEntities({}, {}, {}, {})"
,
guids
,
entityType
,
attribute
,
value
);
}
...
...
@@ -494,19 +535,26 @@ public class EntityResource {
perf
=
AtlasPerfTracer
.
getPerfTracer
(
PERF_LOG
,
"EntityResource.deleteEntities("
+
guids
+
", "
+
entityType
+
", "
+
attribute
+
", "
+
value
+
")"
);
}
AtlasClient
.
EntityResult
entityResult
;
EntityResult
entityResult
;
EntityREST
entityREST
=
resourceContext
.
getResource
(
EntityREST
.
class
);
if
(
guids
!=
null
&&
!
guids
.
isEmpty
())
{
if
(
LOG
.
isDebugEnabled
())
{
LOG
.
debug
(
"Deleting entities {}"
,
guids
);
}
entityResult
=
metadataService
.
deleteEntities
(
guids
);
EntityMutationResponse
mutationResponse
=
entityREST
.
deleteByGuids
(
guids
);
entityResult
=
restAdapters
.
toCreateUpdateEntitiesResult
(
mutationResponse
).
getEntityResult
();
}
else
{
if
(
LOG
.
isDebugEnabled
())
{
LOG
.
debug
(
"Deleting entity type={} with property {}={}"
,
entityType
,
attribute
,
value
);
}
entityResult
=
metadataService
.
deleteEntityByUniqueAttribute
(
entityType
,
attribute
,
value
);
Map
<
String
,
Object
>
attributes
=
new
HashMap
<>();
attributes
.
put
(
attribute
,
value
);
EntityMutationResponse
mutationResponse
=
entitiesStore
.
deleteByUniqueAttributes
(
getEntityType
(
entityType
),
attributes
);
entityResult
=
restAdapters
.
toCreateUpdateEntitiesResult
(
mutationResponse
).
getEntityResult
();
}
if
(
LOG
.
isDebugEnabled
())
{
...
...
@@ -634,7 +682,7 @@ public class EntityResource {
@Produces
(
Servlets
.
JSON_MEDIA_TYPE
)
public
Response
getEntity
(
@QueryParam
(
"type"
)
String
entityType
,
@QueryParam
(
"property"
)
String
attribute
,
@QueryParam
(
"value"
)
String
value
)
{
@QueryParam
(
"value"
)
final
String
value
)
{
if
(
LOG
.
isDebugEnabled
())
{
LOG
.
debug
(
"==> EntityResource.getEntity({}, {}, {})"
,
entityType
,
attribute
,
value
);
}
...
...
@@ -678,7 +726,26 @@ public class EntityResource {
attribute
=
ParamChecker
.
notEmpty
(
attribute
,
"attribute name cannot be null"
);
value
=
ParamChecker
.
notEmpty
(
value
,
"attribute value cannot be null"
);
final
String
entityDefinition
=
metadataService
.
getEntityDefinition
(
entityType
,
attribute
,
value
);
Map
<
String
,
Object
>
attributes
=
new
HashMap
<>();
attributes
.
put
(
attribute
,
value
);
AtlasEntityWithExtInfo
entityInfo
;
try
{
entityInfo
=
entitiesStore
.
getByUniqueAttributes
(
getEntityType
(
entityType
),
attributes
);
}
catch
(
AtlasBaseException
e
)
{
LOG
.
error
(
"Cannot find entity with type: {0}, attribute: {1} and value: {2}"
,
entityType
,
attribute
,
value
);
throw
new
WebApplicationException
(
Servlets
.
getErrorResponse
(
e
,
Response
.
Status
.
BAD_REQUEST
));
}
String
entityDefinition
=
null
;
if
(
entityInfo
!=
null
)
{
AtlasEntity
entity
=
entityInfo
.
getEntity
();
final
ITypedReferenceableInstance
instance
=
restAdapters
.
getITypedReferenceable
(
entity
);
entityDefinition
=
InstanceSerialization
.
toJson
(
instance
,
true
);
}
JSONObject
response
=
new
JSONObject
();
response
.
put
(
AtlasClient
.
REQUEST_ID
,
Servlets
.
getRequestId
());
...
...
@@ -694,10 +761,7 @@ public class EntityResource {
return
Response
.
status
(
status
).
entity
(
response
).
build
();
}
catch
(
EntityNotFoundException
e
)
{
LOG
.
error
(
"An entity with type={} and qualifiedName={} does not exist"
,
entityType
,
value
,
e
);
throw
new
WebApplicationException
(
Servlets
.
getErrorResponse
(
e
,
Response
.
Status
.
NOT_FOUND
));
}
catch
(
AtlasException
|
IllegalArgumentException
e
)
{
}
catch
(
IllegalArgumentException
e
)
{
LOG
.
error
(
"Bad type={}, qualifiedName={}"
,
entityType
,
value
,
e
);
throw
new
WebApplicationException
(
Servlets
.
getErrorResponse
(
e
,
Response
.
Status
.
BAD_REQUEST
));
}
catch
(
Throwable
e
)
{
...
...
@@ -1032,4 +1096,8 @@ public class EntityResource {
}
return
jsonArray
;
}
private
AtlasEntityType
getEntityType
(
String
typeName
)
{
return
typeRegistry
.
getEntityTypeByName
(
typeName
);
}
}
webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java
View file @
765d556c
...
...
@@ -155,13 +155,30 @@ public class EntityREST {
return
entitiesStore
.
updateByUniqueAttributes
(
entityType
,
uniqueAttributes
,
entity
);
}
/*******
* Entity Partial Update - Add/Update entity attribute identified by its GUID.
* Supports only uprimitive attribute type and entity references.
* does not support updation of complex types like arrays, maps
* Null updates are not possible
*******/
@PUT
@Consumes
(
Servlets
.
JSON_MEDIA_TYPE
)
@Produces
(
Servlets
.
JSON_MEDIA_TYPE
)
@Path
(
"/guid/{guid}"
)
public
EntityMutationResponse
partialUpdateByGuid
(
@PathParam
(
"guid"
)
String
guid
,
@QueryParam
(
"name"
)
String
attrName
,
Object
attrValue
)
throws
Exception
{
return
entitiesStore
.
updateEntityAttributeByGuid
(
guid
,
attrName
,
attrValue
);
}
/**
* Delete an entity identified by its GUID.
* @param guid GUID for the entity
* @return EntityMutationResponse
*/
@DELETE
@Path
(
"guid/{guid}"
)
@Path
(
"
/
guid/{guid}"
)
@Consumes
({
Servlets
.
JSON_MEDIA_TYPE
,
MediaType
.
APPLICATION_JSON
})
@Produces
(
Servlets
.
JSON_MEDIA_TYPE
)
public
EntityMutationResponse
deleteByGuid
(
@PathParam
(
"guid"
)
final
String
guid
)
throws
AtlasBaseException
{
...
...
webapp/src/test/java/org/apache/atlas/web/resources/EntityResourceTest.java
View file @
765d556c
...
...
@@ -6,9 +6,9 @@
* 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
*
*
<p>
* http://www.apache.org/licenses/LICENSE-2.0
*
*
<p>
* 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.
...
...
@@ -21,13 +21,22 @@ import static org.mockito.Mockito.never;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
javax.ws.rs.core.Response
;
import
com.vividsolutions.jts.util.CollectionUtil
;
import
org.apache.atlas.AtlasClient.EntityResult
;
import
org.apache.atlas.model.instance.AtlasEntityHeader
;
import
org.apache.atlas.model.instance.EntityMutationResponse
;
import
org.apache.atlas.model.instance.EntityMutations
;
import
org.apache.atlas.repository.converters.AtlasInstanceConverter
;
import
org.apache.atlas.repository.store.graph.AtlasEntityStore
;
import
org.apache.atlas.services.MetadataService
;
import
org.apache.atlas.type.AtlasTypeRegistry
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.mockito.Matchers
;
import
org.mockito.Mock
;
import
org.mockito.MockitoAnnotations
;
...
...
@@ -42,8 +51,9 @@ public class EntityResourceTest {
private
static
final
String
DELETED_GUID
=
"deleted_guid"
;
@Mock
MetadataService
mockServic
e
;
AtlasEntityStore
entitiesStor
e
;
@BeforeMethod
public
void
setUp
()
{
...
...
@@ -53,22 +63,35 @@ public class EntityResourceTest {
@Test
public
void
testDeleteEntitiesDoesNotLookupDeletedEntity
()
throws
Exception
{
List
<
String
>
guids
=
Collections
.
singletonList
(
DELETED_GUID
);
List
<
AtlasEntityHeader
>
deletedEntities
=
Collections
.
singletonList
(
new
AtlasEntityHeader
(
null
,
DELETED_GUID
,
null
));
// Create EntityResult with a deleted guid and no other guids.
EntityResult
entityResult
=
new
EntityResult
(
Collections
.<
String
>
emptyList
(),
Collections
.<
String
>
emptyList
(),
guids
);
when
(
mockService
.
deleteEntities
(
guids
)).
thenReturn
(
entityResult
);
EntityMutationResponse
resp
=
new
EntityMutationResponse
();
List
<
AtlasEntityHeader
>
headers
=
toAtlasEntityHeaders
(
guids
);
for
(
AtlasEntityHeader
entity
:
headers
)
{
resp
.
addEntity
(
EntityMutations
.
EntityOperation
.
DELETE
,
entity
);
}
// Create EntityResource with mock MetadataService.
EntityResource
entityResource
=
new
EntityResource
(
mockService
);
when
(
entitiesStore
.
deleteByIds
(
guids
)).
thenReturn
(
resp
);
Response
response
=
entityResource
.
deleteEntities
(
guids
,
null
,
null
,
null
);
EntityMutationResponse
response
=
entitiesStore
.
deleteByIds
(
guids
);
// Verify that if the EntityResult returned by MetadataService includes only deleted guids,
// deleteEntities() does not perform any entity lookup.
verify
(
mockService
,
never
()).
getEntityDefinition
(
Matchers
.
anyString
());
List
<
AtlasEntityHeader
>
responseDeletedEntities
=
response
.
getDeletedEntities
();
Assert
.
assertEquals
(
responseDeletedEntities
,
deletedEntities
);
}
private
List
<
AtlasEntityHeader
>
toAtlasEntityHeaders
(
List
<
String
>
guids
)
{
List
<
AtlasEntityHeader
>
ret
=
null
;
if
(
CollectionUtils
.
isNotEmpty
(
guids
))
{
ret
=
new
ArrayList
<>(
guids
.
size
());
for
(
String
guid
:
guids
)
{
ret
.
add
(
new
AtlasEntityHeader
(
null
,
guid
,
null
));
}
}
EntityResult
resultFromEntityResource
=
EntityResult
.
fromString
(
response
.
getEntity
().
toString
());
Assert
.
assertTrue
(
resultFromEntityResource
.
getDeletedEntities
().
contains
(
DELETED_GUID
));
return
ret
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment