Package com.opengamma.masterdb.batch

Source Code of com.opengamma.masterdb.batch.DbBatchMaster$BatchValuesExtractor

/**
* Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.masterdb.batch;

import static com.google.common.collect.Lists.newArrayList;
import static com.opengamma.util.db.HibernateDbUtils.eqOrIsNull;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;

import com.opengamma.DataNotFoundException;
import com.opengamma.batch.BatchMasterWriter;
import com.opengamma.batch.RunCreationMode;
import com.opengamma.batch.SnapshotMode;
import com.opengamma.batch.domain.MarketData;
import com.opengamma.batch.domain.MarketDataValue;
import com.opengamma.batch.domain.RiskRun;
import com.opengamma.batch.domain.RiskValueProperties;
import com.opengamma.batch.rest.BatchRunSearchRequest;
import com.opengamma.engine.ComputationTargetResolver;
import com.opengamma.engine.target.ComputationTargetType;
import com.opengamma.engine.value.ComputedValueResult;
import com.opengamma.engine.value.ValueProperties;
import com.opengamma.engine.value.ValueSpecification;
import com.opengamma.engine.view.AggregatedExecutionLog;
import com.opengamma.engine.view.ViewComputationResultModel;
import com.opengamma.engine.view.ViewResultEntry;
import com.opengamma.engine.view.cycle.ViewCycleMetadata;
import com.opengamma.id.ObjectId;
import com.opengamma.id.UniqueId;
import com.opengamma.masterdb.AbstractDbMaster;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.db.DbConnector;
import com.opengamma.util.db.DbMapSqlParameterSource;
import com.opengamma.util.paging.Paging;
import com.opengamma.util.paging.PagingRequest;
import com.opengamma.util.tuple.Pair;

/**
* A batch master implementation using a database for persistence.
* <p>
* This is a full implementation of the batch master using an SQL database.
* Full details of the API are in {@link BatchMasterWriter}.
* <p>
* The SQL is stored externally in {@code DbBatchMaster.elsql}.
* Alternate databases or specific SQL requirements can be handled using database
* specific overrides, such as {@code DbBatchMaster-MySpecialDB.elsql}.
* <p>
* This class is mutable but must be treated as immutable after configuration.
*/
public class DbBatchMaster extends AbstractDbMaster implements BatchMasterWriter {

  /** Logger. */
  private static final Logger s_logger = LoggerFactory.getLogger(DbBatchMaster.class);

  /**
   * The batch writer.
   */
  private final DbBatchWriter _dbBatchWriter;

  /**
   * Creates an instance.
   *
   * @param dbConnector  the database connector, not null
   */
  public DbBatchMaster(final DbConnector dbConnector, final ComputationTargetResolver computationTargetResolver) {
    super(dbConnector, BATCH_IDENTIFIER_SCHEME);
    _dbBatchWriter = new DbBatchWriter(dbConnector, computationTargetResolver);
    setElSqlBundle(_dbBatchWriter.getElSqlBundle());
  }

  //-------------------------------------------------------------------------
  @Override
  public RiskRun getRiskRun(final ObjectId uniqueId) {
    ArgumentChecker.notNull(uniqueId, "uniqueId");
    s_logger.info("Getting BatchDocument by unique id: ", uniqueId);
    final Long id = extractOid(uniqueId);
    return getHibernateTransactionTemplate().execute(new HibernateCallback<RiskRun>() {
      @Override
      public RiskRun doInHibernate(final Session session) throws HibernateException, SQLException {
        final RiskRun run = _dbBatchWriter.getRiskRunById(id);
        if (run != null) {
          return run;
        } else {
          throw new DataNotFoundException("Batch run not found: " + id);
        }
      }
    });
  }

  @Override
  @SuppressWarnings("unchecked")
  public Pair<List<MarketData>, Paging> getMarketData(final PagingRequest pagingRequest) {
    s_logger.info("Getting markte datas: ", pagingRequest);

    return getTransactionTemplateRetrying(getMaxRetries()).execute(new TransactionCallback<Pair<List<MarketData>, Paging>>() {
      @Override
      public Pair<List<MarketData>, Paging> doInTransaction(final TransactionStatus status) {
        final DetachedCriteria criteria = DetachedCriteria.forClass(MarketData.class);

        List<MarketData> results = Collections.emptyList();
        if (!pagingRequest.equals(PagingRequest.NONE)) {
          results = getHibernateTemplate().findByCriteria(
            criteria,
            pagingRequest.getFirstItem(),
            pagingRequest.getPagingSize());
        }
        //
        Paging paging;
        if (pagingRequest.equals(PagingRequest.ALL)) {
          paging = Paging.of(pagingRequest, results);
        } else {
          criteria.setProjection(Projections.rowCount());
          final Long totalCount = (Long) getHibernateTemplate().findByCriteria(criteria).get(0);
          paging = Paging.of(pagingRequest, totalCount.intValue());
        }
        //    
        return Pair.of(results, paging);
      }
    });
  }

