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.client;
019
020import static org.junit.jupiter.api.Assertions.assertEquals;
021import static org.junit.jupiter.api.Assertions.assertSame;
022import static org.mockito.Mockito.mock;
023import static org.mockito.Mockito.mockConstruction;
024import static org.mockito.Mockito.mockStatic;
025
026import java.net.URI;
027import java.util.List;
028import org.apache.hadoop.conf.Configuration;
029import org.apache.hadoop.hbase.HBaseConfiguration;
030import org.apache.hadoop.hbase.HConstants;
031import org.apache.hadoop.hbase.security.User;
032import org.apache.hadoop.hbase.testclassification.ClientTests;
033import org.apache.hadoop.hbase.testclassification.SmallTests;
034import org.apache.hadoop.hbase.util.ReflectionUtils;
035import org.junit.jupiter.api.AfterEach;
036import org.junit.jupiter.api.BeforeEach;
037import org.junit.jupiter.api.Tag;
038import org.junit.jupiter.api.Test;
039import org.mockito.ArgumentCaptor;
040import org.mockito.MockedConstruction;
041import org.mockito.MockedStatic;
042
043/**
044 * Make sure we can successfully parse the URI component
045 */
046@Tag(ClientTests.TAG)
047@Tag(SmallTests.TAG)
048public class TestConnectionRegistryUriParsing {
049
050  private Configuration conf;
051
052  private User user;
053
054  private MockedConstruction<RpcConnectionRegistry> mockedRpcRegistry;
055
056  private MockedConstruction<ZKConnectionRegistry> mockedZkRegistry;
057
058  private MockedStatic<ReflectionUtils> mockedReflectionUtils;
059
060  private List<?> args;
061
062  @BeforeEach
063  public void setUp() {
064    conf = HBaseConfiguration.create();
065    user = mock(User.class);
066    args = null;
067    mockedRpcRegistry = mockConstruction(RpcConnectionRegistry.class, (mock, context) -> {
068      args = context.arguments();
069    });
070    mockedZkRegistry = mockConstruction(ZKConnectionRegistry.class, (mock, context) -> {
071      args = context.arguments();
072    });
073    mockedReflectionUtils = mockStatic(ReflectionUtils.class);
074  }
075
076  @AfterEach
077  public void tearDown() {
078    mockedRpcRegistry.closeOnDemand();
079    mockedZkRegistry.closeOnDemand();
080    mockedReflectionUtils.closeOnDemand();
081  }
082
083  @Test
084  public void testParseRpcSingle() throws Exception {
085    ConnectionRegistryFactory.create(new URI("hbase+rpc://server1:123"), conf, user);
086    assertEquals(1, mockedRpcRegistry.constructed().size());
087    assertSame(user, args.get(1));
088    Configuration conf = (Configuration) args.get(0);
089    assertEquals("server1:123", conf.get(RpcConnectionRegistry.BOOTSTRAP_NODES));
090  }
091
092  @Test
093  public void testParseRpcMultiple() throws Exception {
094    ConnectionRegistryFactory.create(new URI("hbase+rpc://server1:123,server2:456,server3:789"),
095      conf, user);
096    assertEquals(1, mockedRpcRegistry.constructed().size());
097    assertSame(user, args.get(1));
098    Configuration conf = (Configuration) args.get(0);
099    assertEquals("server1:123,server2:456,server3:789",
100      conf.get(RpcConnectionRegistry.BOOTSTRAP_NODES));
101  }
102
103  @Test
104  public void testParseZkSingle() throws Exception {
105    ConnectionRegistryFactory.create(new URI("hbase+zk://server1:123/root"), conf, user);
106    assertEquals(1, mockedZkRegistry.constructed().size());
107    assertSame(user, args.get(1));
108    Configuration conf = (Configuration) args.get(0);
109    assertEquals("server1:123", conf.get(HConstants.CLIENT_ZOOKEEPER_QUORUM));
110    assertEquals("/root", conf.get(HConstants.ZOOKEEPER_ZNODE_PARENT));
111  }
112
113  @Test
114  public void testParseZkMultiple() throws Exception {
115    ConnectionRegistryFactory
116      .create(new URI("hbase+zk://server1:123,server2:456,server3:789/root/path"), conf, user);
117    assertEquals(1, mockedZkRegistry.constructed().size());
118    assertSame(user, args.get(1));
119    Configuration conf = (Configuration) args.get(0);
120    assertEquals("server1:123,server2:456,server3:789",
121      conf.get(HConstants.CLIENT_ZOOKEEPER_QUORUM));
122    assertEquals("/root/path", conf.get(HConstants.ZOOKEEPER_ZNODE_PARENT));
123  }
124
125  @Test
126  public void testFallbackNoScheme() throws Exception {
127    conf.setClass(HConstants.CLIENT_CONNECTION_REGISTRY_IMPL_CONF_KEY, ZKConnectionRegistry.class,
128      ConnectionRegistry.class);
129    ConnectionRegistryFactory.create(new URI("server1:2181/path"), conf, user);
130    ArgumentCaptor<Class<?>> clazzCaptor = ArgumentCaptor.forClass(Class.class);
131    ArgumentCaptor<Object[]> argsCaptor = ArgumentCaptor.forClass(Object[].class);
132    mockedReflectionUtils
133      .verify(() -> ReflectionUtils.newInstance(clazzCaptor.capture(), argsCaptor.capture()));
134    assertEquals(ZKConnectionRegistry.class, clazzCaptor.getValue());
135    assertSame(conf, argsCaptor.getValue()[0]);
136    assertSame(user, argsCaptor.getValue()[1]);
137  }
138
139  @Test
140  public void testFallbackNoCreator() throws Exception {
141    conf.setClass(HConstants.CLIENT_CONNECTION_REGISTRY_IMPL_CONF_KEY, RpcConnectionRegistry.class,
142      ConnectionRegistry.class);
143    ConnectionRegistryFactory.create(new URI("hbase+tls://server1:123/path"), conf, user);
144    ArgumentCaptor<Class<?>> clazzCaptor = ArgumentCaptor.forClass(Class.class);
145    ArgumentCaptor<Object[]> argsCaptor = ArgumentCaptor.forClass(Object[].class);
146    mockedReflectionUtils
147      .verify(() -> ReflectionUtils.newInstance(clazzCaptor.capture(), argsCaptor.capture()));
148    assertEquals(RpcConnectionRegistry.class, clazzCaptor.getValue());
149    assertSame(conf, argsCaptor.getValue()[0]);
150    assertSame(user, argsCaptor.getValue()[1]);
151  }
152}