Search in sources :

Example 1 with QuorumServerInfo

use of alluxio.grpc.QuorumServerInfo in project alluxio by Alluxio.

the class QuorumInfoCommand method run.

@Override
public int run(CommandLine cl) throws IOException {
    JournalMasterClient jmClient = mMasterJournalMasterClient;
    String domainVal = cl.getOptionValue(DOMAIN_OPTION_NAME);
    try {
        JournalDomain domain = JournalDomain.valueOf(domainVal);
        if (domain == JournalDomain.JOB_MASTER) {
            jmClient = mJobMasterJournalMasterClient;
        }
    } catch (IllegalArgumentException e) {
        throw new InvalidArgumentException(ExceptionMessage.INVALID_OPTION_VALUE.getMessage(DOMAIN_OPTION_NAME, Arrays.toString(JournalDomain.values())));
    }
    GetQuorumInfoPResponse quorumInfo = jmClient.getQuorumInfo();
    Optional<QuorumServerInfo> leadingMasterInfoOpt = quorumInfo.getServerInfoList().stream().filter(QuorumServerInfo::getIsLeader).findFirst();
    String leadingMasterAddr = leadingMasterInfoOpt.isPresent() ? netAddressToString(leadingMasterInfoOpt.get().getServerAddress()) : "UNKNOWN";
    List<String[]> table = quorumInfo.getServerInfoList().stream().map(info -> new String[] { info.getServerState().toString(), Integer.toString(info.getPriority()), netAddressToString(info.getServerAddress()) }).collect(Collectors.toList());
    table.add(0, new String[] { "STATE", "PRIORITY", "SERVER ADDRESS" });
    mPrintStream.println(String.format(OUTPUT_HEADER_DOMAIN, quorumInfo.getDomain()));
    mPrintStream.println(String.format(OUTPUT_HEADER_QUORUM_SIZE, quorumInfo.getServerInfoList().size()));
    mPrintStream.println(String.format(OUTPUT_HEADER_LEADING_MASTER, leadingMasterAddr));
    mPrintStream.println();
    for (String[] output : table) {
        mPrintStream.printf(OUTPUT_SERVER_INFO, output);
    }
    return 0;
}
Also used : JournalMasterClient(alluxio.client.journal.JournalMasterClient) QuorumServerInfo(alluxio.grpc.QuorumServerInfo) Arrays(java.util.Arrays) NetAddress(alluxio.grpc.NetAddress) ExceptionMessage(alluxio.exception.ExceptionMessage) Options(org.apache.commons.cli.Options) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) List(java.util.List) Context(alluxio.cli.fsadmin.command.Context) GetQuorumInfoPResponse(alluxio.grpc.GetQuorumInfoPResponse) AbstractFsAdminCommand(alluxio.cli.fsadmin.command.AbstractFsAdminCommand) AlluxioConfiguration(alluxio.conf.AlluxioConfiguration) CommandLine(org.apache.commons.cli.CommandLine) Optional(java.util.Optional) VisibleForTesting(com.google.common.annotations.VisibleForTesting) JournalDomain(alluxio.grpc.JournalDomain) InvalidArgumentException(alluxio.exception.status.InvalidArgumentException) InvalidArgumentException(alluxio.exception.status.InvalidArgumentException) GetQuorumInfoPResponse(alluxio.grpc.GetQuorumInfoPResponse) QuorumServerInfo(alluxio.grpc.QuorumServerInfo) JournalMasterClient(alluxio.client.journal.JournalMasterClient) JournalDomain(alluxio.grpc.JournalDomain)

Example 2 with QuorumServerInfo

use of alluxio.grpc.QuorumServerInfo in project alluxio by Alluxio.

the class QuorumElectCommand method run.

