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
d934645b
Commit
d934645b
authored
Jul 25, 2016
by
Suma Shivaprasad
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ATLAS-1049 List types by supertype (shwethags via sumasai)
parent
fa47dd2d
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
236 additions
and
119 deletions
+236
-119
AtlasClient.java
client/src/main/java/org/apache/atlas/AtlasClient.java
+54
-0
release-log.txt
release-log.txt
+1
-0
DefaultMetadataService.java
...ava/org/apache/atlas/services/DefaultMetadataService.java
+7
-17
MetadataService.java
.../main/java/org/apache/atlas/services/MetadataService.java
+8
-11
TypeSystem.java
...in/java/org/apache/atlas/typesystem/types/TypeSystem.java
+8
-3
DefaultTypeCache.java
...apache/atlas/typesystem/types/cache/DefaultTypeCache.java
+91
-34
TypeCache.java
...va/org/apache/atlas/typesystem/types/cache/TypeCache.java
+12
-9
DefaultTypeCacheTest.java
...he/atlas/typesystem/types/cache/DefaultTypeCacheTest.java
+0
-0
TypesResource.java
...in/java/org/apache/atlas/web/resources/TypesResource.java
+31
-21
BaseResourceIT.java
...t/java/org/apache/atlas/web/resources/BaseResourceIT.java
+2
-18
TypesJerseyResourceIT.java
...org/apache/atlas/web/resources/TypesJerseyResourceIT.java
+22
-6
No files found.
client/src/main/java/org/apache/atlas/AtlasClient.java
View file @
d934645b
...
@@ -36,6 +36,7 @@ import org.apache.atlas.typesystem.TypesDef;
...
@@ -36,6 +36,7 @@ import org.apache.atlas.typesystem.TypesDef;
import
org.apache.atlas.typesystem.json.InstanceSerialization
;
import
org.apache.atlas.typesystem.json.InstanceSerialization
;
import
org.apache.atlas.typesystem.json.TypesSerialization
;
import
org.apache.atlas.typesystem.json.TypesSerialization
;
import
org.apache.atlas.typesystem.types.AttributeDefinition
;
import
org.apache.atlas.typesystem.types.AttributeDefinition
;
import
org.apache.atlas.typesystem.types.DataTypes
;
import
org.apache.atlas.typesystem.types.HierarchicalTypeDefinition
;
import
org.apache.atlas.typesystem.types.HierarchicalTypeDefinition
;
import
org.apache.atlas.typesystem.types.TraitType
;
import
org.apache.atlas.typesystem.types.TraitType
;
import
org.apache.atlas.typesystem.types.utils.TypesUtil
;
import
org.apache.atlas.typesystem.types.utils.TypesUtil
;
...
@@ -107,6 +108,9 @@ public class AtlasClient {
...
@@ -107,6 +108,9 @@ public class AtlasClient {
public
static
final
String
ATTRIBUTE_NAME
=
"property"
;
public
static
final
String
ATTRIBUTE_NAME
=
"property"
;
public
static
final
String
ATTRIBUTE_VALUE
=
"value"
;
public
static
final
String
ATTRIBUTE_VALUE
=
"value"
;
public
static
final
String
SUPERTYPE
=
"supertype"
;
public
static
final
String
NOT_SUPERTYPE
=
"notsupertype"
;
public
static
final
String
ASSET_TYPE
=
"Asset"
;
public
static
final
String
ASSET_TYPE
=
"Asset"
;
public
static
final
String
NAME
=
"name"
;
public
static
final
String
NAME
=
"name"
;
public
static
final
String
DESCRIPTION
=
"description"
;
public
static
final
String
DESCRIPTION
=
"description"
;
...
@@ -606,11 +610,61 @@ public class AtlasClient {
...
@@ -606,11 +610,61 @@ public class AtlasClient {
return
updateType
(
TypesSerialization
.
toJson
(
typeDef
));
return
updateType
(
TypesSerialization
.
toJson
(
typeDef
));
}
}
/**
* Returns all type names in the system
* @return list of type names
* @throws AtlasServiceException
*/
public
List
<
String
>
listTypes
()
throws
AtlasServiceException
{
public
List
<
String
>
listTypes
()
throws
AtlasServiceException
{
final
JSONObject
jsonObject
=
callAPI
(
API
.
LIST_TYPES
,
null
);
final
JSONObject
jsonObject
=
callAPI
(
API
.
LIST_TYPES
,
null
);
return
extractResults
(
jsonObject
,
AtlasClient
.
RESULTS
,
new
ExtractOperation
<
String
,
String
>());
return
extractResults
(
jsonObject
,
AtlasClient
.
RESULTS
,
new
ExtractOperation
<
String
,
String
>());
}
}
/**
* Returns all type names with the given category
* @param category
* @return list of type names
* @throws AtlasServiceException
*/
public
List
<
String
>
listTypes
(
final
DataTypes
.
TypeCategory
category
)
throws
AtlasServiceException
{
JSONObject
response
=
callAPIWithRetries
(
API
.
LIST_TYPES
,
null
,
new
ResourceCreator
()
{
@Override
public
WebResource
createResource
()
{
WebResource
resource
=
getResource
(
API
.
LIST_TYPES
);
resource
=
resource
.
queryParam
(
TYPE
,
category
.
name
());
return
resource
;
}
});
return
extractResults
(
response
,
AtlasClient
.
RESULTS
,
new
ExtractOperation
<
String
,
String
>());
}
/**
* Return the list of type names in the type system which match the specified filter.
*
* @param category returns types whose category is the given typeCategory
* @param superType returns types which contain the given supertype
* @param notSupertype returns types which do not contain the given supertype
*
* Its possible to specify combination of these filters in one request and the conditions are combined with AND
* For example, typeCategory = TRAIT && supertype contains 'X' && supertype !contains 'Y'
* If there is no filter, all the types are returned
* @return list of type names
*/
public
List
<
String
>
listTypes
(
final
DataTypes
.
TypeCategory
category
,
final
String
superType
,
final
String
notSupertype
)
throws
AtlasServiceException
{
JSONObject
response
=
callAPIWithRetries
(
API
.
LIST_TYPES
,
null
,
new
ResourceCreator
()
{
@Override
public
WebResource
createResource
()
{
WebResource
resource
=
getResource
(
API
.
LIST_TYPES
);
resource
=
resource
.
queryParam
(
TYPE
,
category
.
name
());
resource
=
resource
.
queryParam
(
SUPERTYPE
,
superType
);
resource
=
resource
.
queryParam
(
NOT_SUPERTYPE
,
notSupertype
);
return
resource
;
}
});
return
extractResults
(
response
,
AtlasClient
.
RESULTS
,
new
ExtractOperation
<
String
,
String
>());
}
public
TypesDef
getType
(
String
typeName
)
throws
AtlasServiceException
{
public
TypesDef
getType
(
String
typeName
)
throws
AtlasServiceException
{
try
{
try
{
JSONObject
response
=
callAPI
(
API
.
GET_TYPE
,
null
,
typeName
);;
JSONObject
response
=
callAPI
(
API
.
GET_TYPE
,
null
,
typeName
);;
...
...
release-log.txt
View file @
d934645b
...
@@ -6,6 +6,7 @@ INCOMPATIBLE CHANGES:
...
@@ -6,6 +6,7 @@ INCOMPATIBLE CHANGES:
ALL CHANGES:
ALL CHANGES:
ATLAS-1049 List types by supertype (shwethags via sumasai)
ATLAS-1032 Atlas hook package should not include libraries already present in host component - like log4j(mneethiraj via sumasai)
ATLAS-1032 Atlas hook package should not include libraries already present in host component - like log4j(mneethiraj via sumasai)
ATLAS-1001 UI Paginate search APIs (kevalbhatt18 via sumasai)
ATLAS-1001 UI Paginate search APIs (kevalbhatt18 via sumasai)
ATLAS-1042 Performance improvement changes for propertykey+typeName based queries (sumasai via shwethags)
ATLAS-1042 Performance improvement changes for propertykey+typeName based queries (sumasai via shwethags)
...
...
repository/src/main/java/org/apache/atlas/services/DefaultMetadataService.java
View file @
d934645b
...
@@ -23,11 +23,8 @@ import com.google.common.collect.ImmutableList;
...
@@ -23,11 +23,8 @@ import com.google.common.collect.ImmutableList;
import
com.google.common.collect.ImmutableSet
;
import
com.google.common.collect.ImmutableSet
;
import
com.google.inject.Provider
;
import
com.google.inject.Provider
;
import
com.thinkaurelius.titan.core.schema.TitanManagement
;
import
com.tinkerpop.blueprints.Vertex
;
import
org.apache.atlas.ApplicationProperties
;
import
org.apache.atlas.ApplicationProperties
;
import
org.apache.atlas.AtlasClient
;
import
org.apache.atlas.AtlasClient
;
import
org.apache.atlas.AtlasConstants
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.EntityAuditEvent
;
import
org.apache.atlas.EntityAuditEvent
;
import
org.apache.atlas.RequestContext
;
import
org.apache.atlas.RequestContext
;
...
@@ -302,23 +299,16 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
...
@@ -302,23 +299,16 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
}
}
/**
/**
* Return the list of type
s in the repository
.
* Return the list of type
names in the type system which match the specified filter
.
*
*
* @return list of type names in the repository
* @return list of type names
* @param filterMap - Map of filter for type names. Valid keys are CATEGORY, SUPERTYPE, NOT_SUPERTYPE
* For example, CATEGORY = TRAIT && SUPERTYPE contains 'X' && SUPERTYPE !contains 'Y'
* If there is no filter, all the types are returned
*/
*/
@Override
@Override
public
List
<
String
>
getTypeNamesList
()
throws
AtlasException
{
public
List
<
String
>
getTypeNames
(
Map
<
TypeCache
.
TYPE_FILTER
,
String
>
filterMap
)
throws
AtlasException
{
return
typeSystem
.
getTypeNames
();
return
typeSystem
.
getTypeNames
(
filterMap
);
}
/**
* Return the list of trait type names in the type system.
*
* @return list of trait type names in the type system
*/
@Override
public
List
<
String
>
getTypeNamesByCategory
(
DataTypes
.
TypeCategory
typeCategory
)
throws
AtlasException
{
return
typeSystem
.
getTypeNamesByCategory
(
typeCategory
);
}
}
/**
/**
...
...
server-api/src/main/java/org/apache/atlas/services/MetadataService.java
View file @
d934645b
...
@@ -26,10 +26,11 @@ import org.apache.atlas.typesystem.ITypedReferenceableInstance;
...
@@ -26,10 +26,11 @@ import org.apache.atlas.typesystem.ITypedReferenceableInstance;
import
org.apache.atlas.typesystem.ITypedStruct
;
import
org.apache.atlas.typesystem.ITypedStruct
;
import
org.apache.atlas.typesystem.Referenceable
;
import
org.apache.atlas.typesystem.Referenceable
;
import
org.apache.atlas.typesystem.Struct
;
import
org.apache.atlas.typesystem.Struct
;
import
org.apache.atlas.typesystem.types.
DataTypes
;
import
org.apache.atlas.typesystem.types.
cache.TypeCache
;
import
org.codehaus.jettison.json.JSONObject
;
import
org.codehaus.jettison.json.JSONObject
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
/**
/**
* Metadata service.
* Metadata service.
...
@@ -62,18 +63,14 @@ public interface MetadataService {
...
@@ -62,18 +63,14 @@ public interface MetadataService {
String
getTypeDefinition
(
String
typeName
)
throws
AtlasException
;
String
getTypeDefinition
(
String
typeName
)
throws
AtlasException
;
/**
/**
* Return the list of type
s in the type system
.
* Return the list of type
names in the type system which match the specified filter
.
*
*
* @return list of type names in the type system
* @return list of type names
* @param filterMap - Map of filter for type names. Valid keys are CATEGORY, SUPERTYPE, NOT_SUPERTYPE
* For example, CATEGORY = TRAIT && SUPERTYPE contains 'X' && SUPERTYPE !contains 'Y'
* If there is no filter, all the types are returned
*/
*/
List
<
String
>
getTypeNamesList
()
throws
AtlasException
;
List
<
String
>
getTypeNames
(
Map
<
TypeCache
.
TYPE_FILTER
,
String
>
filterMap
)
throws
AtlasException
;
/**
* Return the list of trait type names in the type system.
*
* @return list of trait type names in the type system
*/
List
<
String
>
getTypeNamesByCategory
(
DataTypes
.
TypeCategory
typeCategory
)
throws
AtlasException
;
/**
/**
* Creates an entity, instance of the type.
* Creates an entity, instance of the type.
...
...
typesystem/src/main/java/org/apache/atlas/typesystem/types/TypeSystem.java
View file @
d934645b
...
@@ -101,12 +101,17 @@ public class TypeSystem {
...
@@ -101,12 +101,17 @@ public class TypeSystem {
return
ImmutableList
.
copyOf
(
typeNames
);
return
ImmutableList
.
copyOf
(
typeNames
);
}
}
public
ImmutableList
<
String
>
getTypeNamesByCategory
(
DataTypes
.
TypeCategory
typeCategory
)
throws
AtlasException
{
public
ImmutableList
<
String
>
getTypeNamesByCategory
(
final
DataTypes
.
TypeCategory
typeCategory
)
throws
AtlasException
{
return
ImmutableList
.
copyOf
(
typeCache
.
getTypeNames
(
typeCategory
));
return
getTypeNames
(
new
HashMap
<
TypeCache
.
TYPE_FILTER
,
String
>()
{{
put
(
TypeCache
.
TYPE_FILTER
.
CATEGORY
,
typeCategory
.
name
());
}});
}
}
private
void
registerPrimitiveTypes
()
{
public
ImmutableList
<
String
>
getTypeNames
(
Map
<
TypeCache
.
TYPE_FILTER
,
String
>
filterMap
)
throws
AtlasException
{
return
ImmutableList
.
copyOf
(
typeCache
.
getTypeNames
(
filterMap
));
}
private
void
registerPrimitiveTypes
()
{
coreTypes
.
put
(
DataTypes
.
BOOLEAN_TYPE
.
getName
(),
DataTypes
.
BOOLEAN_TYPE
);
coreTypes
.
put
(
DataTypes
.
BOOLEAN_TYPE
.
getName
(),
DataTypes
.
BOOLEAN_TYPE
);
coreTypes
.
put
(
DataTypes
.
BYTE_TYPE
.
getName
(),
DataTypes
.
BYTE_TYPE
);
coreTypes
.
put
(
DataTypes
.
BYTE_TYPE
.
getName
(),
DataTypes
.
BYTE_TYPE
);
coreTypes
.
put
(
DataTypes
.
SHORT_TYPE
.
getName
(),
DataTypes
.
SHORT_TYPE
);
coreTypes
.
put
(
DataTypes
.
SHORT_TYPE
.
getName
(),
DataTypes
.
SHORT_TYPE
);
...
...
typesystem/src/main/java/org/apache/atlas/typesystem/types/cache/DefaultTypeCache.java
View file @
d934645b
...
@@ -17,22 +17,24 @@
...
@@ -17,22 +17,24 @@
*/
*/
package
org
.
apache
.
atlas
.
typesystem
.
types
.
cache
;
package
org
.
apache
.
atlas
.
typesystem
.
types
.
cache
;
import
java.util.ArrayList
;
import
com.google.inject.Singleton
;
import
java.util.Collection
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map.Entry
;
import
java.util.concurrent.ConcurrentHashMap
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.typesystem.types.ClassType
;
import
org.apache.atlas.typesystem.types.ClassType
;
import
org.apache.atlas.typesystem.types.DataTypes.TypeCategory
;
import
org.apache.atlas.typesystem.types.DataTypes.TypeCategory
;
import
org.apache.atlas.typesystem.types.EnumType
;
import
org.apache.atlas.typesystem.types.EnumType
;
import
org.apache.atlas.typesystem.types.HierarchicalType
;
import
org.apache.atlas.typesystem.types.IDataType
;
import
org.apache.atlas.typesystem.types.IDataType
;
import
org.apache.atlas.typesystem.types.StructType
;
import
org.apache.atlas.typesystem.types.StructType
;
import
org.apache.atlas.typesystem.types.TraitType
;
import
org.apache.atlas.typesystem.types.TraitType
;
import
org.apache.commons.lang.StringUtils
;
import
com.google.inject.Singleton
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map.Entry
;
import
java.util.concurrent.ConcurrentHashMap
;
/**
/**
* Caches the types in-memory within the same process space.
* Caches the types in-memory within the same process space.
...
@@ -42,6 +44,10 @@ import com.google.inject.Singleton;
...
@@ -42,6 +44,10 @@ import com.google.inject.Singleton;
public
class
DefaultTypeCache
implements
TypeCache
{
public
class
DefaultTypeCache
implements
TypeCache
{
private
Map
<
String
,
IDataType
>
types_
=
new
ConcurrentHashMap
<>();
private
Map
<
String
,
IDataType
>
types_
=
new
ConcurrentHashMap
<>();
private
static
final
List
<
TypeCategory
>
validTypeFilterCategories
=
Arrays
.
asList
(
TypeCategory
.
CLASS
,
TypeCategory
.
TRAIT
,
TypeCategory
.
ENUM
,
TypeCategory
.
STRUCT
);
private
static
final
List
<
TypeCategory
>
validSupertypeFilterCategories
=
Arrays
.
asList
(
TypeCategory
.
CLASS
,
TypeCategory
.
TRAIT
);
/*
/*
* (non-Javadoc)
* (non-Javadoc)
...
@@ -61,32 +67,29 @@ public class DefaultTypeCache implements TypeCache {
...
@@ -61,32 +67,29 @@ public class DefaultTypeCache implements TypeCache {
*/
*/
@Override
@Override
public
boolean
has
(
TypeCategory
typeCategory
,
String
typeName
)
public
boolean
has
(
TypeCategory
typeCategory
,
String
typeName
)
throws
AtlasException
{
throws
AtlasException
{
assertValidTypeCategory
(
typeCategory
);
assertValidTypeCategory
(
typeCategory
);
return
has
(
typeName
);
return
has
(
typeName
);
}
}
private
void
assertValidTypeCategory
(
TypeCategory
typeCategory
)
throws
private
void
assertValidTypeCategory
(
String
typeCategory
)
{
AtlasException
{
assertValidTypeCategory
(
TypeCategory
.
valueOf
(
typeCategory
));
}
private
void
assertValidTypeCategory
(
TypeCategory
typeCategory
)
{
// there might no need of 'typeCategory' in this implementation for
// there might no need of 'typeCategory' in this implementation for
// certain API, but for a distributed cache, it might help for the
// certain API, but for a distributed cache, it might help for the
// implementers to partition the types per their category
// implementers to partition the types per their category
// while persisting so that look can be efficient
// while persisting so that look can be efficient
if
(
typeCategory
==
null
)
{
if
(
typeCategory
==
null
)
{
throw
new
Atlas
Exception
(
"Category of the types to be filtered is null."
);
throw
new
IllegalArgument
Exception
(
"Category of the types to be filtered is null."
);
}
}
boolean
validTypeCategory
=
typeCategory
.
equals
(
TypeCategory
.
CLASS
)
||
if
(!
validTypeFilterCategories
.
contains
(
typeCategory
))
{
typeCategory
.
equals
(
TypeCategory
.
TRAIT
)
||
throw
new
IllegalArgumentException
(
"Category of the types should be one of "
+
typeCategory
.
equals
(
TypeCategory
.
ENUM
)
||
StringUtils
.
join
(
validTypeFilterCategories
,
", "
));
typeCategory
.
equals
(
TypeCategory
.
STRUCT
);
if
(!
validTypeCategory
)
{
throw
new
AtlasException
(
"Category of the types should be one of CLASS "
+
"| TRAIT | ENUM | STRUCT."
);
}
}
}
}
...
@@ -113,29 +116,83 @@ public class DefaultTypeCache implements TypeCache {
...
@@ -113,29 +116,83 @@ public class DefaultTypeCache implements TypeCache {
return
get
(
typeName
);
return
get
(
typeName
);
}
}
/*
/**
* (non-Javadoc)
* Return the list of type names in the type system which match the specified filter.
* @see
*
* org.apache.atlas.typesystem.types.cache.TypeCache#getNames(org
* @return list of type names
* .apache.atlas.typesystem.types.DataTypes.TypeCategory)
* @param filterMap - Map of filter for type names. Valid keys are CATEGORY, SUPERTYPE, NOT_SUPERTYPE
* For example, CATEGORY = TRAIT && SUPERTYPE contains 'X' && SUPERTYPE !contains 'Y'
*/
*/
@Override
@Override
public
Collection
<
String
>
getTypeNames
(
TypeCategory
typeCategory
)
throws
AtlasException
{
public
Collection
<
String
>
getTypeNames
(
Map
<
TYPE_FILTER
,
String
>
filterMap
)
throws
AtlasException
{
assertFilter
(
filterMap
);
assertValidTypeCategory
(
typeCategory
);
List
<
String
>
typeNames
=
new
ArrayList
<>();
List
<
String
>
typeNames
=
new
ArrayList
<>();
for
(
Entry
<
String
,
IDataType
>
typeEntry
:
types_
.
entrySet
())
{
for
(
IDataType
type
:
types_
.
values
())
{
String
name
=
typeEntry
.
getKey
();
if
(
shouldIncludeType
(
type
,
filterMap
))
{
IDataType
type
=
typeEntry
.
getValue
();
typeNames
.
add
(
type
.
getName
());
if
(
type
.
getTypeCategory
().
equals
(
typeCategory
))
{
typeNames
.
add
(
name
);
}
}
}
}
return
typeNames
;
return
typeNames
;
}
}
private
boolean
shouldIncludeType
(
IDataType
type
,
Map
<
TYPE_FILTER
,
String
>
filterMap
)
{
if
(
filterMap
==
null
)
{
return
true
;
}
for
(
Entry
<
TYPE_FILTER
,
String
>
filterEntry
:
filterMap
.
entrySet
())
{
switch
(
filterEntry
.
getKey
())
{
case
CATEGORY:
if
(!
filterEntry
.
getValue
().
equals
(
type
.
getTypeCategory
().
name
()))
{
return
false
;
}
break
;
case
SUPERTYPE:
if
(!
validSupertypeFilterCategories
.
contains
(
type
.
getTypeCategory
())
||
!((
HierarchicalType
)
type
).
getAllSuperTypeNames
().
contains
(
filterEntry
.
getValue
()))
{
return
false
;
}
break
;
case
NOT_SUPERTYPE:
if
(!
validSupertypeFilterCategories
.
contains
(
type
.
getTypeCategory
())
||
type
.
getName
().
equals
(
filterEntry
.
getValue
())
||
((
HierarchicalType
)
type
).
getAllSuperTypeNames
().
contains
(
filterEntry
.
getValue
()))
{
return
false
;
}
break
;
}
}
return
true
;
}
private
void
assertFilter
(
Map
<
TYPE_FILTER
,
String
>
filterMap
)
throws
AtlasException
{
if
(
filterMap
==
null
)
{
return
;
}
for
(
Entry
<
TYPE_FILTER
,
String
>
filterEntry
:
filterMap
.
entrySet
())
{
switch
(
filterEntry
.
getKey
())
{
case
CATEGORY:
assertValidTypeCategory
(
filterEntry
.
getValue
());
break
;
case
SUPERTYPE:
case
NOT_SUPERTYPE:
if
(!
has
(
filterEntry
.
getValue
()))
{
throw
new
IllegalArgumentException
(
"Invalid supertype "
+
filterEntry
.
getValue
());
}
break
;
default
:
throw
new
IllegalStateException
(
"Unhandled filter "
+
filterEntry
.
getKey
());
}
}
}
/*
/*
* (non-Javadoc)
* (non-Javadoc)
* @see
* @see
...
...
typesystem/src/main/java/org/apache/atlas/typesystem/types/cache/TypeCache.java
View file @
d934645b
...
@@ -18,12 +18,13 @@
...
@@ -18,12 +18,13 @@
package
org
.
apache
.
atlas
.
typesystem
.
types
.
cache
;
package
org
.
apache
.
atlas
.
typesystem
.
types
.
cache
;
import
java.util.Collection
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.typesystem.types.DataTypes
;
import
org.apache.atlas.typesystem.types.DataTypes
;
import
org.apache.atlas.typesystem.types.IDataType
;
import
org.apache.atlas.typesystem.types.IDataType
;
import
java.util.Collection
;
import
java.util.Map
;
/**
/**
* The types are cached to allow faster lookup when type info is needed during
* The types are cached to allow faster lookup when type info is needed during
* creation/updation of entities, DSL query translation/execution.
* creation/updation of entities, DSL query translation/execution.
...
@@ -39,6 +40,10 @@ import org.apache.atlas.typesystem.types.IDataType;
...
@@ -39,6 +40,10 @@ import org.apache.atlas.typesystem.types.IDataType;
@SuppressWarnings
(
"rawtypes"
)
@SuppressWarnings
(
"rawtypes"
)
public
interface
TypeCache
{
public
interface
TypeCache
{
enum
TYPE_FILTER
{
CATEGORY
,
SUPERTYPE
,
NOT_SUPERTYPE
}
/**
/**
* @param typeName
* @param typeName
* @return true if the type exists in cache, false otherwise.
* @return true if the type exists in cache, false otherwise.
...
@@ -56,7 +61,7 @@ public interface TypeCache {
...
@@ -56,7 +61,7 @@ public interface TypeCache {
boolean
has
(
DataTypes
.
TypeCategory
typeCategory
,
String
typeName
)
throws
AtlasException
;
boolean
has
(
DataTypes
.
TypeCategory
typeCategory
,
String
typeName
)
throws
AtlasException
;
/**
/**
* @param
n
ame The name of the type.
* @param
typeN
ame The name of the type.
* @return returns non-null type if cached, otherwise null
* @return returns non-null type if cached, otherwise null
* @throws AtlasException
* @throws AtlasException
*/
*/
...
@@ -72,18 +77,16 @@ public interface TypeCache {
...
@@ -72,18 +77,16 @@ public interface TypeCache {
public
IDataType
get
(
DataTypes
.
TypeCategory
typeCategory
,
String
typeName
)
throws
AtlasException
;
public
IDataType
get
(
DataTypes
.
TypeCategory
typeCategory
,
String
typeName
)
throws
AtlasException
;
/**
/**
* @param typeCategory The category of types to filter the returned types. Cannot be null.
*
* The category can be one of TypeCategory.CLASS | TypeCategory.TRAIT |
* @param filter @return
* TypeCategory.STRUCT | TypeCategory.ENUM.
* @return
* @throws AtlasException
* @throws AtlasException
*/
*/
Collection
<
String
>
getTypeNames
(
DataTypes
.
TypeCategory
typeCategory
)
throws
AtlasException
;
Collection
<
String
>
getTypeNames
(
Map
<
TYPE_FILTER
,
String
>
filter
)
throws
AtlasException
;
/**
/**
* This is a convenience API to get the names of all types.
* This is a convenience API to get the names of all types.
*
*
* @see TypeCache#getTypeNames(
org.apache.atlas.typesystem.types.DataTypes.TypeCategory
)
* @see TypeCache#getTypeNames(
Map
)
* @return
* @return
* @throws AtlasException
* @throws AtlasException
*/
*/
...
...
typesystem/src/test/java/org/apache/atlas/typesystem/types/cache/DefaultTypeCacheTest.java
View file @
d934645b
This diff is collapsed.
Click to expand it.
webapp/src/main/java/org/apache/atlas/web/resources/TypesResource.java
View file @
d934645b
...
@@ -23,9 +23,10 @@ import org.apache.atlas.AtlasClient;
...
@@ -23,9 +23,10 @@ import org.apache.atlas.AtlasClient;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.services.MetadataService
;
import
org.apache.atlas.services.MetadataService
;
import
org.apache.atlas.typesystem.exception.TypeExistsException
;
import
org.apache.atlas.typesystem.exception.TypeExistsException
;
import
org.apache.atlas.typesystem.types.
DataTypes
;
import
org.apache.atlas.typesystem.types.
cache.TypeCache
;
import
org.apache.atlas.utils.AtlasPerfTracer
;
import
org.apache.atlas.utils.AtlasPerfTracer
;
import
org.apache.atlas.web.util.Servlets
;
import
org.apache.atlas.web.util.Servlets
;
import
org.apache.commons.lang.StringUtils
;
import
org.codehaus.jettison.json.JSONArray
;
import
org.codehaus.jettison.json.JSONArray
;
import
org.codehaus.jettison.json.JSONException
;
import
org.codehaus.jettison.json.JSONException
;
import
org.codehaus.jettison.json.JSONObject
;
import
org.codehaus.jettison.json.JSONObject
;
...
@@ -36,7 +37,6 @@ import javax.inject.Inject;
...
@@ -36,7 +37,6 @@ import javax.inject.Inject;
import
javax.inject.Singleton
;
import
javax.inject.Singleton
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.ws.rs.Consumes
;
import
javax.ws.rs.Consumes
;
import
javax.ws.rs.DefaultValue
;
import
javax.ws.rs.GET
;
import
javax.ws.rs.GET
;
import
javax.ws.rs.POST
;
import
javax.ws.rs.POST
;
import
javax.ws.rs.PUT
;
import
javax.ws.rs.PUT
;
...
@@ -48,7 +48,9 @@ import javax.ws.rs.WebApplicationException;
...
@@ -48,7 +48,9 @@ import javax.ws.rs.WebApplicationException;
import
javax.ws.rs.core.Context
;
import
javax.ws.rs.core.Context
;
import
javax.ws.rs.core.MediaType
;
import
javax.ws.rs.core.MediaType
;
import
javax.ws.rs.core.Response
;
import
javax.ws.rs.core.Response
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
/**
/**
* This class provides RESTful API for Types.
* This class provides RESTful API for Types.
...
@@ -67,8 +69,6 @@ public class TypesResource {
...
@@ -67,8 +69,6 @@ public class TypesResource {
private
final
MetadataService
metadataService
;
private
final
MetadataService
metadataService
;
static
final
String
TYPE_ALL
=
"all"
;
@Inject
@Inject
public
TypesResource
(
MetadataService
metadataService
)
{
public
TypesResource
(
MetadataService
metadataService
)
{
this
.
metadataService
=
metadataService
;
this
.
metadataService
=
metadataService
;
...
@@ -209,30 +209,33 @@ public class TypesResource {
...
@@ -209,30 +209,33 @@ public class TypesResource {
}
}
/**
/**
* Gets the list of trait type names registered in the type system.
* Return the list of type names in the type system which match the specified filter.
*
* @return list of type names
* @param typeCategory returns types whose category is the given typeCategory
* @param supertype returns types which contain the given supertype
* @param notsupertype returns types which do not contain the given supertype
*
*
* @param type type should be the name of enum
* Its possible to specify combination of these filters in one request and the conditions are combined with AND
* org.apache.atlas.typesystem.types.DataTypes.TypeCategory
* For example, typeCategory = TRAIT && supertype contains 'X' && supertype !contains 'Y'
* Typically, would be one of all, TRAIT, CLASS, ENUM, STRUCT
* If there is no filter, all the types are returned
* @return entity names response payload as json
*/
*/
@GET
@GET
@Produces
(
Servlets
.
JSON_MEDIA_TYPE
)
@Produces
(
Servlets
.
JSON_MEDIA_TYPE
)
public
Response
getTypesByFilter
(
@Context
HttpServletRequest
request
,
public
Response
getTypesByFilter
(
@Context
HttpServletRequest
request
,
@QueryParam
(
"type"
)
String
typeCategory
,
@DefaultValue
(
TYPE_ALL
)
@QueryParam
(
"type"
)
String
type
)
{
@QueryParam
(
"supertype"
)
String
supertype
,
@QueryParam
(
"notsupertype"
)
String
notsupertype
)
{
AtlasPerfTracer
perf
=
null
;
AtlasPerfTracer
perf
=
null
;
try
{
try
{
if
(
AtlasPerfTracer
.
isPerfTraceEnabled
(
PERF_LOG
))
{
if
(
AtlasPerfTracer
.
isPerfTraceEnabled
(
PERF_LOG
))
{
perf
=
AtlasPerfTracer
.
getPerfTracer
(
PERF_LOG
,
"TypesResource.getTypesByFilter("
+
type
+
")"
);
perf
=
AtlasPerfTracer
.
getPerfTracer
(
PERF_LOG
,
"TypesResource.getTypesByFilter("
+
type
Category
+
")"
);
}
}
List
<
String
>
result
;
Map
<
TypeCache
.
TYPE_FILTER
,
String
>
filterMap
=
new
HashMap
<>();
if
(
TYPE_ALL
.
equals
(
type
))
{
addToFilterIfNotEmpty
(
filterMap
,
TypeCache
.
TYPE_FILTER
.
CATEGORY
,
typeCategory
);
result
=
metadataService
.
getTypeNamesList
();
addToFilterIfNotEmpty
(
filterMap
,
TypeCache
.
TYPE_FILTER
.
SUPERTYPE
,
supertype
);
}
else
{
addToFilterIfNotEmpty
(
filterMap
,
TypeCache
.
TYPE_FILTER
.
NOT_SUPERTYPE
,
notsupertype
);
DataTypes
.
TypeCategory
typeCategory
=
DataTypes
.
TypeCategory
.
valueOf
(
type
);
List
<
String
>
result
=
metadataService
.
getTypeNames
(
filterMap
);
result
=
metadataService
.
getTypeNamesByCategory
(
typeCategory
);
}
JSONObject
response
=
new
JSONObject
();
JSONObject
response
=
new
JSONObject
();
response
.
put
(
AtlasClient
.
RESULTS
,
new
JSONArray
(
result
));
response
.
put
(
AtlasClient
.
RESULTS
,
new
JSONArray
(
result
));
...
@@ -241,9 +244,9 @@ public class TypesResource {
...
@@ -241,9 +244,9 @@ public class TypesResource {
return
Response
.
ok
(
response
).
build
();
return
Response
.
ok
(
response
).
build
();
}
catch
(
IllegalArgumentException
|
AtlasException
ie
)
{
}
catch
(
IllegalArgumentException
|
AtlasException
ie
)
{
LOG
.
error
(
"Unsupported typeName while retrieving type list {}"
,
type
);
LOG
.
error
(
"Unsupported typeName while retrieving type list {}"
,
type
Category
);
throw
new
WebApplicationException
(
throw
new
WebApplicationException
(
Servlets
.
getErrorResponse
(
new
Exception
(
"Unsupported type "
+
type
,
ie
),
Response
.
Status
.
BAD_REQUEST
));
Servlets
.
getErrorResponse
(
new
Exception
(
"Unsupported type "
+
type
Category
,
ie
),
Response
.
Status
.
BAD_REQUEST
));
}
catch
(
Throwable
e
)
{
}
catch
(
Throwable
e
)
{
LOG
.
error
(
"Unable to get types list"
,
e
);
LOG
.
error
(
"Unable to get types list"
,
e
);
throw
new
WebApplicationException
(
Servlets
.
getErrorResponse
(
e
,
Response
.
Status
.
INTERNAL_SERVER_ERROR
));
throw
new
WebApplicationException
(
Servlets
.
getErrorResponse
(
e
,
Response
.
Status
.
INTERNAL_SERVER_ERROR
));
...
@@ -251,4 +254,11 @@ public class TypesResource {
...
@@ -251,4 +254,11 @@ public class TypesResource {
AtlasPerfTracer
.
log
(
perf
);
AtlasPerfTracer
.
log
(
perf
);
}
}
}
}
private
void
addToFilterIfNotEmpty
(
Map
<
TypeCache
.
TYPE_FILTER
,
String
>
filterMap
,
TypeCache
.
TYPE_FILTER
filterType
,
String
filterValue
)
{
if
(
StringUtils
.
isNotEmpty
(
filterValue
))
{
filterMap
.
put
(
filterType
,
filterValue
);
}
}
}
}
webapp/src/test/java/org/apache/atlas/web/resources/BaseResourceIT.java
View file @
d934645b
...
@@ -22,7 +22,6 @@ import com.google.common.base.Preconditions;
...
@@ -22,7 +22,6 @@ import com.google.common.base.Preconditions;
import
com.google.common.collect.ImmutableList
;
import
com.google.common.collect.ImmutableList
;
import
com.google.common.collect.ImmutableSet
;
import
com.google.common.collect.ImmutableSet
;
import
com.sun.jersey.api.client.Client
;
import
com.sun.jersey.api.client.Client
;
import
com.sun.jersey.api.client.ClientResponse
;
import
com.sun.jersey.api.client.WebResource
;
import
com.sun.jersey.api.client.WebResource
;
import
com.sun.jersey.api.client.config.DefaultClientConfig
;
import
com.sun.jersey.api.client.config.DefaultClientConfig
;
import
kafka.consumer.ConsumerTimeoutException
;
import
kafka.consumer.ConsumerTimeoutException
;
...
@@ -51,18 +50,14 @@ import org.apache.atlas.typesystem.types.TypeUtils;
...
@@ -51,18 +50,14 @@ import org.apache.atlas.typesystem.types.TypeUtils;
import
org.apache.atlas.typesystem.types.utils.TypesUtil
;
import
org.apache.atlas.typesystem.types.utils.TypesUtil
;
import
org.apache.atlas.utils.AuthenticationUtil
;
import
org.apache.atlas.utils.AuthenticationUtil
;
import
org.apache.atlas.utils.ParamChecker
;
import
org.apache.atlas.utils.ParamChecker
;
import
org.apache.atlas.web.util.Servlets
;
import
org.apache.commons.configuration.Configuration
;
import
org.apache.commons.configuration.Configuration
;
import
org.apache.commons.lang.RandomStringUtils
;
import
org.apache.commons.lang.RandomStringUtils
;
import
org.codehaus.jettison.json.JSONArray
;
import
org.codehaus.jettison.json.JSONArray
;
import
org.codehaus.jettison.json.JSONObject
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
import
org.testng.Assert
;
import
org.testng.Assert
;
import
org.testng.annotations.BeforeClass
;
import
org.testng.annotations.BeforeClass
;
import
javax.ws.rs.HttpMethod
;
import
javax.ws.rs.core.Response
;
import
javax.ws.rs.core.UriBuilder
;
import
javax.ws.rs.core.UriBuilder
;
import
java.util.List
;
import
java.util.List
;
...
@@ -109,19 +104,8 @@ public abstract class BaseResourceIT {
...
@@ -109,19 +104,8 @@ public abstract class BaseResourceIT {
}
}
}
}
protected
void
createType
(
String
typesAsJSON
)
throws
Exception
{
protected
List
<
String
>
createType
(
String
typesAsJSON
)
throws
Exception
{
WebResource
resource
=
service
.
path
(
"api/atlas/types"
);
return
serviceClient
.
createType
(
TypesSerialization
.
fromJson
(
typesAsJSON
));
ClientResponse
clientResponse
=
resource
.
accept
(
Servlets
.
JSON_MEDIA_TYPE
).
type
(
Servlets
.
JSON_MEDIA_TYPE
)
.
method
(
HttpMethod
.
POST
,
ClientResponse
.
class
,
typesAsJSON
);
Assert
.
assertEquals
(
clientResponse
.
getStatus
(),
Response
.
Status
.
CREATED
.
getStatusCode
());
String
responseAsString
=
clientResponse
.
getEntity
(
String
.
class
);
Assert
.
assertNotNull
(
responseAsString
);
JSONObject
response
=
new
JSONObject
(
responseAsString
);
Assert
.
assertNotNull
(
response
.
get
(
"types"
));
Assert
.
assertNotNull
(
response
.
get
(
AtlasClient
.
REQUEST_ID
));
}
}
protected
Id
createInstance
(
Referenceable
referenceable
)
throws
Exception
{
protected
Id
createInstance
(
Referenceable
referenceable
)
throws
Exception
{
...
...
webapp/src/test/java/org/apache/atlas/web/resources/TypesJerseyResourceIT.java
View file @
d934645b
...
@@ -22,7 +22,6 @@ import com.google.common.collect.ImmutableList;
...
@@ -22,7 +22,6 @@ import com.google.common.collect.ImmutableList;
import
com.google.common.collect.ImmutableSet
;
import
com.google.common.collect.ImmutableSet
;
import
com.sun.jersey.api.client.ClientResponse
;
import
com.sun.jersey.api.client.ClientResponse
;
import
com.sun.jersey.api.client.WebResource
;
import
com.sun.jersey.api.client.WebResource
;
import
org.apache.atlas.AtlasClient
;
import
org.apache.atlas.AtlasClient
;
import
org.apache.atlas.AtlasServiceException
;
import
org.apache.atlas.AtlasServiceException
;
import
org.apache.atlas.typesystem.TypesDef
;
import
org.apache.atlas.typesystem.TypesDef
;
...
@@ -47,10 +46,11 @@ import org.testng.annotations.Test;
...
@@ -47,10 +46,11 @@ import org.testng.annotations.Test;
import
javax.ws.rs.HttpMethod
;
import
javax.ws.rs.HttpMethod
;
import
javax.ws.rs.core.Response
;
import
javax.ws.rs.core.Response
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.List
;
import
static
org
.
apache
.
atlas
.
typesystem
.
types
.
utils
.
TypesUtil
.
createOptionalAttrDef
;
import
static
org
.
testng
.
Assert
.
assertEquals
;
import
static
org
.
testng
.
Assert
.
assertEquals
;
import
static
org
.
testng
.
Assert
.
fail
;
import
static
org
.
testng
.
Assert
.
fail
;
...
@@ -126,7 +126,7 @@ public class TypesJerseyResourceIT extends BaseResourceIT {
...
@@ -126,7 +126,7 @@ public class TypesJerseyResourceIT extends BaseResourceIT {
typeDefinition
=
TypesUtil
.
createClassTypeDef
(
typeDefinition
.
typeName
,
typeDefinition
=
TypesUtil
.
createClassTypeDef
(
typeDefinition
.
typeName
,
ImmutableSet
.<
String
>
of
(),
ImmutableSet
.<
String
>
of
(),
TypesUtil
.
createUniqueRequiredAttrDef
(
"name"
,
DataTypes
.
STRING_TYPE
),
TypesUtil
.
createUniqueRequiredAttrDef
(
"name"
,
DataTypes
.
STRING_TYPE
),
TypesUtil
.
createOptionalAttrDef
(
"description"
,
DataTypes
.
STRING_TYPE
));
createOptionalAttrDef
(
"description"
,
DataTypes
.
STRING_TYPE
));
TypesDef
typeDef
=
TypesUtil
.
getTypesDef
(
ImmutableList
.<
EnumTypeDefinition
>
of
(),
TypesDef
typeDef
=
TypesUtil
.
getTypesDef
(
ImmutableList
.<
EnumTypeDefinition
>
of
(),
ImmutableList
.<
StructTypeDefinition
>
of
(),
ImmutableList
.<
HierarchicalTypeDefinition
<
TraitType
>>
of
(),
ImmutableList
.<
StructTypeDefinition
>
of
(),
ImmutableList
.<
HierarchicalTypeDefinition
<
TraitType
>>
of
(),
ImmutableList
.
of
(
typeDefinition
));
ImmutableList
.
of
(
typeDefinition
));
...
@@ -224,6 +224,22 @@ public class TypesJerseyResourceIT extends BaseResourceIT {
...
@@ -224,6 +224,22 @@ public class TypesJerseyResourceIT extends BaseResourceIT {
Assert
.
assertTrue
(
list
.
length
()
>=
traitsAdded
.
length
);
Assert
.
assertTrue
(
list
.
length
()
>=
traitsAdded
.
length
);
}
}
@Test
public
void
testListTypesByFilter
()
throws
Exception
{
AttributeDefinition
attr
=
TypesUtil
.
createOptionalAttrDef
(
"attr"
,
DataTypes
.
STRING_TYPE
);
String
a
=
createType
(
TypesSerialization
.
toJson
(
TypesUtil
.
createClassTypeDef
(
"A"
+
randomString
(),
ImmutableSet
.<
String
>
of
(),
attr
),
false
)).
get
(
0
);
String
a1
=
createType
(
TypesSerialization
.
toJson
(
TypesUtil
.
createClassTypeDef
(
"A1"
+
randomString
(),
ImmutableSet
.
of
(
a
),
attr
),
false
)).
get
(
0
);
String
b
=
createType
(
TypesSerialization
.
toJson
(
TypesUtil
.
createClassTypeDef
(
"B"
+
randomString
(),
ImmutableSet
.<
String
>
of
(),
attr
),
false
)).
get
(
0
);
String
c
=
createType
(
TypesSerialization
.
toJson
(
TypesUtil
.
createClassTypeDef
(
"C"
+
randomString
(),
ImmutableSet
.
of
(
a
,
b
),
attr
),
false
)).
get
(
0
);
List
<
String
>
results
=
serviceClient
.
listTypes
(
DataTypes
.
TypeCategory
.
CLASS
,
a
,
b
);
assertEquals
(
results
,
Arrays
.
asList
(
a1
),
"Results: "
+
results
);
}
private
String
[]
addTraits
()
throws
Exception
{
private
String
[]
addTraits
()
throws
Exception
{
String
[]
traitNames
=
{
"class_trait"
,
"secure_trait"
,
"pii_trait"
,
"ssn_trait"
,
"salary_trait"
,
"sox_trait"
,};
String
[]
traitNames
=
{
"class_trait"
,
"secure_trait"
,
"pii_trait"
,
"ssn_trait"
,
"salary_trait"
,
"sox_trait"
,};
...
@@ -250,9 +266,9 @@ public class TypesJerseyResourceIT extends BaseResourceIT {
...
@@ -250,9 +266,9 @@ public class TypesJerseyResourceIT extends BaseResourceIT {
.
createClassTypeDef
(
"table"
,
ImmutableSet
.<
String
>
of
(),
.
createClassTypeDef
(
"table"
,
ImmutableSet
.<
String
>
of
(),
TypesUtil
.
createUniqueRequiredAttrDef
(
"name"
,
DataTypes
.
STRING_TYPE
),
TypesUtil
.
createUniqueRequiredAttrDef
(
"name"
,
DataTypes
.
STRING_TYPE
),
TypesUtil
.
createRequiredAttrDef
(
"description"
,
DataTypes
.
STRING_TYPE
),
TypesUtil
.
createRequiredAttrDef
(
"description"
,
DataTypes
.
STRING_TYPE
),
TypesUtil
.
createOptionalAttrDef
(
"columnNames"
,
DataTypes
.
arrayTypeName
(
DataTypes
.
STRING_TYPE
)),
createOptionalAttrDef
(
"columnNames"
,
DataTypes
.
arrayTypeName
(
DataTypes
.
STRING_TYPE
)),
TypesUtil
.
createOptionalAttrDef
(
"created"
,
DataTypes
.
DATE_TYPE
),
TypesUtil
createOptionalAttrDef
(
"created"
,
DataTypes
.
DATE_TYPE
),
.
createOptionalAttrDef
(
"parameters"
,
createOptionalAttrDef
(
"parameters"
,
DataTypes
.
mapTypeName
(
DataTypes
.
STRING_TYPE
,
DataTypes
.
STRING_TYPE
)),
DataTypes
.
mapTypeName
(
DataTypes
.
STRING_TYPE
,
DataTypes
.
STRING_TYPE
)),
TypesUtil
.
createRequiredAttrDef
(
"type"
,
DataTypes
.
STRING_TYPE
),
TypesUtil
.
createRequiredAttrDef
(
"type"
,
DataTypes
.
STRING_TYPE
),
new
AttributeDefinition
(
"database"
,
"database"
,
Multiplicity
.
REQUIRED
,
false
,
"database"
));
new
AttributeDefinition
(
"database"
,
"database"
,
Multiplicity
.
REQUIRED
,
false
,
"database"
));
...
...
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