diff --git a/src/main/java/org/caosdb/server/grpc/EntityTransactionServiceImpl.java b/src/main/java/org/caosdb/server/grpc/EntityTransactionServiceImpl.java index 3aa9954e4d1bcf28173dba4405cfff3574c1e562..e83e89c75f8d7f39c54447f7848f9644ca72d9f2 100644 --- a/src/main/java/org/caosdb/server/grpc/EntityTransactionServiceImpl.java +++ b/src/main/java/org/caosdb/server/grpc/EntityTransactionServiceImpl.java @@ -15,6 +15,7 @@ import org.caosdb.api.entity.v1alpha1.DeleteRequest; import org.caosdb.api.entity.v1alpha1.DeleteResponse; import org.caosdb.api.entity.v1alpha1.Entity; import org.caosdb.api.entity.v1alpha1.Entity.Builder; +import org.caosdb.api.entity.v1alpha1.EntityRequest; import org.caosdb.api.entity.v1alpha1.EntityResponse; import org.caosdb.api.entity.v1alpha1.EntityRole; import org.caosdb.api.entity.v1alpha1.EntityTransactionServiceGrpc.EntityTransactionServiceImplBase; @@ -590,37 +591,26 @@ public class EntityTransactionServiceImpl extends EntityTransactionServiceImplBa final WritableContainer container = new WritableContainer( SecurityUtils.getSubject(), getTimestamp(), getSRID(), new HashMap<String, String>()); - for (final TransactionRequest request : requests.getRequestsList()) { - switch (request.getWrappedRequestsCase()) { + + // put entities into the transaction object + for (final TransactionRequest sub_request : requests.getRequestsList()) { + switch (sub_request.getWrappedRequestsCase()) { case INSERT_REQUEST: - final InsertRequest insertRequest = request.getInsertRequest(); - final Entity insertEntity = insertRequest.getEntityRequest().getEntity(); + { + final InsertRequest insertRequest = sub_request.getInsertRequest(); + final Entity insertEntity = insertRequest.getEntityRequest().getEntity(); - try { final InsertEntity entity = new InsertEntity( insertEntity.getName().isEmpty() ? null : insertEntity.getName(), convert(insertEntity.getRole())); - entity.setName(insertEntity.getName().isEmpty() ? null : insertEntity.getName()); convert(insertEntity, entity); - if (insertRequest.getEntityRequest().hasUploadId()) { - final FileProperties uploadFile = - fileTransmissionService.getUploadFile( - insertRequest.getEntityRequest().getUploadId()); - if (uploadFile == null) { - entity.addError(ServerMessages.FILE_HAS_NOT_BEEN_UPLOAED); - } else { - container.addFile(uploadFile.getTmpIdentifyer(), uploadFile); - entity.getFileProperties().setTmpIdentifyer(uploadFile.getTmpIdentifyer()); - } - } + addFileUpload(container, entity, insertRequest.getEntityRequest()); container.add(entity); - } catch (final NumberFormatException e) { - // ID wasn't an integer - we handle this below. } break; case UPDATE_REQUEST: - final UpdateRequest updateRequest = request.getUpdateRequest(); + final UpdateRequest updateRequest = sub_request.getUpdateRequest(); final Entity updateEntity = updateRequest.getEntityRequest().getEntity(); try { @@ -628,44 +618,38 @@ public class EntityTransactionServiceImpl extends EntityTransactionServiceImplBa new UpdateEntity(getId(updateEntity.getId()), convert(updateEntity.getRole())); entity.setName(updateEntity.getName().isEmpty() ? null : updateEntity.getName()); convert(updateEntity, entity); - if (updateRequest.getEntityRequest().hasUploadId()) { - final FileProperties uploadFile = - fileTransmissionService.getUploadFile( - updateRequest.getEntityRequest().getUploadId()); - if (uploadFile == null) { - entity.addError(ServerMessages.FILE_HAS_NOT_BEEN_UPLOAED); - } else { - container.addFile(uploadFile.getTmpIdentifyer(), uploadFile); - entity.getFileProperties().setTmpIdentifyer(uploadFile.getTmpIdentifyer()); - } - } + addFileUpload(container, entity, updateRequest.getEntityRequest()); container.add(entity); } catch (final NumberFormatException e) { - // ID wasn't an integer - we handle this below. + // ID wasn't an integer + return failedWriteDueToStringId(requests); } break; case DELETE_REQUEST: - final DeleteRequest deleteRequest = request.getDeleteRequest(); + final DeleteRequest deleteRequest = sub_request.getDeleteRequest(); try { final DeleteEntity entity = new DeleteEntity(getId(deleteRequest.getId())); container.add(entity); } catch (final NumberFormatException e) { - // ID wasn't an integer - we handle this below + // ID wasn't an integer + return failedWriteDueToStringId(requests); } break; default: throw new CaosDBException( "Cannot process a " - + request.getWrappedRequestsCase().name() + + sub_request.getWrappedRequestsCase().name() + " in a write request."); } } + // execute the transaction final WriteTransaction transaction = new WriteTransaction(container); transaction.setNoIdIsError(false); transaction.execute(); + // put inserted/updated/deleted entities back into the response for (final EntityInterface entity : container) { final IdResponse.Builder idResponse = IdResponse.newBuilder(); if (entity.getId() != null) { @@ -688,52 +672,83 @@ public class EntityTransactionServiceImpl extends EntityTransactionServiceImplBa .setDeleteResponse(DeleteResponse.newBuilder().setIdResponse(idResponse)); } } + return builder.build(); + } + + /** + * Handle a request which contains string id (which cannot be converted to integer ids) and return + * a response which has the "ENTITY_DOES_NOT_EXIST" error for all entities with affected ids. + * + * @param request + * @return + */ + private MultiTransactionResponse failedWriteDueToStringId(final MultiTransactionRequest request) { + final org.caosdb.api.entity.v1alpha1.MultiTransactionResponse.Builder builder = + MultiTransactionResponse.newBuilder(); + for (final TransactionRequest subRequest : request.getRequestsList()) { + final IdResponse.Builder idResponse = IdResponse.newBuilder(); + switch (subRequest.getWrappedRequestsCase()) { + case INSERT_REQUEST: + builder + .addResponsesBuilder() + .setInsertResponse(InsertResponse.newBuilder().setIdResponse(idResponse)); - // Add those entities which have not been processed because the have a string id - for (final TransactionRequest request : requests.getRequestsList()) { - final String id = ""; - switch (request.getWrappedRequestsCase()) { + break; case UPDATE_REQUEST: - final UpdateRequest updateRequest = request.getUpdateRequest(); + final UpdateRequest updateRequest = subRequest.getUpdateRequest(); final Entity updateEntity = updateRequest.getEntityRequest().getEntity(); + idResponse.setId(updateEntity.getId()); try { - final UpdateEntity entity = - new UpdateEntity(getId(updateEntity.getId()), convert(updateEntity.getRole())); - entity.setName(updateEntity.getName().isEmpty() ? null : updateEntity.getName()); - container.add(entity); + getId(updateEntity.getId()); } catch (final NumberFormatException e) { - // ID wasn't an integer - we handle this below. + // ID wasn't an integer + idResponse.addErrors(convert(ServerMessages.ENTITY_DOES_NOT_EXIST)); } + builder + .addResponsesBuilder() + .setUpdateResponse(UpdateResponse.newBuilder().setIdResponse(idResponse)); + break; case DELETE_REQUEST: - final DeleteRequest deleteRequest = request.getDeleteRequest(); + final DeleteRequest deleteRequest = subRequest.getDeleteRequest(); + idResponse.setId(deleteRequest.getId()); try { - final DeleteEntity entity = new DeleteEntity(getId(deleteRequest.getId())); - container.add(entity); - + getId(deleteRequest.getId()); } catch (final NumberFormatException e) { - // ID wasn't an integer - we handle this below + // ID wasn't an integer + idResponse.addErrors(convert(ServerMessages.ENTITY_DOES_NOT_EXIST)); } - default: + builder + .addResponsesBuilder() + .setDeleteResponse(DeleteResponse.newBuilder().setIdResponse(idResponse)); break; - } - if (!id.isBlank()) { - try { - getId(id); - } catch (final NumberFormatException e) { - // ID wasn't an integer - the server doesn't support string id's yet, so that entity - // cannot exist. - final IdResponse.Builder idResponse = IdResponse.newBuilder().setId(id); - idResponse.addErrors(convert(ServerMessages.ENTITY_DOES_NOT_EXIST)); - builder.addResponses( - TransactionResponse.newBuilder() - .setDeleteResponse(DeleteResponse.newBuilder().setIdResponse(idResponse))); - } + default: + throw new CaosDBException( + "Cannot process a " + + subRequest.getWrappedRequestsCase().name() + + " in a write request."); } } + return builder.build(); } + private void addFileUpload( + final WritableContainer container, + final EntityInterface entity, + final EntityRequest entityRequest) { + if (entityRequest.hasUploadId()) { + final FileProperties uploadFile = + fileTransmissionService.getUploadFile(entityRequest.getUploadId()); + if (uploadFile == null) { + entity.addError(ServerMessages.FILE_HAS_NOT_BEEN_UPLOAED); + } else { + container.addFile(uploadFile.getTmpIdentifyer(), uploadFile); + entity.getFileProperties().setTmpIdentifyer(uploadFile.getTmpIdentifyer()); + } + } + } + private Role convert(final EntityRole role) { switch (role) { case ENTITY_ROLE_FILE: @@ -794,6 +809,7 @@ public class EntityTransactionServiceImpl extends EntityTransactionServiceImplBa } private EntityInterface convert(final Entity from, final EntityInterface entity) { + entity.setName(from.getName().isEmpty() ? null : from.getName()); entity.setDescription(from.getDescription().isBlank() ? null : from.getDescription()); if (!from.getUnit().isBlank()) { entity.addProperty(getUnit(from.getUnit()));