@Override
public int run(CommandLine cl) throws IOException {
    JournalMasterClient jmClient = mMasterJournalMasterClient;
    String serverAddress = cl.getOptionValue(ADDRESS_OPTION_NAME);
    NetAddress address = QuorumCommand.stringToAddress(serverAddress);
    boolean success = false;
    try {
        mPrintStream.println(String.format(TRANSFER_INIT, serverAddress));
        String transferId = jmClient.transferLeadership(address);
        AtomicReference<String> errorMessage = new AtomicReference<>("");
        // wait for confirmation of leadership transfer
        // in milliseconds
        final int TIMEOUT_3MIN = 3 * 60 * 1000;
        CommonUtils.waitFor("election to finalize.", () -> {
            try {
                errorMessage.set(jmClient.getTransferLeaderMessage(transferId).getTransMsg().getMsg());
                if (!errorMessage.get().isEmpty()) {
                    // if an error is reported, end the retry immediately
                    return true;
                }
                GetQuorumInfoPResponse quorumInfo = jmClient.getQuorumInfo();
                Optional<QuorumServerInfo> leadingMasterInfoOpt = quorumInfo.getServerInfoList().stream().filter(QuorumServerInfo::getIsLeader).findFirst();
                NetAddress leaderAddress = leadingMasterInfoOpt.isPresent() ? leadingMasterInfoOpt.get().getServerAddress() : null;
                return address.equals(leaderAddress);
            } catch (IOException e) {
                return false;
            }
        }, WaitForOptions.defaults().setTimeoutMs(TIMEOUT_3MIN));
        if (!errorMessage.get().isEmpty()) {
            throw new Exception(errorMessage.get());
        }
        mPrintStream.println(String.format(TRANSFER_SUCCESS, serverAddress));
        success = true;
    } catch (Exception e) {
        mPrintStream.println(String.format(TRANSFER_FAILED, serverAddress, e.getMessage()));
    }
    // reset priorities regardless of transfer success
    try {
        mPrintStream.println(String.format(RESET_INIT, success ? "successful" : "failed"));
        jmClient.resetPriorities();
        mPrintStream.println(RESET_SUCCESS);
    } catch (IOException e) {
        mPrintStream.println(String.format(RESET_FAILED, e));
        success = false;
    }
    return success ? 0 : -1;
}
Also used : GetQuorumInfoPResponse(alluxio.grpc.GetQuorumInfoPResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) QuorumServerInfo(alluxio.grpc.QuorumServerInfo) IOException(java.io.IOException) IOException(java.io.IOException) InvalidArgumentException(alluxio.exception.status.InvalidArgumentException) JournalMasterClient(alluxio.client.journal.JournalMasterClient) NetAddress(alluxio.grpc.NetAddress)

Example 3 with QuorumServerInfo

use of alluxio.grpc.QuorumServerInfo in project alluxio by Alluxio.

the class EmbeddedJournalIntegrationTestResizing method resizeCluster.

