Search in sources :

Example 16 with MockDataNodeId

use of com.github.ambry.clustermap.MockDataNodeId in project ambry by linkedin.

the class ServerTestUtil method endToEndReplicationWithMultiNodeMultiPartitionTest.

static void endToEndReplicationWithMultiNodeMultiPartitionTest(int interestedDataNodePortNumber, Port dataNode1Port, Port dataNode2Port, Port dataNode3Port, MockCluster cluster, SSLConfig clientSSLConfig1, SSLConfig clientSSLConfig2, SSLConfig clientSSLConfig3, SSLSocketFactory clientSSLSocketFactory1, SSLSocketFactory clientSSLSocketFactory2, SSLSocketFactory clientSSLSocketFactory3, MockNotificationSystem notificationSystem, boolean testEncryption) throws Exception {
    // interestedDataNodePortNumber is used to locate the datanode and hence has to be PlainTextPort
    MockClusterMap clusterMap = cluster.getClusterMap();
    BlobIdFactory blobIdFactory = new BlobIdFactory(clusterMap);
    List<AmbryServer> serverList = cluster.getServers();
    byte[] usermetadata = new byte[100];
    byte[] data = new byte[100];
    byte[] encryptionKey = null;
    short accountId = Utils.getRandomShort(TestUtils.RANDOM);
    short containerId = Utils.getRandomShort(TestUtils.RANDOM);
    BlobProperties properties = new BlobProperties(100, "serviceid1", null, null, false, TestUtils.TTL_SECS, cluster.time.milliseconds(), accountId, containerId, false, null, null, null);
    long expectedExpiryTimeMs = getExpiryTimeMs(properties);
    TestUtils.RANDOM.nextBytes(usermetadata);
    TestUtils.RANDOM.nextBytes(data);
    if (testEncryption) {
        encryptionKey = new byte[100];
        TestUtils.RANDOM.nextBytes(encryptionKey);
    }
    // connect to all the servers
    ConnectedChannel channel1 = getBlockingChannelBasedOnPortType(dataNode1Port, "localhost", clientSSLSocketFactory1, clientSSLConfig1);
    ConnectedChannel channel2 = getBlockingChannelBasedOnPortType(dataNode2Port, "localhost", clientSSLSocketFactory2, clientSSLConfig2);
    ConnectedChannel channel3 = getBlockingChannelBasedOnPortType(dataNode3Port, "localhost", clientSSLSocketFactory3, clientSSLConfig3);
    // put all the blobs to random servers
    channel1.connect();
    channel2.connect();
    channel3.connect();
    int noOfParallelThreads = 3;
    int totalBlobsToPut = 50;
    CountDownLatch latch = new CountDownLatch(noOfParallelThreads);
    List<DirectSender> runnables = new ArrayList<DirectSender>(noOfParallelThreads);
    ConnectedChannel channel = null;
    for (int i = 0; i < noOfParallelThreads; i++) {
        if (i % noOfParallelThreads == 0) {
            channel = channel1;
        } else if (i % noOfParallelThreads == 1) {
            channel = channel2;
        } else if (i % noOfParallelThreads == 2) {
            channel = channel3;
        }
        DirectSender runnable = new DirectSender(cluster, channel, totalBlobsToPut, data, usermetadata, properties, encryptionKey, latch);
        runnables.add(runnable);
        Thread threadToRun = new Thread(runnable);
        threadToRun.start();
    }
    assertTrue("Did not put all blobs in 2 minutes", latch.await(2, TimeUnit.MINUTES));
    // wait till replication can complete
    List<BlobId> blobIds = new ArrayList<BlobId>();
    for (int i = 0; i < runnables.size(); i++) {
        blobIds.addAll(runnables.get(i).getBlobIds());
    }
    for (BlobId blobId : blobIds) {
        notificationSystem.awaitBlobCreations(blobId.getID());
    }
    // Now that the blob is created and replicated, test the cases where a put request arrives for the same blob id
    // later than replication.
    testLatePutRequest(blobIds.get(0), properties, usermetadata, data, encryptionKey, channel1, channel2, channel3, ServerErrorCode.No_Error);
    // Test the case where a put arrives with the same id as one in the server, but the blob is not identical.
    BlobProperties differentProperties = new BlobProperties(properties.getBlobSize(), properties.getServiceId(), accountId, containerId, testEncryption, cluster.time.milliseconds());
    testLatePutRequest(blobIds.get(0), differentProperties, usermetadata, data, encryptionKey, channel1, channel2, channel3, ServerErrorCode.Blob_Already_Exists);
    byte[] differentUserMetadata = Arrays.copyOf(usermetadata, usermetadata.length);
    differentUserMetadata[0] = (byte) ~differentUserMetadata[0];
    testLatePutRequest(blobIds.get(0), properties, differentUserMetadata, data, encryptionKey, channel1, channel2, channel3, ServerErrorCode.Blob_Already_Exists);
    byte[] differentData = Arrays.copyOf(data, data.length);
    differentData[0] = (byte) ~differentData[0];
    testLatePutRequest(blobIds.get(0), properties, usermetadata, differentData, encryptionKey, channel1, channel2, channel3, ServerErrorCode.Blob_Already_Exists);
    // verify blob properties, metadata and blob across all nodes
    for (int i = 0; i < 3; i++) {
        channel = null;
        if (i == 0) {
            channel = channel1;
        } else if (i == 1) {
            channel = channel2;
        } else if (i == 2) {
            channel = channel3;
        }
        ArrayList<PartitionRequestInfo> partitionRequestInfoList = new ArrayList<PartitionRequestInfo>();
        for (int j = 0; j < blobIds.size(); j++) {
            ArrayList<BlobId> ids = new ArrayList<BlobId>();
            ids.add(blobIds.get(j));
            partitionRequestInfoList.clear();
            PartitionRequestInfo partitionRequestInfo = new PartitionRequestInfo(blobIds.get(j).getPartition(), ids);
            partitionRequestInfoList.add(partitionRequestInfo);
            GetRequest getRequest = new GetRequest(1, "clientid2", MessageFormatFlags.BlobProperties, partitionRequestInfoList, GetOption.None);
            DataInputStream stream = channel.sendAndReceive(getRequest).getInputStream();
            GetResponse resp = GetResponse.readFrom(stream, clusterMap);
            try {
                BlobProperties propertyOutput = MessageFormatRecord.deserializeBlobProperties(resp.getInputStream());
                assertEquals(100, propertyOutput.getBlobSize());
                assertEquals("serviceid1", propertyOutput.getServiceId());
                assertEquals("AccountId mismatch", accountId, propertyOutput.getAccountId());
                assertEquals("ContainerId mismatch", containerId, propertyOutput.getContainerId());
                assertEquals("Expiration time mismatch (props)", expectedExpiryTimeMs, getExpiryTimeMs(propertyOutput));
                assertEquals("Expiration time mismatch (MessageInfo)", expectedExpiryTimeMs, resp.getPartitionResponseInfoList().get(0).getMessageInfoList().get(0).getExpirationTimeInMs());
                releaseNettyBufUnderneathStream(stream);
            } catch (MessageFormatException e) {
                fail();
            }
            // get user metadata
            getRequest = new GetRequest(1, "clientid2", MessageFormatFlags.BlobUserMetadata, partitionRequestInfoList, GetOption.None);
            stream = channel.sendAndReceive(getRequest).getInputStream();
            resp = GetResponse.readFrom(stream, clusterMap);
            try {
                ByteBuffer userMetadataOutput = MessageFormatRecord.deserializeUserMetadata(resp.getInputStream());
                assertArrayEquals(usermetadata, userMetadataOutput.array());
                if (testEncryption) {
                    assertNotNull("MessageMetadata should not have been null", resp.getPartitionResponseInfoList().get(0).getMessageMetadataList().get(0));
                    assertArrayEquals("EncryptionKey mismatch", encryptionKey, resp.getPartitionResponseInfoList().get(0).getMessageMetadataList().get(0).getEncryptionKey().array());
                } else {
                    assertNull("MessageMetadata should have been null", resp.getPartitionResponseInfoList().get(0).getMessageMetadataList().get(0));
                }
                assertEquals("Expiration time mismatch (MessageInfo)", expectedExpiryTimeMs, resp.getPartitionResponseInfoList().get(0).getMessageInfoList().get(0).getExpirationTimeInMs());
            } catch (MessageFormatException e) {
                e.printStackTrace();
                fail();
            }
            releaseNettyBufUnderneathStream(stream);
            // get blob
            getRequest = new GetRequest(1, "clientid2", MessageFormatFlags.Blob, partitionRequestInfoList, GetOption.None);
            stream = channel.sendAndReceive(getRequest).getInputStream();
            resp = GetResponse.readFrom(stream, clusterMap);
            try {
                BlobData blobData = MessageFormatRecord.deserializeBlob(resp.getInputStream());
                byte[] blobout = getBlobDataAndRelease(blobData);
                assertArrayEquals(data, blobout);
                if (testEncryption) {
                    assertNotNull("MessageMetadata should not have been null", resp.getPartitionResponseInfoList().get(0).getMessageMetadataList().get(0));
                    assertArrayEquals("EncryptionKey mismatch", encryptionKey, resp.getPartitionResponseInfoList().get(0).getMessageMetadataList().get(0).getEncryptionKey().array());
                } else {
                    assertNull("MessageMetadata should have been null", resp.getPartitionResponseInfoList().get(0).getMessageMetadataList().get(0));
                }
                assertEquals("Expiration time mismatch (MessageInfo)", expectedExpiryTimeMs, resp.getPartitionResponseInfoList().get(0).getMessageInfoList().get(0).getExpirationTimeInMs());
            } catch (MessageFormatException e) {
                e.printStackTrace();
                fail();
            }
            releaseNettyBufUnderneathStream(stream);
            // get blob all
            getRequest = new GetRequest(1, "clientid2", MessageFormatFlags.All, partitionRequestInfoList, GetOption.None);
            stream = channel.sendAndReceive(getRequest).getInputStream();
            resp = GetResponse.readFrom(stream, clusterMap);
            try {
                BlobAll blobAll = MessageFormatRecord.deserializeBlobAll(resp.getInputStream(), blobIdFactory);
                assertEquals("Expiration time mismatch (props)", expectedExpiryTimeMs, getExpiryTimeMs(blobAll.getBlobInfo().getBlobProperties()));
                assertEquals("Expiration time mismatch (MessageInfo)", expectedExpiryTimeMs, resp.getPartitionResponseInfoList().get(0).getMessageInfoList().get(0).getExpirationTimeInMs());
                byte[] blobout = getBlobDataAndRelease(blobAll.getBlobData());
                assertArrayEquals(data, blobout);
                if (testEncryption) {
                    assertNotNull("EncryptionKey should not ne null", blobAll.getBlobEncryptionKey());
                    assertArrayEquals("EncryptionKey mismatch", encryptionKey, blobAll.getBlobEncryptionKey().array());
                } else {
                    assertNull("EncryptionKey should have been null", blobAll.getBlobEncryptionKey());
                }
                releaseNettyBufUnderneathStream(stream);
            } catch (MessageFormatException e) {
                e.printStackTrace();
                fail();
            }
        }
    }
    // ttl update all blobs and wait for replication
    Map<ConnectedChannel, List<BlobId>> channelToBlobIds = new HashMap<>();
    for (int i = 0; i < blobIds.size(); i++) {
        final BlobId blobId = blobIds.get(i);
        if (i % 3 == 0) {
            channelToBlobIds.computeIfAbsent(channel1, updateChannel -> new ArrayList<>()).add(blobId);
        } else if (i % 3 == 1) {
            channelToBlobIds.computeIfAbsent(channel2, updateChannel -> new ArrayList<>()).add(blobId);
        } else {
            channelToBlobIds.computeIfAbsent(channel3, updateChannel -> new ArrayList<>()).add(blobId);
        }
    }
    channelToBlobIds.entrySet().stream().map(entry -> CompletableFuture.supplyAsync(() -> {
        try {
            for (BlobId blobId : entry.getValue()) {
                updateBlobTtl(entry.getKey(), blobId, cluster.time.milliseconds());
            }
            return null;
        } catch (Throwable e) {
            throw new RuntimeException("Exception updating ttl for: " + entry, e);
        }
    })).forEach(CompletableFuture::join);
    // check that the TTL update has propagated
    blobIds.forEach(blobId -> notificationSystem.awaitBlobUpdates(blobId.getID(), UpdateType.TTL_UPDATE));
    // check all servers
    for (ConnectedChannel channelToUse : new ConnectedChannel[] { channel1, channel2, channel3 }) {
        for (BlobId blobId : blobIds) {
            checkTtlUpdateStatus(channelToUse, clusterMap, blobIdFactory, blobId, data, true, Utils.Infinite_Time);
        }
    }
    // delete random blobs, wait for replication and ensure it is deleted in all nodes
    Set<BlobId> blobsDeleted = new HashSet<BlobId>();
    Set<BlobId> blobsChecked = new HashSet<BlobId>();
    for (int i = 0; i < blobIds.size(); i++) {
        int j = new Random().nextInt(3);
        if (j == 0) {
            j = new Random().nextInt(3);
            if (j == 0) {
                channel = channel1;
            } else if (j == 1) {
                channel = channel2;
            } else if (j == 2) {
                channel = channel3;
            }
            DeleteRequest deleteRequest = new DeleteRequest(1, "reptest", blobIds.get(i), System.currentTimeMillis());
            DataInputStream deleteResponseStream = channel.sendAndReceive(deleteRequest).getInputStream();
            DeleteResponse deleteResponse = DeleteResponse.readFrom(deleteResponseStream);
            releaseNettyBufUnderneathStream(deleteResponseStream);
            assertEquals(ServerErrorCode.No_Error, deleteResponse.getError());
            blobsDeleted.add(blobIds.get(i));
        }
    }
    Iterator<BlobId> iterator = blobsDeleted.iterator();
    ArrayList<PartitionRequestInfo> partitionRequestInfoList = new ArrayList<PartitionRequestInfo>();
    while (iterator.hasNext()) {
        BlobId deletedId = iterator.next();
        notificationSystem.awaitBlobDeletions(deletedId.getID());
        for (int j = 0; j < 3; j++) {
            if (j == 0) {
                channel = channel1;
            } else if (j == 1) {
                channel = channel2;
            } else if (j == 2) {
                channel = channel3;
            }
            ArrayList<BlobId> ids = new ArrayList<BlobId>();
            ids.add(deletedId);
            partitionRequestInfoList.clear();
            PartitionRequestInfo partitionRequestInfo = new PartitionRequestInfo(deletedId.getPartition(), ids);
            partitionRequestInfoList.add(partitionRequestInfo);
            GetRequest getRequest = new GetRequest(1, "clientid2", MessageFormatFlags.Blob, partitionRequestInfoList, GetOption.None);
            DataInputStream stream = channel.sendAndReceive(getRequest).getInputStream();
            GetResponse resp = GetResponse.readFrom(stream, clusterMap);
            assertEquals(ServerErrorCode.Blob_Deleted, resp.getPartitionResponseInfoList().get(0).getErrorCode());
            releaseNettyBufUnderneathStream(stream);
        }
    }
    // take a server down, clean up a mount path, start and ensure replication fixes it
    serverList.get(0).shutdown();
    serverList.get(0).awaitShutdown();
    MockDataNodeId dataNode = (MockDataNodeId) clusterMap.getDataNodeId("localhost", interestedDataNodePortNumber);
    System.out.println("Cleaning mount path " + dataNode.getMountPaths().get(0));
    for (ReplicaId replicaId : clusterMap.getReplicaIds(dataNode)) {
        if (replicaId.getMountPath().compareToIgnoreCase(dataNode.getMountPaths().get(0)) == 0) {
            System.out.println("Cleaning partition " + replicaId.getPartitionId());
        }
    }
    deleteFolderContent(new File(dataNode.getMountPaths().get(0)), false);
    for (int i = 0; i < blobIds.size(); i++) {
        for (ReplicaId replicaId : blobIds.get(i).getPartition().getReplicaIds()) {
            if (replicaId.getMountPath().compareToIgnoreCase(dataNode.getMountPaths().get(0)) == 0) {
                if (blobsDeleted.contains(blobIds.get(i))) {
                    notificationSystem.decrementDeletedReplica(blobIds.get(i).getID(), dataNode.getHostname(), dataNode.getPort());
                } else {
                    notificationSystem.decrementCreatedReplica(blobIds.get(i).getID(), dataNode.getHostname(), dataNode.getPort());
                    notificationSystem.decrementUpdatedReplica(blobIds.get(i).getID(), dataNode.getHostname(), dataNode.getPort(), UpdateType.TTL_UPDATE);
                }
            }
        }
    }
    cluster.reinitServer(0);
    channel1.disconnect();
    channel1.connect();
    for (int j = 0; j < blobIds.size(); j++) {
        if (blobsDeleted.contains(blobIds.get(j))) {
            notificationSystem.awaitBlobDeletions(blobIds.get(j).getID());
        } else {
            notificationSystem.awaitBlobCreations(blobIds.get(j).getID());
            notificationSystem.awaitBlobUpdates(blobIds.get(j).getID(), UpdateType.TTL_UPDATE);
        }
        ArrayList<BlobId> ids = new ArrayList<BlobId>();
        ids.add(blobIds.get(j));
        partitionRequestInfoList.clear();
        PartitionRequestInfo partitionRequestInfo = new PartitionRequestInfo(blobIds.get(j).getPartition(), ids);
        partitionRequestInfoList.add(partitionRequestInfo);
        GetRequest getRequest = new GetRequest(1, "clientid2", MessageFormatFlags.BlobProperties, partitionRequestInfoList, GetOption.None);
        DataInputStream stream = channel1.sendAndReceive(getRequest).getInputStream();
        GetResponse resp = GetResponse.readFrom(stream, clusterMap);
        if (resp.getPartitionResponseInfoList().get(0).getErrorCode() == ServerErrorCode.Blob_Deleted || resp.getPartitionResponseInfoList().get(0).getErrorCode() == ServerErrorCode.Blob_Not_Found) {
            assertTrue(blobsDeleted.contains(blobIds.get(j)));
        } else {
            try {
                BlobProperties propertyOutput = MessageFormatRecord.deserializeBlobProperties(resp.getInputStream());
                assertEquals(100, propertyOutput.getBlobSize());
                assertEquals("serviceid1", propertyOutput.getServiceId());
                assertEquals("AccountId mismatch", accountId, propertyOutput.getAccountId());
                assertEquals("ContainerId mismatch", containerId, propertyOutput.getContainerId());
                assertEquals("Expiration time mismatch in MessageInfo", Utils.Infinite_Time, resp.getPartitionResponseInfoList().get(0).getMessageInfoList().get(0).getExpirationTimeInMs());
            } catch (MessageFormatException e) {
                fail();
            }
        }
        releaseNettyBufUnderneathStream(stream);
        // get user metadata
        getRequest = new GetRequest(1, "clientid2", MessageFormatFlags.BlobUserMetadata, partitionRequestInfoList, GetOption.None);
        stream = channel1.sendAndReceive(getRequest).getInputStream();
        resp = GetResponse.readFrom(stream, clusterMap);
        if (resp.getPartitionResponseInfoList().get(0).getErrorCode() == ServerErrorCode.Blob_Deleted || resp.getPartitionResponseInfoList().get(0).getErrorCode() == ServerErrorCode.Blob_Not_Found) {
            assertTrue(blobsDeleted.contains(blobIds.get(j)));
        } else {
            try {
                ByteBuffer userMetadataOutput = MessageFormatRecord.deserializeUserMetadata(resp.getInputStream());
                assertArrayEquals(usermetadata, userMetadataOutput.array());
                if (testEncryption) {
                    assertNotNull("MessageMetadata should not have been null", resp.getPartitionResponseInfoList().get(0).getMessageMetadataList().get(0));
                    assertArrayEquals("EncryptionKey mismatch", encryptionKey, resp.getPartitionResponseInfoList().get(0).getMessageMetadataList().get(0).getEncryptionKey().array());
                } else {
                    assertNull("MessageMetadata should have been null", resp.getPartitionResponseInfoList().get(0).getMessageMetadataList().get(0));
                }
                assertEquals("Expiration time mismatch in MessageInfo", Utils.Infinite_Time, resp.getPartitionResponseInfoList().get(0).getMessageInfoList().get(0).getExpirationTimeInMs());
            } catch (MessageFormatException e) {
                fail();
            }
        }
        releaseNettyBufUnderneathStream(stream);
        // get blob
        getRequest = new GetRequest(1, "clientid2", MessageFormatFlags.Blob, partitionRequestInfoList, GetOption.None);
        stream = channel1.sendAndReceive(getRequest).getInputStream();
        resp = GetResponse.readFrom(stream, clusterMap);
        if (resp.getPartitionResponseInfoList().get(0).getErrorCode() == ServerErrorCode.Blob_Deleted || resp.getPartitionResponseInfoList().get(0).getErrorCode() == ServerErrorCode.Blob_Not_Found) {
            assertTrue(blobsDeleted.contains(blobIds.get(j)));
        } else {
            try {
                BlobData blobData = MessageFormatRecord.deserializeBlob(resp.getInputStream());
                byte[] blobout = getBlobDataAndRelease(blobData);
                assertArrayEquals(data, blobout);
                if (testEncryption) {
                    assertNotNull("MessageMetadata should not have been null", resp.getPartitionResponseInfoList().get(0).getMessageMetadataList().get(0));
                    assertArrayEquals("EncryptionKey mismatch", encryptionKey, resp.getPartitionResponseInfoList().get(0).getMessageMetadataList().get(0).getEncryptionKey().array());
                } else {
                    assertNull("MessageMetadata should have been null", resp.getPartitionResponseInfoList().get(0).getMessageMetadataList().get(0));
                }
                assertEquals("Expiration time mismatch in MessageInfo", Utils.Infinite_Time, resp.getPartitionResponseInfoList().get(0).getMessageInfoList().get(0).getExpirationTimeInMs());
            } catch (MessageFormatException e) {
                fail();
            }
        }
        releaseNettyBufUnderneathStream(stream);
        // get blob all
        getRequest = new GetRequest(1, "clientid2", MessageFormatFlags.All, partitionRequestInfoList, GetOption.None);
        stream = channel1.sendAndReceive(getRequest).getInputStream();
        resp = GetResponse.readFrom(stream, clusterMap);
        if (resp.getPartitionResponseInfoList().get(0).getErrorCode() == ServerErrorCode.Blob_Deleted || resp.getPartitionResponseInfoList().get(0).getErrorCode() == ServerErrorCode.Blob_Not_Found) {
            assertTrue(blobsDeleted.contains(blobIds.get(j)));
            blobsDeleted.remove(blobIds.get(j));
            blobsChecked.add(blobIds.get(j));
        } else {
            try {
                BlobAll blobAll = MessageFormatRecord.deserializeBlobAll(resp.getInputStream(), blobIdFactory);
                byte[] blobout = getBlobDataAndRelease(blobAll.getBlobData());
                assertArrayEquals(data, blobout);
                if (testEncryption) {
                    assertNotNull("EncryptionKey should not ne null", blobAll.getBlobEncryptionKey());
                    assertArrayEquals("EncryptionKey mismatch", encryptionKey, blobAll.getBlobEncryptionKey().array());
                } else {
                    assertNull("EncryptionKey should have been null", blobAll.getBlobEncryptionKey());
                }
                assertEquals("Expiration time mismatch in MessageInfo", Utils.Infinite_Time, resp.getPartitionResponseInfoList().get(0).getMessageInfoList().get(0).getExpirationTimeInMs());
            } catch (MessageFormatException e) {
                fail();
            }
        }
        releaseNettyBufUnderneathStream(stream);
    }
    assertEquals(0, blobsDeleted.size());
    // take a server down, clean all contents, start and ensure replication fixes it
    serverList.get(0).shutdown();
    serverList.get(0).awaitShutdown();
    dataNode = (MockDataNodeId) clusterMap.getDataNodeId("localhost", interestedDataNodePortNumber);
    for (int i = 0; i < dataNode.getMountPaths().size(); i++) {
        System.out.println("Cleaning mount path " + dataNode.getMountPaths().get(i));
        for (ReplicaId replicaId : clusterMap.getReplicaIds(dataNode)) {
            if (replicaId.getMountPath().compareToIgnoreCase(dataNode.getMountPaths().get(i)) == 0) {
                System.out.println("Cleaning partition " + replicaId.getPartitionId());
            }
        }
        deleteFolderContent(new File(dataNode.getMountPaths().get(i)), false);
    }
    for (int i = 0; i < blobIds.size(); i++) {
        if (blobsChecked.contains(blobIds.get(i))) {
            notificationSystem.decrementDeletedReplica(blobIds.get(i).getID(), dataNode.getHostname(), dataNode.getPort());
        } else {
            notificationSystem.decrementCreatedReplica(blobIds.get(i).getID(), dataNode.getHostname(), dataNode.getPort());
        }
    }
    cluster.reinitServer(0);
    channel1.disconnect();
    channel1.connect();
    for (int j = 0; j < blobIds.size(); j++) {
        if (blobsChecked.contains(blobIds.get(j))) {
            notificationSystem.awaitBlobDeletions(blobIds.get(j).getID());
        } else {
            notificationSystem.awaitBlobCreations(blobIds.get(j).getID());
        }
        ArrayList<BlobId> ids = new ArrayList<BlobId>();
        ids.add(blobIds.get(j));
        partitionRequestInfoList.clear();
        PartitionRequestInfo partitionRequestInfo = new PartitionRequestInfo(blobIds.get(j).getPartition(), ids);
        partitionRequestInfoList.add(partitionRequestInfo);
        GetRequest getRequest = new GetRequest(1, "clientid2", MessageFormatFlags.BlobProperties, partitionRequestInfoList, GetOption.None);
        DataInputStream stream = channel1.sendAndReceive(getRequest).getInputStream();
        GetResponse resp = GetResponse.readFrom(stream, clusterMap);
        if (resp.getPartitionResponseInfoList().get(0).getErrorCode() == ServerErrorCode.Blob_Deleted || resp.getPartitionResponseInfoList().get(0).getErrorCode() == ServerErrorCode.Blob_Not_Found) {
            assertTrue(blobsChecked.contains(blobIds.get(j)));
        } else {
            try {
                BlobProperties propertyOutput = MessageFormatRecord.deserializeBlobProperties(resp.getInputStream());
                assertEquals(100, propertyOutput.getBlobSize());
                assertEquals("serviceid1", propertyOutput.getServiceId());
                assertEquals("AccountId mismatch", accountId, propertyOutput.getAccountId());
                assertEquals("ContainerId mismatch", containerId, propertyOutput.getContainerId());
            } catch (MessageFormatException e) {
                fail();
            }
        }
        releaseNettyBufUnderneathStream(stream);
        // get user metadata
        getRequest = new GetRequest(1, "clientid2", MessageFormatFlags.BlobUserMetadata, partitionRequestInfoList, GetOption.None);
        stream = channel1.sendAndReceive(getRequest).getInputStream();
        resp = GetResponse.readFrom(stream, clusterMap);
        if (resp.getPartitionResponseInfoList().get(0).getErrorCode() == ServerErrorCode.Blob_Deleted || resp.getPartitionResponseInfoList().get(0).getErrorCode() == ServerErrorCode.Blob_Not_Found) {
            assertTrue(blobsChecked.contains(blobIds.get(j)));
        } else {
            try {
                ByteBuffer userMetadataOutput = MessageFormatRecord.deserializeUserMetadata(resp.getInputStream());
                assertArrayEquals(usermetadata, userMetadataOutput.array());
                if (testEncryption) {
                    assertNotNull("MessageMetadata should not have been null", resp.getPartitionResponseInfoList().get(0).getMessageMetadataList().get(0));
                    assertArrayEquals("EncryptionKey mismatch", encryptionKey, resp.getPartitionResponseInfoList().get(0).getMessageMetadataList().get(0).getEncryptionKey().array());
                } else {
                    assertNull("MessageMetadata should have been null", resp.getPartitionResponseInfoList().get(0).getMessageMetadataList().get(0));
                }
            } catch (MessageFormatException e) {
                fail();
            }
        }
        releaseNettyBufUnderneathStream(stream);
        // get blob
        getRequest = new GetRequest(1, "clientid2", MessageFormatFlags.Blob, partitionRequestInfoList, GetOption.None);
        stream = channel1.sendAndReceive(getRequest).getInputStream();
        resp = GetResponse.readFrom(stream, clusterMap);
        if (resp.getPartitionResponseInfoList().get(0).getErrorCode() == ServerErrorCode.Blob_Deleted || resp.getPartitionResponseInfoList().get(0).getErrorCode() == ServerErrorCode.Blob_Not_Found) {
            assertTrue(blobsChecked.contains(blobIds.get(j)));
        } else {
            try {
                BlobData blobData = MessageFormatRecord.deserializeBlob(resp.getInputStream());
                byte[] blobout = getBlobDataAndRelease(blobData);
                assertArrayEquals(data, blobout);
                if (testEncryption) {
                    assertNotNull("MessageMetadata should not have been null", resp.getPartitionResponseInfoList().get(0).getMessageMetadataList().get(0));
                    assertArrayEquals("EncryptionKey mismatch", encryptionKey, resp.getPartitionResponseInfoList().get(0).getMessageMetadataList().get(0).getEncryptionKey().array());
                } else {
                    assertNull("MessageMetadata should have been null", resp.getPartitionResponseInfoList().get(0).getMessageMetadataList().get(0));
                }
            } catch (MessageFormatException e) {
                fail();
            }
        }
        releaseNettyBufUnderneathStream(stream);
        // get blob all
        getRequest = new GetRequest(1, "clientid2", MessageFormatFlags.All, partitionRequestInfoList, GetOption.None);
        stream = channel1.sendAndReceive(getRequest).getInputStream();
        resp = GetResponse.readFrom(stream, clusterMap);
        if (resp.getPartitionResponseInfoList().get(0).getErrorCode() == ServerErrorCode.Blob_Deleted || resp.getPartitionResponseInfoList().get(0).getErrorCode() == ServerErrorCode.Blob_Not_Found) {
            assertTrue(blobsChecked.contains(blobIds.get(j)));
            blobsChecked.remove(blobIds.get(j));
            blobsDeleted.add(blobIds.get(j));
        } else {
            try {
                BlobAll blobAll = MessageFormatRecord.deserializeBlobAll(resp.getInputStream(), blobIdFactory);
                byte[] blobout = getBlobDataAndRelease(blobAll.getBlobData());
                assertArrayEquals(data, blobout);
                if (testEncryption) {
                    assertNotNull("EncryptionKey should not ne null", blobAll.getBlobEncryptionKey());
                    assertArrayEquals("EncryptionKey mismatch", encryptionKey, blobAll.getBlobEncryptionKey().array());
                } else {
                    assertNull("EncryptionKey should have been null", blobAll.getBlobEncryptionKey());
                }
            } catch (MessageFormatException e) {
                fail();
            }
        }
        releaseNettyBufUnderneathStream(stream);
    }
    assertEquals(0, blobsChecked.size());
    short expectedLifeVersion = 1;
    for (int i = 0; i < 2; i++) {
        expectedLifeVersion += i;
        // First undelete all deleted blobs
        for (BlobId deletedId : blobsDeleted) {
            UndeleteRequest undeleteRequest = new UndeleteRequest(2, "reptest", deletedId, System.currentTimeMillis());
            DataInputStream undeleteResponseStream = channel3.sendAndReceive(undeleteRequest).getInputStream();
            UndeleteResponse undeleteResponse = UndeleteResponse.readFrom(undeleteResponseStream);
            releaseNettyBufUnderneathStream(undeleteResponseStream);
            assertEquals(ServerErrorCode.No_Error, undeleteResponse.getError());
            assertEquals(expectedLifeVersion, undeleteResponse.getLifeVersion());
        }
        Thread.sleep(5000);
        // Then use get request to get all the data back and make sure the lifeVersion is correct
        for (BlobId id : blobsDeleted) {
            // We don't need to wait for blob undeletes, since one of the hosts has Put Record deleted
            // from disk, so undelete this blob would end up replicating Put Record instead of undelete.
            // notificationSystem.awaitBlobUndeletes(id.toString());
            ArrayList<BlobId> ids = new ArrayList<>();
            ids.add(id);
            partitionRequestInfoList.clear();
            PartitionRequestInfo partitionRequestInfo = new PartitionRequestInfo(id.getPartition(), ids);
            partitionRequestInfoList.add(partitionRequestInfo);
            // get blob all
            GetRequest getRequest = new GetRequest(1, "clientid20", MessageFormatFlags.All, partitionRequestInfoList, GetOption.None);
            DataInputStream stream = channel1.sendAndReceive(getRequest).getInputStream();
            GetResponse resp = GetResponse.readFrom(stream, clusterMap);
            assertEquals(ServerErrorCode.No_Error, resp.getError());
            assertEquals(1, resp.getPartitionResponseInfoList().size());
            assertEquals(ServerErrorCode.No_Error, resp.getPartitionResponseInfoList().get(0).getErrorCode());
            assertEquals(1, resp.getPartitionResponseInfoList().get(0).getMessageInfoList().size());
            MessageInfo info = resp.getPartitionResponseInfoList().get(0).getMessageInfoList().get(0);
            assertEquals(expectedLifeVersion, info.getLifeVersion());
            assertFalse(info.isDeleted());
            try {
                BlobAll blobAll = MessageFormatRecord.deserializeBlobAll(resp.getInputStream(), blobIdFactory);
                byte[] blobout = getBlobDataAndRelease(blobAll.getBlobData());
                assertArrayEquals(data, blobout);
                if (testEncryption) {
                    assertNotNull("EncryptionKey should not ne null", blobAll.getBlobEncryptionKey());
                    assertArrayEquals("EncryptionKey mismatch", encryptionKey, blobAll.getBlobEncryptionKey().array());
                } else {
                    assertNull("EncryptionKey should have been null", blobAll.getBlobEncryptionKey());
                }
                assertEquals("Expiration time mismatch in MessageInfo", Utils.Infinite_Time, resp.getPartitionResponseInfoList().get(0).getMessageInfoList().get(0).getExpirationTimeInMs());
                releaseNettyBufUnderneathStream(stream);
            } catch (MessageFormatException e) {
                fail();
            }
        }
        for (BlobId id : blobsDeleted) {
            DeleteRequest deleteRequest = new DeleteRequest(1, "reptest", id, System.currentTimeMillis());
            DataInputStream deleteResponseStream = channel.sendAndReceive(deleteRequest).getInputStream();
            DeleteResponse deleteResponse = DeleteResponse.readFrom(deleteResponseStream);
            releaseNettyBufUnderneathStream(deleteResponseStream);
            assertEquals(ServerErrorCode.No_Error, deleteResponse.getError());
        }
        Thread.sleep(1000);
        for (BlobId id : blobsDeleted) {
            ArrayList<BlobId> ids = new ArrayList<>();
            ids.add(id);
            partitionRequestInfoList.clear();
            PartitionRequestInfo partitionRequestInfo = new PartitionRequestInfo(id.getPartition(), ids);
            partitionRequestInfoList.add(partitionRequestInfo);
            // get blob all
            GetRequest getRequest = new GetRequest(1, "clientid200", MessageFormatFlags.All, partitionRequestInfoList, GetOption.Include_All);
            DataInputStream stream = channel1.sendAndReceive(getRequest).getInputStream();
            GetResponse resp = GetResponse.readFrom(stream, clusterMap);
            assertEquals(ServerErrorCode.No_Error, resp.getError());
            assertEquals(1, resp.getPartitionResponseInfoList().size());
            assertEquals(ServerErrorCode.No_Error, resp.getPartitionResponseInfoList().get(0).getErrorCode());
            assertEquals(1, resp.getPartitionResponseInfoList().get(0).getMessageInfoList().size());
            MessageInfo info = resp.getPartitionResponseInfoList().get(0).getMessageInfoList().get(0);
            assertEquals(expectedLifeVersion, info.getLifeVersion());
            assertTrue(info.isDeleted());
            try {
                BlobAll blobAll = MessageFormatRecord.deserializeBlobAll(resp.getInputStream(), blobIdFactory);
                byte[] blobout = getBlobDataAndRelease(blobAll.getBlobData());
                assertArrayEquals(data, blobout);
                if (testEncryption) {
                    assertNotNull("EncryptionKey should not ne null", blobAll.getBlobEncryptionKey());
                    assertArrayEquals("EncryptionKey mismatch", encryptionKey, blobAll.getBlobEncryptionKey().array());
                } else {
                    assertNull("EncryptionKey should have been null", blobAll.getBlobEncryptionKey());
                }
                assertEquals("Expiration time mismatch in MessageInfo", Utils.Infinite_Time, resp.getPartitionResponseInfoList().get(0).getMessageInfoList().get(0).getExpirationTimeInMs());
                releaseNettyBufUnderneathStream(stream);
            } catch (MessageFormatException e) {
                fail();
            }
        }
    }
    channel1.disconnect();
    channel2.disconnect();
    channel3.disconnect();
}
Also used : AdminRequestOrResponseType(com.github.ambry.protocol.AdminRequestOrResponseType) GetOption(com.github.ambry.protocol.GetOption) Arrays(java.util.Arrays) Http2ClientConfig(com.github.ambry.config.Http2ClientConfig) BlobProperties(com.github.ambry.messageformat.BlobProperties) BlobAll(com.github.ambry.messageformat.BlobAll) SubRecord(com.github.ambry.messageformat.SubRecord) Future(java.util.concurrent.Future) TestUtils(com.github.ambry.utils.TestUtils) Map(java.util.Map) UndeleteRequest(com.github.ambry.protocol.UndeleteRequest) TtlUpdateResponse(com.github.ambry.protocol.TtlUpdateResponse) RetainingAsyncWritableChannel(com.github.ambry.commons.RetainingAsyncWritableChannel) RouterErrorCode(com.github.ambry.router.RouterErrorCode) ReadableStreamChannel(com.github.ambry.router.ReadableStreamChannel) SSLFactory(com.github.ambry.commons.SSLFactory) BlobData(com.github.ambry.messageformat.BlobData) Set(java.util.Set) MockPartitionId(com.github.ambry.clustermap.MockPartitionId) SSLSocketFactory(javax.net.ssl.SSLSocketFactory) CountDownLatch(java.util.concurrent.CountDownLatch) MockDiskId(com.github.ambry.clustermap.MockDiskId) UpdateType(com.github.ambry.notification.UpdateType) PartitionRequestInfo(com.github.ambry.protocol.PartitionRequestInfo) ArrayList(java.util.ArrayList) NettyByteBufDataInputStream(com.github.ambry.utils.NettyByteBufDataInputStream) ReplicationControlAdminRequest(com.github.ambry.protocol.ReplicationControlAdminRequest) BlockingChannel(com.github.ambry.network.BlockingChannel) BlockingChannelConnectionPool(com.github.ambry.network.BlockingChannelConnectionPool) MetricRegistry(com.codahale.metrics.MetricRegistry) Properties(java.util.Properties) PutMessageFormatInputStream(com.github.ambry.messageformat.PutMessageFormatInputStream) Offset(com.github.ambry.store.Offset) VerifiableProperties(com.github.ambry.config.VerifiableProperties) IOException(java.io.IOException) BlobIdFactory(com.github.ambry.commons.BlobIdFactory) MessageFormatException(com.github.ambry.messageformat.MessageFormatException) PutResponse(com.github.ambry.protocol.PutResponse) RouterException(com.github.ambry.router.RouterException) LatchBasedInMemoryCloudDestinationFactory(com.github.ambry.cloud.LatchBasedInMemoryCloudDestinationFactory) File(java.io.File) ExecutionException(java.util.concurrent.ExecutionException) GetBlobResult(com.github.ambry.router.GetBlobResult) ReplicaId(com.github.ambry.clustermap.ReplicaId) PutBlobOptionsBuilder(com.github.ambry.router.PutBlobOptionsBuilder) ByteBufferInputStream(com.github.ambry.utils.ByteBufferInputStream) ClusterMapConfig(com.github.ambry.config.ClusterMapConfig) BlobStoreControlAdminRequest(com.github.ambry.protocol.BlobStoreControlAdminRequest) StoreFindToken(com.github.ambry.store.StoreFindToken) Assert(org.junit.Assert) GetBlobOptionsBuilder(com.github.ambry.router.GetBlobOptionsBuilder) Http2BlockingChannel(com.github.ambry.network.http2.Http2BlockingChannel) ConnectionPoolConfig(com.github.ambry.config.ConnectionPoolConfig) DataNodeId(com.github.ambry.clustermap.DataNodeId) ByteBufferReadableStreamChannel(com.github.ambry.commons.ByteBufferReadableStreamChannel) TimeoutException(java.util.concurrent.TimeoutException) Http2ClientMetrics(com.github.ambry.network.http2.Http2ClientMetrics) Random(java.util.Random) ByteBuffer(java.nio.ByteBuffer) Unpooled(io.netty.buffer.Unpooled) MockReplicaId(com.github.ambry.clustermap.MockReplicaId) GetResponse(com.github.ambry.protocol.GetResponse) PortType(com.github.ambry.network.PortType) BlobStoreControlAction(com.github.ambry.protocol.BlobStoreControlAction) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SSLBlockingChannel(com.github.ambry.network.SSLBlockingChannel) GetRequest(com.github.ambry.protocol.GetRequest) VcrServer(com.github.ambry.cloud.VcrServer) StoreKeyFactory(com.github.ambry.store.StoreKeyFactory) Utils(com.github.ambry.utils.Utils) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) Collectors(java.util.stream.Collectors) ConnectedChannel(com.github.ambry.network.ConnectedChannel) NettySslHttp2Factory(com.github.ambry.commons.NettySslHttp2Factory) Objects(java.util.Objects) RouterConfig(com.github.ambry.config.RouterConfig) List(java.util.List) TtlUpdateRequest(com.github.ambry.protocol.TtlUpdateRequest) MessageFormatFlags(com.github.ambry.messageformat.MessageFormatFlags) QuotaTestUtils(com.github.ambry.quota.QuotaTestUtils) Callback(com.github.ambry.commons.Callback) BlobType(com.github.ambry.messageformat.BlobType) InMemAccountService(com.github.ambry.account.InMemAccountService) PartitionId(com.github.ambry.clustermap.PartitionId) BlobId(com.github.ambry.commons.BlobId) DataInputStream(java.io.DataInputStream) FindTokenFactory(com.github.ambry.replication.FindTokenFactory) CloudDestinationFactory(com.github.ambry.cloud.CloudDestinationFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AccountService(com.github.ambry.account.AccountService) UndeleteResponse(com.github.ambry.protocol.UndeleteResponse) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) HardwareState(com.github.ambry.clustermap.HardwareState) AdminResponse(com.github.ambry.protocol.AdminResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) CrcInputStream(com.github.ambry.utils.CrcInputStream) HashSet(java.util.HashSet) AdminRequest(com.github.ambry.protocol.AdminRequest) SSLConfig(com.github.ambry.config.SSLConfig) ByteBuf(io.netty.buffer.ByteBuf) LatchBasedInMemoryCloudDestination(com.github.ambry.cloud.LatchBasedInMemoryCloudDestination) DeleteResponse(com.github.ambry.protocol.DeleteResponse) CommonTestUtils(com.github.ambry.commons.CommonTestUtils) HelixControllerManager(com.github.ambry.utils.HelixControllerManager) PutRequest(com.github.ambry.protocol.PutRequest) Router(com.github.ambry.router.Router) MockDataNodeId(com.github.ambry.clustermap.MockDataNodeId) VcrTestUtil(com.github.ambry.cloud.VcrTestUtil) DeleteRequest(com.github.ambry.protocol.DeleteRequest) Pair(com.github.ambry.utils.Pair) Iterator(java.util.Iterator) ClusterAgentsFactory(com.github.ambry.clustermap.ClusterAgentsFactory) ReplicaType(com.github.ambry.clustermap.ReplicaType) ConnectionPool(com.github.ambry.network.ConnectionPool) QuotaChargeCallback(com.github.ambry.quota.QuotaChargeCallback) ClusterMap(com.github.ambry.clustermap.ClusterMap) FileInputStream(java.io.FileInputStream) NonBlockingRouterFactory(com.github.ambry.router.NonBlockingRouterFactory) TimeUnit(java.util.concurrent.TimeUnit) MessageInfo(com.github.ambry.store.MessageInfo) MessageFormatRecord(com.github.ambry.messageformat.MessageFormatRecord) Port(com.github.ambry.network.Port) CloudBlobMetadata(com.github.ambry.cloud.CloudBlobMetadata) Collections(java.util.Collections) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) InputStream(java.io.InputStream) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) UndeleteRequest(com.github.ambry.protocol.UndeleteRequest) UndeleteResponse(com.github.ambry.protocol.UndeleteResponse) CompletableFuture(java.util.concurrent.CompletableFuture) BlobAll(com.github.ambry.messageformat.BlobAll) Random(java.util.Random) GetRequest(com.github.ambry.protocol.GetRequest) BlobData(com.github.ambry.messageformat.BlobData) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet) MessageFormatException(com.github.ambry.messageformat.MessageFormatException) ConnectedChannel(com.github.ambry.network.ConnectedChannel) CountDownLatch(java.util.concurrent.CountDownLatch) PartitionRequestInfo(com.github.ambry.protocol.PartitionRequestInfo) NettyByteBufDataInputStream(com.github.ambry.utils.NettyByteBufDataInputStream) DataInputStream(java.io.DataInputStream) GetResponse(com.github.ambry.protocol.GetResponse) ByteBuffer(java.nio.ByteBuffer) ReplicaId(com.github.ambry.clustermap.ReplicaId) MockReplicaId(com.github.ambry.clustermap.MockReplicaId) BlobIdFactory(com.github.ambry.commons.BlobIdFactory) MessageInfo(com.github.ambry.store.MessageInfo) DeleteResponse(com.github.ambry.protocol.DeleteResponse) BlobProperties(com.github.ambry.messageformat.BlobProperties) MockDataNodeId(com.github.ambry.clustermap.MockDataNodeId) BlobId(com.github.ambry.commons.BlobId) DeleteRequest(com.github.ambry.protocol.DeleteRequest) File(java.io.File) MockClusterMap(com.github.ambry.clustermap.MockClusterMap)

