Simplify TransportGetRolesAction (elastic/elasticsearch#3888)

TransportGetRolesAction optimizes for single role case while this
optimization can be simply inside the NativeRoleStore and being
way more contained.

Original commit: elastic/x-pack-elasticsearch@c43d8ba341
This commit is contained in:
Simon Willnauer 2016-10-26 14:55:39 +02:00 committed by GitHub
parent 007e49c5d9
commit 6e1287bab9
3 changed files with 104 additions and 203 deletions

View File

@ -67,44 +67,15 @@ public class TransportGetRolesAction extends HandledTransportAction<GetRolesRequ
roles.addAll(reservedRolesStore.roleDescriptors()); roles.addAll(reservedRolesStore.roleDescriptors());
} }
if (rolesToSearchFor.size() == 1) { if (specificRolesRequested && rolesToSearchFor.isEmpty()) {
final String rolename = rolesToSearchFor.get(0);
// We can fetch a single role with a get, much easier
nativeRolesStore.getRoleDescriptor(rolename, new ActionListener<RoleDescriptor>() {
@Override
public void onResponse(RoleDescriptor roleD) {
if (roleD != null) {
roles.add(roleD);
}
listener.onResponse(new GetRolesResponse(roles.toArray(new RoleDescriptor[roles.size()])));
}
@Override
public void onFailure(Exception t) {
logger.error((Supplier<?>) () -> new ParameterizedMessage("failed to retrieve role [{}]", rolename), t);
listener.onFailure(t);
}
});
} else if (specificRolesRequested && rolesToSearchFor.isEmpty()) {
// specific roles were requested but they were built in only, no need to hit the store // specific roles were requested but they were built in only, no need to hit the store
listener.onResponse(new GetRolesResponse(roles.toArray(new RoleDescriptor[roles.size()]))); listener.onResponse(new GetRolesResponse(roles.toArray(new RoleDescriptor[roles.size()])));
} else { } else {
nativeRolesStore.getRoleDescriptors( String[] roleNames = rolesToSearchFor.toArray(new String[rolesToSearchFor.size()]);
rolesToSearchFor.toArray(new String[rolesToSearchFor.size()]), new ActionListener<List<RoleDescriptor>>() { nativeRolesStore.getRoleDescriptors(roleNames, ActionListener.wrap((foundRoles) -> {
@Override
public void onResponse(List<RoleDescriptor> foundRoles) {
roles.addAll(foundRoles); roles.addAll(foundRoles);
listener.onResponse(new GetRolesResponse(roles.toArray(new RoleDescriptor[roles.size()]))); listener.onResponse(new GetRolesResponse(roles.toArray(new RoleDescriptor[roles.size()])));
} }, listener::onFailure));
@Override
public void onFailure(Exception t) {
logger.error(
(Supplier<?>) () -> new ParameterizedMessage(
"failed to retrieve role [{}]", arrayToDelimitedString(request.names(), ",")), t);
listener.onFailure(t);
}
});
} }
} }
} }

View File

