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 Coprocessor
068 * 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
085    @Override
086    public void revoke(RpcController controller, RevokeRequest request,
087      RpcCallback<RevokeResponse> done) {
088    }
089
090    @Override
091    public void getUserPermissions(RpcController controller, GetUserPermissionsRequest request,
092      RpcCallback<GetUserPermissionsResponse> done) {
093    }
094
095    @Override
096    public void checkPermissions(RpcController controller, CheckPermissionsRequest request,
097      RpcCallback<CheckPermissionsResponse> done) {
098    }
099
100    @Override
101    public void hasPermission(RpcController controller, HasPermissionRequest request,
102      RpcCallback<HasPermissionResponse> done) {
103    }
104  }
105
106  private static class MockVisibilityController implements VisibilityLabelsService.Interface,
107    MasterCoprocessor, RegionCoprocessor, MasterObserver, RegionObserver {
108
109    @Override
110    public void addLabels(RpcController controller, VisibilityLabelsRequest request,
111      RpcCallback<VisibilityLabelsResponse> done) {
112    }
113
114    @Override
115    public void setAuths(RpcController controller, SetAuthsRequest request,
116      RpcCallback<VisibilityLabelsResponse> done) {
117    }
118
119    @Override
120    public void clearAuths(RpcController controller, SetAuthsRequest request,
121      RpcCallback<VisibilityLabelsResponse> done) {
122    }
123
124    @Override
125    public void getAuths(RpcController controller, GetAuthsRequest request,
126      RpcCallback<GetAuthsResponse> done) {
127    }
128
129    @Override
130    public void listLabels(RpcController controller, ListLabelsRequest request,
131      RpcCallback<ListLabelsResponse> done) {
132    }
133  }
134
135  private MasterRpcServices masterServices;
136
137  @SuppressWarnings("unchecked")
138  @Before
139  public void setup() {
140    masterServices = mock(MasterRpcServices.class);
141    when(masterServices.hasAccessControlServiceCoprocessor(any(MasterCoprocessorHost.class)))
142      .thenCallRealMethod();
143    when(masterServices.hasVisibilityLabelsServiceCoprocessor(any(MasterCoprocessorHost.class)))
144      .thenCallRealMethod();
145    when(masterServices.checkCoprocessorWithService(any(List.class), any(Class.class)))
146      .thenCallRealMethod();
147  }
148
149  @Test
150  public void testAccessControlServices() {
151    MasterCoprocessor defaultImpl = new AccessController();
152    MasterCoprocessor customImpl = new MockAccessController();
153    MasterCoprocessor unrelatedImpl = new JMXListener();
154    assertTrue(masterServices.checkCoprocessorWithService(Collections.singletonList(defaultImpl),
155      AccessControlService.Interface.class));
156    assertTrue(masterServices.checkCoprocessorWithService(Collections.singletonList(customImpl),
157      AccessControlService.Interface.class));
158    assertFalse(masterServices.checkCoprocessorWithService(Collections.emptyList(),
159      AccessControlService.Interface.class));
160    assertFalse(
161      masterServices.checkCoprocessorWithService(null, AccessControlService.Interface.class));
162    assertFalse(masterServices.checkCoprocessorWithService(Collections.singletonList(unrelatedImpl),
163      AccessControlService.Interface.class));
164    assertTrue(masterServices.checkCoprocessorWithService(Arrays.asList(unrelatedImpl, customImpl),
165      AccessControlService.Interface.class));
166    assertTrue(masterServices.checkCoprocessorWithService(Arrays.asList(unrelatedImpl, defaultImpl),
167      AccessControlService.Interface.class));
168  }
169
170  @Test
171  public void testVisibilityLabelServices() {
172    MasterCoprocessor defaultImpl = new VisibilityController();
173    MasterCoprocessor customImpl = new MockVisibilityController();
174    MasterCoprocessor unrelatedImpl = new JMXListener();
175    assertTrue(masterServices.checkCoprocessorWithService(Collections.singletonList(defaultImpl),
176      VisibilityLabelsService.Interface.class));
177    assertTrue(masterServices.checkCoprocessorWithService(Collections.singletonList(customImpl),
178      VisibilityLabelsService.Interface.class));
179    assertFalse(masterServices.checkCoprocessorWithService(Collections.emptyList(),
180      VisibilityLabelsService.Interface.class));
181    assertFalse(
182      masterServices.checkCoprocessorWithService(null, VisibilityLabelsService.Interface.class));
183    assertFalse(masterServices.checkCoprocessorWithService(Collections.singletonList(unrelatedImpl),
184      VisibilityLabelsService.Interface.class));
185    assertTrue(masterServices.checkCoprocessorWithService(Arrays.asList(unrelatedImpl, customImpl),
186      VisibilityLabelsService.Interface.class));
187    assertTrue(masterServices.checkCoprocessorWithService(Arrays.asList(unrelatedImpl, defaultImpl),
188      VisibilityLabelsService.Interface.class));
189  }
190}