Commit 5f508c97 by Jeff Hagelberg

ATLAS-746 : After updating a set of entities, response contains only the first entity definition

parent acfe9a48
...@@ -105,7 +105,8 @@ public class DefaultTypeSystem implements AtlasTypeSystem { ...@@ -105,7 +105,8 @@ public class DefaultTypeSystem implements AtlasTypeSystem {
entity.set(TaxonomyResourceProvider.NAMESPACE_ATTRIBUTE_NAME, TaxonomyResourceProvider.TAXONOMY_NS); entity.set(TaxonomyResourceProvider.NAMESPACE_ATTRIBUTE_NAME, TaxonomyResourceProvider.TAXONOMY_NS);
ITypedReferenceableInstance typedInstance = metadataService.getTypedReferenceableInstance(entity); ITypedReferenceableInstance typedInstance = metadataService.getTypedReferenceableInstance(entity);
final List<String> entities = metadataService.createEntities(Collections.singletonList(typedInstance).toArray(new ITypedReferenceableInstance[1])); ITypedReferenceableInstance[] entitiesToCreate = Collections.singletonList(typedInstance).toArray(new ITypedReferenceableInstance[1]);
final List<String> entities = metadataService.createEntities(entitiesToCreate).getCreatedEntities();
return entities != null && entities.size() > 0 ? entities.get(0) : null; return entities != null && entities.size() > 0 ? entities.get(0) : null;
} catch (EntityExistsException e) { } catch (EntityExistsException e) {
throw new ResourceAlreadyExistsException( throw new ResourceAlreadyExistsException(
......
...@@ -17,15 +17,19 @@ ...@@ -17,15 +17,19 @@
*/ */
package org.apache.atlas; package org.apache.atlas;
import com.google.common.annotations.VisibleForTesting; import static org.apache.atlas.security.SecurityProperties.TLS_ENABLED;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientHandlerException; import java.io.IOException;
import com.sun.jersey.api.client.ClientResponse; import java.net.ConnectException;
import com.sun.jersey.api.client.WebResource; import java.util.List;
import com.sun.jersey.api.client.config.DefaultClientConfig; import java.util.Map;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
import com.sun.jersey.api.json.JSONConfiguration; import javax.ws.rs.HttpMethod;
import com.sun.jersey.client.urlconnection.URLConnectionClientHandler; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import org.apache.atlas.model.metrics.AtlasMetrics; import org.apache.atlas.model.metrics.AtlasMetrics;
import org.apache.atlas.security.SecureClientUtils; import org.apache.atlas.security.SecureClientUtils;
import org.apache.atlas.type.AtlasType; import org.apache.atlas.type.AtlasType;
...@@ -38,17 +42,16 @@ import org.codehaus.jettison.json.JSONObject; ...@@ -38,17 +42,16 @@ import org.codehaus.jettison.json.JSONObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.ws.rs.HttpMethod; import com.google.common.annotations.VisibleForTesting;
import javax.ws.rs.core.MediaType; import com.sun.jersey.api.client.Client;
import javax.ws.rs.core.MultivaluedMap; import com.sun.jersey.api.client.ClientHandlerException;
import javax.ws.rs.core.Response; import com.sun.jersey.api.client.ClientResponse;
import javax.ws.rs.core.UriBuilder; import com.sun.jersey.api.client.GenericType;
import java.io.IOException; import com.sun.jersey.api.client.WebResource;
import java.net.ConnectException; import com.sun.jersey.api.client.config.DefaultClientConfig;
import java.util.List; import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
import java.util.Map; import com.sun.jersey.api.json.JSONConfiguration;
import com.sun.jersey.client.urlconnection.URLConnectionClientHandler;
import static org.apache.atlas.security.SecurityProperties.TLS_ENABLED;
public abstract class AtlasBaseClient { public abstract class AtlasBaseClient {
public static final String BASE_URI = "api/atlas/"; public static final String BASE_URI = "api/atlas/";
...@@ -277,6 +280,14 @@ public abstract class AtlasBaseClient { ...@@ -277,6 +280,14 @@ public abstract class AtlasBaseClient {
} }
protected <T> T callAPIWithResource(APIInfo api, WebResource resource, Object requestObject, Class<T> responseType) throws AtlasServiceException { protected <T> T callAPIWithResource(APIInfo api, WebResource resource, Object requestObject, Class<T> responseType) throws AtlasServiceException {
GenericType<T> genericType = null;
if(responseType != null) {
genericType = new GenericType<>(responseType);
}
return callAPIWithResource(api, resource, requestObject, genericType);
}
protected <T> T callAPIWithResource(APIInfo api, WebResource resource, Object requestObject, GenericType<T> responseType) throws AtlasServiceException {
ClientResponse clientResponse = null; ClientResponse clientResponse = null;
int i = 0; int i = 0;
do { do {
...@@ -297,7 +308,7 @@ public abstract class AtlasBaseClient { ...@@ -297,7 +308,7 @@ public abstract class AtlasBaseClient {
return null; return null;
} }
try { try {
if (responseType == JSONObject.class) { if (responseType.getRawClass() == JSONObject.class) {
String stringEntity = clientResponse.getEntity(String.class); String stringEntity = clientResponse.getEntity(String.class);
try { try {
JSONObject jsonObject = new JSONObject(stringEntity); JSONObject jsonObject = new JSONObject(stringEntity);
...@@ -419,6 +430,12 @@ public abstract class AtlasBaseClient { ...@@ -419,6 +430,12 @@ public abstract class AtlasBaseClient {
return callAPIWithResource(api, getResource(api, params), requestObject, responseType); return callAPIWithResource(api, getResource(api, params), requestObject, responseType);
} }
public <T> T callAPI(APIInfo api, Object requestObject, GenericType<T> responseType, String... params)
throws AtlasServiceException {
return callAPIWithResource(api, getResource(api, params), requestObject, responseType);
}
public <T> T callAPI(APIInfo api, Object requestBody, Class<T> responseType, public <T> T callAPI(APIInfo api, Object requestBody, Class<T> responseType,
MultivaluedMap<String, String> queryParams, String... params) throws AtlasServiceException { MultivaluedMap<String, String> queryParams, String... params) throws AtlasServiceException {
WebResource resource = getResource(api, queryParams, params); WebResource resource = getResource(api, queryParams, params);
...@@ -431,6 +448,12 @@ public abstract class AtlasBaseClient { ...@@ -431,6 +448,12 @@ public abstract class AtlasBaseClient {
return callAPIWithResource(api, resource, null, responseType); return callAPIWithResource(api, resource, null, responseType);
} }
public <T> T callAPI(APIInfo api, GenericType<T> responseType, MultivaluedMap<String, String> queryParams, String... params)
throws AtlasServiceException {
WebResource resource = getResource(api, queryParams, params);
return callAPIWithResource(api, resource, null, responseType);
}
protected WebResource getResource(APIInfo api, String... pathParams) { protected WebResource getResource(APIInfo api, String... pathParams) {
return getResource(service, api, pathParams); return getResource(service, api, pathParams);
} }
......
...@@ -61,6 +61,7 @@ public class AtlasClient extends AtlasBaseClient { ...@@ -61,6 +61,7 @@ public class AtlasClient extends AtlasBaseClient {
public static final String TYPENAME = "typeName"; public static final String TYPENAME = "typeName";
public static final String GUID = "GUID"; public static final String GUID = "GUID";
public static final String ENTITIES = "entities"; public static final String ENTITIES = "entities";
public static final String GUID_ASSIGNMENTS = "guidAssignments";
public static final String DEFINITION = "definition"; public static final String DEFINITION = "definition";
public static final String ERROR = "error"; public static final String ERROR = "error";
...@@ -616,7 +617,7 @@ public class AtlasClient extends AtlasBaseClient { ...@@ -616,7 +617,7 @@ public class AtlasClient extends AtlasBaseClient {
/** /**
* Delete the specified entities from the repository * Delete the specified entities from the repository
* *
* @param guids guids of entities to delete * @param guids guids of entities to delete
* @return List of entity ids updated/deleted * @return List of entity ids updated/deleted
* @throws AtlasServiceException * @throws AtlasServiceException
......
...@@ -17,29 +17,32 @@ ...@@ -17,29 +17,32 @@
*/ */
package org.apache.atlas; package org.apache.atlas;
import com.google.common.annotations.VisibleForTesting; import java.util.HashMap;
import com.sun.jersey.api.client.WebResource; import java.util.List;
import com.sun.jersey.core.util.MultivaluedMapImpl; import java.util.Map;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import org.apache.atlas.model.SearchFilter; import org.apache.atlas.model.SearchFilter;
import org.apache.atlas.model.instance.AtlasClassification; import org.apache.atlas.model.instance.AtlasClassification;
import org.apache.atlas.model.instance.AtlasClassification.AtlasClassifications; import org.apache.atlas.model.instance.AtlasClassification.AtlasClassifications;
import org.apache.atlas.model.instance.AtlasEntity; import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasEntity.AtlasEntities;
import org.apache.atlas.model.instance.AtlasEntityWithAssociations; import org.apache.atlas.model.instance.AtlasEntityWithAssociations;
import org.apache.atlas.model.instance.EntityMutationResponse; import org.apache.atlas.model.instance.EntityMutationResponse;
import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.Configuration;
import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.UserGroupInformation;
import javax.ws.rs.HttpMethod; import com.google.common.annotations.VisibleForTesting;
import javax.ws.rs.core.MultivaluedMap; import com.sun.jersey.api.client.GenericType;
import javax.ws.rs.core.Response; import com.sun.jersey.api.client.WebResource;
import java.util.HashMap; import com.sun.jersey.core.util.MultivaluedMapImpl;
import java.util.List;
import java.util.Map;
import static org.apache.atlas.model.instance.AtlasEntity.AtlasEntities;
public class AtlasEntitiesClientV2 extends AtlasBaseClient { public class AtlasEntitiesClientV2 extends AtlasBaseClient {
private static final GenericType<List<AtlasEntityWithAssociations>> ENTITY_WITH_ASSOCIATIONS_LIST_TYPE = new GenericType<List<AtlasEntityWithAssociations>>(){};
public static final String ENTITY_API = BASE_URI + "v2/entity/"; public static final String ENTITY_API = BASE_URI + "v2/entity/";
public static final String ENTITIES_API = BASE_URI + "v2/entities/"; public static final String ENTITIES_API = BASE_URI + "v2/entities/";
...@@ -84,22 +87,25 @@ public class AtlasEntitiesClientV2 extends AtlasBaseClient { ...@@ -84,22 +87,25 @@ public class AtlasEntitiesClientV2 extends AtlasBaseClient {
super(service, configuration); super(service, configuration);
} }
public AtlasEntity getEntityByGuid(String guid) throws AtlasServiceException { public List<AtlasEntityWithAssociations> getEntityByGuid(String guid) throws AtlasServiceException {
return callAPI(GET_ENTITY_BY_GUID, null, AtlasEntity.class, guid);
return callAPI(GET_ENTITY_BY_GUID, null, ENTITY_WITH_ASSOCIATIONS_LIST_TYPE, guid);
} }
public AtlasEntities getEntityByGuids(List<String> guids) throws AtlasServiceException { public AtlasEntities getEntityByGuids(List<String> guids) throws AtlasServiceException {
return callAPI(GET_ENTITY_BY_GUID, AtlasEntities.class, "guid", guids); return callAPI(GET_ENTITY_BY_GUID, AtlasEntities.class, "guid", guids);
} }
public AtlasEntityWithAssociations getEntityWithAssociationByGuid(String guid) throws AtlasServiceException { public List<AtlasEntityWithAssociations> getEntityWithAssociationByGuid(String guid) throws AtlasServiceException {
return callAPI(formatPathForPathParams(GET_ENTITY_WITH_ASSOCIATION_BY_GUID, guid), null, AtlasEntityWithAssociations.class);
return callAPI(formatPathForPathParams(GET_ENTITY_WITH_ASSOCIATION_BY_GUID, guid), null, ENTITY_WITH_ASSOCIATIONS_LIST_TYPE);
} }
public AtlasEntity getEntityByAttribute(String type, String attribute, String value) throws AtlasServiceException { public List<AtlasEntityWithAssociations> getEntityByAttribute(String type, String attribute, String value) throws AtlasServiceException {
MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl();
queryParams.add("value", value); queryParams.add("value", value);
return callAPI(formatPathForPathParams(GET_ENTITY_BY_ATTRIBUTE, type, attribute), AtlasEntity.class, queryParams); return callAPI(formatPathForPathParams(GET_ENTITY_BY_ATTRIBUTE, type, attribute), ENTITY_WITH_ASSOCIATIONS_LIST_TYPE, queryParams);
} }
public EntityMutationResponse updateEntityByAttribute(String type, String attribute, String value, AtlasEntity entity) throws AtlasServiceException { public EntityMutationResponse updateEntityByAttribute(String type, String attribute, String value, AtlasEntity entity) throws AtlasServiceException {
...@@ -115,11 +121,11 @@ public class AtlasEntitiesClientV2 extends AtlasBaseClient { ...@@ -115,11 +121,11 @@ public class AtlasEntitiesClientV2 extends AtlasBaseClient {
} }
public EntityMutationResponse createEntity(final AtlasEntity atlasEntity) throws AtlasServiceException { public EntityMutationResponse createEntity(final AtlasEntity atlasEntity) throws AtlasServiceException {
return callAPI(CREATE_ENTITY, new HashMap<String, AtlasEntity>() {{ put(atlasEntity.getGuid(), atlasEntity); }}, EntityMutationResponse.class); return callAPI(CREATE_ENTITY, new HashMap<String, AtlasEntity>(1) {{ put(atlasEntity.getGuid(), atlasEntity); }}, EntityMutationResponse.class);
} }
public EntityMutationResponse updateEntity(final AtlasEntity atlasEntity) throws AtlasServiceException { public EntityMutationResponse updateEntity(final AtlasEntity atlasEntity) throws AtlasServiceException {
return callAPI(UPDATE_ENTITY, new HashMap<String, AtlasEntity>() {{ put(atlasEntity.getGuid(), atlasEntity); }}, EntityMutationResponse.class); return callAPI(UPDATE_ENTITY, new HashMap<String, AtlasEntity>(1) {{ put(atlasEntity.getGuid(), atlasEntity); }}, EntityMutationResponse.class);
} }
public AtlasEntity deleteEntityByGuid(String guid) throws AtlasServiceException { public AtlasEntity deleteEntityByGuid(String guid) throws AtlasServiceException {
...@@ -135,7 +141,7 @@ public class AtlasEntitiesClientV2 extends AtlasBaseClient { ...@@ -135,7 +141,7 @@ public class AtlasEntitiesClientV2 extends AtlasBaseClient {
} }
public void addClassifications(String guid, List<AtlasClassification> classifications) throws AtlasServiceException { public void addClassifications(String guid, List<AtlasClassification> classifications) throws AtlasServiceException {
callAPI(formatPathForPathParams(ADD_CLASSIFICATIONS, guid), classifications, null, (String[]) null); callAPI(formatPathForPathParams(ADD_CLASSIFICATIONS, guid), classifications, (Class<?>)null, (String[]) null);
} }
public void updateClassifications(String guid, List<AtlasClassification> classifications) throws AtlasServiceException { public void updateClassifications(String guid, List<AtlasClassification> classifications) throws AtlasServiceException {
...@@ -156,11 +162,24 @@ public class AtlasEntitiesClientV2 extends AtlasBaseClient { ...@@ -156,11 +162,24 @@ public class AtlasEntitiesClientV2 extends AtlasBaseClient {
return null; return null;
} }
public List<AtlasEntity> createEntities(Map<String, AtlasEntity> atlasEntities) throws AtlasServiceException { public EntityMutationResponse createEntities(List<AtlasEntity> atlasEntities) throws AtlasServiceException {
return (List<AtlasEntity>)callAPI(CREATE_ENTITIES, atlasEntities, List.class);
return callAPI(CREATE_ENTITIES, entityListToMap(atlasEntities), EntityMutationResponse.class);
}
private Map<String, AtlasEntity> entityListToMap(List<AtlasEntity> atlasEntities) {
Map<String,AtlasEntity> toSend = new HashMap<String, AtlasEntity>(atlasEntities.size());
for(AtlasEntity entity : atlasEntities) {
toSend.put(entity.getGuid(), entity);
}
return toSend;
}
public EntityMutationResponse updateEntities(List<AtlasEntity> atlasEntities) throws AtlasServiceException {
return callAPI(UPDATE_ENTITIES, entityListToMap(atlasEntities), EntityMutationResponse.class);
} }
public List<AtlasEntity> updateEntities(Map<String, AtlasEntity> atlasEntities) throws AtlasServiceException { public AtlasEntity.AtlasEntities searchEntities(SearchFilter searchFilter) throws AtlasServiceException {
return (List<AtlasEntity>)callAPI(UPDATE_ENTITIES, atlasEntities, List.class); return callAPI(GET_ENTITIES, AtlasEntity.AtlasEntities.class, searchFilter.getParams());
} }
} }
/**
* 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;
import java.util.Collections;
import java.util.List;
import org.apache.atlas.AtlasClient.EntityResult;
import org.apache.atlas.model.instance.GuidMapping;
/**
* Result from creating or updating entities.
*/
public class CreateUpdateEntitiesResult {
/**
* Guid mapping for the entities that were created/updated
*/
private GuidMapping guidMapping;
/**
* Entity result
*/
private EntityResult entityResult;
/**
* Gets the guid mapping
*/
public GuidMapping getGuidMapping() {
return guidMapping;
}
/**
* Sets the guid mapping
*/
public void setGuidMapping(GuidMapping guidMapping) {
this.guidMapping = guidMapping;
}
/**
* Gets the entity result
*/
public EntityResult getEntityResult() {
return entityResult;
}
/**
* Sets the entity result
*/
public void setEntityResult(EntityResult entityResult) {
this.entityResult = entityResult;
}
/**
* Deserializes the given json into an instance of
* CreateUpdateEntitiesResult.
*
* @param json
* the (unmodified) json that comes back from Atlas.
* @return
* @throws AtlasServiceException
*/
public static CreateUpdateEntitiesResult fromJson(String json) throws AtlasServiceException {
GuidMapping guidMapping = GuidMapping.fromString(json);
EntityResult entityResult = EntityResult.fromString(json);
CreateUpdateEntitiesResult result = new CreateUpdateEntitiesResult();
result.setEntityResult(entityResult);
result.setGuidMapping(guidMapping);
return result;
}
/**
* Convenience method to get the guids of the created entities from
* the EntityResult.
*/
public List<String> getCreatedEntities() {
if(entityResult == null) {
return Collections.emptyList();
}
return getEntityResult().getCreatedEntities();
}
/**
* Convenience method to get the guids of the updated entities from
* the EntityResult.
*/
public List<String> getUpdatedEntities() {
if(entityResult == null) {
return Collections.emptyList();
}
return getEntityResult().getUpdateEntities();
}
/**
* Convenience method to get the guids of the deleted entities
* from the EntityResult.
*/
public List<String> getDeletedEntities() {
if (entityResult == null) {
return Collections.emptyList();
}
return getEntityResult().getDeletedEntities();
}
}
...@@ -18,25 +18,24 @@ ...@@ -18,25 +18,24 @@
package org.apache.atlas.model.instance; package org.apache.atlas.model.instance;
import org.apache.atlas.model.typedef.AtlasBaseTypeDef; import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
import org.apache.commons.collections.CollectionUtils; import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
import org.apache.commons.collections.MapUtils;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE; import javax.xml.bind.annotation.XmlAccessType;
import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY; import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.annotate.JsonSerialize;
@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE) @JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
...@@ -46,6 +45,7 @@ import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONL ...@@ -46,6 +45,7 @@ import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONL
public class EntityMutationResponse { public class EntityMutationResponse {
Map<EntityMutations.EntityOperation, List<AtlasEntityHeader>> entitiesMutated; Map<EntityMutations.EntityOperation, List<AtlasEntityHeader>> entitiesMutated;
Map<String,String> guidAssignments;
public EntityMutationResponse() { public EntityMutationResponse() {
} }
...@@ -148,16 +148,25 @@ public class EntityMutationResponse { ...@@ -148,16 +148,25 @@ public class EntityMutationResponse {
if (this == o) return true; if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
EntityMutationResponse that = (EntityMutationResponse) o; EntityMutationResponse that = (EntityMutationResponse) o;
return Objects.equals(entitiesMutated, that.entitiesMutated); return Objects.equals(entitiesMutated, that.entitiesMutated) &&
Objects.equals(guidAssignments, that.guidAssignments);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(entitiesMutated); return Objects.hash(entitiesMutated, guidAssignments);
} }
@Override @Override
public String toString() { public String toString() {
return toString(new StringBuilder()).toString(); return toString(new StringBuilder()).toString();
} }
public void setGuidAssignments(Map<String,String> guidAssignments) {
this.guidAssignments = guidAssignments;
}
public Map<String,String> getGuidAssignments() {
return guidAssignments;
}
} }
/**
* 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.model.instance;
import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
import java.util.Map;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
/**
* This stores a mapping of guid assignments that were made during the processing
* of a create or update entity request.
*.
*/
@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown=true)
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public class GuidMapping {
@JsonIgnore
private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
private Map<String,String> guidAssignments;
public GuidMapping() {
}
public GuidMapping(Map<String,String> guidAssignments) {
this.guidAssignments = guidAssignments;
}
public Map<String,String> getGuidAssignments() {
return guidAssignments;
}
public void setGuidAssignments(Map<String,String> guidAssignments) {
this.guidAssignments = guidAssignments;
}
/**
* Converts the GuidMapping to json
*/
@Override
public String toString() {
return gson.toJson(this);
}
@JsonIgnore
public static GuidMapping fromString(String json) {
return gson.fromJson(json, GuidMapping.class);
}
}
\ No newline at end of file
...@@ -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-746 After updating a set of entities, response contains only the first entity definition (jnhagelb)
ATLAS-1510 Consolidate/batch calls to GraphBackedTypeStore.findVertex() (jnhagelb) ATLAS-1510 Consolidate/batch calls to GraphBackedTypeStore.findVertex() (jnhagelb)
ATLAS-1388 Cache entities that are created/updated (jnhagelb) ATLAS-1388 Cache entities that are created/updated (jnhagelb)
ATLAS-1369 Optimize Gremlin queries generated by DSL translator (jnhagelb) ATLAS-1369 Optimize Gremlin queries generated by DSL translator (jnhagelb)
......
...@@ -20,6 +20,7 @@ package org.apache.atlas.repository; ...@@ -20,6 +20,7 @@ package org.apache.atlas.repository;
import org.apache.atlas.AtlasClient; import org.apache.atlas.AtlasClient;
import org.apache.atlas.AtlasException; import org.apache.atlas.AtlasException;
import org.apache.atlas.CreateUpdateEntitiesResult;
import org.apache.atlas.typesystem.ITypedReferenceableInstance; import org.apache.atlas.typesystem.ITypedReferenceableInstance;
import org.apache.atlas.typesystem.ITypedStruct; import org.apache.atlas.typesystem.ITypedStruct;
import org.apache.atlas.typesystem.exception.EntityExistsException; import org.apache.atlas.typesystem.exception.EntityExistsException;
...@@ -91,11 +92,11 @@ public interface MetadataRepository { ...@@ -91,11 +92,11 @@ public interface MetadataRepository {
* Creates an entity definition (instance) corresponding to a given type. * Creates an entity definition (instance) corresponding to a given type.
* *
* @param entities entity (typed instance) * @param entities entity (typed instance)
* @return a globally unique identifier * @return CreateOrUpdateEntitiesResult with the guids of the entities that were created
* @throws RepositoryException * @throws RepositoryException
* @throws EntityExistsException * @throws EntityExistsException
*/ */
List<String> createEntities(ITypedReferenceableInstance... entities) throws RepositoryException, EntityExistsException; CreateUpdateEntitiesResult createEntities(ITypedReferenceableInstance... entities) throws RepositoryException, EntityExistsException;
/** /**
* Fetch the complete definition of an entity given its GUID. * Fetch the complete definition of an entity given its GUID.
...@@ -166,13 +167,13 @@ public interface MetadataRepository { ...@@ -166,13 +167,13 @@ public interface MetadataRepository {
* Adds/Updates the property to the entity that corresponds to the GUID * Adds/Updates the property to the entity that corresponds to the GUID
* Supports only primitive attribute/Class Id updations. * Supports only primitive attribute/Class Id updations.
*/ */
AtlasClient.EntityResult updatePartial(ITypedReferenceableInstance entity) throws RepositoryException; CreateUpdateEntitiesResult updatePartial(ITypedReferenceableInstance entity) throws RepositoryException;
/** /**
* Adds the property to the entity that corresponds to the GUID * Adds the property to the entity that corresponds to the GUID
* @param entitiesToBeUpdated The entities to be updated * @param entitiesToBeUpdated The entities to be updated
*/ */
AtlasClient.EntityResult updateEntities(ITypedReferenceableInstance... entitiesToBeUpdated) throws RepositoryException; CreateUpdateEntitiesResult updateEntities(ITypedReferenceableInstance... entitiesToBeUpdated) throws RepositoryException;
/** /**
* Returns the entity for the given type and qualified name * Returns the entity for the given type and qualified name
......
...@@ -27,8 +27,10 @@ import java.util.Map; ...@@ -27,8 +27,10 @@ import java.util.Map;
import org.apache.atlas.AtlasClient; import org.apache.atlas.AtlasClient;
import org.apache.atlas.AtlasException; import org.apache.atlas.AtlasException;
import org.apache.atlas.CreateUpdateEntitiesResult;
import org.apache.atlas.GraphTransaction; import org.apache.atlas.GraphTransaction;
import org.apache.atlas.RequestContext; import org.apache.atlas.RequestContext;
import org.apache.atlas.model.instance.GuidMapping;
import org.apache.atlas.repository.Constants; import org.apache.atlas.repository.Constants;
import org.apache.atlas.repository.MetadataRepository; import org.apache.atlas.repository.MetadataRepository;
import org.apache.atlas.repository.RepositoryException; import org.apache.atlas.repository.RepositoryException;
...@@ -143,7 +145,7 @@ public class GraphBackedMetadataRepository implements MetadataRepository { ...@@ -143,7 +145,7 @@ public class GraphBackedMetadataRepository implements MetadataRepository {
@Override @Override
@GraphTransaction @GraphTransaction
public List<String> createEntities(ITypedReferenceableInstance... entities) throws RepositoryException, public CreateUpdateEntitiesResult createEntities(ITypedReferenceableInstance... entities) throws RepositoryException,
EntityExistsException { EntityExistsException {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("adding entities={}", entities); LOG.debug("adding entities={}", entities);
...@@ -152,7 +154,13 @@ public class GraphBackedMetadataRepository implements MetadataRepository { ...@@ -152,7 +154,13 @@ public class GraphBackedMetadataRepository implements MetadataRepository {
try { try {
TypedInstanceToGraphMapper instanceToGraphMapper = new TypedInstanceToGraphMapper(graphToInstanceMapper, deleteHandler); TypedInstanceToGraphMapper instanceToGraphMapper = new TypedInstanceToGraphMapper(graphToInstanceMapper, deleteHandler);
instanceToGraphMapper.mapTypedInstanceToGraph(TypedInstanceToGraphMapper.Operation.CREATE, entities); instanceToGraphMapper.mapTypedInstanceToGraph(TypedInstanceToGraphMapper.Operation.CREATE, entities);
return RequestContext.get().getCreatedEntityIds(); List<String> createdGuids = RequestContext.get().getCreatedEntityIds();
CreateUpdateEntitiesResult result = new CreateUpdateEntitiesResult();
AtlasClient.EntityResult entityResult = new AtlasClient.EntityResult(createdGuids, null, null);
GuidMapping mapping = instanceToGraphMapper.createGuidMapping();
result.setEntityResult(entityResult);
result.setGuidMapping(mapping);
return result;
} catch (EntityExistsException e) { } catch (EntityExistsException e) {
throw e; throw e;
} catch (AtlasException e) { } catch (AtlasException e) {
...@@ -360,7 +368,7 @@ public class GraphBackedMetadataRepository implements MetadataRepository { ...@@ -360,7 +368,7 @@ public class GraphBackedMetadataRepository implements MetadataRepository {
@Override @Override
@GraphTransaction @GraphTransaction
public AtlasClient.EntityResult updateEntities(ITypedReferenceableInstance... entitiesUpdated) throws RepositoryException { public CreateUpdateEntitiesResult updateEntities(ITypedReferenceableInstance... entitiesUpdated) throws RepositoryException {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("updating entity {}", entitiesUpdated); LOG.debug("updating entity {}", entitiesUpdated);
} }
...@@ -369,8 +377,12 @@ public class GraphBackedMetadataRepository implements MetadataRepository { ...@@ -369,8 +377,12 @@ public class GraphBackedMetadataRepository implements MetadataRepository {
TypedInstanceToGraphMapper instanceToGraphMapper = new TypedInstanceToGraphMapper(graphToInstanceMapper, deleteHandler); TypedInstanceToGraphMapper instanceToGraphMapper = new TypedInstanceToGraphMapper(graphToInstanceMapper, deleteHandler);
instanceToGraphMapper.mapTypedInstanceToGraph(TypedInstanceToGraphMapper.Operation.UPDATE_FULL, instanceToGraphMapper.mapTypedInstanceToGraph(TypedInstanceToGraphMapper.Operation.UPDATE_FULL,
entitiesUpdated); entitiesUpdated);
CreateUpdateEntitiesResult result = new CreateUpdateEntitiesResult();
RequestContext requestContext = RequestContext.get(); RequestContext requestContext = RequestContext.get();
return createEntityResultFromContext(requestContext); result.setEntityResult(createEntityResultFromContext(requestContext));
GuidMapping mapping = instanceToGraphMapper.createGuidMapping();
result.setGuidMapping(mapping);
return result;
} catch (AtlasException e) { } catch (AtlasException e) {
throw new RepositoryException(e); throw new RepositoryException(e);
} }
...@@ -378,7 +390,7 @@ public class GraphBackedMetadataRepository implements MetadataRepository { ...@@ -378,7 +390,7 @@ public class GraphBackedMetadataRepository implements MetadataRepository {
@Override @Override
@GraphTransaction @GraphTransaction
public AtlasClient.EntityResult updatePartial(ITypedReferenceableInstance entity) throws RepositoryException { public CreateUpdateEntitiesResult updatePartial(ITypedReferenceableInstance entity) throws RepositoryException {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("updating entity {}", entity); LOG.debug("updating entity {}", entity);
} }
...@@ -387,7 +399,11 @@ public class GraphBackedMetadataRepository implements MetadataRepository { ...@@ -387,7 +399,11 @@ public class GraphBackedMetadataRepository implements MetadataRepository {
TypedInstanceToGraphMapper instanceToGraphMapper = new TypedInstanceToGraphMapper(graphToInstanceMapper, deleteHandler); TypedInstanceToGraphMapper instanceToGraphMapper = new TypedInstanceToGraphMapper(graphToInstanceMapper, deleteHandler);
instanceToGraphMapper.mapTypedInstanceToGraph(TypedInstanceToGraphMapper.Operation.UPDATE_PARTIAL, entity); instanceToGraphMapper.mapTypedInstanceToGraph(TypedInstanceToGraphMapper.Operation.UPDATE_PARTIAL, entity);
RequestContext requestContext = RequestContext.get(); RequestContext requestContext = RequestContext.get();
return createEntityResultFromContext(requestContext); CreateUpdateEntitiesResult result = new CreateUpdateEntitiesResult();
GuidMapping mapping = instanceToGraphMapper.createGuidMapping();
result.setEntityResult(createEntityResultFromContext(requestContext));
result.setGuidMapping(mapping);
return result;
} catch (AtlasException e) { } catch (AtlasException e) {
throw new RepositoryException(e); throw new RepositoryException(e);
} }
......
...@@ -32,6 +32,7 @@ import java.util.Set; ...@@ -32,6 +32,7 @@ import java.util.Set;
import org.apache.atlas.AtlasException; import org.apache.atlas.AtlasException;
import org.apache.atlas.RequestContext; import org.apache.atlas.RequestContext;
import org.apache.atlas.model.instance.GuidMapping;
import org.apache.atlas.repository.Constants; import org.apache.atlas.repository.Constants;
import org.apache.atlas.repository.RepositoryException; import org.apache.atlas.repository.RepositoryException;
import org.apache.atlas.repository.graphdb.AtlasEdge; import org.apache.atlas.repository.graphdb.AtlasEdge;
...@@ -847,4 +848,16 @@ public final class TypedInstanceToGraphMapper { ...@@ -847,4 +848,16 @@ public final class TypedInstanceToGraphMapper {
context.cache(instance); context.cache(instance);
} }
} }
}
public GuidMapping createGuidMapping() {
Map<String,String> mapping = new HashMap<>(idToVertexMap.size());
for(Map.Entry<Id, AtlasVertex> entry : idToVertexMap.entrySet()) {
Id id = entry.getKey();
if (id.isUnassigned()) {
AtlasVertex classVertex = entry.getValue();
mapping.put(id._getId(), GraphHelper.getGuid(classVertex));
}
}
return new GuidMapping(mapping);
}
}
\ No newline at end of file
...@@ -43,6 +43,8 @@ import org.codehaus.jettison.json.JSONException; ...@@ -43,6 +43,8 @@ import org.codehaus.jettison.json.JSONException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.google.common.annotations.VisibleForTesting;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
...@@ -498,7 +500,8 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1 implements At ...@@ -498,7 +500,8 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1 implements At
} }
} }
private static String toJsonFromAttribute(AtlasAttribute attribute) { @VisibleForTesting
public static String toJsonFromAttribute(AtlasAttribute attribute) {
AtlasAttributeDef attributeDef = attribute.getAttributeDef(); AtlasAttributeDef attributeDef = attribute.getAttributeDef();
boolean isComposite = attribute.legacyIsComposite(); boolean isComposite = attribute.legacyIsComposite();
String reverseAttribName = attribute.legacyReverseAttribute(); String reverseAttribName = attribute.legacyReverseAttribute();
...@@ -539,7 +542,8 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1 implements At ...@@ -539,7 +542,8 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1 implements At
return AtlasType.toJson(attribInfo); return AtlasType.toJson(attribInfo);
} }
private static AtlasAttributeDef toAttributeDefFromJson(AtlasStructDef structDef, @VisibleForTesting
public static AtlasAttributeDef toAttributeDefFromJson(AtlasStructDef structDef,
Map attribInfo, Map attribInfo,
AtlasTypeDefGraphStoreV1 typeDefStore) AtlasTypeDefGraphStoreV1 typeDefStore)
throws AtlasBaseException { throws AtlasBaseException {
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
*/ */
package org.apache.atlas.repository.store.graph.v1; package org.apache.atlas.repository.store.graph.v1;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.inject.Inject; import com.google.inject.Inject;
...@@ -110,7 +111,8 @@ public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore { ...@@ -110,7 +111,8 @@ public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore {
AtlasGraph getAtlasGraph() { return atlasGraph; } AtlasGraph getAtlasGraph() { return atlasGraph; }
AtlasVertex findTypeVertexByName(String typeName) { @VisibleForTesting
public AtlasVertex findTypeVertexByName(String typeName) {
Iterator results = atlasGraph.query().has(VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE) Iterator results = atlasGraph.query().has(VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE)
.has(Constants.TYPENAME_PROPERTY_KEY, typeName) .has(Constants.TYPENAME_PROPERTY_KEY, typeName)
.vertices().iterator(); .vertices().iterator();
...@@ -276,7 +278,8 @@ public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore { ...@@ -276,7 +278,8 @@ public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore {
return VERTEX_TYPE.equals(vertexType); return VERTEX_TYPE.equals(vertexType);
} }
boolean isTypeVertex(AtlasVertex vertex, TypeCategory category) { @VisibleForTesting
public boolean isTypeVertex(AtlasVertex vertex, TypeCategory category) {
boolean ret = false; boolean ret = false;
if (isTypeVertex(vertex)) { if (isTypeVertex(vertex)) {
......
...@@ -26,6 +26,7 @@ import org.apache.atlas.ApplicationProperties; ...@@ -26,6 +26,7 @@ import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.AtlasClient; import org.apache.atlas.AtlasClient;
import org.apache.atlas.AtlasErrorCode; import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.AtlasException; import org.apache.atlas.AtlasException;
import org.apache.atlas.CreateUpdateEntitiesResult;
import org.apache.atlas.EntityAuditEvent; import org.apache.atlas.EntityAuditEvent;
import org.apache.atlas.RequestContext; import org.apache.atlas.RequestContext;
import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.exception.AtlasBaseException;
...@@ -293,7 +294,7 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang ...@@ -293,7 +294,7 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
* @return guids - list of guids * @return guids - list of guids
*/ */
@Override @Override
public List<String> createEntities(String entityInstanceDefinition) throws AtlasException { public CreateUpdateEntitiesResult createEntities(String entityInstanceDefinition) throws AtlasException {
entityInstanceDefinition = ParamChecker.notEmpty(entityInstanceDefinition, "Entity instance definition"); entityInstanceDefinition = ParamChecker.notEmpty(entityInstanceDefinition, "Entity instance definition");
ITypedReferenceableInstance[] typedInstances = deserializeClassInstances(entityInstanceDefinition); ITypedReferenceableInstance[] typedInstances = deserializeClassInstances(entityInstanceDefinition);
...@@ -301,10 +302,10 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang ...@@ -301,10 +302,10 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
return createEntities(typedInstances); return createEntities(typedInstances);
} }
public List<String> createEntities(ITypedReferenceableInstance[] typedInstances) throws AtlasException { public CreateUpdateEntitiesResult createEntities(ITypedReferenceableInstance[] typedInstances) throws AtlasException {
final List<String> guids = repository.createEntities(typedInstances); final CreateUpdateEntitiesResult result = repository.createEntities(typedInstances);
onEntitiesAdded(guids); onEntitiesAdded(result.getCreatedEntities());
return guids; return result;
} }
private ITypedReferenceableInstance[] deserializeClassInstances(String entityInstanceDefinition) throws AtlasException { private ITypedReferenceableInstance[] deserializeClassInstances(String entityInstanceDefinition) throws AtlasException {
...@@ -397,13 +398,13 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang ...@@ -397,13 +398,13 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
* @return guids - json array of guids * @return guids - json array of guids
*/ */
@Override @Override
public AtlasClient.EntityResult updateEntities(String entityInstanceDefinition) throws AtlasException { public CreateUpdateEntitiesResult updateEntities(String entityInstanceDefinition) throws AtlasException {
entityInstanceDefinition = ParamChecker.notEmpty(entityInstanceDefinition, "Entity instance definition"); entityInstanceDefinition = ParamChecker.notEmpty(entityInstanceDefinition, "Entity instance definition");
ITypedReferenceableInstance[] typedInstances = deserializeClassInstances(entityInstanceDefinition); ITypedReferenceableInstance[] typedInstances = deserializeClassInstances(entityInstanceDefinition);
AtlasClient.EntityResult entityResult = repository.updateEntities(typedInstances); CreateUpdateEntitiesResult result = repository.updateEntities(typedInstances);
onEntitiesAddedUpdated(entityResult); onEntitiesAddedUpdated(result.getEntityResult());
return entityResult; return result;
} }
/** /**
...@@ -413,10 +414,10 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang ...@@ -413,10 +414,10 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
* @return guids - json array of guids * @return guids - json array of guids
*/ */
@Override @Override
public AtlasClient.EntityResult updateEntities(ITypedReferenceableInstance[] entityInstanceDefinitions) throws AtlasException { public CreateUpdateEntitiesResult updateEntities(ITypedReferenceableInstance[] entityInstanceDefinitions) throws AtlasException {
AtlasClient.EntityResult entityResult = repository.updateEntities(entityInstanceDefinitions); CreateUpdateEntitiesResult result = repository.updateEntities(entityInstanceDefinitions);
onEntitiesAddedUpdated(entityResult); onEntitiesAddedUpdated(result.getEntityResult());
return entityResult; return result;
} }
private void onEntitiesAddedUpdated(AtlasClient.EntityResult entityResult) throws AtlasException { private void onEntitiesAddedUpdated(AtlasClient.EntityResult entityResult) throws AtlasException {
...@@ -427,7 +428,7 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang ...@@ -427,7 +428,7 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
} }
@Override @Override
public AtlasClient.EntityResult updateEntityAttributeByGuid(String guid, String attributeName, public CreateUpdateEntitiesResult updateEntityAttributeByGuid(String guid, String attributeName,
String value) throws AtlasException { String value) throws AtlasException {
guid = ParamChecker.notEmpty(guid, "entity id"); guid = ParamChecker.notEmpty(guid, "entity id");
attributeName = ParamChecker.notEmpty(attributeName, "attribute name"); attributeName = ParamChecker.notEmpty(attributeName, "attribute name");
...@@ -457,9 +458,9 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang ...@@ -457,9 +458,9 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
} }
((ReferenceableInstance)newInstance).replaceWithNewId(new Id(guid, 0, newInstance.getTypeName())); ((ReferenceableInstance)newInstance).replaceWithNewId(new Id(guid, 0, newInstance.getTypeName()));
AtlasClient.EntityResult entityResult = repository.updatePartial(newInstance); CreateUpdateEntitiesResult result = repository.updatePartial(newInstance);
onEntitiesAddedUpdated(entityResult); onEntitiesAddedUpdated(result.getEntityResult());
return entityResult; return result;
} }
private ITypedReferenceableInstance validateEntityExists(String guid) private ITypedReferenceableInstance validateEntityExists(String guid)
...@@ -472,7 +473,7 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang ...@@ -472,7 +473,7 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
} }
@Override @Override
public AtlasClient.EntityResult updateEntityPartialByGuid(String guid, Referenceable newEntity) public CreateUpdateEntitiesResult updateEntityPartialByGuid(String guid, Referenceable newEntity)
throws AtlasException { throws AtlasException {
guid = ParamChecker.notEmpty(guid, "guid cannot be null"); guid = ParamChecker.notEmpty(guid, "guid cannot be null");
newEntity = ParamChecker.notNull(newEntity, "updatedEntity cannot be null"); newEntity = ParamChecker.notNull(newEntity, "updatedEntity cannot be null");
...@@ -481,9 +482,9 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang ...@@ -481,9 +482,9 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
ITypedReferenceableInstance newInstance = convertToTypedInstance(newEntity, existInstance.getTypeName()); ITypedReferenceableInstance newInstance = convertToTypedInstance(newEntity, existInstance.getTypeName());
((ReferenceableInstance)newInstance).replaceWithNewId(new Id(guid, 0, newInstance.getTypeName())); ((ReferenceableInstance)newInstance).replaceWithNewId(new Id(guid, 0, newInstance.getTypeName()));
AtlasClient.EntityResult entityResult = repository.updatePartial(newInstance); CreateUpdateEntitiesResult result = repository.updatePartial(newInstance);
onEntitiesAddedUpdated(entityResult); onEntitiesAddedUpdated(result.getEntityResult());
return entityResult; return result;
} }
private ITypedReferenceableInstance convertToTypedInstance(Referenceable updatedEntity, String typeName) private ITypedReferenceableInstance convertToTypedInstance(Referenceable updatedEntity, String typeName)
...@@ -530,7 +531,7 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang ...@@ -530,7 +531,7 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
} }
@Override @Override
public AtlasClient.EntityResult updateEntityByUniqueAttribute(String typeName, String uniqueAttributeName, public CreateUpdateEntitiesResult updateEntityByUniqueAttribute(String typeName, String uniqueAttributeName,
String attrValue, String attrValue,
Referenceable updatedEntity) throws AtlasException { Referenceable updatedEntity) throws AtlasException {
typeName = ParamChecker.notEmpty(typeName, "typeName"); typeName = ParamChecker.notEmpty(typeName, "typeName");
...@@ -543,9 +544,9 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang ...@@ -543,9 +544,9 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
final ITypedReferenceableInstance newInstance = convertToTypedInstance(updatedEntity, typeName); final ITypedReferenceableInstance newInstance = convertToTypedInstance(updatedEntity, typeName);
((ReferenceableInstance)newInstance).replaceWithNewId(oldInstance.getId()); ((ReferenceableInstance)newInstance).replaceWithNewId(oldInstance.getId());
AtlasClient.EntityResult entityResult = repository.updatePartial(newInstance); CreateUpdateEntitiesResult result = repository.updatePartial(newInstance);
onEntitiesAddedUpdated(entityResult); onEntitiesAddedUpdated(result.getEntityResult());
return entityResult; return result;
} }
private void validateTypeExists(String entityType) throws AtlasException { private void validateTypeExists(String entityType) throws AtlasException {
......
...@@ -395,7 +395,7 @@ public class BaseRepositoryTest { ...@@ -395,7 +395,7 @@ public class BaseRepositoryTest {
} }
private Id createInstance(Referenceable referenceable, ClassType clsType) throws Exception { private Id createInstance(Referenceable referenceable, ClassType clsType) throws Exception {
ITypedReferenceableInstance typedInstance = clsType.convert(referenceable, Multiplicity.REQUIRED); ITypedReferenceableInstance typedInstance = clsType.convert(referenceable, Multiplicity.REQUIRED);
List<String> guids = repository.createEntities(typedInstance); List<String> guids = repository.createEntities(typedInstance).getCreatedEntities();
// return the reference to created instance with guid // return the reference to created instance with guid
return new Id(guids.get(guids.size() - 1), 0, referenceable.getTypeName()); return new Id(guids.get(guids.size() - 1), 0, referenceable.getTypeName());
......
...@@ -121,7 +121,7 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest { ...@@ -121,7 +121,7 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest {
} }
} }
//We need to commit the transaction before creating the indices to release the locks held by the transaction. //We need to commit the transaction before creating the indices to release the locks held by the transaction.
//otherwise, the index commit will fail while waiting for the those locks to be released. //otherwise, the index commit will fail while waiting for the those locks to be released.
AtlasGraphProvider.getGraphInstance().commit(); AtlasGraphProvider.getGraphInstance().commit();
...@@ -302,7 +302,7 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest { ...@@ -302,7 +302,7 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest {
for (String name : Arrays.asList("John", "Max")) { for (String name : Arrays.asList("John", "Max")) {
Assert.assertTrue(names.contains(name)); Assert.assertTrue(names.contains(name));
} }
// Query for all Vertices modified after 01/01/2015 00:00:00 GMT // Query for all Vertices modified after 01/01/2015 00:00:00 GMT
r = discoveryService.searchByGremlin("g.V.filter{it." + Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY + " > 1420070400000}.toList()"); r = discoveryService.searchByGremlin("g.V.filter{it." + Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY + " > 1420070400000}.toList()");
Assert.assertTrue(r instanceof List); Assert.assertTrue(r instanceof List);
...@@ -524,55 +524,55 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest { ...@@ -524,55 +524,55 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest {
{"hive_db, hive_table limit 5", 5}, {"hive_db, hive_table limit 5", 5},
{"hive_db, hive_table limit 5 offset 0", 5}, {"hive_db, hive_table limit 5 offset 0", 5},
{"hive_db, hive_table limit 5 offset 5", 5}, {"hive_db, hive_table limit 5 offset 5", 5},
{"View is JdbcAccess", 2}, {"View is JdbcAccess", 2},
{"View is JdbcAccess limit 1", 1}, {"View is JdbcAccess limit 1", 1},
{"View is JdbcAccess limit 2 offset 1", 1}, {"View is JdbcAccess limit 2 offset 1", 1},
{"hive_db as db1, hive_table where db1.name = \"Reporting\"", 0}, //Not working - ATLAS-145 {"hive_db as db1, hive_table where db1.name = \"Reporting\"", 0}, //Not working - ATLAS-145
{"from hive_table", 10}, {"from hive_table", 10},
{"from hive_table limit 5", 5}, {"from hive_table limit 5", 5},
{"from hive_table limit 5 offset 5", 5}, {"from hive_table limit 5 offset 5", 5},
{"hive_table", 10}, {"hive_table", 10},
{"hive_table limit 5", 5}, {"hive_table limit 5", 5},
{"hive_table limit 5 offset 5", 5}, {"hive_table limit 5 offset 5", 5},
{"hive_table isa Dimension", 3}, {"hive_table isa Dimension", 3},
{"hive_table isa Dimension limit 2", 2}, {"hive_table isa Dimension limit 2", 2},
{"hive_table isa Dimension limit 2 offset 0", 2}, {"hive_table isa Dimension limit 2 offset 0", 2},
{"hive_table isa Dimension limit 2 offset 1", 2}, {"hive_table isa Dimension limit 2 offset 1", 2},
{"hive_table isa Dimension limit 3 offset 1", 2}, {"hive_table isa Dimension limit 3 offset 1", 2},
{"hive_column where hive_column isa PII", 8}, {"hive_column where hive_column isa PII", 8},
{"hive_column where hive_column isa PII limit 5", 5}, {"hive_column where hive_column isa PII limit 5", 5},
{"hive_column where hive_column isa PII limit 5 offset 1", 5}, {"hive_column where hive_column isa PII limit 5 offset 1", 5},
{"hive_column where hive_column isa PII limit 5 offset 5", 3}, {"hive_column where hive_column isa PII limit 5 offset 5", 3},
{"View is Dimension" , 2}, {"View is Dimension" , 2},
{"View is Dimension limit 1" , 1}, {"View is Dimension limit 1" , 1},
{"View is Dimension limit 1 offset 1" , 1}, {"View is Dimension limit 1 offset 1" , 1},
{"View is Dimension limit 10 offset 1" , 1}, {"View is Dimension limit 10 offset 1" , 1},
{"hive_column select hive_column.name", 37}, {"hive_column select hive_column.name", 37},
{"hive_column select hive_column.name limit 5", 5}, {"hive_column select hive_column.name limit 5", 5},
{"hive_column select hive_column.name limit 5 offset 36", 1}, {"hive_column select hive_column.name limit 5 offset 36", 1},
{"hive_column select name", 37}, {"hive_column select name", 37},
{"hive_column select name limit 5", 5}, {"hive_column select name limit 5", 5},
{"hive_column select name limit 5 offset 36 ", 1}, {"hive_column select name limit 5 offset 36 ", 1},
{"hive_column where hive_column.name=\"customer_id\"", 6}, {"hive_column where hive_column.name=\"customer_id\"", 6},
{"hive_column where hive_column.name=\"customer_id\" limit 2", 2}, {"hive_column where hive_column.name=\"customer_id\" limit 2", 2},
{"hive_column where hive_column.name=\"customer_id\" limit 2 offset 1", 2}, {"hive_column where hive_column.name=\"customer_id\" limit 2 offset 1", 2},
{"hive_column where hive_column.name=\"customer_id\" limit 10 offset 3", 3}, {"hive_column where hive_column.name=\"customer_id\" limit 10 offset 3", 3},
{"from hive_table select hive_table.name", 10}, {"from hive_table select hive_table.name", 10},
{"from hive_table select hive_table.name limit 5", 5}, {"from hive_table select hive_table.name limit 5", 5},
{"from hive_table select hive_table.name limit 5 offset 5", 5}, {"from hive_table select hive_table.name limit 5 offset 5", 5},
{"hive_db where (name = \"Reporting\")", 1}, {"hive_db where (name = \"Reporting\")", 1},
{"hive_db where (name = \"Reporting\") limit 10", 1}, {"hive_db where (name = \"Reporting\") limit 10", 1},
{"hive_db where (name = \"Reporting\") select name as _col_0, owner as _col_1", 1}, {"hive_db where (name = \"Reporting\") select name as _col_0, owner as _col_1", 1},
...@@ -585,18 +585,18 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest { ...@@ -585,18 +585,18 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest {
{"hive_db where hive_db has name limit 5", 3}, {"hive_db where hive_db has name limit 5", 3},
{"hive_db where hive_db has name limit 2 offset 0", 2}, {"hive_db where hive_db has name limit 2 offset 0", 2},
{"hive_db where hive_db has name limit 2 offset 1", 2}, {"hive_db where hive_db has name limit 2 offset 1", 2},
{"hive_db as db1 hive_table where (db1.name = \"Reporting\")", 0}, //Not working -> ATLAS-145 {"hive_db as db1 hive_table where (db1.name = \"Reporting\")", 0}, //Not working -> ATLAS-145
{"hive_db where (name = \"Reporting\") select name as _col_0, (createTime + 1) as _col_1 ", 1}, {"hive_db where (name = \"Reporting\") select name as _col_0, (createTime + 1) as _col_1 ", 1},
{"hive_db where (name = \"Reporting\") select name as _col_0, (createTime + 1) as _col_1 limit 10", 1}, {"hive_db where (name = \"Reporting\") select name as _col_0, (createTime + 1) as _col_1 limit 10", 1},
{"hive_db where (name = \"Reporting\") select name as _col_0, (createTime + 1) as _col_1 limit 10 offset 1", 0}, {"hive_db where (name = \"Reporting\") select name as _col_0, (createTime + 1) as _col_1 limit 10 offset 1", 0},
{"hive_db where (name = \"Reporting\") select name as _col_0, (createTime + 1) as _col_1 limit 10 offset 0", 1}, {"hive_db where (name = \"Reporting\") select name as _col_0, (createTime + 1) as _col_1 limit 10 offset 0", 1},
{"hive_table where (name = \"sales_fact\" and createTime > \"2014-01-01\" ) select name as _col_0, createTime as _col_1 ", 1}, {"hive_table where (name = \"sales_fact\" and createTime > \"2014-01-01\" ) select name as _col_0, createTime as _col_1 ", 1},
{"hive_table where (name = \"sales_fact\" and createTime > \"2014-01-01\" ) select name as _col_0, createTime as _col_1 limit 10 ", 1}, {"hive_table where (name = \"sales_fact\" and createTime > \"2014-01-01\" ) select name as _col_0, createTime as _col_1 limit 10 ", 1},
{"hive_table where (name = \"sales_fact\" and createTime > \"2014-01-01\" ) select name as _col_0, createTime as _col_1 limit 10 offset 0", 1}, {"hive_table where (name = \"sales_fact\" and createTime > \"2014-01-01\" ) select name as _col_0, createTime as _col_1 limit 10 offset 0", 1},
{"hive_table where (name = \"sales_fact\" and createTime > \"2014-01-01\" ) select name as _col_0, createTime as _col_1 limit 10 offset 5", 0}, {"hive_table where (name = \"sales_fact\" and createTime > \"2014-01-01\" ) select name as _col_0, createTime as _col_1 limit 10 offset 5", 0},
{"hive_table where (name = \"sales_fact\" and createTime >= \"2014-12-11T02:35:58.440Z\" ) select name as _col_0, createTime as _col_1 ", 1}, {"hive_table where (name = \"sales_fact\" and createTime >= \"2014-12-11T02:35:58.440Z\" ) select name as _col_0, createTime as _col_1 ", 1},
{"hive_table where (name = \"sales_fact\" and createTime >= \"2014-12-11T02:35:58.440Z\" ) select name as _col_0, createTime as _col_1 limit 10 offset 0", 1}, {"hive_table where (name = \"sales_fact\" and createTime >= \"2014-12-11T02:35:58.440Z\" ) select name as _col_0, createTime as _col_1 limit 10 offset 0", 1},
{"hive_table where (name = \"sales_fact\" and createTime >= \"2014-12-11T02:35:58.440Z\" ) select name as _col_0, createTime as _col_1 limit 10 offset 1", 0}, {"hive_table where (name = \"sales_fact\" and createTime >= \"2014-12-11T02:35:58.440Z\" ) select name as _col_0, createTime as _col_1 limit 10 offset 1", 0},
...@@ -608,25 +608,25 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest { ...@@ -608,25 +608,25 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest {
{"Dimension limit 2", 2}, {"Dimension limit 2", 2},
{"Dimension limit 2 offset 1", 2}, {"Dimension limit 2 offset 1", 2},
{"Dimension limit 5 offset 4", 1}, {"Dimension limit 5 offset 4", 1},
{"JdbcAccess", 2}, {"JdbcAccess", 2},
{"JdbcAccess limit 5 offset 0", 2}, {"JdbcAccess limit 5 offset 0", 2},
{"JdbcAccess limit 2 offset 1", 1}, {"JdbcAccess limit 2 offset 1", 1},
{"JdbcAccess limit 1", 1}, {"JdbcAccess limit 1", 1},
{"ETL", 5}, {"ETL", 5},
{"ETL limit 2", 2}, {"ETL limit 2", 2},
{"ETL limit 1", 1}, {"ETL limit 1", 1},
{"ETL limit 1 offset 0", 1}, {"ETL limit 1 offset 0", 1},
{"ETL limit 2 offset 1", 2}, {"ETL limit 2 offset 1", 2},
{"Metric", 9}, {"Metric", 9},
{"Metric limit 10", 9}, {"Metric limit 10", 9},
{"Metric limit 2", 2}, {"Metric limit 2", 2},
{"Metric limit 10 offset 1", 8}, {"Metric limit 10 offset 1", 8},
{"PII", 8}, {"PII", 8},
{"PII limit 10", 8}, {"PII limit 10", 8},
{"PII limit 2", 2}, {"PII limit 2", 2},
...@@ -933,7 +933,7 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest { ...@@ -933,7 +933,7 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest {
System.out.println("query [" + dslQuery + "] returned [" + rows.length() + "] rows"); System.out.println("query [" + dslQuery + "] returned [" + rows.length() + "] rows");
} }
@Test(dataProvider = "dslQueriesProvider") @Test(dataProvider = "dslQueriesProvider")
public void testSearchByDSLQueries(String dslQuery, Integer expectedNumRows) throws Exception { public void testSearchByDSLQueries(String dslQuery, Integer expectedNumRows) throws Exception {
runQuery(dslQuery, expectedNumRows, 40, 0); runQuery(dslQuery, expectedNumRows, 40, 0);
...@@ -1207,6 +1207,27 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest { ...@@ -1207,6 +1207,27 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest {
} }
@Test
public void testSearchForTypeWithNoInstances() throws Exception {
HierarchicalTypeDefinition EMPTY = createClassTypeDef("EmptyType", null,
createRequiredAttrDef("a", DataTypes.INT_TYPE));
TypeSystem.getInstance().defineClassTypes(EMPTY);
String dslQuery = "EmptyType";
String jsonResults = searchByDSL(dslQuery);
assertNotNull(jsonResults);
JSONObject results = new JSONObject(jsonResults);
assertEquals(results.length(), 3);
JSONArray rows = results.getJSONArray("rows");
assertNotNull(rows);
// query should not return any rows
assertEquals(rows.length(), 0);
}
private FieldValueValidator makeCountValidator(int count) { private FieldValueValidator makeCountValidator(int count) {
return new FieldValueValidator().withFieldNames("count()").withExpectedValues(count); return new FieldValueValidator().withFieldNames("count()").withExpectedValues(count);
} }
......
...@@ -257,7 +257,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase { ...@@ -257,7 +257,7 @@ 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); List<String> results = repositoryService.createEntities(instance).getCreatedEntities();
return results.get(results.size() - 1); return results.get(results.size() - 1);
} }
...@@ -403,7 +403,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase { ...@@ -403,7 +403,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
ITypedReferenceableInstance mapValueInstance = compositeMapValueType.createInstance(); ITypedReferenceableInstance mapValueInstance = compositeMapValueType.createInstance();
mapValueInstance.set(NAME, TestUtils.randomString()); mapValueInstance.set(NAME, TestUtils.randomString());
mapOwnerInstance.set("map", Collections.singletonMap("value1", mapValueInstance)); mapOwnerInstance.set("map", Collections.singletonMap("value1", mapValueInstance));
List<String> createEntitiesResult = repositoryService.createEntities(mapOwnerInstance, mapValueInstance); List<String> createEntitiesResult = repositoryService.createEntities(mapOwnerInstance, mapValueInstance).getCreatedEntities();
Assert.assertEquals(createEntitiesResult.size(), 2); Assert.assertEquals(createEntitiesResult.size(), 2);
ITypedReferenceableInstance entityDefinition = repositoryService.getEntityDefinition("CompositeMapOwner", ITypedReferenceableInstance entityDefinition = repositoryService.getEntityDefinition("CompositeMapOwner",
NAME, mapOwnerInstance.get(NAME)); NAME, mapOwnerInstance.get(NAME));
...@@ -412,7 +412,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase { ...@@ -412,7 +412,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
private AtlasClient.EntityResult updatePartial(ITypedReferenceableInstance entity) throws RepositoryException { private AtlasClient.EntityResult updatePartial(ITypedReferenceableInstance entity) throws RepositoryException {
RequestContext.createContext(); RequestContext.createContext();
return repositoryService.updatePartial(entity); return repositoryService.updatePartial(entity).getEntityResult();
} }
@Test @Test
...@@ -641,7 +641,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase { ...@@ -641,7 +641,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
structContainerType.convert(structContainerEntity, Multiplicity.REQUIRED); structContainerType.convert(structContainerEntity, Multiplicity.REQUIRED);
List<String> guids = repositoryService.createEntities( List<String> guids = repositoryService.createEntities(
structTargetConvertedEntity, traitTargetConvertedEntity, structContainerConvertedEntity); structTargetConvertedEntity, traitTargetConvertedEntity, structContainerConvertedEntity).getCreatedEntities();
Assert.assertEquals(guids.size(), 3); Assert.assertEquals(guids.size(), 3);
guids = repositoryService.getEntityList("StructTarget"); guids = repositoryService.getEntityList("StructTarget");
...@@ -746,7 +746,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase { ...@@ -746,7 +746,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
mapOwnerInstance.set("biMap", Collections.singletonMap("value1", mapValueInstance)); mapOwnerInstance.set("biMap", Collections.singletonMap("value1", mapValueInstance));
// Set biMapOwner reverse reference on MapValue. // Set biMapOwner reverse reference on MapValue.
mapValueInstance.set("biMapOwner", mapOwnerInstance); mapValueInstance.set("biMapOwner", mapOwnerInstance);
List<String> createEntitiesResult = repositoryService.createEntities(mapOwnerInstance, mapValueInstance); List<String> createEntitiesResult = repositoryService.createEntities(mapOwnerInstance, mapValueInstance).getCreatedEntities();
Assert.assertEquals(createEntitiesResult.size(), 2); Assert.assertEquals(createEntitiesResult.size(), 2);
List<String> guids = repositoryService.getEntityList("MapOwner"); List<String> guids = repositoryService.getEntityList("MapOwner");
Assert.assertEquals(guids.size(), 1); Assert.assertEquals(guids.size(), 1);
...@@ -856,7 +856,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase { ...@@ -856,7 +856,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
ITypedReferenceableInstance mapOwnerInstance = mapOwnerType.createInstance(); ITypedReferenceableInstance mapOwnerInstance = mapOwnerType.createInstance();
ITypedReferenceableInstance mapValueInstance = mapValueType.createInstance(); ITypedReferenceableInstance mapValueInstance = mapValueType.createInstance();
mapOwnerInstance.set("map", Collections.singletonMap("value1", mapValueInstance)); mapOwnerInstance.set("map", Collections.singletonMap("value1", mapValueInstance));
List<String> createEntitiesResult = repositoryService.createEntities(mapOwnerInstance, mapValueInstance); List<String> createEntitiesResult = repositoryService.createEntities(mapOwnerInstance, mapValueInstance).getCreatedEntities();
Assert.assertEquals(createEntitiesResult.size(), 2); Assert.assertEquals(createEntitiesResult.size(), 2);
List<String> guids = repositoryService.getEntityList("RequiredMapOwner"); List<String> guids = repositoryService.getEntityList("RequiredMapOwner");
Assert.assertEquals(guids.size(), 1); Assert.assertEquals(guids.size(), 1);
...@@ -985,7 +985,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase { ...@@ -985,7 +985,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
// Create instance of MapValueReferencerContainer // Create instance of MapValueReferencerContainer
RequestContext.createContext(); RequestContext.createContext();
ITypedReferenceableInstance mapValueReferencerContainer = mapValueReferencerContainerType.createInstance(); ITypedReferenceableInstance mapValueReferencerContainer = mapValueReferencerContainerType.createInstance();
List<String> createdEntities = repositoryService.createEntities(mapValueReferencerContainer); List<String> createdEntities = repositoryService.createEntities(mapValueReferencerContainer).getCreatedEntities();
Assert.assertEquals(createdEntities.size(), 1); Assert.assertEquals(createdEntities.size(), 1);
String mapValueReferencerContainerGuid = createdEntities.get(0); String mapValueReferencerContainerGuid = createdEntities.get(0);
mapValueReferencerContainer = repositoryService.getEntityDefinition(createdEntities.get(0)); mapValueReferencerContainer = repositoryService.getEntityDefinition(createdEntities.get(0));
...@@ -997,7 +997,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase { ...@@ -997,7 +997,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
mapValueReferencer.set("refToMapValue", mapValueInstance.getId()); mapValueReferencer.set("refToMapValue", mapValueInstance.getId());
RequestContext.createContext(); RequestContext.createContext();
EntityResult updateEntitiesResult = repositoryService.updateEntities(mapValueReferencerContainer); EntityResult updateEntitiesResult = repositoryService.updateEntities(mapValueReferencerContainer).getEntityResult();
Assert.assertEquals(updateEntitiesResult.getCreatedEntities().size(), 1); Assert.assertEquals(updateEntitiesResult.getCreatedEntities().size(), 1);
Assert.assertEquals(updateEntitiesResult.getUpdateEntities().size(), 1); Assert.assertEquals(updateEntitiesResult.getUpdateEntities().size(), 1);
Assert.assertEquals(updateEntitiesResult.getUpdateEntities().get(0), mapValueReferencerContainerGuid); Assert.assertEquals(updateEntitiesResult.getUpdateEntities().get(0), mapValueReferencerContainerGuid);
...@@ -1016,7 +1016,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase { ...@@ -1016,7 +1016,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
public void testDeleteMixOfExistentAndNonExistentEntities() throws Exception { public void testDeleteMixOfExistentAndNonExistentEntities() throws Exception {
ITypedReferenceableInstance entity1 = compositeMapValueType.createInstance(); ITypedReferenceableInstance entity1 = compositeMapValueType.createInstance();
ITypedReferenceableInstance entity2 = compositeMapValueType.createInstance(); ITypedReferenceableInstance entity2 = compositeMapValueType.createInstance();
List<String> createEntitiesResult = repositoryService.createEntities(entity1, entity2); List<String> createEntitiesResult = repositoryService.createEntities(entity1, entity2).getCreatedEntities();
Assert.assertEquals(createEntitiesResult.size(), 2); Assert.assertEquals(createEntitiesResult.size(), 2);
List<String> guids = Arrays.asList(createEntitiesResult.get(0), "non-existent-guid1", "non-existent-guid2", createEntitiesResult.get(1)); List<String> guids = Arrays.asList(createEntitiesResult.get(0), "non-existent-guid1", "non-existent-guid2", createEntitiesResult.get(1));
EntityResult deleteEntitiesResult = repositoryService.deleteEntities(guids); EntityResult deleteEntitiesResult = repositoryService.deleteEntities(guids);
...@@ -1028,7 +1028,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase { ...@@ -1028,7 +1028,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
public void testDeleteMixOfNullAndNonNullGuids() throws Exception { public void testDeleteMixOfNullAndNonNullGuids() throws Exception {
ITypedReferenceableInstance entity1 = compositeMapValueType.createInstance(); ITypedReferenceableInstance entity1 = compositeMapValueType.createInstance();
ITypedReferenceableInstance entity2 = compositeMapValueType.createInstance(); ITypedReferenceableInstance entity2 = compositeMapValueType.createInstance();
List<String> createEntitiesResult = repositoryService.createEntities(entity1, entity2); List<String> createEntitiesResult = repositoryService.createEntities(entity1, entity2).getCreatedEntities();
Assert.assertEquals(createEntitiesResult.size(), 2); Assert.assertEquals(createEntitiesResult.size(), 2);
List<String> guids = Arrays.asList(createEntitiesResult.get(0), null, null, createEntitiesResult.get(1)); List<String> guids = Arrays.asList(createEntitiesResult.get(0), null, null, createEntitiesResult.get(1));
EntityResult deleteEntitiesResult = repositoryService.deleteEntities(guids); EntityResult deleteEntitiesResult = repositoryService.deleteEntities(guids);
...@@ -1076,7 +1076,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase { ...@@ -1076,7 +1076,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
ClassType dataType = typeSystem.getDataType(ClassType.class, table1Entity.getTypeName()); ClassType dataType = typeSystem.getDataType(ClassType.class, table1Entity.getTypeName());
ITypedReferenceableInstance instance = dataType.convert(table1Entity, Multiplicity.REQUIRED); ITypedReferenceableInstance instance = dataType.convert(table1Entity, Multiplicity.REQUIRED);
TestUtils.resetRequestContext(); TestUtils.resetRequestContext();
List<String> result = repositoryService.createEntities(instance); List<String> result = repositoryService.createEntities(instance).getCreatedEntities();
Assert.assertEquals(result.size(), 3); Assert.assertEquals(result.size(), 3);
ITypedReferenceableInstance entityDefinition = repositoryService.getEntityDefinition(TABLE_TYPE, NAME, tableName); ITypedReferenceableInstance entityDefinition = repositoryService.getEntityDefinition(TABLE_TYPE, NAME, tableName);
String tableGuid = entityDefinition.getId()._getId(); String tableGuid = entityDefinition.getId()._getId();
...@@ -1106,7 +1106,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase { ...@@ -1106,7 +1106,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
private String createHrDeptGraph() throws Exception { private String createHrDeptGraph() throws Exception {
ITypedReferenceableInstance hrDept = TestUtils.createDeptEg1(typeSystem); ITypedReferenceableInstance hrDept = TestUtils.createDeptEg1(typeSystem);
List<String> guids = repositoryService.createEntities(hrDept); List<String> guids = repositoryService.createEntities(hrDept).getCreatedEntities();
Assert.assertNotNull(guids); Assert.assertNotNull(guids);
Assert.assertEquals(guids.size(), 5); Assert.assertEquals(guids.size(), 5);
......
...@@ -143,7 +143,7 @@ public class GraphHelperTest { ...@@ -143,7 +143,7 @@ public class GraphHelperTest {
@Test @Test
public void testGetVerticesForGUIDSWithDuplicates() throws Exception { public void testGetVerticesForGUIDSWithDuplicates() throws Exception {
ITypedReferenceableInstance hrDept = TestUtils.createDeptEg1(TypeSystem.getInstance()); ITypedReferenceableInstance hrDept = TestUtils.createDeptEg1(TypeSystem.getInstance());
List<String> result = repositoryService.createEntities(hrDept); List<String> result = repositoryService.createEntities(hrDept).getCreatedEntities();
String guid = result.get(0); String guid = result.get(0);
Map<String, AtlasVertex> verticesForGUIDs = GraphHelper.getInstance().getVerticesForGUIDs(Arrays.asList(guid, guid)); Map<String, AtlasVertex> verticesForGUIDs = GraphHelper.getInstance().getVerticesForGUIDs(Arrays.asList(guid, guid));
Assert.assertEquals(verticesForGUIDs.size(), 1); Assert.assertEquals(verticesForGUIDs.size(), 1);
...@@ -152,7 +152,7 @@ public class GraphHelperTest { ...@@ -152,7 +152,7 @@ public class GraphHelperTest {
@Test @Test
public void testGetCompositeGuidsAndVertices() throws Exception { public void testGetCompositeGuidsAndVertices() throws Exception {
ITypedReferenceableInstance hrDept = TestUtils.createDeptEg1(typeSystem); ITypedReferenceableInstance hrDept = TestUtils.createDeptEg1(typeSystem);
List<String> createdGuids = repositoryService.createEntities(hrDept); List<String> createdGuids = repositoryService.createEntities(hrDept).getCreatedEntities();
String deptGuid = null; String deptGuid = null;
Set<String> expectedGuids = new HashSet<>(); Set<String> expectedGuids = new HashSet<>();
...@@ -214,7 +214,7 @@ public class GraphHelperTest { ...@@ -214,7 +214,7 @@ public class GraphHelperTest {
String entityjson = InstanceSerialization.toJson(entity, true); String entityjson = InstanceSerialization.toJson(entity, true);
JSONArray entitiesJson = new JSONArray(); JSONArray entitiesJson = new JSONArray();
entitiesJson.put(entityjson); entitiesJson.put(entityjson);
List<String> guids = metadataService.createEntities(entitiesJson.toString()); List<String> guids = metadataService.createEntities(entitiesJson.toString()).getCreatedEntities();
if (guids != null && guids.size() > 0) { if (guids != null && guids.size() > 0) {
return guids.get(guids.size() - 1); return guids.get(guids.size() - 1);
} }
......
...@@ -19,10 +19,12 @@ ...@@ -19,10 +19,12 @@
package org.apache.atlas.repository.graph; package org.apache.atlas.repository.graph;
import org.apache.atlas.ApplicationProperties; import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.CreateUpdateEntitiesResult;
import org.apache.atlas.GraphTransaction; import org.apache.atlas.GraphTransaction;
import org.apache.atlas.RepositoryMetadataModule; import org.apache.atlas.RepositoryMetadataModule;
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.repository.RepositoryException;
import org.apache.atlas.repository.graphdb.AtlasGraph; import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.graphdb.AtlasGraphQuery; import org.apache.atlas.repository.graphdb.AtlasGraphQuery;
import org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator; import org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator;
...@@ -32,6 +34,7 @@ import org.apache.atlas.type.AtlasTypeRegistry; ...@@ -32,6 +34,7 @@ import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.atlas.typesystem.ITypedReferenceableInstance; import org.apache.atlas.typesystem.ITypedReferenceableInstance;
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.exception.EntityExistsException;
import org.apache.atlas.typesystem.persistence.Id; import org.apache.atlas.typesystem.persistence.Id;
import org.apache.atlas.typesystem.types.ClassType; import org.apache.atlas.typesystem.types.ClassType;
import org.apache.atlas.typesystem.types.IDataType; import org.apache.atlas.typesystem.types.IDataType;
...@@ -100,16 +103,21 @@ public class GraphRepoMapperScaleTest { ...@@ -100,16 +103,21 @@ public class GraphRepoMapperScaleTest {
ClassType dbType = typeSystem.getDataType(ClassType.class, TestUtils.DATABASE_TYPE); ClassType dbType = typeSystem.getDataType(ClassType.class, TestUtils.DATABASE_TYPE);
ITypedReferenceableInstance db = dbType.convert(databaseInstance, Multiplicity.REQUIRED); ITypedReferenceableInstance db = dbType.convert(databaseInstance, Multiplicity.REQUIRED);
dbGUID = repositoryService.createEntities(db).get(0); dbGUID = result(db).getCreatedEntities().get(0);
Referenceable dbInstance = new Referenceable(dbGUID, TestUtils.DATABASE_TYPE, databaseInstance.getValuesMap()); Referenceable dbInstance = new Referenceable(dbGUID, TestUtils.DATABASE_TYPE, databaseInstance.getValuesMap());
for (int index = 0; index < 1000; index++) { for (int index = 0; index < 1000; index++) {
ITypedReferenceableInstance table = createHiveTableInstance(dbInstance, index); ITypedReferenceableInstance table = createHiveTableInstance(dbInstance, index);
repositoryService.createEntities(table); result(table);
} }
} }
private CreateUpdateEntitiesResult result(ITypedReferenceableInstance db)
throws RepositoryException, EntityExistsException {
return repositoryService.createEntities(db);
}
@Test(dependsOnMethods = "testSubmitEntity") @Test(dependsOnMethods = "testSubmitEntity")
public void testSearchIndex() throws Exception { public void testSearchIndex() throws Exception {
......
...@@ -165,7 +165,8 @@ public class GraphBackedTypeStoreTest { ...@@ -165,7 +165,8 @@ public class GraphBackedTypeStoreTest {
HierarchicalTypeDefinition<ClassType> deptTypeDef = createClassTypeDef("Department", "Department"+_description, HierarchicalTypeDefinition<ClassType> deptTypeDef = createClassTypeDef("Department", "Department"+_description,
ImmutableSet.<String>of(), createRequiredAttrDef("name", DataTypes.STRING_TYPE), ImmutableSet.<String>of(), createRequiredAttrDef("name", DataTypes.STRING_TYPE),
new AttributeDefinition("employees", String.format("array<%s>", "Person"), Multiplicity.OPTIONAL, new AttributeDefinition("employees", String.format("array<%s>", "Person"), Multiplicity.OPTIONAL,
true, "department")); true, "department"),
new AttributeDefinition("positions", String.format("map<%s,%s>", DataTypes.STRING_TYPE.getName(), "Person"), Multiplicity.OPTIONAL, false, null));
TypesDef typesDef = TypesUtil.getTypesDef(ImmutableList.of(orgLevelEnum), ImmutableList.of(addressDetails), TypesDef typesDef = TypesUtil.getTypesDef(ImmutableList.of(orgLevelEnum), ImmutableList.of(addressDetails),
ImmutableList.<HierarchicalTypeDefinition<TraitType>>of(), ImmutableList.<HierarchicalTypeDefinition<TraitType>>of(),
ImmutableList.of(deptTypeDef)); ImmutableList.of(deptTypeDef));
......
...@@ -170,7 +170,7 @@ public class DefaultMetadataServiceTest { ...@@ -170,7 +170,7 @@ public class DefaultMetadataServiceTest {
String entityjson = InstanceSerialization.toJson(entity, true); String entityjson = InstanceSerialization.toJson(entity, true);
JSONArray entitiesJson = new JSONArray(); JSONArray entitiesJson = new JSONArray();
entitiesJson.put(entityjson); entitiesJson.put(entityjson);
return metadataService.updateEntities(entitiesJson.toString()); return metadataService.updateEntities(entitiesJson.toString()).getEntityResult();
} }
@Test(expectedExceptions = TypeNotFoundException.class) @Test(expectedExceptions = TypeNotFoundException.class)
...@@ -544,7 +544,7 @@ public class DefaultMetadataServiceTest { ...@@ -544,7 +544,7 @@ public class DefaultMetadataServiceTest {
private AtlasClient.EntityResult updateEntityPartial(String guid, Referenceable entity) throws AtlasException { private AtlasClient.EntityResult updateEntityPartial(String guid, Referenceable entity) throws AtlasException {
RequestContext.createContext(); RequestContext.createContext();
return metadataService.updateEntityPartialByGuid(guid, entity); return metadataService.updateEntityPartialByGuid(guid, entity).getEntityResult();
} }
@Test @Test
......
...@@ -20,6 +20,7 @@ package org.apache.atlas.services; ...@@ -20,6 +20,7 @@ package org.apache.atlas.services;
import org.apache.atlas.AtlasClient; import org.apache.atlas.AtlasClient;
import org.apache.atlas.AtlasException; import org.apache.atlas.AtlasException;
import org.apache.atlas.CreateUpdateEntitiesResult;
import org.apache.atlas.EntityAuditEvent; import org.apache.atlas.EntityAuditEvent;
import org.apache.atlas.listener.EntityChangeListener; import org.apache.atlas.listener.EntityChangeListener;
import org.apache.atlas.typesystem.ITypedReferenceableInstance; import org.apache.atlas.typesystem.ITypedReferenceableInstance;
...@@ -78,9 +79,9 @@ public interface MetadataService { ...@@ -78,9 +79,9 @@ public interface MetadataService {
* Creates an entity, instance of the type. * Creates an entity, instance of the type.
* *
* @param entityDefinition definition * @param entityDefinition definition
* @return json array of guids of entities created * @return CreateUpdateEntitiesResult with the guids of the entities created
*/ */
List<String> createEntities(String entityDefinition) throws AtlasException; CreateUpdateEntitiesResult createEntities(String entityDefinition) throws AtlasException;
/** /**
* Get a typed entity instance. * Get a typed entity instance.
...@@ -96,11 +97,11 @@ public interface MetadataService { ...@@ -96,11 +97,11 @@ public interface MetadataService {
* Create entity instances. * Create entity instances.
* *
* @param typedInstances instance to create * @param typedInstances instance to create
* @return collection of guids for created entities * @return CreateUpdateEntitiesResult with the guids of the entities created
* *
* @throws AtlasException if unable to create the entities * @throws AtlasException if unable to create the entities
*/ */
List<String> createEntities(ITypedReferenceableInstance[] typedInstances) throws AtlasException; CreateUpdateEntitiesResult createEntities(ITypedReferenceableInstance[] typedInstances) throws AtlasException;
/** /**
...@@ -148,36 +149,36 @@ public interface MetadataService { ...@@ -148,36 +149,36 @@ public interface MetadataService {
* @param guid entity id * @param guid entity id
* @param attribute property name * @param attribute property name
* @param value property value * @param value property value
* @return json array of guids of entities created/updated * @return {@link CreateUpdateEntitiesResult} with the guids of the entities that were created/updated
*/ */
AtlasClient.EntityResult updateEntityAttributeByGuid(String guid, String attribute, String value) throws AtlasException; CreateUpdateEntitiesResult updateEntityAttributeByGuid(String guid, String attribute, String value) throws AtlasException;
/** /**
* Supports Partial updates of an entity. Users can update a subset of attributes for an entity identified by its guid * Supports Partial updates of an entity. Users can update a subset of attributes for an entity identified by its guid
* Note however that it cannot be used to set attribute values to null or delete attrbute values * Note however that it cannot be used to set attribute values to null or delete attrbute values
* @param guid entity id * @param guid entity id
* @param entity * @param entity
* @return json array of guids of entities created/updated * @return {@link CreateUpdateEntitiesResult} with the guids of the entities that were created/updated
* @throws AtlasException * @throws AtlasException
*/ */
AtlasClient.EntityResult updateEntityPartialByGuid(String guid, Referenceable entity) throws AtlasException; CreateUpdateEntitiesResult updateEntityPartialByGuid(String guid, Referenceable entity) throws AtlasException;
/** /**
* Batch API - Adds/Updates the given entity id(guid). * Batch API - Adds/Updates the given entity id(guid).
* *
* @param entityJson entity json * @param entityJson entity json
* @return json array of guids of entities created/updated * @return {@link CreateUpdateEntitiesResult} with the guids of the entities that were created/updated
*/ */
AtlasClient.EntityResult updateEntities(String entityJson) throws AtlasException; CreateUpdateEntitiesResult updateEntities(String entityJson) throws AtlasException;
/** /**
* Batch API - Adds/Updates the given entity id(guid). * Batch API - Adds/Updates the given entity id(guid).
* *
* @param entityJson entity json * @param entityJson entity json
* @return json array of guids of entities created/updated * @return {@link CreateUpdateEntitiesResult} with the guids of the entities that were created/updated
*/ */
AtlasClient.EntityResult updateEntities(ITypedReferenceableInstance[] iTypedReferenceableInstances) throws AtlasException; CreateUpdateEntitiesResult updateEntities(ITypedReferenceableInstance[] iTypedReferenceableInstances) throws AtlasException;
// Trait management functions // Trait management functions
...@@ -191,7 +192,7 @@ public interface MetadataService { ...@@ -191,7 +192,7 @@ public interface MetadataService {
* @return Guid of updated entity * @return Guid of updated entity
* @throws AtlasException * @throws AtlasException
*/ */
AtlasClient.EntityResult updateEntityByUniqueAttribute(String typeName, String uniqueAttributeName, CreateUpdateEntitiesResult updateEntityByUniqueAttribute(String typeName, String uniqueAttributeName,
String attrValue, String attrValue,
Referenceable updatedEntity) throws AtlasException; Referenceable updatedEntity) throws AtlasException;
......
...@@ -618,7 +618,7 @@ public class TypeSystem { ...@@ -618,7 +618,7 @@ public class TypeSystem {
try { try {
oldType = TypeSystem.this.getDataType(IDataType.class, newType.getName()); oldType = TypeSystem.this.getDataType(IDataType.class, newType.getName());
} catch (TypeNotFoundException e) { } catch (TypeNotFoundException e) {
LOG.debug("No existing type %s found - update OK", newType.getName()); LOG.debug(String.format("No existing type %s found - update OK", newType.getName()));
} }
if (oldType != null) { if (oldType != null) {
oldType.validateUpdate(newType); oldType.validateUpdate(newType);
......
...@@ -356,7 +356,8 @@ public class QuickStartV2 { ...@@ -356,7 +356,8 @@ public class QuickStartV2 {
List<AtlasEntityHeader> entities = response.getEntitiesByOperation(EntityOperation.CREATE); List<AtlasEntityHeader> entities = response.getEntitiesByOperation(EntityOperation.CREATE);
if (CollectionUtils.isNotEmpty(entities)) { if (CollectionUtils.isNotEmpty(entities)) {
ret = entitiesClient.getEntityByGuid(entities.get(0).getGuid()); List<AtlasEntityWithAssociations> getByGuidResponse = entitiesClient.getEntityByGuid(entities.get(0).getGuid());
ret = getByGuidResponse.get(0);
System.out.println("Created entity of type [" + ret.getTypeName() + "], guid: " + ret.getGuid()); System.out.println("Created entity of type [" + ret.getTypeName() + "], guid: " + ret.getGuid());
} }
...@@ -567,7 +568,7 @@ public class QuickStartV2 { ...@@ -567,7 +568,7 @@ public class QuickStartV2 {
} }
private String getTableId(String tableName) throws AtlasServiceException { private String getTableId(String tableName) throws AtlasServiceException {
AtlasEntity tableEntity = entitiesClient.getEntityByAttribute(TABLE_TYPE, AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, tableName); AtlasEntity tableEntity = entitiesClient.getEntityByAttribute(TABLE_TYPE, AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, tableName).get(0);
return tableEntity.getGuid(); return tableEntity.getGuid();
} }
} }
...@@ -18,10 +18,22 @@ ...@@ -18,10 +18,22 @@
package org.apache.atlas.util; package org.apache.atlas.util;
import com.google.common.collect.ImmutableList; import static org.apache.atlas.AtlasErrorCode.INVALID_TYPE_DEFINITION;
import com.google.common.collect.ImmutableSet; import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_ON_DELETE;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_VAL_CASCADE;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_FOREIGN_KEY;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_MAPPED_FROM_REF;
import static org.apache.atlas.type.AtlasTypeUtil.isArrayType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TypeCategory; import org.apache.atlas.model.TypeCategory;
import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.typedef.AtlasClassificationDef; import org.apache.atlas.model.typedef.AtlasClassificationDef;
import org.apache.atlas.model.typedef.AtlasEntityDef; import org.apache.atlas.model.typedef.AtlasEntityDef;
import org.apache.atlas.model.typedef.AtlasEnumDef; import org.apache.atlas.model.typedef.AtlasEnumDef;
...@@ -55,21 +67,12 @@ import org.apache.atlas.typesystem.types.TraitType; ...@@ -55,21 +67,12 @@ import org.apache.atlas.typesystem.types.TraitType;
import org.apache.atlas.typesystem.types.utils.TypesUtil; import org.apache.atlas.typesystem.types.utils.TypesUtil;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.ArrayList; import com.google.common.collect.ImmutableList;
import java.util.HashMap; import com.google.common.collect.ImmutableSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.apache.atlas.AtlasErrorCode.INVALID_TYPE_DEFINITION;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_ON_DELETE;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_VAL_CASCADE;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_FOREIGN_KEY;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_MAPPED_FROM_REF;
import static org.apache.atlas.type.AtlasTypeUtil.isArrayType;
public final class RestUtils { public final class RestUtils {
...@@ -500,4 +503,5 @@ public final class RestUtils { ...@@ -500,4 +503,5 @@ public final class RestUtils {
private static boolean isEntity(AtlasType type) { private static boolean isEntity(AtlasType type) {
return type.getTypeCategory() == TypeCategory.ENTITY; return type.getTypeCategory() == TypeCategory.ENTITY;
} }
} }
\ No newline at end of file
...@@ -17,11 +17,12 @@ ...@@ -17,11 +17,12 @@
*/ */
package org.apache.atlas.web.adapters; package org.apache.atlas.web.adapters;
import com.google.inject.Inject; import java.util.List;
import com.google.inject.Singleton;
import org.apache.atlas.AtlasClient; import org.apache.atlas.AtlasClient;
import org.apache.atlas.AtlasErrorCode; import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.AtlasException; import org.apache.atlas.AtlasException;
import org.apache.atlas.CreateUpdateEntitiesResult;
import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TypeCategory; import org.apache.atlas.model.TypeCategory;
import org.apache.atlas.model.instance.AtlasClassification; import org.apache.atlas.model.instance.AtlasClassification;
...@@ -30,6 +31,7 @@ import org.apache.atlas.model.instance.AtlasEntityHeader; ...@@ -30,6 +31,7 @@ import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.model.instance.AtlasEntityWithAssociations; import org.apache.atlas.model.instance.AtlasEntityWithAssociations;
import org.apache.atlas.model.instance.EntityMutationResponse; import org.apache.atlas.model.instance.EntityMutationResponse;
import org.apache.atlas.model.instance.EntityMutations; import org.apache.atlas.model.instance.EntityMutations;
import org.apache.atlas.model.instance.GuidMapping;
import org.apache.atlas.services.MetadataService; import org.apache.atlas.services.MetadataService;
import org.apache.atlas.type.AtlasClassificationType; import org.apache.atlas.type.AtlasClassificationType;
import org.apache.atlas.type.AtlasEntityType; import org.apache.atlas.type.AtlasEntityType;
...@@ -50,7 +52,8 @@ import org.slf4j.LoggerFactory; ...@@ -50,7 +52,8 @@ import org.slf4j.LoggerFactory;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.util.Map; import java.util.Map;
@Singleton @Singleton
...@@ -142,8 +145,14 @@ public class AtlasInstanceRestAdapters { ...@@ -142,8 +145,14 @@ public class AtlasInstanceRestAdapters {
return ctx.getEntities(); return ctx.getEntities();
} }
public static EntityMutationResponse toEntityMutationResponse(AtlasClient.EntityResult entityResult) {
public static EntityMutationResponse toEntityMutationResponse(AtlasClient.EntityResult result) { CreateUpdateEntitiesResult result = new CreateUpdateEntitiesResult();
result.setEntityResult(entityResult);
return toEntityMutationResponse(result);
}
public static EntityMutationResponse toEntityMutationResponse(CreateUpdateEntitiesResult result) {
EntityMutationResponse response = new EntityMutationResponse(); EntityMutationResponse response = new EntityMutationResponse();
for (String guid : result.getCreatedEntities()) { for (String guid : result.getCreatedEntities()) {
AtlasEntityHeader header = new AtlasEntityHeader(); AtlasEntityHeader header = new AtlasEntityHeader();
...@@ -151,7 +160,7 @@ public class AtlasInstanceRestAdapters { ...@@ -151,7 +160,7 @@ public class AtlasInstanceRestAdapters {
response.addEntity(EntityMutations.EntityOperation.CREATE, header); response.addEntity(EntityMutations.EntityOperation.CREATE, header);
} }
for (String guid : result.getUpdateEntities()) { for (String guid : result.getUpdatedEntities()) {
AtlasEntityHeader header = new AtlasEntityHeader(); AtlasEntityHeader header = new AtlasEntityHeader();
header.setGuid(guid); header.setGuid(guid);
response.addEntity(EntityMutations.EntityOperation.UPDATE, header); response.addEntity(EntityMutations.EntityOperation.UPDATE, header);
...@@ -162,6 +171,10 @@ public class AtlasInstanceRestAdapters { ...@@ -162,6 +171,10 @@ public class AtlasInstanceRestAdapters {
header.setGuid(guid); header.setGuid(guid);
response.addEntity(EntityMutations.EntityOperation.DELETE, header); response.addEntity(EntityMutations.EntityOperation.DELETE, header);
} }
GuidMapping guidMapping = result.getGuidMapping();
if(guidMapping != null) {
response.setGuidAssignments(guidMapping.getGuidAssignments());
}
return response; return response;
} }
......
...@@ -23,7 +23,10 @@ import com.google.common.base.Preconditions; ...@@ -23,7 +23,10 @@ import com.google.common.base.Preconditions;
import org.apache.atlas.AtlasClient; import org.apache.atlas.AtlasClient;
import org.apache.atlas.AtlasConstants; import org.apache.atlas.AtlasConstants;
import org.apache.atlas.AtlasException; import org.apache.atlas.AtlasException;
import org.apache.atlas.CreateUpdateEntitiesResult;
import org.apache.atlas.EntityAuditEvent; import org.apache.atlas.EntityAuditEvent;
import org.apache.atlas.AtlasClient.EntityResult;
import org.apache.atlas.model.instance.GuidMapping;
import org.apache.atlas.services.MetadataService; import org.apache.atlas.services.MetadataService;
import org.apache.atlas.typesystem.IStruct; import org.apache.atlas.typesystem.IStruct;
import org.apache.atlas.typesystem.Referenceable; import org.apache.atlas.typesystem.Referenceable;
...@@ -127,13 +130,13 @@ public class EntityResource { ...@@ -127,13 +130,13 @@ public class EntityResource {
LOG.debug("submitting entities {} ", entityJson); LOG.debug("submitting entities {} ", entityJson);
} }
final List<String> guids = metadataService.createEntities(entities); final CreateUpdateEntitiesResult result = metadataService.createEntities(entities);
final List<String> guids = result.getEntityResult().getCreatedEntities();
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("Created entities {}", guids); LOG.debug("Created entities {}", guids);
} }
JSONObject response = getResponse(new AtlasClient.EntityResult(guids, null, null)); JSONObject response = getResponse(result);
URI locationURI = getLocationURI(guids); URI locationURI = getLocationURI(guids);
...@@ -179,13 +182,26 @@ public class EntityResource { ...@@ -179,13 +182,26 @@ public class EntityResource {
} }
private JSONObject getResponse(AtlasClient.EntityResult entityResult) throws AtlasException, JSONException { private JSONObject getResponse(AtlasClient.EntityResult entityResult) throws AtlasException, JSONException {
CreateUpdateEntitiesResult result = new CreateUpdateEntitiesResult();
result.setEntityResult(entityResult);
return getResponse(result);
}
private JSONObject getResponse(CreateUpdateEntitiesResult result) throws AtlasException, JSONException {
JSONObject response = new JSONObject(); JSONObject response = new JSONObject();
EntityResult entityResult = result.getEntityResult();
GuidMapping mapping = result.getGuidMapping();
response.put(AtlasClient.REQUEST_ID, Servlets.getRequestId()); response.put(AtlasClient.REQUEST_ID, Servlets.getRequestId());
response.put(AtlasClient.ENTITIES, new JSONObject(entityResult.toString()).get(AtlasClient.ENTITIES)); if(entityResult != null) {
String sampleEntityId = getSample(entityResult); response.put(AtlasClient.ENTITIES, new JSONObject(entityResult.toString()).get(AtlasClient.ENTITIES));
if (sampleEntityId != null) { String sampleEntityId = getSample(result.getEntityResult());
String entityDefinition = metadataService.getEntityDefinitionJson(sampleEntityId); if (sampleEntityId != null) {
response.put(AtlasClient.DEFINITION, new JSONObject(entityDefinition)); String entityDefinition = metadataService.getEntityDefinitionJson(sampleEntityId);
response.put(AtlasClient.DEFINITION, new JSONObject(entityDefinition));
}
}
if(mapping != null) {
response.put(AtlasClient.GUID_ASSIGNMENTS, new JSONObject(mapping.toString()).get(AtlasClient.GUID_ASSIGNMENTS));
} }
return response; return response;
} }
...@@ -218,13 +234,13 @@ public class EntityResource { ...@@ -218,13 +234,13 @@ public class EntityResource {
LOG.info("updating entities {} ", entityJson); LOG.info("updating entities {} ", entityJson);
} }
AtlasClient.EntityResult entityResult = metadataService.updateEntities(entities); CreateUpdateEntitiesResult result = metadataService.updateEntities(entities);
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("Updated entities: {}", entityResult); LOG.debug("Updated entities: {}", result.getEntityResult());
} }
JSONObject response = getResponse(entityResult); JSONObject response = getResponse(result);
return Response.ok(response).build(); return Response.ok(response).build();
} catch(EntityExistsException e) { } catch(EntityExistsException e) {
LOG.error("Unique constraint violation for entityDef={}", entityJson, e); LOG.error("Unique constraint violation for entityDef={}", entityJson, e);
...@@ -303,14 +319,14 @@ public class EntityResource { ...@@ -303,14 +319,14 @@ public class EntityResource {
Referenceable updatedEntity = Referenceable updatedEntity =
InstanceSerialization.fromJsonReferenceable(entityJson, true); InstanceSerialization.fromJsonReferenceable(entityJson, true);
AtlasClient.EntityResult entityResult = CreateUpdateEntitiesResult result =
metadataService.updateEntityByUniqueAttribute(entityType, attribute, value, updatedEntity); metadataService.updateEntityByUniqueAttribute(entityType, attribute, value, updatedEntity);
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("Updated entities: {}", entityResult); LOG.debug("Updated entities: {}", result.getEntityResult());
} }
JSONObject response = getResponse(entityResult); JSONObject response = getResponse(result);
return Response.ok(response).build(); return Response.ok(response).build();
} catch (ValueConversionException ve) { } catch (ValueConversionException ve) {
LOG.error("Unable to persist entity instance due to a deserialization error {} ", entityJson, ve); LOG.error("Unable to persist entity instance due to a deserialization error {} ", entityJson, ve);
...@@ -388,13 +404,13 @@ public class EntityResource { ...@@ -388,13 +404,13 @@ public class EntityResource {
Referenceable updatedEntity = Referenceable updatedEntity =
InstanceSerialization.fromJsonReferenceable(entityJson, true); InstanceSerialization.fromJsonReferenceable(entityJson, true);
AtlasClient.EntityResult entityResult = metadataService.updateEntityPartialByGuid(guid, updatedEntity); CreateUpdateEntitiesResult result = metadataService.updateEntityPartialByGuid(guid, updatedEntity);
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("Updated entities: {}", entityResult); LOG.debug("Updated entities: {}", result.getEntityResult());
} }
JSONObject response = getResponse(entityResult); JSONObject response = getResponse(result);
return Response.ok(response).build(); return Response.ok(response).build();
} catch (EntityNotFoundException e) { } catch (EntityNotFoundException e) {
LOG.error("An entity with GUID={} does not exist {} ", guid, entityJson, e); LOG.error("An entity with GUID={} does not exist {} ", guid, entityJson, e);
...@@ -429,13 +445,13 @@ public class EntityResource { ...@@ -429,13 +445,13 @@ public class EntityResource {
LOG.debug("Updating entity {} for property {} = {}", guid, property, value); LOG.debug("Updating entity {} for property {} = {}", guid, property, value);
} }
AtlasClient.EntityResult entityResult = metadataService.updateEntityAttributeByGuid(guid, property, value); CreateUpdateEntitiesResult result = metadataService.updateEntityAttributeByGuid(guid, property, value);
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("Updated entities: {}", entityResult); LOG.debug("Updated entities: {}", result.getEntityResult());
} }
JSONObject response = getResponse(entityResult); JSONObject response = getResponse(result);
return Response.ok(response).build(); return Response.ok(response).build();
} catch (EntityNotFoundException e) { } catch (EntityNotFoundException e) {
LOG.error("An entity with GUID={} does not exist {} ", guid, value, e); LOG.error("An entity with GUID={} does not exist {} ", guid, value, e);
...@@ -453,7 +469,7 @@ public class EntityResource { ...@@ -453,7 +469,7 @@ public class EntityResource {
* Delete entities from the repository identified by their guids (including their composite references) * Delete entities from the repository identified by their guids (including their composite references)
* or * or
* Deletes a single entity identified by its type and unique attribute value from the repository (including their composite references) * Deletes a single entity identified by its type and unique attribute value from the repository (including their composite references)
* *
* @param guids list of deletion candidate guids * @param guids list of deletion candidate guids
* or * or
* @param entityType the entity type * @param entityType the entity type
......
...@@ -20,6 +20,7 @@ package org.apache.atlas.web.rest; ...@@ -20,6 +20,7 @@ package org.apache.atlas.web.rest;
import org.apache.atlas.AtlasClient; import org.apache.atlas.AtlasClient;
import org.apache.atlas.AtlasErrorCode; import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.AtlasException; import org.apache.atlas.AtlasException;
import org.apache.atlas.CreateUpdateEntitiesResult;
import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.SearchFilter; import org.apache.atlas.model.SearchFilter;
import org.apache.atlas.model.instance.AtlasClassification; import org.apache.atlas.model.instance.AtlasClassification;
...@@ -100,7 +101,7 @@ public class EntitiesREST { ...@@ -100,7 +101,7 @@ public class EntitiesREST {
ITypedReferenceableInstance[] entitiesInOldFormat = restAdapters.getITypedReferenceables(entities.values()); ITypedReferenceableInstance[] entitiesInOldFormat = restAdapters.getITypedReferenceables(entities.values());
try { try {
final AtlasClient.EntityResult result = metadataService.updateEntities(entitiesInOldFormat); final CreateUpdateEntitiesResult result = metadataService.updateEntities(entitiesInOldFormat);
response = toEntityMutationResponse(result); response = toEntityMutationResponse(result);
} catch (AtlasException e) { } catch (AtlasException e) {
LOG.error("Exception while getting a typed reference for the entity ", e); LOG.error("Exception while getting a typed reference for the entity ", e);
......
...@@ -20,6 +20,7 @@ package org.apache.atlas.web.rest; ...@@ -20,6 +20,7 @@ package org.apache.atlas.web.rest;
import org.apache.atlas.AtlasClient; import org.apache.atlas.AtlasClient;
import org.apache.atlas.AtlasErrorCode; import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.AtlasException; import org.apache.atlas.AtlasException;
import org.apache.atlas.CreateUpdateEntitiesResult;
import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TypeCategory; import org.apache.atlas.model.TypeCategory;
import org.apache.atlas.model.instance.AtlasClassification; import org.apache.atlas.model.instance.AtlasClassification;
...@@ -151,7 +152,7 @@ public class EntityREST { ...@@ -151,7 +152,7 @@ public class EntityREST {
AtlasFormatConverter.ConverterContext ctx = new AtlasFormatConverter.ConverterContext(); AtlasFormatConverter.ConverterContext ctx = new AtlasFormatConverter.ConverterContext();
ctx.addEntity(entity); ctx.addEntity(entity);
Referenceable ref = restAdapters.getReferenceable(entity, ctx); Referenceable ref = restAdapters.getReferenceable(entity, ctx);
AtlasClient.EntityResult result = metadataService.updateEntityByUniqueAttribute(entityType, attribute, value, ref); CreateUpdateEntitiesResult result = metadataService.updateEntityByUniqueAttribute(entityType, attribute, value, ref);
return toEntityMutationResponse(result); return toEntityMutationResponse(result);
} }
......
...@@ -56,7 +56,7 @@ public class QuickStartV2IT extends BaseResourceIT { ...@@ -56,7 +56,7 @@ public class QuickStartV2IT extends BaseResourceIT {
} }
private AtlasEntity getDB(String dbName) throws AtlasServiceException, JSONException { private AtlasEntity getDB(String dbName) throws AtlasServiceException, JSONException {
AtlasEntity dbEntity = entitiesClientV2.getEntityByAttribute(QuickStartV2.DATABASE_TYPE, "name", dbName); AtlasEntity dbEntity = entitiesClientV2.getEntityByAttribute(QuickStartV2.DATABASE_TYPE, "name", dbName).get(0);
return dbEntity; return dbEntity;
} }
...@@ -73,14 +73,15 @@ public class QuickStartV2IT extends BaseResourceIT { ...@@ -73,14 +73,15 @@ public class QuickStartV2IT extends BaseResourceIT {
} }
private AtlasEntity getTable(String tableName) throws AtlasServiceException { private AtlasEntity getTable(String tableName) throws AtlasServiceException {
AtlasEntity tableEntity = entitiesClientV2.getEntityByAttribute(QuickStartV2.TABLE_TYPE, AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, tableName); AtlasEntity tableEntity = entitiesClientV2.getEntityByAttribute(QuickStartV2.TABLE_TYPE, AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, tableName).get(0);
return tableEntity; return tableEntity;
} }
private AtlasEntity getProcess(String processName) throws AtlasServiceException { private AtlasEntity getProcess(String processName) throws AtlasServiceException {
AtlasEntity processEntity = entitiesClientV2.getEntityByAttribute(QuickStartV2.LOAD_PROCESS_TYPE, AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, processName); AtlasEntity processEntity = entitiesClientV2.getEntityByAttribute(QuickStartV2.LOAD_PROCESS_TYPE, AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, processName).get(0);
return processEntity; return processEntity;
} }
private void verifyTrait(AtlasEntity table) throws AtlasServiceException { private void verifyTrait(AtlasEntity table) throws AtlasServiceException {
AtlasClassification.AtlasClassifications classfications = entitiesClientV2.getClassifications(table.getGuid()); AtlasClassification.AtlasClassifications classfications = entitiesClientV2.getClassifications(table.getGuid());
...@@ -115,7 +116,7 @@ public class QuickStartV2IT extends BaseResourceIT { ...@@ -115,7 +116,7 @@ public class QuickStartV2IT extends BaseResourceIT {
@Test @Test
public void testProcessIsAdded() throws AtlasServiceException, JSONException { public void testProcessIsAdded() throws AtlasServiceException, JSONException {
AtlasEntity loadProcess = entitiesClientV2.getEntityByAttribute(QuickStartV2.LOAD_PROCESS_TYPE, AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, AtlasEntity loadProcess = entitiesClientV2.getEntityByAttribute(QuickStartV2.LOAD_PROCESS_TYPE, AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME,
QuickStartV2.LOAD_SALES_DAILY_PROCESS); QuickStartV2.LOAD_SALES_DAILY_PROCESS).get(0);
Map loadProcessAttribs = loadProcess.getAttributes(); Map loadProcessAttribs = loadProcess.getAttributes();
assertEquals(QuickStartV2.LOAD_SALES_DAILY_PROCESS, loadProcessAttribs.get(AtlasClient.NAME)); assertEquals(QuickStartV2.LOAD_SALES_DAILY_PROCESS, loadProcessAttribs.get(AtlasClient.NAME));
...@@ -168,7 +169,7 @@ public class QuickStartV2IT extends BaseResourceIT { ...@@ -168,7 +169,7 @@ public class QuickStartV2IT extends BaseResourceIT {
@Test @Test
public void testViewIsAdded() throws AtlasServiceException, JSONException { public void testViewIsAdded() throws AtlasServiceException, JSONException {
AtlasEntity view = entitiesClientV2.getEntityByAttribute(QuickStartV2.VIEW_TYPE, AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, QuickStartV2.PRODUCT_DIM_VIEW); AtlasEntity view = entitiesClientV2.getEntityByAttribute(QuickStartV2.VIEW_TYPE, AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, QuickStartV2.PRODUCT_DIM_VIEW).get(0);
Map<String, Object> viewAttributes = view.getAttributes(); Map<String, Object> viewAttributes = view.getAttributes();
assertEquals(QuickStartV2.PRODUCT_DIM_VIEW, viewAttributes.get(AtlasClient.NAME)); assertEquals(QuickStartV2.PRODUCT_DIM_VIEW, viewAttributes.get(AtlasClient.NAME));
......
...@@ -18,16 +18,24 @@ ...@@ -18,16 +18,24 @@
package org.apache.atlas.web.resources; package org.apache.atlas.web.resources;
import com.google.common.collect.ImmutableList; import static org.testng.Assert.assertEquals;
import com.google.common.collect.ImmutableSet; import static org.testng.Assert.assertNotNull;
import com.google.gson.Gson; import static org.testng.Assert.fail;
import com.google.gson.JsonSyntaxException;
import com.google.inject.Inject; import java.util.ArrayList;
import com.sun.jersey.api.client.ClientResponse; import java.util.Collections;
import com.sun.jersey.core.util.MultivaluedMapImpl; import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import org.apache.atlas.AtlasClient; import org.apache.atlas.AtlasClient;
import org.apache.atlas.AtlasServiceException; import org.apache.atlas.AtlasServiceException;
import org.apache.atlas.EntityAuditEvent; import org.apache.atlas.EntityAuditEvent;
import org.apache.atlas.model.instance.GuidMapping;
import org.apache.atlas.notification.NotificationConsumer; import org.apache.atlas.notification.NotificationConsumer;
import org.apache.atlas.notification.NotificationInterface; import org.apache.atlas.notification.NotificationInterface;
import org.apache.atlas.notification.NotificationModule; import org.apache.atlas.notification.NotificationModule;
...@@ -61,18 +69,13 @@ import org.testng.annotations.DataProvider; ...@@ -61,18 +69,13 @@ import org.testng.annotations.DataProvider;
import org.testng.annotations.Guice; import org.testng.annotations.Guice;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import javax.ws.rs.core.MultivaluedMap; import com.google.common.collect.ImmutableList;
import javax.ws.rs.core.Response; import com.google.common.collect.ImmutableSet;
import java.util.ArrayList; import com.google.gson.Gson;
import java.util.Collections; import com.google.gson.JsonSyntaxException;
import java.util.HashMap; import com.google.inject.Inject;
import java.util.List; import com.sun.jersey.api.client.ClientResponse;
import java.util.Map; import com.sun.jersey.core.util.MultivaluedMapImpl;
import java.util.UUID;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.fail;
/** /**
...@@ -110,6 +113,66 @@ public class EntityJerseyResourceIT extends BaseResourceIT { ...@@ -110,6 +113,66 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
} }
@Test @Test
public void testCreateNestedEntities() throws Exception {
Referenceable databaseInstance = new Referenceable(DATABASE_TYPE);
databaseInstance.set("name", "db1");
databaseInstance.set("description", "foo database");
int nTables = 5;
int colsPerTable=3;
List<Referenceable> tables = new ArrayList<>();
List<Referenceable> allColumns = new ArrayList<>();
for(int i = 0; i < nTables; i++) {
String tableName = "db1-table-" + i;
Referenceable tableInstance =
new Referenceable(HIVE_TABLE_TYPE);
tableInstance.set("name", tableName);
tableInstance.set(AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, tableName);
tableInstance.set("db", databaseInstance);
tableInstance.set("description", tableName + " table");
tables.add(tableInstance);
List<Referenceable> columns = new ArrayList<>();
for(int j = 0; j < colsPerTable; j++) {
Referenceable columnInstance = new Referenceable(COLUMN_TYPE);
columnInstance.set("name", tableName + "-col-" + j);
columnInstance.set("dataType", "String");
columnInstance.set("comment", "column " + j + " for table " + i);
allColumns.add(columnInstance);
columns.add(columnInstance);
}
tableInstance.set("columns", columns);
}
//Create the tables. The database and columns should be created automatically, since
//the tables reference them.
JSONArray entityArray = new JSONArray(tables.size());
for(int i = 0; i < tables.size(); i++) {
Referenceable table = tables.get(i);
entityArray.put(InstanceSerialization.toJson(table, true));
}
String json = entityArray.toString();
JSONObject response = atlasClientV1.callAPIWithBodyAndParams(AtlasClient.API.CREATE_ENTITY, json);
GuidMapping guidMapping = GuidMapping.fromString(response.toString());
Map<String,String> guidsCreated = guidMapping.getGuidAssignments();
assertEquals(guidsCreated.size(), nTables * colsPerTable + nTables + 1);
assertNotNull(guidsCreated.get(databaseInstance.getId()._getId()));
for(Referenceable r : allColumns) {
assertNotNull(guidsCreated.get(r.getId()._getId()));
}
for(Referenceable r : tables) {
assertNotNull(guidsCreated.get(r.getId()._getId()));
}
}
@Test
public void testSubmitEntity() throws Exception { public void testSubmitEntity() throws Exception {
tableInstance = createHiveTableInstanceBuiltIn(DATABASE_NAME, TABLE_NAME, dbId); tableInstance = createHiveTableInstanceBuiltIn(DATABASE_NAME, TABLE_NAME, dbId);
tableId = createInstance(tableInstance); tableId = createInstance(tableInstance);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment