Search in sources :

Example 46 with ResultSetFuture

use of com.datastax.driver.core.ResultSetFuture in project nifi by apache.

the class QueryCassandra method onTrigger.

@Override
public void onTrigger(final ProcessContext context, final ProcessSession session) throws ProcessException {
    FlowFile fileToProcess = null;
    if (context.hasIncomingConnection()) {
        fileToProcess = session.get();
        // we know that we should run only if we have a FlowFile.
        if (fileToProcess == null && context.hasNonLoopConnection()) {
            return;
        }
    }
    final ComponentLog logger = getLogger();
    final String selectQuery = context.getProperty(CQL_SELECT_QUERY).evaluateAttributeExpressions(fileToProcess).getValue();
    final long queryTimeout = context.getProperty(QUERY_TIMEOUT).evaluateAttributeExpressions(fileToProcess).asTimePeriod(TimeUnit.MILLISECONDS);
    final String outputFormat = context.getProperty(OUTPUT_FORMAT).getValue();
    final Charset charset = Charset.forName(context.getProperty(CHARSET).evaluateAttributeExpressions(fileToProcess).getValue());
    final StopWatch stopWatch = new StopWatch(true);
    if (fileToProcess == null) {
        fileToProcess = session.create();
    }
    try {
        // The documentation for the driver recommends the session remain open the entire time the processor is running
        // and states that it is thread-safe. This is why connectionSession is not in a try-with-resources.
        final Session connectionSession = cassandraSession.get();
        final ResultSetFuture queryFuture = connectionSession.executeAsync(selectQuery);
        final AtomicLong nrOfRows = new AtomicLong(0L);
        fileToProcess = session.write(fileToProcess, new OutputStreamCallback() {

            @Override
            public void process(final OutputStream out) throws IOException {
                try {
                    logger.debug("Executing CQL query {}", new Object[] { selectQuery });
                    final ResultSet resultSet;
                    if (queryTimeout > 0) {
                        resultSet = queryFuture.getUninterruptibly(queryTimeout, TimeUnit.MILLISECONDS);
                        if (AVRO_FORMAT.equals(outputFormat)) {
                            nrOfRows.set(convertToAvroStream(resultSet, out, queryTimeout, TimeUnit.MILLISECONDS));
                        } else if (JSON_FORMAT.equals(outputFormat)) {
                            nrOfRows.set(convertToJsonStream(resultSet, out, charset, queryTimeout, TimeUnit.MILLISECONDS));
                        }
                    } else {
                        resultSet = queryFuture.getUninterruptibly();
                        if (AVRO_FORMAT.equals(outputFormat)) {
                            nrOfRows.set(convertToAvroStream(resultSet, out, 0, null));
                        } else if (JSON_FORMAT.equals(outputFormat)) {
                            nrOfRows.set(convertToJsonStream(resultSet, out, charset, 0, null));
                        }
                    }
                } catch (final TimeoutException | InterruptedException | ExecutionException e) {
                    throw new ProcessException(e);
                }
            }
        });
        // set attribute how many rows were selected
        fileToProcess = session.putAttribute(fileToProcess, RESULT_ROW_COUNT, String.valueOf(nrOfRows.get()));
        // set mime.type based on output format
        fileToProcess = session.putAttribute(fileToProcess, CoreAttributes.MIME_TYPE.key(), JSON_FORMAT.equals(outputFormat) ? "application/json" : "application/avro-binary");
        logger.info("{} contains {} Avro records; transferring to 'success'", new Object[] { fileToProcess, nrOfRows.get() });
        session.getProvenanceReporter().modifyContent(fileToProcess, "Retrieved " + nrOfRows.get() + " rows", stopWatch.getElapsed(TimeUnit.MILLISECONDS));
        session.transfer(fileToProcess, REL_SUCCESS);
    } catch (final NoHostAvailableException nhae) {
        getLogger().error("No host in the Cassandra cluster can be contacted successfully to execute this query", nhae);
        // Log up to 10 error messages. Otherwise if a 1000-node cluster was specified but there was no connectivity,
        // a thousand error messages would be logged. However we would like information from Cassandra itself, so
        // cap the error limit at 10, format the messages, and don't include the stack trace (it is displayed by the
        // logger message above).
        getLogger().error(nhae.getCustomMessage(10, true, false));
        fileToProcess = session.penalize(fileToProcess);
        session.transfer(fileToProcess, REL_RETRY);
    } catch (final QueryExecutionException qee) {
        logger.error("Cannot execute the query with the requested consistency level successfully", qee);
        fileToProcess = session.penalize(fileToProcess);
        session.transfer(fileToProcess, REL_RETRY);
    } catch (final QueryValidationException qve) {
        if (context.hasIncomingConnection()) {
            logger.error("The CQL query {} is invalid due to syntax error, authorization issue, or another " + "validation problem; routing {} to failure", new Object[] { selectQuery, fileToProcess }, qve);
            fileToProcess = session.penalize(fileToProcess);
            session.transfer(fileToProcess, REL_FAILURE);
        } else {
            // This can happen if any exceptions occur while setting up the connection, statement, etc.
            logger.error("The CQL query {} is invalid due to syntax error, authorization issue, or another " + "validation problem", new Object[] { selectQuery }, qve);
            session.remove(fileToProcess);
            context.yield();
        }
    } catch (final ProcessException e) {
        if (context.hasIncomingConnection()) {
            logger.error("Unable to execute CQL select query {} for {} due to {}; routing to failure", new Object[] { selectQuery, fileToProcess, e });
            fileToProcess = session.penalize(fileToProcess);
            session.transfer(fileToProcess, REL_FAILURE);
        } else {
            logger.error("Unable to execute CQL select query {} due to {}", new Object[] { selectQuery, e });
            session.remove(fileToProcess);
            context.yield();
        }
    }
}
Also used : FlowFile(org.apache.nifi.flowfile.FlowFile) ResultSetFuture(com.datastax.driver.core.ResultSetFuture) OutputStream(java.io.OutputStream) Charset(java.nio.charset.Charset) ComponentLog(org.apache.nifi.logging.ComponentLog) StopWatch(org.apache.nifi.util.StopWatch) AtomicLong(java.util.concurrent.atomic.AtomicLong) ProcessException(org.apache.nifi.processor.exception.ProcessException) QueryExecutionException(com.datastax.driver.core.exceptions.QueryExecutionException) QueryValidationException(com.datastax.driver.core.exceptions.QueryValidationException) NoHostAvailableException(com.datastax.driver.core.exceptions.NoHostAvailableException) ResultSet(com.datastax.driver.core.ResultSet) OutputStreamCallback(org.apache.nifi.processor.io.OutputStreamCallback) QueryExecutionException(com.datastax.driver.core.exceptions.QueryExecutionException) ExecutionException(java.util.concurrent.ExecutionException) Session(com.datastax.driver.core.Session) ProcessSession(org.apache.nifi.processor.ProcessSession) TimeoutException(java.util.concurrent.TimeoutException)

