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