@ -64,6 +64,7 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
@ -207,6 +208,11 @@ public class NativeRolesStore extends AbstractComponent implements ClusterStateL
listener.onFailure(new IllegalStateException("roles cannot be retrieved as native role service has not been started")); listener.onFailure(new IllegalStateException("roles cannot be retrieved as native role service has not been started"));
return; return;
} }
if (names != null && names.length == 1) {
getRoleAndVersion(Objects.requireNonNull(names[0]), ActionListener.wrap(roleAndVersion ->
listener.onResponse(roleAndVersion == null || roleAndVersion.getRoleDescriptor() == null ? Collections.emptyList()
: Collections.singletonList(roleAndVersion.getRoleDescriptor())), listener::onFailure));
} else {
try { try {
final List<RoleDescriptor> roles = new ArrayList<>(); final List<RoleDescriptor> roles = new ArrayList<>();
QueryBuilder query; QueryBuilder query;
@ -273,23 +279,6 @@ public class NativeRolesStore extends AbstractComponent implements ClusterStateL
listener.onFailure(e); listener.onFailure(e);
} }
} }
public void getRoleDescriptor(final String role, final ActionListener<RoleDescriptor> listener) {
if (state() != State.STARTED) {
logger.trace("attempted to get role [{}] before service was started", role);
listener.onResponse(null);
}
getRoleAndVersion(role, new ActionListener<RoleAndVersion>() {
@Override
public void onResponse(RoleAndVersion roleAndVersion) {
listener.onResponse(roleAndVersion == null ? null : roleAndVersion.getRoleDescriptor());
}
@Override
public void onFailure(Exception e) {
listener.onFailure(e);
}
});
} }
public void deleteRole(final DeleteRoleRequest deleteRoleRequest, final ActionListener<Boolean> listener) { public void deleteRole(final DeleteRoleRequest deleteRoleRequest, final ActionListener<Boolean> listener) {

View File

@ -71,15 +71,12 @@ public class TransportGetRolesActionTests extends ESTestCase {
expectedNames.remove(KibanaRole.NAME); expectedNames.remove(KibanaRole.NAME);
} }
doAnswer(new Answer() { doAnswer(invocation -> {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments(); Object[] args = invocation.getArguments();
assert args.length == 2; assert args.length == 2;
ActionListener<List<RoleDescriptor>> listener = (ActionListener<List<RoleDescriptor>>) args[1]; ActionListener<List<RoleDescriptor>> listener = (ActionListener<List<RoleDescriptor>>) args[1];
listener.onResponse(Collections.emptyList()); listener.onResponse(Collections.emptyList());
return null; return null;
}
}).when(rolesStore).getRoleDescriptors(aryEq(Strings.EMPTY_ARRAY), any(ActionListener.class)); }).when(rolesStore).getRoleDescriptors(aryEq(Strings.EMPTY_ARRAY), any(ActionListener.class));
GetRolesRequest request = new GetRolesRequest(); GetRolesRequest request = new GetRolesRequest();
@ -131,32 +128,13 @@ public class TransportGetRolesActionTests extends ESTestCase {
GetRolesRequest request = new GetRolesRequest(); GetRolesRequest request = new GetRolesRequest();
request.names(storeRoleDescriptors.stream().map(RoleDescriptor::getName).collect(Collectors.toList()).toArray(Strings.EMPTY_ARRAY)); request.names(storeRoleDescriptors.stream().map(RoleDescriptor::getName).collect(Collectors.toList()).toArray(Strings.EMPTY_ARRAY));
if (request.names().length == 1) { doAnswer(invocation -> {
doAnswer(new Answer() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
assert args.length == 2;
String requestedName = (String) args[0];
ActionListener<RoleDescriptor> listener = (ActionListener<RoleDescriptor>) args[1];
Optional<RoleDescriptor> rd =
storeRoleDescriptors.stream().filter(r -> r.getName().equals(requestedName)).findFirst();
listener.onResponse(rd.get());
return null;
}
}).when(rolesStore).getRoleDescriptor(eq(request.names()[0]), any(ActionListener.class));
} else {
doAnswer(new Answer() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments(); Object[] args = invocation.getArguments();
assert args.length == 2; assert args.length == 2;
ActionListener<List<RoleDescriptor>> listener = (ActionListener<List<RoleDescriptor>>) args[1]; ActionListener<List<RoleDescriptor>> listener = (ActionListener<List<RoleDescriptor>>) args[1];
listener.onResponse(storeRoleDescriptors); listener.onResponse(storeRoleDescriptors);
return null; return null;
}
}).when(rolesStore).getRoleDescriptors(aryEq(request.names()), any(ActionListener.class)); }).when(rolesStore).getRoleDescriptors(aryEq(request.names()), any(ActionListener.class));
}
final AtomicReference<Throwable> throwableRef = new AtomicReference<>(); final AtomicReference<Throwable> throwableRef = new AtomicReference<>();
final AtomicReference<GetRolesResponse> responseRef = new AtomicReference<>(); final AtomicReference<GetRolesResponse> responseRef = new AtomicReference<>();
@ -219,40 +197,21 @@ public class TransportGetRolesActionTests extends ESTestCase {
GetRolesRequest request = new GetRolesRequest(); GetRolesRequest request = new GetRolesRequest();
request.names(requestedNames.toArray(Strings.EMPTY_ARRAY)); request.names(requestedNames.toArray(Strings.EMPTY_ARRAY));
if (specificStoreNames.size() == 1) { doAnswer(invocation -> {
doAnswer(new Answer() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments(); Object[] args = invocation.getArguments();
assert args.length == 2; assert args.length == 2;
String requestedName = (String) args[0]; String[] requestedNames1 = (String[]) args[0];
ActionListener<RoleDescriptor> listener = (ActionListener<RoleDescriptor>) args[1];
Optional<RoleDescriptor> rd =
storeRoleDescriptors.stream().filter(r -> r.getName().equals(requestedName)).findFirst();
listener.onResponse(rd.get());
return null;
}
}).when(rolesStore).getRoleDescriptor(eq(specificStoreNames.get(0)), any(ActionListener.class));
} else {
doAnswer(new Answer() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
assert args.length == 2;
String[] requestedNames = (String[]) args[0];
ActionListener<List<RoleDescriptor>> listener = (ActionListener<List<RoleDescriptor>>) args[1]; ActionListener<List<RoleDescriptor>> listener = (ActionListener<List<RoleDescriptor>>) args[1];
if (requestedNames.length == 0) { if (requestedNames1.length == 0) {
listener.onResponse(storeRoleDescriptors); listener.onResponse(storeRoleDescriptors);
} else { } else {
List<String> requestedNamesList = Arrays.asList(requestedNames); List<String> requestedNamesList = Arrays.asList(requestedNames1);
listener.onResponse(storeRoleDescriptors.stream() listener.onResponse(storeRoleDescriptors.stream()
.filter(r -> requestedNamesList.contains(r.getName())) .filter(r -> requestedNamesList.contains(r.getName()))
.collect(Collectors.toList())); .collect(Collectors.toList()));
} }
return null; return null;
}
}).when(rolesStore).getRoleDescriptors(aryEq(specificStoreNames.toArray(Strings.EMPTY_ARRAY)), any(ActionListener.class)); }).when(rolesStore).getRoleDescriptors(aryEq(specificStoreNames.toArray(Strings.EMPTY_ARRAY)), any(ActionListener.class));
}
final AtomicReference<Throwable> throwableRef = new AtomicReference<>(); final AtomicReference<Throwable> throwableRef = new AtomicReference<>();
final AtomicReference<GetRolesResponse> responseRef = new AtomicReference<>(); final AtomicReference<GetRolesResponse> responseRef = new AtomicReference<>();
@ -276,8 +235,6 @@ public class TransportGetRolesActionTests extends ESTestCase {
if (all) { if (all) {
verify(rolesStore, times(1)).getRoleDescriptors(aryEq(Strings.EMPTY_ARRAY), any(ActionListener.class)); verify(rolesStore, times(1)).getRoleDescriptors(aryEq(Strings.EMPTY_ARRAY), any(ActionListener.class));
} else if (specificStoreNames.size() == 1) {
verify(rolesStore, times(1)).getRoleDescriptor(eq(specificStoreNames.get(0)), any(ActionListener.class));
} else { } else {
verify(rolesStore, times(1)) verify(rolesStore, times(1))
.getRoleDescriptors(aryEq(specificStoreNames.toArray(Strings.EMPTY_ARRAY)), any(ActionListener.class)); .getRoleDescriptors(aryEq(specificStoreNames.toArray(Strings.EMPTY_ARRAY)), any(ActionListener.class));
@ -297,29 +254,13 @@ public class TransportGetRolesActionTests extends ESTestCase {
GetRolesRequest request = new GetRolesRequest(); GetRolesRequest request = new GetRolesRequest();
request.names(storeRoleDescriptors.stream().map(RoleDescriptor::getName).collect(Collectors.toList()).toArray(Strings.EMPTY_ARRAY)); request.names(storeRoleDescriptors.stream().map(RoleDescriptor::getName).collect(Collectors.toList()).toArray(Strings.EMPTY_ARRAY));
if (request.names().length == 1) { doAnswer(invocation -> {
doAnswer(new Answer() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
assert args.length == 2;
ActionListener<RoleDescriptor> listener = (ActionListener<RoleDescriptor>) args[1];
listener.onFailure(e);
return null;
}
}).when(rolesStore).getRoleDescriptor(eq(request.names()[0]), any(ActionListener.class));
} else {
doAnswer(new Answer() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments(); Object[] args = invocation.getArguments();
assert args.length == 2; assert args.length == 2;
ActionListener<List<RoleDescriptor>> listener = (ActionListener<List<RoleDescriptor>>) args[1]; ActionListener<List<RoleDescriptor>> listener = (ActionListener<List<RoleDescriptor>>) args[1];
listener.onFailure(e); listener.onFailure(e);
return null; return null;
}
}).when(rolesStore).getRoleDescriptors(aryEq(request.names()), any(ActionListener.class)); }).when(rolesStore).getRoleDescriptors(aryEq(request.names()), any(ActionListener.class));
}
final AtomicReference<Throwable> throwableRef = new AtomicReference<>(); final AtomicReference<Throwable> throwableRef = new AtomicReference<>();
final AtomicReference<GetRolesResponse> responseRef = new AtomicReference<>(); final AtomicReference<GetRolesResponse> responseRef = new AtomicReference<>();