Example 17 with MockDataNodeId

use of com.github.ambry.clustermap.MockDataNodeId in project ambry by linkedin.

the class ServerTestUtil method undeleteRecoveryTest.

static void undeleteRecoveryTest(Port targetPort, MockCluster cluster, SSLConfig clientSSLConfig, SSLSocketFactory clientSSLSocketFactory) {
    try {
        MockClusterMap clusterMap = cluster.getClusterMap();
        byte[] userMetadata = new byte[1000];
        byte[] data = new byte[31870];
        short accountId = Utils.getRandomShort(TestUtils.RANDOM);
        short containerId = Utils.getRandomShort(TestUtils.RANDOM);
        BlobProperties properties = new BlobProperties(31870, "serviceid1", accountId, containerId, false, cluster.time.milliseconds());
        TestUtils.RANDOM.nextBytes(userMetadata);
        TestUtils.RANDOM.nextBytes(data);
        List<PartitionId> partitionIds = clusterMap.getWritablePartitionIds(MockClusterMap.DEFAULT_PARTITION_CLASS);
        short blobIdVersion = CommonTestUtils.getCurrentBlobIdVersion();
        BlobId blobId1 = new BlobId(blobIdVersion, BlobId.BlobIdType.NATIVE, clusterMap.getLocalDatacenterId(), properties.getAccountId(), properties.getContainerId(), partitionIds.get(0), false, BlobId.BlobDataType.DATACHUNK);
        // put blob 1
        PutRequest putRequest = new PutRequest(1, "client1", blobId1, properties, ByteBuffer.wrap(userMetadata), Unpooled.wrappedBuffer(data), properties.getBlobSize(), BlobType.DataBlob, null);
        ConnectedChannel channel = getBlockingChannelBasedOnPortType(targetPort, "localhost", clientSSLSocketFactory, clientSSLConfig);
        channel.connect();
        DataInputStream stream = channel.sendAndReceive(putRequest).getInputStream();
        PutResponse response = PutResponse.readFrom(stream);
        releaseNettyBufUnderneathStream(stream);
        assertEquals(ServerErrorCode.No_Error, response.getError());
        for (int i = 0; i < 2; i++) {
            // delete blob 1
            deleteBlob(channel, blobId1, cluster.time.milliseconds());
            // undelete blob 1
            undeleteBlob(channel, blobId1, cluster.time.milliseconds(), (short) (i + 1));
        }
        // put blob 2 that is expired (Add additional 5 secs to avoid Blob_Update_Not_Allowed failure as TtlUpdate op time
        // is also cluster.time.milliseconds(). Theoretically, it should succeed as op time = expiry time - buffer time.
        // However, the index value converts ms to sec when putting a blob, so the milliseconds part of initial put blob
        // time is wiped out and makes op time > expiry time - buffer time. Adding some time should avoid this failure.)
        long ttl = 24 * 60 * 60 + 5;
        BlobProperties propertiesExpired = new BlobProperties(31870, "serviceid1", "ownerid", "jpeg", false, ttl, cluster.time.milliseconds(), accountId, containerId, false, null, null, null);
        BlobId blobId2 = new BlobId(blobIdVersion, BlobId.BlobIdType.NATIVE, clusterMap.getLocalDatacenterId(), propertiesExpired.getAccountId(), propertiesExpired.getContainerId(), partitionIds.get(0), false, BlobId.BlobDataType.DATACHUNK);
        PutRequest putRequest2 = new PutRequest(1, "client1", blobId2, propertiesExpired, ByteBuffer.wrap(userMetadata), Unpooled.wrappedBuffer(data), properties.getBlobSize(), BlobType.DataBlob, null);
        stream = channel.sendAndReceive(putRequest2).getInputStream();
        PutResponse response2 = PutResponse.readFrom(stream);
        releaseNettyBufUnderneathStream(stream);
        assertEquals(ServerErrorCode.No_Error, response2.getError());
        for (int i = 0; i < 2; i++) {
            // delete blob 2
            deleteBlob(channel, blobId2, cluster.time.milliseconds());
            // undelete blob 2
            undeleteBlob(channel, blobId2, cluster.time.milliseconds(), (short) (i + 1));
        }
        // ttl update blob 2
        updateBlobTtl(channel, blobId2, cluster.time.milliseconds());
        cluster.time.sleep(ttl + 10000);
        // Now stops the server and remove all the index files for this partition and test its recovery.
        channel.disconnect();
        AmbryServer server = cluster.getServers().get(0);
        server.shutdown();
        server.awaitShutdown();
        MockDataNodeId dataNode = (MockDataNodeId) clusterMap.getDataNodeId("localhost", channel.getRemotePort());
        for (ReplicaId replica : partitionIds.get(0).getReplicaIds()) {
            if (replica.getDataNodeId().equals(dataNode)) {
                for (File file : Objects.requireNonNull(new File(replica.getReplicaPath()).listFiles((file, filename) -> filename.endsWith("index")))) {
                    file.delete();
                }
            }
        }
        cluster.reinitServer(0);
        channel = getBlockingChannelBasedOnPortType(targetPort, "localhost", clientSSLSocketFactory, clientSSLConfig);
        channel.connect();
        // Now verify that we can fetch blob1 and blob2.
        for (BlobId blobId : new BlobId[] { blobId1, blobId2 }) {
            long deadline = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(10);
            while (true) {
                // get blob properties
                ArrayList<BlobId> ids = new ArrayList<>();
                ids.add(blobId);
                ArrayList<PartitionRequestInfo> partitionRequestInfoList = new ArrayList<>();
                PartitionRequestInfo partitionRequestInfo = new PartitionRequestInfo(partitionIds.get(0), ids);
                partitionRequestInfoList.add(partitionRequestInfo);
                GetRequest getRequest = new GetRequest(1, "clientid2", MessageFormatFlags.BlobProperties, partitionRequestInfoList, GetOption.None);
                stream = channel.sendAndReceive(getRequest).getInputStream();
                GetResponse getResponse = GetResponse.readFrom(stream, clusterMap);
                if (getResponse.getPartitionResponseInfoList().get(0).getErrorCode() == ServerErrorCode.No_Error) {
                    BlobProperties propertyOutput = MessageFormatRecord.deserializeBlobProperties(getResponse.getInputStream());
                    assertEquals(31870, propertyOutput.getBlobSize());
                    assertEquals("serviceid1", propertyOutput.getServiceId());
                    assertEquals("AccountId mismatch", accountId, propertyOutput.getAccountId());
                    assertEquals("ContainerId mismatch", containerId, propertyOutput.getContainerId());
                    releaseNettyBufUnderneathStream(stream);
                    break;
                } else {
                    Thread.sleep(1000);
                    if (System.currentTimeMillis() > deadline) {
                        throw new TimeoutException("Fail to get blob " + blobId + " at  " + channel.getRemoteHost());
                    }
                }
            }
        }
        channel.disconnect();
    } catch (Exception e) {
        e.printStackTrace();
        fail();
    }
}
Also used : AdminRequestOrResponseType(com.github.ambry.protocol.AdminRequestOrResponseType) GetOption(com.github.ambry.protocol.GetOption) Arrays(java.util.Arrays) Http2ClientConfig(com.github.ambry.config.Http2ClientConfig) BlobProperties(com.github.ambry.messageformat.BlobProperties) BlobAll(com.github.ambry.messageformat.BlobAll) SubRecord(com.github.ambry.messageformat.SubRecord) Future(java.util.concurrent.Future) TestUtils(com.github.ambry.utils.TestUtils) Map(java.util.Map) UndeleteRequest(com.github.ambry.protocol.UndeleteRequest) TtlUpdateResponse(com.github.ambry.protocol.TtlUpdateResponse) RetainingAsyncWritableChannel(com.github.ambry.commons.RetainingAsyncWritableChannel) RouterErrorCode(com.github.ambry.router.RouterErrorCode) ReadableStreamChannel(com.github.ambry.router.ReadableStreamChannel) SSLFactory(com.github.ambry.commons.SSLFactory) BlobData(com.github.ambry.messageformat.BlobData) Set(java.util.Set) MockPartitionId(com.github.ambry.clustermap.MockPartitionId) SSLSocketFactory(javax.net.ssl.SSLSocketFactory) CountDownLatch(java.util.concurrent.CountDownLatch) MockDiskId(com.github.ambry.clustermap.MockDiskId) UpdateType(com.github.ambry.notification.UpdateType) PartitionRequestInfo(com.github.ambry.protocol.PartitionRequestInfo) ArrayList(java.util.ArrayList) NettyByteBufDataInputStream(com.github.ambry.utils.NettyByteBufDataInputStream) ReplicationControlAdminRequest(com.github.ambry.protocol.ReplicationControlAdminRequest) BlockingChannel(com.github.ambry.network.BlockingChannel) BlockingChannelConnectionPool(com.github.ambry.network.BlockingChannelConnectionPool) MetricRegistry(com.codahale.metrics.MetricRegistry) Properties(java.util.Properties) PutMessageFormatInputStream(com.github.ambry.messageformat.PutMessageFormatInputStream) Offset(com.github.ambry.store.Offset) VerifiableProperties(com.github.ambry.config.VerifiableProperties) IOException(java.io.IOException) BlobIdFactory(com.github.ambry.commons.BlobIdFactory) MessageFormatException(com.github.ambry.messageformat.MessageFormatException) PutResponse(com.github.ambry.protocol.PutResponse) RouterException(com.github.ambry.router.RouterException) LatchBasedInMemoryCloudDestinationFactory(com.github.ambry.cloud.LatchBasedInMemoryCloudDestinationFactory) File(java.io.File) ExecutionException(java.util.concurrent.ExecutionException) GetBlobResult(com.github.ambry.router.GetBlobResult) ReplicaId(com.github.ambry.clustermap.ReplicaId) PutBlobOptionsBuilder(com.github.ambry.router.PutBlobOptionsBuilder) ByteBufferInputStream(com.github.ambry.utils.ByteBufferInputStream) ClusterMapConfig(com.github.ambry.config.ClusterMapConfig) BlobStoreControlAdminRequest(com.github.ambry.protocol.BlobStoreControlAdminRequest) StoreFindToken(com.github.ambry.store.StoreFindToken) Assert(org.junit.Assert) GetBlobOptionsBuilder(com.github.ambry.router.GetBlobOptionsBuilder) Http2BlockingChannel(com.github.ambry.network.http2.Http2BlockingChannel) ConnectionPoolConfig(com.github.ambry.config.ConnectionPoolConfig) DataNodeId(com.github.ambry.clustermap.DataNodeId) ByteBufferReadableStreamChannel(com.github.ambry.commons.ByteBufferReadableStreamChannel) TimeoutException(java.util.concurrent.TimeoutException) Http2ClientMetrics(com.github.ambry.network.http2.Http2ClientMetrics) Random(java.util.Random) ByteBuffer(java.nio.ByteBuffer) Unpooled(io.netty.buffer.Unpooled) MockReplicaId(com.github.ambry.clustermap.MockReplicaId) GetResponse(com.github.ambry.protocol.GetResponse) PortType(com.github.ambry.network.PortType) BlobStoreControlAction(com.github.ambry.protocol.BlobStoreControlAction) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SSLBlockingChannel(com.github.ambry.network.SSLBlockingChannel) GetRequest(com.github.ambry.protocol.GetRequest) VcrServer(com.github.ambry.cloud.VcrServer) StoreKeyFactory(com.github.ambry.store.StoreKeyFactory) Utils(com.github.ambry.utils.Utils) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) Collectors(java.util.stream.Collectors) ConnectedChannel(com.github.ambry.network.ConnectedChannel) NettySslHttp2Factory(com.github.ambry.commons.NettySslHttp2Factory) Objects(java.util.Objects) RouterConfig(com.github.ambry.config.RouterConfig) List(java.util.List) TtlUpdateRequest(com.github.ambry.protocol.TtlUpdateRequest) MessageFormatFlags(com.github.ambry.messageformat.MessageFormatFlags) QuotaTestUtils(com.github.ambry.quota.QuotaTestUtils) Callback(com.github.ambry.commons.Callback) BlobType(com.github.ambry.messageformat.BlobType) InMemAccountService(com.github.ambry.account.InMemAccountService) PartitionId(com.github.ambry.clustermap.PartitionId) BlobId(com.github.ambry.commons.BlobId) DataInputStream(java.io.DataInputStream) FindTokenFactory(com.github.ambry.replication.FindTokenFactory) CloudDestinationFactory(com.github.ambry.cloud.CloudDestinationFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AccountService(com.github.ambry.account.AccountService) UndeleteResponse(com.github.ambry.protocol.UndeleteResponse) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) HardwareState(com.github.ambry.clustermap.HardwareState) AdminResponse(com.github.ambry.protocol.AdminResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) CrcInputStream(com.github.ambry.utils.CrcInputStream) HashSet(java.util.HashSet) AdminRequest(com.github.ambry.protocol.AdminRequest) SSLConfig(com.github.ambry.config.SSLConfig) ByteBuf(io.netty.buffer.ByteBuf) LatchBasedInMemoryCloudDestination(com.github.ambry.cloud.LatchBasedInMemoryCloudDestination) DeleteResponse(com.github.ambry.protocol.DeleteResponse) CommonTestUtils(com.github.ambry.commons.CommonTestUtils) HelixControllerManager(com.github.ambry.utils.HelixControllerManager) PutRequest(com.github.ambry.protocol.PutRequest) Router(com.github.ambry.router.Router) MockDataNodeId(com.github.ambry.clustermap.MockDataNodeId) VcrTestUtil(com.github.ambry.cloud.VcrTestUtil) DeleteRequest(com.github.ambry.protocol.DeleteRequest) Pair(com.github.ambry.utils.Pair) Iterator(java.util.Iterator) ClusterAgentsFactory(com.github.ambry.clustermap.ClusterAgentsFactory) ReplicaType(com.github.ambry.clustermap.ReplicaType) ConnectionPool(com.github.ambry.network.ConnectionPool) QuotaChargeCallback(com.github.ambry.quota.QuotaChargeCallback) ClusterMap(com.github.ambry.clustermap.ClusterMap) FileInputStream(java.io.FileInputStream) NonBlockingRouterFactory(com.github.ambry.router.NonBlockingRouterFactory) TimeUnit(java.util.concurrent.TimeUnit) MessageInfo(com.github.ambry.store.MessageInfo) MessageFormatRecord(com.github.ambry.messageformat.MessageFormatRecord) Port(com.github.ambry.network.Port) CloudBlobMetadata(com.github.ambry.cloud.CloudBlobMetadata) Collections(java.util.Collections) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) InputStream(java.io.InputStream) ArrayList(java.util.ArrayList) PutResponse(com.github.ambry.protocol.PutResponse) GetRequest(com.github.ambry.protocol.GetRequest) TimeoutException(java.util.concurrent.TimeoutException) PutRequest(com.github.ambry.protocol.PutRequest) ConnectedChannel(com.github.ambry.network.ConnectedChannel) MockPartitionId(com.github.ambry.clustermap.MockPartitionId) PartitionId(com.github.ambry.clustermap.PartitionId) NettyByteBufDataInputStream(com.github.ambry.utils.NettyByteBufDataInputStream) DataInputStream(java.io.DataInputStream) PartitionRequestInfo(com.github.ambry.protocol.PartitionRequestInfo) GetResponse(com.github.ambry.protocol.GetResponse) ReplicaId(com.github.ambry.clustermap.ReplicaId) MockReplicaId(com.github.ambry.clustermap.MockReplicaId) IOException(java.io.IOException) MessageFormatException(com.github.ambry.messageformat.MessageFormatException) RouterException(com.github.ambry.router.RouterException) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException) BlobProperties(com.github.ambry.messageformat.BlobProperties) MockDataNodeId(com.github.ambry.clustermap.MockDataNodeId) BlobId(com.github.ambry.commons.BlobId) File(java.io.File) MockClusterMap(com.github.ambry.clustermap.MockClusterMap)

