Search in sources :

Example 1 with UserException

use of com.torodb.core.exceptions.user.UserException in project torodb by torodb.

the class InsertImplementation method apply.

@Override
public Status<InsertResult> apply(Request req, Command<? super InsertArgument, ? super InsertResult> command, InsertArgument arg, WriteMongodTransaction context) {
    mongodMetrics.getInserts().mark(arg.getDocuments().size());
    Stream<KvDocument> docsToInsert = arg.getDocuments().stream().map(FromBsonValueTranslator.getInstance()).map((v) -> (KvDocument) v);
    try {
        if (!context.getTorodTransaction().existsCollection(req.getDatabase(), arg.getCollection())) {
            context.getTorodTransaction().createIndex(req.getDatabase(), arg.getCollection(), Constants.ID_INDEX, ImmutableList.<IndexFieldInfo>of(new IndexFieldInfo(new AttributeReference(Arrays.asList(new Key[] { new ObjectKey(Constants.ID) })), FieldIndexOrdering.ASC.isAscending())), true);
        }
        context.getTorodTransaction().insert(req.getDatabase(), arg.getCollection(), docsToInsert);
    } catch (UserException ex) {
        //TODO: Improve error reporting
        return Status.from(ErrorCode.COMMAND_FAILED, ex.getLocalizedMessage());
    }
    return Status.ok(new InsertResult(arg.getDocuments().size()));
}
Also used : KvDocument(com.torodb.kvdocument.values.KvDocument) InsertResult(com.torodb.mongodb.commands.signatures.general.InsertCommand.InsertResult) AttributeReference(com.torodb.core.language.AttributeReference) ObjectKey(com.torodb.core.language.AttributeReference.ObjectKey) IndexFieldInfo(com.torodb.torod.IndexFieldInfo) UserException(com.torodb.core.exceptions.user.UserException)

Example 2 with UserException

use of com.torodb.core.exceptions.user.UserException in project torodb by torodb.

the class UpdateImplementation method apply.