@Test
public void resizeCluster() throws Exception {
    final int NUM_MASTERS = 5;
    final int NUM_WORKERS = 0;
    mCluster = MultiProcessCluster.newBuilder(PortCoordination.EMBEDDED_JOURNAL_RESIZE).setClusterName("EmbeddedJournalResizing_resizeCluster").setNumMasters(NUM_MASTERS).setNumWorkers(NUM_WORKERS).addProperty(PropertyKey.MASTER_JOURNAL_TYPE, JournalType.EMBEDDED.toString()).addProperty(PropertyKey.MASTER_JOURNAL_FLUSH_TIMEOUT_MS, "5min").addProperty(PropertyKey.MASTER_EMBEDDED_JOURNAL_MIN_ELECTION_TIMEOUT, "750ms").addProperty(PropertyKey.MASTER_EMBEDDED_JOURNAL_MAX_ELECTION_TIMEOUT, "1500ms").build();
    mCluster.start();
    assertEquals(5, mCluster.getJournalMasterClientForMaster().getQuorumInfo().getServerInfoList().size());
    AlluxioURI testDir = new AlluxioURI("/" + CommonUtils.randomAlphaNumString(10));
    FileSystem fs = mCluster.getFileSystemClient();
    fs.createDirectory(testDir);
    assertTrue(fs.exists(testDir));
    // Stop 2 masters. Now cluster can't tolerate any loss.
    mCluster.stopMaster(0);
    mCluster.stopMaster(1);
    // Verify cluster is still serving requests.
    assertTrue(fs.exists(testDir));
    waitForQuorumPropertySize(info -> info.getServerState() == QuorumServerState.UNAVAILABLE, 2);
    // Get and verify list of unavailable masters.
    List<NetAddress> unavailableMasters = new LinkedList<>();
    for (QuorumServerInfo serverState : mCluster.getJournalMasterClientForMaster().getQuorumInfo().getServerInfoList()) {
        if (serverState.getServerState().equals(QuorumServerState.UNAVAILABLE)) {
            unavailableMasters.add(serverState.getServerAddress());
        }
    }
    assertEquals(2, unavailableMasters.size());
    // Remove unavailable masters from quorum.
    for (NetAddress unavailableMasterAddress : unavailableMasters) {
        mCluster.getJournalMasterClientForMaster().removeQuorumServer(unavailableMasterAddress);
    }
    // Verify quorum is down to 3 masters.
    assertEquals(3, mCluster.getJournalMasterClientForMaster().getQuorumInfo().getServerInfoList().size());
    // Validate that cluster can tolerate one more master failure after resizing.
    mCluster.stopMaster(2);
    assertTrue(fs.exists(testDir));
    mCluster.notifySuccess();
}
Also used : FileSystem(alluxio.client.file.FileSystem) QuorumServerInfo(alluxio.grpc.QuorumServerInfo) LinkedList(java.util.LinkedList) AlluxioURI(alluxio.AlluxioURI) NetAddress(alluxio.grpc.NetAddress) MasterNetAddress(alluxio.multi.process.MasterNetAddress) Test(org.junit.Test)

Example 4 with QuorumServerInfo

use of alluxio.grpc.QuorumServerInfo in project alluxio by Alluxio.

the class RaftJournalSystem method getQuorumServerInfoList.

/**
 * Used to get information of internal RAFT quorum.
 *
 * @return list of information for participating servers in RAFT quorum
 */