  @Override
  public MarketData getMarketDataById(final ObjectId batchSnapshotId) {
    s_logger.info("Getting the batch data snapshot: {}", batchSnapshotId);

    final Long marketDataPK = extractOid(batchSnapshotId);

    return getTransactionTemplateRetrying(getMaxRetries()).execute(new TransactionCallback<MarketData>() {
      @Override
      public MarketData doInTransaction(final TransactionStatus status) {
        return getHibernateTemplate().get(MarketData.class, marketDataPK);
      }
    });
  }

  @Override
  @SuppressWarnings("unchecked")
  public Pair<List<MarketDataValue>, Paging> getMarketDataValues(final ObjectId marketDataId, final PagingRequest pagingRequest) {
    s_logger.info("Getting the batch data snapshot: {}", marketDataId);

    final Long marketDataPK = extractOid(marketDataId);

    return getTransactionTemplateRetrying(getMaxRetries()).execute(new TransactionCallback<Pair<List<MarketDataValue>, Paging>>() {
      @Override
      public Pair<List<MarketDataValue>, Paging> doInTransaction(final TransactionStatus status) {

        final DetachedCriteria criteria = DetachedCriteria.forClass(MarketDataValue.class);
        criteria.add(Restrictions.eq("marketDataId", marketDataPK));
        //
        List<MarketDataValue> results = Collections.emptyList();
        if (!pagingRequest.equals(PagingRequest.NONE)) {
          results = getHibernateTemplate().findByCriteria(
            criteria,
            pagingRequest.getFirstItem(),
            pagingRequest.getPagingSize());
        }
        //
        Paging paging;
        if (pagingRequest.equals(PagingRequest.ALL)) {
          paging = Paging.of(pagingRequest, results);
        } else {
          criteria.setProjection(Projections.rowCount());
          final Long totalCount = (Long) getHibernateTemplate().findByCriteria(criteria).get(0);
          paging = Paging.of(pagingRequest, totalCount.intValue());
        }
        //
        return Pair.of(results, paging);
      }
    });
  }

  @Override
  public void deleteMarketData(final ObjectId batchSnapshotId) {
    s_logger.info("Deleting market data snapshot: ", batchSnapshotId);
    getTransactionTemplateRetrying(getMaxRetries()).execute(new TransactionCallback<Void>() {
      @Override
      public Void doInTransaction(final TransactionStatus status) {
        _dbBatchWriter.deleteSnapshotInTransaction(batchSnapshotId);
        return null;
      }
    });
  }

