Skip to content

Commit

Permalink
Merge pull request #735 from scalecube/get-rid-of-principal
Browse files Browse the repository at this point in the history
Get rid of @principal
  • Loading branch information
artem-v authored May 13, 2020
2 parents feeb200 + ae685c0 commit d0c8414
Show file tree
Hide file tree
Showing 19 changed files with 411 additions and 427 deletions.
55 changes: 12 additions & 43 deletions services-api/src/main/java/io/scalecube/services/Reflect.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@
import io.scalecube.services.api.Qualifier;
import io.scalecube.services.api.ServiceMessage;
import io.scalecube.services.auth.Auth;
import io.scalecube.services.auth.Principal;
import io.scalecube.services.methods.MethodInfo;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
Expand Down Expand Up @@ -93,10 +91,6 @@ public static Class<?> requestType(Method method) {
if (method.isAnnotationPresent(RequestType.class)) {
return method.getAnnotation(RequestType.class).value();
} else {
if (method.getParameters()[0].isAnnotationPresent(Principal.class)) {
return Void.TYPE;
}

if (method.getGenericParameterTypes()[0] instanceof ParameterizedType) {
try {
return Class.forName(parameterizedRequestType(method).getTypeName());
Expand Down Expand Up @@ -157,17 +151,17 @@ public static Map<Method, MethodInfo> methodsInfo(Class<?> serviceInterface) {
.collect(
Collectors.toMap(
Function.identity(),
method1 ->
method ->
new MethodInfo(
serviceName(serviceInterface),
methodName(method1),
parameterizedReturnType(method1),
isReturnTypeServiceMessage(method1),
communicationMode(method1),
method1.getParameterCount(),
requestType(method1),
isRequestTypeServiceMessage(method1),
isAuth(method1)))));
methodName(method),
parameterizedReturnType(method),
isReturnTypeServiceMessage(method),
communicationMode(method),
method.getParameterCount(),
requestType(method),
isRequestTypeServiceMessage(method),
isAuth(method)))));
}

/**
Expand Down Expand Up @@ -290,10 +284,10 @@ public static void validateMethodOrThrow(Method method) {

validateResponseType(method);
validateRequestType(method);
validatePrincipalParameter(method);

if (method.getParameterCount() > 2) {
throw new UnsupportedOperationException("Service method can accept maximum 2 parameters");
if (method.getParameterCount() > 1) {
throw new UnsupportedOperationException(
"Service method can accept at maximum single parameter");
}
}

Expand Down Expand Up @@ -321,31 +315,6 @@ private static void validateRequestType(Method method) {
}
}

private static void validatePrincipalParameter(Method method) {
Parameter[] parameters = method.getParameters();

if (!isAuth(method)) {
for (Parameter parameter : parameters) {
if (parameter.isAnnotationPresent(Principal.class)) {
throw new UnsupportedOperationException(
"@Principal can be used only for parameter of @Auth method");
}
}
}

if (method.getParameterCount() == 2) {
if (parameters[0].isAnnotationPresent(Principal.class)) {
throw new UnsupportedOperationException(
"@Principal cannot be the first parameter on method with two parameters");
}

if (!parameters[1].isAnnotationPresent(Principal.class)) {
throw new UnsupportedOperationException(
"The second parameter can be only @Principal (optional)");
}
}
}

/**
* This method is used to get catual {@link CommunicationMode} os service method.
*
Expand Down
76 changes: 52 additions & 24 deletions services-api/src/main/java/io/scalecube/services/ServiceCall.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.scalecube.net.Address;
import io.scalecube.services.api.ErrorData;
import io.scalecube.services.api.ServiceMessage;
import io.scalecube.services.exceptions.DefaultErrorMapper;
import io.scalecube.services.exceptions.ServiceClientErrorMapper;
import io.scalecube.services.exceptions.ServiceUnavailableException;
import io.scalecube.services.methods.MethodInfo;
Expand Down Expand Up @@ -38,39 +39,66 @@ public class ServiceCall {
private static final ServiceMessage UNEXPECTED_EMPTY_RESPONSE =
ServiceMessage.error(503, 503, "Unexpected empty response");

private final ClientTransport transport;
private final ServiceMethodRegistry methodRegistry;
private final ServiceRegistry serviceRegistry;

private ClientTransport transport;
private ServiceMethodRegistry methodRegistry;
private ServiceRegistry serviceRegistry;
private Router router;
private ServiceClientErrorMapper errorMapper;
private ServiceClientErrorMapper errorMapper = DefaultErrorMapper.INSTANCE;
private Map<String, String> credentials = Collections.emptyMap();
private String contentType;

ServiceCall(
ClientTransport transport,
ServiceMethodRegistry methodRegistry,
ServiceRegistry serviceRegistry) {
this.transport = transport;
this.methodRegistry = methodRegistry;
this.serviceRegistry = serviceRegistry;
}
public ServiceCall() {}

private ServiceCall(ServiceCall other) {
this.transport = other.transport;
this.methodRegistry = other.methodRegistry;
this.serviceRegistry = other.serviceRegistry;
// Set resettable fields
this.router = other.router;
this.errorMapper = other.errorMapper;
this.contentType = other.contentType;
this.credentials = Collections.unmodifiableMap(new HashMap<>(other.credentials));
}

/**
* Creates new {@link ServiceCall}'s definition with a given router.
* Setter for {@code clientTransport}.
*
* @param clientTransport client transport.
* @return new {@link ServiceCall} instance.
*/
public ServiceCall transport(ClientTransport clientTransport) {
ServiceCall target = new ServiceCall(this);
target.transport = clientTransport;
return target;
}

