/**
  * Creates a new key based on the view definition and a single market data availability provider.
  *
  * @param viewDefinition the view definition, not null
  * @param marketDataProvider the market data availability provider, not null
  * @return the cache key, not null
  */
 public static ViewExecutionCacheKey of(
     final ViewDefinition viewDefinition,
     final MarketDataAvailabilityProvider marketDataProvider) {
   return new ViewExecutionCacheKey(
       viewDefinition.getUniqueId(),
       new Serializable[] {marketDataProvider.getAvailabilityHintKey()});
 }
  private static List<RequirementBasedColumnKey> getRequirements(
      ViewDefinition viewDefinition, EnumSet<ComputationTargetType> targetTypes) {
    List<RequirementBasedColumnKey> result = new ArrayList<RequirementBasedColumnKey>();
    for (ViewCalculationConfiguration calcConfig :
        viewDefinition.getAllCalculationConfigurations()) {
      String calcConfigName = calcConfig.getName();
      if (targetTypes.contains(ComputationTargetType.POSITION)
          || targetTypes.contains(ComputationTargetType.PORTFOLIO_NODE)) {
        for (Pair<String, ValueProperties> portfolioOutput :
            calcConfig.getAllPortfolioRequirements()) {
          String valueName = portfolioOutput.getFirst();
          ValueProperties constraints = portfolioOutput.getSecond();
          RequirementBasedColumnKey columnKey =
              new RequirementBasedColumnKey(calcConfigName, valueName, constraints);
          result.add(columnKey);
        }
      }

      for (ValueRequirement specificRequirement : calcConfig.getSpecificRequirements()) {
        if (!targetTypes.contains(specificRequirement.getTargetSpecification().getType())) {
          continue;
        }
        String valueName = specificRequirement.getValueName();
        ValueProperties constraints = specificRequirement.getConstraints();
        RequirementBasedColumnKey columnKey =
            new RequirementBasedColumnKey(calcConfigName, valueName, constraints);
        result.add(columnKey);
      }
    }
    return result;
  }
 /**
  * Creates a new key based on the view definition and an array of market data availability
  * providers.
  *
  * @param viewDefinition the view definition, not null
  * @param marketDataProviders the market data availability providers, not null and not containing
  *     nulls
  * @return the cache key, not null
  */
 public static ViewExecutionCacheKey of(
     final ViewDefinition viewDefinition,
     final MarketDataAvailabilityProvider[] marketDataProviders) {
   final Serializable[] tokens = new Serializable[marketDataProviders.length];
   for (int i = 0; i < marketDataProviders.length; i++) {
     tokens[i] = marketDataProviders[i].getAvailabilityHintKey();
   }
   return new ViewExecutionCacheKey(viewDefinition.getUniqueId(), tokens);
 }
 /**
  * Creates a new key based on the view definition and an ordered collection of market data
  * availability providers.
  *
  * @param viewDefinition the view definition, not null
  * @param marketDataProviders the market data availability providers, not null and not containing
  *     nulls
  * @return the cache key, not null
  */
 public static ViewExecutionCacheKey of(
     final ViewDefinition viewDefinition,
     final Iterable<MarketDataAvailabilityProvider> marketDataProviders) {
   final Collection<Serializable> tokens = new LinkedList<Serializable>();
   for (MarketDataAvailabilityProvider marketDataProvider : marketDataProviders) {
     tokens.add(marketDataProvider.getAvailabilityHintKey());
   }
   return new ViewExecutionCacheKey(
       viewDefinition.getUniqueId(), tokens.toArray(new Serializable[tokens.size()]));
 }
 /**
  * Creates a new view.
  *
  * @param request Details of the view
  * @param clientId ID of the client connection
  * @param user User requesting the view
  * @param clientConnection Connection that will be notified of changes to the view
  * @param viewId ID of the view, must be unique
  * @param viewCallbackId ID that's passed to the listener when the view's portfolio grid structure
  *     changes
  * @param portfolioGridId ID that's passed to the listener when the view's portfolio grid
  *     structure changes
  * @param primitivesGridId ID that's passed to the listener when the view's primitives grid
  *     structure changes
  * @param errorId
  */
 public void createView(
     ViewRequest request,
     String clientId,
     UserPrincipal user,
     ClientConnection clientConnection,
     String viewId,
     Object viewCallbackId,
     String portfolioGridId,
     String primitivesGridId,
     String errorId) {
   if (_viewConnections.containsKey(viewId)) {
     throw new IllegalArgumentException("View ID " + viewId + " is already in use");
   }
   AggregatedViewDefinition aggregatedViewDef =
       new AggregatedViewDefinition(_aggregatedViewDefManager, request);
   ViewDefinition viewDef =
       (ViewDefinition) _configSource.get(aggregatedViewDef.getUniqueId()).getValue();
   VersionCorrection versionCorrection = request.getPortfolioVersionCorrection();
   // this can be null for a primitives-only view
   UniqueId portfolioId = viewDef.getPortfolioId();
   Supplier<Portfolio> portfolioSupplier;
   ObjectId portfolioObjectId;
   if (portfolioId != null) {
     portfolioObjectId = portfolioId.getObjectId();
   } else {
     portfolioObjectId = null;
   }
   portfolioSupplier =
       new PortfolioSupplier(
           portfolioObjectId,
           versionCorrection,
           _positionSource,
           _securitySource,
           _portfolioResolutionExecutor);
   // TODO something a bit more sophisticated with the executor
   ViewClient viewClient = _viewProcessor.createViewClient(user);
   s_logger.debug("Client ID {} creating new view with ID {}", clientId, viewId);
   ViewportListener viewportListener = new LoggingViewportListener(viewClient);
   PortfolioEntityExtractor entityExtractor =
       new PortfolioEntityExtractor(versionCorrection, _securityMaster);
   // TODO add filtering change listener to portfolio master which calls portfolioChanged() on the
   // outer view
   boolean primitivesOnly = portfolioId == null;
   ErrorManager errorManager = new ErrorManager(errorId);
   AnalyticsView view =
       new SimpleAnalyticsView(
           aggregatedViewDef.getUniqueId(),
           primitivesOnly,
           versionCorrection,
           viewId,
           portfolioGridId,
           primitivesGridId,
           _targetResolver,
           viewportListener,
           _blotterColumnMapper,
           portfolioSupplier,
           entityExtractor,
           request.showBlotterColumns(),
           errorManager);
   AnalyticsView lockingView = new LockingAnalyticsView(view);
   AnalyticsView notifyingView = new NotifyingAnalyticsView(lockingView, clientConnection);
   AnalyticsView timingView = new TimingAnalyticsView(notifyingView);
   AnalyticsView catchingView =
       new CatchingAnalyticsView(timingView, errorManager, clientConnection);
   AutoCloseable securityListener =
       new MasterNotificationListener<>(_securityMaster, catchingView);
   AutoCloseable positionListener =
       new MasterNotificationListener<>(_positionMaster, catchingView);
   AutoCloseable portfolioListener =
       new PortfolioListener(portfolioObjectId, catchingView, _positionSource);
   List<AutoCloseable> listeners =
       Lists.newArrayList(securityListener, positionListener, portfolioListener);
   AnalyticsViewClientConnection connection =
       new AnalyticsViewClientConnection(
           request,
           aggregatedViewDef,
           viewClient,
           catchingView,
           listeners,
           _parallelViewRecompilation,
           _marketDataSpecificationRepository,
           _portfolioResolutionExecutor,
           _securitySource);
   _viewConnections.put(viewId, connection);
   // need to notify the listener that the view has been created
   // TODO would it be neater to leave this to the constructor of NotifyingAnalyticsView
   clientConnection.itemUpdated(viewCallbackId);
   connection.start();
   clientConnection.addDisconnectionListener(new DisconnectionListener(viewId));
 }
 /**
  * Tests whether the view has portfolio outputs enabled.
  *
  * @param viewDefinition the view definition
  * @return {@code true} if there is at least one portfolio target, {@code false} otherwise
  */
 private static boolean isPortfolioOutputEnabled(ViewDefinition viewDefinition) {
   ResultModelDefinition resultModelDefinition = viewDefinition.getResultModelDefinition();
   return resultModelDefinition.getPositionOutputMode() != ResultOutputMode.NONE
       || resultModelDefinition.getAggregatePositionOutputMode() != ResultOutputMode.NONE;
 }
  private Future<?> executeTestJob(DependencyGraphExecutorFactory<?> factory) {
    final InMemoryLKVMarketDataProvider marketDataProvider = new InMemoryLKVMarketDataProvider();
    final MarketDataProviderResolver marketDataProviderResolver =
        new SingleMarketDataProviderResolver(
            new SingletonMarketDataProviderFactory(marketDataProvider));
    final InMemoryFunctionRepository functionRepository = new InMemoryFunctionRepository();
    _functionCount.set(0);
    final MockFunction mockFunction =
        new MockFunction(new ComputationTarget("Foo")) {

          @Override
          public Set<ComputedValue> execute(
              FunctionExecutionContext executionContext,
              FunctionInputs inputs,
              ComputationTarget target,
              Set<ValueRequirement> desiredValues) {
            try {
              Thread.sleep(JOB_FINISH_TIME / (JOB_SIZE * 2));
            } catch (InterruptedException e) {
              throw new OpenGammaRuntimeException("Function interrupted", e);
            }
            _functionCount.incrementAndGet();
            return super.execute(executionContext, inputs, target, desiredValues);
          }
        };
    functionRepository.addFunction(mockFunction);
    final FunctionCompilationContext compilationContext = new FunctionCompilationContext();
    final CompiledFunctionService compilationService =
        new CompiledFunctionService(
            functionRepository, new CachingFunctionRepositoryCompiler(), compilationContext);
    compilationService.initialize();
    final FunctionResolver functionResolver = new DefaultFunctionResolver(compilationService);
    final MockSecuritySource securitySource = new MockSecuritySource();
    final MockPositionSource positionSource = new MockPositionSource();
    final ViewComputationCacheSource computationCacheSource =
        new InMemoryViewComputationCacheSource(FudgeContext.GLOBAL_DEFAULT);
    final FunctionInvocationStatisticsGatherer functionInvocationStatistics =
        new DiscardingInvocationStatisticsGatherer();
    final ViewProcessorQueryReceiver viewProcessorQueryReceiver = new ViewProcessorQueryReceiver();
    final ViewProcessorQuerySender viewProcessorQuerySender =
        new ViewProcessorQuerySender(InMemoryRequestConduit.create(viewProcessorQueryReceiver));
    final FunctionExecutionContext executionContext = new FunctionExecutionContext();
    final ComputationTargetResolver targetResolver =
        new DefaultComputationTargetResolver(securitySource, positionSource);
    final JobDispatcher jobDispatcher =
        new JobDispatcher(
            new LocalNodeJobInvoker(
                new LocalCalculationNode(
                    computationCacheSource,
                    compilationService,
                    executionContext,
                    targetResolver,
                    viewProcessorQuerySender,
                    Executors.newCachedThreadPool(),
                    functionInvocationStatistics)));
    final ViewPermissionProvider viewPermissionProvider = new DefaultViewPermissionProvider();
    final GraphExecutorStatisticsGathererProvider graphExecutorStatisticsProvider =
        new DiscardingGraphStatisticsGathererProvider();

    ViewDefinition viewDefinition = new ViewDefinition("TestView", UserPrincipal.getTestUser());
    viewDefinition.addViewCalculationConfiguration(
        new ViewCalculationConfiguration(viewDefinition, "default"));
    MockViewDefinitionRepository viewDefinitionRepository = new MockViewDefinitionRepository();
    viewDefinitionRepository.addDefinition(viewDefinition);

    final ViewProcessContext vpc =
        new ViewProcessContext(
            viewDefinitionRepository,
            viewPermissionProvider,
            marketDataProviderResolver,
            compilationService,
            functionResolver,
            positionSource,
            securitySource,
            new DefaultCachingComputationTargetResolver(
                new DefaultComputationTargetResolver(securitySource, positionSource),
                EHCacheUtils.createCacheManager()),
            computationCacheSource,
            jobDispatcher,
            viewProcessorQueryReceiver,
            factory,
            graphExecutorStatisticsProvider);
    final DependencyGraph graph = new DependencyGraph("Default");
    DependencyNode previous = null;
    for (int i = 0; i < JOB_SIZE; i++) {
      DependencyNode node = new DependencyNode(new ComputationTarget("Foo"));
      node.setFunction(mockFunction);
      if (previous != null) {
        node.addInputNode(previous);
      }
      graph.addDependencyNode(node);
      previous = node;
    }
    final Map<String, DependencyGraph> graphs = new HashMap<String, DependencyGraph>();
    graphs.put(graph.getCalculationConfigurationName(), graph);
    CompiledViewDefinitionWithGraphsImpl viewEvaluationModel =
        new CompiledViewDefinitionWithGraphsImpl(
            viewDefinition, graphs, new SimplePortfolio("Test Portfolio"), 0);
    ViewCycleExecutionOptions cycleOptions = new ViewCycleExecutionOptions();
    cycleOptions.setValuationTime(Instant.ofEpochMillis(1));
    cycleOptions.setMarketDataSpecification(new MarketDataSpecification());
    final SingleComputationCycle cycle =
        new SingleComputationCycle(
            UniqueId.of("Test", "Cycle1"),
            UniqueId.of("Test", "ViewProcess1"),
            vpc,
            viewEvaluationModel,
            cycleOptions,
            VersionCorrection.of(Instant.ofEpochMillis(1), Instant.ofEpochMillis(1)));
    return cycle.getDependencyGraphExecutor().execute(graph, cycle.getStatisticsGatherer());
  }