blob: 6e0766dec85c242493e78f7f74147ab1657750b2 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.atlas.repository.converters;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.apache.atlas.AtlasClient;
import org.apache.atlas.AtlasClient.EntityResult;
import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.AtlasException;
import org.apache.atlas.CreateUpdateEntitiesResult;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TypeCategory;
import org.apache.atlas.model.instance.AtlasClassification;
import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo;
import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.model.instance.EntityMutationResponse;
import org.apache.atlas.model.instance.EntityMutations;
import org.apache.atlas.model.instance.EntityMutations.EntityOperation;
import org.apache.atlas.model.instance.GuidMapping;
import org.apache.atlas.services.MetadataService;
import org.apache.atlas.type.AtlasClassificationType;
import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasType;
import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.atlas.typesystem.IReferenceableInstance;
import org.apache.atlas.typesystem.IStruct;
import org.apache.atlas.typesystem.ITypedReferenceableInstance;
import org.apache.atlas.typesystem.ITypedStruct;
import org.apache.atlas.typesystem.Referenceable;
import org.apache.atlas.typesystem.Struct;
import org.apache.atlas.typesystem.exception.EntityExistsException;
import org.apache.atlas.typesystem.exception.EntityNotFoundException;
import org.apache.atlas.typesystem.exception.TraitNotFoundException;
import org.apache.atlas.typesystem.exception.TypeNotFoundException;
import org.apache.atlas.repository.converters.AtlasFormatConverter.ConverterContext;
import org.apache.atlas.typesystem.types.ValueConversionException;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@Singleton
public class AtlasInstanceConverter {
private static final Logger LOG = LoggerFactory.getLogger(AtlasInstanceConverter.class);
@Inject
private AtlasTypeRegistry typeRegistry;
@Inject
private AtlasFormatConverters instanceFormatters;
@Inject
private MetadataService metadataService;
public ITypedReferenceableInstance[] getITypedReferenceables(Collection<AtlasEntity> entities) throws AtlasBaseException {
ITypedReferenceableInstance[] entitiesInOldFormat = new ITypedReferenceableInstance[entities.size()];
AtlasFormatConverter.ConverterContext ctx = new AtlasFormatConverter.ConverterContext();
for(Iterator<AtlasEntity> i = entities.iterator(); i.hasNext(); ) {
ctx.addEntity(i.next());
}
Iterator<AtlasEntity> entityIterator = entities.iterator();
for (int i = 0; i < entities.size(); i++) {
ITypedReferenceableInstance typedInstance = getITypedReferenceable(entityIterator.next());
entitiesInOldFormat[i] = typedInstance;
}
return entitiesInOldFormat;
}
public ITypedReferenceableInstance getITypedReferenceable(AtlasEntity entity) throws AtlasBaseException {
try {
return metadataService.getEntityDefinition(entity.getGuid());
} catch (AtlasException e) {
LOG.error("Exception while getting a typed reference for the entity ", e);
throw toAtlasBaseException(e);
}
}
public ITypedReferenceableInstance getITypedReferenceable(String guid) throws AtlasBaseException {
try {
return metadataService.getEntityDefinition(guid);
} catch (AtlasException e) {
LOG.error("Exception while getting a typed reference for the entity ", e);
throw toAtlasBaseException(e);
}
}
public Referenceable getReferenceable(AtlasEntity entity, final ConverterContext ctx) throws AtlasBaseException {
AtlasFormatConverter converter = instanceFormatters.getConverter(TypeCategory.ENTITY);
AtlasType entityType = typeRegistry.getType(entity.getTypeName());
Referenceable ref = (Referenceable) converter.fromV2ToV1(entity, entityType, ctx);
return ref;
}
public ITypedStruct getTrait(AtlasClassification classification) throws AtlasBaseException {
AtlasFormatConverter converter = instanceFormatters.getConverter(TypeCategory.CLASSIFICATION);
AtlasType classificationType = typeRegistry.getType(classification.getTypeName());
Struct trait = (Struct)converter.fromV2ToV1(classification, classificationType, new ConverterContext());
try {
return metadataService.createTraitInstance(trait);
} catch (AtlasException e) {
LOG.error("Exception while getting a typed reference for the entity ", e);
throw toAtlasBaseException(e);
}
}
public AtlasClassification getClassification(IStruct classification) throws AtlasBaseException {
AtlasFormatConverter converter = instanceFormatters.getConverter(TypeCategory.CLASSIFICATION);
AtlasClassificationType classificationType = typeRegistry.getClassificationTypeByName(classification.getTypeName());
if (classificationType == null) {
throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, TypeCategory.CLASSIFICATION.name(), classification.getTypeName());
}
AtlasClassification ret = (AtlasClassification)converter.fromV1ToV2(classification, classificationType, new AtlasFormatConverter.ConverterContext());
return ret;
}
public AtlasEntitiesWithExtInfo toAtlasEntity(IReferenceableInstance referenceable) throws AtlasBaseException {
AtlasEntityFormatConverter converter = (AtlasEntityFormatConverter) instanceFormatters.getConverter(TypeCategory.ENTITY);
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(referenceable.getTypeName());
if (entityType == null) {
throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, TypeCategory.ENTITY.name(), referenceable.getTypeName());
}
// validate
try {
metadataService.validateAndConvertToTypedInstance(referenceable, entityType.getTypeName());
} catch (AtlasException excp) {
throw toAtlasBaseException(excp);
}
ConverterContext ctx = new ConverterContext();
AtlasEntity entity = converter.fromV1ToV2(referenceable, entityType, ctx);
ctx.addEntity(entity);
return ctx.getEntities();
}
public static EntityMutationResponse toEntityMutationResponse(AtlasClient.EntityResult entityResult) {
CreateUpdateEntitiesResult result = new CreateUpdateEntitiesResult();
result.setEntityResult(entityResult);
return toEntityMutationResponse(result);
}
public static EntityMutationResponse toEntityMutationResponse(CreateUpdateEntitiesResult result) {
EntityMutationResponse response = new EntityMutationResponse();
for (String guid : result.getCreatedEntities()) {
AtlasEntityHeader header = new AtlasEntityHeader();
header.setGuid(guid);
response.addEntity(EntityMutations.EntityOperation.CREATE, header);
}
for (String guid : result.getUpdatedEntities()) {
AtlasEntityHeader header = new AtlasEntityHeader();
header.setGuid(guid);
response.addEntity(EntityMutations.EntityOperation.UPDATE, header);
}
for (String guid : result.getDeletedEntities()) {
AtlasEntityHeader header = new AtlasEntityHeader();
header.setGuid(guid);
response.addEntity(EntityMutations.EntityOperation.DELETE, header);
}
GuidMapping guidMapping = result.getGuidMapping();
if(guidMapping != null) {
response.setGuidAssignments(guidMapping.getGuidAssignments());
}
return response;
}
public static AtlasBaseException toAtlasBaseException(AtlasException e) {
if (e instanceof EntityExistsException) {
return new AtlasBaseException(AtlasErrorCode.INSTANCE_ALREADY_EXISTS, e.getMessage());
}
if ( e instanceof EntityNotFoundException || e instanceof TraitNotFoundException) {
return new AtlasBaseException(AtlasErrorCode.INSTANCE_NOT_FOUND, e.getMessage());
}
if ( e instanceof TypeNotFoundException) {
return new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, e.getMessage());
}
if (e instanceof ValueConversionException) {
return new AtlasBaseException(AtlasErrorCode.INVALID_VALUE, e, e.getMessage());
}
return new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, e.getMessage());
}
public AtlasEntity.AtlasEntitiesWithExtInfo toAtlasEntities(List<Referenceable> referenceables) throws AtlasBaseException {
if (LOG.isDebugEnabled()) {
LOG.debug("==> toAtlasEntities");
}
AtlasFormatConverter.ConverterContext context = new AtlasFormatConverter.ConverterContext();
for (Referenceable referenceable : referenceables) {
AtlasEntity entity = fromV1toV2Entity(referenceable, context);
context.addEntity(entity);
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== toAtlasEntities");
}
return context.getEntities();
}
public AtlasEntitiesWithExtInfo toAtlasEntities(String entitiesJson) throws AtlasBaseException, AtlasException {
ITypedReferenceableInstance[] referenceables = metadataService.deserializeClassInstances(entitiesJson);
AtlasEntityFormatConverter converter = (AtlasEntityFormatConverter) instanceFormatters.getConverter(TypeCategory.ENTITY);
ConverterContext context = new ConverterContext();
AtlasEntitiesWithExtInfo ret = null;
if (referenceables != null) {
for (IReferenceableInstance referenceable : referenceables) {
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(referenceable.getTypeName());
if (entityType == null) {
throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, TypeCategory.ENTITY.name(), referenceable.getTypeName());
}
AtlasEntity entity = converter.fromV1ToV2(referenceable, entityType, context);
context.addEntity(entity);
}
ret = context.getEntities();
}
return ret;
}
private AtlasEntity fromV1toV2Entity(Referenceable referenceable, AtlasFormatConverter.ConverterContext context) throws AtlasBaseException {
if (LOG.isDebugEnabled()) {
LOG.debug("==> fromV1toV2Entity");
}
AtlasEntityFormatConverter converter = (AtlasEntityFormatConverter) instanceFormatters.getConverter(TypeCategory.ENTITY);
AtlasEntity entity = converter.fromV1ToV2(referenceable, typeRegistry.getType(referenceable.getTypeName()), context);
if (LOG.isDebugEnabled()) {
LOG.debug("<== fromV1toV2Entity");
}
return entity;
}
public CreateUpdateEntitiesResult toCreateUpdateEntitiesResult(EntityMutationResponse reponse) {
CreateUpdateEntitiesResult ret = null;
if (reponse != null) {
Map<EntityOperation, List<AtlasEntityHeader>> mutatedEntities = reponse.getMutatedEntities();
Map<String, String> guidAssignments = reponse.getGuidAssignments();
ret = new CreateUpdateEntitiesResult();
if (MapUtils.isNotEmpty(guidAssignments)) {
ret.setGuidMapping(new GuidMapping(guidAssignments));
}
if (MapUtils.isNotEmpty(mutatedEntities)) {
EntityResult entityResult = new EntityResult();
for (Map.Entry<EntityOperation, List<AtlasEntityHeader>> e : mutatedEntities.entrySet()) {
switch (e.getKey()) {
case CREATE:
List<AtlasEntityHeader> createdEntities = mutatedEntities.get(EntityOperation.CREATE);
if (CollectionUtils.isNotEmpty(createdEntities)) {
Collections.reverse(createdEntities);
entityResult.set(EntityResult.OP_CREATED, getGuids(createdEntities));
}
break;
case UPDATE:
List<AtlasEntityHeader> updatedEntities = mutatedEntities.get(EntityOperation.UPDATE);
if (CollectionUtils.isNotEmpty(updatedEntities)) {
Collections.reverse(updatedEntities);
entityResult.set(EntityResult.OP_UPDATED, getGuids(updatedEntities));
}
break;
case PARTIAL_UPDATE:
List<AtlasEntityHeader> partialUpdatedEntities = mutatedEntities.get(EntityOperation.PARTIAL_UPDATE);
if (CollectionUtils.isNotEmpty(partialUpdatedEntities)) {
Collections.reverse(partialUpdatedEntities);
entityResult.set(EntityResult.OP_UPDATED, getGuids(partialUpdatedEntities));
}
break;
case DELETE:
List<AtlasEntityHeader> deletedEntities = mutatedEntities.get(EntityOperation.DELETE);
if (CollectionUtils.isNotEmpty(deletedEntities)) {
Collections.reverse(deletedEntities);
entityResult.set(EntityResult.OP_DELETED, getGuids(deletedEntities));
}
break;
}
}
ret.setEntityResult(entityResult);
}
}
return ret;
}
public List<String> getGuids(List<AtlasEntityHeader> entities) {
List<String> ret = null;
if (CollectionUtils.isNotEmpty(entities)) {
ret = new ArrayList<>();
for (AtlasEntityHeader entity : entities) {
ret.add(entity.getGuid());
}
}
return ret;
}
}