public synchronized List<QuorumServerInfo> getQuorumServerInfoList() throws IOException {
    List<QuorumServerInfo> quorumMemberStateList = new LinkedList<>();
    GroupInfoReply groupInfo = getGroupInfo();
    if (groupInfo == null) {
        throw new UnavailableException("Cannot get raft group info");
    }
    if (groupInfo.getException() != null) {
        throw groupInfo.getException();
    }
    RaftProtos.RoleInfoProto roleInfo = groupInfo.getRoleInfoProto();
    if (roleInfo == null) {
        throw new UnavailableException("Cannot get server role info");
    }
    RaftProtos.LeaderInfoProto leaderInfo = roleInfo.getLeaderInfo();
    if (leaderInfo == null) {
        throw new UnavailableException("Cannot get server leader info");
    }
    for (RaftProtos.ServerRpcProto member : leaderInfo.getFollowerInfoList()) {
        HostAndPort hp = HostAndPort.fromString(member.getId().getAddress());
        NetAddress memberAddress = NetAddress.newBuilder().setHost(hp.getHost()).setRpcPort(hp.getPort()).build();
        quorumMemberStateList.add(QuorumServerInfo.newBuilder().setIsLeader(false).setPriority(member.getId().getPriority()).setServerAddress(memberAddress).setServerState(member.getLastRpcElapsedTimeMs() > mConf.getMaxElectionTimeoutMs() ? QuorumServerState.UNAVAILABLE : QuorumServerState.AVAILABLE).build());
    }
    InetSocketAddress localAddress = mConf.getLocalAddress();
    NetAddress self = NetAddress.newBuilder().setHost(localAddress.getHostString()).setRpcPort(localAddress.getPort()).build();
    quorumMemberStateList.add(QuorumServerInfo.newBuilder().setIsLeader(true).setPriority(roleInfo.getSelf().getPriority()).setServerAddress(self).setServerState(QuorumServerState.AVAILABLE).build());
    quorumMemberStateList.sort(Comparator.comparing(info -> info.getServerAddress().toString()));
    return quorumMemberStateList;
}
Also used : Arrays(java.util.Arrays) GroupInfoReply(org.apache.ratis.protocol.GroupInfoReply) RaftGroup(org.apache.ratis.protocol.RaftGroup) LeaderNotReadyException(org.apache.ratis.protocol.exceptions.LeaderNotReadyException) LoggerFactory(org.slf4j.LoggerFactory) TimeoutException(java.util.concurrent.TimeoutException) PropertyKey(alluxio.conf.PropertyKey) GrpcService(alluxio.grpc.GrpcService) LogUtils(alluxio.util.LogUtils) NetUtils(org.apache.ratis.util.NetUtils) JournalQueryRequest(alluxio.grpc.JournalQueryRequest) MetricKey(alluxio.metrics.MetricKey) Map(java.util.Map) RaftConfigKeys(org.apache.ratis.RaftConfigKeys) CancelledException(alluxio.exception.status.CancelledException) UnsafeByteOperations(org.apache.ratis.thirdparty.com.google.protobuf.UnsafeByteOperations) QuorumServerInfo(alluxio.grpc.QuorumServerInfo) ServerConfiguration(alluxio.conf.ServerConfiguration) RaftPeer(org.apache.ratis.protocol.RaftPeer) RetryPolicy(org.apache.ratis.retry.RetryPolicy) Master(alluxio.master.Master) Collection(java.util.Collection) AbstractJournalSystem(alluxio.master.journal.AbstractJournalSystem) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) SupportedRpcType(org.apache.ratis.rpc.SupportedRpcType) CompletionException(java.util.concurrent.CompletionException) ThreadSafe(javax.annotation.concurrent.ThreadSafe) UUID(java.util.UUID) InetSocketAddress(java.net.InetSocketAddress) Collectors(java.util.stream.Collectors) List(java.util.List) ClientId(org.apache.ratis.protocol.ClientId) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) RaftProperties(org.apache.ratis.conf.RaftProperties) ServiceType(alluxio.grpc.ServiceType) ExponentialBackoffRetry(org.apache.ratis.retry.ExponentialBackoffRetry) Optional(java.util.Optional) PrimarySelector(alluxio.master.PrimarySelector) RatisDropwizardExports(alluxio.metrics.sink.RatisDropwizardExports) AccessDeniedException(java.nio.file.AccessDeniedException) RaftClientConfigKeys(org.apache.ratis.client.RaftClientConfigKeys) UnavailableException(alluxio.exception.status.UnavailableException) TimeDuration(org.apache.ratis.util.TimeDuration) AsyncJournalWriter(alluxio.master.journal.AsyncJournalWriter) GroupInfoRequest(org.apache.ratis.protocol.GroupInfoRequest) CatchupFuture(alluxio.master.journal.CatchupFuture) SetConfigurationRequest(org.apache.ratis.protocol.SetConfigurationRequest) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) JournalEntry(alluxio.proto.journal.Journal.JournalEntry) WaitForOptions(alluxio.util.WaitForOptions) RaftGroupId(org.apache.ratis.protocol.RaftGroupId) AddQuorumServerRequest(alluxio.grpc.AddQuorumServerRequest) Message(org.apache.ratis.protocol.Message) OptionalLong(java.util.OptionalLong) Constants(alluxio.Constants) QuorumServerState(alluxio.grpc.QuorumServerState) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) MetricsSystem(alluxio.metrics.MetricsSystem) LinkedList(java.util.LinkedList) SizeInBytes(org.apache.ratis.util.SizeInBytes) Nullable(javax.annotation.Nullable) Logger(org.slf4j.Logger) NetAddress(alluxio.grpc.NetAddress) Iterator(java.util.Iterator) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RaftServerConfigKeys(org.apache.ratis.server.RaftServerConfigKeys) ExceptionMessage(alluxio.exception.ExceptionMessage) RaftProtos(org.apache.ratis.proto.RaftProtos) FileUtils(org.apache.commons.io.FileUtils) GrpcConfigKeys(org.apache.ratis.grpc.GrpcConfigKeys) RaftClientRequest(org.apache.ratis.protocol.RaftClientRequest) IOException(java.io.IOException) TransferLeaderMessage(alluxio.grpc.TransferLeaderMessage) HostAndPort(com.google.common.net.HostAndPort) File(java.io.File) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Parameters(org.apache.ratis.conf.Parameters) AtomicLong(java.util.concurrent.atomic.AtomicLong) LifeCycle(org.apache.ratis.util.LifeCycle) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) RaftServer(org.apache.ratis.server.RaftServer) RaftClient(org.apache.ratis.client.RaftClient) Comparator(java.util.Comparator) Journal(alluxio.master.journal.Journal) Collections(java.util.Collections) CommonUtils(alluxio.util.CommonUtils) InetSocketAddress(java.net.InetSocketAddress) UnavailableException(alluxio.exception.status.UnavailableException) QuorumServerInfo(alluxio.grpc.QuorumServerInfo) LinkedList(java.util.LinkedList) NetAddress(alluxio.grpc.NetAddress) HostAndPort(com.google.common.net.HostAndPort) RaftProtos(org.apache.ratis.proto.RaftProtos) GroupInfoReply(org.apache.ratis.protocol.GroupInfoReply)