@Override
public Status<UpdateResult> apply(Request req, Command<? super UpdateArgument, ? super UpdateResult> command, UpdateArgument arg, WriteMongodTransaction context) {
    UpdateStatus updateStatus = new UpdateStatus();
    try {
        if (!context.getTorodTransaction().existsCollection(req.getDatabase(), arg.getCollection())) {
            context.getTorodTransaction().createIndex(req.getDatabase(), arg.getCollection(), Constants.ID_INDEX, ImmutableList.<IndexFieldInfo>of(new IndexFieldInfo(new AttributeReference(Arrays.asList(new Key[] { new ObjectKey(Constants.ID) })), FieldIndexOrdering.ASC.isAscending())), true);
        }
        for (UpdateStatement updateStatement : arg.getStatements()) {
            BsonDocument query = updateStatement.getQuery();
            UpdateAction updateAction = UpdateActionTranslator.translate(updateStatement.getUpdate());
            Cursor<ToroDocument> candidatesCursor;
            switch(query.size()) {
                case 0:
                    {
                        candidatesCursor = context.getTorodTransaction().findAll(req.getDatabase(), arg.getCollection()).asDocCursor();
                        break;
                    }
                case 1:
                    {
                        try {
                            candidatesCursor = findByAttribute(context.getTorodTransaction(), req.getDatabase(), arg.getCollection(), query);
                        } catch (CommandFailed ex) {
                            return Status.from(ex);
                        }
                        break;
                    }
                default:
                    {
                        return Status.from(ErrorCode.COMMAND_FAILED, "The given query is not supported right now");
                    }
            }
            if (candidatesCursor.hasNext()) {
                try {
                    Stream<List<ToroDocument>> candidatesbatchStream;
                    if (updateStatement.isMulti()) {
                        candidatesbatchStream = StreamSupport.stream(Spliterators.spliteratorUnknownSize(candidatesCursor.batch(100), Spliterator.ORDERED), false);
                    } else {
                        candidatesbatchStream = Stream.of(ImmutableList.of(candidatesCursor.next()));
                    }
                    Stream<KvDocument> updatedCandidates = candidatesbatchStream.map(candidates -> {
                        updateStatus.increaseCandidates(candidates.size());
                        context.getTorodTransaction().delete(req.getDatabase(), arg.getCollection(), candidates);
                        return candidates;
                    }).flatMap(l -> l.stream()).map(candidate -> {
                        try {
                            updateStatus.increaseUpdated();
                            return update(updateAction, candidate);
                        } catch (UserException userException) {
                            throw new UserWrappedException(userException);
                        }
                    });
                    context.getTorodTransaction().insert(req.getDatabase(), arg.getCollection(), updatedCandidates);
                } catch (UserWrappedException userWrappedException) {
                    throw userWrappedException.getCause();
                }
            } else if (updateStatement.isUpsert()) {
                KvDocument toInsertCandidate;
                if (updateAction instanceof SetDocumentUpdateAction) {
                    toInsertCandidate = ((SetDocumentUpdateAction) updateAction).getNewValue();
                } else {
                    toInsertCandidate = update(updateAction, new ToroDocument(-1, (KvDocument) MongoWpConverter.translate(query)));
                }
                if (!toInsertCandidate.containsKey(Constants.ID)) {
                    KvDocument.Builder builder = new KvDocument.Builder();
                    for (DocEntry<?> entry : toInsertCandidate) {
                        builder.putValue(entry.getKey(), entry.getValue());
                    }
                    builder.putValue(Constants.ID, MongoWpConverter.translate(objectIdFactory.consumeObjectId()));
                    toInsertCandidate = builder.build();
                }
                updateStatus.increaseCandidates(1);
                updateStatus.increaseCreated(toInsertCandidate.get(Constants.ID));
                Stream<KvDocument> toInsertCandidates = Stream.of(toInsertCandidate);
                context.getTorodTransaction().insert(req.getDatabase(), arg.getCollection(), toInsertCandidates);
            }
        }
    } catch (UserException ex) {
        //TODO: Improve error reporting
        return Status.from(ErrorCode.COMMAND_FAILED, ex.getLocalizedMessage());
    }
    mongodMetrics.getUpdateModified().mark(updateStatus.updated);
    mongodMetrics.getUpdateMatched().mark(updateStatus.candidates);
    mongodMetrics.getUpdateUpserted().mark(updateStatus.upsertResults.size());
    return Status.ok(new UpdateResult(updateStatus.updated, updateStatus.candidates, ImmutableList.copyOf(updateStatus.upsertResults)));
}
Also used : Request(com.eightkdata.mongowp.server.api.Request) UpdateActionTranslator(com.torodb.mongodb.language.UpdateActionTranslator) Arrays(java.util.Arrays) UpdatedToroDocumentBuilder(com.torodb.mongodb.language.update.UpdatedToroDocumentBuilder) FieldIndexOrdering(com.torodb.core.transaction.metainf.FieldIndexOrdering) Spliterators(java.util.Spliterators) BsonDocument(com.eightkdata.mongowp.bson.BsonDocument) WriteTorodbCommandImpl(com.torodb.mongodb.commands.impl.WriteTorodbCommandImpl) UpdateAction(com.torodb.mongodb.language.update.UpdateAction) UpdateStatement(com.torodb.mongodb.commands.signatures.general.UpdateCommand.UpdateStatement) Singleton(javax.inject.Singleton) ToroDocument(com.torodb.core.document.ToroDocument) UpdateResult(com.torodb.mongodb.commands.signatures.general.UpdateCommand.UpdateResult) ArrayList(java.util.ArrayList) ObjectKey(com.torodb.core.language.AttributeReference.ObjectKey) IndexFieldInfo(com.torodb.torod.IndexFieldInfo) Inject(javax.inject.Inject) KvValue(com.torodb.kvdocument.values.KvValue) ImmutableList(com.google.common.collect.ImmutableList) MongoWpConverter(com.torodb.kvdocument.conversion.mongowp.MongoWpConverter) StreamSupport(java.util.stream.StreamSupport) Builder(com.torodb.core.language.AttributeReference.Builder) ErrorCode(com.eightkdata.mongowp.ErrorCode) CommandFailed(com.eightkdata.mongowp.exceptions.CommandFailed) UpdateException(com.torodb.core.exceptions.user.UpdateException) SharedWriteTorodTransaction(com.torodb.torod.SharedWriteTorodTransaction) AttributeReference(com.torodb.core.language.AttributeReference) Constants(com.torodb.mongodb.language.Constants) Cursor(com.torodb.core.cursors.Cursor) KvDocument(com.torodb.kvdocument.values.KvDocument) UpsertResult(com.torodb.mongodb.commands.signatures.general.UpdateCommand.UpsertResult) Command(com.eightkdata.mongowp.server.api.Command) UserException(com.torodb.core.exceptions.user.UserException) SetDocumentUpdateAction(com.torodb.mongodb.language.update.SetDocumentUpdateAction) ObjectIdFactory(com.torodb.mongodb.language.ObjectIdFactory) DocEntry(com.torodb.kvdocument.values.KvDocument.DocEntry) MongodMetrics(com.torodb.mongodb.core.MongodMetrics) WriteMongodTransaction(com.torodb.mongodb.core.WriteMongodTransaction) List(java.util.List) Stream(java.util.stream.Stream) Status(com.eightkdata.mongowp.Status) UserWrappedException(com.torodb.core.exceptions.UserWrappedException) UpdateArgument(com.torodb.mongodb.commands.signatures.general.UpdateCommand.UpdateArgument) Spliterator(java.util.Spliterator) Key(com.torodb.core.language.AttributeReference.Key) KvDocument(com.torodb.kvdocument.values.KvDocument) UpdateStatement(com.torodb.mongodb.commands.signatures.general.UpdateCommand.UpdateStatement) UpdateAction(com.torodb.mongodb.language.update.UpdateAction) SetDocumentUpdateAction(com.torodb.mongodb.language.update.SetDocumentUpdateAction) AttributeReference(com.torodb.core.language.AttributeReference) UpdatedToroDocumentBuilder(com.torodb.mongodb.language.update.UpdatedToroDocumentBuilder) Builder(com.torodb.core.language.AttributeReference.Builder) ObjectKey(com.torodb.core.language.AttributeReference.ObjectKey) DocEntry(com.torodb.kvdocument.values.KvDocument.DocEntry) BsonDocument(com.eightkdata.mongowp.bson.BsonDocument) UserWrappedException(com.torodb.core.exceptions.UserWrappedException) ToroDocument(com.torodb.core.document.ToroDocument) CommandFailed(com.eightkdata.mongowp.exceptions.CommandFailed) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) Stream(java.util.stream.Stream) IndexFieldInfo(com.torodb.torod.IndexFieldInfo) UserException(com.torodb.core.exceptions.user.UserException) UpdateResult(com.torodb.mongodb.commands.signatures.general.UpdateCommand.UpdateResult) SetDocumentUpdateAction(com.torodb.mongodb.language.update.SetDocumentUpdateAction)

