Search in sources :

Example 31 with RouterConfig

use of com.github.ambry.config.RouterConfig in project ambry by linkedin.

the class NonBlockingRouterTest method testRequestResponseHandlerThreadExitFlow.

/**
 * Test RequestResponseHandler thread exit flow. If the RequestResponseHandlerThread exits on its own (due to a
 * Throwable), then the router gets closed immediately along with the completion of all the operations.
 */
@Test
public void testRequestResponseHandlerThreadExitFlow() throws Exception {
    nettyByteBufLeakHelper.setDisabled(true);
    Properties props = getNonBlockingRouterProperties("DC1");
    VerifiableProperties verifiableProperties = new VerifiableProperties((props));
    RouterConfig routerConfig = new RouterConfig(verifiableProperties);
    MockClusterMap mockClusterMap = new MockClusterMap();
    MockTime mockTime = new MockTime();
    router = new NonBlockingRouter(routerConfig, new NonBlockingRouterMetrics(mockClusterMap, routerConfig), new MockNetworkClientFactory(verifiableProperties, mockSelectorState, MAX_PORTS_PLAIN_TEXT, MAX_PORTS_SSL, CHECKOUT_TIMEOUT_MS, new MockServerLayout(mockClusterMap), mockTime), new LoggingNotificationSystem(), mockClusterMap, kms, cryptoService, cryptoJobHandler, accountService, mockTime, MockClusterMap.DEFAULT_PARTITION_CLASS);
    assertExpectedThreadCounts(2, 1);
    setOperationParams();
    mockSelectorState.set(MockSelectorState.ThrowExceptionOnAllPoll);
    Future future = router.putBlob(putBlobProperties, putUserMetadata, putChannel, new PutBlobOptionsBuilder().build());
    try {
        while (!future.isDone()) {
            mockTime.sleep(1000);
            Thread.yield();
        }
        future.get();
        Assert.fail("The operation should have failed");
    } catch (ExecutionException e) {
        Assert.assertEquals(RouterErrorCode.OperationTimedOut, ((RouterException) e.getCause()).getErrorCode());
    }
    setOperationParams();
    mockSelectorState.set(MockSelectorState.ThrowThrowableOnSend);
    future = router.putBlob(putBlobProperties, putUserMetadata, putChannel, new PutBlobOptionsBuilder().build());
    Thread requestResponseHandlerThreadRegular = TestUtils.getThreadByThisName("RequestResponseHandlerThread-0");
    Thread requestResponseHandlerThreadBackground = TestUtils.getThreadByThisName("RequestResponseHandlerThread-backgroundDeleter");
    if (requestResponseHandlerThreadRegular != null) {
        requestResponseHandlerThreadRegular.join(NonBlockingRouter.SHUTDOWN_WAIT_MS);
    }
    if (requestResponseHandlerThreadBackground != null) {
        requestResponseHandlerThreadBackground.join(NonBlockingRouter.SHUTDOWN_WAIT_MS);
    }
    try {
        future.get();
        Assert.fail("The operation should have failed");
    } catch (ExecutionException e) {
        Assert.assertEquals(RouterErrorCode.RouterClosed, ((RouterException) e.getCause()).getErrorCode());
    }
    assertClosed();
    // Ensure that both operations failed and with the right exceptions.
    Assert.assertEquals("No ChunkFiller Thread should be running after the router is closed", 0, TestUtils.numThreadsByThisName("ChunkFillerThread"));
    Assert.assertEquals("No RequestResponseHandler should be running after the router is closed", 0, TestUtils.numThreadsByThisName("RequestResponseHandlerThread"));
    Assert.assertEquals("All operations should have completed", 0, router.getOperationsCount());
}
Also used : VerifiableProperties(com.github.ambry.config.VerifiableProperties) BlobProperties(com.github.ambry.messageformat.BlobProperties) Properties(java.util.Properties) VerifiableProperties(com.github.ambry.config.VerifiableProperties) RouterConfig(com.github.ambry.config.RouterConfig) LoggingNotificationSystem(com.github.ambry.commons.LoggingNotificationSystem) Future(java.util.concurrent.Future) ExecutionException(java.util.concurrent.ExecutionException) MockTime(com.github.ambry.utils.MockTime) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) Test(org.junit.Test)