Example 47 with ResultSetFuture

use of com.datastax.driver.core.ResultSetFuture in project atlasdb by palantir.

the class CqlKeyValueService method getLatestTimestampsInternal.

private Map<Cell, Long> getLatestTimestampsInternal(final TableReference tableRef, Map<Cell, Long> timestampByCell) throws Exception {
    int fetchBatchCount = config.fetchBatchCount();
    Iterable<List<Cell>> partitions = Iterables.partition(timestampByCell.keySet(), fetchBatchCount);
    int numPartitions = (timestampByCell.size() / fetchBatchCount) + (timestampByCell.size() % fetchBatchCount > 0 ? 1 : 0);
    List<Future<Map<Cell, Long>>> futures = Lists.newArrayListWithCapacity(numPartitions);
    String loadOnlyTsQuery = "SELECT " + fieldNameProvider.row() + ", " + fieldNameProvider.column() + ", " + fieldNameProvider.timestamp() + " FROM " + getFullTableName(tableRef) + " WHERE " + fieldNameProvider.row() + " = ?" + " AND " + fieldNameProvider.column() + " = ?" + " LIMIT 1";
    if (timestampByCell.size() > fetchBatchCount) {
        log.warn("Re-batching in getLatestTimestamps a call to {} that attempted to multiget {} cells; " + "this may indicate overly-large batching on a higher level.\n{}", tableRef, timestampByCell.size(), CassandraKeyValueServices.getFilteredStackTrace("com.palantir"));
    }
    for (final List<Cell> partition : partitions) {
        futures.add(executor.submit(AnnotatedCallable.wrapWithThreadName(AnnotationType.PREPEND, "Atlas CQL getLatestTimestamps partition of " + partition.size(), () -> {
            PreparedStatement preparedStatement = getPreparedStatement(tableRef, loadOnlyTsQuery, session);
            preparedStatement.setConsistencyLevel(readConsistency);
            List<ResultSetFuture> resultSetFutures = Lists.newArrayListWithExpectedSize(partition.size());
            for (Cell c : partition) {
                BoundStatement boundStatement = preparedStatement.bind();
                boundStatement.setBytes(fieldNameProvider.row(), ByteBuffer.wrap(c.getRowName()));
                boundStatement.setBytes(fieldNameProvider.column(), ByteBuffer.wrap(c.getColumnName()));
                resultSetFutures.add(session.executeAsync(boundStatement));
            }
            Map<Cell, Long> res = Maps.newHashMapWithExpectedSize(partition.size());
            for (ResultSetFuture resultSetFuture : resultSetFutures) {
                ResultSet resultSet = resultSetFuture.getUninterruptibly();
                for (Row row : resultSet.all()) {
                    res.put(Cell.create(getRowName(row), getColName(row)), getTs(row));
                }
                cqlKeyValueServices.logTracedQuery(loadOnlyTsQuery, resultSet, session, cqlStatementCache.normalQuery);
            }
            return res;
        })));
    }
    Map<Cell, Long> res = Maps.newHashMapWithExpectedSize(timestampByCell.size());
    for (Future<Map<Cell, Long>> f : futures) {
        try {
            res.putAll(f.get());
        } catch (InterruptedException e) {
            throw Throwables.throwUncheckedException(e);
        } catch (ExecutionException e) {
            Throwables.throwIfInstance(e, Error.class);
            throw Throwables.throwUncheckedException(e.getCause());
        }
    }
    return res;
}
Also used : ResultSetFuture(com.datastax.driver.core.ResultSetFuture) PreparedStatement(com.datastax.driver.core.PreparedStatement) ResultSet(com.datastax.driver.core.ResultSet) ResultSetFuture(com.datastax.driver.core.ResultSetFuture) Future(java.util.concurrent.Future) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) Row(com.datastax.driver.core.Row) ExecutionException(java.util.concurrent.ExecutionException) Cell(com.palantir.atlasdb.keyvalue.api.Cell) BoundStatement(com.datastax.driver.core.BoundStatement) Map(java.util.Map) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) ImmutableMap(com.google.common.collect.ImmutableMap) NavigableMap(java.util.NavigableMap) SortedMap(java.util.SortedMap)

