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
705014eb
Commit
705014eb
authored
9 years ago
by
Shwetha GS
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ATLAS-716 Entity update/delete notifications (shwethags)
parent
153fc362
Hide whitespace changes
Inline
Side-by-side
Showing
40 changed files
with
1340 additions
and
645 deletions
+1340
-645
HiveMetaStoreBridge.java
...ava/org/apache/atlas/hive/bridge/HiveMetaStoreBridge.java
+1
-1
HiveHookIT.java
.../src/test/java/org/apache/atlas/hive/hook/HiveHookIT.java
+34
-31
AtlasClient.java
client/src/main/java/org/apache/atlas/AtlasClient.java
+91
-21
EntityAuditEvent.java
client/src/main/java/org/apache/atlas/EntityAuditEvent.java
+29
-11
SerDe.java
client/src/main/java/org/apache/atlas/SerDe.java
+79
-0
AtlasClientTest.java
client/src/test/java/org/apache/atlas/AtlasClientTest.java
+26
-0
MessageVersion.java
...in/java/org/apache/atlas/notification/MessageVersion.java
+5
-0
NotificationInterface.java
.../org/apache/atlas/notification/NotificationInterface.java
+1
-1
VersionedMessageDeserializer.java
...ache/atlas/notification/VersionedMessageDeserializer.java
+5
-7
AbstractNotificationConsumerTest.java
.../atlas/notification/AbstractNotificationConsumerTest.java
+9
-5
release-log.txt
release-log.txt
+1
-0
MetadataRepository.java
.../java/org/apache/atlas/repository/MetadataRepository.java
+4
-4
EntityAuditListener.java
...rg/apache/atlas/repository/audit/EntityAuditListener.java
+3
-2
HBaseBasedAuditRepository.java
...che/atlas/repository/audit/HBaseBasedAuditRepository.java
+3
-0
DeleteHandler.java
...java/org/apache/atlas/repository/graph/DeleteHandler.java
+79
-57
GraphBackedMetadataRepository.java
...atlas/repository/graph/GraphBackedMetadataRepository.java
+13
-9
GraphHelper.java
...n/java/org/apache/atlas/repository/graph/GraphHelper.java
+40
-19
GraphToTypedInstanceMapper.java
...he/atlas/repository/graph/GraphToTypedInstanceMapper.java
+7
-6
HardDeleteHandler.java
.../org/apache/atlas/repository/graph/HardDeleteHandler.java
+3
-5
SoftDeleteHandler.java
.../org/apache/atlas/repository/graph/SoftDeleteHandler.java
+21
-11
TypedInstanceToGraphMapper.java
...he/atlas/repository/graph/TypedInstanceToGraphMapper.java
+101
-80
GraphBackedTypeStore.java
...ache/atlas/repository/typestore/GraphBackedTypeStore.java
+4
-17
DefaultMetadataService.java
...ava/org/apache/atlas/services/DefaultMetadataService.java
+38
-34
AuditRepositoryTestBase.java
...pache/atlas/repository/audit/AuditRepositoryTestBase.java
+6
-4
GraphBackedMetadataRepositoryDeleteTestBase.java
...ry/graph/GraphBackedMetadataRepositoryDeleteTestBase.java
+136
-85
GraphBackedRepositoryHardDeleteTest.java
...repository/graph/GraphBackedRepositoryHardDeleteTest.java
+60
-3
GraphBackedRepositorySoftDeleteTest.java
...repository/graph/GraphBackedRepositorySoftDeleteTest.java
+94
-5
DefaultMetadataServiceTest.java
.../org/apache/atlas/service/DefaultMetadataServiceTest.java
+175
-109
RequestContext.java
...er-api/src/main/java/org/apache/atlas/RequestContext.java
+16
-3
MetadataService.java
.../main/java/org/apache/atlas/services/MetadataService.java
+12
-9
Referenceable.java
.../main/java/org/apache/atlas/typesystem/Referenceable.java
+1
-1
LocalAtlasClient.java
webapp/src/main/java/org/apache/atlas/LocalAtlasClient.java
+11
-11
NotificationEntityChangeListener.java
.../atlas/notification/NotificationEntityChangeListener.java
+58
-3
EntityResource.java
...n/java/org/apache/atlas/web/resources/EntityResource.java
+47
-50
ServiceModule.java
...main/java/org/apache/atlas/web/service/ServiceModule.java
+1
-1
LocalAtlasClientTest.java
.../src/test/java/org/apache/atlas/LocalAtlasClientTest.java
+12
-9
EntityNotificationIT.java
...a/org/apache/atlas/notification/EntityNotificationIT.java
+0
-2
NotificationEntityChangeListenerTest.java
...as/notification/NotificationEntityChangeListenerTest.java
+90
-0
EntityJerseyResourceIT.java
...rg/apache/atlas/web/resources/EntityJerseyResourceIT.java
+24
-24
CuratorFactoryTest.java
...java/org/apache/atlas/web/service/CuratorFactoryTest.java
+0
-5
No files found.
addons/hive-bridge/src/main/java/org/apache/atlas/hive/bridge/HiveMetaStoreBridge.java
View file @
705014eb
...
...
@@ -188,7 +188,7 @@ public class HiveMetaStoreBridge {
List
<
String
>
guids
=
getAtlasClient
().
createEntity
(
entityJSON
);
LOG
.
debug
(
"created instance for type "
+
typeName
+
", guid: "
+
guids
);
return
new
Referenceable
(
guids
.
get
(
0
),
referenceable
.
getTypeName
(),
null
);
return
new
Referenceable
(
guids
.
get
(
guids
.
size
()
-
1
),
referenceable
.
getTypeName
(),
null
);
}
/**
...
...
This diff is collapsed.
Click to expand it.
addons/hive-bridge/src/test/java/org/apache/atlas/hive/hook/HiveHookIT.java
View file @
705014eb
...
...
@@ -29,7 +29,6 @@ import org.apache.atlas.hive.bridge.HiveMetaStoreBridge;
import
org.apache.atlas.hive.model.HiveDataModelGenerator
;
import
org.apache.atlas.hive.model.HiveDataTypes
;
import
org.apache.atlas.hive.rewrite.HiveASTRewriter
;
import
org.apache.atlas.hive.rewrite.RewriteException
;
import
org.apache.atlas.typesystem.Referenceable
;
import
org.apache.atlas.typesystem.Struct
;
import
org.apache.atlas.typesystem.persistence.Id
;
...
...
@@ -66,6 +65,7 @@ import java.util.Map;
import
static
org
.
apache
.
atlas
.
hive
.
hook
.
HiveHook
.
lower
;
import
static
org
.
apache
.
atlas
.
hive
.
hook
.
HiveHook
.
normalize
;
import
static
org
.
apache
.
atlas
.
hive
.
model
.
HiveDataModelGenerator
.
NAME
;
import
static
org
.
testng
.
Assert
.
assertEquals
;
import
static
org
.
testng
.
Assert
.
assertNotNull
;
import
static
org
.
testng
.
Assert
.
fail
;
...
...
@@ -197,8 +197,8 @@ public class HiveHookIT {
Assert
.
assertEquals
(
tableRef
.
get
(
HiveDataModelGenerator
.
TABLE_TYPE_ATTR
),
TableType
.
MANAGED_TABLE
.
name
());
Assert
.
assertEquals
(
tableRef
.
get
(
HiveDataModelGenerator
.
COMMENT
),
"table comment"
);
String
entityName
=
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
DEFAULT_DB
,
tableName
);
Assert
.
assertEquals
(
tableRef
.
get
(
HiveDataModelGenerator
.
NAME
),
entityName
);
Assert
.
assertEquals
(
tableRef
.
get
(
HiveDataModelGenerator
.
NAME
),
"default."
+
tableName
.
toLowerCase
()
+
"@"
+
CLUSTER_NAME
);
Assert
.
assertEquals
(
tableRef
.
get
(
NAME
),
entityName
);
Assert
.
assertEquals
(
tableRef
.
get
(
NAME
),
"default."
+
tableName
.
toLowerCase
()
+
"@"
+
CLUSTER_NAME
);
Table
t
=
hiveMetaStoreBridge
.
hiveClient
.
getTable
(
DEFAULT_DB
,
tableName
);
long
createTime
=
Long
.
parseLong
(
t
.
getMetadata
().
getProperty
(
hive_metastoreConstants
.
DDL_TIME
))
*
HiveMetaStoreBridge
.
MILLIS_CONVERT_FACTOR
;
...
...
@@ -631,7 +631,7 @@ public class HiveHookIT {
final
String
newDBName
=
createDatabase
();
assertTableIsRegistered
(
DEFAULT_DB
,
tableName
);
String
columnGuid
=
assertColumnIsRegistered
(
HiveMetaStoreBridge
.
getColumnQualifiedName
(
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
DEFAULT_DB
,
tableName
),
HiveDataModelGenerator
.
NAME
));
String
columnGuid
=
assertColumnIsRegistered
(
HiveMetaStoreBridge
.
getColumnQualifiedName
(
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
DEFAULT_DB
,
tableName
),
NAME
));
String
sdGuid
=
assertSDIsRegistered
(
HiveMetaStoreBridge
.
getStorageDescQFName
(
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
DEFAULT_DB
,
tableName
)),
null
);
assertDatabaseIsRegistered
(
newDBName
);
...
...
@@ -649,10 +649,10 @@ public class HiveHookIT {
String
query
=
String
.
format
(
"alter table %s rename to %s"
,
DEFAULT_DB
+
"."
+
tableName
,
newDBName
+
"."
+
newTableName
);
runCommand
(
query
);
String
newColGuid
=
assertColumnIsRegistered
(
HiveMetaStoreBridge
.
getColumnQualifiedName
(
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
newDBName
,
newTableName
),
HiveDataModelGenerator
.
NAME
));
String
newColGuid
=
assertColumnIsRegistered
(
HiveMetaStoreBridge
.
getColumnQualifiedName
(
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
newDBName
,
newTableName
),
NAME
));
Assert
.
assertEquals
(
newColGuid
,
columnGuid
);
assertColumnIsNotRegistered
(
HiveMetaStoreBridge
.
getColumnQualifiedName
(
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
newDBName
,
tableName
),
HiveDataModelGenerator
.
NAME
));
assertColumnIsNotRegistered
(
HiveMetaStoreBridge
.
getColumnQualifiedName
(
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
newDBName
,
tableName
),
NAME
));
assertTrait
(
columnGuid
,
colTraitDetails
);
String
newSdGuid
=
assertSDIsRegistered
(
HiveMetaStoreBridge
.
getStorageDescQFName
(
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
newDBName
,
newTableName
)),
null
);
...
...
@@ -676,7 +676,16 @@ public class HiveHookIT {
private
List
<
Referenceable
>
getColumns
(
String
dbName
,
String
tableName
)
throws
Exception
{
String
tableId
=
assertTableIsRegistered
(
dbName
,
tableName
);
Referenceable
tableRef
=
atlasClient
.
getEntity
(
tableId
);
return
((
List
<
Referenceable
>)
tableRef
.
get
(
HiveDataModelGenerator
.
COLUMNS
));
//with soft delete, the deleted columns are returned as well. So, filter the deleted ones
List
<
Referenceable
>
columns
=
((
List
<
Referenceable
>)
tableRef
.
get
(
HiveDataModelGenerator
.
COLUMNS
));
List
<
Referenceable
>
activeColumns
=
new
ArrayList
<>();
for
(
Referenceable
col
:
columns
)
{
if
(
col
.
getId
().
getState
()
==
Id
.
EntityState
.
ACTIVE
)
{
activeColumns
.
add
(
col
);
}
}
return
activeColumns
;
}
...
...
@@ -723,21 +732,15 @@ public class HiveHookIT {
colDropped
));
//Verify the number of columns present in the table
assertTableIsRegistered
(
DEFAULT_DB
,
tableName
,
new
AssertPredicate
()
{
@Override
public
void
assertOnEntity
(
Referenceable
tableRef
)
throws
Exception
{
List
<
Referenceable
>
columns
=
(
List
<
Referenceable
>)
tableRef
.
get
(
HiveDataModelGenerator
.
COLUMNS
);
Assert
.
assertEquals
(
columns
.
size
(),
1
);
Assert
.
assertEquals
(
columns
.
get
(
0
).
get
(
HiveDataModelGenerator
.
NAME
),
HiveDataModelGenerator
.
NAME
);
}
});
List
<
Referenceable
>
columns
=
getColumns
(
DEFAULT_DB
,
tableName
);
assertEquals
(
columns
.
size
(),
1
);
assertEquals
(
columns
.
get
(
0
).
get
(
NAME
),
"name"
);
}
@Test
public
void
testAlterTableChangeColumn
()
throws
Exception
{
//Change name
String
oldColName
=
HiveDataModelGenerator
.
NAME
;
String
oldColName
=
NAME
;
String
newColName
=
"name1"
;
String
tableName
=
createTable
();
String
query
=
String
.
format
(
"alter table %s change %s %s string"
,
tableName
,
oldColName
,
newColName
);
...
...
@@ -818,8 +821,8 @@ public class HiveHookIT {
@Override
public
void
assertOnEntity
(
Referenceable
entity
)
throws
Exception
{
List
<
Referenceable
>
columns
=
(
List
<
Referenceable
>)
entity
.
get
(
HiveDataModelGenerator
.
COLUMNS
);
assertEquals
(
columns
.
get
(
0
).
get
(
HiveDataModelGenerator
.
NAME
),
finalNewColName
);
assertEquals
(
columns
.
get
(
1
).
get
(
HiveDataModelGenerator
.
NAME
),
"id"
);
assertEquals
(
columns
.
get
(
0
).
get
(
NAME
),
finalNewColName
);
assertEquals
(
columns
.
get
(
1
).
get
(
NAME
),
"id"
);
}
}
);
...
...
@@ -846,8 +849,8 @@ public class HiveHookIT {
@Override
public
void
assertOnEntity
(
Referenceable
entity
)
throws
Exception
{
List
<
Referenceable
>
columns
=
(
List
<
Referenceable
>)
entity
.
get
(
HiveDataModelGenerator
.
COLUMNS
);
assertEquals
(
columns
.
get
(
1
).
get
(
HiveDataModelGenerator
.
NAME
),
finalNewColName2
);
assertEquals
(
columns
.
get
(
0
).
get
(
HiveDataModelGenerator
.
NAME
),
"id"
);
assertEquals
(
columns
.
get
(
1
).
get
(
NAME
),
finalNewColName2
);
assertEquals
(
columns
.
get
(
0
).
get
(
NAME
),
"id"
);
}
}
);
...
...
@@ -955,7 +958,7 @@ public class HiveHookIT {
Referenceable
hdfsPathRef
=
atlasClient
.
getEntity
(
hdfsPathId
);
Assert
.
assertEquals
(
hdfsPathRef
.
get
(
"path"
),
testPathNormed
);
Assert
.
assertEquals
(
hdfsPathRef
.
get
(
HiveDataModelGenerator
.
NAME
),
testPathNormed
);
Assert
.
assertEquals
(
hdfsPathRef
.
get
(
NAME
),
testPathNormed
);
// Assert.assertEquals(hdfsPathRef.get("name"), new Path(testPath).getName());
Assert
.
assertEquals
(
hdfsPathRef
.
get
(
AtlasClient
.
REFERENCEABLE_ATTRIBUTE_NAME
),
testPathNormed
);
...
...
@@ -964,7 +967,7 @@ public class HiveHookIT {
private
String
assertHDFSPathIsRegistered
(
String
path
)
throws
Exception
{
LOG
.
debug
(
"Searching for hdfs path {}"
,
path
);
return
assertEntityIsRegistered
(
FSDataTypes
.
HDFS_PATH
().
toString
(),
HiveDataModelGenerator
.
NAME
,
path
,
null
);
return
assertEntityIsRegistered
(
FSDataTypes
.
HDFS_PATH
().
toString
(),
NAME
,
path
,
null
);
}
@Test
...
...
@@ -1014,7 +1017,7 @@ public class HiveHookIT {
ImmutableList
<
String
>
cols
=
ImmutableList
.
of
(
"id"
);
runBucketSortQuery
(
tableName
,
5
,
cols
,
cols
);
cols
=
ImmutableList
.
of
(
"id"
,
HiveDataModelGenerator
.
NAME
);
cols
=
ImmutableList
.
of
(
"id"
,
NAME
);
runBucketSortQuery
(
tableName
,
2
,
cols
,
cols
);
}
...
...
@@ -1077,7 +1080,7 @@ public class HiveHookIT {
assertTableIsRegistered
(
DEFAULT_DB
,
tableName
);
assertColumnIsRegistered
(
HiveMetaStoreBridge
.
getColumnQualifiedName
(
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
DEFAULT_DB
,
tableName
),
"id"
));
assertColumnIsRegistered
(
HiveMetaStoreBridge
.
getColumnQualifiedName
(
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
DEFAULT_DB
,
tableName
),
HiveDataModelGenerator
.
NAME
));
assertColumnIsRegistered
(
HiveMetaStoreBridge
.
getColumnQualifiedName
(
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
DEFAULT_DB
,
tableName
),
NAME
));
final
String
query
=
String
.
format
(
"drop table %s "
,
tableName
);
runCommand
(
query
);
...
...
@@ -1086,7 +1089,7 @@ public class HiveHookIT {
"id"
));
assertColumnIsNotRegistered
(
HiveMetaStoreBridge
.
getColumnQualifiedName
(
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
DEFAULT_DB
,
tableName
),
HiveDataModelGenerator
.
NAME
));
NAME
));
assertTableIsNotRegistered
(
DEFAULT_DB
,
tableName
);
}
...
...
@@ -1110,7 +1113,7 @@ public class HiveHookIT {
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
dbName
,
tableNames
[
0
]),
"id"
));
assertColumnIsNotRegistered
(
HiveMetaStoreBridge
.
getColumnQualifiedName
(
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
dbName
,
tableNames
[
0
]),
HiveDataModelGenerator
.
NAME
));
NAME
));
for
(
int
i
=
0
;
i
<
numTables
;
i
++)
{
assertTableIsNotRegistered
(
dbName
,
tableNames
[
i
]);
...
...
@@ -1175,7 +1178,7 @@ public class HiveHookIT {
assertTableIsRegistered
(
DEFAULT_DB
,
viewName
);
assertColumnIsRegistered
(
HiveMetaStoreBridge
.
getColumnQualifiedName
(
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
DEFAULT_DB
,
viewName
),
"id"
));
assertColumnIsRegistered
(
HiveMetaStoreBridge
.
getColumnQualifiedName
(
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
DEFAULT_DB
,
viewName
),
HiveDataModelGenerator
.
NAME
));
assertColumnIsRegistered
(
HiveMetaStoreBridge
.
getColumnQualifiedName
(
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
DEFAULT_DB
,
viewName
),
NAME
));
query
=
String
.
format
(
"drop view %s "
,
viewName
);
...
...
@@ -1185,7 +1188,7 @@ public class HiveHookIT {
"id"
));
assertColumnIsNotRegistered
(
HiveMetaStoreBridge
.
getColumnQualifiedName
(
HiveMetaStoreBridge
.
getTableQualifiedName
(
CLUSTER_NAME
,
DEFAULT_DB
,
viewName
),
HiveDataModelGenerator
.
NAME
));
NAME
));
assertTableIsNotRegistered
(
DEFAULT_DB
,
viewName
);
}
...
...
@@ -1349,7 +1352,7 @@ public class HiveHookIT {
if
(
inputTblName
!=
null
)
{
Referenceable
inputTableRef
=
new
Referenceable
(
HiveDataTypes
.
HIVE_TABLE
.
name
(),
new
HashMap
<
String
,
Object
>()
{{
put
(
HiveDataModelGenerator
.
NAME
,
inputTblName
);
put
(
NAME
,
inputTblName
);
}});
inputs
=
new
ArrayList
<
Referenceable
>();
inputs
.
add
(
inputTableRef
);
...
...
@@ -1357,7 +1360,7 @@ public class HiveHookIT {
List
<
Referenceable
>
outputs
=
null
;
if
(
outputTblName
!=
null
)
{
Referenceable
outputTableRef
=
new
Referenceable
(
HiveDataTypes
.
HIVE_TABLE
.
name
(),
new
HashMap
<
String
,
Object
>()
{{
put
(
HiveDataModelGenerator
.
NAME
,
outputTblName
);
put
(
NAME
,
outputTblName
);
}});
outputs
=
new
ArrayList
<
Referenceable
>();
...
...
This diff is collapsed.
Click to expand it.
client/src/main/java/org/apache/atlas/AtlasClient.java
View file @
705014eb
...
...
@@ -20,11 +20,14 @@ package org.apache.atlas;
import
com.google.common.annotations.VisibleForTesting
;
import
com.google.common.collect.ImmutableSet
;
import
com.google.gson.Gson
;
import
com.google.gson.GsonBuilder
;
import
com.sun.jersey.api.client.Client
;
import
com.sun.jersey.api.client.ClientHandlerException
;
import
com.sun.jersey.api.client.ClientResponse
;
import
com.sun.jersey.api.client.WebResource
;
import
com.sun.jersey.api.client.config.DefaultClientConfig
;
import
com.sun.jersey.api.client.filter.HTTPBasicAuthFilter
;
import
com.sun.jersey.client.urlconnection.URLConnectionClientHandler
;
import
org.apache.atlas.security.SecureClientUtils
;
import
org.apache.atlas.typesystem.Referenceable
;
...
...
@@ -45,6 +48,7 @@ import org.codehaus.jettison.json.JSONException;
import
org.codehaus.jettison.json.JSONObject
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
javax.ws.rs.HttpMethod
;
import
javax.ws.rs.core.MediaType
;
import
javax.ws.rs.core.Response
;
...
...
@@ -54,8 +58,10 @@ import java.net.ConnectException;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.HashMap
;
import
java.util.List
;
import
com.sun.jersey.api.client.filter.HTTPBasicAuthFilter
;
import
java.util.Map
;
import
static
org
.
apache
.
atlas
.
security
.
SecurityProperties
.
TLS_ENABLED
;
/**
...
...
@@ -65,9 +71,10 @@ public class AtlasClient {
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
AtlasClient
.
class
);
public
static
final
String
NAME
=
"name"
;
public
static
final
String
GUID
=
"GUID"
;
public
static
final
String
TYPE
=
"type"
;
public
static
final
String
TYPENAME
=
"typeName"
;
public
static
final
String
GUID
=
"GUID"
;
public
static
final
String
ENTITIES
=
"entities"
;
public
static
final
String
DEFINITION
=
"definition"
;
public
static
final
String
ERROR
=
"error"
;
...
...
@@ -340,6 +347,61 @@ public class AtlasClient {
return
service
;
}
public
static
class
EntityResult
{
private
static
final
Gson
gson
=
new
GsonBuilder
().
setPrettyPrinting
().
create
();
public
static
final
String
OP_CREATED
=
"created"
;
public
static
final
String
OP_UPDATED
=
"updated"
;
public
static
final
String
OP_DELETED
=
"deleted"
;
Map
<
String
,
List
<
String
>>
entities
=
new
HashMap
<>();
public
EntityResult
()
{
//For gson
}
public
EntityResult
(
List
<
String
>
created
,
List
<
String
>
updated
,
List
<
String
>
deleted
)
{
add
(
OP_CREATED
,
created
);
add
(
OP_UPDATED
,
updated
);
add
(
OP_DELETED
,
deleted
);
}
private
void
add
(
String
type
,
List
<
String
>
list
)
{
if
(
list
!=
null
&&
list
.
size
()
>
0
)
{
entities
.
put
(
type
,
list
);
}
}
private
List
<
String
>
get
(
String
type
)
{
List
<
String
>
list
=
entities
.
get
(
type
);
if
(
list
==
null
)
{
list
=
new
ArrayList
<>();
}
return
list
;
}
public
List
<
String
>
getCreatedEntities
()
{
return
get
(
OP_CREATED
);
}
public
List
<
String
>
getUpdateEntities
()
{
return
get
(
OP_UPDATED
);
}
public
List
<
String
>
getDeletedEntities
()
{
return
get
(
OP_DELETED
);
}
@Override
public
String
toString
()
{
return
gson
.
toJson
(
this
);
}
public
static
EntityResult
fromString
(
String
json
)
throws
AtlasServiceException
{
return
gson
.
fromJson
(
json
,
EntityResult
.
class
);
}
}
/**
* Return status of the service instance the client is pointing to.
*
...
...
@@ -562,11 +624,15 @@ public class AtlasClient {
protected
List
<
String
>
createEntity
(
JSONArray
entities
)
throws
AtlasServiceException
{
LOG
.
debug
(
"Creating entities: {}"
,
entities
);
JSONObject
response
=
callAPI
(
API
.
CREATE_ENTITY
,
entities
.
toString
());
List
<
String
>
results
=
extract
Results
(
response
,
GUID
,
new
ExtractOperation
<
String
,
String
>()
);
List
<
String
>
results
=
extract
EntityResult
(
response
).
getCreatedEntities
(
);
LOG
.
debug
(
"Create entities returned results: {}"
,
results
);
return
results
;
}
protected
EntityResult
extractEntityResult
(
JSONObject
response
)
throws
AtlasServiceException
{
return
EntityResult
.
fromString
(
response
.
toString
());
}
/**
* Create the given entity
* @param entitiesAsJson entity(type instance) as json
...
...
@@ -601,19 +667,19 @@ public class AtlasClient {
* @return json array of guids which were updated/created
* @throws AtlasServiceException
*/
public
List
<
String
>
updateEntities
(
Referenceable
...
entities
)
throws
AtlasServiceException
{
public
EntityResult
updateEntities
(
Referenceable
...
entities
)
throws
AtlasServiceException
{
return
updateEntities
(
Arrays
.
asList
(
entities
));
}
protected
List
<
String
>
updateEntities
(
JSONArray
entities
)
throws
AtlasServiceException
{
protected
EntityResult
updateEntities
(
JSONArray
entities
)
throws
AtlasServiceException
{
LOG
.
debug
(
"Updating entities: {}"
,
entities
);
JSONObject
response
=
callAPI
(
API
.
UPDATE_ENTITY
,
entities
.
toString
());
List
<
String
>
results
=
extractResults
(
response
,
GUID
,
new
ExtractOperation
<
String
,
String
>()
);
EntityResult
results
=
extractEntityResult
(
response
);
LOG
.
debug
(
"Update entities returned results: {}"
,
results
);
return
results
;
}
public
List
<
String
>
updateEntities
(
Collection
<
Referenceable
>
entities
)
throws
AtlasServiceException
{
public
EntityResult
updateEntities
(
Collection
<
Referenceable
>
entities
)
throws
AtlasServiceException
{
JSONArray
entitiesArray
=
getEntitiesArray
(
entities
);
return
updateEntities
(
entitiesArray
);
}
...
...
@@ -625,9 +691,10 @@ public class AtlasClient {
* @param attribute property key
* @param value property value
*/
public
void
updateEntityAttribute
(
final
String
guid
,
final
String
attribute
,
String
value
)
throws
AtlasServiceException
{
public
EntityResult
updateEntityAttribute
(
final
String
guid
,
final
String
attribute
,
String
value
)
throws
AtlasServiceException
{
LOG
.
debug
(
"Updating entity id: {}, attribute name: {}, attribute value: {}"
,
guid
,
attribute
,
value
);
callAPIWithRetries
(
API
.
UPDATE_ENTITY_PARTIAL
,
value
,
new
ResourceCreator
()
{
JSONObject
response
=
callAPIWithRetries
(
API
.
UPDATE_ENTITY_PARTIAL
,
value
,
new
ResourceCreator
()
{
@Override
public
WebResource
createResource
()
{
API
api
=
API
.
UPDATE_ENTITY_PARTIAL
;
...
...
@@ -636,6 +703,7 @@ public class AtlasClient {
return
resource
;
}
});
return
extractEntityResult
(
response
);
}
@VisibleForTesting
...
...
@@ -665,10 +733,11 @@ public class AtlasClient {
* @param guid guid
* @param entity entity definition
*/
public
void
updateEntity
(
String
guid
,
Referenceable
entity
)
throws
AtlasServiceException
{
public
EntityResult
updateEntity
(
String
guid
,
Referenceable
entity
)
throws
AtlasServiceException
{
String
entityJson
=
InstanceSerialization
.
toJson
(
entity
,
true
);
LOG
.
debug
(
"Updating entity id {} with {}"
,
guid
,
entityJson
);
callAPI
(
API
.
UPDATE_ENTITY_PARTIAL
,
entityJson
,
guid
);
JSONObject
response
=
callAPI
(
API
.
UPDATE_ENTITY_PARTIAL
,
entityJson
,
guid
);
return
extractEntityResult
(
response
);
}
/**
...
...
@@ -691,8 +760,9 @@ public class AtlasClient {
* @param uniqueAttributeValue Attribute Value that uniquely identifies the entity
* @param entity entity definition
*/
public
String
updateEntity
(
final
String
entityType
,
final
String
uniqueAttributeName
,
final
String
uniqueAttributeValue
,
Referenceable
entity
)
throws
AtlasServiceException
{
public
EntityResult
updateEntity
(
final
String
entityType
,
final
String
uniqueAttributeName
,
final
String
uniqueAttributeValue
,
Referenceable
entity
)
throws
AtlasServiceException
{
final
API
api
=
API
.
UPDATE_ENTITY_PARTIAL
;
String
entityJson
=
InstanceSerialization
.
toJson
(
entity
,
true
);
LOG
.
debug
(
"Updating entity type: {}, attributeName: {}, attributeValue: {}, entity: {}"
,
entityType
,
...
...
@@ -707,7 +777,7 @@ public class AtlasClient {
return
resource
;
}
});
String
result
=
getString
(
response
,
GUID
);
EntityResult
result
=
extractEntityResult
(
response
);
LOG
.
debug
(
"Update entity returned result: {}"
,
result
);
return
result
;
}
...
...
@@ -724,10 +794,10 @@ public class AtlasClient {
* Delete the specified entities from the repository
*
* @param guids guids of entities to delete
* @return List of
deleted entity guids
* @return List of
entity ids updated/deleted
* @throws AtlasServiceException
*/
public
List
<
String
>
deleteEntities
(
final
String
...
guids
)
throws
AtlasServiceException
{
public
EntityResult
deleteEntities
(
final
String
...
guids
)
throws
AtlasServiceException
{
LOG
.
debug
(
"Deleting entities: {}"
,
guids
);
JSONObject
jsonResponse
=
callAPIWithRetries
(
API
.
DELETE_ENTITIES
,
null
,
new
ResourceCreator
()
{
@Override
...
...
@@ -740,7 +810,7 @@ public class AtlasClient {
return
resource
;
}
});
List
<
String
>
results
=
extractResults
(
jsonResponse
,
GUID
,
new
ExtractOperation
<
String
,
String
>()
);
EntityResult
results
=
extractEntityResult
(
jsonResponse
);
LOG
.
debug
(
"Delete entities returned results: {}"
,
results
);
return
results
;
}
...
...
@@ -750,9 +820,9 @@ public class AtlasClient {
* @param entityType Type of the entity being deleted
* @param uniqueAttributeName Attribute Name that uniquely identifies the entity
* @param uniqueAttributeValue Attribute Value that uniquely identifies the entity
* @return List of
deleted entity guids
(including composite references from that entity)
* @return List of
entity ids updated/deleted
(including composite references from that entity)
*/
public
List
<
String
>
deleteEntity
(
String
entityType
,
String
uniqueAttributeName
,
String
uniqueAttributeValue
)
public
EntityResult
deleteEntity
(
String
entityType
,
String
uniqueAttributeName
,
String
uniqueAttributeValue
)
throws
AtlasServiceException
{
LOG
.
debug
(
"Deleting entity type: {}, attributeName: {}, attributeValue: {}"
,
entityType
,
uniqueAttributeName
,
uniqueAttributeValue
);
...
...
@@ -762,7 +832,7 @@ public class AtlasClient {
resource
=
resource
.
queryParam
(
ATTRIBUTE_NAME
,
uniqueAttributeName
);
resource
=
resource
.
queryParam
(
ATTRIBUTE_VALUE
,
uniqueAttributeValue
);
JSONObject
jsonResponse
=
callAPIWithResource
(
API
.
DELETE_ENTITIES
,
resource
,
null
);
List
<
String
>
results
=
extractResults
(
jsonResponse
,
GUID
,
new
ExtractOperation
<
String
,
String
>()
);
EntityResult
results
=
extractEntityResult
(
jsonResponse
);
LOG
.
debug
(
"Delete entities returned results: {}"
,
results
);
return
results
;
}
...
...
@@ -901,7 +971,7 @@ public class AtlasClient {
return
extractResults
(
jsonResponse
,
AtlasClient
.
EVENTS
,
new
ExtractOperation
<
EntityAuditEvent
,
JSONObject
>()
{
@Override
EntityAuditEvent
extractElement
(
JSONObject
element
)
throws
JSONException
{
return
EntityAuditEvent
.
GSON
.
fromJson
(
element
.
toString
(),
EntityAuditEvent
.
class
);
return
SerDe
.
GSON
.
fromJson
(
element
.
toString
(),
EntityAuditEvent
.
class
);
}
});
...
...
This diff is collapsed.
Click to expand it.
client/src/main/java/org/apache/atlas/EntityAuditEvent.java
View file @
705014eb
...
...
@@ -18,16 +18,14 @@
package
org
.
apache
.
atlas
;
import
com.google.gson.Gson
;
import
com.google.gson.GsonBuilder
;
import
org.apache.atlas.typesystem.IReferenceableInstance
;
import
org.apache.atlas.typesystem.json.InstanceSerialization
;
import
org.apache.commons.lang.StringUtils
;
/**
* Structure of entity audit event
*/
public
class
EntityAuditEvent
{
public
static
final
Gson
GSON
=
new
GsonBuilder
().
create
();
public
enum
EntityAuditAction
{
ENTITY_CREATE
,
ENTITY_UPDATE
,
ENTITY_DELETE
,
TAG_ADD
,
TAG_DELETE
}
...
...
@@ -38,16 +36,19 @@ public class EntityAuditEvent {
private
EntityAuditAction
action
;
private
String
details
;
private
String
eventKey
;
private
IReferenceableInstance
entityDefinition
;
public
EntityAuditEvent
()
{
}
public
EntityAuditEvent
(
String
entityId
,
Long
ts
,
String
user
,
EntityAuditAction
action
,
String
details
)
{
public
EntityAuditEvent
(
String
entityId
,
Long
ts
,
String
user
,
EntityAuditAction
action
,
String
details
,
IReferenceableInstance
entityDefinition
)
throws
AtlasException
{
this
.
entityId
=
entityId
;
this
.
timestamp
=
ts
;
this
.
user
=
user
;
this
.
action
=
action
;
this
.
details
=
details
;
this
.
entityDefinition
=
entityDefinition
;
}
@Override
...
...
@@ -62,10 +63,12 @@ public class EntityAuditEvent {
EntityAuditEvent
otherEvent
=
(
EntityAuditEvent
)
other
;
return
StringUtils
.
equals
(
entityId
,
otherEvent
.
entityId
)
&&
(
timestamp
==
otherEvent
.
timestamp
)
&&
StringUtils
.
equals
(
user
,
otherEvent
.
user
)
&&
(
action
==
otherEvent
.
action
)
&&
StringUtils
.
equals
(
details
,
otherEvent
.
details
)
&&
StringUtils
.
equals
(
eventKey
,
otherEvent
.
eventKey
);
(
timestamp
==
otherEvent
.
timestamp
)
&&
StringUtils
.
equals
(
user
,
otherEvent
.
user
)
&&
(
action
==
otherEvent
.
action
)
&&
StringUtils
.
equals
(
details
,
otherEvent
.
details
)
&&
StringUtils
.
equals
(
eventKey
,
otherEvent
.
eventKey
)
&&
StringUtils
.
equals
(
getEntityDefinitionString
(),
otherEvent
.
getEntityDefinitionString
());
}
@Override
...
...
@@ -75,11 +78,11 @@ public class EntityAuditEvent {
@Override
public
String
toString
()
{
return
GSON
.
toJson
(
this
);
return
SerDe
.
GSON
.
toJson
(
this
);
}
public
static
EntityAuditEvent
fromString
(
String
eventString
)
{
return
GSON
.
fromJson
(
eventString
,
EntityAuditEvent
.
class
);
return
SerDe
.
GSON
.
fromJson
(
eventString
,
EntityAuditEvent
.
class
);
}
public
String
getEntityId
()
{
...
...
@@ -129,4 +132,19 @@ public class EntityAuditEvent {
public
void
setEventKey
(
String
eventKey
)
{
this
.
eventKey
=
eventKey
;
}
public
IReferenceableInstance
getEntityDefinition
()
{
return
entityDefinition
;
}
public
String
getEntityDefinitionString
()
{
if
(
entityDefinition
!=
null
)
{
return
InstanceSerialization
.
toJson
(
entityDefinition
,
true
);
}
return
null
;
}
public
void
setEntityDefinition
(
String
entityDefinition
)
{
this
.
entityDefinition
=
InstanceSerialization
.
fromJsonReferenceable
(
entityDefinition
,
true
);
}
}
This diff is collapsed.
Click to expand it.
client/src/main/java/org/apache/atlas/SerDe.java
0 → 100644
View file @
705014eb
/**
* 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
* <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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
apache
.
atlas
;
import
com.google.gson.Gson
;
import
com.google.gson.GsonBuilder
;
import
com.google.gson.JsonDeserializationContext
;
import
com.google.gson.JsonDeserializer
;
import
com.google.gson.JsonElement
;
import
com.google.gson.JsonParser
;
import
com.google.gson.JsonSerializationContext
;
import
com.google.gson.JsonSerializer
;
import
org.apache.atlas.typesystem.IReferenceableInstance
;
import
org.apache.atlas.typesystem.IStruct
;
import
org.apache.atlas.typesystem.Referenceable
;
import
org.apache.atlas.typesystem.Struct
;
import
org.apache.atlas.typesystem.json.InstanceSerialization
;
import
java.lang.reflect.Type
;
public
class
SerDe
{
public
static
final
Gson
GSON
=
new
GsonBuilder
().
registerTypeAdapter
(
IStruct
.
class
,
new
StructDeserializer
()).
registerTypeAdapter
(
IReferenceableInstance
.
class
,
new
ReferenceableSerializerDeserializer
()).
registerTypeAdapter
(
Referenceable
.
class
,
new
ReferenceableSerializerDeserializer
()).
create
();
/**
* Serde for Struct used by AbstractNotificationConsumer.GSON.
*/
public
static
final
class
StructDeserializer
implements
JsonDeserializer
<
IStruct
>,
JsonSerializer
<
IStruct
>
{
@Override
public
IStruct
deserialize
(
final
JsonElement
json
,
final
Type
type
,
final
JsonDeserializationContext
context
)
{
return
context
.
deserialize
(
json
,
Struct
.
class
);
}
@Override
public
JsonElement
serialize
(
IStruct
src
,
Type
typeOfSrc
,
JsonSerializationContext
context
)
{
String
instanceJson
=
InstanceSerialization
.
toJson
(
src
,
true
);
return
new
JsonParser
().
parse
(
instanceJson
).
getAsJsonObject
();
}
}
/**
* Serde for Referenceable used by AbstractNotificationConsumer.GSON.
*/
public
static
final
class
ReferenceableSerializerDeserializer
implements
JsonDeserializer
<
IStruct
>,
JsonSerializer
<
IReferenceableInstance
>
{
@Override
public
IReferenceableInstance
deserialize
(
final
JsonElement
json
,
final
Type
type
,
final
JsonDeserializationContext
context
)
{
return
InstanceSerialization
.
fromJsonReferenceable
(
json
.
toString
(),
true
);
}
@Override
public
JsonElement
serialize
(
IReferenceableInstance
src
,
Type
typeOfSrc
,
JsonSerializationContext
context
)
{
String
instanceJson
=
InstanceSerialization
.
toJson
(
src
,
true
);
return
new
JsonParser
().
parse
(
instanceJson
).
getAsJsonObject
();
}
}
}
This diff is collapsed.
Click to expand it.
client/src/test/java/org/apache/atlas/AtlasClientTest.java
View file @
705014eb
...
...
@@ -21,8 +21,12 @@ import com.sun.jersey.api.client.Client;
import
com.sun.jersey.api.client.ClientHandlerException
;
import
com.sun.jersey.api.client.ClientResponse
;
import
com.sun.jersey.api.client.WebResource
;
import
org.apache.atlas.typesystem.Referenceable
;
import
org.apache.atlas.typesystem.json.InstanceSerialization
;
import
org.apache.commons.configuration.Configuration
;
import
org.apache.hadoop.security.UserGroupInformation
;
import
org.codehaus.jettison.json.JSONObject
;
import
org.mockito.Matchers
;
import
org.mockito.Mock
;
import
org.mockito.MockitoAnnotations
;
import
org.testng.annotations.BeforeMethod
;
...
...
@@ -33,9 +37,12 @@ import javax.ws.rs.core.UriBuilder;
import
java.net.ConnectException
;
import
java.net.URI
;
import
java.net.URISyntaxException
;
import
java.util.Arrays
;
import
java.util.List
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
mockito
.
Matchers
.
anyString
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
...
...
@@ -76,6 +83,25 @@ public class AtlasClientTest {
assertTrue
(
atlasClient
.
isServerReady
());
}
@Test
public
void
testCreateEntity
()
throws
Exception
{
setupRetryParams
();
AtlasClient
atlasClient
=
new
AtlasClient
(
service
,
configuration
);
WebResource
.
Builder
builder
=
setupBuilder
(
AtlasClient
.
API
.
CREATE_ENTITY
,
service
);
ClientResponse
response
=
mock
(
ClientResponse
.
class
);
when
(
response
.
getStatus
()).
thenReturn
(
Response
.
Status
.
CREATED
.
getStatusCode
());
JSONObject
jsonResponse
=
new
JSONObject
(
new
AtlasClient
.
EntityResult
(
Arrays
.
asList
(
"id"
),
null
,
null
).
toString
());
when
(
response
.
getEntity
(
String
.
class
)).
thenReturn
(
jsonResponse
.
toString
());
String
entityJson
=
InstanceSerialization
.
toJson
(
new
Referenceable
(
"type"
),
true
);
when
(
builder
.
method
(
anyString
(),
Matchers
.<
Class
>
any
(),
anyString
())).
thenReturn
(
response
);
List
<
String
>
ids
=
atlasClient
.
createEntity
(
entityJson
);
assertEquals
(
ids
.
size
(),
1
);
assertEquals
(
ids
.
get
(
0
),
"id"
);
}
private
WebResource
.
Builder
setupBuilder
(
AtlasClient
.
API
api
,
WebResource
webResource
)
{
when
(
webResource
.
path
(
api
.
getPath
())).
thenReturn
(
service
);
WebResource
.
Builder
builder
=
getBuilder
(
service
);
...
...
This diff is collapsed.
Click to expand it.
notification/src/main/java/org/apache/atlas/notification/MessageVersion.java
View file @
705014eb
...
...
@@ -97,6 +97,11 @@ public class MessageVersion implements Comparable<MessageVersion> {
}
@Override
public
String
toString
()
{
return
"MessageVersion[version="
+
version
+
"]"
;
}
// ----- helper methods --------------------------------------------------
/**
...
...
This diff is collapsed.
Click to expand it.
notification/src/main/java/org/apache/atlas/notification/NotificationInterface.java
View file @
705014eb
...
...
@@ -17,11 +17,11 @@
*/
package
org
.
apache
.
atlas
.
notification
;
import
com.google.gson.reflect.TypeToken
;
import
org.apache.atlas.notification.entity.EntityMessageDeserializer
;
import
org.apache.atlas.notification.entity.EntityNotification
;
import
org.apache.atlas.notification.hook.HookMessageDeserializer
;
import
org.apache.atlas.notification.hook.HookNotification
;
import
com.google.gson.reflect.TypeToken
;
import
java.lang.reflect.Type
;
import
java.util.List
;
...
...
This diff is collapsed.
Click to expand it.
notification/src/main/java/org/apache/atlas/notification/VersionedMessageDeserializer.java
View file @
705014eb
...
...
@@ -31,7 +31,7 @@ import java.lang.reflect.Type;
public
abstract
class
VersionedMessageDeserializer
<
T
>
implements
MessageDeserializer
<
T
>
{
public
static
final
String
VERSION_MISMATCH_MSG
=
"Notification message version mismatch.
Expected %s but recieved
%s"
;
"Notification message version mismatch.
Expected %s but recieved %s. Message
%s"
;
private
final
Type
versionedMessageType
;
private
final
MessageVersion
expectedVersion
;
...
...
@@ -90,18 +90,16 @@ public abstract class VersionedMessageDeserializer<T> implements MessageDeserial
// message has newer version
if
(
comp
>
0
)
{
String
msg
=
String
.
format
(
VERSION_MISMATCH_MSG
,
expectedVersion
,
versionedMessage
.
getVersion
());
String
msg
=
String
.
format
(
VERSION_MISMATCH_MSG
,
expectedVersion
,
versionedMessage
.
getVersion
(),
messageJson
);
notificationLogger
.
error
(
msg
);
notificationLogger
.
info
(
messageJson
);
throw
new
IncompatibleVersionException
(
msg
);
}
// message has older version
if
(
comp
<
0
)
{
notificationLogger
.
info
(
String
.
format
(
VERSION_MISMATCH_MSG
,
expectedVersion
,
versionedMessage
.
getVersion
()));
notificationLogger
.
info
(
messageJson
);
notificationLogger
.
info
(
String
.
format
(
VERSION_MISMATCH_MSG
,
expectedVersion
,
versionedMessage
.
getVersion
(),
messageJson
));
}
}
}
This diff is collapsed.
Click to expand it.
notification/src/test/java/org/apache/atlas/notification/AbstractNotificationConsumerTest.java
View file @
705014eb
...
...
@@ -27,9 +27,13 @@ import java.lang.reflect.Type;
import
java.util.LinkedList
;
import
java.util.List
;
import
static
org
.
mockito
.
Matchers
.
endsWith
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
testng
.
Assert
.*;
import
static
org
.
testng
.
Assert
.
assertEquals
;
import
static
org
.
testng
.
Assert
.
assertFalse
;
import
static
org
.
testng
.
Assert
.
assertTrue
;
import
static
org
.
testng
.
Assert
.
fail
;
/**
* AbstractNotificationConsumer tests.
...
...
@@ -110,17 +114,17 @@ public class AbstractNotificationConsumerTest {
assertTrue
(
consumer
.
hasNext
());
assertEquals
(
new
TestMessage
(
"sValue2"
,
98
),
consumer
.
next
());
verify
(
logger
).
info
(
json2
);
verify
(
logger
).
info
(
endsWith
(
json2
)
);
assertTrue
(
consumer
.
hasNext
());
assertEquals
(
new
TestMessage
(
"sValue3"
,
97
),
consumer
.
next
());
verify
(
logger
).
info
(
json3
);
verify
(
logger
).
info
(
endsWith
(
json3
)
);
assertTrue
(
consumer
.
hasNext
());
assertEquals
(
new
TestMessage
(
"sValue4"
,
96
),
consumer
.
next
());
verify
(
logger
).
info
(
json4
);
verify
(
logger
).
info
(
endsWith
(
json4
)
);
assertFalse
(
consumer
.
hasNext
());
}
...
...
@@ -154,7 +158,7 @@ public class AbstractNotificationConsumerTest {
consumer
.
next
();
fail
(
"Expected VersionMismatchException!"
);
}
catch
(
IncompatibleVersionException
e
)
{
verify
(
logger
).
info
(
json2
);
verify
(
logger
).
error
(
endsWith
(
json2
)
);
}
assertFalse
(
consumer
.
hasNext
());
...
...
This diff is collapsed.
Click to expand it.
release-log.txt
View file @
705014eb
...
...
@@ -3,6 +3,7 @@ Apache Atlas Release Notes
--trunk - unreleased
INCOMPATIBLE CHANGES:
ATLAS-716 Entity update/delete notifications (shwethags)
ATLAS-619 Canonicalize hive queries (sumasai)
ATLAS-497 Simple Authorization (saqeeb.s via yhemanth)
ATLAS-661 REST API Authentication (nixonrodrigues via yhemanth)
...
...
This diff is collapsed.
Click to expand it.
repository/src/main/java/org/apache/atlas/repository/MetadataRepository.java
View file @
705014eb
...
...
@@ -18,6 +18,7 @@
package
org
.
apache
.
atlas
.
repository
;
import
org.apache.atlas.AtlasClient
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.typesystem.ITypedReferenceableInstance
;
import
org.apache.atlas.typesystem.ITypedStruct
;
...
...
@@ -26,7 +27,6 @@ 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.IDataType
;
import
org.apache.atlas.typesystem.types.TypeUtils
;
import
java.util.List
;
...
...
@@ -111,7 +111,7 @@ public interface MetadataRepository {
* @return guids of deleted entities
* @throws RepositoryException
*/
TypeUtils
.
Pair
<
List
<
String
>,
List
<
ITypedReferenceableInstance
>>
deleteEntities
(
List
<
String
>
guids
)
throws
RepositoryException
;
AtlasClient
.
EntityResult
deleteEntities
(
List
<
String
>
guids
)
throws
RepositoryException
;
// Trait management functions
...
...
@@ -147,13 +147,13 @@ public interface MetadataRepository {
* Adds/Updates the property to the entity that corresponds to the GUID
* Supports only primitive attribute/Class Id updations.
*/
TypeUtils
.
Pair
<
List
<
String
>,
List
<
String
>>
updatePartial
(
ITypedReferenceableInstance
entity
)
throws
RepositoryException
;
AtlasClient
.
EntityResult
updatePartial
(
ITypedReferenceableInstance
entity
)
throws
RepositoryException
;
/**
* Adds the property to the entity that corresponds to the GUID
* @param entitiesToBeUpdated The entities to be updated
*/
TypeUtils
.
Pair
<
List
<
String
>,
List
<
String
>>
updateEntities
(
ITypedReferenceableInstance
...
entitiesToBeUpdated
)
throws
RepositoryException
;
AtlasClient
.
EntityResult
updateEntities
(
ITypedReferenceableInstance
...
entitiesToBeUpdated
)
throws
RepositoryException
;
/**
* Returns the entity for the given type and qualified name
...
...
This diff is collapsed.
Click to expand it.
repository/src/main/java/org/apache/atlas/repository/audit/EntityAuditListener.java
View file @
705014eb
...
...
@@ -55,8 +55,9 @@ public class EntityAuditListener implements EntityChangeListener {
}
private
EntityAuditEvent
createEvent
(
ITypedReferenceableInstance
entity
,
long
ts
,
EntityAuditEvent
.
EntityAuditAction
action
,
String
details
)
{
return
new
EntityAuditEvent
(
entity
.
getId
().
_getId
(),
ts
,
RequestContext
.
get
().
getUser
(),
action
,
details
);
EntityAuditEvent
.
EntityAuditAction
action
,
String
details
)
throws
AtlasException
{
return
new
EntityAuditEvent
(
entity
.
getId
().
_getId
(),
ts
,
RequestContext
.
get
().
getUser
(),
action
,
details
,
entity
);
}
@Override
...
...
This diff is collapsed.
Click to expand it.
repository/src/main/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepository.java
View file @
705014eb
...
...
@@ -78,6 +78,7 @@ public class HBaseBasedAuditRepository implements Service, EntityAuditRepository
public
static
final
byte
[]
COLUMN_ACTION
=
Bytes
.
toBytes
(
"action"
);
public
static
final
byte
[]
COLUMN_DETAIL
=
Bytes
.
toBytes
(
"detail"
);
public
static
final
byte
[]
COLUMN_USER
=
Bytes
.
toBytes
(
"user"
);
public
static
final
byte
[]
COLUMN_DEFINITION
=
Bytes
.
toBytes
(
"def"
);
private
TableName
tableName
;
private
Connection
connection
;
...
...
@@ -110,6 +111,7 @@ public class HBaseBasedAuditRepository implements Service, EntityAuditRepository
addColumn
(
put
,
COLUMN_ACTION
,
event
.
getAction
());
addColumn
(
put
,
COLUMN_USER
,
event
.
getUser
());
addColumn
(
put
,
COLUMN_DETAIL
,
event
.
getDetails
());
addColumn
(
put
,
COLUMN_DEFINITION
,
event
.
getEntityDefinitionString
());
puts
.
add
(
put
);
}
table
.
put
(
puts
);
...
...
@@ -183,6 +185,7 @@ public class HBaseBasedAuditRepository implements Service, EntityAuditRepository
event
.
setUser
(
getResultString
(
result
,
COLUMN_USER
));
event
.
setAction
(
EntityAuditEvent
.
EntityAuditAction
.
valueOf
(
getResultString
(
result
,
COLUMN_ACTION
)));
event
.
setDetails
(
getResultString
(
result
,
COLUMN_DETAIL
));
event
.
setEntityDefinition
(
getResultString
(
result
,
COLUMN_DEFINITION
));
events
.
add
(
event
);
}
LOG
.
info
(
"Got events for entity id {}, starting timestamp {}, #records {}"
,
entityId
,
startKey
,
events
.
size
());
...
...
This diff is collapsed.
Click to expand it.
repository/src/main/java/org/apache/atlas/repository/graph/DeleteHandler.java
View file @
705014eb
...
...
@@ -47,15 +47,16 @@ import static org.apache.atlas.repository.graph.GraphHelper.string;
public
abstract
class
DeleteHandler
{
public
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
DeleteHandler
.
class
);
pr
ivate
static
final
GraphHelper
graphHelper
=
GraphHelper
.
getInstance
();
pr
otected
static
final
GraphHelper
graphHelper
=
GraphHelper
.
getInstance
();
protected
TypeSystem
typeSystem
;
private
boolean
shouldUpdateReverseAttribute
;
private
boolean
softDelete
;
public
DeleteHandler
(
TypeSystem
typeSystem
,
boolean
shouldUpdateReverseAttribute
)
{
public
DeleteHandler
(
TypeSystem
typeSystem
,
boolean
shouldUpdateReverseAttribute
,
boolean
softDelete
)
{
this
.
typeSystem
=
typeSystem
;
this
.
shouldUpdateReverseAttribute
=
shouldUpdateReverseAttribute
;
this
.
softDelete
=
softDelete
;
}
/**
...
...
@@ -64,16 +65,22 @@ public abstract class DeleteHandler {
* @throws AtlasException
*/
public
void
deleteEntity
(
Vertex
instanceVertex
)
throws
AtlasException
{
RequestContext
requestContext
=
RequestContext
.
get
();
String
guid
=
GraphHelper
.
getIdFromVertex
(
instanceVertex
);
Id
.
EntityState
state
=
GraphHelper
.
getState
(
instanceVertex
);
if
(
requestContext
.
getDeletedEntityIds
().
contains
(
guid
)
||
state
==
Id
.
EntityState
.
DELETED
)
{
LOG
.
debug
(
"Skipping deleting {} as its already deleted"
,
guid
);
return
;
}
String
typeName
=
GraphHelper
.
getTypeName
(
instanceVertex
);
RequestContext
.
get
().
recordDeletedEntity
(
guid
,
typeName
);
requestContext
.
recordEntityDelete
(
guid
,
typeName
);
deleteAllTraits
(
instanceVertex
);
deleteTypeVertex
(
instanceVertex
);
deleteTypeVertex
(
instanceVertex
,
false
);
}
protected
abstract
void
deleteEdge
(
Edge
edge
)
throws
AtlasException
;
protected
abstract
void
deleteEdge
(
Edge
edge
,
boolean
force
)
throws
AtlasException
;
/**
* Deletes a type vertex - can be entity(class type) or just vertex(struct/trait type)
...
...
@@ -81,11 +88,11 @@ public abstract class DeleteHandler {
* @param typeCategory
* @throws AtlasException
*/
protected
void
deleteTypeVertex
(
Vertex
instanceVertex
,
DataTypes
.
TypeCategory
typeCategory
)
throws
AtlasException
{
protected
void
deleteTypeVertex
(
Vertex
instanceVertex
,
DataTypes
.
TypeCategory
typeCategory
,
boolean
force
)
throws
AtlasException
{
switch
(
typeCategory
)
{
case
STRUCT:
case
TRAIT:
deleteTypeVertex
(
instanceVertex
);
deleteTypeVertex
(
instanceVertex
,
force
);
break
;
case
CLASS:
...
...
@@ -102,7 +109,7 @@ public abstract class DeleteHandler {
* @param instanceVertex
* @throws AtlasException
*/
protected
void
deleteTypeVertex
(
Vertex
instanceVertex
)
throws
AtlasException
{
protected
void
deleteTypeVertex
(
Vertex
instanceVertex
,
boolean
force
)
throws
AtlasException
{
LOG
.
debug
(
"Deleting {}"
,
string
(
instanceVertex
));
String
typeName
=
GraphHelper
.
getTypeName
(
instanceVertex
);
IDataType
type
=
typeSystem
.
getDataType
(
IDataType
.
class
,
typeName
);
...
...
@@ -115,12 +122,12 @@ public abstract class DeleteHandler {
switch
(
attributeInfo
.
dataType
().
getTypeCategory
())
{
case
CLASS:
//If its class attribute, delete the reference
deleteReference
(
instanceVertex
,
edgeLabel
,
DataTypes
.
TypeCategory
.
CLASS
,
attributeInfo
.
isComposite
);
delete
Edge
Reference
(
instanceVertex
,
edgeLabel
,
DataTypes
.
TypeCategory
.
CLASS
,
attributeInfo
.
isComposite
);
break
;
case
STRUCT:
//If its struct attribute, delete the reference
delete
Reference
(
instanceVertex
,
edgeLabel
,
DataTypes
.
TypeCategory
.
STRUCT
);
delete
EdgeReference
(
instanceVertex
,
edgeLabel
,
DataTypes
.
TypeCategory
.
STRUCT
,
false
);
break
;
case
ARRAY:
...
...
@@ -133,7 +140,7 @@ public abstract class DeleteHandler {
if
(
edges
!=
null
)
{
while
(
edges
.
hasNext
())
{
Edge
edge
=
edges
.
next
();
delete
Reference
(
edge
,
elementType
,
attributeInfo
);
delete
EdgeReference
(
edge
,
elementType
.
getTypeCategory
(),
attributeInfo
.
isComposite
,
false
);
}
}
}
...
...
@@ -151,22 +158,31 @@ public abstract class DeleteHandler {
if
(
keys
!=
null
)
{
for
(
String
key
:
keys
)
{
String
mapEdgeLabel
=
GraphHelper
.
getQualifiedNameForMapKey
(
edgeLabel
,
key
);
deleteReference
(
instanceVertex
,
mapEdgeLabel
,
valueTypeCategory
,
attributeInfo
.
isComposite
);
delete
Edge
Reference
(
instanceVertex
,
mapEdgeLabel
,
valueTypeCategory
,
attributeInfo
.
isComposite
);
}
}
}
}
}
deleteVertex
(
instanceVertex
,
type
.
getTypeCategory
()
);
deleteVertex
(
instanceVertex
,
force
);
}
public
void
deleteReference
(
Edge
edge
,
IDataType
dataType
,
AttributeInfo
attributeInfo
)
throws
AtlasException
{
deleteReference
(
edge
,
dataType
.
getTypeCategory
(),
attributeInfo
.
isComposite
);
}
public
void
deleteReference
(
Edge
edge
,
DataTypes
.
TypeCategory
typeCategory
,
boolean
isComposite
)
throws
AtlasException
{
/**
* Force delete is used to remove struct/trait in case of entity updates
* @param edge
* @param typeCategory
* @param isComposite
* @param forceDeleteStructTrait
* @return returns true if the edge reference is hard deleted
* @throws AtlasException
*/
public
boolean
deleteEdgeReference
(
Edge
edge
,
DataTypes
.
TypeCategory
typeCategory
,
boolean
isComposite
,
boolean
forceDeleteStructTrait
)
throws
AtlasException
{
LOG
.
debug
(
"Deleting {}"
,
string
(
edge
));
boolean
forceDelete
=
(
typeCategory
==
DataTypes
.
TypeCategory
.
STRUCT
||
typeCategory
==
DataTypes
.
TypeCategory
.
TRAIT
)
?
forceDeleteStructTrait
:
false
;
if
(
typeCategory
==
DataTypes
.
TypeCategory
.
STRUCT
||
typeCategory
==
DataTypes
.
TypeCategory
.
TRAIT
||
(
typeCategory
==
DataTypes
.
TypeCategory
.
CLASS
&&
isComposite
))
{
//If the vertex is of type struct/trait, delete the edge and then the reference vertex as the vertex is not shared by any other entities.
...
...
@@ -175,32 +191,28 @@ public abstract class DeleteHandler {
Vertex
vertexForDelete
=
edge
.
getVertex
(
Direction
.
IN
);
//If deleting the edge and then the in vertex, reverse attribute shouldn't be updated
deleteEdge
(
edge
,
false
);
deleteTypeVertex
(
vertexForDelete
,
typeCategory
);
deleteEdge
(
edge
,
false
,
forceDelete
);
deleteTypeVertex
(
vertexForDelete
,
typeCategory
,
forceDelete
);
}
else
{
//If the vertex is of type class, and its not a composite attributes, the reference vertex' lifecycle is not controlled
//through this delete. Hence just remove the reference edge. Leave the reference vertex as is
//If deleting just the edge, reverse attribute should be updated for any references
//For example, for the department type system, if the person's manager edge is deleted, subordinates of manager should be updated
deleteEdge
(
edge
,
true
);
deleteEdge
(
edge
,
true
,
false
);
}
return
!
softDelete
||
forceDelete
;
}
public
void
deleteReference
(
Vertex
instanceVertex
,
String
edgeLabel
,
DataTypes
.
TypeCategory
typeCategory
)
throws
AtlasException
{
deleteReference
(
instanceVertex
,
edgeLabel
,
typeCategory
,
false
);
}
public
void
deleteReference
(
Vertex
instanceVertex
,
String
edgeLabel
,
DataTypes
.
TypeCategory
typeCategory
,
boolean
isComposite
)
throws
AtlasException
{
Edge
edge
=
GraphHelper
.
getEdgeForLabel
(
instanceVertex
,
edgeLabel
);
public
void
deleteEdgeReference
(
Vertex
outVertex
,
String
edgeLabel
,
DataTypes
.
TypeCategory
typeCategory
,
boolean
isComposite
)
throws
AtlasException
{
Edge
edge
=
GraphHelper
.
getEdgeForLabel
(
outVertex
,
edgeLabel
);
if
(
edge
!=
null
)
{
delete
Reference
(
edge
,
typeCategory
,
isComposit
e
);
delete
EdgeReference
(
edge
,
typeCategory
,
isComposite
,
fals
e
);
}
}
protected
void
deleteEdge
(
Edge
edge
,
boolean
updateReverseAttribute
)
throws
AtlasException
{
protected
void
deleteEdge
(
Edge
edge
,
boolean
updateReverseAttribute
,
boolean
force
)
throws
AtlasException
{
//update reverse attribute
if
(
updateReverseAttribute
)
{
AttributeInfo
attributeInfo
=
getAttributeForEdge
(
edge
.
getLabel
());
...
...
@@ -210,28 +222,28 @@ public abstract class DeleteHandler {
}
}
deleteEdge
(
edge
);
deleteEdge
(
edge
,
force
);
}
protected
void
deleteVertex
(
Vertex
instanceVertex
,
DataTypes
.
TypeCategory
typeCategory
)
throws
AtlasException
{
protected
void
deleteVertex
(
Vertex
instanceVertex
,
boolean
force
)
throws
AtlasException
{
//Update external references(incoming edges) to this vertex
LOG
.
debug
(
"Setting the external references to {} to null(removing edges)"
,
string
(
instanceVertex
));
Iterator
<
Edge
>
edges
=
instanceVertex
.
getEdges
(
Direction
.
IN
).
iterator
();
while
(
edges
.
hasNext
())
{
Edge
edge
=
edges
.
next
();
String
edgeState
=
edge
.
getProperty
(
Constants
.
STATE_PROPERTY_KEY
);
if
(
Id
.
EntityState
.
ACTIVE
.
name
().
equals
(
edgeState
)
)
{
Id
.
EntityState
edgeState
=
GraphHelper
.
getState
(
edge
);
if
(
edgeState
==
Id
.
EntityState
.
ACTIVE
)
{
//Delete only the active edge references
AttributeInfo
attribute
=
getAttributeForEdge
(
edge
.
getLabel
());
//TODO use delete edge instead??
deleteEdgeBetweenVertices
(
edge
.
getVertex
(
Direction
.
OUT
),
edge
.
getVertex
(
Direction
.
IN
),
attribute
.
name
);
deleteEdge
(
edge
);
}
}
_deleteVertex
(
instanceVertex
);
_deleteVertex
(
instanceVertex
,
force
);
}
protected
abstract
void
_deleteVertex
(
Vertex
instanceVertex
);
protected
abstract
void
_deleteVertex
(
Vertex
instanceVertex
,
boolean
force
);
/**
* Deletes the edge between outvertex and inVertex. The edge is for attribute attributeName of outVertex
...
...
@@ -245,7 +257,8 @@ public abstract class DeleteHandler {
attributeName
);
String
typeName
=
GraphHelper
.
getTypeName
(
outVertex
);
String
outId
=
GraphHelper
.
getIdFromVertex
(
outVertex
);
if
(
outId
!=
null
&&
RequestContext
.
get
().
isDeletedEntity
(
outId
))
{
Id
.
EntityState
state
=
GraphHelper
.
getState
(
outVertex
);
if
((
outId
!=
null
&&
RequestContext
.
get
().
isDeletedEntity
(
outId
))
||
state
==
Id
.
EntityState
.
DELETED
)
{
//If the reference vertex is marked for deletion, skip updating the reference
return
;
}
...
...
@@ -261,8 +274,10 @@ public abstract class DeleteHandler {
//If its class attribute, its the only edge between two vertices
if
(
attributeInfo
.
multiplicity
.
nullAllowed
())
{
edge
=
GraphHelper
.
getEdgeForLabel
(
outVertex
,
edgeLabel
);
}
else
{
if
(
shouldUpdateReverseAttribute
)
{
GraphHelper
.
setProperty
(
outVertex
,
propertyName
,
null
);
}
}
else
{
// Cannot unset a required attribute.
throw
new
NullRequiredAttributeException
(
"Cannot unset required attribute "
+
GraphHelper
.
getQualifiedFieldName
(
type
,
attributeName
)
+
" on "
+
string
(
outVertex
)
+
" edge = "
+
edgeLabel
);
...
...
@@ -275,23 +290,26 @@ public abstract class DeleteHandler {
if
(
elements
!=
null
)
{
elements
=
new
ArrayList
<>(
elements
);
//Make a copy, else list.remove reflects on titan.getProperty()
for
(
String
elementEdgeId
:
elements
)
{
Edge
elementEdge
=
graphHelper
.
getEdgeBy
Id
(
elementEdgeId
);
Edge
elementEdge
=
graphHelper
.
getEdgeBy
EdgeId
(
outVertex
,
edgeLabel
,
elementEdgeId
);
if
(
elementEdge
==
null
)
{
continue
;
}
Vertex
elementVertex
=
elementEdge
.
getVertex
(
Direction
.
IN
);
if
(
elementVertex
.
getId
().
toString
().
equals
(
inVertex
.
getId
().
toString
()))
{
if
(
attributeInfo
.
multiplicity
.
nullAllowed
()
||
elements
.
size
()
>
attributeInfo
.
multiplicity
.
lower
)
{
edge
=
elementEdge
;
}
else
{
edge
=
elementEdge
;
//TODO element.size includes deleted items as well. should exclude
if
(!
attributeInfo
.
multiplicity
.
nullAllowed
()
&&
elements
.
size
()
<=
attributeInfo
.
multiplicity
.
lower
)
{
// Deleting this edge would violate the attribute's lower bound.
throw
new
NullRequiredAttributeException
(
"Cannot remove array element from required attribute "
+
GraphHelper
.
getQualifiedFieldName
(
type
,
attributeName
)
+
" on "
+
string
(
outVertex
)
+
" "
+
string
(
elementEdge
));
"Cannot remove array element from required attribute "
+
GraphHelper
.
getQualifiedFieldName
(
type
,
attributeName
)
+
" on "
+
string
(
outVertex
)
+
" "
+
string
(
elementEdge
));
}
if
(
shouldUpdateReverseAttribute
||
attributeInfo
.
isComposite
)
{
if
(
shouldUpdateReverseAttribute
)
{
//if composite attribute, remove the reference as well. else, just remove the edge
//for example, when table is deleted, process still references the table
//but when column is deleted, table will not reference the deleted column
...
...
@@ -299,8 +317,9 @@ public abstract class DeleteHandler {
attributeName
);
elements
.
remove
(
elementEdge
.
getId
().
toString
());
GraphHelper
.
setProperty
(
outVertex
,
propertyName
,
elements
);
break
;
}
break
;
}
}
}
...
...
@@ -312,11 +331,12 @@ public abstract class DeleteHandler {
if
(
keys
!=
null
)
{
keys
=
new
ArrayList
<>(
keys
);
//Make a copy, else list.remove reflects on titan.getProperty()
for
(
String
key
:
keys
)
{
String
keyPropertyName
=
propertyName
+
"."
+
key
;
String
keyPropertyName
=
GraphHelper
.
getQualifiedNameForMapKey
(
propertyName
,
key
)
;
String
mapEdgeId
=
outVertex
.
getProperty
(
keyPropertyName
);
Edge
mapEdge
=
graphHelper
.
getEdgeBy
Id
(
mapEdgeId
);
Edge
mapEdge
=
graphHelper
.
getEdgeBy
EdgeId
(
outVertex
,
keyPropertyName
,
mapEdgeId
);
Vertex
mapVertex
=
mapEdge
.
getVertex
(
Direction
.
IN
);
if
(
mapVertex
.
getId
().
toString
().
equals
(
inVertex
.
getId
().
toString
()))
{
//TODO keys.size includes deleted items as well. should exclude
if
(
attributeInfo
.
multiplicity
.
nullAllowed
()
||
keys
.
size
()
>
attributeInfo
.
multiplicity
.
lower
)
{
edge
=
mapEdge
;
}
...
...
@@ -327,7 +347,7 @@ public abstract class DeleteHandler {
GraphHelper
.
getQualifiedFieldName
(
type
,
attributeName
)
+
" on "
+
string
(
outVertex
)
+
" "
+
string
(
mapEdge
));
}
if
(
shouldUpdateReverseAttribute
||
attributeInfo
.
isComposite
)
{
if
(
shouldUpdateReverseAttribute
)
{
//remove this key
LOG
.
debug
(
"Removing edge {}, key {} from the map attribute {}"
,
string
(
mapEdge
),
key
,
attributeName
);
...
...
@@ -351,9 +371,11 @@ public abstract class DeleteHandler {
}
if
(
edge
!=
null
)
{
deleteEdge
(
edge
);
deleteEdge
(
edge
,
false
);
RequestContext
requestContext
=
RequestContext
.
get
();
GraphHelper
.
setProperty
(
outVertex
,
Constants
.
MODIFICATION_TIMESTAMP_PROPERTY_KEY
,
RequestContext
.
get
().
getRequestTime
());
requestContext
.
getRequestTime
());
requestContext
.
recordEntityUpdate
(
outId
);
}
}
...
...
@@ -389,7 +411,7 @@ public abstract class DeleteHandler {
for
(
String
traitNameToBeDeleted
:
traitNames
)
{
String
relationshipLabel
=
GraphHelper
.
getTraitLabel
(
typeName
,
traitNameToBeDeleted
);
delete
Reference
(
instanceVertex
,
relationshipLabel
,
DataTypes
.
TypeCategory
.
TRAIT
);
delete
EdgeReference
(
instanceVertex
,
relationshipLabel
,
DataTypes
.
TypeCategory
.
TRAIT
,
false
);
}
}
}
This diff is collapsed.
Click to expand it.
repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepository.java
View file @
705014eb
...
...
@@ -22,8 +22,10 @@ import com.google.common.base.Preconditions;
import
com.google.inject.Inject
;
import
com.google.inject.Singleton
;
import
com.thinkaurelius.titan.core.TitanGraph
;
import
com.tinkerpop.blueprints.Edge
;
import
com.tinkerpop.blueprints.GraphQuery
;
import
com.tinkerpop.blueprints.Vertex
;
import
org.apache.atlas.AtlasClient
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.GraphTransaction
;
import
org.apache.atlas.RequestContext
;
...
...
@@ -40,7 +42,6 @@ import org.apache.atlas.typesystem.types.ClassType;
import
org.apache.atlas.typesystem.types.DataTypes
;
import
org.apache.atlas.typesystem.types.IDataType
;
import
org.apache.atlas.typesystem.types.TypeSystem
;
import
org.apache.atlas.typesystem.types.TypeUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -258,8 +259,8 @@ public class GraphBackedMetadataRepository implements MetadataRepository {
try
{
final
String
entityTypeName
=
GraphHelper
.
getTypeName
(
instanceVertex
);
String
relationshipLabel
=
GraphHelper
.
getTraitLabel
(
entityTypeName
,
traitNameToBeDeleted
);
deleteHandler
.
delete
Reference
(
instanceVertex
,
relationshipLabel
,
DataTypes
.
TypeCategory
.
TRAIT
);
Edge
edge
=
GraphHelper
.
getEdgeForLabel
(
instanceVertex
,
relationshipLabel
);
deleteHandler
.
delete
EdgeReference
(
edge
,
DataTypes
.
TypeCategory
.
TRAIT
,
false
,
true
);
// update the traits in entity once trait removal is successful
traitNames
.
remove
(
traitNameToBeDeleted
);
...
...
@@ -284,14 +285,15 @@ public class GraphBackedMetadataRepository implements MetadataRepository {
@Override
@GraphTransaction
public
TypeUtils
.
Pair
<
List
<
String
>,
List
<
String
>>
updateEntities
(
ITypedReferenceableInstance
...
entitiesUpdated
)
throws
RepositoryException
{
public
AtlasClient
.
EntityResult
updateEntities
(
ITypedReferenceableInstance
...
entitiesUpdated
)
throws
RepositoryException
{
LOG
.
info
(
"updating entity {}"
,
entitiesUpdated
);
try
{
TypedInstanceToGraphMapper
instanceToGraphMapper
=
new
TypedInstanceToGraphMapper
(
graphToInstanceMapper
,
deleteHandler
);
instanceToGraphMapper
.
mapTypedInstanceToGraph
(
TypedInstanceToGraphMapper
.
Operation
.
UPDATE_FULL
,
entitiesUpdated
);
RequestContext
requestContext
=
RequestContext
.
get
();
return
TypeUtils
.
Pair
.
of
(
requestContext
.
getCreatedEntityIds
(),
requestContext
.
getUpdatedEntityIds
());
return
new
AtlasClient
.
EntityResult
(
requestContext
.
getCreatedEntityIds
(),
requestContext
.
getUpdatedEntityIds
(),
requestContext
.
getDeletedEntityIds
());
}
catch
(
AtlasException
e
)
{
throw
new
RepositoryException
(
e
);
}
...
...
@@ -299,13 +301,14 @@ public class GraphBackedMetadataRepository implements MetadataRepository {
@Override
@GraphTransaction
public
TypeUtils
.
Pair
<
List
<
String
>,
List
<
String
>>
updatePartial
(
ITypedReferenceableInstance
entity
)
throws
RepositoryException
{
public
AtlasClient
.
EntityResult
updatePartial
(
ITypedReferenceableInstance
entity
)
throws
RepositoryException
{
LOG
.
info
(
"updating entity {}"
,
entity
);
try
{
TypedInstanceToGraphMapper
instanceToGraphMapper
=
new
TypedInstanceToGraphMapper
(
graphToInstanceMapper
,
deleteHandler
);
instanceToGraphMapper
.
mapTypedInstanceToGraph
(
TypedInstanceToGraphMapper
.
Operation
.
UPDATE_PARTIAL
,
entity
);
RequestContext
requestContext
=
RequestContext
.
get
();
return
TypeUtils
.
Pair
.
of
(
requestContext
.
getCreatedEntityIds
(),
requestContext
.
getUpdatedEntityIds
());
return
new
AtlasClient
.
EntityResult
(
requestContext
.
getCreatedEntityIds
(),
requestContext
.
getUpdatedEntityIds
(),
requestContext
.
getDeletedEntityIds
());
}
catch
(
AtlasException
e
)
{
throw
new
RepositoryException
(
e
);
}
...
...
@@ -313,7 +316,7 @@ public class GraphBackedMetadataRepository implements MetadataRepository {
@Override
@GraphTransaction
public
TypeUtils
.
Pair
<
List
<
String
>,
List
<
ITypedReferenceableInstance
>>
deleteEntities
(
List
<
String
>
guids
)
throws
RepositoryException
{
public
AtlasClient
.
EntityResult
deleteEntities
(
List
<
String
>
guids
)
throws
RepositoryException
{
if
(
guids
==
null
||
guids
.
size
()
==
0
)
{
throw
new
IllegalArgumentException
(
"guids must be non-null and non-empty"
);
...
...
@@ -337,6 +340,7 @@ public class GraphBackedMetadataRepository implements MetadataRepository {
}
}
RequestContext
requestContext
=
RequestContext
.
get
();
return
new
TypeUtils
.
Pair
<>(
requestContext
.
getDeletedEntityIds
(),
requestContext
.
getDeletedEntities
());
return
new
AtlasClient
.
EntityResult
(
requestContext
.
getCreatedEntityIds
(),
requestContext
.
getUpdatedEntityIds
(),
requestContext
.
getDeletedEntityIds
());
}
}
This diff is collapsed.
Click to expand it.
repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
View file @
705014eb
...
...
@@ -107,11 +107,13 @@ public final class GraphHelper {
// add timestamp information
setProperty
(
vertexWithoutIdentity
,
Constants
.
TIMESTAMP_PROPERTY_KEY
,
RequestContext
.
get
().
getRequestTime
());
setProperty
(
vertexWithoutIdentity
,
Constants
.
MODIFICATION_TIMESTAMP_PROPERTY_KEY
,
RequestContext
.
get
().
getRequestTime
());
return
vertexWithoutIdentity
;
}
p
ublic
Edge
addEdge
(
Vertex
fromVertex
,
Vertex
toVertex
,
String
edgeLabel
)
{
p
rivate
Edge
addEdge
(
Vertex
fromVertex
,
Vertex
toVertex
,
String
edgeLabel
)
{
LOG
.
debug
(
"Adding edge for {} -> label {} -> {}"
,
string
(
fromVertex
),
edgeLabel
,
string
(
toVertex
));
Edge
edge
=
titanGraph
.
addEdge
(
null
,
fromVertex
,
toVertex
,
edgeLabel
);
...
...
@@ -127,12 +129,34 @@ public final class GraphHelper {
Iterable
<
Edge
>
edges
=
inVertex
.
getEdges
(
Direction
.
IN
,
edgeLabel
);
for
(
Edge
edge
:
edges
)
{
if
(
edge
.
getVertex
(
Direction
.
OUT
).
getId
().
toString
().
equals
(
outVertex
.
getId
().
toString
()))
{
return
edge
;
Id
.
EntityState
edgeState
=
getState
(
edge
);
if
(
edgeState
==
null
||
edgeState
==
Id
.
EntityState
.
ACTIVE
)
{
return
edge
;
}
}
}
return
addEdge
(
outVertex
,
inVertex
,
edgeLabel
);
}
public
Edge
getEdgeByEdgeId
(
Vertex
outVertex
,
String
edgeLabel
,
String
edgeId
)
{
if
(
edgeId
==
null
)
{
return
null
;
}
return
titanGraph
.
getEdge
(
edgeId
);
//TODO get edge id is expensive. Use this logic. But doesn't work for now
/**
Iterable<Edge> edges = outVertex.getEdges(Direction.OUT, edgeLabel);
for (Edge edge : edges) {
if (edge.getId().toString().equals(edgeId)) {
return edge;
}
}
return null;
**/
}
/**
* Args of the format prop1, key1, prop2, key2...
* Searches for a vertex with prop1=key1 && prop2=key2
...
...
@@ -180,15 +204,14 @@ public final class GraphHelper {
* @return
*/
public
static
Edge
getEdgeForLabel
(
Vertex
vertex
,
String
edgeLabel
)
{
String
vertexState
=
vertex
.
getProperty
(
Constants
.
STATE_PROPERTY_KEY
);
Iterator
<
Edge
>
iterator
=
GraphHelper
.
getOutGoingEdgesByLabel
(
vertex
,
edgeLabel
);
Edge
latestDeletedEdge
=
null
;
long
latestDeletedEdgeTime
=
Long
.
MIN_VALUE
;
while
(
iterator
!=
null
&&
iterator
.
hasNext
())
{
Edge
edge
=
iterator
.
next
();
String
edgeState
=
edge
.
getProperty
(
Constants
.
STATE_PROPERTY_KEY
);
if
(
edgeState
==
null
||
Id
.
EntityState
.
ACTIVE
.
name
().
equals
(
edgeState
)
)
{
Id
.
EntityState
edgeState
=
getState
(
edge
);
if
(
edgeState
==
null
||
edgeState
==
Id
.
EntityState
.
ACTIVE
)
{
LOG
.
debug
(
"Found {}"
,
string
(
edge
));
return
edge
;
}
else
{
...
...
@@ -201,19 +224,8 @@ public final class GraphHelper {
}
//If the vertex is deleted, return latest deleted edge
if
(
Id
.
EntityState
.
DELETED
.
equals
(
vertexState
))
{
LOG
.
debug
(
"Found {}"
,
string
(
latestDeletedEdge
));
return
latestDeletedEdge
;
}
return
null
;
}
public
Edge
getEdgeById
(
String
edgeId
)
{
if
(
edgeId
!=
null
)
{
return
titanGraph
.
getEdge
(
edgeId
);
}
return
null
;
LOG
.
debug
(
"Found {}"
,
latestDeletedEdge
==
null
?
"null"
:
string
(
latestDeletedEdge
));
return
latestDeletedEdge
;
}
public
static
String
vertexString
(
final
Vertex
vertex
)
{
...
...
@@ -343,6 +355,15 @@ public final class GraphHelper {
return
instanceVertex
.
getProperty
(
Constants
.
ENTITY_TYPE_PROPERTY_KEY
);
}
public
static
Id
.
EntityState
getState
(
Element
element
)
{
String
state
=
getStateAsString
(
element
);
return
state
==
null
?
null
:
Id
.
EntityState
.
valueOf
(
state
);
}
public
static
String
getStateAsString
(
Element
element
)
{
return
element
.
getProperty
(
Constants
.
STATE_PROPERTY_KEY
);
}
/**
* For the given type, finds an unique attribute and checks if there is an existing instance with the same
* unique value
...
...
This diff is collapsed.
Click to expand it.
repository/src/main/java/org/apache/atlas/repository/graph/GraphToTypedInstanceMapper.java
View file @
705014eb
...
...
@@ -68,9 +68,9 @@ public final class GraphToTypedInstanceMapper {
LOG
.
debug
(
"Mapping graph root vertex {} to typed instance for guid {}"
,
instanceVertex
,
guid
);
String
typeName
=
instanceVertex
.
getProperty
(
Constants
.
ENTITY_TYPE_PROPERTY_KEY
);
List
<
String
>
traits
=
GraphHelper
.
getTraitNames
(
instanceVertex
);
String
state
=
GraphHelper
.
getStateAsString
(
instanceVertex
);
Id
id
=
new
Id
(
guid
,
instanceVertex
.<
Integer
>
getProperty
(
Constants
.
VERSION_PROPERTY_KEY
),
typeName
,
instanceVertex
.<
String
>
getProperty
(
Constants
.
STATE_PROPERTY_KEY
));
Id
id
=
new
Id
(
guid
,
instanceVertex
.<
Integer
>
getProperty
(
Constants
.
VERSION_PROPERTY_KEY
),
typeName
,
state
);
LOG
.
debug
(
"Created id {} for instance type {}"
,
id
,
typeName
);
ClassType
classType
=
typeSystem
.
getDataType
(
ClassType
.
class
,
typeName
);
...
...
@@ -161,9 +161,9 @@ public final class GraphToTypedInstanceMapper {
Edge
edge
;
if
(
edgeId
==
null
)
{
edge
=
GraphHelper
.
getEdgeForLabel
(
instanceVertex
,
relationshipLabel
);
;
edge
=
GraphHelper
.
getEdgeForLabel
(
instanceVertex
,
relationshipLabel
);
}
else
{
edge
=
graphHelper
.
getEdgeBy
Id
(
edgeId
);
edge
=
graphHelper
.
getEdgeBy
EdgeId
(
instanceVertex
,
relationshipLabel
,
edgeId
);
}
if
(
edge
!=
null
)
{
...
...
@@ -175,9 +175,10 @@ public final class GraphToTypedInstanceMapper {
LOG
.
debug
(
"Found composite, mapping vertex to instance"
);
return
mapGraphToTypedInstance
(
guid
,
referenceVertex
);
}
else
{
String
state
=
GraphHelper
.
getStateAsString
(
referenceVertex
);
Id
referenceId
=
new
Id
(
guid
,
referenceVertex
.<
Integer
>
getProperty
(
Constants
.
VERSION_PROPERTY_KEY
),
dataType
.
getName
());
dataType
.
getName
()
,
state
);
LOG
.
debug
(
"Found non-composite, adding id {} "
,
referenceId
);
return
referenceId
;
}
...
...
@@ -271,7 +272,7 @@ public final class GraphToTypedInstanceMapper {
if
(
edgeId
==
null
)
{
edge
=
GraphHelper
.
getEdgeForLabel
(
instanceVertex
,
relationshipLabel
);
}
else
{
edge
=
graphHelper
.
getEdgeBy
Id
(
edgeId
);
edge
=
graphHelper
.
getEdgeBy
EdgeId
(
instanceVertex
,
relationshipLabel
,
edgeId
);
}
if
(
edge
!=
null
)
{
...
...
This diff is collapsed.
Click to expand it.
repository/src/main/java/org/apache/atlas/repository/graph/HardDeleteHandler.java
View file @
705014eb
...
...
@@ -26,20 +26,18 @@ import org.apache.atlas.typesystem.types.TypeSystem;
public
class
HardDeleteHandler
extends
DeleteHandler
{
private
static
final
GraphHelper
graphHelper
=
GraphHelper
.
getInstance
();
@Inject
public
HardDeleteHandler
(
TypeSystem
typeSystem
)
{
super
(
typeSystem
,
true
);
super
(
typeSystem
,
true
,
false
);
}
@Override
protected
void
_deleteVertex
(
Vertex
instanceVertex
)
{
protected
void
_deleteVertex
(
Vertex
instanceVertex
,
boolean
force
)
{
graphHelper
.
removeVertex
(
instanceVertex
);
}
@Override
protected
void
deleteEdge
(
Edge
edge
)
throws
AtlasException
{
protected
void
deleteEdge
(
Edge
edge
,
boolean
force
)
throws
AtlasException
{
graphHelper
.
removeEdge
(
edge
);
}
}
This diff is collapsed.
Click to expand it.
repository/src/main/java/org/apache/atlas/repository/graph/SoftDeleteHandler.java
View file @
705014eb
...
...
@@ -32,24 +32,34 @@ import static org.apache.atlas.repository.Constants.STATE_PROPERTY_KEY;
public
class
SoftDeleteHandler
extends
DeleteHandler
{
@Inject
public
SoftDeleteHandler
(
TypeSystem
typeSystem
)
{
super
(
typeSystem
,
false
);
super
(
typeSystem
,
false
,
true
);
}
@Override
protected
void
_deleteVertex
(
Vertex
instanceVertex
)
{
Id
.
EntityState
state
=
Id
.
EntityState
.
valueOf
((
String
)
instanceVertex
.
getProperty
(
STATE_PROPERTY_KEY
));
if
(
state
!=
Id
.
EntityState
.
DELETED
)
{
GraphHelper
.
setProperty
(
instanceVertex
,
STATE_PROPERTY_KEY
,
Id
.
EntityState
.
DELETED
.
name
());
GraphHelper
.
setProperty
(
instanceVertex
,
MODIFICATION_TIMESTAMP_PROPERTY_KEY
,
RequestContext
.
get
().
getRequestTime
());
protected
void
_deleteVertex
(
Vertex
instanceVertex
,
boolean
force
)
{
if
(
force
)
{
graphHelper
.
removeVertex
(
instanceVertex
);
}
else
{
Id
.
EntityState
state
=
GraphHelper
.
getState
(
instanceVertex
);
if
(
state
!=
Id
.
EntityState
.
DELETED
)
{
GraphHelper
.
setProperty
(
instanceVertex
,
STATE_PROPERTY_KEY
,
Id
.
EntityState
.
DELETED
.
name
());
GraphHelper
.
setProperty
(
instanceVertex
,
MODIFICATION_TIMESTAMP_PROPERTY_KEY
,
RequestContext
.
get
().
getRequestTime
());
}
}
}
@Override
protected
void
deleteEdge
(
Edge
edge
)
throws
AtlasException
{
Id
.
EntityState
state
=
Id
.
EntityState
.
valueOf
((
String
)
edge
.
getProperty
(
STATE_PROPERTY_KEY
));
if
(
state
!=
Id
.
EntityState
.
DELETED
)
{
GraphHelper
.
setProperty
(
edge
,
STATE_PROPERTY_KEY
,
Id
.
EntityState
.
DELETED
.
name
());
GraphHelper
.
setProperty
(
edge
,
MODIFICATION_TIMESTAMP_PROPERTY_KEY
,
RequestContext
.
get
().
getRequestTime
());
protected
void
deleteEdge
(
Edge
edge
,
boolean
force
)
throws
AtlasException
{
if
(
force
)
{
graphHelper
.
removeEdge
(
edge
);
}
else
{
Id
.
EntityState
state
=
GraphHelper
.
getState
(
edge
);
if
(
state
!=
Id
.
EntityState
.
DELETED
)
{
GraphHelper
.
setProperty
(
edge
,
STATE_PROPERTY_KEY
,
Id
.
EntityState
.
DELETED
.
name
());
GraphHelper
.
setProperty
(
edge
,
MODIFICATION_TIMESTAMP_PROPERTY_KEY
,
RequestContext
.
get
().
getRequestTime
());
}
}
}
}
This diff is collapsed.
Click to expand it.
repository/src/main/java/org/apache/atlas/repository/graph/TypedInstanceToGraphMapper.java
View file @
705014eb
...
...
@@ -101,15 +101,15 @@ public final class TypedInstanceToGraphMapper {
case
CREATE:
List
<
String
>
ids
=
addOrUpdateAttributesAndTraits
(
operation
,
entitiesToCreate
);
addFullTextProperty
(
entitiesToCreate
,
fulltextMapper
);
requestContext
.
record
CreatedEntities
(
ids
);
requestContext
.
record
EntityCreate
(
ids
);
break
;
case
UPDATE_FULL:
case
UPDATE_PARTIAL:
ids
=
addOrUpdateAttributesAndTraits
(
Operation
.
CREATE
,
entitiesToCreate
);
requestContext
.
record
CreatedEntities
(
ids
);
requestContext
.
record
EntityCreate
(
ids
);
ids
=
addOrUpdateAttributesAndTraits
(
operation
,
entitiesToUpdate
);
requestContext
.
record
UpdatedEntities
(
ids
);
requestContext
.
record
EntityUpdate
(
ids
);
addFullTextProperty
(
entitiesToCreate
,
fulltextMapper
);
addFullTextProperty
(
entitiesToUpdate
,
fulltextMapper
);
...
...
@@ -218,8 +218,8 @@ public final class TypedInstanceToGraphMapper {
attrValue
,
currentEdge
,
edgeLabel
,
operation
);
if
(
currentEdge
!=
null
&&
!
currentEdge
.
getId
().
toString
().
equals
(
newEdgeId
))
{
deleteHandler
.
deleteReference
(
currentEdge
,
attributeInfo
.
dataType
().
getTypeCategory
(),
attributeInfo
.
isComposite
);
deleteHandler
.
delete
Edge
Reference
(
currentEdge
,
attributeInfo
.
dataType
().
getTypeCategory
(),
attributeInfo
.
isComposite
,
true
);
}
break
;
...
...
@@ -326,7 +326,7 @@ public final class TypedInstanceToGraphMapper {
String
propertyName
=
GraphHelper
.
getQualifiedFieldName
(
typedInstance
,
attributeInfo
);
List
<
String
>
currentElements
=
instanceVertex
.
getProperty
(
propertyName
);
IDataType
elementType
=
((
DataTypes
.
ArrayType
)
attributeInfo
.
dataType
()).
getElemType
();
List
<
String
>
newElementsCreated
=
new
ArrayList
<>();
List
<
Object
>
newElementsCreated
=
new
ArrayList
<>();
if
(!
newAttributeEmpty
)
{
if
(
newElements
!=
null
&&
!
newElements
.
isEmpty
())
{
...
...
@@ -336,75 +336,53 @@ public final class TypedInstanceToGraphMapper {
currentElements
.
get
(
index
)
:
null
;
LOG
.
debug
(
"Adding/updating element at position {}, current element {}, new element {}"
,
index
,
currentElement
,
newElements
.
get
(
index
));
String
newEntry
=
addOrUpdateCollectionEntry
(
instanceVertex
,
attributeInfo
,
elementType
,
Object
newEntry
=
addOrUpdateCollectionEntry
(
instanceVertex
,
attributeInfo
,
elementType
,
newElements
.
get
(
index
),
currentElement
,
propertyName
,
operation
);
newElementsCreated
.
add
(
newEntry
);
}
}
}
List
<
String
>
additionalEdges
=
removeUnusedEntries
(
instanceVertex
,
propertyName
,
currentElements
,
newElementsCreated
,
elementType
,
attributeInfo
);
newElementsCreated
.
addAll
(
additionalEdges
);
// for dereference on way out
GraphHelper
.
setProperty
(
instanceVertex
,
propertyName
,
newElementsCreated
);
removeUnusedEntries
(
currentElements
,
newElementsCreated
,
elementType
,
attributeInfo
);
}
private
void
removeUnusedEntries
(
List
<
String
>
currentEntries
,
List
<
String
>
newEntries
,
IDataType
entryType
,
AttributeInfo
attributeInfo
)
throws
AtlasException
{
if
(
currentEntries
==
null
||
currentEntries
.
isEmpty
())
{
return
;
}
LOG
.
debug
(
"Removing unused entries from the old collection"
);
if
(
entryType
.
getTypeCategory
()
==
DataTypes
.
TypeCategory
.
STRUCT
||
entryType
.
getTypeCategory
()
==
DataTypes
.
TypeCategory
.
CLASS
)
{
//Get map of edge id to edge
Map
<
String
,
Edge
>
edgeMap
=
new
HashMap
<>();
getEdges
(
currentEntries
,
edgeMap
);
getEdges
(
newEntries
,
edgeMap
);
//Get final set of in vertices
Set
<
String
>
newInVertices
=
new
HashSet
<>();
for
(
String
edgeId
:
newEntries
)
{
Vertex
inVertex
=
edgeMap
.
get
(
edgeId
).
getVertex
(
Direction
.
IN
);
newInVertices
.
add
(
inVertex
.
getId
().
toString
());
}
//Remove the edges for (current edges - new edges)
List
<
String
>
cloneElements
=
new
ArrayList
<>(
currentEntries
);
cloneElements
.
removeAll
(
newEntries
);
LOG
.
debug
(
"Removing unused entries from the old collection - {}"
,
cloneElements
);
if
(!
cloneElements
.
isEmpty
())
{
for
(
String
edgeIdForDelete
:
cloneElements
)
{
Edge
edge
=
edgeMap
.
get
(
edgeIdForDelete
);
Vertex
inVertex
=
edge
.
getVertex
(
Direction
.
IN
);
if
(
newInVertices
.
contains
(
inVertex
.
getId
().
toString
()))
{
//If the edge.inVertex is in the new set of in vertices, just delete the edge
deleteHandler
.
deleteEdge
(
edge
,
true
);
}
else
{
//else delete the edge + vertex
deleteHandler
.
deleteReference
(
edge
,
entryType
.
getTypeCategory
(),
attributeInfo
.
isComposite
);
//Removes unused edges from the old collection, compared to the new collection
private
List
<
String
>
removeUnusedEntries
(
Vertex
instanceVertex
,
String
edgeLabel
,
Collection
<
String
>
currentEntries
,
Collection
<
Object
>
newEntries
,
IDataType
entryType
,
AttributeInfo
attributeInfo
)
throws
AtlasException
{
if
(
currentEntries
!=
null
&&
!
currentEntries
.
isEmpty
())
{
LOG
.
debug
(
"Removing unused entries from the old collection"
);
if
(
entryType
.
getTypeCategory
()
==
DataTypes
.
TypeCategory
.
STRUCT
||
entryType
.
getTypeCategory
()
==
DataTypes
.
TypeCategory
.
CLASS
)
{
//Remove the edges for (current edges - new edges)
List
<
String
>
cloneElements
=
new
ArrayList
<>(
currentEntries
);
cloneElements
.
removeAll
(
newEntries
);
List
<
String
>
additionalElements
=
new
ArrayList
<>();
LOG
.
debug
(
"Removing unused entries from the old collection - {}"
,
cloneElements
);
if
(!
cloneElements
.
isEmpty
())
{
for
(
String
edgeIdForDelete
:
cloneElements
)
{
Edge
edge
=
graphHelper
.
getEdgeByEdgeId
(
instanceVertex
,
edgeLabel
,
edgeIdForDelete
);
boolean
deleted
=
deleteHandler
.
deleteEdgeReference
(
edge
,
entryType
.
getTypeCategory
(),
attributeInfo
.
isComposite
,
true
);
if
(!
deleted
)
{
additionalElements
.
add
(
edgeIdForDelete
);
}
}
}
return
additionalElements
;
}
}
return
new
ArrayList
<>();
}
private
void
getEdges
(
List
<
String
>
edgeIds
,
Map
<
String
,
Edge
>
edgeMap
)
{
if
(
edgeIds
==
null
)
{
return
;
}
for
(
String
edgeId
:
edgeIds
)
{
if
(!
edgeMap
.
containsKey
(
edgeId
))
{
edgeMap
.
put
(
edgeId
,
graphHelper
.
getEdgeById
(
edgeId
));
}
}
}
/******************************************** MAP **************************************************/
private
void
mapMapCollectionToVertex
(
ITypedInstance
typedInstance
,
Vertex
instanceVertex
,
...
...
@@ -421,38 +399,81 @@ public final class TypedInstanceToGraphMapper {
IDataType
elementType
=
((
DataTypes
.
MapType
)
attributeInfo
.
dataType
()).
getValueType
();
String
propertyName
=
GraphHelper
.
getQualifiedFieldName
(
typedInstance
,
attributeInfo
);
List
<
String
>
currentElements
=
new
ArrayList
<>();
List
<
String
>
newElementsCreated
=
new
ArrayList
<>();
List
<
String
>
newKeysCreated
=
new
ArrayList
<>();
Map
<
String
,
String
>
currentMap
=
new
HashMap
<>();
Map
<
String
,
Object
>
newMap
=
new
HashMap
<>();
List
<
String
>
currentKeys
=
instanceVertex
.
getProperty
(
propertyName
);
if
(
currentKeys
!=
null
&&
!
currentKeys
.
isEmpty
())
{
for
(
String
key
:
currentKeys
)
{
String
propertyNameForKey
=
GraphHelper
.
getQualifiedNameForMapKey
(
propertyName
,
key
);
String
propertyValueForKey
=
instanceVertex
.
getProperty
(
propertyNameForKey
).
toString
();
currentMap
.
put
(
key
,
propertyValueForKey
);
}
}
if
(!
newAttributeEmpty
)
{
for
(
Map
.
Entry
entry
:
newAttribute
.
entrySet
())
{
String
propertyNameForKey
=
GraphHelper
.
getQualifiedNameForMapKey
(
propertyName
,
entry
.
getKey
().
toString
()
);
newKeysCreated
.
add
(
entry
.
getKey
().
toString
()
);
String
keyStr
=
entry
.
getKey
().
toString
(
);
String
propertyNameForKey
=
GraphHelper
.
getQualifiedNameForMapKey
(
propertyName
,
keyStr
);
String
currentEntry
=
instanceVertex
.
getProperty
(
propertyNameForKey
);
if
(
currentEntry
!=
null
)
{
currentElements
.
add
(
currentEntry
);
}
String
newEntry
=
addOrUpdateCollectionEntry
(
instanceVertex
,
attributeInfo
,
elementType
,
entry
.
getValue
(),
currentEntry
,
propertyNameForKey
,
operation
);
Object
newEntry
=
addOrUpdateCollectionEntry
(
instanceVertex
,
attributeInfo
,
elementType
,
entry
.
getValue
(),
currentMap
.
get
(
keyStr
),
propertyNameForKey
,
operation
);
//Add/Update/Remove property value
GraphHelper
.
setProperty
(
instanceVertex
,
propertyNameForKey
,
newEntry
);
new
ElementsCreated
.
add
(
newEntry
);
new
Map
.
put
(
keyStr
,
newEntry
);
}
}
Map
<
String
,
String
>
additionalMap
=
removeUnusedMapEntries
(
instanceVertex
,
propertyName
,
currentMap
,
newMap
,
elementType
,
attributeInfo
);
Set
<
String
>
newKeys
=
new
HashSet
<>(
newMap
.
keySet
());
newKeys
.
addAll
(
additionalMap
.
keySet
());
// for dereference on way out
GraphHelper
.
setProperty
(
instanceVertex
,
propertyName
,
newKeysCreated
);
GraphHelper
.
setProperty
(
instanceVertex
,
propertyName
,
new
ArrayList
<>(
newKeys
));
}
//Remove unused entries from map
private
Map
<
String
,
String
>
removeUnusedMapEntries
(
Vertex
instanceVertex
,
String
propertyName
,
Map
<
String
,
String
>
currentMap
,
Map
<
String
,
Object
>
newMap
,
IDataType
elementType
,
AttributeInfo
attributeInfo
)
throws
AtlasException
{
boolean
reference
=
(
elementType
.
getTypeCategory
()
==
DataTypes
.
TypeCategory
.
STRUCT
||
elementType
.
getTypeCategory
()
==
DataTypes
.
TypeCategory
.
CLASS
);
Map
<
String
,
String
>
additionalMap
=
new
HashMap
<>();
for
(
String
currentKey
:
currentMap
.
keySet
())
{
boolean
shouldDeleteKey
=
!
newMap
.
containsKey
(
currentKey
);
if
(
reference
)
{
String
currentEdge
=
currentMap
.
get
(
currentKey
);
//Delete the edge reference if its not part of new edges created/updated
if
(!
newMap
.
values
().
contains
(
currentEdge
))
{
String
edgeLabel
=
GraphHelper
.
getQualifiedNameForMapKey
(
propertyName
,
currentKey
);
Edge
edge
=
graphHelper
.
getEdgeByEdgeId
(
instanceVertex
,
edgeLabel
,
currentMap
.
get
(
currentKey
));
boolean
deleted
=
deleteHandler
.
deleteEdgeReference
(
edge
,
elementType
.
getTypeCategory
(),
attributeInfo
.
isComposite
,
true
);
if
(!
deleted
)
{
additionalMap
.
put
(
currentKey
,
currentEdge
);
shouldDeleteKey
=
false
;
}
}
}
removeUnusedEntries
(
currentElements
,
newElementsCreated
,
elementType
,
attributeInfo
);
if
(
shouldDeleteKey
)
{
String
propertyNameForKey
=
GraphHelper
.
getQualifiedNameForMapKey
(
propertyName
,
currentKey
);
graphHelper
.
setProperty
(
instanceVertex
,
propertyNameForKey
,
null
);
}
}
return
additionalMap
;
}
/******************************************** ARRAY & MAP **************************************************/
private
String
addOrUpdateCollectionEntry
(
Vertex
instanceVertex
,
AttributeInfo
attributeInfo
,
private
Object
addOrUpdateCollectionEntry
(
Vertex
instanceVertex
,
AttributeInfo
attributeInfo
,
IDataType
elementType
,
Object
newAttributeValue
,
String
currentValue
,
String
propertyName
,
Operation
operation
)
throws
AtlasException
{
...
...
@@ -460,7 +481,7 @@ public final class TypedInstanceToGraphMapper {
switch
(
elementType
.
getTypeCategory
())
{
case
PRIMITIVE:
case
ENUM:
return
newAttributeValue
!=
null
?
newAttributeValue
.
toString
()
:
null
;
return
newAttributeValue
!=
null
?
newAttributeValue
:
null
;
case
ARRAY:
case
MAP:
...
...
@@ -471,7 +492,7 @@ public final class TypedInstanceToGraphMapper {
case
STRUCT:
case
CLASS:
final
String
edgeLabel
=
GraphHelper
.
EDGE_LABEL_PREFIX
+
propertyName
;
Edge
currentEdge
=
graphHelper
.
getEdgeBy
Id
(
currentValue
);
Edge
currentEdge
=
graphHelper
.
getEdgeBy
EdgeId
(
instanceVertex
,
edgeLabel
,
currentValue
);
return
addOrUpdateReference
(
instanceVertex
,
attributeInfo
,
elementType
,
newAttributeValue
,
currentEdge
,
edgeLabel
,
operation
);
...
...
@@ -526,7 +547,7 @@ public final class TypedInstanceToGraphMapper {
mapInstanceToVertex
(
structInstance
,
structInstanceVertex
,
structInstance
.
fieldMapping
().
fields
,
false
,
Operation
.
CREATE
);
// add an edge to the newly created vertex from the parent
Edge
newEdge
=
graphHelper
.
add
Edge
(
instanceVertex
,
structInstanceVertex
,
edgeLabel
);
Edge
newEdge
=
graphHelper
.
getOrCreate
Edge
(
instanceVertex
,
structInstanceVertex
,
edgeLabel
);
return
newEdge
;
}
...
...
@@ -575,7 +596,7 @@ public final class TypedInstanceToGraphMapper {
private
Edge
addClassEdge
(
Vertex
instanceVertex
,
Vertex
toVertex
,
String
edgeLabel
)
throws
AtlasException
{
// add an edge to the class vertex from the instance
return
graphHelper
.
add
Edge
(
instanceVertex
,
toVertex
,
edgeLabel
);
return
graphHelper
.
getOrCreate
Edge
(
instanceVertex
,
toVertex
,
edgeLabel
);
}
private
Vertex
getClassVertex
(
ITypedReferenceableInstance
typedReference
)
throws
EntityNotFoundException
{
...
...
@@ -644,7 +665,7 @@ public final class TypedInstanceToGraphMapper {
// add an edge to the newly created vertex from the parent
String
relationshipLabel
=
GraphHelper
.
getTraitLabel
(
entityType
.
getName
(),
traitName
);
graphHelper
.
add
Edge
(
parentInstanceVertex
,
traitInstanceVertex
,
relationshipLabel
);
graphHelper
.
getOrCreate
Edge
(
parentInstanceVertex
,
traitInstanceVertex
,
relationshipLabel
);
}
/******************************************** PRIMITIVES **************************************************/
...
...
This diff is collapsed.
Click to expand it.
repository/src/main/java/org/apache/atlas/repository/typestore/GraphBackedTypeStore.java
View file @
705014eb
...
...
@@ -69,6 +69,8 @@ public class GraphBackedTypeStore implements ITypeStore {
private
final
TitanGraph
titanGraph
;
private
GraphHelper
graphHelper
=
GraphHelper
.
getInstance
();
@Inject
public
GraphBackedTypeStore
(
GraphProvider
<
TitanGraph
>
graphProvider
)
{
titanGraph
=
graphProvider
.
get
();
...
...
@@ -155,7 +157,7 @@ public class GraphBackedTypeStore implements ITypeStore {
for
(
String
superTypeName
:
superTypes
)
{
HierarchicalType
superType
=
typeSystem
.
getDataType
(
HierarchicalType
.
class
,
superTypeName
);
Vertex
superVertex
=
createVertex
(
superType
.
getTypeCategory
(),
superTypeName
,
superType
.
getDescription
());
add
Edge
(
vertex
,
superVertex
,
SUPERTYPE_EDGE_LABEL
);
graphHelper
.
getOrCreate
Edge
(
vertex
,
superVertex
,
SUPERTYPE_EDGE_LABEL
);
}
}
}
...
...
@@ -200,26 +202,11 @@ public class GraphBackedTypeStore implements ITypeStore {
if
(!
coreTypes
.
contains
(
attrType
.
getName
()))
{
Vertex
attrVertex
=
createVertex
(
attrType
.
getTypeCategory
(),
attrType
.
getName
(),
attrType
.
getDescription
());
String
label
=
getEdgeLabel
(
vertexTypeName
,
attribute
.
name
);
add
Edge
(
vertex
,
attrVertex
,
label
);
graphHelper
.
getOrCreate
Edge
(
vertex
,
attrVertex
,
label
);
}
}
}
private
void
addEdge
(
Vertex
fromVertex
,
Vertex
toVertex
,
String
label
)
{
Iterator
<
Edge
>
edges
=
GraphHelper
.
getOutGoingEdgesByLabel
(
fromVertex
,
label
);
// ATLAS-474: Check if this type system edge already exists, to avoid duplicates.
while
(
edges
.
hasNext
())
{
Edge
edge
=
edges
.
next
();
if
(
edge
.
getVertex
(
Direction
.
IN
).
equals
(
toVertex
))
{
LOG
.
debug
(
"Edge from {} to {} with label {} already exists"
,
toString
(
fromVertex
),
toString
(
toVertex
),
label
);
return
;
}
}
LOG
.
debug
(
"Adding edge from {} to {} with label {}"
,
toString
(
fromVertex
),
toString
(
toVertex
),
label
);
titanGraph
.
addEdge
(
null
,
fromVertex
,
toVertex
,
label
);
}
@Override
@GraphTransaction
public
TypesDef
restore
()
throws
AtlasException
{
...
...
This diff is collapsed.
Click to expand it.
repository/src/main/java/org/apache/atlas/services/DefaultMetadataService.java
View file @
705014eb
...
...
@@ -26,6 +26,7 @@ import org.apache.atlas.ApplicationProperties;
import
org.apache.atlas.AtlasClient
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.EntityAuditEvent
;
import
org.apache.atlas.RequestContext
;
import
org.apache.atlas.classification.InterfaceAudience
;
import
org.apache.atlas.ha.HAConfiguration
;
import
org.apache.atlas.listener.ActiveStateChangeHandler
;
...
...
@@ -58,8 +59,6 @@ import org.apache.atlas.typesystem.types.Multiplicity;
import
org.apache.atlas.typesystem.types.StructTypeDefinition
;
import
org.apache.atlas.typesystem.types.TraitType
;
import
org.apache.atlas.typesystem.types.TypeSystem
;
import
org.apache.atlas.typesystem.types.TypeUtils
;
import
org.apache.atlas.typesystem.types.TypeUtils.Pair
;
import
org.apache.atlas.typesystem.types.ValueConversionException
;
import
org.apache.atlas.typesystem.types.utils.TypesUtil
;
import
org.apache.atlas.utils.ParamChecker
;
...
...
@@ -305,16 +304,15 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
* Creates an entity, instance of the type.
*
* @param entityInstanceDefinition json array of entity definitions
* @return guids -
json array
of guids
* @return guids -
list
of guids
*/
@Override
public
String
createEntities
(
String
entityInstanceDefinition
)
throws
AtlasException
{
public
List
<
String
>
createEntities
(
String
entityInstanceDefinition
)
throws
AtlasException
{
ParamChecker
.
notEmpty
(
entityInstanceDefinition
,
"Entity instance definition"
);
ITypedReferenceableInstance
[]
typedInstances
=
deserializeClassInstances
(
entityInstanceDefinition
);
List
<
String
>
guids
=
createEntities
(
typedInstances
);
return
new
JSONArray
(
guids
).
toString
();
return
createEntities
(
typedInstances
);
}
public
List
<
String
>
createEntities
(
ITypedReferenceableInstance
[]
typedInstances
)
throws
AtlasException
{
...
...
@@ -422,25 +420,26 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
* @return guids - json array of guids
*/
@Override
public
String
updateEntities
(
String
entityInstanceDefinition
)
throws
AtlasException
{
public
AtlasClient
.
EntityResult
updateEntities
(
String
entityInstanceDefinition
)
throws
AtlasException
{
ParamChecker
.
notEmpty
(
entityInstanceDefinition
,
"Entity instance definition"
);
ITypedReferenceableInstance
[]
typedInstances
=
deserializeClassInstances
(
entityInstanceDefinition
);
TypeUtils
.
Pair
<
List
<
String
>,
List
<
String
>>
guids
=
repository
.
updateEntities
(
typedInstances
);
return
onEntitiesAddedUpdated
(
guids
);
AtlasClient
.
EntityResult
entityResult
=
repository
.
updateEntities
(
typedInstances
);
onEntitiesAddedUpdated
(
entityResult
);
return
entityResult
;
}
private
String
onEntitiesAddedUpdated
(
TypeUtils
.
Pair
<
List
<
String
>,
List
<
String
>>
guids
)
throws
AtlasException
{
onEntitiesAdded
(
guids
.
left
);
onEntitiesUpdated
(
guids
.
right
);
guids
.
left
.
addAll
(
guids
.
right
);
return
new
JSONArray
(
guids
.
left
).
toString
();
private
void
onEntitiesAddedUpdated
(
AtlasClient
.
EntityResult
entityResult
)
throws
AtlasException
{
onEntitiesAdded
(
entityResult
.
getCreatedEntities
());
onEntitiesUpdated
(
entityResult
.
getUpdateEntities
());
//Note: doesn't access deletedEntities from entityResult
onEntitiesDeleted
(
RequestContext
.
get
().
getDeletedEntities
());
}
@Override
public
String
updateEntityAttributeByGuid
(
final
String
guid
,
String
attributeName
,
String
value
)
throws
AtlasException
{
public
AtlasClient
.
EntityResult
updateEntityAttributeByGuid
(
final
String
guid
,
String
attributeName
,
String
value
)
throws
AtlasException
{
ParamChecker
.
notEmpty
(
guid
,
"entity id"
);
ParamChecker
.
notEmpty
(
attributeName
,
"attribute name"
);
ParamChecker
.
notEmpty
(
value
,
"attribute value"
);
...
...
@@ -469,8 +468,9 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
}
((
ReferenceableInstance
)
newInstance
).
replaceWithNewId
(
new
Id
(
guid
,
0
,
newInstance
.
getTypeName
()));
TypeUtils
.
Pair
<
List
<
String
>,
List
<
String
>>
guids
=
repository
.
updatePartial
(
newInstance
);
return
onEntitiesAddedUpdated
(
guids
);
AtlasClient
.
EntityResult
entityResult
=
repository
.
updatePartial
(
newInstance
);
onEntitiesAddedUpdated
(
entityResult
);
return
entityResult
;
}
private
ITypedReferenceableInstance
validateEntityExists
(
String
guid
)
...
...
@@ -483,7 +483,8 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
}
@Override
public
String
updateEntityPartialByGuid
(
final
String
guid
,
Referenceable
newEntity
)
throws
AtlasException
{
public
AtlasClient
.
EntityResult
updateEntityPartialByGuid
(
final
String
guid
,
Referenceable
newEntity
)
throws
AtlasException
{
ParamChecker
.
notEmpty
(
guid
,
"guid cannot be null"
);
ParamChecker
.
notNull
(
newEntity
,
"updatedEntity cannot be null"
);
ITypedReferenceableInstance
existInstance
=
validateEntityExists
(
guid
);
...
...
@@ -491,11 +492,13 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
ITypedReferenceableInstance
newInstance
=
convertToTypedInstance
(
newEntity
,
existInstance
.
getTypeName
());
((
ReferenceableInstance
)
newInstance
).
replaceWithNewId
(
new
Id
(
guid
,
0
,
newInstance
.
getTypeName
()));
TypeUtils
.
Pair
<
List
<
String
>,
List
<
String
>>
guids
=
repository
.
updatePartial
(
newInstance
);
return
onEntitiesAddedUpdated
(
guids
);
AtlasClient
.
EntityResult
entityResult
=
repository
.
updatePartial
(
newInstance
);
onEntitiesAddedUpdated
(
entityResult
);
return
entityResult
;
}
private
ITypedReferenceableInstance
convertToTypedInstance
(
Referenceable
updatedEntity
,
String
typeName
)
throws
AtlasException
{
private
ITypedReferenceableInstance
convertToTypedInstance
(
Referenceable
updatedEntity
,
String
typeName
)
throws
AtlasException
{
ClassType
type
=
typeSystem
.
getDataType
(
ClassType
.
class
,
typeName
);
ITypedReferenceableInstance
newInstance
=
type
.
createInstance
();
...
...
@@ -538,8 +541,9 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
}
@Override
public
String
updateEntityByUniqueAttribute
(
String
typeName
,
String
uniqueAttributeName
,
String
attrValue
,
Referenceable
updatedEntity
)
throws
AtlasException
{
public
AtlasClient
.
EntityResult
updateEntityByUniqueAttribute
(
String
typeName
,
String
uniqueAttributeName
,
String
attrValue
,
Referenceable
updatedEntity
)
throws
AtlasException
{
ParamChecker
.
notEmpty
(
typeName
,
"typeName"
);
ParamChecker
.
notEmpty
(
uniqueAttributeName
,
"uniqueAttributeName"
);
ParamChecker
.
notNull
(
attrValue
,
"unique attribute value"
);
...
...
@@ -550,8 +554,9 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
final
ITypedReferenceableInstance
newInstance
=
convertToTypedInstance
(
updatedEntity
,
typeName
);
((
ReferenceableInstance
)
newInstance
).
replaceWithNewId
(
oldInstance
.
getId
());
TypeUtils
.
Pair
<
List
<
String
>,
List
<
String
>>
guids
=
repository
.
updatePartial
(
newInstance
);
return
onEntitiesAddedUpdated
(
guids
);
AtlasClient
.
EntityResult
entityResult
=
repository
.
updatePartial
(
newInstance
);
onEntitiesAddedUpdated
(
entityResult
);
return
entityResult
;
}
private
void
validateTypeExists
(
String
entityType
)
throws
AtlasException
{
...
...
@@ -726,13 +731,14 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
* @see org.apache.atlas.services.MetadataService#deleteEntities(java.lang.String)
*/
@Override
public
List
<
String
>
deleteEntities
(
List
<
String
>
deleteCandidateGuids
)
throws
AtlasException
{
public
AtlasClient
.
EntityResult
deleteEntities
(
List
<
String
>
deleteCandidateGuids
)
throws
AtlasException
{
ParamChecker
.
notEmpty
(
deleteCandidateGuids
,
"delete candidate guids"
);
return
deleteGuids
(
deleteCandidateGuids
);
}
@Override
public
List
<
String
>
deleteEntityByUniqueAttribute
(
String
typeName
,
String
uniqueAttributeName
,
String
attrValue
)
throws
AtlasException
{
public
AtlasClient
.
EntityResult
deleteEntityByUniqueAttribute
(
String
typeName
,
String
uniqueAttributeName
,
String
attrValue
)
throws
AtlasException
{
ParamChecker
.
notEmpty
(
typeName
,
"delete candidate typeName"
);
ParamChecker
.
notEmpty
(
uniqueAttributeName
,
"delete candidate unique attribute name"
);
ParamChecker
.
notEmpty
(
attrValue
,
"delete candidate unique attribute value"
);
...
...
@@ -745,12 +751,10 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
return
deleteGuids
(
deleteCandidateGuids
);
}
private
List
<
String
>
deleteGuids
(
List
<
String
>
deleteCandidateGuids
)
throws
AtlasException
{
Pair
<
List
<
String
>,
List
<
ITypedReferenceableInstance
>>
deleteEntitiesResult
=
repository
.
deleteEntities
(
deleteCandidateGuids
);
if
(
deleteEntitiesResult
.
right
.
size
()
>
0
)
{
onEntitiesDeleted
(
deleteEntitiesResult
.
right
);
}
return
deleteEntitiesResult
.
left
;
private
AtlasClient
.
EntityResult
deleteGuids
(
List
<
String
>
deleteCandidateGuids
)
throws
AtlasException
{
AtlasClient
.
EntityResult
entityResult
=
repository
.
deleteEntities
(
deleteCandidateGuids
);
onEntitiesAddedUpdated
(
entityResult
);
return
entityResult
;
}
private
void
onEntitiesDeleted
(
List
<
ITypedReferenceableInstance
>
entities
)
throws
AtlasException
{
...
...
This diff is collapsed.
Click to expand it.
repository/src/test/java/org/apache/atlas/repository/audit/AuditRepositoryTestBase.java
View file @
705014eb
...
...
@@ -19,6 +19,7 @@
package
org
.
apache
.
atlas
.
repository
.
audit
;
import
org.apache.atlas.EntityAuditEvent
;
import
org.apache.atlas.typesystem.Referenceable
;
import
org.apache.commons.lang.RandomStringUtils
;
import
org.testng.annotations.Test
;
...
...
@@ -38,7 +39,7 @@ public class AuditRepositoryTestBase {
@Test
public
void
testAddEvents
()
throws
Exception
{
EntityAuditEvent
event
=
new
EntityAuditEvent
(
rand
(),
System
.
currentTimeMillis
(),
"u1"
,
EntityAuditEvent
.
EntityAuditAction
.
ENTITY_CREATE
,
"d1"
);
EntityAuditEvent
.
EntityAuditAction
.
ENTITY_CREATE
,
"d1"
,
new
Referenceable
(
rand
())
);
eventRepository
.
putEvents
(
event
);
...
...
@@ -54,17 +55,18 @@ public class AuditRepositoryTestBase {
String
id2
=
"id2"
+
rand
();
String
id3
=
"id3"
+
rand
();
long
ts
=
System
.
currentTimeMillis
();
Referenceable
entity
=
new
Referenceable
(
rand
());
List
<
EntityAuditEvent
>
expectedEvents
=
new
ArrayList
<>(
3
);
for
(
int
i
=
0
;
i
<
3
;
i
++)
{
//Add events for both ids
EntityAuditEvent
event
=
new
EntityAuditEvent
(
id2
,
ts
-
i
,
"user"
+
i
,
EntityAuditEvent
.
EntityAuditAction
.
ENTITY_UPDATE
,
"details"
+
i
);
EntityAuditEvent
.
EntityAuditAction
.
ENTITY_UPDATE
,
"details"
+
i
,
entity
);
eventRepository
.
putEvents
(
event
);
expectedEvents
.
add
(
event
);
eventRepository
.
putEvents
(
new
EntityAuditEvent
(
id1
,
ts
-
i
,
"user"
+
i
,
EntityAuditEvent
.
EntityAuditAction
.
TAG_DELETE
,
"details"
+
i
));
EntityAuditEvent
.
EntityAuditAction
.
TAG_DELETE
,
"details"
+
i
,
entity
));
eventRepository
.
putEvents
(
new
EntityAuditEvent
(
id3
,
ts
-
i
,
"user"
+
i
,
EntityAuditEvent
.
EntityAuditAction
.
TAG_ADD
,
"details"
+
i
));
EntityAuditEvent
.
EntityAuditAction
.
TAG_ADD
,
"details"
+
i
,
entity
));
}
//Use ts for which there is no event - ts + 2
...
...
This diff is collapsed.
Click to expand it.
repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryDeleteTestBase.java
View file @
705014eb
...
...
@@ -23,7 +23,6 @@ import com.google.common.collect.ImmutableSet;
import
com.thinkaurelius.titan.core.TitanGraph
;
import
com.thinkaurelius.titan.core.util.TitanCleanup
;
import
com.tinkerpop.blueprints.Vertex
;
import
org.apache.atlas.AtlasClient
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.RepositoryMetadataModule
;
...
...
@@ -50,7 +49,6 @@ import org.apache.atlas.typesystem.types.Multiplicity;
import
org.apache.atlas.typesystem.types.StructTypeDefinition
;
import
org.apache.atlas.typesystem.types.TraitType
;
import
org.apache.atlas.typesystem.types.TypeSystem
;
import
org.apache.atlas.typesystem.types.TypeUtils
;
import
org.apache.atlas.typesystem.types.utils.TypesUtil
;
import
org.testng.Assert
;
import
org.testng.annotations.AfterClass
;
...
...
@@ -60,7 +58,6 @@ import org.testng.annotations.Guice;
import
org.testng.annotations.Test
;
import
javax.inject.Inject
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
...
...
@@ -71,6 +68,7 @@ import java.util.Map;
import
static
org
.
apache
.
atlas
.
TestUtils
.
COLUMNS_ATTR_NAME
;
import
static
org
.
apache
.
atlas
.
TestUtils
.
COLUMN_TYPE
;
import
static
org
.
apache
.
atlas
.
TestUtils
.
NAME
;
import
static
org
.
apache
.
atlas
.
TestUtils
.
PII
;
import
static
org
.
apache
.
atlas
.
TestUtils
.
PROCESS_TYPE
;
import
static
org
.
apache
.
atlas
.
TestUtils
.
TABLE_TYPE
;
import
static
org
.
apache
.
atlas
.
TestUtils
.
createColumnEntity
;
...
...
@@ -78,8 +76,6 @@ import static org.apache.atlas.TestUtils.createDBEntity;
import
static
org
.
apache
.
atlas
.
TestUtils
.
createTableEntity
;
import
static
org
.
testng
.
Assert
.
assertEquals
;
import
static
org
.
testng
.
Assert
.
assertNotEquals
;
import
static
org
.
testng
.
Assert
.
assertNotNull
;
import
static
org
.
testng
.
Assert
.
assertNull
;
import
static
org
.
testng
.
Assert
.
assertTrue
;
import
static
org
.
testng
.
Assert
.
fail
;
...
...
@@ -145,7 +141,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
assertEquals
(
instance
.
getId
().
_getId
(),
id
);
//delete entity should mark it as deleted
List
<
String
>
results
=
deleteEntities
(
id
);
List
<
String
>
results
=
deleteEntities
(
id
)
.
getDeletedEntities
()
;
assertEquals
(
results
.
get
(
0
),
id
);
assertEntityDeleted
(
id
);
...
...
@@ -167,6 +163,26 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
}
@Test
public
void
testDeleteEntityWithTraits
()
throws
Exception
{
Referenceable
entity
=
createDBEntity
();
String
id
=
createInstance
(
entity
);
TraitType
dataType
=
typeSystem
.
getDataType
(
TraitType
.
class
,
PII
);
ITypedStruct
trait
=
dataType
.
convert
(
new
Struct
(
TestUtils
.
PII
),
Multiplicity
.
REQUIRED
);
repositoryService
.
addTrait
(
id
,
trait
);
ITypedReferenceableInstance
instance
=
repositoryService
.
getEntityDefinition
(
id
);
assertTrue
(
instance
.
getTraits
().
contains
(
PII
));
deleteEntities
(
id
);
assertEntityDeleted
(
id
);
assertTestDeleteEntityWithTraits
(
id
);
}
protected
abstract
void
assertTestDeleteEntityWithTraits
(
String
guid
)
throws
EntityNotFoundException
,
RepositoryException
,
Exception
;
@Test
public
void
testDeleteReference
()
throws
Exception
{
//Deleting column should update table
Referenceable
db
=
createDBEntity
();
...
...
@@ -179,13 +195,16 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
table
.
set
(
COLUMNS_ATTR_NAME
,
Arrays
.
asList
(
new
Id
(
colId
,
0
,
COLUMN_TYPE
)));
String
tableId
=
createInstance
(
table
);
deleteEntities
(
colId
);
AtlasClient
.
EntityResult
entityResult
=
deleteEntities
(
colId
);
assertEquals
(
entityResult
.
getDeletedEntities
().
size
(),
1
);
assertEquals
(
entityResult
.
getDeletedEntities
().
get
(
0
),
colId
);
assertEquals
(
entityResult
.
getUpdateEntities
().
size
(),
1
);
assertEquals
(
entityResult
.
getUpdateEntities
().
get
(
0
),
tableId
);
assertEntityDeleted
(
colId
);
ITypedReferenceableInstance
tableInstance
=
repositoryService
.
getEntityDefinition
(
tableId
);
List
<
ITypedReferenceableInstance
>
columns
=
(
List
<
ITypedReferenceableInstance
>)
tableInstance
.
get
(
COLUMNS_ATTR_NAME
);
assertNull
(
columns
);
assertColumnForTestDeleteReference
(
tableInstance
);
//Deleting table should update process
Referenceable
process
=
new
Referenceable
(
PROCESS_TYPE
);
...
...
@@ -195,18 +214,23 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
deleteEntities
(
tableId
);
assertEntityDeleted
(
tableId
);
assertTestDeleteReference
(
processInstance
);
assertTableForTestDeleteReference
(
tableId
);
assertProcessForTestDeleteReference
(
processInstance
);
}
protected
abstract
void
assertTestDeleteReference
(
ITypedReferenceableInstance
processInstance
)
throws
Exception
;
protected
abstract
void
assertTableForTestDeleteReference
(
String
tableId
)
throws
Exception
;
protected
abstract
void
assertColumnForTestDeleteReference
(
ITypedReferenceableInstance
tableInstance
)
throws
AtlasException
;
protected
abstract
void
assertProcessForTestDeleteReference
(
ITypedReferenceableInstance
processInstance
)
throws
Exception
;
protected
abstract
void
assertEntityDeleted
(
String
id
)
throws
Exception
;
private
List
<
String
>
deleteEntities
(
String
...
id
)
throws
Exception
{
private
AtlasClient
.
EntityResult
deleteEntities
(
String
...
id
)
throws
Exception
{
RequestContext
.
createContext
();
List
<
String
>
response
=
repositoryService
.
deleteEntities
(
Arrays
.
asList
(
id
)).
left
;
assertNotNull
(
response
);
return
response
;
return
repositoryService
.
deleteEntities
(
Arrays
.
asList
(
id
));
}
private
String
createInstance
(
Referenceable
entity
)
throws
Exception
{
...
...
@@ -228,21 +252,41 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
table1Entity
.
set
(
COLUMNS_ATTR_NAME
,
ImmutableList
.
of
(
col1
,
col2
,
col3
));
createInstance
(
table1Entity
);
// Retrieve the table entities from the auditRepository,
// to get their guids and the composite column guids.
// Retrieve the table entities from the Repository, to get their guids and the composite column guids.
ITypedReferenceableInstance
tableInstance
=
repositoryService
.
getEntityDefinition
(
TestUtils
.
TABLE_TYPE
,
NAME
,
table1Entity
.
get
(
NAME
));
List
<
IReferenceableInstance
>
table1Columns
=
(
List
<
IReferenceableInstance
>)
tableInstance
.
get
(
COLUMNS_ATTR_NAME
);
List
<
IReferenceableInstance
>
columns
=
(
List
<
IReferenceableInstance
>)
tableInstance
.
get
(
COLUMNS_ATTR_NAME
);
//Delete column
String
colId
=
columns
.
get
(
0
).
getId
().
_getId
();
String
tableId
=
tableInstance
.
getId
().
_getId
();
AtlasClient
.
EntityResult
entityResult
=
deleteEntities
(
colId
);
assertEquals
(
entityResult
.
getDeletedEntities
().
size
(),
1
);
assertEquals
(
entityResult
.
getDeletedEntities
().
get
(
0
),
colId
);
assertEquals
(
entityResult
.
getUpdateEntities
().
size
(),
1
);
assertEquals
(
entityResult
.
getUpdateEntities
().
get
(
0
),
tableId
);
assertEntityDeleted
(
colId
);
tableInstance
=
repositoryService
.
getEntityDefinition
(
TestUtils
.
TABLE_TYPE
,
NAME
,
table1Entity
.
get
(
NAME
));
assertDeletedColumn
(
tableInstance
);
// Delete the table entities. The deletion should cascade
// to their composite columns.
List
<
String
>
deletedGuids
=
deleteEntities
(
tableInstance
.
getId
().
_getId
());
//update by removing a column
tableInstance
.
set
(
COLUMNS_ATTR_NAME
,
ImmutableList
.
of
(
col3
));
entityResult
=
updatePartial
(
tableInstance
);
colId
=
columns
.
get
(
1
).
getId
().
_getId
();
assertEquals
(
entityResult
.
getDeletedEntities
().
size
(),
1
);
assertEquals
(
entityResult
.
getDeletedEntities
().
get
(
0
),
colId
);
assertEntityDeleted
(
colId
);
// Delete the table entities. The deletion should cascade to their composite columns.
tableInstance
=
repositoryService
.
getEntityDefinition
(
TestUtils
.
TABLE_TYPE
,
NAME
,
table1Entity
.
get
(
NAME
));
List
<
String
>
deletedGuids
=
deleteEntities
(
tableInstance
.
getId
().
_getId
()).
getDeletedEntities
();
assertEquals
(
deletedGuids
.
size
(),
2
);
// Verify that deleteEntities() response has guids for tables and their composite columns.
Assert
.
assertTrue
(
deletedGuids
.
contains
(
tableInstance
.
getId
().
_getId
()));
for
(
IReferenceableInstance
column
:
table1Columns
)
{
Assert
.
assertTrue
(
deletedGuids
.
contains
(
column
.
getId
().
_getId
()));
}
Assert
.
assertTrue
(
deletedGuids
.
contains
(
columns
.
get
(
2
).
getId
().
_getId
()));
// Verify that tables and their composite columns have been deleted from the graph Repository.
for
(
String
guid
:
deletedGuids
)
{
...
...
@@ -251,6 +295,8 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
assertTestDeleteEntities
(
tableInstance
);
}
protected
abstract
void
assertDeletedColumn
(
ITypedReferenceableInstance
tableInstance
)
throws
AtlasException
;
protected
abstract
void
assertTestDeleteEntities
(
ITypedReferenceableInstance
tableInstance
)
throws
Exception
;
/**
...
...
@@ -276,12 +322,13 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
vertexCount
=
getVertices
(
Constants
.
ENTITY_TYPE_PROPERTY_KEY
,
"SecurityClearance"
).
size
();
Assert
.
assertEquals
(
vertexCount
,
1
);
List
<
String
>
deletedEntities
=
deleteEntities
(
hrDeptGuid
);
List
<
String
>
deletedEntities
=
deleteEntities
(
hrDeptGuid
)
.
getDeletedEntities
()
;
assertTrue
(
deletedEntities
.
contains
(
hrDeptGuid
));
assertEntityDeleted
(
hrDeptGuid
);
// Verify Department entity and its contained Person entities were deleted.
assertEntityDeleted
(
hrDeptGuid
);
for
(
String
employeeGuid
:
employeeGuids
)
{
assertTrue
(
deletedEntities
.
contains
(
employeeGuid
));
assertEntityDeleted
(
employeeGuid
);
}
...
...
@@ -341,15 +388,16 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
object
=
mapOwnerVertex
.
getProperty
(
atlasEdgeLabel
.
getQualifiedMapKey
());
Assert
.
assertNotNull
(
object
);
List
<
String
>
deletedEntities
=
deleteEntities
(
mapOwnerGuid
);
List
<
String
>
deletedEntities
=
deleteEntities
(
mapOwnerGuid
)
.
getDeletedEntities
()
;
Assert
.
assertEquals
(
deletedEntities
.
size
(),
2
);
Assert
.
assertTrue
(
deletedEntities
.
containsAll
(
guids
));
Assert
.
assertTrue
(
deletedEntities
.
contains
(
mapOwnerGuid
));
Assert
.
assertTrue
(
deletedEntities
.
contains
(
mapValueGuid
));
assertEntityDeleted
(
mapOwnerGuid
);
assertEntityDeleted
(
mapValueGuid
);
}
private
TypeUtils
.
Pair
<
List
<
String
>,
List
<
String
>>
updatePartial
(
ITypedReferenceableInstance
entity
)
throws
RepositoryException
{
private
AtlasClient
.
EntityResult
updatePartial
(
ITypedReferenceableInstance
entity
)
throws
RepositoryException
{
RequestContext
.
createContext
();
return
repositoryService
.
updatePartial
(
entity
);
}
...
...
@@ -379,7 +427,9 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
ClassType
personType
=
typeSystem
.
getDataType
(
ClassType
.
class
,
"Person"
);
ITypedReferenceableInstance
maxEntity
=
personType
.
createInstance
(
max
.
getId
());
maxEntity
.
set
(
"mentor"
,
johnGuid
);
updatePartial
(
maxEntity
);
AtlasClient
.
EntityResult
entityResult
=
updatePartial
(
maxEntity
);
assertEquals
(
entityResult
.
getUpdateEntities
().
size
(),
1
);
assertTrue
(
entityResult
.
getUpdateEntities
().
contains
(
maxGuid
));
// Verify the update was applied correctly - john should now be max's mentor.
max
=
repositoryService
.
getEntityDefinition
(
maxGuid
);
...
...
@@ -394,7 +444,9 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
// Update max's mentor reference to jane.
maxEntity
.
set
(
"mentor"
,
janeGuid
);
updatePartial
(
maxEntity
);
entityResult
=
updatePartial
(
maxEntity
);
assertEquals
(
entityResult
.
getUpdateEntities
().
size
(),
1
);
assertTrue
(
entityResult
.
getUpdateEntities
().
contains
(
maxGuid
));
// Verify the update was applied correctly - jane should now be max's mentor.
max
=
repositoryService
.
getEntityDefinition
(
maxGuid
);
...
...
@@ -411,7 +463,11 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
Id
juliusGuid
=
julius
.
getId
();
maxEntity
=
personType
.
createInstance
(
max
.
getId
());
maxEntity
.
set
(
"manager"
,
juliusGuid
);
updatePartial
(
maxEntity
);
entityResult
=
updatePartial
(
maxEntity
);
//TODO ATLAS-499 should have updated julius' subordinates
assertEquals
(
entityResult
.
getUpdateEntities
().
size
(),
2
);
assertTrue
(
entityResult
.
getUpdateEntities
().
contains
(
maxGuid
));
assertTrue
(
entityResult
.
getUpdateEntities
().
contains
(
janeGuid
.
_getId
()));
// Verify the update was applied correctly - julius should now be max's manager.
max
=
repositoryService
.
getEntityDefinition
(
maxGuid
);
...
...
@@ -456,41 +512,38 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
}
Assert
.
assertTrue
(
subordinateIds
.
contains
(
maxGuid
));
List
<
String
>
deletedEntities
=
deleteEntities
(
maxGuid
);
Assert
.
assertTrue
(
deletedEntities
.
contains
(
maxGuid
));
assertEntityDeleted
(
maxGuid
);
// Verify that the Department.employees reference to the deleted employee
// was disconnected.
hrDept
=
repositoryService
.
getEntityDefinition
(
hrDeptGuid
);
refValue
=
hrDept
.
get
(
"employees"
);
Assert
.
assertTrue
(
refValue
instanceof
List
);
List
<
Object
>
employees
=
(
List
<
Object
>)
refValue
;
Assert
.
assertEquals
(
employees
.
size
(),
3
);
for
(
Object
listValue
:
employees
)
{
Assert
.
assertTrue
(
listValue
instanceof
ITypedReferenceableInstance
);
ITypedReferenceableInstance
employee
=
(
ITypedReferenceableInstance
)
listValue
;
Assert
.
assertNotEquals
(
employee
.
getId
().
_getId
(),
maxGuid
);
}
AtlasClient
.
EntityResult
entityResult
=
deleteEntities
(
maxGuid
);
ITypedReferenceableInstance
john
=
repositoryService
.
getEntityDefinition
(
"Manager"
,
"name"
,
"John"
);
// Verify that max's Person.mentor unidirectional reference to john was disconnected.
ITypedReferenceableInstance
john
=
repositoryService
.
getEntityDefinition
(
johnGuid
);
refValue
=
john
.
get
(
"mentor"
);
Assert
.
assertNull
(
refValue
);
assertEquals
(
entityResult
.
getDeletedEntities
().
size
(),
1
);
assertTrue
(
entityResult
.
getDeletedEntities
().
contains
(
maxGuid
));
assertEquals
(
entityResult
.
getUpdateEntities
().
size
(),
3
);
assertTrue
(
entityResult
.
getUpdateEntities
().
containsAll
(
Arrays
.
asList
(
jane
.
getId
().
_getId
(),
hrDeptGuid
,
john
.
getId
().
_getId
())));
assertEntityDeleted
(
maxGuid
);
assert
TestDisconnectBidirectionalReferences
(
janeGuid
);
assert
MaxForTestDisconnectBidirectionalReferences
(
nameGuidMap
);
// Now delete jane - this should disconnect the manager reference from her
// subordinate.
deletedEntities
=
deleteEntities
(
janeGuid
);
Assert
.
assertTrue
(
deletedEntities
.
contains
(
janeGuid
));
entityResult
=
deleteEntities
(
janeGuid
);
assertEquals
(
entityResult
.
getDeletedEntities
().
size
(),
1
);
assertTrue
(
entityResult
.
getDeletedEntities
().
contains
(
janeGuid
));
assertEquals
(
entityResult
.
getUpdateEntities
().
size
(),
2
);
assertTrue
(
entityResult
.
getUpdateEntities
().
containsAll
(
Arrays
.
asList
(
hrDeptGuid
,
john
.
getId
().
_getId
())));
assertEntityDeleted
(
janeGuid
);
john
=
repositoryService
.
getEntityDefinition
(
johnGuid
);
Assert
.
assertNull
(
john
.
get
(
"manager"
)
);
john
=
repositoryService
.
getEntityDefinition
(
"Person"
,
"name"
,
"John"
);
assertJohnForTestDisconnectBidirectionalReferences
(
john
,
janeGuid
);
}
protected
abstract
void
assertTestDisconnectBidirectionalReferences
(
String
janeGuid
)
throws
Exception
;
protected
abstract
void
assertJohnForTestDisconnectBidirectionalReferences
(
ITypedReferenceableInstance
john
,
String
janeGuid
)
throws
Exception
;
protected
abstract
void
assertMaxForTestDisconnectBidirectionalReferences
(
Map
<
String
,
String
>
nameGuidMap
)
throws
Exception
;
/**
* Verify deleting entity that is the target of a unidirectional class array reference
...
...
@@ -503,30 +556,27 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
// Get the guid for one of the table's columns.
ITypedReferenceableInstance
table
=
repositoryService
.
getEntityDefinition
(
TestUtils
.
TABLE_TYPE
,
"name"
,
TestUtils
.
TABLE_NAME
);
String
tableGuid
=
table
.
getId
().
_getId
();
Object
refValues
=
table
.
get
(
"columns"
);
Assert
.
assertTrue
(
refValues
instanceof
List
);
List
<
Object
>
refList
=
(
List
<
Object
>)
refValues
;
Assert
.
assertEquals
(
refList
.
size
(),
5
);
Assert
.
assertTrue
(
refList
.
get
(
0
)
instanceof
ITypedReferenceableInstance
);
ITypedReferenceableInstance
column
=
(
ITypedReferenceableInstance
)
refList
.
get
(
0
);
String
columnGuid
=
column
.
getId
().
_getId
();
List
<
ITypedReferenceableInstance
>
columns
=
(
List
<
ITypedReferenceableInstance
>)
table
.
get
(
"columns"
);
Assert
.
assertEquals
(
columns
.
size
(),
5
);
String
columnGuid
=
columns
.
get
(
0
).
getId
().
_getId
();
// Delete the column.
List
<
String
>
deletedEntities
=
deleteEntities
(
columnGuid
);
Assert
.
assertTrue
(
deletedEntities
.
contains
(
columnGuid
));
AtlasClient
.
EntityResult
entityResult
=
deleteEntities
(
columnGuid
);
assertEquals
(
entityResult
.
getDeletedEntities
().
size
(),
1
);
Assert
.
assertTrue
(
entityResult
.
getDeletedEntities
().
contains
(
columnGuid
));
assertEquals
(
entityResult
.
getUpdateEntities
().
size
(),
1
);
Assert
.
assertTrue
(
entityResult
.
getUpdateEntities
().
contains
(
tableGuid
));
assertEntityDeleted
(
columnGuid
);
// Verify table.columns reference to the deleted column has been disconnected.
table
=
repositoryService
.
getEntityDefinition
(
tableGuid
);
refList
=
(
List
<
Object
>)
table
.
get
(
"columns"
);
Assert
.
assertEquals
(
refList
.
size
(),
4
);
for
(
Object
refValue
:
refList
)
{
Assert
.
assertTrue
(
refValue
instanceof
ITypedReferenceableInstance
);
column
=
(
ITypedReferenceableInstance
)
refValue
;
Assert
.
assertFalse
(
column
.
getId
().
_getId
().
equals
(
columnGuid
));
}
assertTestDisconnectUnidirectionalArrayReferenceFromClassType
(
(
List
<
ITypedReferenceableInstance
>)
table
.
get
(
"columns"
),
columnGuid
);
}
protected
abstract
void
assertTestDisconnectUnidirectionalArrayReferenceFromClassType
(
List
<
ITypedReferenceableInstance
>
columns
,
String
columnGuid
);
/**
* Verify deleting entities that are the target of a unidirectional class array reference
* from a struct or trait instance.
...
...
@@ -559,8 +609,8 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
Referenceable
structTargetEntity
=
new
Referenceable
(
"StructTarget"
);
Referenceable
traitTargetEntity
=
new
Referenceable
(
"TraitTarget"
);
Referenceable
structContainerEntity
=
new
Referenceable
(
"StructContainer"
);
Referenceable
structInstance
=
new
Referenceable
(
"TestStruct"
);
Referenceable
nestedStructInstance
=
new
Referenceable
(
"NestedStruct"
);
Struct
structInstance
=
new
Struct
(
"TestStruct"
);
Struct
nestedStructInstance
=
new
Struct
(
"NestedStruct"
);
Referenceable
traitInstance
=
new
Referenceable
(
"TestTrait"
);
structContainerEntity
.
set
(
"struct"
,
structInstance
);
structInstance
.
set
(
"target"
,
ImmutableList
.
of
(
structTargetEntity
));
...
...
@@ -623,19 +673,19 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
Assert
.
assertEquals
(
refList
.
get
(
0
).
getId
().
_getId
(),
traitTargetGuid
);
// Delete the entities that are targets of the struct and trait instances.
List
<
String
>
deletedEntities
=
deleteEntities
(
structTargetGuid
,
traitTargetGuid
);
AtlasClient
.
EntityResult
entityResult
=
deleteEntities
(
structTargetGuid
,
traitTargetGuid
);
Assert
.
assertEquals
(
entityResult
.
getDeletedEntities
().
size
(),
2
);
Assert
.
assertTrue
(
entityResult
.
getDeletedEntities
().
containsAll
(
Arrays
.
asList
(
structTargetGuid
,
traitTargetGuid
)));
assertEntityDeleted
(
structTargetGuid
);
assertEntityDeleted
(
traitTargetGuid
);
Assert
.
assertEquals
(
deletedEntities
.
size
(),
2
);
Assert
.
assertTrue
(
deletedEntities
.
containsAll
(
Arrays
.
asList
(
structTargetGuid
,
traitTargetGuid
)));
assertTestDisconnectUnidirectionalArrayReferenceFromStructAndTraitTypes
(
structContainerGuid
);
// Delete the entity which contains nested structs and has the TestTrait trait.
deletedEntities
=
deleteEntities
(
structContainerGuid
);
entityResult
=
deleteEntities
(
structContainerGuid
);
Assert
.
assertEquals
(
entityResult
.
getDeletedEntities
().
size
(),
1
);
Assert
.
assertTrue
(
entityResult
.
getDeletedEntities
().
contains
(
structContainerGuid
));
assertEntityDeleted
(
structContainerGuid
);
Assert
.
assertEquals
(
deletedEntities
.
size
(),
1
);
Assert
.
assertTrue
(
deletedEntities
.
contains
(
structContainerGuid
));
// Verify all TestStruct struct vertices were removed.
assertVerticesDeleted
(
getVertices
(
Constants
.
ENTITY_TYPE_PROPERTY_KEY
,
"TestStruct"
));
...
...
@@ -890,13 +940,14 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
return
list
;
}
private
Map
<
String
,
String
>
getEmployeeNameGuidMap
(
ITypedReferenceableInstance
hrDept
)
throws
AtlasException
{
private
Map
<
String
,
String
>
getEmployeeNameGuidMap
(
final
ITypedReferenceableInstance
hrDept
)
throws
AtlasException
{
Object
refValue
=
hrDept
.
get
(
"employees"
);
Assert
.
assertTrue
(
refValue
instanceof
List
);
List
<
Object
>
employees
=
(
List
<
Object
>)
refValue
;
Assert
.
assertEquals
(
employees
.
size
(),
4
);
Map
<
String
,
String
>
nameGuidMap
=
new
HashMap
<
String
,
String
>();
Map
<
String
,
String
>
nameGuidMap
=
new
HashMap
<
String
,
String
>()
{{
put
(
"hr"
,
hrDept
.
getId
().
_getId
());
}};
for
(
Object
listValue
:
employees
)
{
Assert
.
assertTrue
(
listValue
instanceof
ITypedReferenceableInstance
);
...
...
This diff is collapsed.
Click to expand it.
repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedRepositoryHardDeleteTest.java
View file @
705014eb
...
...
@@ -21,8 +21,10 @@ package org.apache.atlas.repository.graph;
import
com.tinkerpop.blueprints.Vertex
;
import
org.apache.atlas.AtlasClient
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.TestUtils
;
import
org.apache.atlas.repository.Constants
;
import
org.apache.atlas.typesystem.IReferenceableInstance
;
import
org.apache.atlas.typesystem.IStruct
;
import
org.apache.atlas.typesystem.ITypedReferenceableInstance
;
import
org.apache.atlas.typesystem.ITypedStruct
;
...
...
@@ -32,8 +34,11 @@ import org.apache.atlas.typesystem.types.TypeSystem;
import
org.testng.Assert
;
import
java.util.List
;
import
java.util.Map
;
import
static
org
.
apache
.
atlas
.
TestUtils
.
COLUMNS_ATTR_NAME
;
import
static
org
.
testng
.
Assert
.
assertEquals
;
import
static
org
.
testng
.
Assert
.
assertFalse
;
import
static
org
.
testng
.
Assert
.
assertNull
;
import
static
org
.
testng
.
Assert
.
fail
;
import
static
org
.
testng
.
AssertJUnit
.
assertNotNull
;
...
...
@@ -45,7 +50,24 @@ public class GraphBackedRepositoryHardDeleteTest extends GraphBackedMetadataRepo
}
@Override
protected
void
assertTestDeleteReference
(
ITypedReferenceableInstance
processInstance
)
throws
Exception
{
protected
void
assertTestDeleteEntityWithTraits
(
String
guid
)
{
//entity is deleted. So, no assertions
}
@Override
protected
void
assertTableForTestDeleteReference
(
String
tableId
)
{
//entity is deleted. So, no assertions
}
@Override
protected
void
assertColumnForTestDeleteReference
(
ITypedReferenceableInstance
tableInstance
)
throws
AtlasException
{
List
<
ITypedReferenceableInstance
>
columns
=
(
List
<
ITypedReferenceableInstance
>)
tableInstance
.
get
(
COLUMNS_ATTR_NAME
);
assertNull
(
columns
);
}
@Override
protected
void
assertProcessForTestDeleteReference
(
ITypedReferenceableInstance
processInstance
)
throws
Exception
{
//assert that outputs is empty
ITypedReferenceableInstance
newProcess
=
repositoryService
.
getEntityDefinition
(
processInstance
.
getId
().
_getId
());
...
...
@@ -63,6 +85,11 @@ public class GraphBackedRepositoryHardDeleteTest extends GraphBackedMetadataRepo
}
@Override
protected
void
assertDeletedColumn
(
ITypedReferenceableInstance
tableInstance
)
throws
AtlasException
{
assertEquals
(((
List
<
IReferenceableInstance
>)
tableInstance
.
get
(
COLUMNS_ATTR_NAME
)).
size
(),
2
);
}
@Override
protected
void
assertTestDeleteEntities
(
ITypedReferenceableInstance
tableInstance
)
{
int
vertexCount
=
getVertices
(
Constants
.
ENTITY_TYPE_PROPERTY_KEY
,
TestUtils
.
TABLE_TYPE
).
size
();
assertEquals
(
vertexCount
,
0
);
...
...
@@ -85,12 +112,42 @@ public class GraphBackedRepositoryHardDeleteTest extends GraphBackedMetadataRepo
}
@Override
protected
void
assertTestDisconnectBidirectionalReferences
(
String
janeGuid
)
throws
Exception
{
protected
void
assertJohnForTestDisconnectBidirectionalReferences
(
ITypedReferenceableInstance
john
,
String
janeGuid
)
throws
Exception
{
assertNull
(
john
.
get
(
"manager"
));
}
@Override
protected
void
assertMaxForTestDisconnectBidirectionalReferences
(
Map
<
String
,
String
>
nameGuidMap
)
throws
Exception
{
// Verify that the Department.employees reference to the deleted employee
// was disconnected.
ITypedReferenceableInstance
hrDept
=
repositoryService
.
getEntityDefinition
(
nameGuidMap
.
get
(
"hr"
));
List
<
ITypedReferenceableInstance
>
employees
=
(
List
<
ITypedReferenceableInstance
>)
hrDept
.
get
(
"employees"
);
Assert
.
assertEquals
(
employees
.
size
(),
3
);
String
maxGuid
=
nameGuidMap
.
get
(
"Max"
);
for
(
ITypedReferenceableInstance
employee
:
employees
)
{
Assert
.
assertNotEquals
(
employee
.
getId
().
_getId
(),
maxGuid
);
}
// Verify that the Manager.subordinates reference to the deleted employee
// Max was disconnected.
ITypedReferenceableInstance
jane
=
repositoryService
.
getEntityDefinition
(
janeGuid
);
ITypedReferenceableInstance
jane
=
repositoryService
.
getEntityDefinition
(
nameGuidMap
.
get
(
"Jane"
)
);
List
<
ITypedReferenceableInstance
>
subordinates
=
(
List
<
ITypedReferenceableInstance
>)
jane
.
get
(
"subordinates"
);
assertEquals
(
subordinates
.
size
(),
1
);
// Verify that max's Person.mentor unidirectional reference to john was disconnected.
ITypedReferenceableInstance
john
=
repositoryService
.
getEntityDefinition
(
nameGuidMap
.
get
(
"John"
));
assertNull
(
john
.
get
(
"mentor"
));
}
@Override
protected
void
assertTestDisconnectUnidirectionalArrayReferenceFromClassType
(
List
<
ITypedReferenceableInstance
>
columns
,
String
columnGuid
)
{
assertEquals
(
columns
.
size
(),
4
);
for
(
ITypedReferenceableInstance
column
:
columns
)
{
assertFalse
(
column
.
getId
().
_getId
().
equals
(
columnGuid
));
}
}
@Override
...
...
This diff is collapsed.
Click to expand it.
repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedRepositorySoftDeleteTest.java
View file @
705014eb
...
...
@@ -19,10 +19,11 @@
package
org
.
apache
.
atlas
.
repository
.
graph
;
import
com.tinkerpop.blueprints.Vertex
;
import
org.apache.atlas.AtlasClient
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.TestUtils
;
import
org.apache.atlas.repository.Constants
;
import
org.apache.atlas.typesystem.IReferenceableInstance
;
import
org.apache.atlas.typesystem.IStruct
;
import
org.apache.atlas.typesystem.ITypedReferenceableInstance
;
import
org.apache.atlas.typesystem.ITypedStruct
;
...
...
@@ -33,8 +34,12 @@ import org.testng.Assert;
import
java.util.List
;
import
java.util.Map
;
import
static
org
.
apache
.
atlas
.
TestUtils
.
COLUMNS_ATTR_NAME
;
import
static
org
.
apache
.
atlas
.
TestUtils
.
NAME
;
import
static
org
.
apache
.
atlas
.
TestUtils
.
PII
;
import
static
org
.
testng
.
Assert
.
assertEquals
;
import
static
org
.
testng
.
Assert
.
assertNotNull
;
import
static
org
.
testng
.
Assert
.
assertTrue
;
public
class
GraphBackedRepositorySoftDeleteTest
extends
GraphBackedMetadataRepositoryDeleteTestBase
{
@Override
...
...
@@ -43,7 +48,38 @@ public class GraphBackedRepositorySoftDeleteTest extends GraphBackedMetadataRepo
}
@Override
protected
void
assertTestDeleteReference
(
ITypedReferenceableInstance
expected
)
throws
Exception
{
protected
void
assertTestDeleteEntityWithTraits
(
String
guid
)
throws
Exception
{
ITypedReferenceableInstance
instance
=
repositoryService
.
getEntityDefinition
(
guid
);
assertTrue
(
instance
.
getTraits
().
contains
(
PII
));
}
@Override
protected
void
assertTableForTestDeleteReference
(
String
tableId
)
throws
Exception
{
ITypedReferenceableInstance
table
=
repositoryService
.
getEntityDefinition
(
tableId
);
assertNotNull
(
table
.
get
(
NAME
));
assertNotNull
(
table
.
get
(
"description"
));
assertNotNull
(
table
.
get
(
"type"
));
assertNotNull
(
table
.
get
(
"tableType"
));
assertNotNull
(
table
.
get
(
"created"
));
Id
dbId
=
(
Id
)
table
.
get
(
"database"
);
assertNotNull
(
dbId
);
ITypedReferenceableInstance
db
=
repositoryService
.
getEntityDefinition
(
dbId
.
getId
().
_getId
());
assertNotNull
(
db
);
assertEquals
(
db
.
getId
().
getState
(),
Id
.
EntityState
.
ACTIVE
);
}
@Override
protected
void
assertColumnForTestDeleteReference
(
ITypedReferenceableInstance
tableInstance
)
throws
AtlasException
{
List
<
ITypedReferenceableInstance
>
columns
=
(
List
<
ITypedReferenceableInstance
>)
tableInstance
.
get
(
COLUMNS_ATTR_NAME
);
assertEquals
(
columns
.
size
(),
1
);
assertEquals
(
columns
.
get
(
0
).
getId
().
getState
(),
Id
.
EntityState
.
DELETED
);
}
@Override
protected
void
assertProcessForTestDeleteReference
(
ITypedReferenceableInstance
expected
)
throws
Exception
{
ITypedReferenceableInstance
process
=
repositoryService
.
getEntityDefinition
(
expected
.
getId
().
_getId
());
List
<
ITypedReferenceableInstance
>
outputs
=
(
List
<
ITypedReferenceableInstance
>)
process
.
get
(
AtlasClient
.
PROCESS_ATTRIBUTE_OUTPUTS
);
...
...
@@ -59,6 +95,13 @@ public class GraphBackedRepositorySoftDeleteTest extends GraphBackedMetadataRepo
}
@Override
protected
void
assertDeletedColumn
(
ITypedReferenceableInstance
tableInstance
)
throws
AtlasException
{
List
<
IReferenceableInstance
>
columns
=
(
List
<
IReferenceableInstance
>)
tableInstance
.
get
(
COLUMNS_ATTR_NAME
);
assertEquals
(
columns
.
size
(),
3
);
assertEquals
(
columns
.
get
(
0
).
getId
().
getState
(),
Id
.
EntityState
.
DELETED
);
}
@Override
protected
void
assertTestDeleteEntities
(
ITypedReferenceableInstance
expected
)
throws
Exception
{
//Assert that the deleted table can be fully constructed back
ITypedReferenceableInstance
table
=
repositoryService
.
getEntityDefinition
(
expected
.
getId
().
_getId
());
...
...
@@ -67,6 +110,7 @@ public class GraphBackedRepositorySoftDeleteTest extends GraphBackedMetadataRepo
List
<
ITypedReferenceableInstance
>
expectedColumns
=
(
List
<
ITypedReferenceableInstance
>)
table
.
get
(
TestUtils
.
COLUMNS_ATTR_NAME
);
assertEquals
(
columns
.
size
(),
expectedColumns
.
size
());
assertNotNull
(
table
.
get
(
"database"
));
}
@Override
...
...
@@ -85,11 +129,57 @@ public class GraphBackedRepositorySoftDeleteTest extends GraphBackedMetadataRepo
}
@Override
protected
void
assertTestDisconnectBidirectionalReferences
(
String
janeGuid
)
throws
Exception
{
protected
void
assertJohnForTestDisconnectBidirectionalReferences
(
ITypedReferenceableInstance
john
,
String
janeGuid
)
throws
Exception
{
Id
mgr
=
(
Id
)
john
.
get
(
"manager"
);
assertNotNull
(
mgr
);
assertEquals
(
mgr
.
_getId
(),
janeGuid
);
assertEquals
(
mgr
.
getState
(),
Id
.
EntityState
.
DELETED
);
}
@Override
protected
void
assertMaxForTestDisconnectBidirectionalReferences
(
Map
<
String
,
String
>
nameGuidMap
)
throws
Exception
{
// Verify that the Department.employees reference to the deleted employee
// was disconnected.
ITypedReferenceableInstance
hrDept
=
repositoryService
.
getEntityDefinition
(
nameGuidMap
.
get
(
"hr"
));
List
<
ITypedReferenceableInstance
>
employees
=
(
List
<
ITypedReferenceableInstance
>)
hrDept
.
get
(
"employees"
);
Assert
.
assertEquals
(
employees
.
size
(),
4
);
String
maxGuid
=
nameGuidMap
.
get
(
"Max"
);
for
(
ITypedReferenceableInstance
employee
:
employees
)
{
if
(
employee
.
getId
().
_getId
().
equals
(
maxGuid
))
{
assertEquals
(
employee
.
getId
().
getState
(),
Id
.
EntityState
.
DELETED
);
}
}
// Verify that the Manager.subordinates still references deleted employee
ITypedReferenceableInstance
jane
=
repositoryService
.
getEntityDefinition
(
janeGuid
);
ITypedReferenceableInstance
jane
=
repositoryService
.
getEntityDefinition
(
nameGuidMap
.
get
(
"Jane"
)
);
List
<
ITypedReferenceableInstance
>
subordinates
=
(
List
<
ITypedReferenceableInstance
>)
jane
.
get
(
"subordinates"
);
assertEquals
(
subordinates
.
size
(),
2
);
for
(
ITypedReferenceableInstance
subordinate
:
subordinates
)
{
if
(
subordinate
.
getId
().
_getId
().
equals
(
maxGuid
))
{
assertEquals
(
subordinate
.
getId
().
getState
(),
Id
.
EntityState
.
DELETED
);
}
}
// Verify that max's Person.mentor unidirectional reference to john was disconnected.
ITypedReferenceableInstance
john
=
repositoryService
.
getEntityDefinition
(
nameGuidMap
.
get
(
"John"
));
Id
mentor
=
(
Id
)
john
.
get
(
"mentor"
);
assertEquals
(
mentor
.
_getId
(),
maxGuid
);
assertEquals
(
mentor
.
getState
(),
Id
.
EntityState
.
DELETED
);
}
@Override
protected
void
assertTestDisconnectUnidirectionalArrayReferenceFromClassType
(
List
<
ITypedReferenceableInstance
>
columns
,
String
columnGuid
)
{
Assert
.
assertEquals
(
columns
.
size
(),
5
);
for
(
ITypedReferenceableInstance
column
:
columns
)
{
if
(
column
.
getId
().
_getId
().
equals
(
columnGuid
))
{
assertEquals
(
column
.
getId
().
getState
(),
Id
.
EntityState
.
DELETED
);
}
else
{
assertEquals
(
column
.
getId
().
getState
(),
Id
.
EntityState
.
ACTIVE
);
}
}
}
@Override
...
...
@@ -122,7 +212,6 @@ public class GraphBackedRepositorySoftDeleteTest extends GraphBackedMetadataRepo
@Override
protected
void
assertTestDeleteTargetOfMultiplicityRequiredReference
()
throws
Exception
{
// No-op - it's ok that no exception was thrown if soft deletes are enabled.
}
}
This diff is collapsed.
Click to expand it.
repository/src/test/java/org/apache/atlas/service/DefaultMetadataServiceTest.java
View file @
705014eb
...
...
@@ -73,6 +73,7 @@ import java.util.Map;
import
static
org
.
apache
.
atlas
.
TestUtils
.
COLUMNS_ATTR_NAME
;
import
static
org
.
apache
.
atlas
.
TestUtils
.
COLUMN_TYPE
;
import
static
org
.
apache
.
atlas
.
TestUtils
.
PII
;
import
static
org
.
apache
.
atlas
.
TestUtils
.
TABLE_TYPE
;
import
static
org
.
apache
.
atlas
.
TestUtils
.
createColumnEntity
;
import
static
org
.
apache
.
atlas
.
TestUtils
.
createDBEntity
;
...
...
@@ -80,6 +81,7 @@ import static org.apache.atlas.TestUtils.createTableEntity;
import
static
org
.
testng
.
Assert
.
assertEquals
;
import
static
org
.
testng
.
Assert
.
assertNotNull
;
import
static
org
.
testng
.
Assert
.
assertNull
;
import
static
org
.
testng
.
Assert
.
assertTrue
;
import
static
org
.
testng
.
Assert
.
fail
;
@Guice
(
modules
=
RepositoryMetadataModule
.
class
)
...
...
@@ -154,23 +156,21 @@ public class DefaultMetadataServiceTest {
String
entityjson
=
InstanceSerialization
.
toJson
(
entity
,
true
);
JSONArray
entitiesJson
=
new
JSONArray
();
entitiesJson
.
put
(
entityjson
);
String
response
=
metadataService
.
createEntities
(
entitiesJson
.
toString
());
JSONArray
guids
=
new
JSONArray
(
response
);
if
(
guids
!=
null
&&
guids
.
length
()
>
0
)
{
return
guids
.
getString
(
guids
.
length
()
-
1
);
List
<
String
>
guids
=
metadataService
.
createEntities
(
entitiesJson
.
toString
());
if
(
guids
!=
null
&&
guids
.
size
()
>
0
)
{
return
guids
.
get
(
guids
.
size
()
-
1
);
}
return
null
;
}
private
String
updateInstance
(
Referenceable
entity
)
throws
Exception
{
private
AtlasClient
.
EntityResult
updateInstance
(
Referenceable
entity
)
throws
Exception
{
RequestContext
.
createContext
();
ParamChecker
.
notNull
(
entity
,
"Entity"
);
ParamChecker
.
notNull
(
entity
.
getId
(),
"Entity"
);
String
entityjson
=
InstanceSerialization
.
toJson
(
entity
,
true
);
JSONArray
entitiesJson
=
new
JSONArray
();
entitiesJson
.
put
(
entityjson
);
String
response
=
metadataService
.
updateEntities
(
entitiesJson
.
toString
());
return
new
JSONArray
(
response
).
getString
(
0
);
return
metadataService
.
updateEntities
(
entitiesJson
.
toString
());
}
@Test
(
expectedExceptions
=
TypeNotFoundException
.
class
)
...
...
@@ -201,6 +201,32 @@ public class DefaultMetadataServiceTest {
}
@Test
public
void
testAddDeleteTrait
()
throws
Exception
{
Referenceable
entity
=
createDBEntity
();
String
id
=
createInstance
(
entity
);
//add trait
Struct
tag
=
new
Struct
(
TestUtils
.
PII
);
metadataService
.
addTrait
(
id
,
InstanceSerialization
.
toJson
(
tag
,
true
));
List
<
String
>
traits
=
metadataService
.
getTraitNames
(
id
);
assertEquals
(
traits
.
size
(),
1
);
assertEquals
(
traits
.
get
(
0
),
PII
);
//delete trait
metadataService
.
deleteTrait
(
id
,
PII
);
traits
=
metadataService
.
getTraitNames
(
id
);
assertEquals
(
traits
.
size
(),
0
);
//add trait again
metadataService
.
addTrait
(
id
,
InstanceSerialization
.
toJson
(
tag
,
true
));
traits
=
metadataService
.
getTraitNames
(
id
);
assertEquals
(
traits
.
size
(),
1
);
assertEquals
(
traits
.
get
(
0
),
PII
);
}
@Test
public
void
testEntityAudit
()
throws
Exception
{
//create entity
Referenceable
entity
=
createDBEntity
();
...
...
@@ -221,7 +247,7 @@ public class DefaultMetadataServiceTest {
assertAuditEvents
(
id
,
EntityAuditEvent
.
EntityAuditAction
.
ENTITY_DELETE
);
}
private
List
<
String
>
deleteEntities
(
String
...
guids
)
throws
AtlasException
{
private
AtlasClient
.
EntityResult
deleteEntities
(
String
...
guids
)
throws
AtlasException
{
RequestContext
.
createContext
();
return
metadataService
.
deleteEntities
(
Arrays
.
asList
(
guids
));
}
...
...
@@ -350,7 +376,7 @@ public class DefaultMetadataServiceTest {
Assert
.
assertTrue
(
partsMap
.
get
(
"part2"
).
equalsContents
(((
Map
<
String
,
Struct
>)
tableDefinition
.
get
(
"partitionsMap"
)).
get
(
"part2"
)));
//Test map pointing to a class
final
Map
<
String
,
Struct
>
columnsMap
=
new
HashMap
<>();
final
Map
<
String
,
Referenceable
>
columnsMap
=
new
HashMap
<>();
Referenceable
col0Type
=
new
Referenceable
(
TestUtils
.
COLUMN_TYPE
,
new
HashMap
<
String
,
Object
>()
{{
put
(
NAME
,
"test1"
);
...
...
@@ -393,17 +419,33 @@ public class DefaultMetadataServiceTest {
verifyMapUpdates
(
TestUtils
.
TABLE_TYPE
,
NAME
,
(
String
)
table
.
get
(
NAME
),
null
,
TestUtils
.
COLUMNS_MAP
);
}
private
void
verifyMapUpdates
(
String
typeName
,
String
uniqAttrName
,
String
uniqAttrValue
,
Map
<
String
,
Struct
>
expectedMap
,
String
mapAttrName
)
throws
AtlasException
{
private
void
verifyMapUpdates
(
String
typeName
,
String
uniqAttrName
,
String
uniqAttrValue
,
Map
<
String
,
Referenceable
>
expectedMap
,
String
mapAttrName
)
throws
AtlasException
{
String
json
=
metadataService
.
getEntityDefinition
(
typeName
,
uniqAttrName
,
uniqAttrValue
);
Referenceable
tableDefinition
=
InstanceSerialization
.
fromJsonReferenceable
(
json
,
true
);
Map
<
String
,
Referenceable
>
actualMap
=
(
Map
<
String
,
Referenceable
>)
tableDefinition
.
get
(
mapAttrName
);
if
(
expectedMap
==
null
)
{
Assert
.
assertNull
(
tableDefinition
.
get
(
TestUtils
.
COLUMNS_MAP
));
if
(
expectedMap
==
null
&&
actualMap
!=
null
)
{
//all are marked as deleted in case of soft delete
for
(
String
key
:
actualMap
.
keySet
())
{
assertEquals
(
actualMap
.
get
(
key
).
getId
().
state
,
Id
.
EntityState
.
DELETED
);
}
}
else
if
(
expectedMap
==
null
)
{
//hard delete case
assertNull
(
actualMap
);
}
else
{
Assert
.
assertEquals
(((
Map
<
String
,
Referenceable
>)
tableDefinition
.
get
(
mapAttrName
)).
size
(),
expectedMap
.
size
());
assertTrue
(
actualMap
.
size
()
>=
expectedMap
.
size
());
for
(
String
key
:
expectedMap
.
keySet
())
{
Assert
.
assertTrue
(((
Map
<
String
,
Referenceable
>)
tableDefinition
.
get
(
mapAttrName
)).
get
(
key
).
equalsContents
(
expectedMap
.
get
(
key
)));
assertTrue
(
actualMap
.
get
(
key
).
equalsContents
(
expectedMap
.
get
(
key
)));
}
//rest of the keys are marked as deleted
List
<
String
>
extraKeys
=
new
ArrayList
<>(
actualMap
.
keySet
());
extraKeys
.
removeAll
(
expectedMap
.
keySet
());
for
(
String
key
:
extraKeys
)
{
assertEquals
(
actualMap
.
get
(
key
).
getId
().
getState
(),
Id
.
EntityState
.
DELETED
);
}
}
}
...
...
@@ -438,14 +480,13 @@ public class DefaultMetadataServiceTest {
Assert
.
assertEquals
(
actualColumns
,
updatedColNameList
);
}
private
void
updateEntityPartial
(
String
guid
,
Referenceable
entity
)
throws
AtlasException
{
private
AtlasClient
.
EntityResult
updateEntityPartial
(
String
guid
,
Referenceable
entity
)
throws
AtlasException
{
RequestContext
.
createContext
();
metadataService
.
updateEntityPartialByGuid
(
guid
,
entity
);
return
metadataService
.
updateEntityPartialByGuid
(
guid
,
entity
);
}
@Test
public
void
testUpdateEntityArrayOfClass
()
throws
Exception
{
//test array of class with id
final
List
<
Referenceable
>
columns
=
new
ArrayList
<>();
Map
<
String
,
Object
>
values
=
new
HashMap
<>();
...
...
@@ -456,63 +497,67 @@ public class DefaultMetadataServiceTest {
Referenceable
tableUpdated
=
new
Referenceable
(
TestUtils
.
TABLE_TYPE
,
new
HashMap
<
String
,
Object
>()
{{
put
(
COLUMNS_ATTR_NAME
,
columns
);
}});
updateEntityPartial
(
tableId
.
_getId
(),
tableUpdated
);
AtlasClient
.
EntityResult
entityResult
=
updateEntityPartial
(
tableId
.
_getId
(),
tableUpdated
);
assertEquals
(
entityResult
.
getCreatedEntities
().
size
(),
1
);
//col1 created
assertEquals
(
entityResult
.
getUpdateEntities
().
size
(),
1
);
//table updated
assertEquals
(
entityResult
.
getUpdateEntities
().
get
(
0
),
tableId
.
_getId
());
verifyArrayUpdates
(
TestUtils
.
TABLE_TYPE
,
NAME
,
(
String
)
table
.
get
(
NAME
),
columns
,
COLUMNS_ATTR_NAME
);
//Partial update. Add col
5
But also update col1
//Partial update. Add col
2
But also update col1
Map
<
String
,
Object
>
valuesCol5
=
new
HashMap
<>();
valuesCol5
.
put
(
NAME
,
"col
5
"
);
valuesCol5
.
put
(
NAME
,
"col
2
"
);
valuesCol5
.
put
(
"type"
,
"type"
);
Referenceable
col2
=
new
Referenceable
(
TestUtils
.
COLUMN_TYPE
,
valuesCol5
);
//update col1
col1
.
set
(
"type"
,
"type1"
);
//add col5
final
List
<
Referenceable
>
updateColumns
=
Arrays
.
asList
(
col1
,
col2
);
columns
.
add
(
col2
);
tableUpdated
=
new
Referenceable
(
TestUtils
.
TABLE_TYPE
,
new
HashMap
<
String
,
Object
>()
{{
put
(
COLUMNS_ATTR_NAME
,
updateC
olumns
);
put
(
COLUMNS_ATTR_NAME
,
c
olumns
);
}});
updateEntityPartial
(
tableId
.
_getId
(),
tableUpdated
);
entityResult
=
updateEntityPartial
(
tableId
.
_getId
(),
tableUpdated
);
assertEquals
(
entityResult
.
getCreatedEntities
().
size
(),
1
);
//col2 created
assertEquals
(
entityResult
.
getUpdateEntities
().
size
(),
2
);
//table, col1 updated
verifyArrayUpdates
(
TestUtils
.
TABLE_TYPE
,
NAME
,
(
String
)
table
.
get
(
NAME
),
updateC
olumns
,
COLUMNS_ATTR_NAME
);
verifyArrayUpdates
(
TestUtils
.
TABLE_TYPE
,
NAME
,
(
String
)
table
.
get
(
NAME
),
c
olumns
,
COLUMNS_ATTR_NAME
);
//Complete update. Add array elements - col3,4
//Complete update. Add array elements - col3,
col
4
Map
<
String
,
Object
>
values1
=
new
HashMap
<>();
values1
.
put
(
NAME
,
"col3"
);
values1
.
put
(
"type"
,
"type"
);
Referenceable
ref1
=
new
Referenceable
(
TestUtils
.
COLUMN_TYPE
,
values1
);
columns
.
add
(
ref1
);
Referenceable
col3
=
new
Referenceable
(
TestUtils
.
COLUMN_TYPE
,
values1
);
columns
.
add
(
col3
);
Map
<
String
,
Object
>
values2
=
new
HashMap
<>();
values2
.
put
(
NAME
,
"col4"
);
values2
.
put
(
"type"
,
"type"
);
Referenceable
ref2
=
new
Referenceable
(
TestUtils
.
COLUMN_TYPE
,
values2
);
columns
.
add
(
ref2
);
Referenceable
col4
=
new
Referenceable
(
TestUtils
.
COLUMN_TYPE
,
values2
);
columns
.
add
(
col4
);
table
.
set
(
COLUMNS_ATTR_NAME
,
columns
);
updateInstance
(
table
);
entityResult
=
updateInstance
(
table
);
assertEquals
(
entityResult
.
getCreatedEntities
().
size
(),
2
);
//col3, col4 created
verifyArrayUpdates
(
TestUtils
.
TABLE_TYPE
,
NAME
,
(
String
)
table
.
get
(
NAME
),
columns
,
COLUMNS_ATTR_NAME
);
//Swap elements
columns
.
clear
();
columns
.
add
(
ref2
);
columns
.
add
(
ref1
);
columns
.
add
(
col4
);
columns
.
add
(
col3
);
table
.
set
(
COLUMNS_ATTR_NAME
,
columns
);
updateInstance
(
table
);
entityResult
=
updateInstance
(
table
);
assertEquals
(
entityResult
.
getDeletedEntities
().
size
(),
2
);
//col1, col2 are deleted
verifyArrayUpdates
(
TestUtils
.
TABLE_TYPE
,
NAME
,
(
String
)
table
.
get
(
NAME
),
columns
,
COLUMNS_ATTR_NAME
);
//drop a single column
columns
.
clear
();
columns
.
add
(
ref1
);
columns
.
add
(
col3
);
table
.
set
(
COLUMNS_ATTR_NAME
,
columns
);
updateInstance
(
table
);
entityResult
=
updateInstance
(
table
);
assertEquals
(
entityResult
.
getDeletedEntities
().
size
(),
1
);
//col4 deleted
verifyArrayUpdates
(
TestUtils
.
TABLE_TYPE
,
NAME
,
(
String
)
table
.
get
(
NAME
),
columns
,
COLUMNS_ATTR_NAME
);
//Remove a class reference/Id and insert another reference
...
...
@@ -520,34 +565,46 @@ public class DefaultMetadataServiceTest {
values
.
clear
();
columns
.
clear
();
values
.
put
(
NAME
,
"col
2
"
);
values
.
put
(
NAME
,
"col
5
"
);
values
.
put
(
"type"
,
"type"
);
col1
=
new
Referenceable
(
TestUtils
.
COLUMN_TYPE
,
values
);
columns
.
add
(
col
1
);
Referenceable
col5
=
new
Referenceable
(
TestUtils
.
COLUMN_TYPE
,
values
);
columns
.
add
(
col
5
);
table
.
set
(
COLUMNS_ATTR_NAME
,
columns
);
updateInstance
(
table
);
entityResult
=
updateInstance
(
table
);
assertEquals
(
entityResult
.
getCreatedEntities
().
size
(),
1
);
//col5 created
assertEquals
(
entityResult
.
getDeletedEntities
().
size
(),
1
);
//col3 deleted
verifyArrayUpdates
(
TestUtils
.
TABLE_TYPE
,
NAME
,
(
String
)
table
.
get
(
NAME
),
columns
,
COLUMNS_ATTR_NAME
);
//Update array column to null
table
.
setNull
(
COLUMNS_ATTR_NAME
);
String
newtableId
=
updateInstance
(
table
);
Assert
.
assertEquals
(
newtableId
,
tableId
.
_getId
());
entityResult
=
updateInstance
(
table
);
assertEquals
(
entityResult
.
getDeletedEntities
().
size
(),
1
);
verifyArrayUpdates
(
TestUtils
.
TABLE_TYPE
,
NAME
,
(
String
)
table
.
get
(
NAME
),
null
,
COLUMNS_ATTR_NAME
);
}
private
void
verifyArrayUpdates
(
String
typeName
,
String
uniqAttrName
,
String
uniqAttrValue
,
List
<?
extends
Struct
>
expectedArray
,
String
arrAttrName
)
throws
AtlasException
{
String
json
=
metadataService
.
getEntityDefinition
(
typeName
,
uniqAttrName
,
uniqAttrValue
);
private
void
verifyArrayUpdates
(
String
typeName
,
String
uniqAttrName
,
String
uniqAttrValue
,
List
<
Referenceable
>
expectedArray
,
String
arrAttrName
)
throws
AtlasException
{
String
json
=
metadataService
.
getEntityDefinition
(
typeName
,
uniqAttrName
,
uniqAttrValue
);
Referenceable
entityDefinition
=
InstanceSerialization
.
fromJsonReferenceable
(
json
,
true
);
if
(
expectedArray
==
null
)
{
Assert
.
assertNull
(
entityDefinition
.
get
(
arrAttrName
));
List
<
Referenceable
>
actualArray
=
(
List
<
Referenceable
>)
entityDefinition
.
get
(
arrAttrName
);
if
(
expectedArray
==
null
&&
actualArray
!=
null
)
{
//all are marked as deleted in case of soft delete
for
(
int
index
=
0
;
index
<
actualArray
.
size
();
index
++)
{
assertEquals
(
actualArray
.
get
(
index
).
getId
().
state
,
Id
.
EntityState
.
DELETED
);
}
}
else
if
(
expectedArray
==
null
)
{
//hard delete case
assertNull
(
actualArray
);
}
else
{
Assert
.
assertEquals
(((
List
<
Referenceable
>)
entityDefinition
.
get
(
arrAttrName
)).
size
(),
expectedArray
.
size
());
for
(
int
index
=
0
;
index
<
expectedArray
.
size
();
index
++)
{
Assert
.
assertTrue
(((
List
<
Referenceable
>)
entityDefinition
.
get
(
arrAttrName
)).
get
(
index
).
equalsContents
(
expectedArray
.
get
(
index
)));
int
index
;
for
(
index
=
0
;
index
<
expectedArray
.
size
();
index
++)
{
Assert
.
assertTrue
(
actualArray
.
get
(
index
).
equalsContents
(
expectedArray
.
get
(
index
)));
}
//Rest of the entities in the list are marked as deleted
for
(;
index
<
actualArray
.
size
();
index
++)
{
assertEquals
(
actualArray
.
get
(
index
).
getId
().
state
,
Id
.
EntityState
.
DELETED
);
}
}
}
...
...
@@ -560,7 +617,7 @@ public class DefaultMetadataServiceTest {
serdeInstance
.
set
(
"description"
,
"testDesc"
);
table
.
set
(
"serde1"
,
serdeInstance
);
String
newtableId
=
updateInstance
(
table
);
String
newtableId
=
updateInstance
(
table
)
.
getUpdateEntities
().
get
(
0
)
;
Assert
.
assertEquals
(
newtableId
,
tableId
.
_getId
());
String
tableDefinitionJson
=
...
...
@@ -664,7 +721,7 @@ public class DefaultMetadataServiceTest {
List
<
Struct
>
partitions
=
new
ArrayList
<
Struct
>(){{
add
(
partition1
);
add
(
partition2
);
}};
table
.
set
(
"partitions"
,
partitions
);
String
newtableId
=
updateInstance
(
table
);
String
newtableId
=
updateInstance
(
table
)
.
getUpdateEntities
().
get
(
0
)
;
Assert
.
assertEquals
(
newtableId
,
tableId
.
_getId
());
String
tableDefinitionJson
=
...
...
@@ -673,15 +730,14 @@ public class DefaultMetadataServiceTest {
Assert
.
assertNotNull
(
tableDefinition
.
get
(
"partitions"
));
List
<
Struct
>
partitionsActual
=
(
List
<
Struct
>)
tableDefinition
.
get
(
"partitions"
);
Assert
.
assertEquals
(
partitionsActual
.
size
(),
2
);
Assert
.
assertTrue
(
partitions
.
get
(
0
).
equalsContents
(
partitionsActual
.
get
(
0
)));
assertPartitions
(
partitionsActual
,
partitions
);
//add a new element to array of struct
final
Struct
partition3
=
new
Struct
(
TestUtils
.
PARTITION_STRUCT_TYPE
);
partition3
.
set
(
NAME
,
"part3"
);
partitions
.
add
(
partition3
);
table
.
set
(
"partitions"
,
partitions
);
newtableId
=
updateInstance
(
table
);
newtableId
=
updateInstance
(
table
)
.
getUpdateEntities
().
get
(
0
)
;
Assert
.
assertEquals
(
newtableId
,
tableId
.
_getId
());
tableDefinitionJson
=
...
...
@@ -690,13 +746,12 @@ public class DefaultMetadataServiceTest {
Assert
.
assertNotNull
(
tableDefinition
.
get
(
"partitions"
));
partitionsActual
=
(
List
<
Struct
>)
tableDefinition
.
get
(
"partitions"
);
Assert
.
assertEquals
(
partitionsActual
.
size
(),
3
);
Assert
.
assertTrue
(
partitions
.
get
(
2
).
equalsContents
(
partitionsActual
.
get
(
2
)));
assertPartitions
(
partitionsActual
,
partitions
);
//remove one of the struct values
partitions
.
remove
(
1
);
table
.
set
(
"partitions"
,
partitions
);
newtableId
=
updateInstance
(
table
);
newtableId
=
updateInstance
(
table
)
.
getUpdateEntities
().
get
(
0
)
;
Assert
.
assertEquals
(
newtableId
,
tableId
.
_getId
());
tableDefinitionJson
=
...
...
@@ -705,13 +760,11 @@ public class DefaultMetadataServiceTest {
Assert
.
assertNotNull
(
tableDefinition
.
get
(
"partitions"
));
partitionsActual
=
(
List
<
Struct
>)
tableDefinition
.
get
(
"partitions"
);
Assert
.
assertEquals
(
partitionsActual
.
size
(),
2
);
Assert
.
assertTrue
(
partitions
.
get
(
0
).
equalsContents
(
partitionsActual
.
get
(
0
)));
Assert
.
assertTrue
(
partitions
.
get
(
1
).
equalsContents
(
partitionsActual
.
get
(
1
)));
assertPartitions
(
partitionsActual
,
partitions
);
//Update struct value within array of struct
partition
1
.
set
(
NAME
,
"part4"
);
newtableId
=
updateInstance
(
table
);
partition
s
.
get
(
0
)
.
set
(
NAME
,
"part4"
);
newtableId
=
updateInstance
(
table
)
.
getUpdateEntities
().
get
(
0
)
;
Assert
.
assertEquals
(
newtableId
,
tableId
.
_getId
());
tableDefinitionJson
=
...
...
@@ -720,15 +773,14 @@ public class DefaultMetadataServiceTest {
Assert
.
assertNotNull
(
tableDefinition
.
get
(
"partitions"
));
partitionsActual
=
(
List
<
Struct
>)
tableDefinition
.
get
(
"partitions"
);
Assert
.
assertEquals
(
partitionsActual
.
size
(),
2
);
Assert
.
assertTrue
(
partitions
.
get
(
0
).
equalsContents
(
partitionsActual
.
get
(
0
)));
assertPartitions
(
partitionsActual
,
partitions
);
//add a repeated element to array of struct
final
Struct
partition4
=
new
Struct
(
TestUtils
.
PARTITION_STRUCT_TYPE
);
partition4
.
set
(
NAME
,
"part4"
);
partitions
.
add
(
partition4
);
table
.
set
(
"partitions"
,
partitions
);
newtableId
=
updateInstance
(
table
);
newtableId
=
updateInstance
(
table
)
.
getUpdateEntities
().
get
(
0
)
;
Assert
.
assertEquals
(
newtableId
,
tableId
.
_getId
());
tableDefinitionJson
=
...
...
@@ -737,15 +789,12 @@ public class DefaultMetadataServiceTest {
Assert
.
assertNotNull
(
tableDefinition
.
get
(
"partitions"
));
partitionsActual
=
(
List
<
Struct
>)
tableDefinition
.
get
(
"partitions"
);
Assert
.
assertEquals
(
partitionsActual
.
size
(),
3
);
Assert
.
assertEquals
(
partitionsActual
.
get
(
2
).
get
(
NAME
),
"part4"
);
Assert
.
assertEquals
(
partitionsActual
.
get
(
0
).
get
(
NAME
),
"part4"
);
Assert
.
assertTrue
(
partitions
.
get
(
2
).
equalsContents
(
partitionsActual
.
get
(
2
)));
assertPartitions
(
partitionsActual
,
partitions
);
// Remove all elements. Should set array attribute to null
partitions
.
clear
();
newtableId
=
updateInstance
(
table
);
newtableId
=
updateInstance
(
table
)
.
getUpdateEntities
().
get
(
0
)
;
Assert
.
assertEquals
(
newtableId
,
tableId
.
_getId
());
tableDefinitionJson
=
...
...
@@ -755,6 +804,13 @@ public class DefaultMetadataServiceTest {
Assert
.
assertNull
(
tableDefinition
.
get
(
"partitions"
));
}
private
void
assertPartitions
(
List
<
Struct
>
partitionsActual
,
List
<
Struct
>
partitions
)
{
assertEquals
(
partitionsActual
.
size
(),
partitions
.
size
());
for
(
int
index
=
0
;
index
<
partitions
.
size
();
index
++)
{
assertTrue
(
partitionsActual
.
get
(
index
).
equalsContents
(
partitions
.
get
(
index
)));
}
}
@Test
(
expectedExceptions
=
ValueConversionException
.
class
)
public
void
testUpdateRequiredAttrToNull
()
throws
Exception
{
...
...
@@ -772,7 +828,6 @@ public class DefaultMetadataServiceTest {
@Test
public
void
testUpdateOptionalAttrToNull
()
throws
Exception
{
String
tableDefinitionJson
=
metadataService
.
getEntityDefinition
(
TestUtils
.
TABLE_TYPE
,
NAME
,
(
String
)
table
.
get
(
NAME
));
Referenceable
tableDefinition
=
InstanceSerialization
.
fromJsonReferenceable
(
tableDefinitionJson
,
true
);
...
...
@@ -782,7 +837,7 @@ public class DefaultMetadataServiceTest {
//Update optional attribute
table
.
setNull
(
"created"
);
String
newtableId
=
updateInstance
(
table
);
String
newtableId
=
updateInstance
(
table
)
.
getUpdateEntities
().
get
(
0
)
;
Assert
.
assertEquals
(
newtableId
,
tableId
.
_getId
());
tableDefinitionJson
=
...
...
@@ -853,35 +908,39 @@ public class DefaultMetadataServiceTest {
// Register an EntityChangeListener to verify the notification mechanism
// is working for deleteEntities().
DeleteEntitiesChangeListener
listener
=
new
Delete
EntitiesChangeListener
();
EntitiesChangeListener
listener
=
new
EntitiesChangeListener
();
metadataService
.
registerListener
(
listener
);
//Delete one column
String
columnId
=
table1Columns
.
get
(
0
).
getId
().
_getId
();
AtlasClient
.
EntityResult
entityResult
=
deleteEntities
(
columnId
);
//column is deleted and table is updated
assertEquals
(
entityResult
.
getDeletedEntities
().
get
(
0
),
columnId
);
assertEquals
(
entityResult
.
getUpdateEntities
().
get
(
0
),
table1Entity
.
getId
().
_getId
());
//verify listener was called for updates and deletes
assertEquals
(
entityResult
.
getDeletedEntities
(),
listener
.
getDeletedEntities
());
assertEquals
(
entityResult
.
getUpdateEntities
(),
listener
.
getUpdatedEntities
());
// Delete the table entities. The deletion should cascade
// to their composite columns.
List
<
String
>
deletedGuids
=
deleteEntities
(
table1Entity
.
getId
().
_getId
());
entityResult
=
deleteEntities
(
table1Entity
.
getId
().
_getId
());
// Verify that deleteEntities() response has guids for tables and their composite columns.
Assert
.
assertTrue
(
deletedGuids
.
contains
(
table1Entity
.
getId
().
_getId
()));
for
(
IReferenceableInstance
column
:
table1Columns
)
{
Assert
.
assertTrue
(
deletedGuids
.
contains
(
column
.
getId
().
_getId
()));
}
Assert
.
assertTrue
(
entityResult
.
getDeletedEntities
().
contains
(
table1Entity
.
getId
().
_getId
()));
Assert
.
assertTrue
(
entityResult
.
getDeletedEntities
().
contains
(
table1Columns
.
get
(
1
).
getId
().
_getId
()));
Assert
.
assertTrue
(
entityResult
.
getDeletedEntities
().
contains
(
table1Columns
.
get
(
2
).
getId
().
_getId
()));
// Verify that tables and their composite columns have been deleted from the repository.
assertEntityDeleted
(
TABLE_TYPE
,
NAME
,
table1Entity
.
get
(
NAME
));
assertEntityDeleted
(
COLUMN_TYPE
,
NAME
,
col1
.
get
(
NAME
));
assertEntityDeleted
(
COLUMN_TYPE
,
NAME
,
col2
.
get
(
NAME
));
assertEntityDeleted
(
COLUMN_TYPE
,
NAME
,
col3
.
get
(
NAME
));
// Verify that the listener was notified about the deleted entities.
Collection
<
ITypedReferenceableInstance
>
deletedEntitiesFromListener
=
listener
.
getDeletedEntities
();
List
<
String
>
deletedEntitiesFromListener
=
listener
.
getDeletedEntities
();
Assert
.
assertNotNull
(
deletedEntitiesFromListener
);
Assert
.
assertEquals
(
deletedEntitiesFromListener
.
size
(),
deletedGuids
.
size
());
List
<
String
>
deletedGuidsFromListener
=
new
ArrayList
<>(
deletedGuids
.
size
());
for
(
ITypedReferenceableInstance
deletedEntity
:
deletedEntitiesFromListener
)
{
deletedGuidsFromListener
.
add
(
deletedEntity
.
getId
().
_getId
());
}
Assert
.
assertEquals
(
deletedGuidsFromListener
.
size
(),
deletedGuids
.
size
());
Assert
.
assertTrue
(
deletedGuidsFromListener
.
containsAll
(
deletedGuids
));
Assert
.
assertEquals
(
deletedEntitiesFromListener
.
size
(),
entityResult
.
getDeletedEntities
().
size
());
Assert
.
assertTrue
(
deletedEntitiesFromListener
.
containsAll
(
entityResult
.
getDeletedEntities
()));
}
private
void
assertEntityDeleted
(
String
typeName
,
String
attributeName
,
Object
attributeValue
)
...
...
@@ -915,12 +974,13 @@ public class DefaultMetadataServiceTest {
// Register an EntityChangeListener to verify the notification mechanism
// is working for deleteEntityByUniqueAttribute().
DeleteEntitiesChangeListener
listener
=
new
Delete
EntitiesChangeListener
();
EntitiesChangeListener
listener
=
new
EntitiesChangeListener
();
metadataService
.
registerListener
(
listener
);
// Delete the table entities. The deletion should cascade
// to their composite columns.
List
<
String
>
deletedGuids
=
metadataService
.
deleteEntityByUniqueAttribute
(
TestUtils
.
TABLE_TYPE
,
NAME
,
(
String
)
table1Entity
.
get
(
NAME
));
List
<
String
>
deletedGuids
=
metadataService
.
deleteEntityByUniqueAttribute
(
TestUtils
.
TABLE_TYPE
,
NAME
,
(
String
)
table1Entity
.
get
(
NAME
)).
getDeletedEntities
();
// Verify that deleteEntities() response has guids for tables and their composite columns.
Assert
.
assertTrue
(
deletedGuids
.
contains
(
table1Entity
.
getId
().
_getId
()));
...
...
@@ -936,15 +996,10 @@ public class DefaultMetadataServiceTest {
assertEntityDeleted
(
COLUMN_TYPE
,
NAME
,
col3
.
get
(
NAME
));
// Verify that the listener was notified about the deleted entities.
Collection
<
ITypedReferenceableInstance
>
deletedEntitiesFromListener
=
listener
.
getDeletedEntities
();
List
<
String
>
deletedEntitiesFromListener
=
listener
.
getDeletedEntities
();
Assert
.
assertNotNull
(
deletedEntitiesFromListener
);
Assert
.
assertEquals
(
deletedEntitiesFromListener
.
size
(),
deletedGuids
.
size
());
List
<
String
>
deletedGuidsFromListener
=
new
ArrayList
<>(
deletedGuids
.
size
());
for
(
ITypedReferenceableInstance
deletedEntity
:
deletedEntitiesFromListener
)
{
deletedGuidsFromListener
.
add
(
deletedEntity
.
getId
().
_getId
());
}
Assert
.
assertEquals
(
deletedGuidsFromListener
.
size
(),
deletedGuids
.
size
());
Assert
.
assertTrue
(
deletedGuidsFromListener
.
containsAll
(
deletedGuids
));
Assert
.
assertTrue
(
deletedEntitiesFromListener
.
containsAll
(
deletedGuids
));
}
@Test
...
...
@@ -1024,10 +1079,10 @@ public class DefaultMetadataServiceTest {
}
}
private
static
class
Delete
EntitiesChangeListener
implements
EntityChangeListener
{
private
Collection
<
ITypedReferenceableInstance
>
deletedEntities_
;
private
static
class
EntitiesChangeListener
implements
EntityChangeListener
{
private
List
<
String
>
deletedEntities
=
new
ArrayList
<>();
private
List
<
String
>
updatedEntities
=
new
ArrayList
<>()
;
@Override
public
void
onEntitiesAdded
(
Collection
<
ITypedReferenceableInstance
>
entities
)
throws
AtlasException
{
...
...
@@ -1036,6 +1091,10 @@ public class DefaultMetadataServiceTest {
@Override
public
void
onEntitiesUpdated
(
Collection
<
ITypedReferenceableInstance
>
entities
)
throws
AtlasException
{
updatedEntities
.
clear
();
for
(
ITypedReferenceableInstance
entity
:
entities
)
{
updatedEntities
.
add
(
entity
.
getId
().
_getId
());
}
}
@Override
...
...
@@ -1051,11 +1110,18 @@ public class DefaultMetadataServiceTest {
@Override
public
void
onEntitiesDeleted
(
Collection
<
ITypedReferenceableInstance
>
entities
)
throws
AtlasException
{
deletedEntities_
=
entities
;
deletedEntities
.
clear
();
for
(
ITypedReferenceableInstance
entity
:
entities
)
{
deletedEntities
.
add
(
entity
.
getId
().
_getId
());
}
}
public
Collection
<
ITypedReferenceableInstance
>
getDeletedEntities
()
{
return
deletedEntities_
;
public
List
<
String
>
getDeletedEntities
()
{
return
deletedEntities
;
}
public
List
<
String
>
getUpdatedEntities
()
{
return
updatedEntities
;
}
}
}
This diff is collapsed.
Click to expand it.
server-api/src/main/java/org/apache/atlas/RequestContext.java
View file @
705014eb
...
...
@@ -49,7 +49,16 @@ public class RequestContext {
private
RequestContext
()
{
}
//To handle gets from background threads where createContext() is not called
//createContext called for every request in the filter
public
static
RequestContext
get
()
{
if
(
CURRENT_CONTEXT
.
get
()
==
null
)
{
synchronized
(
RequestContext
.
class
)
{
if
(
CURRENT_CONTEXT
.
get
()
==
null
)
{
createContext
();
}
}
}
return
CURRENT_CONTEXT
.
get
();
}
...
...
@@ -72,15 +81,19 @@ public class RequestContext {
this
.
user
=
user
;
}
public
void
record
CreatedEntities
(
Collection
<
String
>
createdEntityIds
)
{
public
void
record
EntityCreate
(
Collection
<
String
>
createdEntityIds
)
{
this
.
createdEntityIds
.
addAll
(
createdEntityIds
);
}
public
void
record
UpdatedEntities
(
Collection
<
String
>
updatedEntityIds
)
{
public
void
record
EntityUpdate
(
Collection
<
String
>
updatedEntityIds
)
{
this
.
updatedEntityIds
.
addAll
(
updatedEntityIds
);
}
public
void
recordDeletedEntity
(
String
entityId
,
String
typeName
)
throws
AtlasException
{
public
void
recordEntityUpdate
(
String
entityId
)
{
this
.
updatedEntityIds
.
add
(
entityId
);
}
public
void
recordEntityDelete
(
String
entityId
,
String
typeName
)
throws
AtlasException
{
ClassType
type
=
typeSystem
.
getDataType
(
ClassType
.
class
,
typeName
);
ITypedReferenceableInstance
entity
=
type
.
createInstance
(
new
Id
(
entityId
,
0
,
typeName
));
if
(
deletedEntityIds
.
add
(
entityId
))
{
...
...
This diff is collapsed.
Click to expand it.
server-api/src/main/java/org/apache/atlas/services/MetadataService.java
View file @
705014eb
...
...
@@ -18,6 +18,7 @@
package
org
.
apache
.
atlas
.
services
;
import
org.apache.atlas.AtlasClient
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.EntityAuditEvent
;
import
org.apache.atlas.listener.EntityChangeListener
;
...
...
@@ -80,7 +81,7 @@ public interface MetadataService {
* @param entityDefinition definition
* @return json array of guids of entities created
*/
String
createEntities
(
String
entityDefinition
)
throws
AtlasException
;
List
<
String
>
createEntities
(
String
entityDefinition
)
throws
AtlasException
;
/**
* Get a typed entity instance.
...
...
@@ -136,7 +137,7 @@ public interface MetadataService {
* @param value property value
* @return json array of guids of entities created/updated
*/
String
updateEntityAttributeByGuid
(
String
guid
,
String
attribute
,
String
value
)
throws
AtlasException
;
AtlasClient
.
EntityResult
updateEntityAttributeByGuid
(
String
guid
,
String
attribute
,
String
value
)
throws
AtlasException
;
/**
* Supports Partial updates of an entity. Users can update a subset of attributes for an entity identified by its guid
...
...
@@ -146,7 +147,7 @@ public interface MetadataService {
* @return json array of guids of entities created/updated
* @throws AtlasException
*/
String
updateEntityPartialByGuid
(
String
guid
,
Referenceable
entity
)
throws
AtlasException
;
AtlasClient
.
EntityResult
updateEntityPartialByGuid
(
String
guid
,
Referenceable
entity
)
throws
AtlasException
;
/**
* Batch API - Adds/Updates the given entity id(guid).
...
...
@@ -154,7 +155,7 @@ public interface MetadataService {
* @param entityJson entity json
* @return json array of guids of entities created/updated
*/
String
updateEntities
(
String
entityJson
)
throws
AtlasException
;
AtlasClient
.
EntityResult
updateEntities
(
String
entityJson
)
throws
AtlasException
;
// Trait management functions
...
...
@@ -168,8 +169,9 @@ public interface MetadataService {
* @return Guid of updated entity
* @throws AtlasException
*/
String
updateEntityByUniqueAttribute
(
String
typeName
,
String
uniqueAttributeName
,
String
attrValue
,
Referenceable
updatedEntity
)
throws
AtlasException
;
AtlasClient
.
EntityResult
updateEntityByUniqueAttribute
(
String
typeName
,
String
uniqueAttributeName
,
String
attrValue
,
Referenceable
updatedEntity
)
throws
AtlasException
;
/**
* Gets the list of trait names for a given entity represented by a guid.
...
...
@@ -207,10 +209,10 @@ public interface MetadataService {
* Delete the specified entities from the repository
*
* @param guids entity guids to be deleted
* @return List of guids for deleted entities
* @return List of guids for deleted entities
* @throws AtlasException
*/
List
<
String
>
deleteEntities
(
List
<
String
>
guids
)
throws
AtlasException
;
AtlasClient
.
EntityResult
deleteEntities
(
List
<
String
>
guids
)
throws
AtlasException
;
/**
* Register a listener for entity change.
...
...
@@ -235,7 +237,8 @@ public interface MetadataService {
* @return List of guids for deleted entities (including their composite references)
* @throws AtlasException
*/
List
<
String
>
deleteEntityByUniqueAttribute
(
String
typeName
,
String
uniqueAttributeName
,
String
attrValue
)
throws
AtlasException
;
AtlasClient
.
EntityResult
deleteEntityByUniqueAttribute
(
String
typeName
,
String
uniqueAttributeName
,
String
attrValue
)
throws
AtlasException
;
/**
* Returns entity audit events for entity id in the decreasing order of timestamp
...
...
This diff is collapsed.
Click to expand it.
typesystem/src/main/java/org/apache/atlas/typesystem/Referenceable.java
View file @
705014eb
...
...
@@ -100,7 +100,7 @@ public class Referenceable extends Struct implements IReferenceableInstance {
* @throws AtlasException if the referenceable can not be created
*/
public
Referenceable
(
IReferenceableInstance
instance
)
throws
AtlasException
{
this
(
instance
.
getId
()
.
_getId
()
,
instance
.
getTypeName
(),
instance
.
getValuesMap
(),
instance
.
getTraits
(),
this
(
instance
.
getId
(),
instance
.
getTypeName
(),
instance
.
getValuesMap
(),
instance
.
getTraits
(),
getTraits
(
instance
));
}
...
...
This diff is collapsed.
Click to expand it.
webapp/src/main/java/org/apache/atlas/LocalAtlasClient.java
View file @
705014eb
...
...
@@ -83,13 +83,13 @@ public class LocalAtlasClient extends AtlasClient {
}
};
JSONObject
response
=
entityOperation
.
run
();
List
<
String
>
results
=
extractResults
(
response
,
GUID
,
new
ExtractOperation
<
String
,
String
>()
);
EntityResult
results
=
extractEntityResult
(
response
);
LOG
.
debug
(
"Create entities returned results: {}"
,
results
);
return
results
;
return
results
.
getCreatedEntities
()
;
}
@Override
protected
List
<
String
>
updateEntities
(
final
JSONArray
entities
)
throws
AtlasServiceException
{
protected
EntityResult
updateEntities
(
final
JSONArray
entities
)
throws
AtlasServiceException
{
LOG
.
debug
(
"Updating entities: {}"
,
entities
);
EntityOperation
entityOperation
=
new
EntityOperation
(
API
.
UPDATE_ENTITY
)
{
@Override
...
...
@@ -98,7 +98,7 @@ public class LocalAtlasClient extends AtlasClient {
}
};
JSONObject
response
=
entityOperation
.
run
();
List
<
String
>
results
=
extractResults
(
response
,
GUID
,
new
ExtractOperation
<
String
,
String
>()
);
EntityResult
results
=
extractEntityResult
(
response
);
LOG
.
debug
(
"Update entities returned results: {}"
,
results
);
return
results
;
}
...
...
@@ -130,7 +130,7 @@ public class LocalAtlasClient extends AtlasClient {
}
@Override
public
String
updateEntity
(
final
String
entityType
,
final
String
uniqueAttributeName
,
public
EntityResult
updateEntity
(
final
String
entityType
,
final
String
uniqueAttributeName
,
final
String
uniqueAttributeValue
,
Referenceable
entity
)
throws
AtlasServiceException
{
final
String
entityJson
=
InstanceSerialization
.
toJson
(
entity
,
true
);
LOG
.
debug
(
"Updating entity type: {}, attributeName: {}, attributeValue: {}, entity: {}"
,
entityType
,
...
...
@@ -143,13 +143,13 @@ public class LocalAtlasClient extends AtlasClient {
}
};
JSONObject
response
=
entityOperation
.
run
();
String
result
=
getString
(
response
,
GUID
);
EntityResult
result
=
extractEntityResult
(
response
);
LOG
.
debug
(
"Update entity returned result: {}"
,
result
);
return
result
;
}
@Override
public
List
<
String
>
deleteEntity
(
final
String
entityType
,
final
String
uniqueAttributeName
,
public
EntityResult
deleteEntity
(
final
String
entityType
,
final
String
uniqueAttributeName
,
final
String
uniqueAttributeValue
)
throws
AtlasServiceException
{
LOG
.
debug
(
"Deleting entity type: {}, attributeName: {}, attributeValue: {}"
,
entityType
,
uniqueAttributeName
,
uniqueAttributeValue
);
...
...
@@ -160,7 +160,7 @@ public class LocalAtlasClient extends AtlasClient {
}
};
JSONObject
response
=
entityOperation
.
run
();
List
<
String
>
results
=
extractResults
(
response
,
GUID
,
new
ExtractOperation
<
String
,
String
>()
);
EntityResult
results
=
extractEntityResult
(
response
);
LOG
.
debug
(
"Delete entities returned results: {}"
,
results
);
return
results
;
}
...
...
@@ -191,18 +191,18 @@ public class LocalAtlasClient extends AtlasClient {
}
@Override
public
void
updateEntityAttribute
(
final
String
guid
,
final
String
attribute
,
String
value
)
throws
AtlasServiceException
{
public
EntityResult
updateEntityAttribute
(
final
String
guid
,
final
String
attribute
,
String
value
)
throws
AtlasServiceException
{
throw
new
IllegalStateException
(
"Not supported in LocalAtlasClient"
);
}
@Override
public
void
updateEntity
(
String
guid
,
Referenceable
entity
)
throws
AtlasServiceException
{
public
EntityResult
updateEntity
(
String
guid
,
Referenceable
entity
)
throws
AtlasServiceException
{
throw
new
IllegalStateException
(
"Not supported in LocalAtlasClient"
);
}
@Override
public
List
<
String
>
deleteEntities
(
final
String
...
guids
)
throws
AtlasServiceException
{
public
EntityResult
deleteEntities
(
final
String
...
guids
)
throws
AtlasServiceException
{
throw
new
IllegalStateException
(
"Not supported in LocalAtlasClient"
);
}
...
...
This diff is collapsed.
Click to expand it.
notification/src/main/java/org/apache/atlas/notification/entity
/NotificationEntityChangeListener.java
→
webapp/src/main/java/org/apache/atlas/notification
/NotificationEntityChangeListener.java
View file @
705014eb
...
...
@@ -15,22 +15,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
apache
.
atlas
.
notification
.
entity
;
package
org
.
apache
.
atlas
.
notification
;
import
com.google.common.annotations.VisibleForTesting
;
import
com.google.inject.Inject
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.listener.EntityChangeListener
;
import
org.apache.atlas.notification.NotificationInterface
;
import
org.apache.atlas.notification.entity.EntityNotification
;
import
org.apache.atlas.notification.entity.EntityNotificationImpl
;
import
org.apache.atlas.typesystem.IReferenceableInstance
;
import
org.apache.atlas.typesystem.IStruct
;
import
org.apache.atlas.typesystem.ITypedReferenceableInstance
;
import
org.apache.atlas.typesystem.Referenceable
;
import
org.apache.atlas.typesystem.Struct
;
import
org.apache.atlas.typesystem.types.FieldMapping
;
import
org.apache.atlas.typesystem.types.TraitType
;
import
org.apache.atlas.typesystem.types.TypeSystem
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
/**
* Listen to the repository for entity changes and produce entity change notifications.
...
...
@@ -87,6 +95,53 @@ public class NotificationEntityChangeListener implements EntityChangeListener {
// ----- helper methods -------------------------------------------------
// ----- helper methods ----------------------------------------------------
@VisibleForTesting
public
static
List
<
IStruct
>
getAllTraits
(
IReferenceableInstance
entityDefinition
,
TypeSystem
typeSystem
)
throws
AtlasException
{
List
<
IStruct
>
traitInfo
=
new
LinkedList
<>();
for
(
String
traitName
:
entityDefinition
.
getTraits
())
{
IStruct
trait
=
entityDefinition
.
getTrait
(
traitName
);
String
typeName
=
trait
.
getTypeName
();
Map
<
String
,
Object
>
valuesMap
=
trait
.
getValuesMap
();
traitInfo
.
add
(
new
Struct
(
typeName
,
valuesMap
));
traitInfo
.
addAll
(
getSuperTraits
(
typeName
,
valuesMap
,
typeSystem
));
}
return
traitInfo
;
}
private
static
List
<
IStruct
>
getSuperTraits
(
String
typeName
,
Map
<
String
,
Object
>
values
,
TypeSystem
typeSystem
)
throws
AtlasException
{
List
<
IStruct
>
superTypes
=
new
LinkedList
<>();
TraitType
traitDef
=
typeSystem
.
getDataType
(
TraitType
.
class
,
typeName
);
Set
<
String
>
superTypeNames
=
traitDef
.
getAllSuperTypeNames
();
for
(
String
superTypeName
:
superTypeNames
)
{
TraitType
superTraitDef
=
typeSystem
.
getDataType
(
TraitType
.
class
,
superTypeName
);
Map
<
String
,
Object
>
superTypeValues
=
new
HashMap
<>();
FieldMapping
fieldMapping
=
superTraitDef
.
fieldMapping
();
if
(
fieldMapping
!=
null
)
{
Set
<
String
>
superTypeAttributeNames
=
fieldMapping
.
fields
.
keySet
();
for
(
String
superTypeAttributeName
:
superTypeAttributeNames
)
{
if
(
values
.
containsKey
(
superTypeAttributeName
))
{
superTypeValues
.
put
(
superTypeAttributeName
,
values
.
get
(
superTypeAttributeName
));
}
}
}
IStruct
superTrait
=
new
Struct
(
superTypeName
,
superTypeValues
);
superTypes
.
add
(
superTrait
);
superTypes
.
addAll
(
getSuperTraits
(
superTypeName
,
values
,
typeSystem
));
}
return
superTypes
;
}
// send notification of entity change
private
void
notifyOfEntityEvent
(
Collection
<
ITypedReferenceableInstance
>
entityDefinitions
,
EntityNotification
.
OperationType
operationType
)
throws
AtlasException
{
...
...
@@ -96,7 +151,7 @@ public class NotificationEntityChangeListener implements EntityChangeListener {
Referenceable
entity
=
new
Referenceable
(
entityDefinition
);
EntityNotificationImpl
notification
=
new
EntityNotificationImpl
(
entity
,
operationType
,
typeSystem
);
new
EntityNotificationImpl
(
entity
,
operationType
,
getAllTraits
(
entity
,
typeSystem
)
);
messages
.
add
(
notification
);
}
...
...
This diff is collapsed.
Click to expand it.
webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java
View file @
705014eb
...
...
@@ -19,7 +19,6 @@
package
org
.
apache
.
atlas
.
web
.
resources
;
import
com.google.common.base.Preconditions
;
import
org.apache.atlas.AtlasClient
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.EntityAuditEvent
;
...
...
@@ -59,9 +58,7 @@ import javax.ws.rs.core.MediaType;
import
javax.ws.rs.core.Response
;
import
javax.ws.rs.core.UriBuilder
;
import
javax.ws.rs.core.UriInfo
;
import
java.net.URI
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.List
;
...
...
@@ -119,19 +116,11 @@ public class EntityResource {
LOG
.
debug
(
"submitting entities {} "
,
AtlasClient
.
toString
(
new
JSONArray
(
entities
)));
final
String
guids
=
metadataService
.
createEntities
(
entities
);
final
List
<
String
>
guids
=
metadataService
.
createEntities
(
entities
);
JSONObject
response
=
getResponse
(
new
AtlasClient
.
EntityResult
(
guids
,
null
,
null
));
UriBuilder
ub
=
uriInfo
.
getAbsolutePathBuilder
();
URI
locationURI
=
ub
.
path
(
guids
).
build
();
JSONObject
response
=
new
JSONObject
();
response
.
put
(
AtlasClient
.
REQUEST_ID
,
Servlets
.
getRequestId
());
JSONArray
guidArray
=
new
JSONArray
(
guids
);
response
.
put
(
AtlasClient
.
GUID
,
guidArray
);
if
(
guidArray
.
length
()
>
0
)
{
response
.
put
(
AtlasClient
.
DEFINITION
,
new
JSONObject
(
metadataService
.
getEntityDefinition
(
new
JSONArray
(
guids
).
getString
(
0
))));
}
URI
locationURI
=
guids
.
isEmpty
()
?
null
:
ub
.
path
(
guids
.
get
(
0
)).
build
();
return
Response
.
created
(
locationURI
).
entity
(
response
).
build
();
...
...
@@ -150,6 +139,18 @@ public class EntityResource {
}
}
private
JSONObject
getResponse
(
AtlasClient
.
EntityResult
entityResult
)
throws
AtlasException
,
JSONException
{
JSONObject
response
=
new
JSONObject
();
response
.
put
(
AtlasClient
.
REQUEST_ID
,
Servlets
.
getRequestId
());
response
.
put
(
AtlasClient
.
ENTITIES
,
new
JSONObject
(
entityResult
.
toString
()).
get
(
AtlasClient
.
ENTITIES
));
String
sampleEntityId
=
getSample
(
entityResult
);
if
(
sampleEntityId
!=
null
)
{
String
entityDefinition
=
metadataService
.
getEntityDefinition
(
sampleEntityId
);
response
.
put
(
AtlasClient
.
DEFINITION
,
new
JSONObject
(
entityDefinition
));
}
return
response
;
}
/**
* Complete update of a set of entities - the values not specified will be replaced with null/removed
* Adds/Updates given entities identified by its GUID or unique attribute
...
...
@@ -163,14 +164,8 @@ public class EntityResource {
final
String
entities
=
Servlets
.
getRequestPayload
(
request
);
LOG
.
debug
(
"updating entities {} "
,
AtlasClient
.
toString
(
new
JSONArray
(
entities
)));
final
String
guids
=
metadataService
.
updateEntities
(
entities
);
JSONObject
response
=
new
JSONObject
();
response
.
put
(
AtlasClient
.
REQUEST_ID
,
Servlets
.
getRequestId
());
JSONArray
guidsArray
=
new
JSONArray
(
guids
);
response
.
put
(
AtlasClient
.
GUID
,
guidsArray
);
String
entityDefinition
=
metadataService
.
getEntityDefinition
(
guidsArray
.
getString
(
0
));
response
.
put
(
AtlasClient
.
DEFINITION
,
new
JSONObject
(
entityDefinition
));
AtlasClient
.
EntityResult
entityResult
=
metadataService
.
updateEntities
(
entities
);
JSONObject
response
=
getResponse
(
entityResult
);
return
Response
.
ok
(
response
).
build
();
}
catch
(
EntityExistsException
e
)
{
LOG
.
error
(
"Unique constraint violation"
,
e
);
...
...
@@ -187,6 +182,25 @@ public class EntityResource {
}
}
private
String
getSample
(
AtlasClient
.
EntityResult
entityResult
)
{
String
sample
=
getSample
(
entityResult
.
getCreatedEntities
());
if
(
sample
==
null
)
{
sample
=
getSample
(
entityResult
.
getUpdateEntities
());
}
if
(
sample
==
null
)
{
sample
=
getSample
(
entityResult
.
getDeletedEntities
());
}
return
sample
;
}
private
String
getSample
(
List
<
String
>
list
)
{
if
(
list
!=
null
&&
list
.
size
()
>
0
)
{
return
list
.
get
(
0
);
}
return
null
;
}
/**
* Adds/Updates given entity identified by its unique attribute( entityType, attributeName and value)
* Updates support only partial update of an entity - Adds/updates any new values specified
...
...
@@ -214,11 +228,10 @@ public class EntityResource {
Referenceable
updatedEntity
=
InstanceSerialization
.
fromJsonReferenceable
(
entities
,
true
);
final
String
guid
=
metadataService
.
updateEntityByUniqueAttribute
(
entityType
,
attribute
,
value
,
updatedEntity
);
AtlasClient
.
EntityResult
entityResult
=
metadataService
.
updateEntityByUniqueAttribute
(
entityType
,
attribute
,
value
,
updatedEntity
);
JSONObject
response
=
new
JSONObject
();
response
.
put
(
AtlasClient
.
REQUEST_ID
,
Thread
.
currentThread
().
getName
());
response
.
put
(
AtlasClient
.
GUID
,
guid
);
JSONObject
response
=
getResponse
(
entityResult
);
return
Response
.
ok
(
response
).
build
();
}
catch
(
ValueConversionException
ve
)
{
LOG
.
error
(
"Unable to persist entity instance due to a desrialization error "
,
ve
);
...
...
@@ -268,10 +281,8 @@ public class EntityResource {
Referenceable
updatedEntity
=
InstanceSerialization
.
fromJsonReferenceable
(
entityJson
,
true
);
metadataService
.
updateEntityPartialByGuid
(
guid
,
updatedEntity
);
JSONObject
response
=
new
JSONObject
();
response
.
put
(
AtlasClient
.
REQUEST_ID
,
Thread
.
currentThread
().
getName
());
AtlasClient
.
EntityResult
entityResult
=
metadataService
.
updateEntityPartialByGuid
(
guid
,
updatedEntity
);
JSONObject
response
=
getResponse
(
entityResult
);
return
Response
.
ok
(
response
).
build
();
}
catch
(
EntityNotFoundException
e
)
{
LOG
.
error
(
"An entity with GUID={} does not exist"
,
guid
,
e
);
...
...
@@ -301,12 +312,8 @@ public class EntityResource {
String
value
=
Servlets
.
getRequestPayload
(
request
);
Preconditions
.
checkNotNull
(
value
,
"Entity value cannot be null"
);
metadataService
.
updateEntityAttributeByGuid
(
guid
,
property
,
value
);
JSONObject
response
=
new
JSONObject
();
response
.
put
(
AtlasClient
.
REQUEST_ID
,
Thread
.
currentThread
().
getName
());
response
.
put
(
AtlasClient
.
GUID
,
guid
);
AtlasClient
.
EntityResult
entityResult
=
metadataService
.
updateEntityAttributeByGuid
(
guid
,
property
,
value
);
JSONObject
response
=
getResponse
(
entityResult
);
return
Response
.
ok
(
response
).
build
();
}
catch
(
EntityNotFoundException
e
)
{
LOG
.
error
(
"An entity with GUID={} does not exist"
,
guid
,
e
);
...
...
@@ -340,19 +347,13 @@ public class EntityResource {
@QueryParam
(
"value"
)
String
value
)
{
try
{
List
<
String
>
deletedGuids
=
new
ArrayList
<>()
;
AtlasClient
.
EntityResult
entityResult
;
if
(
guids
!=
null
&&
!
guids
.
isEmpty
())
{
deletedGuids
=
metadataService
.
deleteEntities
(
guids
);
entityResult
=
metadataService
.
deleteEntities
(
guids
);
}
else
{
deletedGuids
=
metadataService
.
deleteEntityByUniqueAttribute
(
entityType
,
attribute
,
value
);
}
JSONObject
response
=
new
JSONObject
();
response
.
put
(
AtlasClient
.
REQUEST_ID
,
Servlets
.
getRequestId
());
JSONArray
guidArray
=
new
JSONArray
(
deletedGuids
.
size
());
for
(
String
guid
:
deletedGuids
)
{
guidArray
.
put
(
guid
);
entityResult
=
metadataService
.
deleteEntityByUniqueAttribute
(
entityType
,
attribute
,
value
);
}
response
.
put
(
AtlasClient
.
GUID
,
guidArray
);
JSONObject
response
=
getResponse
(
entityResult
);
return
Response
.
ok
(
response
).
build
();
}
catch
(
EntityNotFoundException
e
)
{
if
(
guids
!=
null
||
!
guids
.
isEmpty
())
{
...
...
@@ -386,7 +387,6 @@ public class EntityResource {
JSONObject
response
=
new
JSONObject
();
response
.
put
(
AtlasClient
.
REQUEST_ID
,
Servlets
.
getRequestId
());
response
.
put
(
AtlasClient
.
GUID
,
guid
);
Response
.
Status
status
=
Response
.
Status
.
NOT_FOUND
;
if
(
entityDefinition
!=
null
)
{
...
...
@@ -518,7 +518,6 @@ public class EntityResource {
JSONObject
response
=
new
JSONObject
();
response
.
put
(
AtlasClient
.
REQUEST_ID
,
Servlets
.
getRequestId
());
response
.
put
(
AtlasClient
.
GUID
,
guid
);
response
.
put
(
AtlasClient
.
RESULTS
,
new
JSONArray
(
traitNames
));
response
.
put
(
AtlasClient
.
COUNT
,
traitNames
.
size
());
...
...
@@ -555,7 +554,6 @@ public class EntityResource {
JSONObject
response
=
new
JSONObject
();
response
.
put
(
AtlasClient
.
REQUEST_ID
,
Servlets
.
getRequestId
());
response
.
put
(
AtlasClient
.
GUID
,
guid
);
return
Response
.
created
(
locationURI
).
entity
(
response
).
build
();
}
catch
(
EntityNotFoundException
|
TypeNotFoundException
e
)
{
...
...
@@ -588,7 +586,6 @@ public class EntityResource {
JSONObject
response
=
new
JSONObject
();
response
.
put
(
AtlasClient
.
REQUEST_ID
,
Servlets
.
getRequestId
());
response
.
put
(
AtlasClient
.
GUID
,
guid
);
response
.
put
(
TRAIT_NAME
,
traitName
);
return
Response
.
ok
(
response
).
build
();
...
...
This diff is collapsed.
Click to expand it.
webapp/src/main/java/org/apache/atlas/web/service/ServiceModule.java
View file @
705014eb
...
...
@@ -23,7 +23,7 @@ import com.google.inject.multibindings.Multibinder;
import
org.apache.atlas.kafka.KafkaNotification
;
import
org.apache.atlas.listener.EntityChangeListener
;
import
org.apache.atlas.notification.NotificationHookConsumer
;
import
org.apache.atlas.notification.
entity.
NotificationEntityChangeListener
;
import
org.apache.atlas.notification.NotificationEntityChangeListener
;
import
org.apache.atlas.service.Service
;
public
class
ServiceModule
extends
AbstractModule
{
...
...
This diff is collapsed.
Click to expand it.
webapp/src/test/java/org/apache/atlas/LocalAtlasClientTest.java
View file @
705014eb
...
...
@@ -23,7 +23,6 @@ import org.apache.atlas.typesystem.Referenceable;
import
org.apache.atlas.web.resources.EntityResource
;
import
org.apache.atlas.web.service.ServiceState
;
import
org.apache.commons.lang.RandomStringUtils
;
import
org.codehaus.jettison.json.JSONArray
;
import
org.codehaus.jettison.json.JSONObject
;
import
org.mockito.Mock
;
import
org.mockito.MockitoAnnotations
;
...
...
@@ -36,6 +35,7 @@ import javax.ws.rs.core.Response;
import
java.util.Arrays
;
import
java.util.List
;
import
static
org
.
apache
.
atlas
.
AtlasClient
.
ENTITIES
;
import
static
org
.
mockito
.
Matchers
.
any
;
import
static
org
.
mockito
.
Matchers
.
anyListOf
;
import
static
org
.
mockito
.
Matchers
.
anyString
;
...
...
@@ -64,7 +64,8 @@ public class LocalAtlasClientTest {
when
(
entityResource
.
submit
(
any
(
HttpServletRequest
.
class
))).
thenReturn
(
response
);
final
String
guid
=
random
();
when
(
response
.
getEntity
()).
thenReturn
(
new
JSONObject
()
{{
put
(
AtlasClient
.
GUID
,
new
JSONArray
(
Arrays
.
asList
(
guid
)));
put
(
ENTITIES
,
new
JSONObject
(
new
AtlasClient
.
EntityResult
(
Arrays
.
asList
(
guid
),
null
,
null
).
toString
()).
get
(
ENTITIES
));
}});
LocalAtlasClient
atlasClient
=
new
LocalAtlasClient
(
serviceState
,
entityResource
);
...
...
@@ -119,12 +120,14 @@ public class LocalAtlasClientTest {
when
(
entityResource
.
updateByUniqueAttribute
(
anyString
(),
anyString
(),
anyString
(),
any
(
HttpServletRequest
.
class
))).
thenReturn
(
response
);
when
(
response
.
getEntity
()).
thenReturn
(
new
JSONObject
()
{{
put
(
AtlasClient
.
GUID
,
guid
);
put
(
ENTITIES
,
new
JSONObject
(
new
AtlasClient
.
EntityResult
(
null
,
Arrays
.
asList
(
guid
),
null
).
toString
()).
get
(
ENTITIES
));
}});
LocalAtlasClient
atlasClient
=
new
LocalAtlasClient
(
serviceState
,
entityResource
);
String
actualId
=
atlasClient
.
updateEntity
(
random
(),
random
(),
random
(),
new
Referenceable
(
random
()));
assertEquals
(
actualId
,
guid
);
AtlasClient
.
EntityResult
entityResult
=
atlasClient
.
updateEntity
(
random
(),
random
(),
random
(),
new
Referenceable
(
random
()));
assertEquals
(
entityResult
.
getUpdateEntities
(),
Arrays
.
asList
(
guid
));
}
@Test
...
...
@@ -132,14 +135,14 @@ public class LocalAtlasClientTest {
final
String
guid
=
random
();
Response
response
=
mock
(
Response
.
class
);
when
(
response
.
getEntity
()).
thenReturn
(
new
JSONObject
()
{{
put
(
AtlasClient
.
GUID
,
new
JSONArray
(
Arrays
.
asList
(
guid
)));
put
(
ENTITIES
,
new
JSONObject
(
new
AtlasClient
.
EntityResult
(
null
,
null
,
Arrays
.
asList
(
guid
)).
toString
()).
get
(
ENTITIES
));
}});
when
(
entityResource
.
deleteEntities
(
anyListOf
(
String
.
class
),
anyString
(),
anyString
(),
anyString
())).
thenReturn
(
response
);
LocalAtlasClient
atlasClient
=
new
LocalAtlasClient
(
serviceState
,
entityResource
);
List
<
String
>
results
=
atlasClient
.
deleteEntity
(
random
(),
random
(),
random
());
assertEquals
(
results
.
size
(),
1
);
assertEquals
(
results
.
get
(
0
),
guid
);
AtlasClient
.
EntityResult
entityResult
=
atlasClient
.
deleteEntity
(
random
(),
random
(),
random
());
assertEquals
(
entityResult
.
getDeletedEntities
(),
Arrays
.
asList
(
guid
));
}
private
String
random
()
{
...
...
This diff is collapsed.
Click to expand it.
webapp/src/test/java/org/apache/atlas/notification/EntityNotificationIT.java
View file @
705014eb
...
...
@@ -22,7 +22,6 @@ import com.google.common.collect.ImmutableSet;
import
com.google.inject.Inject
;
import
com.sun.jersey.api.client.ClientResponse
;
import
com.sun.jersey.api.client.WebResource
;
import
org.apache.atlas.notification.entity.EntityNotification
;
import
org.apache.atlas.typesystem.IReferenceableInstance
;
import
org.apache.atlas.typesystem.IStruct
;
...
...
@@ -43,7 +42,6 @@ import org.testng.annotations.Test;
import
javax.ws.rs.HttpMethod
;
import
javax.ws.rs.core.Response
;
import
java.util.Collections
;
import
java.util.LinkedList
;
import
java.util.List
;
...
...
This diff is collapsed.
Click to expand it.
webapp/src/test/java/org/apache/atlas/notification/NotificationEntityChangeListenerTest.java
0 → 100644
View file @
705014eb
/**
* 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
.
notification
;
import
org.apache.atlas.typesystem.IStruct
;
import
org.apache.atlas.typesystem.Referenceable
;
import
org.apache.atlas.typesystem.Struct
;
import
org.apache.atlas.typesystem.types.TraitType
;
import
org.apache.atlas.typesystem.types.TypeSystem
;
import
org.testng.annotations.Test
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
static
org
.
testng
.
Assert
.
assertEquals
;
import
static
org
.
testng
.
Assert
.
assertTrue
;
public
class
NotificationEntityChangeListenerTest
{
@Test
public
void
testGetAllTraitsSuperTraits
()
throws
Exception
{
TypeSystem
typeSystem
=
mock
(
TypeSystem
.
class
);
String
traitName
=
"MyTrait"
;
IStruct
myTrait
=
new
Struct
(
traitName
);
String
superTraitName
=
"MySuperTrait"
;
TraitType
traitDef
=
mock
(
TraitType
.
class
);
Set
<
String
>
superTypeNames
=
Collections
.
singleton
(
superTraitName
);
TraitType
superTraitDef
=
mock
(
TraitType
.
class
);
Set
<
String
>
superSuperTypeNames
=
Collections
.
emptySet
();
Referenceable
entity
=
getEntity
(
"id"
,
myTrait
);
when
(
typeSystem
.
getDataType
(
TraitType
.
class
,
traitName
)).
thenReturn
(
traitDef
);
when
(
typeSystem
.
getDataType
(
TraitType
.
class
,
superTraitName
)).
thenReturn
(
superTraitDef
);
when
(
traitDef
.
getAllSuperTypeNames
()).
thenReturn
(
superTypeNames
);
when
(
superTraitDef
.
getAllSuperTypeNames
()).
thenReturn
(
superSuperTypeNames
);
List
<
IStruct
>
allTraits
=
NotificationEntityChangeListener
.
getAllTraits
(
entity
,
typeSystem
);
assertEquals
(
2
,
allTraits
.
size
());
for
(
IStruct
trait
:
allTraits
)
{
String
typeName
=
trait
.
getTypeName
();
assertTrue
(
typeName
.
equals
(
traitName
)
||
typeName
.
equals
(
superTraitName
));
}
}
private
Referenceable
getEntity
(
String
id
,
IStruct
...
traits
)
{
String
typeName
=
"typeName"
;
Map
<
String
,
Object
>
values
=
new
HashMap
<>();
List
<
String
>
traitNames
=
new
LinkedList
<>();
Map
<
String
,
IStruct
>
traitMap
=
new
HashMap
<>();
for
(
IStruct
trait
:
traits
)
{
String
traitName
=
trait
.
getTypeName
();
traitNames
.
add
(
traitName
);
traitMap
.
put
(
traitName
,
trait
);
}
return
new
Referenceable
(
id
,
typeName
,
values
,
traitNames
,
traitMap
);
}
}
This diff is collapsed.
Click to expand it.
webapp/src/test/java/org/apache/atlas/web/resources/EntityJerseyResourceIT.java
View file @
705014eb
...
...
@@ -71,6 +71,7 @@ import java.util.Map;
import
java.util.UUID
;
import
static
org
.
testng
.
Assert
.
assertEquals
;
import
static
org
.
testng
.
Assert
.
assertNotNull
;
import
static
org
.
testng
.
Assert
.
fail
;
...
...
@@ -154,7 +155,10 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
JSONObject
response
=
new
JSONObject
(
responseAsString
);
Assert
.
assertNotNull
(
response
.
get
(
AtlasClient
.
REQUEST_ID
));
Assert
.
assertNotNull
(
response
.
get
(
AtlasClient
.
GUID
));
AtlasClient
.
EntityResult
entityResult
=
AtlasClient
.
EntityResult
.
fromString
(
response
.
toString
());
assertEquals
(
entityResult
.
getCreatedEntities
().
size
(),
1
);
assertNotNull
(
entityResult
.
getCreatedEntities
().
get
(
0
));
}
@Test
...
...
@@ -376,7 +380,9 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
}
private
void
addProperty
(
String
guid
,
String
property
,
String
value
)
throws
AtlasServiceException
{
serviceClient
.
updateEntityAttribute
(
guid
,
property
,
value
);
AtlasClient
.
EntityResult
entityResult
=
serviceClient
.
updateEntityAttribute
(
guid
,
property
,
value
);
assertEquals
(
entityResult
.
getUpdateEntities
().
size
(),
1
);
assertEquals
(
entityResult
.
getUpdateEntities
().
get
(
0
),
guid
);
}
private
ClientResponse
getEntityDefinition
(
String
guid
)
{
...
...
@@ -482,7 +488,6 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
JSONObject
response
=
new
JSONObject
(
responseAsString
);
Assert
.
assertNotNull
(
response
.
get
(
AtlasClient
.
REQUEST_ID
));
Assert
.
assertNotNull
(
response
.
get
(
"GUID"
));
final
JSONArray
list
=
response
.
getJSONArray
(
AtlasClient
.
RESULTS
);
Assert
.
assertEquals
(
list
.
length
(),
7
);
...
...
@@ -513,7 +518,6 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
JSONObject
response
=
new
JSONObject
(
responseAsString
);
Assert
.
assertNotNull
(
response
.
get
(
AtlasClient
.
REQUEST_ID
));
Assert
.
assertNotNull
(
response
.
get
(
AtlasClient
.
GUID
));
assertEntityAudit
(
guid
,
EntityAuditEvent
.
EntityAuditAction
.
TAG_ADD
);
}
...
...
@@ -561,7 +565,6 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
JSONObject
response
=
new
JSONObject
(
responseAsString
);
Assert
.
assertNotNull
(
response
.
get
(
AtlasClient
.
REQUEST_ID
));
Assert
.
assertNotNull
(
response
.
get
(
AtlasClient
.
GUID
));
// verify the response
clientResponse
=
getEntityDefinition
(
guid
);
...
...
@@ -612,7 +615,6 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
JSONObject
response
=
new
JSONObject
(
responseAsString
);
Assert
.
assertNotNull
(
response
.
get
(
AtlasClient
.
REQUEST_ID
));
Assert
.
assertNotNull
(
response
.
get
(
"GUID"
));
Assert
.
assertNotNull
(
response
.
get
(
"traitName"
));
assertEntityAudit
(
guid
,
EntityAuditEvent
.
EntityAuditAction
.
TAG_DELETE
);
}
...
...
@@ -635,7 +637,8 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
"trait="
+
traitName
+
" should be defined in type system before it can be deleted"
);
Assert
.
assertNotNull
(
response
.
get
(
AtlasClient
.
STACKTRACE
));
}
@Test
(
dependsOnMethods
=
"testSubmitEntity()"
)
@Test
(
dependsOnMethods
=
"testSubmitEntity()"
)
public
void
testDeleteExistentTraitNonExistentForEntity
()
throws
Exception
{
final
String
guid
=
tableId
.
_getId
();
...
...
@@ -704,7 +707,9 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
}});
LOG
.
debug
(
"Updating entity= "
+
tableUpdated
);
serviceClient
.
updateEntity
(
tableId
.
_getId
(),
tableUpdated
);
AtlasClient
.
EntityResult
entityResult
=
serviceClient
.
updateEntity
(
tableId
.
_getId
(),
tableUpdated
);
assertEquals
(
entityResult
.
getUpdateEntities
().
size
(),
1
);
assertEquals
(
entityResult
.
getUpdateEntities
().
get
(
0
),
tableId
.
_getId
());
ClientResponse
response
=
getEntityDefinition
(
tableId
.
_getId
());
String
definition
=
getEntityDefinition
(
response
);
...
...
@@ -722,8 +727,10 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
}});
LOG
.
debug
(
"Updating entity= "
+
tableUpdated
);
serviceClient
.
updateEntity
(
BaseResourceIT
.
HIVE_TABLE_TYPE
,
"name"
,
(
String
)
tableInstance
.
get
(
"name"
),
tableUpdated
);
entityResult
=
serviceClient
.
updateEntity
(
BaseResourceIT
.
HIVE_TABLE_TYPE
,
"name"
,
(
String
)
tableInstance
.
get
(
"name"
),
tableUpdated
);
assertEquals
(
entityResult
.
getUpdateEntities
().
size
(),
1
);
assertEquals
(
entityResult
.
getUpdateEntities
().
get
(
0
),
tableId
.
_getId
());
response
=
getEntityDefinition
(
tableId
.
_getId
());
definition
=
getEntityDefinition
(
response
);
...
...
@@ -732,7 +739,6 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
Assert
.
assertTrue
(
refs
.
get
(
0
).
equalsContents
(
columns
.
get
(
0
)));
Assert
.
assertEquals
(
refs
.
get
(
0
).
get
(
"dataType"
),
"int"
);
}
@Test
(
dependsOnMethods
=
"testSubmitEntity"
)
...
...
@@ -765,9 +771,8 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
// ATLAS-586: verify response entity can be parsed by GSON.
String
entity
=
clientResponse
.
getEntity
(
String
.
class
);
Gson
gson
=
new
Gson
();
UpdateEntitiesResponse
updateEntitiesResponse
=
null
;
try
{
updateEntitiesResponse
=
gson
.
fromJson
(
entity
,
UpdateEntitiesResponse
.
class
);
UpdateEntitiesResponse
updateEntitiesResponse
=
gson
.
fromJson
(
entity
,
UpdateEntitiesResponse
.
class
);
}
catch
(
JsonSyntaxException
e
)
{
Assert
.
fail
(
"Response entity from "
+
service
.
path
(
ENTITIES
).
getURI
()
+
" not parseable by GSON"
,
e
);
...
...
@@ -785,7 +790,7 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
private
static
class
UpdateEntitiesResponse
{
String
requestId
;
String
[]
GUID
;
AtlasClient
.
EntityResult
entities
;
AtlasEntity
definition
;
}
...
...
@@ -811,15 +816,9 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
queryParam
(
AtlasClient
.
GUID
.
toLowerCase
(),
db1Id
.
_getId
()).
queryParam
(
AtlasClient
.
GUID
.
toLowerCase
(),
db2Id
.
_getId
()).
accept
(
Servlets
.
JSON_MEDIA_TYPE
).
type
(
Servlets
.
JSON_MEDIA_TYPE
).
method
(
HttpMethod
.
DELETE
,
ClientResponse
.
class
);
JSONObject
response
=
getEntity
(
clientResponse
);
final
String
deletedGuidsJson
=
response
.
getString
(
AtlasClient
.
GUID
);
Assert
.
assertNotNull
(
deletedGuidsJson
);
JSONArray
guidsArray
=
new
JSONArray
(
deletedGuidsJson
);
Assert
.
assertEquals
(
guidsArray
.
length
(),
2
);
List
<
String
>
deletedGuidsList
=
new
ArrayList
<>(
2
);
for
(
int
index
=
0
;
index
<
guidsArray
.
length
();
index
++)
{
deletedGuidsList
.
add
(
guidsArray
.
getString
(
index
));
}
List
<
String
>
deletedGuidsList
=
AtlasClient
.
EntityResult
.
fromString
(
response
.
toString
()).
getDeletedEntities
();
Assert
.
assertTrue
(
deletedGuidsList
.
contains
(
db1Id
.
_getId
()));
Assert
.
assertTrue
(
deletedGuidsList
.
contains
(
db2Id
.
_getId
()));
...
...
@@ -843,7 +842,8 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
Id
db2Id
=
createInstance
(
db2
);
// Delete the database entities
List
<
String
>
deletedGuidsList
=
serviceClient
.
deleteEntities
(
db1Id
.
_getId
(),
db2Id
.
_getId
());
List
<
String
>
deletedGuidsList
=
serviceClient
.
deleteEntities
(
db1Id
.
_getId
(),
db2Id
.
_getId
()).
getDeletedEntities
();
// Verify that deleteEntities() response has database entity guids
Assert
.
assertEquals
(
deletedGuidsList
.
size
(),
2
);
...
...
@@ -867,7 +867,7 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
Id
db1Id
=
createInstance
(
db1
);
// Delete the database entity
List
<
String
>
deletedGuidsList
=
serviceClient
.
deleteEntity
(
DATABASE_TYPE
,
"name"
,
dbName
);
List
<
String
>
deletedGuidsList
=
serviceClient
.
deleteEntity
(
DATABASE_TYPE
,
"name"
,
dbName
)
.
getDeletedEntities
()
;
// Verify that deleteEntities() response has database entity guids
Assert
.
assertEquals
(
deletedGuidsList
.
size
(),
1
);
...
...
This diff is collapsed.
Click to expand it.
webapp/src/test/java/org/apache/atlas/web/service/CuratorFactoryTest.java
View file @
705014eb
...
...
@@ -23,21 +23,16 @@ import org.apache.atlas.ha.HAConfiguration;
import
org.apache.commons.configuration.Configuration
;
import
org.apache.curator.framework.CuratorFrameworkFactory
;
import
org.apache.curator.framework.api.ACLProvider
;
import
org.apache.zookeeper.ZooDefs
;
import
org.apache.zookeeper.data.ACL
;
import
org.mockito.ArgumentMatcher
;
import
org.mockito.Mock
;
import
org.mockito.Mockito
;
import
org.mockito.MockitoAnnotations
;
import
org.testng.annotations.AfterMethod
;
import
org.testng.annotations.BeforeMethod
;
import
org.testng.annotations.Test
;
import
static
junit
.
framework
.
TestCase
.
assertEquals
;
import
static
org
.
mockito
.
Matchers
.
any
;
import
static
org
.
mockito
.
Matchers
.
argThat
;
import
static
org
.
mockito
.
Matchers
.
eq
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
mockito
.
Mockito
.
verifyZeroInteractions
;
import
static
org
.
mockito
.
Mockito
.
when
;
...
...
This diff is collapsed.
Click to expand it.
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