  //-------------------------------------------------------------------------
  @Override
  @SuppressWarnings("unchecked")
  public Pair<List<RiskRun>, Paging> searchRiskRun(final BatchRunSearchRequest request) {
    s_logger.info("Searching BatchDocuments: ", request);
   
    final DetachedCriteria criteria = DetachedCriteria.forClass(RiskRun.class);
   
    if (request.getValuationTime() != null) {
      criteria.add(
        Restrictions.eq("valuationTime", request.getValuationTime()));
    }
    if (request.getVersionCorrection() != null) {
      criteria.add(
        Restrictions.eq("versionCorrection", request.getVersionCorrection()));
    }
   
    if (request.getMarketDataUid() != null) {
      criteria.createCriteria("marketData")
        .add(Restrictions.eq("baseUidScheme", request.getMarketDataUid().getScheme()))
        .add(Restrictions.eq("baseUidValue", request.getMarketDataUid().getValue()))
        .add(eqOrIsNull("baseUidVersion", request.getMarketDataUid().getVersion()));
      //.addOrder(Order.asc("baseUid"));
    }
   
    if (request.getViewDefinitionUid() != null) {
      criteria.add(Restrictions.eq("viewDefinitionUidScheme", request.getViewDefinitionUid().getScheme()))
        .add(Restrictions.eq("viewDefinitionUidValue", request.getViewDefinitionUid().getValue()))
        .add(eqOrIsNull("viewDefinitionUidVersion", request.getViewDefinitionUid().getVersion()));
      //.addOrder(Order.asc("viewDefinitionUid"));
    }
   
    return getTransactionTemplateRetrying(getMaxRetries()).execute(new TransactionCallback<Pair<List<RiskRun>, Paging>>() {
      @Override
      public Pair<List<RiskRun>, Paging> doInTransaction(final TransactionStatus status) {
        //
        final PagingRequest pagingRequest = request.getPagingRequest();
        List<RiskRun> results = Collections.emptyList();
        Paging paging;
        if (!pagingRequest.equals(PagingRequest.NONE)) {
          if (pagingRequest.equals(PagingRequest.ALL)) {
            criteria.addOrder(Order.asc("valuationTime"));
            results = getHibernateTemplate().findByCriteria(
              criteria,
              pagingRequest.getFirstItem(),
              pagingRequest.getPagingSize());
            //
            paging = Paging.of(pagingRequest, results);
          } else {
            criteria.setProjection(Projections.rowCount());
            final Long totalCount = (Long) getHibernateTemplate().findByCriteria(criteria).get(0);
            paging = Paging.of(pagingRequest, totalCount.intValue());
            //
            criteria.setProjection(null);
            criteria.setResultTransformer(Criteria.ROOT_ENTITY);
            criteria.addOrder(Order.asc("valuationTime"));
            results = getHibernateTemplate().findByCriteria(
              criteria,
              pagingRequest.getFirstItem(),
              pagingRequest.getPagingSize());
          }
        } else {
          paging = Paging.of(PagingRequest.NONE, 0);
        }
        return Pair.of(results, paging);
      }
    });
  }

  //-------------------------------------------------------------------------
  @Override
  public void addValuesToMarketData(final ObjectId marketDataId, final Set<MarketDataValue> values) {
    getTransactionTemplateRetrying(getMaxRetries()).execute(new TransactionCallback<Void>() {
      @Override
      public Void doInTransaction(final TransactionStatus status) {
        _dbBatchWriter.addValuesToMarketDataInTransaction(marketDataId, values);
        return null;
      }
    });
  }

  @Override
  public RiskRun startRiskRun(final ViewCycleMetadata cycleMetadata,
                              final Map<String, String> batchParameters,
                              final RunCreationMode runCreationMode,
                              final SnapshotMode snapshotMode) {
    return getTransactionTemplateRetrying(getMaxRetries()).execute(new TransactionCallback<RiskRun>() {
      @Override
      public RiskRun doInTransaction(final TransactionStatus status) {
        return _dbBatchWriter.startBatchInTransaction(cycleMetadata, batchParameters, runCreationMode, snapshotMode);
      }
    });
  }

  @Override
  public void deleteRiskRun(final ObjectId batchUniqueId) {
    getTransactionTemplateRetrying(getMaxRetries()).execute(new TransactionCallback<Void>() {
      @Override
      public Void doInTransaction(final TransactionStatus status) {
        _dbBatchWriter.deleteBatchInTransaction(batchUniqueId);
        return null;
      }
    });
  }

  /**
   * Searches for documents with paging.
   *
   * @param <D>  the  list type
   * @param pagingRequest  the paging request, not null
   * @param sql  the array of SQL, query and count, not null
   * @param args  the query arguments, not null
   * @param extractor  the extractor of results, not null
   * @return values with its paging descriptor
   */
  protected <D> Pair<List<D>, Paging> searchWithPaging(
    final PagingRequest pagingRequest, final String[] sql, final DbMapSqlParameterSource args,
    final ResultSetExtractor<List<D>> extractor) {
   
    return getTransactionTemplateRetrying(getMaxRetries()).execute(new TransactionCallback<Pair<List<D>, Paging>>() {
      @Override
      public Pair<List<D>, Paging> doInTransaction(final TransactionStatus status) {
        final List<D> result = newArrayList();
        Paging paging;
        s_logger.debug("with args {}", args);
        final NamedParameterJdbcOperations namedJdbc = getDbConnector().getJdbcTemplate();
        if (pagingRequest.equals(PagingRequest.ALL)) {
          result.addAll(namedJdbc.query(sql[0], args, extractor));
          paging = Paging.of(pagingRequest, result);
        } else {
          s_logger.debug("executing sql {}", sql[1]);
          final int count = namedJdbc.queryForObject(sql[1], args, Integer.class);
          paging = Paging.of(pagingRequest, count);
          if (count > 0 && !pagingRequest.equals(PagingRequest.NONE)) {
            s_logger.debug("executing sql {}", sql[0]);
            result.addAll(namedJdbc.query(sql[0], args, extractor));
          }
        }
        return Pair.of(result, paging);
      }
    });
  }

