/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.integration.regression; import java.util.EnumSet; import java.util.List; import java.util.Properties; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicReference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.threeten.bp.Instant; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.opengamma.OpenGammaRuntimeException; import com.opengamma.core.position.PositionSource; import com.opengamma.core.security.SecuritySource; import com.opengamma.engine.marketdata.spec.MarketDataSpecification; import com.opengamma.engine.marketdata.spec.UserMarketDataSpecification; 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.client.ViewResultMode; import com.opengamma.engine.view.compilation.CompiledViewDefinition; import com.opengamma.engine.view.execution.ArbitraryViewCycleExecutionSequence; import com.opengamma.engine.view.execution.ExecutionFlags; import com.opengamma.engine.view.execution.ExecutionOptions; import com.opengamma.engine.view.execution.ViewCycleExecutionOptions; import com.opengamma.engine.view.execution.ViewExecutionFlags; import com.opengamma.engine.view.execution.ViewExecutionOptions; import com.opengamma.engine.view.listener.AbstractViewResultListener; import com.opengamma.id.UniqueId; import com.opengamma.id.VersionCorrection; import com.opengamma.integration.server.RemoteServer; import com.opengamma.livedata.UserPrincipal; import com.opengamma.master.config.ConfigMaster; import com.opengamma.master.config.ConfigSearchRequest; import com.opengamma.master.config.ConfigSearchResult; import com.opengamma.master.marketdatasnapshot.MarketDataSnapshotMaster; import com.opengamma.master.marketdatasnapshot.MarketDataSnapshotSearchRequest; import com.opengamma.master.marketdatasnapshot.MarketDataSnapshotSearchResult; import com.opengamma.util.ArgumentChecker; /** */ /* package */ class ViewRunner { private static final Logger s_logger = LoggerFactory.getLogger(ViewRunner.class); private final ConfigMaster _configMaster; private final ViewProcessor _viewProcessor; private final PositionSource _positionSource; private final SecuritySource _securitySource; private final MarketDataSnapshotMaster _snapshotMaster; /* package */ ViewRunner(ConfigMaster configMaster, ViewProcessor viewProcessor, PositionSource positionSource, SecuritySource securitySource, MarketDataSnapshotMaster snapshotMaster) { ArgumentChecker.notNull(configMaster, "configMaster"); ArgumentChecker.notNull(viewProcessor, "viewProcessor"); ArgumentChecker.notNull(positionSource, "positionSource"); ArgumentChecker.notNull(snapshotMaster, "snapshotMaster"); ArgumentChecker.notNull(securitySource, "securitySource"); _securitySource = securitySource; _configMaster = configMaster; _viewProcessor = viewProcessor; _positionSource = positionSource; _snapshotMaster = snapshotMaster; } // TODO convert to a tool /* TODO inputs working directories (and versions?) for each of the two servers views/snapshots/valuation times is it possible to infer it all? run each view using the snapshots which have it as their basis view? either have a fixed valuation time or use Instant.now() (but only once for all runs) where does the DB dump live? presumably with the test config. separate repo / project? part of integration tests repo? or checked into the main repo? after 'mvn install' the server is in $PROJECT_DIR/server/target/server-dir */ public static void main(String[] args) throws Exception { Instant valuationTime = Instant.now(); int serverHttpPort = 8080; String workingDir = System.getProperty("user.dir"); String configFile = "classpath:fullstack/fullstack-examplessimulated-bin.properties"; String projectName = "examples-simulated"; String version = "2.2.0-SNAPSHOT"; String serverJar = projectName + "-" + version + ".jar"; String classpath = "config:lib/" + serverJar; String logbackConfig = "-Dlogback.configurationFile=com/opengamma/util/warn-logback.xml"; try (ServerProcess ignored = ServerProcess.start(workingDir, classpath, configFile, new Properties(), logbackConfig); RemoteServer server = RemoteServer.create("http://localhost:" + serverHttpPort)) { ViewRunner viewRunner = new ViewRunner(server.getConfigMaster(), server.getViewProcessor(), server.getPositionSource(), server.getSecuritySource(), server.getMarketDataSnapshotMaster()); CalculationResults results1 = viewRunner.run( version, "AUD Swaps (3m / 6m basis) (1)", "AUD Swaps (3m / 6m basis) (1)/2013-09-27T12:17:45.587Z", valuationTime); CalculationResults results2 = viewRunner.run( version, "AUD Swaps (3m / 6m basis) (1)", "AUD Swaps (3m / 6m basis) (1)/2013-09-27T12:17:45.587Z", valuationTime); CalculationDifference difference = CalculationDifference.between(results1, results2, 0.001d); System.out.println(difference); } } public CalculationResults run(String version, String viewName, String snapshotName, Instant valuationTime) { ArgumentChecker.notNull(viewName, "viewName"); ArgumentChecker.notNull(snapshotName, "snapshotName"); UniqueId snapshotId = getSnapshotId(snapshotName); UniqueId viewDefId = getViewDefinitionId(viewName); s_logger.info("Running view {} using snapshot {} at valuation time {}", viewName, snapshotName, valuationTime); List<MarketDataSpecification> marketDataSpecs = Lists.<MarketDataSpecification>newArrayList(UserMarketDataSpecification.of(snapshotId)); ViewCycleExecutionOptions cycleOptions = ViewCycleExecutionOptions .builder() .setValuationTime(valuationTime) .setMarketDataSpecifications(marketDataSpecs) // TODO multiple snapshots without rebuilding the graph? .setResolverVersionCorrection(VersionCorrection.LATEST) .create(); EnumSet<ViewExecutionFlags> flags = ExecutionFlags.triggersEnabled().get(); ArbitraryViewCycleExecutionSequence sequence = new ArbitraryViewCycleExecutionSequence(ImmutableList.of(cycleOptions)); ViewExecutionOptions executionOptions = ExecutionOptions.of(sequence, cycleOptions, flags); ViewProcessor viewProcessor = _viewProcessor; ViewClient viewClient = viewProcessor.createViewClient(UserPrincipal.getLocalUser()); Listener listener = new Listener(_positionSource, _securitySource, snapshotName, version); viewClient.setResultListener(listener); viewClient.setResultMode(ViewResultMode.FULL_ONLY); System.out.println("attaching to view process for view definition '" + viewName + "' with snapshot '" + snapshotName + "'"); viewClient.attachToViewProcess(viewDefId, executionOptions, true); System.out.println("waiting for completion"); try { viewClient.waitForCompletion(); System.out.println("view client completed"); } catch (InterruptedException e) { throw new OpenGammaRuntimeException("Interrupted waiting for view client to complete", e); } viewClient.shutdown(); return listener.getResults(); } private UniqueId getSnapshotId(String snapshotName) { //String snapshotTime = "2013-09-27T12:17:45.587Z"; //String snapshotName = snapshotName + "/" + snapshotTime; MarketDataSnapshotSearchRequest snapshotSearchRequest = new MarketDataSnapshotSearchRequest(); snapshotSearchRequest.setName(snapshotName); snapshotSearchRequest.setIncludeData(false); MarketDataSnapshotSearchResult snapshotSearchResult = _snapshotMaster.search(snapshotSearchRequest); return snapshotSearchResult.getSingleSnapshot().getUniqueId(); } private UniqueId getViewDefinitionId(String viewDefName) { ConfigSearchRequest<ViewDefinition> configSearchRequest = new ConfigSearchRequest<>(ViewDefinition.class); configSearchRequest.setName(viewDefName); ConfigSearchResult<ViewDefinition> configSearchResult = _configMaster.search(configSearchRequest); return configSearchResult.getSingleValue().getValue().getUniqueId(); } } class Listener extends AbstractViewResultListener { private final AtomicReference<CompiledViewDefinition> _viewDef = new AtomicReference<>(); private final PositionSource _positionSource; private final SecuritySource _securitySource; private final CountDownLatch _latch = new CountDownLatch(1); private final String _version; private final String _snapshotName; private CalculationResults _results; Listener(PositionSource positionSource, SecuritySource securitySource, String snapshotName, String version) { ArgumentChecker.notNull(positionSource, "positionSource"); ArgumentChecker.notNull(securitySource, "securitySource"); ArgumentChecker.notEmpty(snapshotName, "snapshotName"); ArgumentChecker.notEmpty(version, "version"); _version = version; _securitySource = securitySource; _snapshotName = snapshotName; _positionSource = positionSource; } @Override public UserPrincipal getUser() { return UserPrincipal.getLocalUser(); } @Override public void viewDefinitionCompiled(CompiledViewDefinition compiledViewDefinition, boolean hasMarketDataPermissions) { System.out.println("view def compiled"); _viewDef.set(compiledViewDefinition); } @Override public void viewDefinitionCompilationFailed(Instant valuationTime, Exception exception) { System.out.println("view def compilation failed " + exception); } @Override public void processTerminated(boolean executionInterrupted) { System.out.println("process terminated"); } @Override public void processCompleted() { System.out.println("process completed"); } @Override public void cycleCompleted(ViewComputationResultModel fullResult, ViewDeltaResultModel deltaResult) { try { System.out.println("cycle completed - building CalculationResults object"); _results = CalculationResults.create(fullResult, _viewDef.get(), _snapshotName, fullResult.getViewCycleExecutionOptions().getValuationTime(), _version, _positionSource, _securitySource); System.out.println("built CalculationResults object"); } finally { _latch.countDown(); } } public CalculationResults getResults() { try { _latch.await(); } catch (InterruptedException e) { // not going to happen throw new OpenGammaRuntimeException("unexpected exception", e); } return _results; } }