Example 48 with ResultSetFuture

use of com.datastax.driver.core.ResultSetFuture in project atlasdb by palantir.

the class CqlKeyValueService method multiPut.

@Override
public void multiPut(Map<TableReference, ? extends Map<Cell, byte[]>> valuesByTable, long timestamp) throws KeyAlreadyExistsException {
    Map<ResultSetFuture, TableReference> resultSetFutures = Maps.newHashMap();
    for (Entry<TableReference, ? extends Map<Cell, byte[]>> e : valuesByTable.entrySet()) {
        final TableReference table = e.getKey();
        // We sort here because some key value stores are more efficient if you store adjacent keys together.
        NavigableMap<Cell, byte[]> sortedMap = ImmutableSortedMap.copyOf(e.getValue());
        Iterable<List<Entry<Cell, byte[]>>> partitions = IterablePartitioner.partitionByCountAndBytes(sortedMap.entrySet(), getMultiPutBatchCount(), getMultiPutBatchSizeBytes(), table, CqlKeyValueServices.MULTIPUT_ENTRY_SIZING_FUNCTION);
        for (final List<Entry<Cell, byte[]>> p : partitions) {
            List<Entry<Cell, Value>> partition = Lists.transform(p, input -> Maps.immutableEntry(input.getKey(), Value.create(input.getValue(), timestamp)));
            resultSetFutures.put(getPutPartitionResultSetFuture(table, partition, TransactionType.NONE), table);
        }
    }
    for (Entry<ResultSetFuture, TableReference> result : resultSetFutures.entrySet()) {
        ResultSet resultSet;
        try {
            resultSet = result.getKey().getUninterruptibly();
            resultSet.all();
        } catch (Throwable t) {
            throw Throwables.throwUncheckedException(t);
        }
        cqlKeyValueServices.logTracedQuery(getPutQuery(result.getValue(), CassandraConstants.NO_TTL), resultSet, session, cqlStatementCache.normalQuery);
    }
}
Also used : ResultSetFuture(com.datastax.driver.core.ResultSetFuture) TableReference(com.palantir.atlasdb.keyvalue.api.TableReference) Entry(java.util.Map.Entry) ResultSet(com.datastax.driver.core.ResultSet) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) Cell(com.palantir.atlasdb.keyvalue.api.Cell)

Example 49 with ResultSetFuture

use of com.datastax.driver.core.ResultSetFuture in project teiid by teiid.

the class TestNativeCassandra method testNativeQuery.

@Test
public void testNativeQuery() throws Exception {
    CassandraExecutionFactory cef = new CassandraExecutionFactory();
    cef.setSupportsDirectQueryProcedure(true);
    String input = "call proc('a', 1)";
    TransformationMetadata metadata = RealMetadataFactory.fromDDL("create foreign procedure proc (in x string, in y integer) options (\"teiid_rel:native-query\" 'delete from $1 where $2')", "x", "y");
    TranslationUtility util = new TranslationUtility(metadata);
    Command command = util.parseCommand(input);
    ExecutionContext ec = Mockito.mock(ExecutionContext.class);
    RuntimeMetadata rm = Mockito.mock(RuntimeMetadata.class);
    CassandraConnection connection = Mockito.mock(CassandraConnection.class);
    ResultSetFuture rsf = Mockito.mock(ResultSetFuture.class);
    Mockito.stub(connection.executeQuery("delete from 'a' where 1")).toReturn(rsf);
    Execution execution = cef.createExecution(command, ec, rm, connection);
    execution.execute();
    Mockito.verify(connection).executeQuery("delete from 'a' where 1");
}
Also used : TransformationMetadata(org.teiid.query.metadata.TransformationMetadata) ExecutionContext(org.teiid.translator.ExecutionContext) ResultSetFuture(com.datastax.driver.core.ResultSetFuture) Execution(org.teiid.translator.Execution) ResultSetExecution(org.teiid.translator.ResultSetExecution) Command(org.teiid.language.Command) TranslationUtility(org.teiid.cdk.api.TranslationUtility) RuntimeMetadata(org.teiid.metadata.RuntimeMetadata) Test(org.junit.Test)

Example 50 with ResultSetFuture

use of com.datastax.driver.core.ResultSetFuture in project teiid by teiid.

the class TestUpdates method testBatchedUpdate.

@Test
public void testBatchedUpdate() throws TranslatorException {
    CassandraExecutionFactory cef = new CassandraExecutionFactory();
    String input = "insert into pm1.g1 (e1) values ('a')";
    TranslationUtility util = FakeTranslationFactory.getInstance().getExampleTranslationUtility();
    Command command = util.parseCommand(input);
    Command command1 = util.parseCommand("update pm1.g1 set e1 = 'b'");
    command = new BatchedUpdates(Arrays.asList(command, command1));
    ExecutionContext ec = Mockito.mock(ExecutionContext.class);
    RuntimeMetadata rm = Mockito.mock(RuntimeMetadata.class);
    CassandraConnection connection = Mockito.mock(CassandraConnection.class);
    ResultSetFuture rsf = Mockito.mock(ResultSetFuture.class);
    Mockito.stub(rsf.isDone()).toReturn(true);
    Mockito.stub(connection.executeBatch(Arrays.asList("INSERT INTO g1 (e1) VALUES ('a')", "UPDATE g1 SET e1 = 'b'"))).toReturn(rsf);
    UpdateExecution execution = (UpdateExecution) cef.createExecution(command, ec, rm, connection);
    execution.execute();
    assertArrayEquals(new int[] { 2 }, execution.getUpdateCounts());
    Mockito.verify(connection).executeBatch(Arrays.asList("INSERT INTO g1 (e1) VALUES ('a')", "UPDATE g1 SET e1 = 'b'"));
}
Also used : ExecutionContext(org.teiid.translator.ExecutionContext) ResultSetFuture(com.datastax.driver.core.ResultSetFuture) Command(org.teiid.language.Command) TranslationUtility(org.teiid.cdk.api.TranslationUtility) UpdateExecution(org.teiid.translator.UpdateExecution) RuntimeMetadata(org.teiid.metadata.RuntimeMetadata) BatchedUpdates(org.teiid.language.BatchedUpdates) Test(org.junit.Test)

Aggregations

ResultSetFuture (com.datastax.driver.core.ResultSetFuture)78 Test (org.junit.Test)35 UUID (java.util.UUID)26 ResultSet (com.datastax.driver.core.ResultSet)20 EntityWithCollections (com.datastax.driver.mapping.entity.EntityWithCollections)13 BoundStatement (com.datastax.driver.core.BoundStatement)12 PreparedStatement (com.datastax.driver.core.PreparedStatement)10 ArrayList (java.util.ArrayList)8 Date (java.util.Date)8 Row (com.datastax.driver.core.Row)7 Statement (com.datastax.driver.core.Statement)7 List (java.util.List)6 Session (com.datastax.driver.core.Session)5 Simple (com.datastax.driver.mapping.entity.Simple)5 Cell (com.palantir.atlasdb.keyvalue.api.Cell)5 BigDecimal (java.math.BigDecimal)5 HashSet (java.util.HashSet)5 Result (com.datastax.driver.mapping.Result)4 WriteOptions (com.datastax.driver.mapping.option.WriteOptions)4 Nullable (javax.annotation.Nullable)4