Example 3 with UserException

use of com.torodb.core.exceptions.user.UserException in project torodb by torodb.

the class CreateIndexesReplImpl method apply.

@Override
public Status<CreateIndexesResult> apply(Request req, Command<? super CreateIndexesArgument, ? super CreateIndexesResult> command, CreateIndexesArgument arg, SharedWriteTorodTransaction trans) {
    int indexesBefore = (int) trans.getIndexesInfo(req.getDatabase(), arg.getCollection()).count();
    int indexesAfter = indexesBefore;
    try {
        boolean existsCollection = trans.existsCollection(req.getDatabase(), arg.getCollection());
        final boolean createdCollectionAutomatically = !existsCollection;
        if (!existsCollection) {
            LOGGER.info("Creating collection {} on {}.{}", req.getDatabase(), arg.getCollection());
            trans.createIndex(req.getDatabase(), arg.getCollection(), Constants.ID_INDEX, ImmutableList.<IndexFieldInfo>of(new IndexFieldInfo(new AttributeReference(Arrays.asList(new Key[] { new ObjectKey(Constants.ID) })), FieldIndexOrdering.ASC.isAscending())), true);
        }
        for (IndexOptions indexOptions : arg.getIndexesToCreate()) {
            if (!replicationFilters.getIndexPredicate().test(req.getDatabase(), arg.getCollection(), indexOptions.getName(), indexOptions.isUnique(), indexOptions.getKeys())) {
                LOGGER.info("Skipping filtered index {}.{}.{}.", req.getDatabase(), arg.getCollection(), indexOptions.getName());
                continue;
            }
            if (indexOptions.getKeys().size() < 1) {
                return Status.from(ErrorCode.CANNOT_CREATE_INDEX, "Index keys cannot be empty.");
            }
            if (indexOptions.isBackground()) {
                LOGGER.info("Building index in background is not supported. Ignoring option");
            }
            if (indexOptions.isSparse()) {
                LOGGER.info("Sparse index are not supported. Ignoring option");
            }
            boolean skipIndex = false;
            List<IndexFieldInfo> fields = new ArrayList<>(indexOptions.getKeys().size());
            for (IndexOptions.Key indexKey : indexOptions.getKeys()) {
                AttributeReference.Builder attRefBuilder = new AttributeReference.Builder();
                for (String key : indexKey.getKeys()) {
                    attRefBuilder.addObjectKey(key);
                }
                IndexType indexType = indexKey.getType();
                if (!KnownType.contains(indexType)) {
                    String note = "Bad index key pattern: Unknown index type '" + indexKey.getType().getName() + "'. Skipping index.";
                    LOGGER.info(note);
                    skipIndex = true;
                    break;
                }
                Optional<FieldIndexOrdering> ordering = indexType.accept(filedIndexOrderingConverterVisitor, null);
                if (!ordering.isPresent()) {
                    String note = "Index of type " + indexType.getName() + " is not supported. Skipping index.";
                    LOGGER.info(note);
                    skipIndex = true;
                    break;
                }
                fields.add(new IndexFieldInfo(attRefBuilder.build(), ordering.get().isAscending()));
            }
            if (skipIndex) {
                continue;
            }
            try {
                LOGGER.info("Creating index {} on collection {}.{}", req.getDatabase(), arg.getCollection(), indexOptions.getName());
                if (trans.createIndex(req.getDatabase(), arg.getCollection(), indexOptions.getName(), fields, indexOptions.isUnique())) {
                    indexesAfter++;
                }
            } catch (UnsupportedCompoundIndexException ex) {
                String note = "Compound indexes are not supported. Skipping index.";
                LOGGER.info(note);
                continue;
            } catch (UnsupportedUniqueIndexException ex) {
                String note = "Unique index with keys on distinct subdocuments is not supported. Skipping index.";
                LOGGER.info(note);
                continue;
            }
        }
        String note = null;
        if (indexesAfter == indexesBefore) {
            note = "all indexes already exist";
        }
        return Status.ok(new CreateIndexesResult(indexesBefore, indexesAfter, note, createdCollectionAutomatically));
    } catch (UserException ex) {
        return Status.from(ErrorCode.COMMAND_FAILED, ex.getLocalizedMessage());
    }
}
Also used : IndexOptions(com.torodb.mongodb.commands.pojos.index.IndexOptions) AttributeReference(com.torodb.core.language.AttributeReference) ObjectKey(com.torodb.core.language.AttributeReference.ObjectKey) ArrayList(java.util.ArrayList) UnsupportedUniqueIndexException(com.torodb.core.exceptions.user.UnsupportedUniqueIndexException) UnsupportedCompoundIndexException(com.torodb.core.exceptions.user.UnsupportedCompoundIndexException) CreateIndexesResult(com.torodb.mongodb.commands.signatures.admin.CreateIndexesCommand.CreateIndexesResult) IndexFieldInfo(com.torodb.torod.IndexFieldInfo) UserException(com.torodb.core.exceptions.user.UserException) AscIndexType(com.torodb.mongodb.commands.pojos.index.type.AscIndexType) DescIndexType(com.torodb.mongodb.commands.pojos.index.type.DescIndexType) IndexType(com.torodb.mongodb.commands.pojos.index.type.IndexType) FieldIndexOrdering(com.torodb.core.transaction.metainf.FieldIndexOrdering)

