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;
019
020import static org.junit.Assert.assertFalse;
021import static org.junit.Assert.assertTrue;
022import static org.mockito.ArgumentMatchers.any;
023import static org.mockito.Mockito.mock;
024import static org.mockito.Mockito.when;
025
026import java.util.Arrays;
027import java.util.Collections;
028import java.util.List;
029import org.apache.hadoop.hbase.HBaseClassTestRule;
030import org.apache.hadoop.hbase.JMXListener;
031import org.apache.hadoop.hbase.coprocessor.MasterCoprocessor;
032import org.apache.hadoop.hbase.coprocessor.MasterObserver;
033import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor;
034import org.apache.hadoop.hbase.coprocessor.RegionObserver;
035import org.apache.hadoop.hbase.security.access.AccessController;
036import org.apache.hadoop.hbase.security.visibility.VisibilityController;
037import org.apache.hadoop.hbase.testclassification.SmallTests;
038import org.junit.Before;
039import org.junit.ClassRule;
040import org.junit.Test;
041import org.junit.experimental.categories.Category;
042
043import org.apache.hbase.thirdparty.com.google.protobuf.RpcCallback;
044import org.apache.hbase.thirdparty.com.google.protobuf.RpcController;
045
046import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.AccessControlService;
047import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.CheckPermissionsRequest;
048import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.CheckPermissionsResponse;
049import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.GetUserPermissionsRequest;
050import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.GetUserPermissionsResponse;
051import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.GrantRequest;
052import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.GrantResponse;
053import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.HasPermissionRequest;
054import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.HasPermissionResponse;
055import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.RevokeRequest;
056import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.RevokeResponse;
057import org.apache.hadoop.hbase.shaded.protobuf.generated.VisibilityLabelsProtos.GetAuthsRequest;
058import org.apache.hadoop.hbase.shaded.protobuf.generated.VisibilityLabelsProtos.GetAuthsResponse;
059import org.apache.hadoop.hbase.shaded.protobuf.generated.VisibilityLabelsProtos.ListLabelsRequest;
060import org.apache.hadoop.hbase.shaded.protobuf.generated.VisibilityLabelsProtos.ListLabelsResponse;
061import org.apache.hadoop.hbase.shaded.protobuf.generated.VisibilityLabelsProtos.SetAuthsRequest;
062import org.apache.hadoop.hbase.shaded.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsRequest;
063import org.apache.hadoop.hbase.shaded.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsResponse;
064import org.apache.hadoop.hbase.shaded.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsService;
065
066/**
067 * Tests that the MasterRpcServices is correctly searching for implementations of the
068 * Coprocessor Service and not just the "default" implementations of those services.
069 */
070@Category({SmallTests.class})
071public class TestMasterCoprocessorServices {
072
073  @ClassRule
074  public static final HBaseClassTestRule CLASS_RULE =
075      HBaseClassTestRule.forClass(TestMasterCoprocessorServices.class);
076
077  private static class MockAccessController implements AccessControlService.Interface,
078      MasterCoprocessor, RegionCoprocessor, MasterObserver, RegionObserver {
079
080    @Override
081    public void grant(RpcController controller, GrantRequest request,
082        RpcCallback<GrantResponse> done) {}
083
084    @Override
085    public void revoke(RpcController controller, RevokeRequest request,
086        RpcCallback<RevokeResponse> done) {}
087
088    @Override
089    public void getUserPermissions(RpcController controller, GetUserPermissionsRequest request,
090        RpcCallback<GetUserPermissionsResponse> done) {}
091
092    @Override
093    public void checkPermissions(RpcController controller, CheckPermissionsRequest request,
094        RpcCallback<CheckPermissionsResponse> done) {}
095
096    @Override
097    public void hasPermission(RpcController controller, HasPermissionRequest request,
098        RpcCallback<HasPermissionResponse> done) {
099    }
100  }
101
102  private static class MockVisibilityController implements VisibilityLabelsService.Interface,
103      MasterCoprocessor, RegionCoprocessor, MasterObserver, RegionObserver {
104
105    @Override
106    public void addLabels(RpcController controller, VisibilityLabelsRequest request,
107        RpcCallback<VisibilityLabelsResponse> done) {
108    }
109
110    @Override
111    public void setAuths(RpcController controller, SetAuthsRequest request,
112        RpcCallback<VisibilityLabelsResponse> done) {
113    }
114
115    @Override
116    public void clearAuths(RpcController controller, SetAuthsRequest request,
117        RpcCallback<VisibilityLabelsResponse> done) {
118    }
119
120    @Override
121    public void getAuths(RpcController controller, GetAuthsRequest request,
122        RpcCallback<GetAuthsResponse> done) {
123    }
124
125    @Override
126    public void listLabels(RpcController controller, ListLabelsRequest request,
127        RpcCallback<ListLabelsResponse> done) {
128    }
129  }
130
131  private MasterRpcServices masterServices;
132
133  @SuppressWarnings("unchecked")
134  @Before
135  public void setup() {
136    masterServices = mock(MasterRpcServices.class);
137    when(masterServices.hasAccessControlServiceCoprocessor(
138        any(MasterCoprocessorHost.class))).thenCallRealMethod();
139    when(masterServices.hasVisibilityLabelsServiceCoprocessor(
140        any(MasterCoprocessorHost.class))).thenCallRealMethod();
141    when(masterServices.checkCoprocessorWithService(
142        any(List.class), any(Class.class))).thenCallRealMethod();
143  }
144
145  @Test
146  public void testAccessControlServices() {
147    MasterCoprocessor defaultImpl = new AccessController();
148    MasterCoprocessor customImpl = new MockAccessController();
149    MasterCoprocessor unrelatedImpl = new JMXListener();
150    assertTrue(masterServices.checkCoprocessorWithService(
151        Collections.singletonList(defaultImpl), AccessControlService.Interface.class));
152    assertTrue(masterServices.checkCoprocessorWithService(
153        Collections.singletonList(customImpl), AccessControlService.Interface.class));
154    assertFalse(masterServices.checkCoprocessorWithService(
155        Collections.emptyList(), AccessControlService.Interface.class));
156    assertFalse(masterServices.checkCoprocessorWithService(
157        null, AccessControlService.Interface.class));
158    assertFalse(masterServices.checkCoprocessorWithService(
159        Collections.singletonList(unrelatedImpl), AccessControlService.Interface.class));
160    assertTrue(masterServices.checkCoprocessorWithService(
161        Arrays.asList(unrelatedImpl, customImpl), AccessControlService.Interface.class));
162    assertTrue(masterServices.checkCoprocessorWithService(
163        Arrays.asList(unrelatedImpl, defaultImpl), AccessControlService.Interface.class));
164  }
165
166  @Test
167  public void testVisibilityLabelServices() {
168    MasterCoprocessor defaultImpl = new VisibilityController();
169    MasterCoprocessor customImpl = new MockVisibilityController();
170    MasterCoprocessor unrelatedImpl = new JMXListener();
171    assertTrue(masterServices.checkCoprocessorWithService(
172        Collections.singletonList(defaultImpl), VisibilityLabelsService.Interface.class));
173    assertTrue(masterServices.checkCoprocessorWithService(
174        Collections.singletonList(customImpl), VisibilityLabelsService.Interface.class));
175    assertFalse(masterServices.checkCoprocessorWithService(
176        Collections.emptyList(), VisibilityLabelsService.Interface.class));
177    assertFalse(masterServices.checkCoprocessorWithService(
178        null, VisibilityLabelsService.Interface.class));
179    assertFalse(masterServices.checkCoprocessorWithService(
180        Collections.singletonList(unrelatedImpl), VisibilityLabelsService.Interface.class));
181    assertTrue(masterServices.checkCoprocessorWithService(
182        Arrays.asList(unrelatedImpl, customImpl), VisibilityLabelsService.Interface.class));
183    assertTrue(masterServices.checkCoprocessorWithService(
184        Arrays.asList(unrelatedImpl, defaultImpl), VisibilityLabelsService.Interface.class));
185  }
186}