use of org.apache.hadoop.ozone.protocol.commands.CreatePipelineCommand in project ozone by apache.
the class TestCreatePipelineCommandHandler method testCommandIdempotency.
@Test
public void testCommandIdempotency() throws IOException {
final List<DatanodeDetails> datanodes = getDatanodes();
final PipelineID pipelineID = PipelineID.randomId();
final SCMCommand<CreatePipelineCommandProto> command = new CreatePipelineCommand(pipelineID, HddsProtos.ReplicationType.RATIS, HddsProtos.ReplicationFactor.THREE, datanodes);
final XceiverServerSpi writeChanel = Mockito.mock(XceiverServerSpi.class);
final DatanodeStateMachine dnsm = Mockito.mock(DatanodeStateMachine.class);
Mockito.when(stateContext.getParent()).thenReturn(dnsm);
Mockito.when(dnsm.getDatanodeDetails()).thenReturn(datanodes.get(0));
Mockito.when(ozoneContainer.getWriteChannel()).thenReturn(writeChanel);
Mockito.when(writeChanel.isExist(pipelineID.getProtobuf())).thenReturn(true);
final CreatePipelineCommandHandler commandHandler = new CreatePipelineCommandHandler(new OzoneConfiguration());
commandHandler.handle(command, ozoneContainer, stateContext, connectionManager);
Mockito.verify(writeChanel, Mockito.times(0)).addGroup(pipelineID.getProtobuf(), datanodes);
Mockito.verify(raftClientGroupManager, Mockito.times(0)).add(Mockito.any(RaftGroup.class));
}
use of org.apache.hadoop.ozone.protocol.commands.CreatePipelineCommand in project ozone by apache.
the class TestCreatePipelineCommandHandler method testPipelineCreation.
@Test
public void testPipelineCreation() throws IOException {
final List<DatanodeDetails> datanodes = getDatanodes();
final PipelineID pipelineID = PipelineID.randomId();
final SCMCommand<CreatePipelineCommandProto> command = new CreatePipelineCommand(pipelineID, HddsProtos.ReplicationType.RATIS, HddsProtos.ReplicationFactor.THREE, datanodes);
final XceiverServerSpi writeChanel = Mockito.mock(XceiverServerSpi.class);
final DatanodeStateMachine dnsm = Mockito.mock(DatanodeStateMachine.class);
Mockito.when(stateContext.getParent()).thenReturn(dnsm);
Mockito.when(dnsm.getDatanodeDetails()).thenReturn(datanodes.get(0));
Mockito.when(ozoneContainer.getWriteChannel()).thenReturn(writeChanel);
Mockito.when(writeChanel.isExist(pipelineID.getProtobuf())).thenReturn(false);
final CreatePipelineCommandHandler commandHandler = new CreatePipelineCommandHandler(new OzoneConfiguration());
commandHandler.handle(command, ozoneContainer, stateContext, connectionManager);
List<Integer> priorityList = new ArrayList<>(Collections.nCopies(datanodes.size(), 0));
Mockito.verify(writeChanel, Mockito.times(1)).addGroup(pipelineID.getProtobuf(), datanodes, priorityList);
Mockito.verify(raftClientGroupManager, Mockito.times(2)).add(Mockito.any(RaftGroup.class));
}
use of org.apache.hadoop.ozone.protocol.commands.CreatePipelineCommand in project ozone by apache.
the class HeartbeatEndpointTask method processResponse.
/**
* Add this command to command processing Queue.
*
* @param response - SCMHeartbeat response.
*/
private void processResponse(SCMHeartbeatResponseProto response, final DatanodeDetailsProto datanodeDetails) {
Preconditions.checkState(response.getDatanodeUUID().equalsIgnoreCase(datanodeDetails.getUuid()), "Unexpected datanode ID in the response.");
// Verify the response is indeed for this datanode.
for (SCMCommandProto commandResponseProto : response.getCommandsList()) {
switch(commandResponseProto.getCommandType()) {
case reregisterCommand:
if (rpcEndpoint.getState() == EndPointStates.HEARTBEAT) {
if (LOG.isDebugEnabled()) {
LOG.debug("Received SCM notification to register." + " Interrupt HEARTBEAT and transit to REGISTER state.");
}
rpcEndpoint.setState(EndPointStates.REGISTER);
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Illegal state {} found, expecting {}.", rpcEndpoint.getState().name(), EndPointStates.HEARTBEAT);
}
}
break;
case deleteBlocksCommand:
DeleteBlocksCommand deleteBlocksCommand = DeleteBlocksCommand.getFromProtobuf(commandResponseProto.getDeleteBlocksCommandProto());
if (commandResponseProto.hasTerm()) {
deleteBlocksCommand.setTerm(commandResponseProto.getTerm());
}
if (!deleteBlocksCommand.blocksTobeDeleted().isEmpty()) {
if (LOG.isDebugEnabled()) {
LOG.debug(DeletedContainerBlocksSummary.getFrom(deleteBlocksCommand.blocksTobeDeleted()).toString());
}
this.context.addCommand(deleteBlocksCommand);
}
break;
case closeContainerCommand:
CloseContainerCommand closeContainer = CloseContainerCommand.getFromProtobuf(commandResponseProto.getCloseContainerCommandProto());
if (commandResponseProto.hasTerm()) {
closeContainer.setTerm(commandResponseProto.getTerm());
}
if (commandResponseProto.hasEncodedToken()) {
closeContainer.setEncodedToken(commandResponseProto.getEncodedToken());
}
if (LOG.isDebugEnabled()) {
LOG.debug("Received SCM container close request for container {}", closeContainer.getContainerID());
}
this.context.addCommand(closeContainer);
break;
case replicateContainerCommand:
ReplicateContainerCommand replicateContainerCommand = ReplicateContainerCommand.getFromProtobuf(commandResponseProto.getReplicateContainerCommandProto());
if (commandResponseProto.hasTerm()) {
replicateContainerCommand.setTerm(commandResponseProto.getTerm());
}
if (LOG.isDebugEnabled()) {
LOG.debug("Received SCM container replicate request for container {}", replicateContainerCommand.getContainerID());
}
this.context.addCommand(replicateContainerCommand);
break;
case deleteContainerCommand:
DeleteContainerCommand deleteContainerCommand = DeleteContainerCommand.getFromProtobuf(commandResponseProto.getDeleteContainerCommandProto());
if (commandResponseProto.hasTerm()) {
deleteContainerCommand.setTerm(commandResponseProto.getTerm());
}
if (LOG.isDebugEnabled()) {
LOG.debug("Received SCM delete container request for container {}", deleteContainerCommand.getContainerID());
}
this.context.addCommand(deleteContainerCommand);
break;
case createPipelineCommand:
CreatePipelineCommand createPipelineCommand = CreatePipelineCommand.getFromProtobuf(commandResponseProto.getCreatePipelineCommandProto());
if (commandResponseProto.hasTerm()) {
createPipelineCommand.setTerm(commandResponseProto.getTerm());
}
if (LOG.isDebugEnabled()) {
LOG.debug("Received SCM create pipeline request {}", createPipelineCommand.getPipelineID());
}
this.context.addCommand(createPipelineCommand);
break;
case closePipelineCommand:
ClosePipelineCommand closePipelineCommand = ClosePipelineCommand.getFromProtobuf(commandResponseProto.getClosePipelineCommandProto());
if (commandResponseProto.hasTerm()) {
closePipelineCommand.setTerm(commandResponseProto.getTerm());
}
if (LOG.isDebugEnabled()) {
LOG.debug("Received SCM close pipeline request {}", closePipelineCommand.getPipelineID());
}
this.context.addCommand(closePipelineCommand);
break;
case setNodeOperationalStateCommand:
SetNodeOperationalStateCommand setNodeOperationalStateCommand = SetNodeOperationalStateCommand.getFromProtobuf(commandResponseProto.getSetNodeOperationalStateCommandProto());
if (commandResponseProto.hasTerm()) {
setNodeOperationalStateCommand.setTerm(commandResponseProto.getTerm());
}
if (LOG.isDebugEnabled()) {
LOG.debug("Received SCM set operational state command. State: {} " + "Expiry: {}", setNodeOperationalStateCommand.getOpState(), setNodeOperationalStateCommand.getStateExpiryEpochSeconds());
}
this.context.addCommand(setNodeOperationalStateCommand);
break;
case finalizeNewLayoutVersionCommand:
FinalizeNewLayoutVersionCommand finalizeNewLayoutVersionCommand = FinalizeNewLayoutVersionCommand.getFromProtobuf(commandResponseProto.getFinalizeNewLayoutVersionCommandProto());
if (commandResponseProto.hasTerm()) {
finalizeNewLayoutVersionCommand.setTerm(commandResponseProto.getTerm());
}
if (LOG.isDebugEnabled()) {
LOG.debug("Received SCM finalize command {}", finalizeNewLayoutVersionCommand.getId());
}
this.context.addCommand(finalizeNewLayoutVersionCommand);
break;
case refreshVolumeUsageInfo:
RefreshVolumeUsageCommand refreshVolumeUsageCommand = RefreshVolumeUsageCommand.getFromProtobuf(commandResponseProto.getRefreshVolumeUsageCommandProto());
if (commandResponseProto.hasTerm()) {
refreshVolumeUsageCommand.setTerm(commandResponseProto.getTerm());
}
this.context.addCommand(refreshVolumeUsageCommand);
break;
default:
throw new IllegalArgumentException("Unknown response : " + commandResponseProto.getCommandType().name());
}
}
}
use of org.apache.hadoop.ozone.protocol.commands.CreatePipelineCommand in project ozone by apache.
the class CreatePipelineCommandHandler method handle.
/**
* Handles a given SCM command.
*
* @param command - SCM Command
* @param ozoneContainer - Ozone Container.
* @param context - Current Context.
* @param connectionManager - The SCMs that we are talking to.
*/
@Override
public void handle(SCMCommand command, OzoneContainer ozoneContainer, StateContext context, SCMConnectionManager connectionManager) {
invocationCount.incrementAndGet();
final long startTime = Time.monotonicNow();
final DatanodeDetails dn = context.getParent().getDatanodeDetails();
final CreatePipelineCommand createCommand = (CreatePipelineCommand) command;
final PipelineID pipelineID = createCommand.getPipelineID();
final HddsProtos.PipelineID pipelineIdProto = pipelineID.getProtobuf();
final List<DatanodeDetails> peers = createCommand.getNodeList();
final List<Integer> priorityList = createCommand.getPriorityList();
try {
XceiverServerSpi server = ozoneContainer.getWriteChannel();
if (!server.isExist(pipelineIdProto)) {
final RaftGroupId groupId = RaftGroupId.valueOf(pipelineID.getId());
final RaftGroup group = RatisHelper.newRaftGroup(groupId, peers, priorityList);
server.addGroup(pipelineIdProto, peers, priorityList);
peers.stream().filter(d -> !d.getUuid().equals(dn.getUuid())).forEach(d -> {
final RaftPeer peer = RatisHelper.toRaftPeer(d);
try (RaftClient client = RatisHelper.newRaftClient(peer, conf, ozoneContainer.getTlsClientConfig())) {
client.getGroupManagementApi(peer.getId()).add(group);
} catch (AlreadyExistsException ae) {
// do not log
} catch (IOException ioe) {
LOG.warn("Add group failed for {}", d, ioe);
}
});
LOG.info("Created Pipeline {} {} {}.", createCommand.getReplicationType(), createCommand.getFactor(), pipelineID);
}
} catch (IOException e) {
// from another peer, so we may got an AlreadyExistsException.
if (!(e.getCause() instanceof AlreadyExistsException)) {
LOG.error("Can't create pipeline {} {} {}", createCommand.getReplicationType(), createCommand.getFactor(), pipelineID, e);
}
} finally {
long endTime = Time.monotonicNow();
totalTime += endTime - startTime;
}
}
use of org.apache.hadoop.ozone.protocol.commands.CreatePipelineCommand in project ozone by apache.
the class RatisPipelineProvider method create.
@Override
public synchronized Pipeline create(RatisReplicationConfig replicationConfig) throws IOException {
if (exceedPipelineNumberLimit(replicationConfig)) {
throw new SCMException("Ratis pipeline number meets the limit: " + pipelineNumberLimit + " replicationConfig : " + replicationConfig, SCMException.ResultCodes.FAILED_TO_FIND_SUITABLE_NODE);
}
List<DatanodeDetails> dns;
final ReplicationFactor factor = replicationConfig.getReplicationFactor();
switch(factor) {
case ONE:
dns = pickNodesNotUsed(replicationConfig, minRatisVolumeSizeBytes, containerSizeBytes);
break;
case THREE:
dns = placementPolicy.chooseDatanodes(null, null, factor.getNumber(), minRatisVolumeSizeBytes, containerSizeBytes);
break;
default:
throw new IllegalStateException("Unknown factor: " + factor.name());
}
DatanodeDetails suggestedLeader = leaderChoosePolicy.chooseLeader(dns);
Pipeline pipeline = Pipeline.newBuilder().setId(PipelineID.randomId()).setState(PipelineState.ALLOCATED).setReplicationConfig(RatisReplicationConfig.getInstance(factor)).setNodes(dns).setSuggestedLeaderId(suggestedLeader != null ? suggestedLeader.getUuid() : null).build();
// Send command to datanodes to create pipeline
final CreatePipelineCommand createCommand = suggestedLeader != null ? new CreatePipelineCommand(pipeline.getId(), pipeline.getType(), factor, dns, suggestedLeader) : new CreatePipelineCommand(pipeline.getId(), pipeline.getType(), factor, dns);
createCommand.setTerm(scmContext.getTermOfLeader());
dns.forEach(node -> {
LOG.info("Sending CreatePipelineCommand for pipeline:{} to datanode:{}", pipeline.getId(), node.getUuidString());
eventPublisher.fireEvent(SCMEvents.DATANODE_COMMAND, new CommandForDatanode<>(node.getUuid(), createCommand));
});
return pipeline;
}
Aggregations