info.archinnov.achilles.internals.statements.StatementWrapper.java Source code

Java tutorial

Introduction

Here is the source code for info.archinnov.achilles.internals.statements.StatementWrapper.java

Source

/*
 * Copyright (C) 2012-2016 DuyHai DOAN
 *
 * Licensed 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 info.archinnov.achilles.internals.statements;

import static info.archinnov.achilles.internals.cql.TypeMapper.toJavaType;
import static info.archinnov.achilles.internals.utils.LoggerHelper.replaceByteBuffersByHexString;
import static java.lang.String.format;

import java.util.*;
import java.util.stream.IntStream;

import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.datastax.driver.core.*;
import com.datastax.driver.core.exceptions.TraceRetrievalException;

import info.archinnov.achilles.internals.options.Options;
import info.archinnov.achilles.internals.types.ResultSetWrapper;
import info.archinnov.achilles.logger.AchillesLoggers;

public interface StatementWrapper {
    Logger LOGGER = LoggerFactory.getLogger(StatementWrapper.class);

    EventComparator EVENT_TRACE_COMPARATOR = new EventComparator();
    Logger DML_LOGGER = LoggerFactory.getLogger(AchillesLoggers.ACHILLES_DML_STATEMENT);
    int RESULTS_LOG_DISPLAY_LIMIT = 10;

    Object[] getBoundValues();

    BoundStatement getBoundStatement();

    void applyOptions(Options options);

    void logDML();

    ResultSet logReturnResults(ResultSet resultSet);

    Row logReturnedRow(Row row);

    ResultSet logTrace(ResultSet resultSet);

    default void writeDMLStatementLog(Logger actualLogger, UUID queryId, String queryString,
            ConsistencyLevel consistencyLevel, Object[] boundValues, Object[] encodedValues) {
        if (actualLogger.isDebugEnabled()) {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug(format("Writing DML log for query %s with id %s", queryString, queryId));
            }
            actualLogger.debug("Query ID {} : [{}] with CONSISTENCY LEVEL [{}]", queryId.toString(), queryString,
                    consistencyLevel);
            if (ArrayUtils.isNotEmpty(boundValues)) {
                actualLogger.debug("\t Java bound values : {}", replaceByteBuffersByHexString(boundValues));
                actualLogger.debug("\t Encoded bound values : {}", replaceByteBuffersByHexString(encodedValues));
            }
        }
    }

    default void logReturnedResultsInternal(Logger actualLogger, UUID queryId, ResultSetWrapper resultSet) {
        final int availableWithoutFetching = resultSet.getAvailableWithoutFetching();
        StringBuilder results = new StringBuilder(format("Query ID %s results : \n", queryId));
        actualLogger.debug(resultSet.toString());
        for (int i = 0; i < Integer.min(availableWithoutFetching, RESULTS_LOG_DISPLAY_LIMIT); i++) {
            final Row row = resultSet.peek();
            appendRowDataToBuilder(row, row.getColumnDefinitions().asList(), results);
        }
        actualLogger.debug(results.toString());
    }

    default void logReturnedRowInternal(Logger actualLogger, UUID queryId, Row row) {
        StringBuilder results = new StringBuilder(format("Query ID %s row : \n", queryId));
        appendRowDataToBuilder(row, row.getColumnDefinitions().asList(), results);
        actualLogger.debug(results.toString());
    }

    default void appendRowDataToBuilder(Row row, List<ColumnDefinitions.Definition> columnsDef,
            StringBuilder builder) {
        StringJoiner joiner = new StringJoiner(", ", "\t", "\n");
        IntStream.range(0, columnsDef.size()).forEach(index -> {
            final ColumnDefinitions.Definition def = columnsDef.get(index);
            final Object value = extractValueFromRow(row, index, def.getType());
            joiner.add(format("%s: %s", def.getName(), value));
        });
        builder.append(joiner.toString());
    }

    default Object extractValueFromRow(Row row, int index, DataType dataType) {
        final DataType.Name typeName = dataType.getName();
        switch (typeName) {
        case LIST:
        case SET:
        case MAP:
        case TUPLE:
        case CUSTOM:
            return row.getObject(index);
        default:
            return row.get(index, toJavaType(typeName));
        }
    }

    default void tracingInternal(Logger actualLogger, UUID queryId, ResultSet resultSet) {
        StringBuilder trace = new StringBuilder();
        if (actualLogger.isTraceEnabled()) {
            for (ExecutionInfo executionInfo : resultSet.getAllExecutionInfo()) {

                trace.append(format("\n\nTracing for Query ID %s at host %s with achieved consistency level %s \n",
                        queryId.toString(), executionInfo.getQueriedHost(),
                        executionInfo.getAchievedConsistencyLevel()));
                trace.append("****************************\n");
                trace.append(format("%1$-80s | %2$-16s | %3$-24s | %4$-20s\n", "Description", "Source",
                        "Source elapsed in micros", "Thread name"));
                try {
                    final QueryTrace queryTrace = executionInfo.getQueryTrace();
                    if (queryTrace != null) {
                        final List<QueryTrace.Event> events = new ArrayList<>(queryTrace.getEvents());
                        Collections.sort(events, EVENT_TRACE_COMPARATOR);
                        for (QueryTrace.Event event : events) {
                            trace.append(format("%1$-80s | %2$-16s | %3$-24s | %4$-20s\n", event.getDescription(),
                                    event.getSource(), event.getSourceElapsedMicros(), event.getThreadName()));
                        }
                    }
                } catch (TraceRetrievalException e) {
                    final String queryString = getBoundStatement().preparedStatement().getQueryString();
                    trace.append(
                            format(" ERROR: cannot retrieve trace for query {} because it may not be yet available",
                                    queryString));
                }
                trace.append("****************************\n\n");
            }

            actualLogger.trace(trace.toString());
        }
    }

    class EventComparator implements Comparator<QueryTrace.Event> {
        @Override
        public int compare(QueryTrace.Event event1, QueryTrace.Event event2) {
            return event1.getSource().toString().compareTo(event2.getSource().toString());
        }
    }
}