blob: f479be57dbd50c0ec1e868a8a3f1f82c13f8cd60 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.geode.management.internal.cli.commands;
import static org.apache.geode.management.internal.cli.commands.AlterQueryServiceCommand.AUTHORIZER_NAME;
import static org.apache.geode.management.internal.cli.commands.AlterQueryServiceCommand.AUTHORIZER_PARAMETERS;
import static org.apache.geode.management.internal.cli.commands.AlterQueryServiceCommand.COMMAND_NAME;
import static org.apache.geode.management.internal.cli.commands.AlterQueryServiceCommand.FORCE_UPDATE;
import static org.apache.geode.management.internal.cli.commands.AlterQueryServiceCommand.NO_MEMBERS_FOUND_MESSAGE;
import static org.apache.geode.management.internal.cli.commands.AlterQueryServiceCommand.PARTIAL_FAILURE_MESSAGE;
import static org.apache.geode.management.internal.cli.commands.AlterQueryServiceCommand.SPLITTING_REGEX;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.apache.geode.cache.configuration.CacheConfig;
import org.apache.geode.cache.configuration.CacheElement;
import org.apache.geode.cache.query.management.configuration.QueryConfigService;
import org.apache.geode.cache.query.security.RegExMethodAuthorizer;
import org.apache.geode.cache.query.security.UnrestrictedMethodAuthorizer;
import org.apache.geode.distributed.ConfigurationPersistenceService;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.management.internal.cli.GfshParseResult;
import org.apache.geode.management.internal.cli.functions.AlterQueryServiceFunction;
import org.apache.geode.management.internal.functions.CliFunctionResult;
import org.apache.geode.test.junit.rules.GfshParserRule;
public class AlterQueryServiceCommandTest {
private Set<DistributedMember> members;
private AlterQueryServiceCommand command;
private QueryConfigService mockQueryConfigService;
@ClassRule
public static GfshParserRule gfsh = new GfshParserRule();
@Before
public void setup() {
members = new HashSet<>();
command = spy(new AlterQueryServiceCommand());
mockQueryConfigService = mock(QueryConfigService.class);
doReturn(members).when(command).findMembers(null, null);
}
private void mockMembers(int amount, String memberNamePreffix) {
IntStream.range(0, amount).forEach(i -> {
DistributedMember mockMember = mock(DistributedMember.class);
when(mockMember.getName()).thenReturn(memberNamePreffix + i);
members.add(mockMember);
});
}
private String buildCommandString(String authorizerName, String authorizerParameters,
Boolean forceUpdate) {
StringBuilder commandBuilder = new StringBuilder(COMMAND_NAME);
commandBuilder.append(" --").append(AUTHORIZER_NAME).append("=").append(authorizerName);
if (authorizerParameters != null) {
commandBuilder.append(" --").append(AUTHORIZER_PARAMETERS).append("=")
.append(authorizerParameters);
}
if (forceUpdate != null) {
commandBuilder.append(" --").append(FORCE_UPDATE).append("=").append(forceUpdate);
}
return commandBuilder.toString();
}
@Test
public void commandParsesForceUpdateCorrectly() {
GfshParseResult noForceUpdate =
gfsh.parse(COMMAND_NAME + " --" + AUTHORIZER_NAME + "=MyAuthorizer");
assertThat(noForceUpdate.getCommandName()).isEqualTo(COMMAND_NAME);
assertThat(noForceUpdate.getParamValue(AUTHORIZER_NAME)).isEqualTo("MyAuthorizer");
assertThat(noForceUpdate.getParamValue(FORCE_UPDATE)).isEqualTo(false);
GfshParseResult forceUpdateWithoutValue =
gfsh.parse(COMMAND_NAME + " --" + AUTHORIZER_NAME + "=MyAuthorizer --" + FORCE_UPDATE);
assertThat(forceUpdateWithoutValue.getCommandName()).isEqualTo(COMMAND_NAME);
assertThat(forceUpdateWithoutValue.getParamValue(AUTHORIZER_NAME)).isEqualTo("MyAuthorizer");
assertThat(forceUpdateWithoutValue.getParamValue(FORCE_UPDATE)).isEqualTo(true);
GfshParseResult forceUpdateAsFalse = gfsh.parse(
COMMAND_NAME + " --" + AUTHORIZER_NAME + "=MyAuthorizer --" + FORCE_UPDATE + "=false");
assertThat(forceUpdateAsFalse.getCommandName()).isEqualTo(COMMAND_NAME);
assertThat(forceUpdateAsFalse.getParamValue(AUTHORIZER_NAME)).isEqualTo("MyAuthorizer");
assertThat(forceUpdateAsFalse.getParamValue(FORCE_UPDATE)).isEqualTo(false);
GfshParseResult forceUpdateAsTrue = gfsh.parse(
COMMAND_NAME + " --" + AUTHORIZER_NAME + "=MyAuthorizer --" + FORCE_UPDATE + "=true");
assertThat(forceUpdateAsTrue.getCommandName()).isEqualTo(COMMAND_NAME);
assertThat(forceUpdateAsTrue.getParamValue(AUTHORIZER_NAME)).isEqualTo("MyAuthorizer");
assertThat(forceUpdateAsTrue.getParamValue(FORCE_UPDATE)).isEqualTo(true);
}
@Test
public void commandShouldReturnErrorWhenMandatoryParameterIsNotSet() {
gfsh.executeAndAssertThat(command, COMMAND_NAME).statusIsError()
.containsOutput("Invalid command");
}
@Test
public void commandReturnsCorrectMessageWhenMethodAuthorizerIsSpecifiedAndNoMembersAreFound() {
String commandString =
buildCommandString(UnrestrictedMethodAuthorizer.class.getName(), null, null);
gfsh.executeAndAssertThat(command, commandString).statusIsSuccess()
.containsOutput(NO_MEMBERS_FOUND_MESSAGE);
}
@Test
public void commandReturnsCorrectResultModelWhenMethodAuthorizerIsSpecified() {
String memberName = "memberName";
mockMembers(1, memberName);
doReturn(mockQueryConfigService).when(command).getQueryConfigService();
doNothing().when(command).populateMethodAuthorizer(any(), any(), any());
List<CliFunctionResult> resultList = new ArrayList<>();
resultList.add(new CliFunctionResult(memberName, CliFunctionResult.StatusState.OK, ""));
doReturn(resultList).when(command).executeAndGetFunctionResult(any(), any(), any());
String authorizerName = RegExMethodAuthorizer.class.getName();
String parameterString = "^java.util.List..{4,8}$;^java.util.Set..{4,8}$";
Set<String> expectedParameterSet =
new HashSet<>(Arrays.asList(parameterString.split(SPLITTING_REGEX)));
String commandString = buildCommandString(authorizerName, parameterString, null);
gfsh.executeAndAssertThat(command, commandString).statusIsSuccess().containsOutput(memberName);
verify(command).populateMethodAuthorizer(authorizerName, expectedParameterSet,
mockQueryConfigService);
verify(command).executeAndGetFunctionResult(any(AlterQueryServiceFunction.class),
eq(new Object[] {false, authorizerName, expectedParameterSet}), eq(members));
}
@Test
public void commandReturnsCorrectResultModelWhenCliResultListIsPartialFailure() {
String memberName = "name";
mockMembers(2, memberName);
doReturn(mockQueryConfigService).when(command).getQueryConfigService();
doNothing().when(command).populateMethodAuthorizer(any(), any(), any());
List<CliFunctionResult> resultList = new ArrayList<>();
resultList.add(new CliFunctionResult(memberName + 1, CliFunctionResult.StatusState.OK, ""));
resultList.add(new CliFunctionResult(memberName + 2, CliFunctionResult.StatusState.ERROR, ""));
doReturn(resultList).when(command).executeAndGetFunctionResult(any(), any(), any());
String commandString =
buildCommandString(UnrestrictedMethodAuthorizer.class.getName(), null, true);
gfsh.executeAndAssertThat(command, commandString).statusIsSuccess()
.containsOutput(PARTIAL_FAILURE_MESSAGE);
verify(command).executeAndGetFunctionResult(any(AlterQueryServiceFunction.class),
eq(new Object[] {true, UnrestrictedMethodAuthorizer.class.getName(), new HashSet<>()}),
eq(members));
}
@Test
public void populateMethodAuthorizerSetsAuthorizerNameAndParameters() {
String authorizerName = "authorizerName";
QueryConfigService queryConfigService = new QueryConfigService();
Set<String> parameters = new HashSet<>(Arrays.asList("param1", "param2"));
command.populateMethodAuthorizer(authorizerName, parameters, queryConfigService);
QueryConfigService.MethodAuthorizer methodAuthorizer = queryConfigService.getMethodAuthorizer();
assertThat(methodAuthorizer.getClassName()).isEqualTo(authorizerName);
assertThat(methodAuthorizer.getParameters().size()).isEqualTo(parameters.size());
assertThat(methodAuthorizer.getParameters().stream()
.map(QueryConfigService.MethodAuthorizer.Parameter::getParameterValue)
.collect(Collectors.toSet())).isEqualTo(parameters);
}
@Test
public void getQueryConfigurationServiceReturnsExistingQueryConfigService() {
CacheConfig mockCacheConfig = mock(CacheConfig.class);
QueryConfigService mockQueryConfigService = mock(QueryConfigService.class);
ConfigurationPersistenceService mockConfigPersistenceService =
mock(ConfigurationPersistenceService.class);
doReturn(mockConfigPersistenceService).when(command).getConfigurationPersistenceService();
when(mockConfigPersistenceService.getCacheConfig(null)).thenReturn(mockCacheConfig);
when(mockCacheConfig.findCustomCacheElement(QueryConfigService.ELEMENT_ID,
QueryConfigService.class)).thenReturn(mockQueryConfigService);
assertThat(command.getQueryConfigService()).isSameAs(mockQueryConfigService);
}
@Test
public void getQueryConfigurationServiceReturnsNewQueryConfigServiceWhenNoExistingServiceIsFound() {
CacheConfig mockCacheConfig = mock(CacheConfig.class);
ConfigurationPersistenceService mockConfigPersistenceService =
mock(ConfigurationPersistenceService.class);
doReturn(mockConfigPersistenceService).when(command).getConfigurationPersistenceService();
when(mockConfigPersistenceService.getCacheConfig(null)).thenReturn(mockCacheConfig);
when(mockCacheConfig.findCustomCacheElement(QueryConfigService.ELEMENT_ID,
QueryConfigService.class)).thenReturn(null);
assertThat(command.getQueryConfigService()).isInstanceOf(QueryConfigService.class);
}
@Test
public void updateConfigForGroupReplacesExistingElementWithNewElement() {
CacheConfig mockCacheConfig = mock(CacheConfig.class);
QueryConfigService newConfigService = mock(QueryConfigService.class);
QueryConfigService existingConfigService = mock(QueryConfigService.class);
List<CacheElement> elements = new ArrayList<>();
elements.add(existingConfigService);
when(mockCacheConfig.getCustomCacheElements()).thenReturn(elements);
assertThat(elements.size()).isEqualTo(1);
assertThat(command.updateConfigForGroup(null, mockCacheConfig, newConfigService)).isTrue();
assertThat(elements.size()).isEqualTo(1);
assertThat(elements.get(0)).isSameAs(newConfigService);
}
}