Example 32 with RouterConfig

use of com.github.ambry.config.RouterConfig in project ambry by linkedin.

the class CloudRouterTest method setRouter.

/**
 * Initialize and set the router with the given {@link Properties} and {@link MockServerLayout}
 * @param props the {@link Properties}
 * @param notificationSystem the {@link NotificationSystem} to use.
 */
@Override
protected void setRouter(Properties props, MockServerLayout mockServerLayout, NotificationSystem notificationSystem) throws Exception {
    VerifiableProperties verifiableProperties = new VerifiableProperties((props));
    RouterConfig routerConfig = new RouterConfig(verifiableProperties);
    routerMetrics = new NonBlockingRouterMetrics(mockClusterMap, routerConfig);
    CloudConfig cloudConfig = new CloudConfig(verifiableProperties);
    CloudDestinationFactory cloudDestinationFactory = Utils.getObj(cloudConfig.cloudDestinationFactoryClass, verifiableProperties, mockClusterMap.getMetricRegistry(), mockClusterMap);
    CloudDestination cloudDestination = cloudDestinationFactory.getCloudDestination();
    AccountService accountService = new InMemAccountService(false, true);
    CloudRouterFactory cloudRouterFactory = new CloudRouterFactory(verifiableProperties, mockClusterMap, new LoggingNotificationSystem(), null, accountService);
    RequestHandlerPool requestHandlerPool = cloudRouterFactory.getRequestHandlerPool(verifiableProperties, mockClusterMap, cloudDestination, cloudConfig);
    Map<ReplicaType, NetworkClientFactory> childFactories = new EnumMap<>(ReplicaType.class);
    childFactories.put(ReplicaType.CLOUD_BACKED, new LocalNetworkClientFactory((LocalRequestResponseChannel) requestHandlerPool.getChannel(), new NetworkConfig(verifiableProperties), new NetworkMetrics(routerMetrics.getMetricRegistry()), mockTime));
    childFactories.put(ReplicaType.DISK_BACKED, new MockNetworkClientFactory(verifiableProperties, mockSelectorState, MAX_PORTS_PLAIN_TEXT, MAX_PORTS_SSL, CHECKOUT_TIMEOUT_MS, mockServerLayout, mockTime));
    NetworkClientFactory networkClientFactory = new CompositeNetworkClientFactory(childFactories);
    router = new NonBlockingRouter(routerConfig, routerMetrics, networkClientFactory, notificationSystem, mockClusterMap, kms, cryptoService, cryptoJobHandler, accountService, mockTime, MockClusterMap.DEFAULT_PARTITION_CLASS);
    router.addResourceToClose(requestHandlerPool);
}
Also used : LocalNetworkClientFactory(com.github.ambry.network.LocalNetworkClientFactory) LocalRequestResponseChannel(com.github.ambry.network.LocalRequestResponseChannel) VerifiableProperties(com.github.ambry.config.VerifiableProperties) LocalNetworkClientFactory(com.github.ambry.network.LocalNetworkClientFactory) NetworkClientFactory(com.github.ambry.network.NetworkClientFactory) CompositeNetworkClientFactory(com.github.ambry.network.CompositeNetworkClientFactory) NetworkMetrics(com.github.ambry.network.NetworkMetrics) CloudDestination(com.github.ambry.cloud.CloudDestination) CloudConfig(com.github.ambry.config.CloudConfig) NetworkConfig(com.github.ambry.config.NetworkConfig) CloudDestinationFactory(com.github.ambry.cloud.CloudDestinationFactory) LatchBasedInMemoryCloudDestinationFactory(com.github.ambry.cloud.LatchBasedInMemoryCloudDestinationFactory) RouterConfig(com.github.ambry.config.RouterConfig) CompositeNetworkClientFactory(com.github.ambry.network.CompositeNetworkClientFactory) InMemAccountService(com.github.ambry.account.InMemAccountService) LoggingNotificationSystem(com.github.ambry.commons.LoggingNotificationSystem) ReplicaType(com.github.ambry.clustermap.ReplicaType) RequestHandlerPool(com.github.ambry.protocol.RequestHandlerPool) AccountService(com.github.ambry.account.AccountService) InMemAccountService(com.github.ambry.account.InMemAccountService) EnumMap(java.util.EnumMap)