/**
* Setter for {@code serviceRegistry}.
*
* @param serviceRegistry service registry.
* @return new {@link ServiceCall} instance.
*/
public ServiceCall serviceRegistry(ServiceRegistry serviceRegistry) {
ServiceCall target = new ServiceCall(this);
target.serviceRegistry = serviceRegistry;
return target;
}

/**
* Setter for {@code methodRegistry}.
*
* @param methodRegistry method registry.
* @return new {@link ServiceCall} instance.
*/
public ServiceCall methodRegistry(ServiceMethodRegistry methodRegistry) {
ServiceCall target = new ServiceCall(this);
target.methodRegistry = methodRegistry;
return target;
}

/**
* Setter for {@code routerType}.
*
* @param routerType given class of the router.
* @param routerType method registry.
* @return new {@link ServiceCall} instance.
*/
public ServiceCall router(Class<? extends Router> routerType) {
Expand All @@ -80,9 +108,9 @@ public ServiceCall router(Class<? extends Router> routerType) {
}

/**
* Creates new {@link ServiceCall}'s definition with a given router.
* Setter for {@code router}.
*
* @param router given.
* @param router router.
* @return new {@link ServiceCall} instance.
*/
public ServiceCall router(Router router) {
Expand All @@ -92,9 +120,9 @@ public ServiceCall router(Router router) {
}

/**
* Creates new {@link ServiceCall}'s definition with a given error mapper.
* Setter for {@code errorMapper}.
*
* @param errorMapper given.
* @param errorMapper error mapper.
* @return new {@link ServiceCall} instance.
*/
public ServiceCall errorMapper(ServiceClientErrorMapper errorMapper) {
Expand All @@ -104,19 +132,19 @@ public ServiceCall errorMapper(ServiceClientErrorMapper errorMapper) {
}

/**
* Creates new {@link ServiceCall}'s definition with a given credentials.
* Setter for {@code credentials}.
*
* @param credentials given.
* @param credentials credentials.
* @return new {@link ServiceCall} instance.
*/
public ServiceCall credentials(Map<String, String> credentials) {
ServiceCall target = new ServiceCall(this);
target.credentials = credentials;
target.credentials = Collections.unmodifiableMap(new HashMap<>(credentials));
return target;
}

/**
* Creates new {@link ServiceCall}'s definition with a given content type.
* Setter for {@code contentType}.
*
* @param contentType content type.
* @return new {@link ServiceCall} instance.
Expand Down
48 changes: 45 additions & 3 deletions services-api/src/main/java/io/scalecube/services/ServiceInfo.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
package io.scalecube.services;

import io.scalecube.services.auth.Authenticator;
import io.scalecube.services.auth.PrincipalMapper;
import io.scalecube.services.exceptions.ServiceProviderErrorMapper;
import io.scalecube.services.transport.api.ServiceMessageDataDecoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;

@SuppressWarnings("rawtypes")
public class ServiceInfo {

private final Object serviceInstance;
private final Map<String, String> tags;
private final ServiceProviderErrorMapper errorMapper;
private final ServiceMessageDataDecoder dataDecoder;
private final Authenticator authenticator;
private final PrincipalMapper<Object> principalMapper;

private ServiceInfo(Builder builder) {
this.serviceInstance = builder.serviceInstance;
this.tags = Collections.unmodifiableMap(new HashMap<>(builder.tags));
this.errorMapper = builder.errorMapper;
this.dataDecoder = builder.dataDecoder;
this.authenticator = builder.authenticator;
this.principalMapper = builder.principalMapper;
}

public static Builder from(ServiceInfo serviceInfo) {
Expand Down Expand Up @@ -53,32 +55,38 @@ public Authenticator authenticator() {
return authenticator;
}

public PrincipalMapper<Object> principalMapper() {
return principalMapper;
}

@Override
public String toString() {
return new StringJoiner(", ", ServiceInfo.class.getSimpleName() + "[", "]")
.add("serviceInstance=" + serviceInstance)
.add("tags=" + tags)
.add("tags(" + tags.size() + ")")
.add("errorMapper=" + errorMapper)
.add("dataDecoder=" + dataDecoder)
.add("authenticator=" + authenticator)
.add("principalMapper=" + principalMapper)
.toString();
}

@SuppressWarnings("rawtypes")
public static class Builder {

private Object serviceInstance;
private Map<String, String> tags = new HashMap<>();
private ServiceProviderErrorMapper errorMapper;
private ServiceMessageDataDecoder dataDecoder;
private Authenticator authenticator;
private PrincipalMapper<Object> principalMapper;

private Builder(ServiceInfo serviceInfo) {
this.serviceInstance = serviceInfo.serviceInstance;
this.tags.putAll(new HashMap<>(serviceInfo.tags));
this.errorMapper = serviceInfo.errorMapper;
this.dataDecoder = serviceInfo.dataDecoder;
this.authenticator = serviceInfo.authenticator;
this.principalMapper = serviceInfo.principalMapper;
}

private Builder(Object serviceInstance) {
Expand All @@ -105,6 +113,40 @@ public Builder authenticator(Authenticator authenticator) {
return this;
}

@SuppressWarnings("unchecked")
public <T> Builder principalMapper(PrincipalMapper<? extends T> principalMapper) {
this.principalMapper = (PrincipalMapper<Object>) principalMapper;
return this;
}

Builder errorMapperIfAbsent(ServiceProviderErrorMapper errorMapper) {
if (this.errorMapper == null) {
this.errorMapper = errorMapper;
}
return this;
}

Builder dataDecoderIfAbsent(ServiceMessageDataDecoder dataDecoder) {
if (this.dataDecoder == null) {
this.dataDecoder = dataDecoder;
}
return this;
}

Builder authenticatorIfAbsent(Authenticator authenticator) {
if (this.authenticator == null) {
this.authenticator = authenticator;
}
return this;
}

Builder principalMapperIfAbsent(PrincipalMapper<Object> principalMapper) {
if (this.principalMapper == null) {
this.principalMapper = principalMapper;
}
return this;
}

public ServiceInfo build() {
return new ServiceInfo(this);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
package io.scalecube.services.auth;

import io.scalecube.services.api.ServiceMessage;
import java.util.Map;
import reactor.core.publisher.Mono;

/**
* Authenticator.
*
* @param <P> principal type
*/
public interface Authenticator<P> {
@FunctionalInterface
public interface Authenticator {

/**
* Returns principal by given credentials.
* Returns {@code authData} by given credentials.
*
* @param message service message
* @return async result with obtained principal
* @param credentials credentials
* @return async result with obtained {@code authData}
*/
Mono<P> authenticate(ServiceMessage message);
Mono<Map<String, String>> authenticate(Map<String, String> credentials);
}

This file was deleted.

Loading

0 comments on commit d0c8414

Please sign in to comment.