Package com.opengamma.integration.viewer.status.impl

Source Code of com.opengamma.integration.viewer.status.impl.ViewStatusCalculationTask$ViewStatusResultListener

/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.integration.viewer.status.impl;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.threeten.bp.Instant;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.core.config.impl.ConfigItem;
import com.opengamma.core.position.Portfolio;
import com.opengamma.core.position.Position;
import com.opengamma.core.position.PositionSource;
import com.opengamma.core.position.Trade;
import com.opengamma.engine.ComputationTargetSpecification;
import com.opengamma.engine.calcnode.MissingValue;
import com.opengamma.engine.marketdata.spec.MarketDataSpecification;
import com.opengamma.engine.target.ComputationTargetType;
import com.opengamma.engine.value.ComputedValueResult;
import com.opengamma.engine.value.ValueProperties;
import com.opengamma.engine.value.ValueRequirement;
import com.opengamma.engine.value.ValueSpecification;
import com.opengamma.engine.view.ViewCalculationConfiguration;
import com.opengamma.engine.view.ViewCalculationResultModel;
import com.opengamma.engine.view.ViewComputationResultModel;
import com.opengamma.engine.view.ViewDefinition;
import com.opengamma.engine.view.ViewDeltaResultModel;
import com.opengamma.engine.view.ViewProcessor;
import com.opengamma.engine.view.client.ViewClient;
import com.opengamma.engine.view.compilation.CompiledViewCalculationConfiguration;
import com.opengamma.engine.view.compilation.CompiledViewDefinition;
import com.opengamma.engine.view.cycle.ViewCycleMetadata;
import com.opengamma.engine.view.execution.ExecutionOptions;
import com.opengamma.engine.view.execution.ViewCycleExecutionOptions;
import com.opengamma.engine.view.listener.AbstractViewResultListener;
import com.opengamma.financial.aggregation.CurrenciesAggregationFunction;
import com.opengamma.financial.aggregation.PortfolioAggregator;
import com.opengamma.financial.tool.ToolContext;
import com.opengamma.id.UniqueId;
import com.opengamma.id.VersionCorrection;
import com.opengamma.integration.viewer.status.ViewStatus;
import com.opengamma.livedata.UserPrincipal;
import com.opengamma.master.config.ConfigMaster;
import com.opengamma.master.config.ConfigMasterUtils;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.GUIDGenerator;
import com.opengamma.util.tuple.Pair;

/**
* View status calculation task
*/
public class ViewStatusCalculationTask implements Callable<PerViewStatusResult> {
 
  private final class ViewStatusResultListener extends AbstractViewResultListener {
    private final CountDownLatch _latch;
    private final PerViewStatusResult _statusResult;
    private final ViewDefinition _viewDefinition;
    private AtomicLong _count = new AtomicLong(0);

    private ViewStatusResultListener(CountDownLatch latch, PerViewStatusResult statusResult, ViewDefinition viewDefinition) {
      _latch = latch;
      _statusResult = statusResult;
      _viewDefinition = viewDefinition;
    }

    @Override
    public UserPrincipal getUser() {
      return _user;
    }

    @Override
    public void viewDefinitionCompiled(CompiledViewDefinition compiledViewDefinition, boolean hasMarketDataPermissions) {
      s_logger.error("View definition compiled");
      CompiledViewCalculationConfiguration compiledCalculationConfiguration = compiledViewDefinition.getCompiledCalculationConfiguration(DEFAULT_CALC_CONFIG);
      Map<ValueSpecification, Set<ValueRequirement>> terminalOutputs = compiledCalculationConfiguration.getTerminalOutputSpecifications();
      for (ValueSpecification valueSpec : terminalOutputs.keySet()) {
        ComputationTargetType computationTargetType = valueSpec.getTargetSpecification().getType();
        if (isValidTargetType(computationTargetType)) {
          UniqueId uniqueId = valueSpec.getTargetSpecification().getUniqueId();
          String currency = getCurrency(uniqueId, computationTargetType);
          if (currency != null) {
            _statusResult.put(new ViewStatusKeyBean(_securityType, valueSpec.getValueName(), currency, computationTargetType.getName()), ViewStatus.NO_VALUE);
          } else {
            s_logger.error("Discarding result as NULL return as Currency for id: {} targetType:{}", uniqueId, computationTargetType);
          }
        }
      }
    }