Example 33 with RouterConfig

use of com.github.ambry.config.RouterConfig in project ambry by linkedin.

the class OperationTrackerTest method operationClassTest.

/**
 * Test that operation tracker can correctly populate parameters(i.e. successTarget) based on input {@link RouterOperation}.
 */
@Test
public void operationClassTest() {
    Properties props = new Properties();
    props.setProperty("router.hostname", "localhost");
    props.setProperty("router.datacenter.name", "dc-0");
    props.setProperty("router.get.success.target", "1");
    props.setProperty("router.put.success.target", "2");
    props.setProperty("router.delete.success.target", "2");
    props.setProperty("router.ttl.update.success.target", "2");
    RouterConfig routerConfig = new RouterConfig(new VerifiableProperties(props));
    initialize();
    NonBlockingRouterMetrics routerMetrics = new NonBlockingRouterMetrics(mockClusterMap, routerConfig);
    Map<RouterOperation, Integer> operationAndSuccessTarget = new HashMap<>();
    operationAndSuccessTarget.put(RouterOperation.GetBlobOperation, 1);
    operationAndSuccessTarget.put(RouterOperation.GetBlobInfoOperation, 1);
    operationAndSuccessTarget.put(RouterOperation.PutOperation, 2);
    operationAndSuccessTarget.put(RouterOperation.DeleteOperation, 2);
    operationAndSuccessTarget.put(RouterOperation.TtlUpdateOperation, 2);
    for (Map.Entry<RouterOperation, Integer> entry : operationAndSuccessTarget.entrySet()) {
        SimpleOperationTracker operationTracker = null;
        switch(operationTrackerType) {
            case SIMPLE_OP_TRACKER:
                operationTracker = new SimpleOperationTracker(routerConfig, entry.getKey(), mockPartition, originatingDcName, true, routerMetrics);
                break;
            case ADAPTIVE_OP_TRACKER:
                try {
                    operationTracker = new AdaptiveOperationTracker(routerConfig, routerMetrics, entry.getKey(), mockPartition, originatingDcName, time);
                } catch (IllegalArgumentException e) {
                    assertTrue("Get operation shouldn't throw any exception in adaptive tracker", entry.getKey() != RouterOperation.GetBlobOperation && entry.getKey() != RouterOperation.GetBlobInfoOperation);
                }
                break;
        }
        // ensure the success target matches the number specified for each type of operaiton
        if (operationTracker != null) {
            assertEquals("The suggest target doesn't match", (long) entry.getValue(), operationTracker.getSuccessTarget(ReplicaType.DISK_BACKED));
        }
    }
}
Also used : VerifiableProperties(com.github.ambry.config.VerifiableProperties) HashMap(java.util.HashMap) Properties(java.util.Properties) VerifiableProperties(com.github.ambry.config.VerifiableProperties) RouterConfig(com.github.ambry.config.RouterConfig) HashMap(java.util.HashMap) Map(java.util.Map) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) Test(org.junit.Test)

Example 34 with RouterConfig

use of com.github.ambry.config.RouterConfig in project ambry by linkedin.

the class AdaptiveOperationTrackerTest method invalidOperationTrackerScopeTest.

/**
 * Test that if metric scope in router config is invalid, the {@link IllegalArgumentException} is thrown explicitly.
 */