  @Override
  public Pair<List<ViewResultEntry>, Paging> getBatchValues(final ObjectId batchId, final PagingRequest pagingRequest) {
    s_logger.info("Getting Batch values: ", pagingRequest);
   
    final Long runId = extractOid(batchId);
    final DbMapSqlParameterSource args = new DbMapSqlParameterSource();
    args.addValue("run_id", runId);
    if (pagingRequest != null) {
      args.addValue("paging_offset", pagingRequest.getFirstItem());
      args.addValue("paging_fetch", pagingRequest.getPagingSize());
    }
   
    final String[] sql = {getElSqlBundle().getSql("GetBatchValues", args), getElSqlBundle().getSql("BatchValuesCount", args)};
    return searchWithPaging(pagingRequest, sql, args, new BatchValuesExtractor());
  }

  @Override
  public void endRiskRun(final ObjectId batchUniqueId) {
    getTransactionTemplateRetrying(getMaxRetries()).execute(new TransactionCallback<Void>() {
      @Override
      public Void doInTransaction(final TransactionStatus status) {
        _dbBatchWriter.endBatchInTransaction(batchUniqueId);
        return null;
      }
    });
  }

  @Override
  public MarketData createMarketData(final UniqueId marketDataSnapshotUniqueId) {
    return getTransactionTemplateRetrying(getMaxRetries()).execute(new TransactionCallback<MarketData>() {
      @Override
      public MarketData doInTransaction(final TransactionStatus status) {
        return _dbBatchWriter.createOrGetMarketDataInTransaction(marketDataSnapshotUniqueId);
      }
    });
  }

  //-------------------------------------------------------------------------
  @Override
  public void addJobResults(final ObjectId riskRunId, final ViewComputationResultModel result) {
    getTransactionTemplateRetrying(getMaxRetries()).execute(new TransactionCallback<Void>() {
      @Override
      public Void doInTransaction(final TransactionStatus status) {
        _dbBatchWriter.addJobResultsInTransaction(status, riskRunId, result);
        return null;
      }
    });
  }

  /**
   * Mapper from SQL rows to a ViewResultEntries.
   */
  protected final class BatchValuesExtractor implements ResultSetExtractor<List<ViewResultEntry>> {

    @Override
    public List<ViewResultEntry> extractData(final ResultSet rs) throws SQLException, DataAccessException {
      final List<ViewResultEntry> data = newArrayList();
      while (rs.next()) {
        data.add(buildBatchValue(rs));
      }
      return data;
    }

    private ViewResultEntry buildBatchValue(final ResultSet rs) throws SQLException {
//      final long id = rs.getLong("ID");
//      final long calculationConfigurationId = rs.getLong("calculation_configuration_id");
//      final long valueSpecificationId = rs.getLong("value_specification_id");
//      final long functionUniqueId = rs.getLong("function_unique_id");
//      final long computationTargetId = rs.getLong("computation_target_id");
//      final long runId = rs.getLong("run_id");
      final double value = rs.getDouble("value");
      final String valueName = rs.getString("name");
//      final Timestamp evalInstant = rs.getTimestamp("eval_instant");
//      final long computeNodeId = rs.getLong("compute_node_id");
      final ComputationTargetType computationTargetType = ComputationTargetType.parse(rs.getString("target_type"));
      final String valueRequirementsSyntheticForm = rs.getString("synthetic_form");
      final String targetTypeIdScheme = rs.getString("target_type_id_scheme");
      final String targetTypeIdValue = rs.getString("target_type_id_value");
      final String targetTypeIdVersion = rs.getString("target_type_id_version");
      final UniqueId targetId = UniqueId.of(targetTypeIdScheme, targetTypeIdValue, targetTypeIdVersion);
      final ValueProperties valueProperties = RiskValueProperties.parseJson(valueRequirementsSyntheticForm);
      final String configurationName = rs.getString("config_name");
      final ValueSpecification valueSpecification = ValueSpecification.of(valueName, computationTargetType, targetId, valueProperties);
      final ComputedValueResult computedValue = new ComputedValueResult(valueSpecification, value, AggregatedExecutionLog.EMPTY);
      final ViewResultEntry viewResultEntry = new ViewResultEntry(configurationName, computedValue);

      return viewResultEntry;
    }
  }

}
TOP

Related Classes of com.opengamma.masterdb.batch.DbBatchMaster$BatchValuesExtractor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.