Example 18 with MockDataNodeId

use of com.github.ambry.clustermap.MockDataNodeId in project ambry by linkedin.

the class Verifier method run.

@Override
public void run() {
    try {
        List<PartitionRequestInfo> partitionRequestInfoList = new ArrayList<PartitionRequestInfo>();
        while (requestsVerified.get() != totalRequests.get() && !cancelTest.get()) {
            Payload payload = payloadQueue.poll(1000, TimeUnit.MILLISECONDS);
            if (payload != null) {
                notificationSystem.awaitBlobCreations(payload.blobId);
                for (MockDataNodeId dataNodeId : clusterMap.getDataNodes()) {
                    ConnectedChannel channel1 = null;
                    try {
                        BlobId blobId = new BlobId(payload.blobId, clusterMap);
                        Port port = new Port(portType == PortType.PLAINTEXT ? dataNodeId.getPort() : dataNodeId.getSSLPort(), portType);
                        channel1 = connectionPool.checkOutConnection("localhost", port, 10000);
                        ArrayList<BlobId> ids = new ArrayList<BlobId>();
                        ids.add(blobId);
                        partitionRequestInfoList.clear();
                        PartitionRequestInfo partitionRequestInfo = new PartitionRequestInfo(ids.get(0).getPartition(), ids);
                        partitionRequestInfoList.add(partitionRequestInfo);
                        GetRequest getRequest = new GetRequest(1, "clientid2", MessageFormatFlags.BlobProperties, partitionRequestInfoList, GetOption.None);
                        channel1.send(getRequest);
                        DataInputStream stream = channel1.receive().getInputStream();
                        GetResponse resp = GetResponse.readFrom(stream, clusterMap);
                        if (resp.getError() != ServerErrorCode.No_Error) {
                            System.out.println(dataNodeId.getHostname() + " " + dataNodeId.getPort() + " " + resp.getError());
                            throw new IllegalStateException();
                        } else {
                            try {
                                BlobProperties propertyOutput = MessageFormatRecord.deserializeBlobProperties(resp.getInputStream());
                                if (propertyOutput.getBlobSize() != payload.blobProperties.getBlobSize()) {
                                    String exceptionMsg = "blob size not matching " + " expected " + payload.blobProperties.getBlobSize() + " actual " + propertyOutput.getBlobSize();
                                    System.out.println(exceptionMsg);
                                    throw new IllegalStateException(exceptionMsg);
                                }
                                if (!propertyOutput.getServiceId().equals(payload.blobProperties.getServiceId())) {
                                    String exceptionMsg = "service id not matching " + " expected " + payload.blobProperties.getServiceId() + " actual " + propertyOutput.getBlobSize();
                                    System.out.println(exceptionMsg);
                                    throw new IllegalStateException(exceptionMsg);
                                }
                                if (propertyOutput.getAccountId() != payload.blobProperties.getAccountId()) {
                                    String exceptionMsg = "accountid not matching " + " expected " + payload.blobProperties.getAccountId() + " actual " + propertyOutput.getAccountId();
                                    System.out.println(exceptionMsg);
                                    throw new IllegalStateException(exceptionMsg);
                                }
                                if (propertyOutput.getContainerId() != payload.blobProperties.getContainerId()) {
                                    String exceptionMsg = "containerId not matching " + " expected " + payload.blobProperties.getContainerId() + " actual " + propertyOutput.getContainerId();
                                    System.out.println(exceptionMsg);
                                    throw new IllegalStateException(exceptionMsg);
                                }
                                if (propertyOutput.isEncrypted() != payload.blobProperties.isEncrypted()) {
                                    String exceptionMsg = "IsEncrypted not matching " + " expected " + payload.blobProperties.isEncrypted() + " actual " + propertyOutput.isEncrypted();
                                    System.out.println(exceptionMsg);
                                    throw new IllegalStateException(exceptionMsg);
                                }
                                long actualExpiryTimeMs = resp.getPartitionResponseInfoList().get(0).getMessageInfoList().get(0).getExpirationTimeInMs();
                                checkExpiryTimeMatch(payload, actualExpiryTimeMs, "messageinfo in blobproperty");
                            } catch (MessageFormatException e) {
                                e.printStackTrace();
                                throw new IllegalStateException(e);
                            }
                        }
                        // get user metadata
                        ids.clear();
                        ids.add(blobId);
                        partitionRequestInfoList.clear();
                        partitionRequestInfo = new PartitionRequestInfo(ids.get(0).getPartition(), ids);
                        partitionRequestInfoList.add(partitionRequestInfo);
                        getRequest = new GetRequest(1, "clientid2", MessageFormatFlags.BlobUserMetadata, partitionRequestInfoList, GetOption.None);
                        channel1.send(getRequest);
                        stream = channel1.receive().getInputStream();
                        resp = GetResponse.readFrom(stream, clusterMap);
                        if (resp.getError() != ServerErrorCode.No_Error) {
                            System.out.println("Error after get user metadata " + resp.getError());
                            throw new IllegalStateException();
                        } else {
                            try {
                                ByteBuffer userMetadataOutput = MessageFormatRecord.deserializeUserMetadata(resp.getInputStream());
                                if (userMetadataOutput.compareTo(ByteBuffer.wrap(payload.metadata)) != 0) {
                                    throw new IllegalStateException();
                                }
                                long actualExpiryTimeMs = resp.getPartitionResponseInfoList().get(0).getMessageInfoList().get(0).getExpirationTimeInMs();
                                checkExpiryTimeMatch(payload, actualExpiryTimeMs, "messageinfo in usermetadatga");
                            } catch (MessageFormatException e) {
                                e.printStackTrace();
                                throw new IllegalStateException();
                            }
                        }
                        // get blob
                        ids.clear();
                        ids.add(blobId);
                        partitionRequestInfoList.clear();
                        partitionRequestInfo = new PartitionRequestInfo(ids.get(0).getPartition(), ids);
                        partitionRequestInfoList.add(partitionRequestInfo);
                        getRequest = new GetRequest(1, "clientid2", MessageFormatFlags.Blob, partitionRequestInfoList, GetOption.None);
                        channel1.send(getRequest);
                        stream = channel1.receive().getInputStream();
                        resp = GetResponse.readFrom(stream, clusterMap);
                        // System.out.println("response from get " + resp.getError());
                        if (resp.getError() != ServerErrorCode.No_Error) {
                            System.out.println("Error after get blob " + resp.getError());
                            throw new IllegalStateException();
                        } else {
                            try {
                                BlobData blobData = MessageFormatRecord.deserializeBlob(resp.getInputStream());
                                byte[] blobout = new byte[(int) blobData.getSize()];
                                ByteBuf buffer = blobData.content();
                                try {
                                    buffer.readBytes(blobout);
                                } finally {
                                    buffer.release();
                                }
                                if (ByteBuffer.wrap(blobout).compareTo(ByteBuffer.wrap(payload.blob)) != 0) {
                                    throw new IllegalStateException();
                                }
                                long actualExpiryTimeMs = resp.getPartitionResponseInfoList().get(0).getMessageInfoList().get(0).getExpirationTimeInMs();
                                checkExpiryTimeMatch(payload, actualExpiryTimeMs, "messageinfo in blobdata");
                            } catch (MessageFormatException e) {
                                e.printStackTrace();
                                throw new IllegalStateException();
                            }
                        }
                        // get blob all
                        getRequest = new GetRequest(1, "clientid2", MessageFormatFlags.All, partitionRequestInfoList, GetOption.None);
                        channel1.send(getRequest);
                        stream = channel1.receive().getInputStream();
                        resp = GetResponse.readFrom(stream, clusterMap);
                        if (resp.getError() != ServerErrorCode.No_Error) {
                            System.out.println("Error after get blob " + resp.getError());
                            throw new IllegalStateException();
                        } else {
                            try {
                                BlobAll blobAll = MessageFormatRecord.deserializeBlobAll(resp.getInputStream(), new BlobIdFactory(clusterMap));
                                byte[] blobout = new byte[(int) blobAll.getBlobData().getSize()];
                                ByteBuf buffer = blobAll.getBlobData().content();
                                try {
                                    buffer.readBytes(blobout);
                                } finally {
                                    buffer.release();
                                }
                                if (ByteBuffer.wrap(blobout).compareTo(ByteBuffer.wrap(payload.blob)) != 0) {
                                    throw new IllegalStateException();
                                }
                                long actualExpiryTimeMs = resp.getPartitionResponseInfoList().get(0).getMessageInfoList().get(0).getExpirationTimeInMs();
                                checkExpiryTimeMatch(payload, actualExpiryTimeMs, "messageinfo in bloball");
                            } catch (MessageFormatException e) {
                                e.printStackTrace();
                                throw new IllegalStateException();
                            }
                        }
                        if (payload.blobProperties.getTimeToLiveInSeconds() != Utils.Infinite_Time) {
                            // ttl update, check and wait for replication
                            ServerTestUtil.updateBlobTtl(channel1, new BlobId(payload.blobId, clusterMap), time.milliseconds());
                            ServerTestUtil.checkTtlUpdateStatus(channel1, clusterMap, new BlobIdFactory(clusterMap), blobId, payload.blob, true, Utils.Infinite_Time);
                            notificationSystem.awaitBlobUpdates(payload.blobId, UpdateType.TTL_UPDATE);
                            BlobProperties old = payload.blobProperties;
                            payload.blobProperties = new BlobProperties(old.getBlobSize(), old.getServiceId(), old.getOwnerId(), old.getContentType(), old.isEncrypted(), Utils.Infinite_Time, old.getCreationTimeInMs(), old.getAccountId(), old.getContainerId(), old.isEncrypted(), old.getExternalAssetTag(), old.getContentEncoding(), old.getFilename());
                        }
                    } catch (Exception e) {
                        if (channel1 != null) {
                            connectionPool.destroyConnection(channel1);
                            channel1 = null;
                        }
                    } finally {
                        if (channel1 != null) {
                            connectionPool.checkInConnection(channel1);
                            channel1 = null;
                        }
                    }
                }
                requestsVerified.incrementAndGet();
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        cancelTest.set(true);
    } finally {
        completedLatch.countDown();
    }
}
Also used : MessageFormatException(com.github.ambry.messageformat.MessageFormatException) Port(com.github.ambry.network.Port) ArrayList(java.util.ArrayList) ConnectedChannel(com.github.ambry.network.ConnectedChannel) PartitionRequestInfo(com.github.ambry.protocol.PartitionRequestInfo) DataInputStream(java.io.DataInputStream) ByteBuf(io.netty.buffer.ByteBuf) GetResponse(com.github.ambry.protocol.GetResponse) ByteBuffer(java.nio.ByteBuffer) MessageFormatException(com.github.ambry.messageformat.MessageFormatException) BlobIdFactory(com.github.ambry.commons.BlobIdFactory) BlobAll(com.github.ambry.messageformat.BlobAll) GetRequest(com.github.ambry.protocol.GetRequest) BlobProperties(com.github.ambry.messageformat.BlobProperties) MockDataNodeId(com.github.ambry.clustermap.MockDataNodeId) BlobData(com.github.ambry.messageformat.BlobData) BlobId(com.github.ambry.commons.BlobId)

Example 19 with MockDataNodeId

use of com.github.ambry.clustermap.MockDataNodeId in project ambry by linkedin.

the class AmbryServerRequestsTest method addBlobStoreFailureTest.

@Test
public void addBlobStoreFailureTest() throws Exception {
    // create newPartition1 that no replica sits on current node.
    List<MockDataNodeId> dataNodes = clusterMap.getDataNodes().stream().filter(node -> !node.getHostname().equals(dataNodeId.getHostname()) || node.getPort() != dataNodeId.getPort()).collect(Collectors.toList());
    PartitionId newPartition1 = clusterMap.createNewPartition(dataNodes);
    // test that getting new replica from cluster map fails
    sendAndVerifyStoreControlRequest(newPartition1, BlobStoreControlAction.AddStore, (short) 0, ServerErrorCode.Replica_Unavailable);
    // create newPartition2 that has one replica on current node
    PartitionId newPartition2 = clusterMap.createNewPartition(clusterMap.getDataNodes());
    // test that adding store into StorageManager fails
    storageManager.returnValueOfAddBlobStore = false;
    sendAndVerifyStoreControlRequest(newPartition2, BlobStoreControlAction.AddStore, (short) 0, ServerErrorCode.Unknown_Error);
    storageManager.returnValueOfAddBlobStore = true;
    // test that adding replica into ReplicationManager fails (we first add replica into ReplicationManager to trigger failure)
    ReplicaId replicaToAdd = clusterMap.getBootstrapReplica(newPartition2.toPathString(), dataNodeId);
    replicationManager.addReplica(replicaToAdd);
    sendAndVerifyStoreControlRequest(newPartition2, BlobStoreControlAction.AddStore, (short) 0, ServerErrorCode.Unknown_Error);
    assertTrue("Remove replica from replication manager should succeed.", replicationManager.removeReplica(replicaToAdd));
    // test that adding replica into StatsManager fails
    statsManager.returnValOfAddReplica = false;
    sendAndVerifyStoreControlRequest(newPartition2, BlobStoreControlAction.AddStore, (short) 0, ServerErrorCode.Unknown_Error);
    statsManager.returnValOfAddReplica = true;
}
Also used : NetworkRequest(com.github.ambry.network.NetworkRequest) AdminRequestOrResponseType(com.github.ambry.protocol.AdminRequestOrResponseType) GetOption(com.github.ambry.protocol.GetOption) Arrays(java.util.Arrays) BlobProperties(com.github.ambry.messageformat.BlobProperties) CatchupStatusAdminResponse(com.github.ambry.protocol.CatchupStatusAdminResponse) StoreErrorCodes(com.github.ambry.store.StoreErrorCodes) TestUtils(com.github.ambry.utils.TestUtils) Map(java.util.Map) ServerMetrics(com.github.ambry.commons.ServerMetrics) RequestOrResponseType(com.github.ambry.protocol.RequestOrResponseType) UndeleteRequest(com.github.ambry.protocol.UndeleteRequest) ReplicaMetadataRequest(com.github.ambry.protocol.ReplicaMetadataRequest) EnumSet(java.util.EnumSet) ReplicationConfig(com.github.ambry.config.ReplicationConfig) FindTokenHelper(com.github.ambry.replication.FindTokenHelper) StatsManagerConfig(com.github.ambry.config.StatsManagerConfig) Set(java.util.Set) MockPartitionId(com.github.ambry.clustermap.MockPartitionId) ReplicaMetadataRequestInfo(com.github.ambry.protocol.ReplicaMetadataRequestInfo) AmbryRequests(com.github.ambry.protocol.AmbryRequests) StoreKey(com.github.ambry.store.StoreKey) PartitionRequestInfo(com.github.ambry.protocol.PartitionRequestInfo) MockFindTokenHelper(com.github.ambry.replication.MockFindTokenHelper) IdUndeletedStoreException(com.github.ambry.store.IdUndeletedStoreException) RunWith(org.junit.runner.RunWith) ArrayList(java.util.ArrayList) TestUtils(com.github.ambry.clustermap.TestUtils) SystemTime(com.github.ambry.utils.SystemTime) StoreException(com.github.ambry.store.StoreException) ReplicationControlAdminRequest(com.github.ambry.protocol.ReplicationControlAdminRequest) MockStoreKeyConverterFactory(com.github.ambry.store.MockStoreKeyConverterFactory) Before(org.junit.Before) ReplicaState(com.github.ambry.clustermap.ReplicaState) MetricRegistry(com.codahale.metrics.MetricRegistry) Properties(java.util.Properties) VerifiableProperties(com.github.ambry.config.VerifiableProperties) IOException(java.io.IOException) Test(org.junit.Test) MessageFormatException(com.github.ambry.messageformat.MessageFormatException) Store(com.github.ambry.store.Store) ReplicaId(com.github.ambry.clustermap.ReplicaId) MockReplicationManager(com.github.ambry.replication.MockReplicationManager) ByteBufferInputStream(com.github.ambry.utils.ByteBufferInputStream) ClusterMapConfig(com.github.ambry.config.ClusterMapConfig) BlobStoreControlAdminRequest(com.github.ambry.protocol.BlobStoreControlAdminRequest) BlobStore(com.github.ambry.store.BlobStore) Assert(org.junit.Assert) Response(com.github.ambry.protocol.Response) ByteBufferDataInputStream(com.github.ambry.utils.ByteBufferDataInputStream) MessageInfoTest(com.github.ambry.store.MessageInfoTest) DataNodeId(com.github.ambry.clustermap.DataNodeId) ByteBuffer(java.nio.ByteBuffer) Unpooled(io.netty.buffer.Unpooled) MockReplicaId(com.github.ambry.clustermap.MockReplicaId) GetResponse(com.github.ambry.protocol.GetResponse) ErrorMapping(com.github.ambry.commons.ErrorMapping) BlobStoreControlAction(com.github.ambry.protocol.BlobStoreControlAction) JSONObject(org.json.JSONObject) After(org.junit.After) SocketRequestResponseChannel(com.github.ambry.network.SocketRequestResponseChannel) NettyByteBufLeakHelper(com.github.ambry.utils.NettyByteBufLeakHelper) GetRequest(com.github.ambry.protocol.GetRequest) Parameterized(org.junit.runners.Parameterized) ServerNetworkResponseMetrics(com.github.ambry.network.ServerNetworkResponseMetrics) PartitionResponseInfo(com.github.ambry.protocol.PartitionResponseInfo) StoreKeyFactory(com.github.ambry.store.StoreKeyFactory) ServerConfig(com.github.ambry.config.ServerConfig) Utils(com.github.ambry.utils.Utils) Collectors(java.util.stream.Collectors) List(java.util.List) ReplicaMetadataResponse(com.github.ambry.protocol.ReplicaMetadataResponse) TtlUpdateRequest(com.github.ambry.protocol.TtlUpdateRequest) MessageFormatFlags(com.github.ambry.messageformat.MessageFormatFlags) BlobType(com.github.ambry.messageformat.BlobType) PartitionId(com.github.ambry.clustermap.PartitionId) BlobId(com.github.ambry.commons.BlobId) CatchupStatusAdminRequest(com.github.ambry.protocol.CatchupStatusAdminRequest) ByteBufferChannel(com.github.ambry.utils.ByteBufferChannel) HashMap(java.util.HashMap) AdminResponse(com.github.ambry.protocol.AdminResponse) MessageWriteSet(com.github.ambry.store.MessageWriteSet) HashSet(java.util.HashSet) AdminRequest(com.github.ambry.protocol.AdminRequest) MockHelixParticipant(com.github.ambry.clustermap.MockHelixParticipant) CommonTestUtils(com.github.ambry.commons.CommonTestUtils) RequestOrResponse(com.github.ambry.protocol.RequestOrResponse) Assume(org.junit.Assume) ReplicaMetadataResponseInfo(com.github.ambry.protocol.ReplicaMetadataResponseInfo) PutRequest(com.github.ambry.protocol.PutRequest) RequestControlAdminRequest(com.github.ambry.protocol.RequestControlAdminRequest) MockDataNodeId(com.github.ambry.clustermap.MockDataNodeId) MessageFormatInputStreamTest(com.github.ambry.messageformat.MessageFormatInputStreamTest) ReplicationManager(com.github.ambry.replication.ReplicationManager) DeleteRequest(com.github.ambry.protocol.DeleteRequest) ReplicaStatusDelegate(com.github.ambry.clustermap.ReplicaStatusDelegate) ReplicaType(com.github.ambry.clustermap.ReplicaType) MockWrite(com.github.ambry.store.MockWrite) ClusterMap(com.github.ambry.clustermap.ClusterMap) Mockito(org.mockito.Mockito) ReplicationException(com.github.ambry.replication.ReplicationException) MessageInfo(com.github.ambry.store.MessageInfo) ReplicaEventType(com.github.ambry.clustermap.ReplicaEventType) Send(com.github.ambry.network.Send) MessageFormatRecord(com.github.ambry.messageformat.MessageFormatRecord) Collections(java.util.Collections) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) InputStream(java.io.InputStream) MockDataNodeId(com.github.ambry.clustermap.MockDataNodeId) MockPartitionId(com.github.ambry.clustermap.MockPartitionId) PartitionId(com.github.ambry.clustermap.PartitionId) ReplicaId(com.github.ambry.clustermap.ReplicaId) MockReplicaId(com.github.ambry.clustermap.MockReplicaId) Test(org.junit.Test) MessageInfoTest(com.github.ambry.store.MessageInfoTest) MessageFormatInputStreamTest(com.github.ambry.messageformat.MessageFormatInputStreamTest)

Example 20 with MockDataNodeId

use of com.github.ambry.clustermap.MockDataNodeId in project ambry by linkedin.

the class UndeleteOperationTrackerTest method failureForInitialization.

/**
 * Tests when there are not sufficient eligible hosts.
 */
@Test
public void failureForInitialization() {
    assumeTrue(replicasStateEnabled);
    List<Port> portList = Collections.singletonList(new Port(PORT, PortType.PLAINTEXT));
    List<String> mountPaths = Collections.singletonList("mockMountPath");
    datanodes = new ArrayList<>(Arrays.asList(new MockDataNodeId(portList, mountPaths, "dc-0"), new MockDataNodeId(portList, mountPaths, "dc-1"), new MockDataNodeId(portList, mountPaths, "dc-2"), new MockDataNodeId(portList, mountPaths, "dc-3")));
    mockPartition = new MockPartitionId();
    populateReplicaList(4, ReplicaState.STANDBY);
    populateReplicaList(4, ReplicaState.INACTIVE);
    populateReplicaList(4, ReplicaState.DROPPED);
    localDcName = datanodes.get(0).getDatacenterName();
    mockClusterMap = new MockClusterMap(false, datanodes, 1, Collections.singletonList(mockPartition), localDcName);
    try {
        getOperationTracker(3);
        fail("Should fail to create undelete operation tracker because of insufficient eligible hosts");
    } catch (IllegalArgumentException e) {
    }
}
Also used : MockPartitionId(com.github.ambry.clustermap.MockPartitionId) Port(com.github.ambry.network.Port) MockDataNodeId(com.github.ambry.clustermap.MockDataNodeId) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) Test(org.junit.Test)

Aggregations

MockDataNodeId (com.github.ambry.clustermap.MockDataNodeId)63 Test (org.junit.Test)49 MockPartitionId (com.github.ambry.clustermap.MockPartitionId)44 ReplicaId (com.github.ambry.clustermap.ReplicaId)35 Port (com.github.ambry.network.Port)29 MockClusterMap (com.github.ambry.clustermap.MockClusterMap)28 PartitionId (com.github.ambry.clustermap.PartitionId)28 ArrayList (java.util.ArrayList)25 BlobStoreTest (com.github.ambry.store.BlobStoreTest)24 VerifiableProperties (com.github.ambry.config.VerifiableProperties)16 Properties (java.util.Properties)16 MetricRegistry (com.codahale.metrics.MetricRegistry)15 File (java.io.File)14 HashSet (java.util.HashSet)13 DataNodeId (com.github.ambry.clustermap.DataNodeId)12 MockReplicaId (com.github.ambry.clustermap.MockReplicaId)11 StateTransitionException (com.github.ambry.clustermap.StateTransitionException)11 HashMap (java.util.HashMap)10 CountDownLatch (java.util.concurrent.CountDownLatch)10 Counter (com.codahale.metrics.Counter)9