@Test
public void invalidOperationTrackerScopeTest() {
    Properties props = new Properties();
    props.setProperty("router.hostname", "localhost");
    props.setProperty("router.datacenter.name", localDcName);
    props.setProperty("router.operation.tracker.metric.scope", "Invalid Scope");
    props.setProperty("router.get.success.target", Integer.toString(1));
    props.setProperty("router.get.request.parallelism", Integer.toString(1));
    RouterConfig routerConfig = null;
    try {
        routerConfig = new RouterConfig(new VerifiableProperties(props));
    } catch (IllegalArgumentException e) {
        // exception is expected and set valid metric scope to instantiate routerConfig for subsequent test.
        props.setProperty("router.operation.tracker.metric.scope", "Datacenter");
        routerConfig = new RouterConfig(new VerifiableProperties(props));
    }
    NonBlockingRouterMetrics routerMetrics = new NonBlockingRouterMetrics(mockClusterMap, routerConfig);
    AdaptiveOperationTracker tracker = new AdaptiveOperationTracker(routerConfig, routerMetrics, RouterOperation.GetBlobInfoOperation, mockPartition, null, time);
    // test that operation tracker works correctly with default Datacenter scope
    sendRequests(tracker, 1);
    assertFalse("Operation should not be done", tracker.isDone());
    tracker.onResponse(partitionAndInflightReplicas.get(mockPartition).poll(), TrackedRequestFinalState.SUCCESS);
    assertTrue("Operation should have succeeded", tracker.hasSucceeded());
    // test that no other resource-level metrics have been instantiated.
    assertTrue("Partition histogram in RouterMetrics should be empty", routerMetrics.getBlobInfoLocalDcResourceToLatency.isEmpty());
    assertTrue("Partition histogram in RouterMetrics should be empty", routerMetrics.getBlobInfoCrossDcResourceToLatency.isEmpty());
    assertTrue("Partition histogram in OperationTracker should be empty", tracker.getResourceToLatencyMap(RouterOperation.GetBlobInfoOperation, true).isEmpty());
    assertTrue("Partition histogram in OperationTracker should be empty", tracker.getResourceToLatencyMap(RouterOperation.GetBlobInfoOperation, false).isEmpty());
    // extra test: invalid router operation
    try {
        tracker.getResourceToLatencyMap(RouterOperation.TtlUpdateOperation, true);
        fail("should fail due to invalid router operation");
    } catch (IllegalArgumentException e) {
    // expected
    }
}
Also used : VerifiableProperties(com.github.ambry.config.VerifiableProperties) Properties(java.util.Properties) VerifiableProperties(com.github.ambry.config.VerifiableProperties) RouterConfig(com.github.ambry.config.RouterConfig) Test(org.junit.Test)

Example 35 with RouterConfig

use of com.github.ambry.config.RouterConfig in project ambry by linkedin.

the class ChunkFillTest method testChunkNumAndSizeCalculations.

/**
 * Test the calculation of number of chunks and the size of each chunk, using a very large blob size. No content
 * comparison is done. This test does not consume memory more than chunkSize.
 */