    @Override
    public void viewDefinitionCompilationFailed(final Instant valuationTime, final Exception exception) {
      s_logger.debug("View definition {} failed to initialize", _viewDefinition);
      try {
        processGraphFailResult(_statusResult);
      } finally {
        _latch.countDown();
      }
    }

    public void cycleStarted(ViewCycleMetadata cycleInfo) {
      s_logger.debug("Cycle started");
    }

    @Override
    public void cycleExecutionFailed(ViewCycleExecutionOptions executionOptions, Exception exception) {
      s_logger.debug("Cycle execution failed", exception);
    }

    @Override
    public void processCompleted() {
      s_logger.debug("Process completed");
    }

    @Override
    public void processTerminated(boolean executionInterrupted) {
      s_logger.debug("Process terminated");
    }

    @Override
    public void clientShutdown(Exception e) {
      s_logger.debug("Client shutdown");
    }

    @Override
    public void cycleFragmentCompleted(ViewComputationResultModel fullResult, ViewDeltaResultModel deltaResult) {
      s_logger.debug("cycle fragment completed");
    }

    @Override
    public void cycleCompleted(final ViewComputationResultModel fullResult, final ViewDeltaResultModel deltaResult) {
      s_logger.debug("cycle {} completed", _count.get());
      if (_count.getAndIncrement() > 5) {
        processStatusResult(fullResult, _statusResult);
        _latch.countDown();
      }
    }
  }

  private static final String MIXED_CURRENCY = "MIXED_CURRENCY";
  private static final Logger s_logger = LoggerFactory.getLogger(ViewStatusCalculationTask.class);
 
  private static final String DEFAULT_CALC_CONFIG = "Default";
 
  private final String _securityType;
  private final Set<String> _valueRequirementNames;
  private final UniqueId _portfolioId;
  private final UserPrincipal _user;
  private final ToolContext _toolContext;
  private final CurrenciesAggregationFunction _currenciesAggrFunction;
  private final Map<UniqueId, String> _targetCurrenciesCache = Maps.newConcurrentMap();
  private final MarketDataSpecification _marketDataSpecification;
 
  public ViewStatusCalculationTask(ToolContext toolcontext, UniqueId portfolioId, UserPrincipal user, String securityType,
      Collection<String> valueRequirementNames, MarketDataSpecification marketDataSpecification) {
    ArgumentChecker.notNull(portfolioId, "portfolioId");
    ArgumentChecker.notNull(securityType, "securityType");
    ArgumentChecker.notNull(valueRequirementNames, "valueRequirementNames");
    ArgumentChecker.notNull(user, "user");
    ArgumentChecker.notNull(toolcontext, "toolcontext");
    ArgumentChecker.notNull(marketDataSpecification, "marketDataSpecification");
   
    _portfolioId = portfolioId;
    _user = user;
    _securityType = securityType;
    _valueRequirementNames = ImmutableSet.copyOf(valueRequirementNames);
    _toolContext = toolcontext;
    _currenciesAggrFunction = new CurrenciesAggregationFunction(_toolContext.getSecuritySource());
    _marketDataSpecification = marketDataSpecification;
  }

