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