Example 4 with UserException

use of com.torodb.core.exceptions.user.UserException in project torodb by torodb.

the class AkkaDbCloner method cloneIndex.

private void cloneIndex(MongodServer localServer, String fromDb, String dstDb, MongoConnection remoteConnection, CloneOptions opts, String fromCol, String toCol) throws CloningException {
    WriteMongodTransaction transaction = createWriteMongodTransaction(localServer);
    try {
        try {
            List<IndexOptions> indexesToClone = getIndexesToClone(Lists.newArrayList(ListIndexesRequester.getListCollections(remoteConnection, dstDb, fromCol).getFirstBatch()), dstDb, toCol, fromDb, fromCol, opts);
            if (indexesToClone.isEmpty()) {
                return;
            }
            Status<CreateIndexesResult> status = transaction.execute(new Request(dstDb, null, true, null), CreateIndexesCommand.INSTANCE, new CreateIndexesArgument(fromCol, indexesToClone));
            if (!status.isOk()) {
                throw new CloningException("Error while cloning indexes: " + status.getErrorMsg());
            }
            transaction.commit();
        } catch (UserException | MongoException ex) {
            throw new CloningException("Unexpected error while cloning indexes", ex);
        }
    } finally {
        transaction.close();
    }
}
Also used : CreateIndexesResult(com.torodb.mongodb.commands.signatures.admin.CreateIndexesCommand.CreateIndexesResult) WriteMongodTransaction(com.torodb.mongodb.core.WriteMongodTransaction) MongoException(com.eightkdata.mongowp.exceptions.MongoException) CreateIndexesArgument(com.torodb.mongodb.commands.signatures.admin.CreateIndexesCommand.CreateIndexesArgument) IndexOptions(com.torodb.mongodb.commands.pojos.index.IndexOptions) Request(com.eightkdata.mongowp.server.api.Request) UserException(com.torodb.core.exceptions.user.UserException)

