/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.bbg.livedata.faketicks; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertTrue; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.opengamma.bbg.referencedata.ReferenceDataProvider; import com.opengamma.bbg.referencedata.ReferenceDataProviderGetRequest; import com.opengamma.bbg.referencedata.ReferenceDataProviderGetResult; import com.opengamma.bbg.referencedata.impl.AbstractReferenceDataProvider; import com.opengamma.bbg.referencedata.impl.BloombergReferenceDataProvider; import com.opengamma.bbg.test.BloombergLiveDataServerUtils; import com.opengamma.core.id.ExternalSchemes; import com.opengamma.id.ExternalId; import com.opengamma.livedata.LiveDataClient; import com.opengamma.livedata.LiveDataListener; import com.opengamma.livedata.LiveDataSpecification; import com.opengamma.livedata.LiveDataValueUpdate; import com.opengamma.livedata.UserPrincipal; import com.opengamma.livedata.client.JmsLiveDataClient; import com.opengamma.livedata.msg.LiveDataSubscriptionResponse; import com.opengamma.livedata.msg.LiveDataSubscriptionResult; import com.opengamma.livedata.server.ExpirationManager; import com.opengamma.livedata.server.StandardLiveDataServer; import com.opengamma.livedata.server.Subscription; import com.opengamma.livedata.server.SubscriptionListener; import com.opengamma.livedata.test.CollectingLiveDataListener; import com.opengamma.livedata.test.LiveDataClientTestUtils; import com.opengamma.util.test.TestGroup; /** * Test. */ @Test(groups = TestGroup.INTEGRATION) public class CombiningBloombergLiveDataServerTest { private static final UserPrincipal TEST_USER = UserPrincipal.getTestUser(); private CombiningBloombergLiveDataServer _server; private JmsLiveDataClient _liveDataClient; private BloombergReferenceDataProvider _underlying; private UnitTestingReferenceDataProvider _unitTestingProvider; @BeforeMethod public void setUpClass() { _underlying = BloombergLiveDataServerUtils.getUnderlyingProvider(); _unitTestingProvider = new UnitTestingReferenceDataProvider(_underlying); _server = BloombergLiveDataServerUtils.startTestServer( CombiningBloombergLiveDataServerTest.class, new UnionFakeSubscriptionSelector( new BySchemeFakeSubscriptionSelector(ExternalSchemes.BLOOMBERG_BUID_WEAK, ExternalSchemes.BLOOMBERG_TICKER_WEAK), new ByTypeFakeSubscriptionSelector("SWAPTION VOLATILITY")), _unitTestingProvider); _liveDataClient = LiveDataClientTestUtils.getJmsClient(_server); _unitTestingProvider.reset(); } @AfterMethod public void tearDownClass() { BloombergLiveDataServerUtils.stopTestServer(_server); _liveDataClient.stop(); _underlying.stop(); } //------------------------------------------------------------------------- @Test public void testFakeSubscribe() throws Exception { ExternalId broken = ExternalId.of(ExternalSchemes.BLOOMBERG_TICKER, "CZPFGQFC Curncy"); ExternalId working = ExternalId.of(ExternalSchemes.BLOOMBERG_TICKER_WEAK, "USPFJD5W Curncy"); ExternalId workingStrong = ExternalId.of(ExternalSchemes.BLOOMBERG_TICKER, "USPFJD5W Curncy"); List<ExternalId> instruments = Lists.newArrayList(broken, working, workingStrong); int repeats = 2; CollectingLiveDataListener listener = new CollectingLiveDataListener(instruments.size() * repeats, 1 * repeats); for (int i = 0; i < repeats; i++) { subscribe(_liveDataClient, listener, instruments); unsubscribe(_liveDataClient, listener, instruments); _unitTestingProvider.rejectAllfurtherRequests(); } assertTrue(listener.waitUntilEnoughUpdatesReceived(30000)); LiveDataSubscriptionResponse workingSub = null; LiveDataSubscriptionResponse workingStrongSub = null; for (LiveDataSubscriptionResponse response : listener.getSubscriptionResponses()) { if (response.getRequestedSpecification().getIdentifiers().contains(working)) { assertEquals(response.getSubscriptionResult(), LiveDataSubscriptionResult.SUCCESS); workingSub = response; } else if (response.getRequestedSpecification().getIdentifiers().contains(broken)) { assertEquals(response.getSubscriptionResult(), LiveDataSubscriptionResult.INTERNAL_ERROR); } else if (response.getRequestedSpecification().getIdentifiers().contains(workingStrong)) { assertEquals(response.getSubscriptionResult(), LiveDataSubscriptionResult.SUCCESS); workingStrongSub = response; } else { throw new Exception("Unexpected subscription response"); } } assertEquals(workingSub.getFullyQualifiedSpecification(), workingStrongSub.getFullyQualifiedSpecification()); assertEquals(workingSub.getTickDistributionSpecification(), workingStrongSub.getTickDistributionSpecification()); List<LiveDataValueUpdate> allUpdates = listener.getValueUpdates(); List<LiveDataValueUpdate> workingUpdates = listener.getValueUpdates(getLiveDataSpec(_liveDataClient, working)); assertEquals(allUpdates, workingUpdates); assertFalse(_unitTestingProvider.hadToRejectRequests()); // Necessary, since exceptions are expected from the live data service } //------------------------------------------------------------------------- @Test(groups = {"bbgSubscriptionTests" }, enabled = false) public void testRealSubscribe() throws Exception { ExternalId strong = ExternalId.of(ExternalSchemes.BLOOMBERG_TICKER, "GBP Curncy"); List<ExternalId> instruments = Lists.newArrayList(strong); CollectingLiveDataListener listener = new CollectingLiveDataListener(instruments.size(), 3); subscribe(_liveDataClient, listener, instruments); assertTrue(listener.waitUntilEnoughUpdatesReceived(60000)); unsubscribe(_liveDataClient, listener, instruments); for (LiveDataSubscriptionResponse response : listener.getSubscriptionResponses()) { if (response.getRequestedSpecification().getIdentifiers().contains(strong)) { assertEquals(response.getSubscriptionResult(), LiveDataSubscriptionResult.SUCCESS); } } List<LiveDataValueUpdate> allUpdates = listener.getValueUpdates(); List<LiveDataValueUpdate> stronUpdates = listener.getValueUpdates(getLiveDataSpec(_liveDataClient, strong)); assertEquals(allUpdates, stronUpdates); } @Test(groups = {"bbgSubscriptionTests" }, enabled = false) public void testMixedSubscribe() throws Exception { ExternalId strong = ExternalId.of(ExternalSchemes.BLOOMBERG_TICKER, "GBP Curncy"); ExternalId weak = ExternalId.of(ExternalSchemes.BLOOMBERG_TICKER_WEAK, "GBP Curncy"); List<ExternalId> instruments = Lists.newArrayList(strong, weak); CollectingLiveDataListener listener = new CollectingLiveDataListener(instruments.size(), 3); subscribe(_liveDataClient, listener, instruments); assertTrue(listener.waitUntilEnoughUpdatesReceived(30000)); unsubscribe(_liveDataClient, listener, instruments); LiveDataSubscriptionResponse strongSub = null; LiveDataSubscriptionResponse weakSub = null; for (LiveDataSubscriptionResponse response : listener.getSubscriptionResponses()) { if (response.getRequestedSpecification().getIdentifiers().contains(strong)) { assertEquals(response.getSubscriptionResult(), LiveDataSubscriptionResult.SUCCESS); strongSub = response; } else if (response.getRequestedSpecification().getIdentifiers().contains(weak)) { assertEquals(response.getSubscriptionResult(), LiveDataSubscriptionResult.SUCCESS); weakSub = response; } else { throw new Exception("Unexpected subscription response"); } } assertFalse(strongSub.getFullyQualifiedSpecification().equals(weakSub.getFullyQualifiedSpecification())); assertFalse(strongSub.getTickDistributionSpecification().equals(weakSub.getTickDistributionSpecification())); List<LiveDataValueUpdate> allUpdates = listener.getValueUpdates(); List<LiveDataValueUpdate> stronUpdates = listener.getValueUpdates(getLiveDataSpec(_liveDataClient, strong)); List<LiveDataValueUpdate> weakUpdates = listener.getValueUpdates(getLiveDataSpec(_liveDataClient, weak)); assertEquals(1, weakUpdates.size()); assertEquals(allUpdates.size(), weakUpdates.size() + stronUpdates.size()); } @Test(groups = {"bbgSubscriptionTests" }, enabled = false) public void testBrokenSubscribe() throws Exception { ExternalId broken = ExternalId.of(ExternalSchemes.BLOOMBERG_TICKER, "USSV15F Curncy");//Broken ExternalId working = ExternalId.of(ExternalSchemes.BLOOMBERG_TICKER, "GBP Curncy"); List<ExternalId> instruments = Lists.newArrayList(broken, working); CollectingLiveDataListener listener = new CollectingLiveDataListener(instruments.size(), 3); subscribe(_liveDataClient, listener, instruments); assertTrue(listener.waitUntilEnoughUpdatesReceived(30000)); unsubscribe(_liveDataClient, listener, instruments); LiveDataSubscriptionResponse strongSub = null; LiveDataSubscriptionResponse weakSub = null; for (LiveDataSubscriptionResponse response : listener.getSubscriptionResponses()) { if (response.getRequestedSpecification().getIdentifiers().contains(working)) { assertEquals(LiveDataSubscriptionResult.SUCCESS, response.getSubscriptionResult()); strongSub = response; } else if (response.getRequestedSpecification().getIdentifiers().contains(broken)) { assertEquals(LiveDataSubscriptionResult.NOT_PRESENT, response.getSubscriptionResult()); weakSub = response; } else { throw new Exception("Unexpected subscription response"); } } assertFalse(strongSub.getFullyQualifiedSpecification().equals(weakSub.getFullyQualifiedSpecification())); assertFalse(strongSub.getTickDistributionSpecification().equals(weakSub.getTickDistributionSpecification())); List<LiveDataValueUpdate> allUpdates = listener.getValueUpdates(); List<LiveDataValueUpdate> brokenUpdates = listener.getValueUpdates(getLiveDataSpec(_liveDataClient, broken)); List<LiveDataValueUpdate> workingUpdates = listener.getValueUpdates(getLiveDataSpec(_liveDataClient, working)); assertEquals(0, brokenUpdates.size()); assertEquals(allUpdates.size(), brokenUpdates.size() + workingUpdates.size()); } @Test public void testExpiration() throws Exception { int period = 15000; ExpirationManager expirationManager = _server.getExpirationManager(); expirationManager.stop(); expirationManager.setCheckPeriod(15000); expirationManager.setTimeoutExtension(15000); expirationManager.start(); final AtomicInteger combinedSubs = countSubscriptions(_server); final AtomicInteger fakeSubs = countSubscriptions(_server.getFakeServer()); final AtomicInteger realSubs = countSubscriptions(_server.getRealServer()); ExternalId weak = ExternalId.of(ExternalSchemes.BLOOMBERG_TICKER_WEAK, "GBP Curncy"); List<ExternalId> instruments = Lists.newArrayList(weak); CollectingLiveDataListener listener = new CollectingLiveDataListener(1, 1); subscribe(_liveDataClient, listener, instruments); assertEquals(1, combinedSubs.get()); assertEquals(combinedSubs.get(), fakeSubs.get()); assertEquals(0, realSubs.get()); assertTrue(listener.waitUntilEnoughUpdatesReceived(30000)); for (int i = 0; i < 3; i++) { expirationManager.extendPublicationTimeout(ImmutableSet.of(getLiveDataSpec(_liveDataClient, weak))); Thread.sleep(period / 2); } assertEquals(1, combinedSubs.get()); assertEquals(combinedSubs.get(), fakeSubs.get()); assertEquals(0, realSubs.get()); unsubscribe(_liveDataClient, listener, instruments); Thread.sleep(period * 2); assertEquals(0, combinedSubs.get()); assertEquals(combinedSubs.get(), fakeSubs.get()); assertEquals(0, realSubs.get()); } private AtomicInteger countSubscriptions(StandardLiveDataServer server) { final AtomicInteger fakeSubs = new AtomicInteger(0); server.addSubscriptionListener(new SubscriptionListener() { @Override public void unsubscribed(Subscription subscription) { fakeSubs.decrementAndGet(); } @Override public void subscribed(Subscription subscription) { fakeSubs.incrementAndGet(); } }); return fakeSubs; } private void subscribe(LiveDataClient liveDataClient, LiveDataListener listener, Collection<ExternalId> instruments) { Collection<LiveDataSpecification> specs = getLiveDataSpecs(liveDataClient, instruments); liveDataClient.subscribe(TEST_USER, specs, listener); } private void unsubscribe(LiveDataClient liveDataClient, LiveDataListener listener, Collection<ExternalId> instruments) { Collection<LiveDataSpecification> specs = getLiveDataSpecs(liveDataClient, instruments); liveDataClient.unsubscribe(TEST_USER, specs, listener); } private Collection<LiveDataSpecification> getLiveDataSpecs(LiveDataClient liveDataClient, Collection<ExternalId> instruments) { Collection<LiveDataSpecification> specs = new ArrayList<LiveDataSpecification>(instruments.size()); for (ExternalId instrument : instruments) { specs.add(getLiveDataSpec(liveDataClient, instrument)); } return specs; } private LiveDataSpecification getLiveDataSpec(LiveDataClient liveDataClient, ExternalId id) { LiveDataSpecification requestedSpecification = new LiveDataSpecification( liveDataClient.getDefaultNormalizationRuleSetId(), id); return requestedSpecification; } @Test(groups = {"bbgSubscriptionTests" }, enabled = false) public void testRepeatedSubscriptions_BBG_80() throws Exception { ExternalId broken = ExternalId.of(ExternalSchemes.BLOOMBERG_TICKER, "USSV15F Curncy");//Broken ExternalId working = ExternalId.of(ExternalSchemes.BLOOMBERG_TICKER, "GBP Curncy"); ExternalId workingWeak = ExternalId.of(ExternalSchemes.BLOOMBERG_TICKER_WEAK, "USPFJD5W Curncy"); ExternalId workingStrong = ExternalId.of(ExternalSchemes.BLOOMBERG_TICKER, "USPFJD5W Curncy"); List<ExternalId> instruments = Lists.newArrayList(broken, working, workingWeak, workingStrong); for (int i = 0; i < 10; i++) { CollectingLiveDataListener listener = new CollectingLiveDataListener(instruments.size(), 3); subscribe(_liveDataClient, listener, instruments); assertTrue(listener.waitUntilEnoughUpdatesReceived(30000)); unsubscribe(_liveDataClient, listener, instruments); _unitTestingProvider.rejectAllfurtherRequests(); } assertFalse(_unitTestingProvider.hadToRejectRequests()); } //------------------------------------------------------------------------- public static class UnitTestingReferenceDataProvider extends AbstractReferenceDataProvider { private final ReferenceDataProvider _underlying; private java.util.concurrent.atomic.AtomicBoolean _locked = new java.util.concurrent.atomic.AtomicBoolean(); private java.util.concurrent.atomic.AtomicBoolean _broken = new java.util.concurrent.atomic.AtomicBoolean(); public UnitTestingReferenceDataProvider(ReferenceDataProvider underlying) { _underlying = underlying; } public void reset() { _locked.set(false); _broken.set(false); } public void rejectAllfurtherRequests() { _locked.set(true); } public boolean hadToRejectRequests() { return _broken.get(); } @Override protected ReferenceDataProviderGetResult doBulkGet(ReferenceDataProviderGetRequest request) { if (_locked.get()) { _broken.set(true); } assertFalse(_locked.get()); return _underlying.getReferenceData(request); } } }