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
852a7118
Commit
852a7118
authored
Feb 17, 2017
by
Dave Kantor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ATLAS-1551 auto update of reverse references in V1 API
parent
3a0865ad
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
561 additions
and
29 deletions
+561
-29
release-log.txt
release-log.txt
+1
-0
TypedInstanceToGraphMapper.java
...he/atlas/repository/graph/TypedInstanceToGraphMapper.java
+93
-13
GraphBackedMetadataRepositoryDeleteTestBase.java
...ry/graph/GraphBackedMetadataRepositoryDeleteTestBase.java
+20
-16
ReverseReferenceUpdateHardDeleteTest.java
...epository/graph/ReverseReferenceUpdateHardDeleteTest.java
+52
-0
ReverseReferenceUpdateSoftDeleteTest.java
...epository/graph/ReverseReferenceUpdateSoftDeleteTest.java
+83
-0
ReverseReferenceUpdateTestBase.java
...tlas/repository/graph/ReverseReferenceUpdateTestBase.java
+286
-0
TypesUtil.java
...va/org/apache/atlas/typesystem/types/utils/TypesUtil.java
+26
-0
No files found.
release-log.txt
View file @
852a7118
...
@@ -9,6 +9,7 @@ ATLAS-1060 Add composite indexes for exact match performance improvements for al
...
@@ -9,6 +9,7 @@ ATLAS-1060 Add composite indexes for exact match performance improvements for al
ATLAS-1127 Modify creation and modification timestamps to Date instead of Long(sumasai)
ATLAS-1127 Modify creation and modification timestamps to Date instead of Long(sumasai)
ALL CHANGES:
ALL CHANGES:
ATLAS-1551 auto update of reverse references in V1 API (dkantor)
ATLAS-1565 Create EntityREST endpoints for delete operations (sarathkumarsubramanian via svimal2106)
ATLAS-1565 Create EntityREST endpoints for delete operations (sarathkumarsubramanian via svimal2106)
ATLAS-1547 Added tests for hard delete (mneethiraj)
ATLAS-1547 Added tests for hard delete (mneethiraj)
ATLAS-1546 (ATLAS-1546.3.patch)Hive hook should choose appropriate JAAS config if host uses kerberos ticket-cache (nixonrodrigues via kevalbhat)
ATLAS-1546 (ATLAS-1546.3.patch)Hive hook should choose appropriate JAAS config if host uses kerberos ticket-cache (nixonrodrigues via kevalbhat)
...
...
repository/src/main/java/org/apache/atlas/repository/graph/TypedInstanceToGraphMapper.java
View file @
852a7118
...
@@ -49,6 +49,7 @@ import org.apache.atlas.typesystem.persistence.ReferenceableInstance;
...
@@ -49,6 +49,7 @@ import org.apache.atlas.typesystem.persistence.ReferenceableInstance;
import
org.apache.atlas.typesystem.types.AttributeInfo
;
import
org.apache.atlas.typesystem.types.AttributeInfo
;
import
org.apache.atlas.typesystem.types.ClassType
;
import
org.apache.atlas.typesystem.types.ClassType
;
import
org.apache.atlas.typesystem.types.DataTypes
;
import
org.apache.atlas.typesystem.types.DataTypes
;
import
org.apache.atlas.typesystem.types.DataTypes.TypeCategory
;
import
org.apache.atlas.typesystem.types.EnumValue
;
import
org.apache.atlas.typesystem.types.EnumValue
;
import
org.apache.atlas.typesystem.types.IDataType
;
import
org.apache.atlas.typesystem.types.IDataType
;
import
org.apache.atlas.typesystem.types.Multiplicity
;
import
org.apache.atlas.typesystem.types.Multiplicity
;
...
@@ -56,6 +57,7 @@ import org.apache.atlas.typesystem.types.ObjectGraphWalker;
...
@@ -56,6 +57,7 @@ import org.apache.atlas.typesystem.types.ObjectGraphWalker;
import
org.apache.atlas.typesystem.types.TraitType
;
import
org.apache.atlas.typesystem.types.TraitType
;
import
org.apache.atlas.typesystem.types.TypeSystem
;
import
org.apache.atlas.typesystem.types.TypeSystem
;
import
org.apache.atlas.typesystem.types.TypeUtils
;
import
org.apache.atlas.typesystem.types.TypeUtils
;
import
org.apache.atlas.typesystem.types.utils.TypesUtil
;
import
org.apache.atlas.util.AtlasRepositoryConfiguration
;
import
org.apache.atlas.util.AtlasRepositoryConfiguration
;
import
org.apache.atlas.utils.MD5Utils
;
import
org.apache.atlas.utils.MD5Utils
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
...
@@ -249,6 +251,9 @@ public final class TypedInstanceToGraphMapper {
...
@@ -249,6 +251,9 @@ public final class TypedInstanceToGraphMapper {
deleteHandler
.
deleteEdgeReference
(
currentEdge
,
attributeInfo
.
dataType
().
getTypeCategory
(),
deleteHandler
.
deleteEdgeReference
(
currentEdge
,
attributeInfo
.
dataType
().
getTypeCategory
(),
attributeInfo
.
isComposite
,
true
);
attributeInfo
.
isComposite
,
true
);
}
}
if
(
attributeInfo
.
reverseAttributeName
!=
null
&&
newEdge
!=
null
)
{
addReverseReference
(
instanceVertex
,
attributeInfo
.
reverseAttributeName
,
newEdge
);
}
break
;
break
;
case
TRAIT:
case
TRAIT:
...
@@ -421,24 +426,35 @@ public final class TypedInstanceToGraphMapper {
...
@@ -421,24 +426,35 @@ public final class TypedInstanceToGraphMapper {
List
<
Object
>
newElementsCreated
=
new
ArrayList
<>();
List
<
Object
>
newElementsCreated
=
new
ArrayList
<>();
if
(!
newAttributeEmpty
)
{
if
(!
newAttributeEmpty
)
{
if
(
newElements
!=
null
&&
!
newElements
.
isEmpty
())
{
int
index
=
0
;
int
index
=
0
;
for
(;
index
<
newElements
.
size
();
index
++)
{
for
(;
index
<
newElements
.
size
();
index
++)
{
Object
currentElement
=
(
currentElements
!=
null
&&
index
<
currentElements
.
size
())
?
Object
currentElement
=
(
currentElements
!=
null
&&
index
<
currentElements
.
size
())
?
currentElements
.
get
(
index
)
:
null
;
currentElements
.
get
(
index
)
:
null
;
if
(
LOG
.
isDebugEnabled
())
{
if
(
LOG
.
isDebugEnabled
())
{
LOG
.
debug
(
"Adding/updating element at position {}, current element {}, new element {}"
,
index
,
LOG
.
debug
(
"Adding/updating element at position {}, current element {}, new element {}"
,
index
,
currentElement
,
newElements
.
get
(
index
));
currentElement
,
newElements
.
get
(
index
));
}
Object
newEntry
=
addOrUpdateCollectionEntry
(
instanceVertex
,
attributeInfo
,
elementType
,
newElements
.
get
(
index
),
currentElement
,
propertyName
,
operation
);
newElementsCreated
.
add
(
newEntry
);
}
}
Object
newEntry
=
addOrUpdateCollectionEntry
(
instanceVertex
,
attributeInfo
,
elementType
,
newElements
.
get
(
index
),
currentElement
,
propertyName
,
operation
);
newElementsCreated
.
add
(
newEntry
);
}
}
}
}
if
(
GraphHelper
.
isReference
(
elementType
))
{
if
(
GraphHelper
.
isReference
(
elementType
))
{
if
(
attributeInfo
.
reverseAttributeName
!=
null
&&
newElementsCreated
.
size
()
>
0
)
{
// Set/add the new reference value(s) on the reverse reference.
for
(
Object
newElement
:
newElementsCreated
)
{
if
((
newElement
instanceof
AtlasEdge
))
{
AtlasEdge
newEdge
=
(
AtlasEdge
)
newElement
;
addReverseReference
(
instanceVertex
,
attributeInfo
.
reverseAttributeName
,
newEdge
);
}
else
{
throw
new
AtlasException
(
"Invalid array element type "
+
newElement
.
getClass
().
getName
()
+
" - expected "
+
AtlasEdge
.
class
.
getName
()
+
" for reference "
+
GraphHelper
.
getQualifiedFieldName
(
typedInstance
,
attributeInfo
)
+
" on vertex "
+
GraphHelper
.
getVertexDetails
(
instanceVertex
));
}
}
}
List
<
AtlasEdge
>
additionalEdges
=
removeUnusedEntries
(
instanceVertex
,
propertyName
,
(
List
)
currentElements
,
List
<
AtlasEdge
>
additionalEdges
=
removeUnusedEntries
(
instanceVertex
,
propertyName
,
(
List
)
currentElements
,
(
List
)
newElementsCreated
,
elementType
,
attributeInfo
);
(
List
)
newElementsCreated
,
elementType
,
attributeInfo
);
...
@@ -866,4 +882,67 @@ public final class TypedInstanceToGraphMapper {
...
@@ -866,4 +882,67 @@ public final class TypedInstanceToGraphMapper {
}
}
return
new
GuidMapping
(
mapping
);
return
new
GuidMapping
(
mapping
);
}
}
private
<
V
,
E
>
void
addReverseReference
(
AtlasVertex
<
V
,
E
>
vertex
,
String
reverseAttributeName
,
AtlasEdge
<
V
,
E
>
edge
)
throws
AtlasException
{
String
typeName
=
GraphHelper
.
getTypeName
(
vertex
);
Id
id
=
GraphHelper
.
getIdFromVertex
(
typeName
,
vertex
);
AtlasVertex
<
V
,
E
>
reverseVertex
=
edge
.
getInVertex
();
String
reverseTypeName
=
GraphHelper
.
getTypeName
(
reverseVertex
);
Id
reverseId
=
GraphHelper
.
getIdFromVertex
(
reverseTypeName
,
reverseVertex
);
IDataType
reverseType
=
typeSystem
.
getDataType
(
IDataType
.
class
,
reverseTypeName
);
AttributeInfo
reverseAttrInfo
=
TypesUtil
.
getFieldMapping
(
reverseType
).
fields
.
get
(
reverseAttributeName
);
if
(
reverseAttrInfo
.
dataType
().
getTypeCategory
()
==
TypeCategory
.
MAP
)
{
// If the reverse reference is a map, what would be used as the key?
// Not supporting automatic update of reverse map references.
LOG
.
debug
(
"Automatic update of reverse map reference is not supported - reference = {}"
,
GraphHelper
.
getQualifiedFieldName
(
reverseType
,
reverseAttributeName
));
return
;
}
String
propertyName
=
GraphHelper
.
getQualifiedFieldName
(
reverseType
,
reverseAttributeName
);
String
reverseEdgeLabel
=
GraphHelper
.
EDGE_LABEL_PREFIX
+
propertyName
;
AtlasEdge
<
V
,
E
>
reverseEdge
=
graphHelper
.
getEdgeForLabel
(
reverseVertex
,
reverseEdgeLabel
);
AtlasEdge
<
V
,
E
>
newEdge
=
null
;
if
(
reverseEdge
!=
null
)
{
newEdge
=
updateClassEdge
(
reverseVertex
,
reverseEdge
,
id
,
vertex
,
reverseAttrInfo
,
reverseEdgeLabel
);
}
else
{
newEdge
=
addClassEdge
(
reverseVertex
,
vertex
,
reverseEdgeLabel
);
}
switch
(
reverseAttrInfo
.
dataType
().
getTypeCategory
())
{
case
CLASS:
if
(
reverseEdge
!=
null
&&
!
reverseEdge
.
getId
().
toString
().
equals
(
newEdge
.
getId
().
toString
()))
{
// Disconnect old reference
deleteHandler
.
deleteEdgeReference
(
reverseEdge
,
reverseAttrInfo
.
dataType
().
getTypeCategory
(),
reverseAttrInfo
.
isComposite
,
true
);
}
break
;
case
ARRAY:
// Add edge ID to property value
List
<
String
>
elements
=
reverseVertex
.
getProperty
(
propertyName
,
List
.
class
);
if
(
elements
==
null
)
{
elements
=
new
ArrayList
<>();
elements
.
add
(
newEdge
.
getId
().
toString
());
reverseVertex
.
setProperty
(
propertyName
,
elements
);
}
else
{
if
(!
elements
.
contains
(
newEdge
.
getId
().
toString
()))
{
elements
.
add
(
newEdge
.
getId
().
toString
());
reverseVertex
.
setProperty
(
propertyName
,
elements
);
}
}
break
;
}
RequestContext
requestContext
=
RequestContext
.
get
();
GraphHelper
.
setProperty
(
reverseVertex
,
Constants
.
MODIFICATION_TIMESTAMP_PROPERTY_KEY
,
requestContext
.
getRequestTime
());
requestContext
.
recordEntityUpdate
(
reverseId
.
_getId
());
}
}
}
\ No newline at end of file
repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryDeleteTestBase.java
View file @
852a7118
...
@@ -24,11 +24,11 @@ import com.google.common.collect.ImmutableSet;
...
@@ -24,11 +24,11 @@ import com.google.common.collect.ImmutableSet;
import
org.apache.atlas.AtlasClient
;
import
org.apache.atlas.AtlasClient
;
import
org.apache.atlas.AtlasClient.EntityResult
;
import
org.apache.atlas.AtlasClient.EntityResult
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.GraphTransaction
;
import
org.apache.atlas.RepositoryMetadataModule
;
import
org.apache.atlas.RepositoryMetadataModule
;
import
org.apache.atlas.RequestContext
;
import
org.apache.atlas.RequestContext
;
import
org.apache.atlas.TestUtils
;
import
org.apache.atlas.TestUtils
;
import
org.apache.atlas.repository.Constants
;
import
org.apache.atlas.repository.Constants
;
import
org.apache.atlas.CreateUpdateEntitiesResult
;
import
org.apache.atlas.repository.MetadataRepository
;
import
org.apache.atlas.repository.MetadataRepository
;
import
org.apache.atlas.repository.RepositoryException
;
import
org.apache.atlas.repository.RepositoryException
;
import
org.apache.atlas.repository.graphdb.AtlasGraph
;
import
org.apache.atlas.repository.graphdb.AtlasGraph
;
...
@@ -63,10 +63,6 @@ import org.testng.annotations.BeforeMethod;
...
@@ -63,10 +63,6 @@ import org.testng.annotations.BeforeMethod;
import
org.testng.annotations.Guice
;
import
org.testng.annotations.Guice
;
import
org.testng.annotations.Test
;
import
org.testng.annotations.Test
;
import
java.lang.reflect.InvocationHandler
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Proxy
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Collections
;
...
@@ -257,7 +253,8 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
...
@@ -257,7 +253,8 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
private
String
createInstance
(
Referenceable
entity
)
throws
Exception
{
private
String
createInstance
(
Referenceable
entity
)
throws
Exception
{
ClassType
dataType
=
typeSystem
.
getDataType
(
ClassType
.
class
,
entity
.
getTypeName
());
ClassType
dataType
=
typeSystem
.
getDataType
(
ClassType
.
class
,
entity
.
getTypeName
());
ITypedReferenceableInstance
instance
=
dataType
.
convert
(
entity
,
Multiplicity
.
REQUIRED
);
ITypedReferenceableInstance
instance
=
dataType
.
convert
(
entity
,
Multiplicity
.
REQUIRED
);
List
<
String
>
results
=
repositoryService
.
createEntities
(
instance
).
getCreatedEntities
();
CreateUpdateEntitiesResult
result
=
repositoryService
.
createEntities
(
instance
);
List
<
String
>
results
=
result
.
getCreatedEntities
();
return
results
.
get
(
results
.
size
()
-
1
);
return
results
.
get
(
results
.
size
()
-
1
);
}
}
...
@@ -434,7 +431,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
...
@@ -434,7 +431,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
Assert
.
assertNotNull
(
modificationTimestampPreUpdate
);
Assert
.
assertNotNull
(
modificationTimestampPreUpdate
);
ITypedReferenceableInstance
jane
=
repositoryService
.
getEntityDefinition
(
nameGuidMap
.
get
(
"Jane"
));
ITypedReferenceableInstance
jane
=
repositoryService
.
getEntityDefinition
(
nameGuidMap
.
get
(
"Jane"
));
Id
jane
Gui
d
=
jane
.
getId
();
Id
jane
I
d
=
jane
.
getId
();
// Update max's mentor reference to john.
// Update max's mentor reference to john.
ClassType
personType
=
typeSystem
.
getDataType
(
ClassType
.
class
,
"Person"
);
ClassType
personType
=
typeSystem
.
getDataType
(
ClassType
.
class
,
"Person"
);
...
@@ -456,7 +453,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
...
@@ -456,7 +453,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
Assert
.
assertTrue
(
creationTimestamp
<
modificationTimestampPostUpdate
);
Assert
.
assertTrue
(
creationTimestamp
<
modificationTimestampPostUpdate
);
// Update max's mentor reference to jane.
// Update max's mentor reference to jane.
maxEntity
.
set
(
"mentor"
,
jane
Gui
d
);
maxEntity
.
set
(
"mentor"
,
jane
I
d
);
entityResult
=
updatePartial
(
maxEntity
);
entityResult
=
updatePartial
(
maxEntity
);
assertEquals
(
entityResult
.
getUpdateEntities
().
size
(),
1
);
assertEquals
(
entityResult
.
getUpdateEntities
().
size
(),
1
);
assertTrue
(
entityResult
.
getUpdateEntities
().
contains
(
maxGuid
));
assertTrue
(
entityResult
.
getUpdateEntities
().
contains
(
maxGuid
));
...
@@ -464,7 +461,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
...
@@ -464,7 +461,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
// Verify the update was applied correctly - jane should now be max's mentor.
// Verify the update was applied correctly - jane should now be max's mentor.
max
=
repositoryService
.
getEntityDefinition
(
maxGuid
);
max
=
repositoryService
.
getEntityDefinition
(
maxGuid
);
refTarget
=
(
ITypedReferenceableInstance
)
max
.
get
(
"mentor"
);
refTarget
=
(
ITypedReferenceableInstance
)
max
.
get
(
"mentor"
);
Assert
.
assertEquals
(
refTarget
.
getId
().
_getId
(),
jane
Gui
d
.
_getId
());
Assert
.
assertEquals
(
refTarget
.
getId
().
_getId
(),
jane
I
d
.
_getId
());
// Verify modification timestamp was updated.
// Verify modification timestamp was updated.
vertex
=
GraphHelper
.
getInstance
().
getVertexForGUID
(
maxGuid
);
vertex
=
GraphHelper
.
getInstance
().
getVertexForGUID
(
maxGuid
);
...
@@ -473,21 +470,28 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
...
@@ -473,21 +470,28 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
Assert
.
assertTrue
(
modificationTimestampPostUpdate
<
modificationTimestampPost2ndUpdate
);
Assert
.
assertTrue
(
modificationTimestampPostUpdate
<
modificationTimestampPost2ndUpdate
);
ITypedReferenceableInstance
julius
=
repositoryService
.
getEntityDefinition
(
nameGuidMap
.
get
(
"Julius"
));
ITypedReferenceableInstance
julius
=
repositoryService
.
getEntityDefinition
(
nameGuidMap
.
get
(
"Julius"
));
Id
julius
Gui
d
=
julius
.
getId
();
Id
julius
I
d
=
julius
.
getId
();
maxEntity
=
personType
.
createInstance
(
max
.
getId
());
maxEntity
=
personType
.
createInstance
(
max
.
getId
());
maxEntity
.
set
(
"manager"
,
julius
Gui
d
);
maxEntity
.
set
(
"manager"
,
julius
I
d
);
entityResult
=
updatePartial
(
maxEntity
);
entityResult
=
updatePartial
(
maxEntity
);
//
TODO ATLAS-499 should have updated julius' subordinates
//
Verify julius' subordinates were updated.
assertEquals
(
entityResult
.
getUpdateEntities
().
size
(),
2
);
assertEquals
(
entityResult
.
getUpdateEntities
().
size
(),
3
);
assertTrue
(
entityResult
.
getUpdateEntities
().
contains
(
maxGuid
));
assertTrue
(
entityResult
.
getUpdateEntities
().
contains
(
maxGuid
));
assertTrue
(
entityResult
.
getUpdateEntities
().
contains
(
janeGuid
.
_getId
(
)));
assertTrue
(
entityResult
.
getUpdateEntities
().
contains
All
(
Arrays
.
asList
(
maxGuid
,
janeId
.
_getId
(),
juliusId
.
_getId
()
)));
// Verify the update was applied correctly - julius should now be max's manager.
// Verify the update was applied correctly - julius should now be max's manager.
max
=
repositoryService
.
getEntityDefinition
(
maxGuid
);
max
=
repositoryService
.
getEntityDefinition
(
maxGuid
);
refTarget
=
(
ITypedReferenceableInstance
)
max
.
get
(
"manager"
);
refTarget
=
(
ITypedReferenceableInstance
)
max
.
get
(
"manager"
);
Assert
.
assertEquals
(
refTarget
.
getId
().
_getId
(),
juliusGuid
.
_getId
());
Assert
.
assertEquals
(
refTarget
.
getId
().
_getId
(),
juliusId
.
_getId
());
Assert
.
assertEquals
(
refTarget
.
getId
().
_getId
(),
juliusId
.
_getId
());
julius
=
repositoryService
.
getEntityDefinition
(
nameGuidMap
.
get
(
"Julius"
));
Object
object
=
julius
.
get
(
"subordinates"
);
Assert
.
assertTrue
(
object
instanceof
List
);
List
<
ITypedReferenceableInstance
>
refValues
=
(
List
<
ITypedReferenceableInstance
>)
object
;
Assert
.
assertEquals
(
refValues
.
size
(),
1
);
Assert
.
assertTrue
(
refValues
.
contains
(
max
.
getId
()));
assertTestUpdateEntity_MultiplicityOneNonCompositeReference
(
jane
Gui
d
.
_getId
());
assertTestUpdateEntity_MultiplicityOneNonCompositeReference
(
jane
I
d
.
_getId
());
}
}
protected
abstract
void
assertTestUpdateEntity_MultiplicityOneNonCompositeReference
(
String
janeGuid
)
throws
Exception
;
protected
abstract
void
assertTestUpdateEntity_MultiplicityOneNonCompositeReference
(
String
janeGuid
)
throws
Exception
;
...
...
repository/src/test/java/org/apache/atlas/repository/graph/ReverseReferenceUpdateHardDeleteTest.java
0 → 100644
View file @
852a7118
/**
* 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
.
repository
.
graph
;
import
java.util.List
;
import
org.apache.atlas.typesystem.ITypedReferenceableInstance
;
import
org.apache.atlas.typesystem.types.TypeSystem
;
import
org.testng.Assert
;
/**
* Run tests in {@link ReverseReferenceUpdateTestBase} with hard delete enabled.
*
*/
public
class
ReverseReferenceUpdateHardDeleteTest
extends
ReverseReferenceUpdateTestBase
{
@Override
DeleteHandler
getDeleteHandler
(
TypeSystem
typeSystem
)
{
return
new
HardDeleteHandler
(
typeSystem
);
}
@Override
void
assertTestOneToOneReference
(
Object
refValue
,
ITypedReferenceableInstance
expectedValue
,
ITypedReferenceableInstance
referencingInstance
)
throws
Exception
{
// Verify reference was disconnected
Assert
.
assertNull
(
refValue
);
}
@Override
void
assertTestOneToManyReference
(
Object
object
,
ITypedReferenceableInstance
referencingInstance
)
{
Assert
.
assertTrue
(
object
instanceof
List
);
List
<
ITypedReferenceableInstance
>
refValues
=
(
List
<
ITypedReferenceableInstance
>)
object
;
Assert
.
assertEquals
(
refValues
.
size
(),
1
);
}
}
repository/src/test/java/org/apache/atlas/repository/graph/ReverseReferenceUpdateSoftDeleteTest.java
0 → 100644
View file @
852a7118
/**
* 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
.
repository
.
graph
;
import
java.util.Iterator
;
import
java.util.List
;
import
org.apache.atlas.repository.Constants
;
import
org.apache.atlas.repository.graphdb.AtlasEdge
;
import
org.apache.atlas.repository.graphdb.AtlasVertex
;
import
org.apache.atlas.typesystem.ITypedReferenceableInstance
;
import
org.apache.atlas.typesystem.persistence.Id
;
import
org.apache.atlas.typesystem.types.TypeSystem
;
import
org.testng.Assert
;
/**
* Run tests in {@link ReverseReferenceUpdateTestBase} with soft delete enabled.
*
*/
public
class
ReverseReferenceUpdateSoftDeleteTest
extends
ReverseReferenceUpdateTestBase
{
@Override
DeleteHandler
getDeleteHandler
(
TypeSystem
typeSystem
)
{
return
new
SoftDeleteHandler
(
typeSystem
);
}
@Override
void
assertTestOneToOneReference
(
Object
actual
,
ITypedReferenceableInstance
expectedValue
,
ITypedReferenceableInstance
referencingInstance
)
throws
Exception
{
// Verify reference was not disconnected if soft deletes are enabled.
Assert
.
assertNotNull
(
actual
);
Assert
.
assertTrue
(
actual
instanceof
ITypedReferenceableInstance
);
ITypedReferenceableInstance
referenceValue
=
(
ITypedReferenceableInstance
)
actual
;
Assert
.
assertEquals
(
referenceValue
.
getId
().
_getId
(),
expectedValue
.
getId
().
_getId
());
//Verify reference edge was marked as DELETED.
AtlasVertex
vertexForGUID
=
GraphHelper
.
getInstance
().
getVertexForGUID
(
referencingInstance
.
getId
().
_getId
());
String
edgeLabel
=
GraphHelper
.
getEdgeLabel
(
typeB
,
typeB
.
fieldMapping
.
fields
.
get
(
"a"
));
AtlasEdge
edgeForLabel
=
GraphHelper
.
getInstance
().
getEdgeForLabel
(
vertexForGUID
,
edgeLabel
);
String
edgeState
=
edgeForLabel
.
getProperty
(
Constants
.
STATE_PROPERTY_KEY
,
String
.
class
);
Assert
.
assertEquals
(
edgeState
,
Id
.
EntityState
.
DELETED
.
name
());
}
@Override
void
assertTestOneToManyReference
(
Object
object
,
ITypedReferenceableInstance
referencingInstance
)
throws
Exception
{
// Verify reference was not disconnected if soft deletes are enabled.
Assert
.
assertTrue
(
object
instanceof
List
);
List
<
ITypedReferenceableInstance
>
refValues
=
(
List
<
ITypedReferenceableInstance
>)
object
;
Assert
.
assertEquals
(
refValues
.
size
(),
2
);
// Verify that one of the reference edges is marked DELETED.
AtlasVertex
vertexForGUID
=
GraphHelper
.
getInstance
().
getVertexForGUID
(
referencingInstance
.
getId
().
_getId
());
String
edgeLabel
=
GraphHelper
.
getEdgeLabel
(
typeB
,
typeB
.
fieldMapping
.
fields
.
get
(
"manyA"
));
Iterator
<
AtlasEdge
>
outGoingEdgesByLabel
=
GraphHelper
.
getInstance
().
getOutGoingEdgesByLabel
(
vertexForGUID
,
edgeLabel
);
boolean
found
=
false
;
while
(
outGoingEdgesByLabel
.
hasNext
())
{
AtlasEdge
edge
=
outGoingEdgesByLabel
.
next
();
String
edgeState
=
edge
.
getProperty
(
Constants
.
STATE_PROPERTY_KEY
,
String
.
class
);
if
(
edgeState
.
equals
(
Id
.
EntityState
.
DELETED
.
name
()))
{
found
=
true
;
break
;
}
}
Assert
.
assertTrue
(
found
,
"One edge for label "
+
edgeLabel
+
" should be marked "
+
Id
.
EntityState
.
DELETED
.
name
());
}
}
repository/src/test/java/org/apache/atlas/repository/graph/ReverseReferenceUpdateTestBase.java
0 → 100644
View file @
852a7118
/**
* 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
.
repository
.
graph
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Map
;
import
org.apache.atlas.CreateUpdateEntitiesResult
;
import
org.apache.atlas.RepositoryMetadataModule
;
import
org.apache.atlas.TestUtils
;
import
org.apache.atlas.repository.MetadataRepository
;
import
org.apache.atlas.type.AtlasTypeRegistry
;
import
org.apache.atlas.typesystem.ITypedReferenceableInstance
;
import
org.apache.atlas.typesystem.TypesDef
;
import
org.apache.atlas.typesystem.types.AttributeDefinition
;
import
org.apache.atlas.typesystem.types.ClassType
;
import
org.apache.atlas.typesystem.types.DataTypes
;
import
org.apache.atlas.typesystem.types.EnumTypeDefinition
;
import
org.apache.atlas.typesystem.types.HierarchicalTypeDefinition
;
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.utils.TypesUtil
;
import
org.testng.Assert
;
import
org.testng.annotations.BeforeClass
;
import
org.testng.annotations.BeforeMethod
;
import
org.testng.annotations.Guice
;
import
org.testng.annotations.Test
;
import
com.google.common.collect.ImmutableList
;
import
com.google.common.collect.ImmutableSet
;
import
com.google.inject.Inject
;
/**
* Verifies automatic update of reverse references
*
*/
@Guice
(
modules
=
RepositoryMetadataModule
.
class
)
public
abstract
class
ReverseReferenceUpdateTestBase
{
@Inject
MetadataRepository
repositoryService
;
private
TypeSystem
typeSystem
;
protected
ClassType
typeA
;
protected
ClassType
typeB
;
abstract
DeleteHandler
getDeleteHandler
(
TypeSystem
typeSystem
);
abstract
void
assertTestOneToOneReference
(
Object
actual
,
ITypedReferenceableInstance
expectedValue
,
ITypedReferenceableInstance
referencingInstance
)
throws
Exception
;
abstract
void
assertTestOneToManyReference
(
Object
refValue
,
ITypedReferenceableInstance
referencingInstance
)
throws
Exception
;
@BeforeClass
public
void
setUp
()
throws
Exception
{
typeSystem
=
TypeSystem
.
getInstance
();
typeSystem
.
reset
();
new
GraphBackedSearchIndexer
(
new
AtlasTypeRegistry
());
HierarchicalTypeDefinition
<
ClassType
>
aDef
=
TypesUtil
.
createClassTypeDef
(
"A"
,
ImmutableSet
.<
String
>
of
(),
TypesUtil
.
createRequiredAttrDef
(
"name"
,
DataTypes
.
STRING_TYPE
),
new
AttributeDefinition
(
"b"
,
"B"
,
Multiplicity
.
OPTIONAL
,
false
,
"a"
),
// 1-1
new
AttributeDefinition
(
"oneB"
,
"B"
,
Multiplicity
.
OPTIONAL
,
false
,
"manyA"
),
// 1-*
new
AttributeDefinition
(
"manyB"
,
DataTypes
.
arrayTypeName
(
"B"
),
Multiplicity
.
OPTIONAL
,
false
,
"manyToManyA"
),
// *-*
new
AttributeDefinition
(
"map"
,
DataTypes
.
mapTypeName
(
DataTypes
.
STRING_TYPE
.
getName
(),
"B"
),
Multiplicity
.
OPTIONAL
,
false
,
"backToMap"
));
HierarchicalTypeDefinition
<
ClassType
>
bDef
=
TypesUtil
.
createClassTypeDef
(
"B"
,
ImmutableSet
.<
String
>
of
(),
TypesUtil
.
createRequiredAttrDef
(
"name"
,
DataTypes
.
STRING_TYPE
),
new
AttributeDefinition
(
"a"
,
"A"
,
Multiplicity
.
OPTIONAL
,
false
,
"b"
),
new
AttributeDefinition
(
"manyA"
,
DataTypes
.
arrayTypeName
(
"A"
),
Multiplicity
.
OPTIONAL
,
false
,
"oneB"
),
new
AttributeDefinition
(
"manyToManyA"
,
DataTypes
.
arrayTypeName
(
"A"
),
Multiplicity
.
OPTIONAL
,
false
,
"manyB"
),
new
AttributeDefinition
(
"backToMap"
,
"A"
,
Multiplicity
.
OPTIONAL
,
false
,
"map"
));
TypesDef
typesDef
=
TypesUtil
.
getTypesDef
(
ImmutableList
.<
EnumTypeDefinition
>
of
(),
ImmutableList
.<
StructTypeDefinition
>
of
(),
ImmutableList
.<
HierarchicalTypeDefinition
<
TraitType
>>
of
(),
ImmutableList
.
of
(
aDef
,
bDef
));
typeSystem
.
defineTypes
(
typesDef
);
typeA
=
typeSystem
.
getDataType
(
ClassType
.
class
,
"A"
);
typeB
=
typeSystem
.
getDataType
(
ClassType
.
class
,
"B"
);
repositoryService
=
new
GraphBackedMetadataRepository
(
getDeleteHandler
(
typeSystem
));
repositoryService
=
TestUtils
.
addTransactionWrapper
(
repositoryService
);
}
@BeforeMethod
public
void
setupContext
()
{
TestUtils
.
resetRequestContext
();
}
@Test
public
void
testOneToOneReference
()
throws
Exception
{
ITypedReferenceableInstance
a
=
typeA
.
createInstance
();
a
.
setString
(
"name"
,
TestUtils
.
randomString
());
ITypedReferenceableInstance
b1
=
typeB
.
createInstance
();
b1
.
setString
(
"name"
,
TestUtils
.
randomString
());
a
.
set
(
"b"
,
b1
);
// Create a. This should also create b1 and set the reverse b1->a reference.
repositoryService
.
createEntities
(
a
);
a
=
repositoryService
.
getEntityDefinition
(
"A"
,
"name"
,
a
.
getString
(
"name"
));
b1
=
repositoryService
.
getEntityDefinition
(
"B"
,
"name"
,
b1
.
getString
(
"name"
));
Object
object
=
a
.
get
(
"b"
);
Assert
.
assertTrue
(
object
instanceof
ITypedReferenceableInstance
);
ITypedReferenceableInstance
refValue
=
(
ITypedReferenceableInstance
)
object
;
Assert
.
assertEquals
(
refValue
.
getId
().
_getId
(),
b1
.
getId
().
_getId
());
object
=
b1
.
get
(
"a"
);
Assert
.
assertTrue
(
object
instanceof
ITypedReferenceableInstance
);
refValue
=
(
ITypedReferenceableInstance
)
object
;
Assert
.
assertEquals
(
refValue
.
getId
().
_getId
(),
a
.
getId
().
_getId
());
ITypedReferenceableInstance
b2
=
typeB
.
createInstance
();
b2
.
setString
(
"name"
,
TestUtils
.
randomString
());
b2
.
set
(
"a"
,
a
.
getId
());
// Create b2. This should set the reverse a->b2 reference
// and disconnect b1->a.
repositoryService
.
createEntities
(
b2
);
a
=
repositoryService
.
getEntityDefinition
(
a
.
getId
().
_getId
());
b2
=
repositoryService
.
getEntityDefinition
(
"B"
,
"name"
,
b2
.
getString
(
"name"
));
object
=
a
.
get
(
"b"
);
Assert
.
assertTrue
(
object
instanceof
ITypedReferenceableInstance
);
refValue
=
(
ITypedReferenceableInstance
)
object
;
Assert
.
assertEquals
(
refValue
.
getId
().
_getId
(),
b2
.
getId
().
_getId
());
object
=
b2
.
get
(
"a"
);
Assert
.
assertTrue
(
object
instanceof
ITypedReferenceableInstance
);
refValue
=
(
ITypedReferenceableInstance
)
object
;
Assert
.
assertEquals
(
refValue
.
getId
().
_getId
(),
a
.
getId
().
_getId
());
// Verify b1->a was disconnected.
b1
=
repositoryService
.
getEntityDefinition
(
"B"
,
"name"
,
b1
.
getString
(
"name"
));
object
=
b1
.
get
(
"a"
);
assertTestOneToOneReference
(
object
,
a
,
b1
);
}
@Test
public
void
testOneToManyReference
()
throws
Exception
{
ITypedReferenceableInstance
a1
=
typeA
.
createInstance
();
a1
.
setString
(
"name"
,
TestUtils
.
randomString
());
ITypedReferenceableInstance
a2
=
typeA
.
createInstance
();
a2
.
setString
(
"name"
,
TestUtils
.
randomString
());
ITypedReferenceableInstance
b1
=
typeB
.
createInstance
();
b1
.
setString
(
"name"
,
TestUtils
.
randomString
());
a1
.
set
(
"oneB"
,
b1
);
ITypedReferenceableInstance
b2
=
typeB
.
createInstance
();
b2
.
setString
(
"name"
,
TestUtils
.
randomString
());
repositoryService
.
createEntities
(
a1
,
a2
,
b2
);
a1
=
repositoryService
.
getEntityDefinition
(
"A"
,
"name"
,
a1
.
getString
(
"name"
));
a2
=
repositoryService
.
getEntityDefinition
(
"A"
,
"name"
,
a2
.
getString
(
"name"
));
b1
=
repositoryService
.
getEntityDefinition
(
"B"
,
"name"
,
b1
.
getString
(
"name"
));
b2
=
repositoryService
.
getEntityDefinition
(
"B"
,
"name"
,
b2
.
getString
(
"name"
));
Object
object
=
b1
.
get
(
"manyA"
);
Assert
.
assertTrue
(
object
instanceof
List
);
List
<
ITypedReferenceableInstance
>
refValues
=
(
List
<
ITypedReferenceableInstance
>)
object
;
Assert
.
assertEquals
(
refValues
.
size
(),
1
);
Assert
.
assertTrue
(
refValues
.
contains
(
a1
.
getId
()));
a2
.
set
(
"oneB"
,
b1
.
getId
());
repositoryService
.
updateEntities
(
a2
);
b1
=
repositoryService
.
getEntityDefinition
(
b1
.
getId
().
_getId
());
object
=
b1
.
get
(
"manyA"
);
Assert
.
assertTrue
(
object
instanceof
List
);
refValues
=
(
List
<
ITypedReferenceableInstance
>)
object
;
Assert
.
assertEquals
(
refValues
.
size
(),
2
);
Assert
.
assertTrue
(
refValues
.
containsAll
(
Arrays
.
asList
(
a1
.
getId
(),
a2
.
getId
())));
b2
.
set
(
"manyA"
,
Collections
.
singletonList
(
a2
));
repositoryService
.
updateEntities
(
b2
);
a2
=
repositoryService
.
getEntityDefinition
(
"A"
,
"name"
,
a2
.
getString
(
"name"
));
// Verify reverse a2.oneB reference was set to b2.
object
=
a2
.
get
(
"oneB"
);
Assert
.
assertTrue
(
object
instanceof
ITypedReferenceableInstance
);
ITypedReferenceableInstance
refValue
=
(
ITypedReferenceableInstance
)
object
;
Assert
.
assertEquals
(
refValue
.
getId
().
_getId
(),
b2
.
getId
().
_getId
());
// Verify a2 was removed from b1.manyA reference list.
b1
=
repositoryService
.
getEntityDefinition
(
b1
.
getId
().
_getId
());
object
=
b1
.
get
(
"manyA"
);
assertTestOneToManyReference
(
object
,
b1
);
}
@Test
public
void
testManyToManyReference
()
throws
Exception
{
ITypedReferenceableInstance
a1
=
typeA
.
createInstance
();
a1
.
setString
(
"name"
,
TestUtils
.
randomString
());
ITypedReferenceableInstance
a2
=
typeA
.
createInstance
();
a2
.
setString
(
"name"
,
TestUtils
.
randomString
());
ITypedReferenceableInstance
b1
=
typeB
.
createInstance
();
b1
.
setString
(
"name"
,
TestUtils
.
randomString
());
ITypedReferenceableInstance
b2
=
typeB
.
createInstance
();
b2
.
setString
(
"name"
,
TestUtils
.
randomString
());
repositoryService
.
createEntities
(
a1
,
a2
,
b1
,
b2
);
a1
=
repositoryService
.
getEntityDefinition
(
"A"
,
"name"
,
a1
.
getString
(
"name"
));
a2
=
repositoryService
.
getEntityDefinition
(
"A"
,
"name"
,
a2
.
getString
(
"name"
));
b1
=
repositoryService
.
getEntityDefinition
(
"B"
,
"name"
,
b1
.
getString
(
"name"
));
b2
=
repositoryService
.
getEntityDefinition
(
"B"
,
"name"
,
b2
.
getString
(
"name"
));
// Update a1 to add b1 to its manyB reference.
// This should update b1.manyToManyA.
a1
.
set
(
"manyB"
,
Arrays
.
asList
(
b1
.
getId
()));
repositoryService
.
updateEntities
(
a1
);
// Verify reverse b1.manyToManyA reference was updated.
b1
=
repositoryService
.
getEntityDefinition
(
b1
.
getId
().
_getId
());
Object
object
=
b1
.
get
(
"manyToManyA"
);
Assert
.
assertTrue
(
object
instanceof
List
);
List
<
ITypedReferenceableInstance
>
refValues
=
(
List
<
ITypedReferenceableInstance
>)
object
;
Assert
.
assertEquals
(
refValues
.
size
(),
1
);
Assert
.
assertTrue
(
refValues
.
contains
(
a1
.
getId
()));
}
/**
* Auto-update of bi-directional references where one end is a map reference is
* not currently supported. Verify that the auto-update is not applied in this case.
*/
@Test
public
void
testMapReference
()
throws
Exception
{
ITypedReferenceableInstance
a1
=
typeA
.
createInstance
();
a1
.
setString
(
"name"
,
TestUtils
.
randomString
());
ITypedReferenceableInstance
a2
=
typeA
.
createInstance
();
a2
.
setString
(
"name"
,
TestUtils
.
randomString
());
ITypedReferenceableInstance
b1
=
typeB
.
createInstance
();
b1
.
setString
(
"name"
,
TestUtils
.
randomString
());
ITypedReferenceableInstance
b2
=
typeB
.
createInstance
();
b2
.
setString
(
"name"
,
TestUtils
.
randomString
());
repositoryService
.
createEntities
(
a1
,
a2
,
b1
,
b2
);
a1
=
repositoryService
.
getEntityDefinition
(
"A"
,
"name"
,
a1
.
getString
(
"name"
));
a2
=
repositoryService
.
getEntityDefinition
(
"A"
,
"name"
,
a2
.
getString
(
"name"
));
b1
=
repositoryService
.
getEntityDefinition
(
"B"
,
"name"
,
b1
.
getString
(
"name"
));
b2
=
repositoryService
.
getEntityDefinition
(
"B"
,
"name"
,
b2
.
getString
(
"name"
));
a1
.
set
(
"map"
,
Collections
.
singletonMap
(
"b1"
,
b1
));
repositoryService
.
updateEntities
(
a1
);
// Verify reverse b1.manyToManyA reference was not updated.
b1
=
repositoryService
.
getEntityDefinition
(
b1
.
getId
().
_getId
());
Object
object
=
b1
.
get
(
"backToMap"
);
Assert
.
assertNull
(
object
);
}
/**
* Verify that explicitly setting both ends of a reference
* does not cause duplicate entries due to auto-update of
* reverse reference.
*/
@Test
public
void
testCallerHasSetBothEnds
()
throws
Exception
{
ITypedReferenceableInstance
a
=
typeA
.
createInstance
();
a
.
setString
(
"name"
,
TestUtils
.
randomString
());
ITypedReferenceableInstance
b1
=
typeB
.
createInstance
();
b1
.
setString
(
"name"
,
TestUtils
.
randomString
());
// Set both sides of the reference.
a
.
set
(
"oneB"
,
b1
);
b1
.
set
(
"manyA"
,
Collections
.
singletonList
(
a
));
CreateUpdateEntitiesResult
result
=
repositoryService
.
createEntities
(
a
);
Map
<
String
,
String
>
guidAssignments
=
result
.
getGuidMapping
().
getGuidAssignments
();
String
aGuid
=
a
.
getId
().
_getId
();
String
b1Guid
=
guidAssignments
.
get
(
b1
.
getId
().
_getId
());
a
=
repositoryService
.
getEntityDefinition
(
aGuid
);
Object
object
=
a
.
get
(
"oneB"
);
Assert
.
assertTrue
(
object
instanceof
ITypedReferenceableInstance
);
Assert
.
assertEquals
(((
ITypedReferenceableInstance
)
object
).
getId
().
_getId
(),
b1Guid
);
b1
=
repositoryService
.
getEntityDefinition
(
b1Guid
);
object
=
b1
.
get
(
"manyA"
);
Assert
.
assertTrue
(
object
instanceof
List
);
List
<
ITypedReferenceableInstance
>
refValues
=
(
List
<
ITypedReferenceableInstance
>)
object
;
Assert
.
assertEquals
(
refValues
.
size
(),
1
);
Assert
.
assertEquals
(
refValues
.
get
(
0
).
getId
().
_getId
(),
aGuid
);
}
}
typesystem/src/main/java/org/apache/atlas/typesystem/types/utils/TypesUtil.java
View file @
852a7118
...
@@ -28,9 +28,12 @@ import org.apache.atlas.typesystem.types.AttributeInfo;
...
@@ -28,9 +28,12 @@ import org.apache.atlas.typesystem.types.AttributeInfo;
import
org.apache.atlas.typesystem.types.ClassType
;
import
org.apache.atlas.typesystem.types.ClassType
;
import
org.apache.atlas.typesystem.types.EnumTypeDefinition
;
import
org.apache.atlas.typesystem.types.EnumTypeDefinition
;
import
org.apache.atlas.typesystem.types.EnumValue
;
import
org.apache.atlas.typesystem.types.EnumValue
;
import
org.apache.atlas.typesystem.types.FieldMapping
;
import
org.apache.atlas.typesystem.types.HierarchicalType
;
import
org.apache.atlas.typesystem.types.HierarchicalTypeDefinition
;
import
org.apache.atlas.typesystem.types.HierarchicalTypeDefinition
;
import
org.apache.atlas.typesystem.types.IDataType
;
import
org.apache.atlas.typesystem.types.IDataType
;
import
org.apache.atlas.typesystem.types.Multiplicity
;
import
org.apache.atlas.typesystem.types.Multiplicity
;
import
org.apache.atlas.typesystem.types.StructType
;
import
org.apache.atlas.typesystem.types.StructTypeDefinition
;
import
org.apache.atlas.typesystem.types.StructTypeDefinition
;
import
org.apache.atlas.typesystem.types.TraitType
;
import
org.apache.atlas.typesystem.types.TraitType
;
import
org.apache.atlas.AtlasConstants
;
import
org.apache.atlas.AtlasConstants
;
...
@@ -129,4 +132,27 @@ public class TypesUtil {
...
@@ -129,4 +132,27 @@ public class TypesUtil {
throw
new
RuntimeException
(
e
);
throw
new
RuntimeException
(
e
);
}
}
}
}
/**
* Get the field mappings for the specified data type.
* Field mappings are only relevant for CLASS, TRAIT, and STRUCT types.
*
* @param type
* @return {@link FieldMapping} for the specified type
* @throws IllegalArgumentException if type is not a CLASS, TRAIT, or STRUCT type.
*/
public
static
FieldMapping
getFieldMapping
(
IDataType
type
)
{
switch
(
type
.
getTypeCategory
())
{
case
CLASS:
case
TRAIT:
return
((
HierarchicalType
)
type
).
fieldMapping
();
case
STRUCT:
return
((
StructType
)
type
).
fieldMapping
();
default
:
throw
new
IllegalArgumentException
(
"Type "
+
type
+
" doesn't have any fields!"
);
}
}
}
}
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