Example 5 with UserException

use of com.torodb.core.exceptions.user.UserException in project torodb by torodb.

the class AkkaDbCloner method prepareCollection.

private void prepareCollection(MongodServer localServer, String dstDb, Entry colEntry) throws RetrierAbortException {
    try {
        retrier.retry(() -> {
            try (WriteMongodTransaction transaction = createWriteMongodTransaction(localServer)) {
                dropCollection(transaction, dstDb, colEntry.getCollectionName());
                createCollection(transaction, dstDb, colEntry.getCollectionName(), colEntry.getCollectionOptions());
                transaction.commit();
                return null;
            } catch (UserException ex) {
                throw new RetrierAbortException("An unexpected user exception was catched", ex);
            }
        });
    } catch (RetrierGiveUpException ex) {
        throw new CloningException(ex);
    }
}
Also used : WriteMongodTransaction(com.torodb.mongodb.core.WriteMongodTransaction) RetrierAbortException(com.torodb.core.retrier.RetrierAbortException) UserException(com.torodb.core.exceptions.user.UserException) RetrierGiveUpException(com.torodb.core.retrier.RetrierGiveUpException)

Aggregations

UserException (com.torodb.core.exceptions.user.UserException)15 AttributeReference (com.torodb.core.language.AttributeReference)5 RollbackException (com.torodb.core.transaction.RollbackException)5 MongoException (com.eightkdata.mongowp.exceptions.MongoException)4 Request (com.eightkdata.mongowp.server.api.Request)4 OplogOperation (com.eightkdata.mongowp.server.api.oplog.OplogOperation)4 ObjectKey (com.torodb.core.language.AttributeReference.ObjectKey)4 RetrierAbortException (com.torodb.core.retrier.RetrierAbortException)4 WriteMongodTransaction (com.torodb.mongodb.core.WriteMongodTransaction)4 IndexFieldInfo (com.torodb.torod.IndexFieldInfo)4 OplogManagerPersistException (com.torodb.mongodb.repl.OplogManager.OplogManagerPersistException)3 WriteOplogTransaction (com.torodb.mongodb.repl.OplogManager.WriteOplogTransaction)3 OpTime (com.eightkdata.mongowp.OpTime)2 Status (com.eightkdata.mongowp.Status)2 MongoClient (com.eightkdata.mongowp.client.core.MongoClient)2 MongoConnection (com.eightkdata.mongowp.client.core.MongoConnection)2 UnreachableMongoServerException (com.eightkdata.mongowp.client.core.UnreachableMongoServerException)2 CommandFailed (com.eightkdata.mongowp.exceptions.CommandFailed)2 OplogOperationUnsupported (com.eightkdata.mongowp.exceptions.OplogOperationUnsupported)2 OplogStartMissingException (com.eightkdata.mongowp.exceptions.OplogStartMissingException)2