Example 5 with QuorumServerInfo

use of alluxio.grpc.QuorumServerInfo in project alluxio by Alluxio.

the class SnapshotReplicationManagerTest method before.

private void before(int numFollowers) throws Exception {
    mLeader = Mockito.mock(RaftJournalSystem.class);
    Mockito.when(mLeader.isLeader()).thenReturn(true);
    Mockito.when(mLeader.getLocalPeerId()).thenReturn(RaftPeerId.getRaftPeerId("leader"));
    mLeaderStore = getSimpleStateMachineStorage();
    mLeaderSnapshotManager = Mockito.spy(new SnapshotReplicationManager(mLeader, mLeaderStore));
    String serverName = InProcessServerBuilder.generateName();
    mServer = InProcessServerBuilder.forName(serverName).directExecutor().addService(new RaftJournalServiceHandler(mLeaderSnapshotManager)).build();
    mServer.start();
    ManagedChannel channel = InProcessChannelBuilder.forName(serverName).directExecutor().build();
    RaftJournalServiceGrpc.RaftJournalServiceStub stub = RaftJournalServiceGrpc.newStub(channel);
    // mock RaftJournalServiceClient
    mClient = Mockito.mock(RaftJournalServiceClient.class);
    Mockito.doNothing().when(mClient).close();
    // download rpc mock
    Mockito.when(mClient.downloadSnapshot(any())).thenAnswer((args) -> {
        StreamObserver responseObserver = args.getArgument(0, StreamObserver.class);
        return stub.downloadSnapshot(responseObserver);
    });
    // upload rpc mock
    Mockito.when(mClient.uploadSnapshot(any())).thenAnswer((args) -> {
        StreamObserver responseObserver = args.getArgument(0, StreamObserver.class);
        return stub.uploadSnapshot(responseObserver);
    });
    Mockito.doReturn(mClient).when(mLeaderSnapshotManager).getJournalServiceClient();
    for (int i = 0; i < numFollowers; i++) {
        Follower follower = new Follower(mClient);
        mFollowers.put(follower.getRaftPeerId(), follower);
    }
    List<QuorumServerInfo> quorumServerInfos = mFollowers.values().stream().map(follower -> {
        return QuorumServerInfo.newBuilder().setServerAddress(NetAddress.newBuilder().setHost(follower.mHost).setRpcPort(follower.mRpcPort)).build();
    }).collect(Collectors.toList());
    Mockito.when(mLeader.getQuorumServerInfoList()).thenReturn(quorumServerInfos);
    Mockito.when(mLeader.sendMessageAsync(any(), any())).thenAnswer((args) -> {
        RaftPeerId peerId = args.getArgument(0, RaftPeerId.class);
        Message message = args.getArgument(1, Message.class);
        JournalQueryRequest queryRequest = JournalQueryRequest.parseFrom(message.getContent().asReadOnlyByteBuffer());
        Message response = mFollowers.get(peerId).mSnapshotManager.handleRequest(queryRequest);
        RaftClientReply reply = Mockito.mock(RaftClientReply.class);
        Mockito.when(reply.getMessage()).thenReturn(response);
        return CompletableFuture.completedFuture(reply);
    });
}
Also used : StreamObserver(io.grpc.stub.StreamObserver) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) BufferUtils(alluxio.util.io.BufferUtils) UploadSnapshotPResponse(alluxio.grpc.UploadSnapshotPResponse) TermIndex(org.apache.ratis.server.protocol.TermIndex) ManagedChannel(io.grpc.ManagedChannel) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) RandomString(net.bytebuddy.utility.RandomString) RaftJournalServiceGrpc(alluxio.grpc.RaftJournalServiceGrpc) PropertyKey(alluxio.conf.PropertyKey) InProcessServerBuilder(io.grpc.inprocess.InProcessServerBuilder) ArrayList(java.util.ArrayList) WaitForOptions(alluxio.util.WaitForOptions) Message(org.apache.ratis.protocol.Message) StreamObserver(io.grpc.stub.StreamObserver) ConfigurationRule(alluxio.ConfigurationRule) JournalQueryRequest(alluxio.grpc.JournalQueryRequest) After(org.junit.After) Map(java.util.Map) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) RaftStorage(org.apache.ratis.server.storage.RaftStorage) Status(io.grpc.Status) Server(io.grpc.Server) InProcessChannelBuilder(io.grpc.inprocess.InProcessChannelBuilder) SingleFileSnapshotInfo(org.apache.ratis.statemachine.impl.SingleFileSnapshotInfo) QuorumServerInfo(alluxio.grpc.QuorumServerInfo) ServerConfiguration(alluxio.conf.ServerConfiguration) NetAddress(alluxio.grpc.NetAddress) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RaftServerConfigKeys(org.apache.ratis.server.RaftServerConfigKeys) FileUtils(org.apache.commons.io.FileUtils) Test(org.junit.Test) IOException(java.io.IOException) SimpleStateMachineStorage(org.apache.ratis.statemachine.impl.SimpleStateMachineStorage) Collectors(java.util.stream.Collectors) StatusRuntimeException(io.grpc.StatusRuntimeException) Mockito(org.mockito.Mockito) RaftStorageImpl(org.apache.ratis.server.storage.RaftStorageImpl) List(java.util.List) Rule(org.junit.Rule) UploadSnapshotPRequest(alluxio.grpc.UploadSnapshotPRequest) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) Assert(org.junit.Assert) CommonUtils(alluxio.util.CommonUtils) TemporaryFolder(org.junit.rules.TemporaryFolder) SnapshotData(alluxio.grpc.SnapshotData) Message(org.apache.ratis.protocol.Message) QuorumServerInfo(alluxio.grpc.QuorumServerInfo) JournalQueryRequest(alluxio.grpc.JournalQueryRequest) RandomString(net.bytebuddy.utility.RandomString) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) ManagedChannel(io.grpc.ManagedChannel) RaftJournalServiceGrpc(alluxio.grpc.RaftJournalServiceGrpc) RaftPeerId(org.apache.ratis.protocol.RaftPeerId)

Aggregations

QuorumServerInfo (alluxio.grpc.QuorumServerInfo)7 NetAddress (alluxio.grpc.NetAddress)5 Collectors (java.util.stream.Collectors)5 PropertyKey (alluxio.conf.PropertyKey)4 ServerConfiguration (alluxio.conf.ServerConfiguration)4 CommonUtils (alluxio.util.CommonUtils)4 WaitForOptions (alluxio.util.WaitForOptions)4 IOException (java.io.IOException)4 List (java.util.List)4 Test (org.junit.Test)4 ExceptionMessage (alluxio.exception.ExceptionMessage)3 VisibleForTesting (com.google.common.annotations.VisibleForTesting)3 ArrayList (java.util.ArrayList)3 Arrays (java.util.Arrays)3 HashMap (java.util.HashMap)3 LinkedList (java.util.LinkedList)3 Map (java.util.Map)3 CompletableFuture (java.util.concurrent.CompletableFuture)3 After (org.junit.After)3 Assert (org.junit.Assert)3