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
85f9b502
Commit
85f9b502
authored
Jul 15, 2019
by
Merryle Wang
Committed by
Sarath Subramanian
Jul 15, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ATLAS-3286: Populate the dynamic attribute flag for each AtlasAttribute in each AltasEntityType
Signed-off-by:
Sarath Subramanian
<
sarath@apache.org
>
parent
23eacbaf
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
466 additions
and
48 deletions
+466
-48
AtlasEntityType.java
.../src/main/java/org/apache/atlas/type/AtlasEntityType.java
+146
-4
AtlasStructType.java
.../src/main/java/org/apache/atlas/type/AtlasStructType.java
+14
-4
AttributeToken.java
intg/src/main/java/org/apache/atlas/type/AttributeToken.java
+43
-0
ConstantToken.java
intg/src/main/java/org/apache/atlas/type/ConstantToken.java
+38
-0
DependentToken.java
intg/src/main/java/org/apache/atlas/type/DependentToken.java
+52
-0
TemplateToken.java
intg/src/main/java/org/apache/atlas/type/TemplateToken.java
+27
-0
TestAtlasEntityType.java
.../test/java/org/apache/atlas/type/TestAtlasEntityType.java
+57
-0
AtlasEntityGraphDiscoveryV2.java
...epository/store/graph/v2/AtlasEntityGraphDiscoveryV2.java
+36
-0
NotificationHookConsumerIT.java
...apache/atlas/notification/NotificationHookConsumerIT.java
+45
-34
EntityJerseyResourceIT.java
.../apache/atlas/web/integration/EntityJerseyResourceIT.java
+8
-6
No files found.
intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
View file @
85f9b502
...
...
@@ -30,6 +30,7 @@ import org.apache.atlas.utils.AtlasEntityUtil;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.collections.MapUtils
;
import
org.apache.commons.lang.StringUtils
;
import
org.apache.curator.shaded.com.google.common.annotations.VisibleForTesting
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -42,16 +43,21 @@ import java.util.Map;
import
java.util.Set
;
/**
* class that implements behaviour of an entity-type.
*/
public
class
AtlasEntityType
extends
AtlasStructType
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
AtlasEntityType
.
class
);
private
static
final
String
NAME
=
"name"
;
private
static
final
String
DESCRIPTION
=
"description"
;
private
static
final
String
OWNER
=
"owner"
;
private
static
final
String
CREATE_TIME
=
"createTime"
;
private
static
final
String
NAME
=
"name"
;
private
static
final
String
DESCRIPTION
=
"description"
;
private
static
final
String
OWNER
=
"owner"
;
private
static
final
String
CREATE_TIME
=
"createTime"
;
private
static
final
String
DYN_ATTRIBUTE_PREFIX
=
"dynAttribute:"
;
private
static
final
char
DYN_ATTRIBUTE_NAME_SEPARATOR
=
'.'
;
private
static
final
char
DYN_ATTRIBUTE_OPEN_DELIM
=
'{'
;
private
static
final
char
DYN_ATTRIBUTE_CLOSE_DELIM
=
'}'
;
private
static
final
String
[]
ENTITY_HEADER_ATTRIBUTES
=
new
String
[]{
NAME
,
DESCRIPTION
,
OWNER
,
CREATE_TIME
};
private
static
final
String
OPTION_SCHEMA_ATTRIBUTES
=
"schemaAttributes"
;
...
...
@@ -73,6 +79,9 @@ public class AtlasEntityType extends AtlasStructType {
private
boolean
isInternalType
=
false
;
private
Map
<
String
,
AtlasAttribute
>
headerAttributes
=
Collections
.
emptyMap
();
private
Map
<
String
,
AtlasAttribute
>
minInfoAttributes
=
Collections
.
emptyMap
();
private
List
<
AtlasAttribute
>
dynAttributes
=
Collections
.
emptyList
();
private
List
<
AtlasAttribute
>
dynEvalTriggerAttributes
=
Collections
.
emptyList
();
private
Map
<
String
,
List
<
TemplateToken
>>
parsedTemplates
=
Collections
.
emptyMap
();
public
AtlasEntityType
(
AtlasEntityDef
entityDef
)
{
...
...
@@ -256,6 +265,10 @@ public class AtlasEntityType extends AtlasStructType {
}
entityDef
.
setRelationshipAttributeDefs
(
Collections
.
unmodifiableList
(
relationshipAttrDefs
));
this
.
parsedTemplates
=
parseDynAttributeTemplates
();
populateDynFlagsInfo
();
}
public
Set
<
String
>
getSuperTypes
()
{
...
...
@@ -318,6 +331,18 @@ public class AtlasEntityType extends AtlasStructType {
return
ownedRefAttributes
;
}
public
List
<
AtlasAttribute
>
getDynEvalAttributes
()
{
return
dynAttributes
;
}
@VisibleForTesting
public
void
setDynEvalAttributes
(
List
<
AtlasAttribute
>
dynAttributes
)
{
this
.
dynAttributes
=
dynAttributes
;
}
public
List
<
AtlasAttribute
>
getDynEvalTriggerAttributes
()
{
return
dynEvalTriggerAttributes
;
}
@VisibleForTesting
public
void
setDynEvalTriggerAttributes
(
List
<
AtlasAttribute
>
dynEvalTriggerAttributes
)
{
this
.
dynEvalTriggerAttributes
=
dynEvalTriggerAttributes
;
}
public
Map
<
String
,
List
<
TemplateToken
>>
getParsedTemplates
()
{
return
parsedTemplates
;
}
public
AtlasAttribute
getRelationshipAttribute
(
String
attributeName
,
String
relationshipType
)
{
final
AtlasAttribute
ret
;
Map
<
String
,
AtlasAttribute
>
attributes
=
relationshipAttributes
.
get
(
attributeName
);
...
...
@@ -651,6 +676,123 @@ public class AtlasEntityType extends AtlasStructType {
}
}
private
void
populateDynFlagsInfo
()
{
dynAttributes
=
new
ArrayList
<>();
dynEvalTriggerAttributes
=
new
ArrayList
<>();
for
(
String
attributeName
:
parsedTemplates
.
keySet
())
{
AtlasAttribute
attribute
=
getAttribute
(
attributeName
);
if
(
attribute
!=
null
)
{
dynAttributes
.
add
(
attribute
);
}
}
for
(
List
<
TemplateToken
>
parsedTemplate
:
parsedTemplates
.
values
())
{
for
(
TemplateToken
token
:
parsedTemplate
)
{
// If token is an instance of AttributeToken means that the attribute is of this entity type
// so it must be added to the dynEvalTriggerAttributes list
if
(
token
instanceof
AttributeToken
)
{
AtlasAttribute
attribute
=
getAttribute
(
token
.
getValue
());
if
(
attribute
!=
null
)
{
dynEvalTriggerAttributes
.
add
(
attribute
);
}
}
}
}
dynAttributes
=
Collections
.
unmodifiableList
(
dynAttributes
);
dynEvalTriggerAttributes
=
Collections
.
unmodifiableList
(
dynEvalTriggerAttributes
);
for
(
AtlasAttribute
attribute
:
dynAttributes
)
{
attribute
.
setIsDynAttribute
(
true
);
}
for
(
AtlasAttribute
attribute
:
dynEvalTriggerAttributes
)
{
attribute
.
setIsDynAttributeEvalTrigger
(
true
);
}
}
private
Map
<
String
,
List
<
TemplateToken
>>
parseDynAttributeTemplates
(){
Map
<
String
,
List
<
TemplateToken
>>
ret
=
new
HashMap
<>();
Map
<
String
,
String
>
options
=
entityDef
.
getOptions
();
if
(
options
==
null
||
options
.
size
()
==
0
)
{
return
ret
;
}
for
(
String
key
:
options
.
keySet
())
{
if
(
key
.
startsWith
(
DYN_ATTRIBUTE_PREFIX
))
{
String
attributeName
=
key
.
substring
(
DYN_ATTRIBUTE_PREFIX
.
length
());
AtlasAttribute
attribute
=
getAttribute
(
attributeName
);
if
(
attribute
==
null
)
{
LOG
.
warn
(
"Ignoring {} attribute of {} type as dynamic attribute because attribute does not exist"
,
attributeName
,
this
.
getTypeName
());
continue
;
}
if
(!(
attribute
.
getAttributeType
()
instanceof
AtlasBuiltInTypes
.
AtlasStringType
))
{
LOG
.
warn
(
"Ignoring {} attribute of {} type as dynamic attribute because attribute isn't a string type"
,
attributeName
,
this
.
getTypeName
());
continue
;
}
String
template
=
options
.
get
(
key
);
List
<
TemplateToken
>
splitTemplate
=
templateSplit
(
template
);
ret
.
put
(
attributeName
,
splitTemplate
);
}
}
return
Collections
.
unmodifiableMap
(
ret
);
}
// own split function that also designates the right subclass for each token
private
List
<
TemplateToken
>
templateSplit
(
String
template
)
{
List
<
TemplateToken
>
ret
=
new
ArrayList
<>();
StringBuilder
token
=
new
StringBuilder
();
boolean
isInAttrName
=
false
;
for
(
int
i
=
0
;
i
<
template
.
length
();
i
++)
{
char
c
=
template
.
charAt
(
i
);
switch
(
c
)
{
case
DYN_ATTRIBUTE_OPEN_DELIM:
isInAttrName
=
true
;
if
(
token
.
length
()
>
0
)
{
ret
.
add
(
new
ConstantToken
(
token
.
toString
()));
token
.
setLength
(
0
);
}
break
;
case
DYN_ATTRIBUTE_CLOSE_DELIM:
if
(
isInAttrName
)
{
isInAttrName
=
false
;
if
(
token
.
length
()
>
0
)
{
String
attrName
=
token
.
toString
();
if
(
attrName
.
indexOf
(
DYN_ATTRIBUTE_NAME_SEPARATOR
)
!=
-
1
)
{
ret
.
add
(
new
DependentToken
(
token
.
toString
()));
}
else
{
ret
.
add
(
new
AttributeToken
(
token
.
toString
()));
}
token
.
setLength
(
0
);
}
}
else
{
token
.
append
(
c
);
}
break
;
default
:
token
.
append
(
c
);
break
;
}
}
return
ret
;
}
boolean
isAssignableFrom
(
AtlasObjectId
objId
)
{
boolean
ret
=
AtlasTypeUtil
.
isValid
(
objId
)
&&
(
StringUtils
.
equals
(
objId
.
getTypeName
(),
getTypeName
())
||
isSuperTypeOf
(
objId
.
getTypeName
()));
...
...
intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
View file @
85f9b502
...
...
@@ -710,6 +710,9 @@ public class AtlasStructType extends AtlasType {
private
boolean
isLegacyAttribute
;
private
String
indexFieldName
;
private
boolean
isDynAttribute
=
false
;
private
boolean
isDynAttributeEvalTrigger
=
false
;
public
AtlasAttribute
(
AtlasStructType
definedInType
,
AtlasAttributeDef
attrDef
,
AtlasType
attributeType
,
String
relationshipName
,
String
relationshipLabel
)
{
this
.
definedInType
=
definedInType
;
this
.
attributeDef
=
attrDef
;
...
...
@@ -746,23 +749,23 @@ public class AtlasStructType extends AtlasType {
switch
(
this
.
attributeType
.
getTypeCategory
())
{
case
OBJECT_ID_TYPE:
isObjectRef
=
true
;
break
;
break
;
case
MAP:
AtlasMapType
mapType
=
(
AtlasMapType
)
this
.
attributeType
;
isObjectRef
=
mapType
.
getValueType
().
getTypeCategory
()
==
OBJECT_ID_TYPE
;
break
;
break
;
case
ARRAY:
AtlasArrayType
arrayType
=
(
AtlasArrayType
)
this
.
attributeType
;
isObjectRef
=
arrayType
.
getElementType
().
getTypeCategory
()
==
OBJECT_ID_TYPE
;
break
;
break
;
default
:
isObjectRef
=
false
;
break
;
break
;
}
}
...
...
@@ -826,6 +829,13 @@ public class AtlasStructType extends AtlasType {
public
int
getSearchWeight
()
{
return
attributeDef
.
getSearchWeight
();
}
public
boolean
getIsDynAttribute
()
{
return
isDynAttribute
;
}
public
void
setIsDynAttribute
(
boolean
isDynAttribute
){
this
.
isDynAttribute
=
isDynAttribute
;
}
public
boolean
getIsDynAttributeEvalTrigger
()
{
return
isDynAttributeEvalTrigger
;
}
public
void
setIsDynAttributeEvalTrigger
(
boolean
isDynAttributeEvalTrigger
)
{
this
.
isDynAttributeEvalTrigger
=
isDynAttributeEvalTrigger
;
}
public
static
String
getEdgeLabel
(
String
property
)
{
return
"__"
+
property
;
...
...
intg/src/main/java/org/apache/atlas/type/AttributeToken.java
0 → 100644
View file @
85f9b502
/**
* 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
.
type
;
import
org.apache.atlas.exception.AtlasBaseException
;
import
org.apache.atlas.model.instance.AtlasEntity
;
public
class
AttributeToken
implements
TemplateToken
{
private
final
String
attrName
;
public
AttributeToken
(
String
attrName
){
this
.
attrName
=
attrName
;
}
@Override
public
String
eval
(
AtlasEntity
entity
)
throws
AtlasBaseException
{
Object
ret
=
entity
.
getAttribute
(
attrName
);
if
(
ret
==
null
)
{
return
null
;
}
return
ret
.
toString
();
}
@Override
public
String
getValue
()
{
return
attrName
;
}
}
intg/src/main/java/org/apache/atlas/type/ConstantToken.java
0 → 100644
View file @
85f9b502
/**
* 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
.
type
;
import
org.apache.atlas.model.instance.AtlasEntity
;
public
class
ConstantToken
implements
TemplateToken
{
private
final
String
constant
;
public
ConstantToken
(
String
constant
){
this
.
constant
=
constant
;
}
@Override
public
String
eval
(
AtlasEntity
entity
)
{
return
constant
;
}
@Override
public
String
getValue
()
{
return
constant
;
}
}
intg/src/main/java/org/apache/atlas/type/DependentToken.java
0 → 100644
View file @
85f9b502
/**
* 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
.
type
;
import
org.apache.atlas.exception.AtlasBaseException
;
import
org.apache.atlas.model.instance.AtlasEntity
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.List
;
public
class
DependentToken
implements
TemplateToken
{
private
final
String
path
;
private
final
List
<
String
>
objectPath
;
private
final
String
attrName
;
private
static
final
String
DYN_ATTRIBUTE_NAME_SEPARATOR
=
"\\."
;
public
DependentToken
(
String
path
){
List
<
String
>
objectPath
=
new
ArrayList
<>(
Arrays
.
asList
(
path
.
split
(
DYN_ATTRIBUTE_NAME_SEPARATOR
)));
this
.
path
=
path
;
this
.
attrName
=
objectPath
.
remove
(
objectPath
.
size
()
-
1
);
this
.
objectPath
=
Collections
.
unmodifiableList
(
objectPath
);
}
@Override
public
String
eval
(
AtlasEntity
entity
)
throws
AtlasBaseException
{
return
"TEMP"
;
}
@Override
public
String
getValue
()
{
return
path
;
}
}
intg/src/main/java/org/apache/atlas/type/TemplateToken.java
0 → 100644
View file @
85f9b502
/**
* 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
.
type
;
import
org.apache.atlas.exception.AtlasBaseException
;
import
org.apache.atlas.model.instance.AtlasEntity
;
public
interface
TemplateToken
{
String
eval
(
AtlasEntity
entity
)
throws
AtlasBaseException
;
String
getValue
();
}
intg/src/test/java/org/apache/atlas/type/TestAtlasEntityType.java
View file @
85f9b502
...
...
@@ -42,6 +42,7 @@ public class TestAtlasEntityType {
private
static
final
String
TYPE_COLUMN
=
"my_column"
;
private
static
final
String
ATTR_TABLE
=
"table"
;
private
static
final
String
ATTR_COLUMNS
=
"columns"
;
private
static
final
String
ATTR_OWNER
=
"owner"
;
private
static
final
String
ATTR_NAME
=
"name"
;
private
final
AtlasEntityType
entityType
;
...
...
@@ -164,6 +165,39 @@ public class TestAtlasEntityType {
}
@Test
public
void
testDynAttributeFlags
()
{
AtlasTypeRegistry
typeRegistry
=
new
AtlasTypeRegistry
();
AtlasTransientTypeRegistry
ttr
=
null
;
boolean
commit
=
false
;
List
<
AtlasEntityDef
>
entityDefs
=
new
ArrayList
<>();
String
failureMsg
=
null
;
entityDefs
.
add
(
createTableEntityDefWithOptions
());
entityDefs
.
add
(
createColumnEntityDef
());
try
{
ttr
=
typeRegistry
.
lockTypeRegistryForUpdate
();
ttr
.
addTypes
(
entityDefs
);
//options are read in the table,
AtlasEntityType
typeTable
=
ttr
.
getEntityTypeByName
(
TYPE_TABLE
);
AtlasEntityType
typeColumn
=
ttr
.
getEntityTypeByName
(
TYPE_COLUMN
);
assertTrue
(
typeTable
.
getAttribute
(
ATTR_NAME
).
getIsDynAttributeEvalTrigger
());
assertFalse
(
typeTable
.
getAttribute
(
ATTR_NAME
).
getIsDynAttribute
());
assertFalse
(
typeTable
.
getAttribute
(
ATTR_OWNER
).
getIsDynAttributeEvalTrigger
());
assertTrue
(
typeTable
.
getAttribute
(
ATTR_OWNER
).
getIsDynAttribute
());
commit
=
true
;
}
catch
(
AtlasBaseException
excp
)
{
failureMsg
=
excp
.
getMessage
();
}
finally
{
typeRegistry
.
releaseTypeRegistryForUpdate
(
ttr
,
commit
);
}
assertNull
(
failureMsg
,
"failed to create types "
+
TYPE_TABLE
+
" and "
+
TYPE_COLUMN
);
}
@Test
public
void
testConstraintInvalidOwnedRef_InvalidAttributeType
()
{
AtlasTypeRegistry
typeRegistry
=
new
AtlasTypeRegistry
();
AtlasTransientTypeRegistry
ttr
=
null
;
...
...
@@ -314,6 +348,29 @@ public class TestAtlasEntityType {
return
table
;
}
private
AtlasEntityDef
createTableEntityDefWithOptions
()
{
AtlasEntityDef
table
=
new
AtlasEntityDef
(
TYPE_TABLE
);
AtlasAttributeDef
attrName
=
new
AtlasAttributeDef
(
ATTR_NAME
,
AtlasBaseTypeDef
.
ATLAS_TYPE_STRING
);
AtlasAttributeDef
attrColumns
=
new
AtlasAttributeDef
(
ATTR_COLUMNS
,
AtlasBaseTypeDef
.
getArrayTypeName
(
TYPE_COLUMN
));
AtlasAttributeDef
attrOwner
=
new
AtlasAttributeDef
(
ATTR_OWNER
,
AtlasBaseTypeDef
.
ATLAS_TYPE_STRING
);
attrColumns
.
addConstraint
(
new
AtlasConstraintDef
(
AtlasConstraintDef
.
CONSTRAINT_TYPE_OWNED_REF
));
table
.
addAttribute
(
attrName
);
table
.
addAttribute
(
attrColumns
);
table
.
addAttribute
(
attrOwner
);
Map
<
String
,
String
>
options
=
new
HashMap
<>();
String
key
=
"dynAttribute:"
+
ATTR_OWNER
;
String
value
=
"{"
+
ATTR_NAME
+
"}"
;
options
.
put
(
key
,
value
);
table
.
setOptions
(
options
);
return
table
;
}
private
AtlasEntityDef
createTableEntityDefWithOwnedRefOnInvalidType
()
{
AtlasEntityDef
table
=
new
AtlasEntityDef
(
TYPE_TABLE
);
AtlasAttributeDef
attrName
=
new
AtlasAttributeDef
(
ATTR_NAME
,
AtlasBaseTypeDef
.
ATLAS_TYPE_STRING
);
...
...
repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityGraphDiscoveryV2.java
View file @
85f9b502
...
...
@@ -36,6 +36,7 @@ import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
import
org.apache.atlas.type.AtlasType
;
import
org.apache.atlas.type.AtlasTypeRegistry
;
import
org.apache.atlas.type.AtlasTypeUtil
;
import
org.apache.atlas.type.TemplateToken
;
import
org.apache.atlas.utils.AtlasEntityUtil
;
import
org.apache.atlas.utils.AtlasPerfMetrics.MetricRecorder
;
import
org.slf4j.Logger
;
...
...
@@ -144,6 +145,8 @@ public class AtlasEntityGraphDiscoveryV2 implements EntityGraphDiscovery {
throw
new
AtlasBaseException
(
AtlasErrorCode
.
INVALID_PARAMETERS
,
"found null entity"
);
}
processDynamicAttributes
(
entity
);
walkEntityGraph
(
entity
);
walkedEntities
.
add
(
entity
.
getGuid
());
...
...
@@ -395,4 +398,37 @@ public class AtlasEntityGraphDiscoveryV2 implements EntityGraphDiscovery {
discoveryContext
.
addReferencedByUniqAttribs
(
objId
);
}
}
private
void
processDynamicAttributes
(
AtlasEntity
entity
)
throws
AtlasBaseException
{
AtlasEntityType
entityType
=
typeRegistry
.
getEntityTypeByName
(
entity
.
getTypeName
());
for
(
AtlasAttribute
attribute
:
entityType
.
getDynEvalAttributes
())
{
String
attributeName
=
attribute
.
getName
();
List
<
TemplateToken
>
tokens
=
entityType
.
getParsedTemplates
().
get
(
attributeName
);
if
(
tokens
==
null
)
{
continue
;
}
StringBuilder
dynAttributeValue
=
new
StringBuilder
();
boolean
set
=
true
;
for
(
TemplateToken
token
:
tokens
)
{
String
evaluated
=
token
.
eval
(
entity
);
if
(
evaluated
!=
null
)
{
dynAttributeValue
.
append
(
evaluated
);
}
else
{
set
=
false
;
LOG
.
warn
(
"Attribute {} for {} unable to be generated because of dynamic attribute token {}"
,
attributeName
,
entityType
,
token
.
getValue
());
break
;
}
}
if
(
set
)
{
entity
.
setAttribute
(
attributeName
,
dynAttributeValue
.
toString
());
}
}
}
}
webapp/src/test/java/org/apache/atlas/notification/NotificationHookConsumerIT.java
View file @
85f9b502
...
...
@@ -93,13 +93,15 @@ public class NotificationHookConsumerIT extends BaseResourceIT {
@Test
public
void
testCreateEntity
()
throws
Exception
{
final
Referenceable
entity
=
new
Referenceable
(
DATABASE_TYPE_BUILTIN
);
final
String
dbName
=
"db"
+
randomString
();
final
Referenceable
entity
=
new
Referenceable
(
DATABASE_TYPE_BUILTIN
);
final
String
dbName
=
"db"
+
randomString
();
final
String
clusterName
=
randomString
();
final
String
qualifiedName
=
dbName
+
"@"
+
clusterName
;
entity
.
set
(
NAME
,
dbName
);
entity
.
set
(
DESCRIPTION
,
randomString
());
entity
.
set
(
QUALIFIED_NAME
,
db
Name
);
entity
.
set
(
CLUSTER_NAME
,
randomString
()
);
entity
.
set
(
QUALIFIED_NAME
,
qualified
Name
);
entity
.
set
(
CLUSTER_NAME
,
clusterName
);
sendHookMessage
(
new
EntityCreateRequest
(
TEST_USER
,
entity
));
...
...
@@ -122,13 +124,15 @@ public class NotificationHookConsumerIT extends BaseResourceIT {
@Test
public
void
testUpdateEntityPartial
()
throws
Exception
{
final
Referenceable
entity
=
new
Referenceable
(
DATABASE_TYPE_BUILTIN
);
final
String
dbName
=
"db"
+
randomString
();
final
Referenceable
entity
=
new
Referenceable
(
DATABASE_TYPE_BUILTIN
);
final
String
dbName
=
"db"
+
randomString
();
final
String
clusterName
=
randomString
();
final
String
qualifiedName
=
dbName
+
"@"
+
clusterName
;
entity
.
set
(
NAME
,
dbName
);
entity
.
set
(
DESCRIPTION
,
randomString
());
entity
.
set
(
QUALIFIED_NAME
,
db
Name
);
entity
.
set
(
CLUSTER_NAME
,
randomString
()
);
entity
.
set
(
QUALIFIED_NAME
,
qualified
Name
);
entity
.
set
(
CLUSTER_NAME
,
clusterName
);
atlasClientV1
.
createEntity
(
entity
);
...
...
@@ -136,70 +140,75 @@ public class NotificationHookConsumerIT extends BaseResourceIT {
newEntity
.
set
(
"owner"
,
randomString
());
sendHookMessage
(
new
EntityPartialUpdateRequest
(
TEST_USER
,
DATABASE_TYPE_BUILTIN
,
QUALIFIED_NAME
,
dbName
,
newEntity
));
sendHookMessage
(
new
EntityPartialUpdateRequest
(
TEST_USER
,
DATABASE_TYPE_BUILTIN
,
QUALIFIED_NAME
,
(
String
)
entity
.
get
(
QUALIFIED_NAME
)
,
newEntity
));
waitFor
(
MAX_WAIT_TIME
,
new
Predicate
()
{
@Override
public
boolean
evaluate
()
throws
Exception
{
Referenceable
localEntity
=
atlasClientV1
.
getEntity
(
DATABASE_TYPE_BUILTIN
,
QUALIFIED_NAME
,
db
Name
);
Referenceable
localEntity
=
atlasClientV1
.
getEntity
(
DATABASE_TYPE_BUILTIN
,
QUALIFIED_NAME
,
qualified
Name
);
return
(
localEntity
.
get
(
"owner"
)
!=
null
&&
localEntity
.
get
(
"owner"
).
equals
(
newEntity
.
get
(
"owner"
)));
}
});
//Its partial update and un-set fields are not updated
Referenceable
actualEntity
=
atlasClientV1
.
getEntity
(
DATABASE_TYPE_BUILTIN
,
QUALIFIED_NAME
,
dbName
);
Referenceable
actualEntity
=
atlasClientV1
.
getEntity
(
DATABASE_TYPE_BUILTIN
,
QUALIFIED_NAME
,
(
String
)
entity
.
get
(
QUALIFIED_NAME
)
);
assertEquals
(
actualEntity
.
get
(
DESCRIPTION
),
entity
.
get
(
DESCRIPTION
));
}
@Test
public
void
testUpdatePartialUpdatingQualifiedName
()
throws
Exception
{
final
Referenceable
entity
=
new
Referenceable
(
DATABASE_TYPE_BUILTIN
);
final
String
dbName
=
"db"
+
randomString
();
final
Referenceable
entity
=
new
Referenceable
(
DATABASE_TYPE_BUILTIN
);
final
String
dbName
=
"db"
+
randomString
();
final
String
clusterName
=
randomString
();
final
String
qualifiedName
=
dbName
+
"@"
+
clusterName
;
entity
.
set
(
NAME
,
dbName
);
entity
.
set
(
DESCRIPTION
,
randomString
());
entity
.
set
(
QUALIFIED_NAME
,
db
Name
);
entity
.
set
(
CLUSTER_NAME
,
randomString
()
);
entity
.
set
(
QUALIFIED_NAME
,
qualified
Name
);
entity
.
set
(
CLUSTER_NAME
,
clusterName
);
atlasClientV1
.
createEntity
(
entity
);
final
Referenceable
newEntity
=
new
Referenceable
(
DATABASE_TYPE_BUILTIN
);
final
String
newName
=
"db"
+
randomString
();
final
Referenceable
newEntity
=
new
Referenceable
(
DATABASE_TYPE_BUILTIN
);
final
String
newName
=
"db"
+
randomString
();
final
String
newQualifiedName
=
newName
+
"@"
+
clusterName
;
newEntity
.
set
(
QUALIFIED_NAME
,
newName
);
newEntity
.
set
(
QUALIFIED_NAME
,
new
Qualified
Name
);
sendHookMessage
(
new
EntityPartialUpdateRequest
(
TEST_USER
,
DATABASE_TYPE_BUILTIN
,
QUALIFIED_NAME
,
db
Name
,
newEntity
));
sendHookMessage
(
new
EntityPartialUpdateRequest
(
TEST_USER
,
DATABASE_TYPE_BUILTIN
,
QUALIFIED_NAME
,
qualified
Name
,
newEntity
));
waitFor
(
MAX_WAIT_TIME
,
new
Predicate
()
{
@Override
public
boolean
evaluate
()
throws
Exception
{
ArrayNode
results
=
searchByDSL
(
String
.
format
(
"%s where qualifiedName='%s'"
,
DATABASE_TYPE_BUILTIN
,
newName
));
ArrayNode
results
=
searchByDSL
(
String
.
format
(
"%s where qualifiedName='%s'"
,
DATABASE_TYPE_BUILTIN
,
new
Qualified
Name
));
return
results
.
size
()
==
1
;
}
});
//no entity with the old qualified name
ArrayNode
results
=
searchByDSL
(
String
.
format
(
"%s where qualifiedName='%s'"
,
DATABASE_TYPE_BUILTIN
,
db
Name
));
ArrayNode
results
=
searchByDSL
(
String
.
format
(
"%s where qualifiedName='%s'"
,
DATABASE_TYPE_BUILTIN
,
qualified
Name
));
assertEquals
(
results
.
size
(),
0
);
}
@Test
public
void
testDeleteByQualifiedName
()
throws
Exception
{
final
Referenceable
entity
=
new
Referenceable
(
DATABASE_TYPE_BUILTIN
);
final
String
dbName
=
"db"
+
randomString
();
final
Referenceable
entity
=
new
Referenceable
(
DATABASE_TYPE_BUILTIN
);
final
String
dbName
=
"db"
+
randomString
();
final
String
clusterName
=
randomString
();
final
String
qualifiedName
=
dbName
+
"@"
+
clusterName
;
entity
.
set
(
NAME
,
dbName
);
entity
.
set
(
DESCRIPTION
,
randomString
());
entity
.
set
(
QUALIFIED_NAME
,
db
Name
);
entity
.
set
(
CLUSTER_NAME
,
randomString
()
);
entity
.
set
(
QUALIFIED_NAME
,
qualified
Name
);
entity
.
set
(
CLUSTER_NAME
,
clusterName
);
final
String
dbId
=
atlasClientV1
.
createEntity
(
entity
).
get
(
0
);
sendHookMessage
(
new
EntityDeleteRequest
(
TEST_USER
,
DATABASE_TYPE_BUILTIN
,
QUALIFIED_NAME
,
db
Name
));
sendHookMessage
(
new
EntityDeleteRequest
(
TEST_USER
,
DATABASE_TYPE_BUILTIN
,
QUALIFIED_NAME
,
qualified
Name
));
waitFor
(
MAX_WAIT_TIME
,
new
Predicate
()
{
@Override
...
...
@@ -213,23 +222,25 @@ public class NotificationHookConsumerIT extends BaseResourceIT {
@Test
public
void
testUpdateEntityFullUpdate
()
throws
Exception
{
final
Referenceable
entity
=
new
Referenceable
(
DATABASE_TYPE_BUILTIN
);
final
String
dbName
=
"db"
+
randomString
();
final
Referenceable
entity
=
new
Referenceable
(
DATABASE_TYPE_BUILTIN
);
final
String
dbName
=
"db"
+
randomString
();
final
String
clusterName
=
randomString
();
final
String
qualifiedName
=
dbName
+
"@"
+
clusterName
;
entity
.
set
(
NAME
,
dbName
);
entity
.
set
(
DESCRIPTION
,
randomString
());
entity
.
set
(
QUALIFIED_NAME
,
db
Name
);
entity
.
set
(
CLUSTER_NAME
,
randomString
()
);
entity
.
set
(
QUALIFIED_NAME
,
qualified
Name
);
entity
.
set
(
CLUSTER_NAME
,
clusterName
);
atlasClientV1
.
createEntity
(
entity
);
final
Referenceable
newEntity
=
new
Referenceable
(
DATABASE_TYPE_BUILTIN
);
newEntity
.
set
(
NAME
,
randomString
()
);
newEntity
.
set
(
NAME
,
dbName
);
newEntity
.
set
(
DESCRIPTION
,
randomString
());
newEntity
.
set
(
"owner"
,
randomString
());
newEntity
.
set
(
QUALIFIED_NAME
,
db
Name
);
newEntity
.
set
(
CLUSTER_NAME
,
randomString
()
);
newEntity
.
set
(
QUALIFIED_NAME
,
qualified
Name
);
newEntity
.
set
(
CLUSTER_NAME
,
clusterName
);
//updating unique attribute
sendHookMessage
(
new
EntityUpdateRequest
(
TEST_USER
,
newEntity
));
...
...
@@ -243,7 +254,7 @@ public class NotificationHookConsumerIT extends BaseResourceIT {
}
});
Referenceable
actualEntity
=
atlasClientV1
.
getEntity
(
DATABASE_TYPE_BUILTIN
,
QUALIFIED_NAME
,
db
Name
);
Referenceable
actualEntity
=
atlasClientV1
.
getEntity
(
DATABASE_TYPE_BUILTIN
,
QUALIFIED_NAME
,
qualified
Name
);
assertEquals
(
actualEntity
.
get
(
DESCRIPTION
),
newEntity
.
get
(
DESCRIPTION
));
assertEquals
(
actualEntity
.
get
(
"owner"
),
newEntity
.
get
(
"owner"
));
...
...
webapp/src/test/java/org/apache/atlas/web/integration/EntityJerseyResourceIT.java
View file @
85f9b502
...
...
@@ -277,9 +277,10 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
public
void
testGetEntityByAttribute
()
throws
Exception
{
Referenceable
db1
=
new
Referenceable
(
DATABASE_TYPE_BUILTIN
);
String
dbName
=
randomString
();
String
qualifiedName
=
dbName
+
"@cl1"
;
db1
.
set
(
NAME
,
dbName
);
db1
.
set
(
DESCRIPTION
,
randomString
());
db1
.
set
(
AtlasClient
.
REFERENCEABLE_ATTRIBUTE_NAME
,
db
Name
);
db1
.
set
(
AtlasClient
.
REFERENCEABLE_ATTRIBUTE_NAME
,
qualified
Name
);
db1
.
set
(
"owner"
,
"user1"
);
db1
.
set
(
CLUSTER_NAME
,
"cl1"
);
db1
.
set
(
"parameters"
,
Collections
.
EMPTY_MAP
);
...
...
@@ -287,9 +288,9 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
createInstance
(
db1
);
//get entity by attribute
Referenceable
referenceable
=
atlasClientV1
.
getEntity
(
DATABASE_TYPE_BUILTIN
,
QUALIFIED_NAME
,
db
Name
);
Referenceable
referenceable
=
atlasClientV1
.
getEntity
(
DATABASE_TYPE_BUILTIN
,
QUALIFIED_NAME
,
qualified
Name
);
Assert
.
assertEquals
(
referenceable
.
getTypeName
(),
DATABASE_TYPE_BUILTIN
);
Assert
.
assertEquals
(
referenceable
.
get
(
QUALIFIED_NAME
),
dbName
);
Assert
.
assertEquals
(
referenceable
.
get
(
QUALIFIED_NAME
),
dbName
+
"@"
+
"cl1"
);
}
@Test
...
...
@@ -1096,11 +1097,12 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
// Create database entity
Referenceable
db1
=
new
Referenceable
(
DATABASE_TYPE_BUILTIN
);
String
dbName
=
randomString
();
String
qualifiedName
=
dbName
+
"@cl1"
;
db1
.
set
(
NAME
,
dbName
);
db1
.
set
(
QUALIFIED_NAME
,
db
Name
);
db1
.
set
(
QUALIFIED_NAME
,
qualified
Name
);
db1
.
set
(
CLUSTER_NAME
,
randomString
());
db1
.
set
(
DESCRIPTION
,
randomString
());
db1
.
set
(
AtlasClient
.
REFERENCEABLE_ATTRIBUTE_NAME
,
db
Name
);
db1
.
set
(
AtlasClient
.
REFERENCEABLE_ATTRIBUTE_NAME
,
qualified
Name
);
db1
.
set
(
"owner"
,
"user1"
);
db1
.
set
(
CLUSTER_NAME
,
"cl1"
);
db1
.
set
(
"parameters"
,
Collections
.
EMPTY_MAP
);
...
...
@@ -1108,7 +1110,7 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
Id
db1Id
=
createInstance
(
db1
);
// Delete the database entity
List
<
String
>
deletedGuidsList
=
atlasClientV1
.
deleteEntity
(
DATABASE_TYPE_BUILTIN
,
QUALIFIED_NAME
,
db
Name
).
getDeletedEntities
();
List
<
String
>
deletedGuidsList
=
atlasClientV1
.
deleteEntity
(
DATABASE_TYPE_BUILTIN
,
QUALIFIED_NAME
,
qualified
Name
).
getDeletedEntities
();
// Verify that deleteEntities() response has database entity guids
Assert
.
assertEquals
(
deletedGuidsList
.
size
(),
1
);
...
...
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