com.opengamma.integration.viewer.status.impl.ViewStatusCalculationWorker.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.integration.viewer.status.impl.ViewStatusCalculationWorker.java

Source

/**
 * 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.Map;
import java.util.Set;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import com.google.common.collect.TreeMultimap;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.engine.marketdata.spec.MarketDataSpecification;
import com.opengamma.engine.view.helper.AvailableOutput;
import com.opengamma.engine.view.helper.AvailableOutputs;
import com.opengamma.engine.view.helper.AvailableOutputsProvider;
import com.opengamma.financial.tool.ToolContext;
import com.opengamma.id.UniqueId;
import com.opengamma.integration.viewer.status.ViewStatusKey;
import com.opengamma.integration.viewer.status.ViewStatusOption;
import com.opengamma.integration.viewer.status.ViewStatusResultAggregator;
import com.opengamma.livedata.UserPrincipal;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.NamedThreadPoolFactory;

/**
 * Executes the View status calculation task with the default Executor service
 */
public class ViewStatusCalculationWorker {

    private static final Logger s_logger = LoggerFactory.getLogger(ViewStatusCalculationWorker.class);

    private static final ExecutorService DEFAULT_EXECUTOR = Executors
            .newCachedThreadPool(new NamedThreadPoolFactory("ViewStatus"));

    private final ExecutorService _executor;

    private final Map<String, Collection<String>> _valueRequirementBySecType;

    private final ToolContext _toolContext;

    private final UniqueId _portfolioId;

    private final UserPrincipal _user;

    private final MarketDataSpecification _marketDataSpecification;

    public ViewStatusCalculationWorker(final ToolContext toolContext, final UniqueId portfolioId,
            final ViewStatusOption option) {
        this(toolContext, portfolioId, option, DEFAULT_EXECUTOR);
    }

    public ViewStatusCalculationWorker(final ToolContext toolContext, UniqueId portfolioId,
            final ViewStatusOption option, final ExecutorService executorService) {
        ArgumentChecker.notNull(toolContext, "toolContex");
        ArgumentChecker.notNull(portfolioId, "portfolioId");
        ArgumentChecker.notNull(option, "option");
        ArgumentChecker.notNull(option.getUser(), "option.user");
        ArgumentChecker.notNull(option.getMarketDataSpecification(), "option.marketDataSpecification");
        ArgumentChecker.notNull(executorService, "executorService");

        validateComponentsInToolContext(toolContext);
        _portfolioId = portfolioId;
        _user = option.getUser();
        _marketDataSpecification = option.getMarketDataSpecification();
        Map<String, Collection<String>> valueRequirementBySecType = scanValueRequirementBySecType(portfolioId,
                toolContext);
        if (s_logger.isDebugEnabled()) {
            StringBuilder strBuf = new StringBuilder();
            for (String securityType : Sets.newTreeSet(valueRequirementBySecType.keySet())) {
                Set<String> valueNames = Sets.newTreeSet(valueRequirementBySecType.get(securityType));
                strBuf.append(
                        String.format("%s\t%s\n", StringUtils.rightPad(securityType, 40), valueNames.toString()));
            }
            s_logger.debug("\n{}\n", strBuf.toString());
        }
        _toolContext = toolContext;
        _executor = executorService;
        _valueRequirementBySecType = valueRequirementBySecType;
    }

    private void validateComponentsInToolContext(ToolContext toolContext) {
        if (toolContext.getViewProcessor() == null) {
            throw new OpenGammaRuntimeException("Missing view processor in given toolcontext");
        }
        if (toolContext.getSecuritySource() == null) {
            throw new OpenGammaRuntimeException("Missing security source in given toolcontext");
        }
        if (toolContext.getConfigMaster() == null) {
            throw new OpenGammaRuntimeException("Missing config master in given toolcontext");
        }
        if (toolContext.getPositionSource() == null) {
            throw new OpenGammaRuntimeException("Missing position source in given toolcontext");
        }
    }

    private Map<String, Collection<String>> scanValueRequirementBySecType(UniqueId portfolioId,
            ToolContext toolContext) {
        AvailableOutputsProvider availableOutputsProvider = toolContext.getAvaliableOutputsProvider();
        if (availableOutputsProvider == null) {
            throw new OpenGammaRuntimeException("AvailableOutputsProvider missing from ToolContext");
        }
        final SetMultimap<String, String> valueNamesBySecurityType = TreeMultimap.create();

        AvailableOutputs portfolioOutputs = availableOutputsProvider.getPortfolioOutputs(portfolioId, null);
        Set<String> securityTypes = portfolioOutputs.getSecurityTypes();
        for (String securityType : securityTypes) {
            Set<AvailableOutput> positionOutputs = portfolioOutputs.getPositionOutputs(securityType);
            for (AvailableOutput availableOutput : positionOutputs) {
                valueNamesBySecurityType.put(securityType, availableOutput.getValueName());
            }
        }
        return valueNamesBySecurityType.asMap();
    }

    public ViewStatusResultAggregator run() {
        ViewStatusResultAggregator aggregator = new ViewStatusResultAggregatorImpl();
        CompletionService<PerViewStatusResult> completionService = new ExecutorCompletionService<PerViewStatusResult>(
                _executor);
        //submit task to executor to run partitioned by security type
        for (String securityType : _valueRequirementBySecType.keySet()) {
            Collection<String> valueRequirements = _valueRequirementBySecType.get(securityType);
            completionService.submit(new ViewStatusCalculationTask(_toolContext, _portfolioId, _user, securityType,
                    valueRequirements, _marketDataSpecification));
        }
        try {
            // process all completed task
            for (int i = 0; i < _valueRequirementBySecType.size(); i++) {
                Future<PerViewStatusResult> futureTask = completionService.take();
                PerViewStatusResult perViewStatusResult = futureTask.get();
                for (ViewStatusKey viewStatusKey : perViewStatusResult.keySet()) {
                    aggregator.putStatus(viewStatusKey, perViewStatusResult.get(viewStatusKey));
                }

            }
        } catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
        } catch (ExecutionException ex) {
            throw new OpenGammaRuntimeException("Error running View status report", ex.getCause());
        }
        return aggregator;
    }
}