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 */
018
019package org.apache.hadoop.hdfs.protocolPB;
020
021import java.io.IOException;
022import java.util.List;
023
024import org.apache.hadoop.hdfs.protocol.BlockListAsLongs;
025import org.apache.hadoop.hdfs.protocol.DatanodeID;
026import org.apache.hadoop.hdfs.protocol.LocatedBlock;
027import org.apache.hadoop.hdfs.protocol.RollingUpgradeStatus;
028import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.BlockReceivedAndDeletedRequestProto;
029import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.BlockReceivedAndDeletedResponseProto;
030import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.BlockReportRequestProto;
031import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.BlockReportResponseProto;
032import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.CacheReportRequestProto;
033import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.CacheReportResponseProto;
034import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.CommitBlockSynchronizationRequestProto;
035import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.CommitBlockSynchronizationResponseProto;
036import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.ErrorReportRequestProto;
037import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.ErrorReportResponseProto;
038import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.HeartbeatRequestProto;
039import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.HeartbeatResponseProto;
040import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.ReceivedDeletedBlockInfoProto;
041import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.RegisterDatanodeRequestProto;
042import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.RegisterDatanodeResponseProto;
043import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.ReportBadBlocksRequestProto;
044import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.ReportBadBlocksResponseProto;
045import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.StorageBlockReportProto;
046import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.StorageReceivedDeletedBlocksProto;
047import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.DatanodeIDProto;
048import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.LocatedBlockProto;
049import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.VersionRequestProto;
050import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.VersionResponseProto;
051import org.apache.hadoop.hdfs.server.protocol.DatanodeCommand;
052import org.apache.hadoop.hdfs.server.protocol.DatanodeProtocol;
053import org.apache.hadoop.hdfs.server.protocol.DatanodeRegistration;
054import org.apache.hadoop.hdfs.server.protocol.HeartbeatResponse;
055import org.apache.hadoop.hdfs.server.protocol.NamespaceInfo;
056import org.apache.hadoop.hdfs.server.protocol.ReceivedDeletedBlockInfo;
057import org.apache.hadoop.hdfs.server.protocol.StorageBlockReport;
058import org.apache.hadoop.hdfs.server.protocol.StorageReceivedDeletedBlocks;
059import org.apache.hadoop.hdfs.server.protocol.StorageReport;
060import org.apache.hadoop.hdfs.server.protocol.VolumeFailureSummary;
061
062import com.google.common.base.Preconditions;
063import com.google.protobuf.RpcController;
064import com.google.protobuf.ServiceException;
065
066public class DatanodeProtocolServerSideTranslatorPB implements
067    DatanodeProtocolPB {
068
069  private final DatanodeProtocol impl;
070  private static final ErrorReportResponseProto
071      VOID_ERROR_REPORT_RESPONSE_PROTO = 
072          ErrorReportResponseProto.newBuilder().build();
073  private static final BlockReceivedAndDeletedResponseProto 
074      VOID_BLOCK_RECEIVED_AND_DELETE_RESPONSE = 
075          BlockReceivedAndDeletedResponseProto.newBuilder().build();
076  private static final ReportBadBlocksResponseProto
077      VOID_REPORT_BAD_BLOCK_RESPONSE = 
078          ReportBadBlocksResponseProto.newBuilder().build();
079  private static final CommitBlockSynchronizationResponseProto 
080      VOID_COMMIT_BLOCK_SYNCHRONIZATION_RESPONSE_PROTO =
081          CommitBlockSynchronizationResponseProto.newBuilder().build();
082
083  public DatanodeProtocolServerSideTranslatorPB(DatanodeProtocol impl) {
084    this.impl = impl;
085  }
086
087  @Override
088  public RegisterDatanodeResponseProto registerDatanode(
089      RpcController controller, RegisterDatanodeRequestProto request)
090      throws ServiceException {
091    DatanodeRegistration registration = PBHelper.convert(request
092        .getRegistration());
093    DatanodeRegistration registrationResp;
094    try {
095      registrationResp = impl.registerDatanode(registration);
096    } catch (IOException e) {
097      throw new ServiceException(e);
098    }
099    return RegisterDatanodeResponseProto.newBuilder()
100        .setRegistration(PBHelper.convert(registrationResp)).build();
101  }
102
103  @Override
104  public HeartbeatResponseProto sendHeartbeat(RpcController controller,
105      HeartbeatRequestProto request) throws ServiceException {
106    HeartbeatResponse response;
107    try {
108      final StorageReport[] report = PBHelper.convertStorageReports(
109          request.getReportsList());
110      VolumeFailureSummary volumeFailureSummary =
111          request.hasVolumeFailureSummary() ? PBHelper.convertVolumeFailureSummary(
112              request.getVolumeFailureSummary()) : null;
113      response = impl.sendHeartbeat(PBHelper.convert(request.getRegistration()),
114          report, request.getCacheCapacity(), request.getCacheUsed(),
115          request.getXmitsInProgress(),
116          request.getXceiverCount(), request.getFailedVolumes(),
117          volumeFailureSummary);
118    } catch (IOException e) {
119      throw new ServiceException(e);
120    }
121    HeartbeatResponseProto.Builder builder = HeartbeatResponseProto
122        .newBuilder();
123    DatanodeCommand[] cmds = response.getCommands();
124    if (cmds != null) {
125      for (int i = 0; i < cmds.length; i++) {
126        if (cmds[i] != null) {
127          builder.addCmds(PBHelper.convert(cmds[i]));
128        }
129      }
130    }
131    builder.setHaStatus(PBHelper.convert(response.getNameNodeHaState()));
132    RollingUpgradeStatus rollingUpdateStatus = response
133        .getRollingUpdateStatus();
134    if (rollingUpdateStatus != null) {
135      builder.setRollingUpgradeStatus(PBHelper
136          .convertRollingUpgradeStatus(rollingUpdateStatus));
137    }
138    return builder.build();
139  }
140
141  @Override
142  public BlockReportResponseProto blockReport(RpcController controller,
143      BlockReportRequestProto request) throws ServiceException {
144    DatanodeCommand cmd = null;
145    StorageBlockReport[] report = 
146        new StorageBlockReport[request.getReportsCount()];
147    
148    int index = 0;
149    for (StorageBlockReportProto s : request.getReportsList()) {
150      final BlockListAsLongs blocks;
151      if (s.hasNumberOfBlocks()) { // new style buffer based reports
152        int num = (int)s.getNumberOfBlocks();
153        Preconditions.checkState(s.getBlocksCount() == 0,
154            "cannot send both blocks list and buffers");
155        blocks = BlockListAsLongs.decodeBuffers(num, s.getBlocksBuffersList());
156      } else {
157        blocks = BlockListAsLongs.decodeLongs(s.getBlocksList());
158      }
159      report[index++] = new StorageBlockReport(PBHelper.convert(s.getStorage()),
160          blocks);
161    }
162    try {
163      cmd = impl.blockReport(PBHelper.convert(request.getRegistration()),
164          request.getBlockPoolId(), report,
165          request.hasContext() ?
166              PBHelper.convert(request.getContext()) : null);
167    } catch (IOException e) {
168      throw new ServiceException(e);
169    }
170    BlockReportResponseProto.Builder builder = 
171        BlockReportResponseProto.newBuilder();
172    if (cmd != null) {
173      builder.setCmd(PBHelper.convert(cmd));
174    }
175    return builder.build();
176  }
177
178  @Override
179  public CacheReportResponseProto cacheReport(RpcController controller,
180      CacheReportRequestProto request) throws ServiceException {
181    DatanodeCommand cmd = null;
182    try {
183      cmd = impl.cacheReport(
184          PBHelper.convert(request.getRegistration()),
185          request.getBlockPoolId(),
186          request.getBlocksList());
187    } catch (IOException e) {
188      throw new ServiceException(e);
189    }
190    CacheReportResponseProto.Builder builder =
191        CacheReportResponseProto.newBuilder();
192    if (cmd != null) {
193      builder.setCmd(PBHelper.convert(cmd));
194    }
195    return builder.build();
196  }
197
198
199  @Override
200  public BlockReceivedAndDeletedResponseProto blockReceivedAndDeleted(
201      RpcController controller, BlockReceivedAndDeletedRequestProto request)
202      throws ServiceException {
203    List<StorageReceivedDeletedBlocksProto> sBlocks = request.getBlocksList();
204    StorageReceivedDeletedBlocks[] info = 
205        new StorageReceivedDeletedBlocks[sBlocks.size()];
206    for (int i = 0; i < sBlocks.size(); i++) {
207      StorageReceivedDeletedBlocksProto sBlock = sBlocks.get(i);
208      List<ReceivedDeletedBlockInfoProto> list = sBlock.getBlocksList();
209      ReceivedDeletedBlockInfo[] rdBlocks = 
210          new ReceivedDeletedBlockInfo[list.size()];
211      for (int j = 0; j < list.size(); j++) {
212        rdBlocks[j] = PBHelper.convert(list.get(j));
213      }
214      if (sBlock.hasStorage()) {
215        info[i] = new StorageReceivedDeletedBlocks(
216            PBHelper.convert(sBlock.getStorage()), rdBlocks);
217      } else {
218        info[i] = new StorageReceivedDeletedBlocks(sBlock.getStorageUuid(), rdBlocks);
219      }
220    }
221    try {
222      impl.blockReceivedAndDeleted(PBHelper.convert(request.getRegistration()),
223          request.getBlockPoolId(), info);
224    } catch (IOException e) {
225      throw new ServiceException(e);
226    }
227    return VOID_BLOCK_RECEIVED_AND_DELETE_RESPONSE;
228  }
229
230  @Override
231  public ErrorReportResponseProto errorReport(RpcController controller,
232      ErrorReportRequestProto request) throws ServiceException {
233    try {
234      impl.errorReport(PBHelper.convert(request.getRegistartion()),
235          request.getErrorCode(), request.getMsg());
236    } catch (IOException e) {
237      throw new ServiceException(e);
238    }
239    return VOID_ERROR_REPORT_RESPONSE_PROTO;
240  }
241
242  @Override
243  public VersionResponseProto versionRequest(RpcController controller,
244      VersionRequestProto request) throws ServiceException {
245    NamespaceInfo info;
246    try {
247      info = impl.versionRequest();
248    } catch (IOException e) {
249      throw new ServiceException(e);
250    }
251    return VersionResponseProto.newBuilder()
252        .setInfo(PBHelper.convert(info)).build();
253  }
254
255  @Override
256  public ReportBadBlocksResponseProto reportBadBlocks(RpcController controller,
257      ReportBadBlocksRequestProto request) throws ServiceException {
258    List<LocatedBlockProto> lbps = request.getBlocksList();
259    LocatedBlock [] blocks = new LocatedBlock [lbps.size()];
260    for(int i=0; i<lbps.size(); i++) {
261      blocks[i] = PBHelper.convert(lbps.get(i));
262    }
263    try {
264      impl.reportBadBlocks(blocks);
265    } catch (IOException e) {
266      throw new ServiceException(e);
267    }
268    return VOID_REPORT_BAD_BLOCK_RESPONSE;
269  }
270
271  @Override
272  public CommitBlockSynchronizationResponseProto commitBlockSynchronization(
273      RpcController controller, CommitBlockSynchronizationRequestProto request)
274      throws ServiceException {
275    List<DatanodeIDProto> dnprotos = request.getNewTaragetsList();
276    DatanodeID[] dns = new DatanodeID[dnprotos.size()];
277    for (int i = 0; i < dnprotos.size(); i++) {
278      dns[i] = PBHelper.convert(dnprotos.get(i));
279    }
280    final List<String> sidprotos = request.getNewTargetStoragesList();
281    final String[] storageIDs = sidprotos.toArray(new String[sidprotos.size()]);
282    try {
283      impl.commitBlockSynchronization(PBHelper.convert(request.getBlock()),
284          request.getNewGenStamp(), request.getNewLength(),
285          request.getCloseFile(), request.getDeleteBlock(), dns, storageIDs);
286    } catch (IOException e) {
287      throw new ServiceException(e);
288    }
289    return VOID_COMMIT_BLOCK_SYNCHRONIZATION_RESPONSE_PROTO;
290  }
291}