  @Override
  public PerViewStatusResult call() throws Exception {
    s_logger.debug("Start calculating result for security:{} with values{}", _securityType, Sets.newTreeSet(_valueRequirementNames).toString());
   
    final PerViewStatusResult statusResult = new PerViewStatusResult(_securityType);
    //No need to do any work if there are no ValueRequirements to compute
    if (_valueRequirementNames.isEmpty()) {
      return statusResult;
    }
    final ViewDefinition viewDefinition = createViewDefinition();
    final ViewProcessor viewProcessor = _toolContext.getViewProcessor();
    final ViewClient client = viewProcessor.createViewClient(_user);

    final CountDownLatch latch = new CountDownLatch(1);
    client.setResultListener(new ViewStatusResultListener(latch, statusResult, viewDefinition));
    client.attachToViewProcess(viewDefinition.getUniqueId(), ExecutionOptions.infinite(_marketDataSpecification));
  
    try {
      s_logger.info("main thread waiting");
      if (!latch.await(30, TimeUnit.SECONDS)) {
        s_logger.error("Timed out waiting for {}", viewDefinition);
      }
    } catch (final InterruptedException ex) {
      throw new OpenGammaRuntimeException("Interrupted while waiting for " + viewDefinition, ex);
    }
    client.detachFromViewProcess();
    removeViewDefinition(viewDefinition);
    s_logger.debug("PerViewStatusResult for securityType:{} is {}", _securityType, statusResult);
    return statusResult;
  }

 

  protected boolean isValidTargetType(final ComputationTargetType computationTargetType) {
    if (ComputationTargetType.POSITION.isCompatible(computationTargetType) || ComputationTargetType.PORTFOLIO.isCompatible(computationTargetType) ||
        ComputationTargetType.PORTFOLIO_NODE.isCompatible(computationTargetType) || ComputationTargetType.TRADE.isCompatible(computationTargetType)) {
      return true;
    }
    return false;
  }

  private void removeViewDefinition(ViewDefinition viewDefinition) {
    s_logger.debug("Removing ViewDefintion with id: {}", viewDefinition.getUniqueId());
    ConfigMaster configMaster = _toolContext.getConfigMaster();
    configMaster.remove(viewDefinition.getUniqueId().getObjectId());
    s_logger.debug("ViewDefinition {} removed", viewDefinition.getUniqueId());
  }

  private ViewDefinition createViewDefinition() {
    final ViewDefinition viewDefinition = new ViewDefinition("VS_VIEW_" + GUIDGenerator.generate().toString(), _portfolioId, _user);
    viewDefinition.setMaxDeltaCalculationPeriod(500L);
    viewDefinition.setMaxFullCalculationPeriod(500L);
    viewDefinition.setMinDeltaCalculationPeriod(500L);
    viewDefinition.setMinFullCalculationPeriod(500L);

    ViewCalculationConfiguration defaultCalConfig = new ViewCalculationConfiguration(viewDefinition, DEFAULT_CALC_CONFIG);
    for (String requiredOutput : _valueRequirementNames) {
      defaultCalConfig.addPortfolioRequirementName(_securityType, requiredOutput);
    }
    viewDefinition.addViewCalculationConfiguration(defaultCalConfig);
    return storeViewDefinition(viewDefinition);
  }
 
  private ViewDefinition storeViewDefinition(final ViewDefinition viewDefinition) {
    ConfigItem<ViewDefinition> config = ConfigItem.of(viewDefinition, viewDefinition.getName(), ViewDefinition.class);
    config = ConfigMasterUtils.storeByName(_toolContext.getConfigMaster(), config);
    return config.getValue();
  }
 
  private void processGraphFailResult(final PerViewStatusResult statusResult) {
    PositionSource positionSource = _toolContext.getPositionSource();
    Portfolio portfolio = positionSource.getPortfolio(_portfolioId, VersionCorrection.LATEST);
    List<Position> positions = PortfolioAggregator.flatten(portfolio);
    Set<String> currencies = Sets.newHashSet();
    for (Position position : positions) {
      if (position.getSecurity() == null) {
        position.getSecurityLink().resolve(_toolContext.getSecuritySource());
      }
      if (position.getSecurity() != null && _securityType.equals(position.getSecurity().getSecurityType())) {
        currencies.add(getCurrency(position.getUniqueId(), ComputationTargetType.POSITION));
      }
    }
    for (String valueName : _valueRequirementNames) {
      for (String currency : currencies) {
        statusResult.put(new ViewStatusKeyBean(_securityType, valueName, currency, ComputationTargetType.POSITION.getName()), ViewStatus.GRAPH_FAIL);
      }
    }
  }
 