@Test
public void testChunkNumAndSizeCalculations() throws Exception {
    chunkSize = 4 * 1024 * 1024;
    // a large blob greater than Integer.MAX_VALUE and not at chunk size boundary.
    final long blobSize = ((long) Integer.MAX_VALUE / chunkSize + 1) * chunkSize + random.nextInt(chunkSize - 1) + 1;
    VerifiableProperties vProps = getNonBlockingRouterProperties();
    MockClusterMap mockClusterMap = new MockClusterMap();
    RouterConfig routerConfig = new RouterConfig(vProps);
    NonBlockingRouterMetrics routerMetrics = new NonBlockingRouterMetrics(mockClusterMap, routerConfig);
    short accountId = Utils.getRandomShort(random);
    short containerId = Utils.getRandomShort(random);
    BlobProperties putBlobProperties = new BlobProperties(blobSize, "serviceId", "memberId", "contentType", false, Utils.Infinite_Time, accountId, containerId, false, null, null, null);
    Random random = new Random();
    byte[] putUserMetadata = new byte[10];
    random.nextBytes(putUserMetadata);
    final MockReadableStreamChannel putChannel = new MockReadableStreamChannel(blobSize, false);
    FutureResult<String> futureResult = new FutureResult<String>();
    MockTime time = new MockTime();
    MockNetworkClientFactory networkClientFactory = new MockNetworkClientFactory(vProps, null, 0, 0, 0, null, time);
    PutOperation op = PutOperation.forUpload(routerConfig, routerMetrics, mockClusterMap, new LoggingNotificationSystem(), new InMemAccountService(true, false), putUserMetadata, putChannel, PutBlobOptions.DEFAULT, futureResult, null, new RouterCallback(networkClientFactory.getNetworkClient(), new ArrayList<>()), null, null, null, null, new MockTime(), putBlobProperties, MockClusterMap.DEFAULT_PARTITION_CLASS, quotaChargeCallback);
    op.startOperation();
    numChunks = RouterUtils.getNumChunksForBlobAndChunkSize(blobSize, chunkSize);
    // largeBlobSize is not a multiple of chunkSize
    int expectedNumChunks = (int) (blobSize / chunkSize + 1);
    Assert.assertEquals("numChunks should be as expected", expectedNumChunks, numChunks);
    int lastChunkSize = (int) (blobSize % chunkSize);
    final AtomicReference<Exception> channelException = new AtomicReference<Exception>(null);
    int chunkIndex = 0;
    // The write to the MockReadableStreamChannel blocks until the data is read as part fo the chunk filling,
    // so create a thread that fills the MockReadableStreamChannel.
    Utils.newThread(new Runnable() {

        @Override
        public void run() {
            try {
                byte[] writeBuf = new byte[chunkSize];
                long written = 0;
                while (written < blobSize) {
                    int toWrite = (int) Math.min(chunkSize, blobSize - written);
                    putChannel.write(ByteBuffer.wrap(writeBuf, 0, toWrite));
                    written += toWrite;
                }
            } catch (Exception e) {
                channelException.set(e);
            }
        }
    }, false).start();
    // Do the chunk filling.
    boolean fillingComplete = false;
    do {
        op.fillChunks();
        // since the channel is ByteBuffer based.
        for (PutOperation.PutChunk putChunk : op.putChunks) {
            Assert.assertNull("Mock channel write should not have caused an exception", channelException.get());
            if (putChunk.isFree()) {
                continue;
            }
            if (chunkIndex == numChunks - 1) {
                // last chunk may not be Ready as it is dependent on the completion callback to be called.
                Assert.assertTrue("Chunk should be Building or Ready.", putChunk.getState() == PutOperation.ChunkState.Ready || putChunk.getState() == PutOperation.ChunkState.Building);
                if (putChunk.getState() == PutOperation.ChunkState.Ready) {
                    Assert.assertEquals("Chunk size should be the last chunk size", lastChunkSize, putChunk.buf.readableBytes());
                    Assert.assertTrue("Chunk Filling should be complete at this time", op.isChunkFillingDone());
                    fillingComplete = true;
                }
            } else {
                // if not last chunk, then the chunk should be full and Ready.
                Assert.assertEquals("Chunk should be ready.", PutOperation.ChunkState.Ready, putChunk.getState());
                Assert.assertEquals("Chunk size should be maxChunkSize", chunkSize, putChunk.buf.readableBytes());
                chunkIndex++;
                putChunk.clear();
            }
        }
    } while (!fillingComplete);
}
Also used : ArrayList(java.util.ArrayList) InMemAccountService(com.github.ambry.account.InMemAccountService) Random(java.util.Random) MockTime(com.github.ambry.utils.MockTime) VerifiableProperties(com.github.ambry.config.VerifiableProperties) AtomicReference(java.util.concurrent.atomic.AtomicReference) RouterConfig(com.github.ambry.config.RouterConfig) IOException(java.io.IOException) LoggingNotificationSystem(com.github.ambry.commons.LoggingNotificationSystem) BlobProperties(com.github.ambry.messageformat.BlobProperties) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) Test(org.junit.Test)

Aggregations

RouterConfig (com.github.ambry.config.RouterConfig)43 VerifiableProperties (com.github.ambry.config.VerifiableProperties)39 Properties (java.util.Properties)29 Test (org.junit.Test)28 BlobProperties (com.github.ambry.messageformat.BlobProperties)21 LoggingNotificationSystem (com.github.ambry.commons.LoggingNotificationSystem)18 MockClusterMap (com.github.ambry.clustermap.MockClusterMap)15 MockTime (com.github.ambry.utils.MockTime)12 ArrayList (java.util.ArrayList)12 InMemAccountService (com.github.ambry.account.InMemAccountService)10 PutManagerTest (com.github.ambry.router.PutManagerTest)10 ServerErrorCode (com.github.ambry.server.ServerErrorCode)9 HashMap (java.util.HashMap)8 Map (java.util.Map)8 CountDownLatch (java.util.concurrent.CountDownLatch)8 MockDataNodeId (com.github.ambry.clustermap.MockDataNodeId)7 BlobId (com.github.ambry.commons.BlobId)6 AtomicReference (java.util.concurrent.atomic.AtomicReference)6 ReplicaId (com.github.ambry.clustermap.ReplicaId)5 ResponseHandler (com.github.ambry.commons.ResponseHandler)5