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.namequeues;
019
020import static org.junit.Assert.assertArrayEquals;
021import static org.junit.Assert.assertEquals;
022import static org.junit.Assert.assertFalse;
023
024import java.io.IOException;
025import java.net.InetAddress;
026import java.nio.ByteBuffer;
027import java.security.cert.X509Certificate;
028import java.util.Arrays;
029import java.util.Collections;
030import java.util.Map;
031import java.util.Optional;
032import org.apache.hadoop.hbase.CellScanner;
033import org.apache.hadoop.hbase.HBaseClassTestRule;
034import org.apache.hadoop.hbase.ipc.RpcCall;
035import org.apache.hadoop.hbase.ipc.RpcCallback;
036import org.apache.hadoop.hbase.security.User;
037import org.apache.hadoop.hbase.testclassification.RegionServerTests;
038import org.apache.hadoop.hbase.testclassification.SmallTests;
039import org.apache.hadoop.hbase.util.Bytes;
040import org.junit.ClassRule;
041import org.junit.Test;
042import org.junit.experimental.categories.Category;
043
044import org.apache.hbase.thirdparty.com.google.protobuf.BlockingService;
045import org.apache.hbase.thirdparty.com.google.protobuf.ByteString;
046import org.apache.hbase.thirdparty.com.google.protobuf.CodedInputStream;
047import org.apache.hbase.thirdparty.com.google.protobuf.Descriptors;
048import org.apache.hbase.thirdparty.com.google.protobuf.Message;
049import org.apache.hbase.thirdparty.com.google.protobuf.UnsafeByteOperations;
050
051import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
052import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos;
053import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;
054import org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos;
055
056@Category({ RegionServerTests.class, SmallTests.class })
057public class TestRpcLogDetails {
058
059  @ClassRule
060  public static final HBaseClassTestRule CLASS_RULE =
061    HBaseClassTestRule.forClass(TestRpcLogDetails.class);
062
063  private final ClientProtos.Scan scan =
064    ClientProtos.Scan.newBuilder().setStartRow(ByteString.copyFrom(Bytes.toBytes("abc")))
065      .setStopRow(ByteString.copyFrom(Bytes.toBytes("xyz"))).build();
066  private final ClientProtos.Scan otherScan =
067    ClientProtos.Scan.newBuilder().setStartRow(ByteString.copyFrom(Bytes.toBytes("def")))
068      .setStopRow(ByteString.copyFrom(Bytes.toBytes("uvw"))).build();
069  private final ClientProtos.ScanRequest scanRequest = ClientProtos.ScanRequest
070    .newBuilder(ClientProtos.ScanRequest.getDefaultInstance()).setScan(scan).build();
071  private final ClientProtos.ScanRequest otherScanRequest = ClientProtos.ScanRequest
072    .newBuilder(ClientProtos.ScanRequest.getDefaultInstance()).setScan(otherScan).build();
073
074  @Test
075  public void itDeepCopiesRpcLogDetailsParams() throws IOException {
076    ByteBuffer buffer = ByteBuffer.allocate(scanRequest.toByteArray().length);
077    CodedInputStream cis = UnsafeByteOperations.unsafeWrap(buffer).newCodedInput();
078    cis.enableAliasing(true);
079    buffer.put(scanRequest.toByteArray());
080    Message.Builder messageBuilder = ClientProtos.ScanRequest.newBuilder();
081    ProtobufUtil.mergeFrom(messageBuilder, cis, buffer.capacity());
082    Message message = messageBuilder.build();
083    RpcLogDetails rpcLogDetails =
084      new RpcLogDetails(getRpcCall(message), message, null, 0L, 0L, 0, null, true, false);
085
086    // log's scan should be equal
087    ClientProtos.Scan logScan = ((ClientProtos.ScanRequest) rpcLogDetails.getParam()).getScan();
088    assertEquals(logScan, scan);
089
090    // ensure we have a different byte array for testing
091    assertFalse(Arrays.equals(scanRequest.toByteArray(), otherScanRequest.toByteArray()));
092
093    // corrupt the underlying buffer
094    buffer.position(0);
095    buffer.put(otherScanRequest.toByteArray(), 0, otherScanRequest.toByteArray().length);
096    assertArrayEquals(otherScanRequest.toByteArray(), buffer.array());
097
098    // log scan should still be original scan
099    assertEquals(logScan, scan);
100  }
101
102  @SuppressWarnings("checkstyle:methodlength")
103  private static RpcCall getRpcCall(Message message) {
104    RpcCall rpcCall = new RpcCall() {
105      @Override
106      public BlockingService getService() {
107        return null;
108      }
109
110      @Override
111      public Descriptors.MethodDescriptor getMethod() {
112        return null;
113      }
114
115      @Override
116      public Message getParam() {
117        return message;
118      }
119
120      @Override
121      public CellScanner getCellScanner() {
122        return null;
123      }
124
125      @Override
126      public long getReceiveTime() {
127        return 0;
128      }
129
130      @Override
131      public long getStartTime() {
132        return 0;
133      }
134
135      @Override
136      public void setStartTime(long startTime) {
137      }
138
139      @Override
140      public int getTimeout() {
141        return 0;
142      }
143
144      @Override
145      public int getPriority() {
146        return 0;
147      }
148
149      @Override
150      public long getDeadline() {
151        return 0;
152      }
153
154      @Override
155      public long getSize() {
156        return 0;
157      }
158
159      @Override
160      public RPCProtos.RequestHeader getHeader() {
161        return null;
162      }
163
164      @Override
165      public Map<String, byte[]> getConnectionAttributes() {
166        return Collections.emptyMap();
167      }
168
169      @Override
170      public Map<String, byte[]> getRequestAttributes() {
171        return Collections.emptyMap();
172      }
173
174      @Override
175      public byte[] getRequestAttribute(String key) {
176        return null;
177      }
178
179      @Override
180      public int getRemotePort() {
181        return 0;
182      }
183
184      @Override
185      public void setResponse(Message param, CellScanner cells, Throwable errorThrowable,
186        String error) {
187      }
188
189      @Override
190      public void sendResponseIfReady() throws IOException {
191      }
192
193      @Override
194      public void cleanup() {
195      }
196
197      @Override
198      public String toShortString() {
199        return null;
200      }
201
202      @Override
203      public long disconnectSince() {
204        return 0;
205      }
206
207      @Override
208      public boolean isClientCellBlockSupported() {
209        return false;
210      }
211
212      @Override
213      public Optional<User> getRequestUser() {
214        return null;
215      }
216
217      @Override
218      public Optional<X509Certificate[]> getClientCertificateChain() {
219        return Optional.empty();
220      }
221
222      @Override
223      public InetAddress getRemoteAddress() {
224        return null;
225      }
226
227      @Override
228      public HBaseProtos.VersionInfo getClientVersionInfo() {
229        return null;
230      }
231
232      @Override
233      public void setCallBack(RpcCallback callback) {
234      }
235
236      @Override
237      public boolean isRetryImmediatelySupported() {
238        return false;
239      }
240
241      @Override
242      public long getResponseCellSize() {
243        return 0;
244      }
245
246      @Override
247      public void incrementResponseCellSize(long cellSize) {
248      }
249
250      @Override
251      public long getBlockBytesScanned() {
252        return 0;
253      }
254
255      @Override
256      public void incrementBlockBytesScanned(long blockSize) {
257      }
258
259      @Override
260      public long getResponseExceptionSize() {
261        return 0;
262      }
263
264      @Override
265      public void incrementResponseExceptionSize(long exceptionSize) {
266      }
267
268      @Override
269      public void updateFsReadTime(long latencyMillis) {
270
271      }
272
273      @Override
274      public long getFsReadTime() {
275        return 0;
276      }
277    };
278    return rpcCall;
279  }
280
281}