  private void processStatusResult(ViewComputationResultModel fullResult, PerViewStatusResult statusResult) {
    ViewCalculationResultModel calculationResult = fullResult.getCalculationResult(DEFAULT_CALC_CONFIG);
    Collection<ComputationTargetSpecification> allTargets = calculationResult.getAllTargets();
    for (ComputationTargetSpecification targetSpec : allTargets) {
      ComputationTargetType targetType = targetSpec.getSpecification().getType();
      if (isValidTargetType(targetType)) {
        Map<Pair<String, ValueProperties>, ComputedValueResult> values = calculationResult.getValues(targetSpec);
        for (Map.Entry<Pair<String, ValueProperties>, ComputedValueResult> valueEntry : values.entrySet()) {
          String valueName = valueEntry.getKey().getFirst();
          String currency = getCurrency(targetSpec.getUniqueId(), targetType);
          s_logger.debug("{} currency returned for id:{} targetType:{}", currency, targetSpec.getUniqueId(), targetType);
          if (currency != null) {
            ComputedValueResult computedValue = valueEntry.getValue();
            if (isGoodValue(computedValue)) {
              statusResult.put(new ViewStatusKeyBean(_securityType, valueName, currency, targetType.getName()), ViewStatus.VALUE);
            }
          } else {
            s_logger.error("Discarding result as NULL return as Currency for id: {} targetType:{}", targetSpec.getUniqueId(), targetType);
          }
        }
      }
    }
  }
 
  private String getCurrency(UniqueId uniqueId, ComputationTargetType computationTargetType) {
    synchronized (_targetCurrenciesCache) {
      String currency = _targetCurrenciesCache.get(uniqueId);
      if (currency == null) {
        if (ComputationTargetType.PORTFOLIO_NODE.isCompatible(computationTargetType) || ComputationTargetType.PORTFOLIO.isCompatible(computationTargetType)) {
          currency = MIXED_CURRENCY;
        } else if (ComputationTargetType.POSITION.isCompatible(computationTargetType)) {
          PositionSource positionSource = _toolContext.getPositionSource();
          Position position = positionSource.getPosition(uniqueId);
          if (position.getSecurity() == null) {
            position.getSecurityLink().resolve(_toolContext.getSecuritySource());
          }
          if (position.getSecurity() != null) {
            currency = _currenciesAggrFunction.classifyPosition(position);
          }
        } else if (ComputationTargetType.TRADE.isCompatible(computationTargetType)) {
          PositionSource positionSource = _toolContext.getPositionSource();
          Trade trade = positionSource.getTrade(uniqueId);
          if (trade.getSecurity() == null) {
            trade.getSecurityLink().resolve(_toolContext.getSecuritySource());
          }
          if (trade.getSecurity() != null) {
            currency = CurrenciesAggregationFunction.classifyBasedOnSecurity(trade.getSecurity(), _toolContext.getSecuritySource());
          }
        }
      }
      if (currency == null) {
        currency = CurrenciesAggregationFunction.NO_CURRENCY;
      }
      _targetCurrenciesCache.put(uniqueId, currency);
      return currency;
    }
  }
 
  private boolean isGoodValue(final ComputedValueResult computedValue) {
    if (computedValue == null || computedValue.getValue() == null || StringUtils.EMPTY.equals(computedValue.getValue())) {
      return false;
    } else {
      return !(computedValue.getValue() instanceof MissingValue);
    }
  }
 
}
TOP

Related Classes of com.opengamma.integration.viewer.status.impl.ViewStatusCalculationTask$ViewStatusResultListener

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.