001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.master.replication;
019
020import java.io.IOException;
021import java.util.Optional;
022import org.apache.hadoop.hbase.ServerName;
023import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;
024import org.apache.hadoop.hbase.master.procedure.PeerProcedureInterface;
025import org.apache.hadoop.hbase.master.procedure.RSProcedureDispatcher.ServerOperation;
026import org.apache.hadoop.hbase.master.procedure.ServerRemoteProcedure;
027import org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer;
028import org.apache.hadoop.hbase.procedure2.RemoteProcedureDispatcher.RemoteOperation;
029import org.apache.hadoop.hbase.procedure2.RemoteProcedureDispatcher.RemoteProcedure;
030import org.apache.hadoop.hbase.replication.regionserver.RefreshPeerCallable;
031import org.apache.yetus.audience.InterfaceAudience;
032import org.slf4j.Logger;
033import org.slf4j.LoggerFactory;
034
035import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
036import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.PeerModificationType;
037import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RefreshPeerParameter;
038import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RefreshPeerStateData;
039
040@InterfaceAudience.Private
041public class RefreshPeerProcedure extends ServerRemoteProcedure
042  implements PeerProcedureInterface, RemoteProcedure<MasterProcedureEnv, ServerName> {
043
044  private static final Logger LOG = LoggerFactory.getLogger(RefreshPeerProcedure.class);
045
046  private String peerId;
047
048  private PeerOperationType type;
049
050  private int stage;
051
052  public RefreshPeerProcedure() {
053  }
054
055  public RefreshPeerProcedure(String peerId, PeerOperationType type, ServerName targetServer) {
056    this(peerId, type, targetServer, 0);
057  }
058
059  public RefreshPeerProcedure(String peerId, PeerOperationType type, ServerName targetServer,
060    int stage) {
061    this.peerId = peerId;
062    this.type = type;
063    this.targetServer = targetServer;
064    this.stage = stage;
065  }
066
067  @Override
068  public String getPeerId() {
069    return peerId;
070  }
071
072  @Override
073  public PeerOperationType getPeerOperationType() {
074    return PeerOperationType.REFRESH;
075  }
076
077  private static PeerModificationType toPeerModificationType(PeerOperationType type) {
078    switch (type) {
079      case ADD:
080        return PeerModificationType.ADD_PEER;
081      case REMOVE:
082        return PeerModificationType.REMOVE_PEER;
083      case ENABLE:
084        return PeerModificationType.ENABLE_PEER;
085      case DISABLE:
086        return PeerModificationType.DISABLE_PEER;
087      case UPDATE_CONFIG:
088        return PeerModificationType.UPDATE_PEER_CONFIG;
089      case TRANSIT_SYNC_REPLICATION_STATE:
090        return PeerModificationType.TRANSIT_SYNC_REPLICATION_STATE;
091      default:
092        throw new IllegalArgumentException("Unknown type: " + type);
093    }
094  }
095
096  private static PeerOperationType toPeerOperationType(PeerModificationType type) {
097    switch (type) {
098      case ADD_PEER:
099        return PeerOperationType.ADD;
100      case REMOVE_PEER:
101        return PeerOperationType.REMOVE;
102      case ENABLE_PEER:
103        return PeerOperationType.ENABLE;
104      case DISABLE_PEER:
105        return PeerOperationType.DISABLE;
106      case UPDATE_PEER_CONFIG:
107        return PeerOperationType.UPDATE_CONFIG;
108      case TRANSIT_SYNC_REPLICATION_STATE:
109        return PeerOperationType.TRANSIT_SYNC_REPLICATION_STATE;
110      default:
111        throw new IllegalArgumentException("Unknown type: " + type);
112    }
113  }
114
115  @Override
116  public Optional<RemoteOperation> remoteCallBuild(MasterProcedureEnv env, ServerName remote) {
117    assert targetServer.equals(remote);
118    return Optional.of(new ServerOperation(this, getProcId(), RefreshPeerCallable.class,
119      RefreshPeerParameter.newBuilder().setPeerId(peerId).setType(toPeerModificationType(type))
120        .setTargetServer(ProtobufUtil.toServerName(remote)).setStage(stage).build().toByteArray()));
121  }
122
123  @Override
124  protected void complete(MasterProcedureEnv env, Throwable error) {
125    if (error != null) {
126      LOG.warn("Refresh peer {} for {} on {} failed", peerId, type, targetServer, error);
127      this.succ = false;
128    } else {
129      LOG.info("Refresh peer {} for {} on {} suceeded", peerId, type, targetServer);
130      this.succ = true;
131    }
132  }
133
134  @Override
135  protected void rollback(MasterProcedureEnv env) throws IOException, InterruptedException {
136    throw new UnsupportedOperationException();
137  }
138
139  @Override
140  protected boolean abort(MasterProcedureEnv env) {
141    // TODO: no correctness problem if we just ignore this, implement later.
142    return false;
143  }
144
145  @Override
146  protected boolean waitInitialized(MasterProcedureEnv env) {
147    return env.waitInitialized(this);
148  }
149
150  @Override
151  protected void serializeStateData(ProcedureStateSerializer serializer) throws IOException {
152    serializer.serialize(
153      RefreshPeerStateData.newBuilder().setPeerId(peerId).setType(toPeerModificationType(type))
154        .setTargetServer(ProtobufUtil.toServerName(targetServer)).setStage(stage).build());
155  }
156
157  @Override
158  protected void deserializeStateData(ProcedureStateSerializer serializer) throws IOException {
159    RefreshPeerStateData data = serializer.deserialize(RefreshPeerStateData.class);
160    peerId = data.getPeerId();
161    type = toPeerOperationType(data.getType());
162    targetServer = ProtobufUtil.toServerName(data.getTargetServer());
163    stage = data.getStage();
164  }
165}