Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: [ISSUE-708] Extract interface from Microservices #710

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.scalecube.services;

import static java.util.Objects.requireNonNull;

import java.util.Collection;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import reactor.core.publisher.Mono;

@Deprecated
public class DeprecatedServiceProviderAdapter implements ServicesProvider {

private final Collection<ServiceProvider> delegates;

public DeprecatedServiceProviderAdapter(Collection<ServiceProvider> delegates) {
this.delegates = requireNonNull(delegates);
}

@Override
public Mono<Collection<ServiceInfo>> provide(Microservices microservices) {
Supplier<Mono<Collection<ServiceInfo>>> beanSupplier =
() ->
Mono.just(
delegates.stream()
.map(delegate -> delegate.provide(microservices.call()))
.flatMap(Collection::stream)
.collect(Collectors.toList()));
return Mono.defer(beanSupplier);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.scalecube.services;

import io.scalecube.net.Address;
import io.scalecube.services.discovery.api.ServiceDiscovery;

public interface Microservices {

ServiceCall call();

Address serviceAddress();

ServiceDiscovery discovery();
}
11 changes: 6 additions & 5 deletions services-api/src/main/java/io/scalecube/services/Reflect.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
Expand Down Expand Up @@ -249,14 +251,13 @@ public static Map<String, Method> serviceMethods(Class<?> serviceInterface) {
/**
* Util function to get service interfaces collections from service instance.
*
* @param serviceObject with extends service interface with @Service annotation.
* @param serviceType type with extends service interface with @Service annotation.
* @return service interface class.
*/
public static Collection<Class<?>> serviceInterfaces(Object serviceObject) {
Class<?>[] interfaces = serviceObject.getClass().getInterfaces();
public static Stream<Class<?>> serviceInterfaces(Class<?> serviceType) {
Class<?>[] interfaces = serviceType.getInterfaces();
return Arrays.stream(interfaces)
.filter(interfaceClass -> interfaceClass.isAnnotationPresent(Service.class))
.collect(Collectors.toList());
.filter(interfaceClass -> interfaceClass.isAnnotationPresent(Service.class));
}

public static String methodName(Method method) {
Expand Down
30 changes: 20 additions & 10 deletions services-api/src/main/java/io/scalecube/services/ServiceInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,21 @@
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;
import java.util.function.Supplier;

@SuppressWarnings("rawtypes")
public class ServiceInfo {

private final Object serviceInstance;
private final Class<?> serviceType;
private final Supplier<Object> serviceInstanceSupplier;
private final Map<String, String> tags;
private final ServiceProviderErrorMapper errorMapper;
private final ServiceMessageDataDecoder dataDecoder;
private final Authenticator authenticator;

private ServiceInfo(Builder builder) {
this.serviceInstance = builder.serviceInstance;
this.serviceType = builder.serviceType;
this.serviceInstanceSupplier = builder.serviceInstanceSupplier;
this.tags = Collections.unmodifiableMap(new HashMap<>(builder.tags));
this.errorMapper = builder.errorMapper;
this.dataDecoder = builder.dataDecoder;
Expand All @@ -30,11 +33,11 @@ public static Builder from(ServiceInfo serviceInfo) {
}

public static Builder fromServiceInstance(Object serviceInstance) {
return new Builder(serviceInstance);
return new Builder(serviceInstance.getClass(), () -> serviceInstance);
}

public Object serviceInstance() {
return serviceInstance;
public Supplier<Object> serviceInstanceSupplier() {
return serviceInstanceSupplier;
}

public Map<String, String> tags() {
Expand All @@ -53,10 +56,14 @@ public Authenticator authenticator() {
return authenticator;
}

public Class<?> type() {
return serviceType;
}

@Override
public String toString() {
return new StringJoiner(", ", ServiceInfo.class.getSimpleName() + "[", "]")
.add("serviceInstance=" + serviceInstance)
.add("serviceInstance=" + serviceInstanceSupplier)
.add("tags=" + tags)
.add("errorMapper=" + errorMapper)
.add("dataDecoder=" + dataDecoder)
Expand All @@ -67,22 +74,25 @@ public String toString() {
@SuppressWarnings("rawtypes")
public static class Builder {

private Object serviceInstance;
private final Class<?> serviceType;
private final Supplier<Object> serviceInstanceSupplier;
private Map<String, String> tags = new HashMap<>();
private ServiceProviderErrorMapper errorMapper;
private ServiceMessageDataDecoder dataDecoder;
private Authenticator authenticator;

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

private Builder(Object serviceInstance) {
this.serviceInstance = serviceInstance;
private Builder(Class<?> serviceType, Supplier<Object> serviceInstanceSupplier) {
this.serviceType = serviceType;
this.serviceInstanceSupplier = serviceInstanceSupplier;
}

public Builder tag(String key, String value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

import java.util.Collection;

/**
* Provide service instances.
*
* @deprecated use {@link ServicesProvider}
*/
@FunctionalInterface
@Deprecated
public interface ServiceProvider {

Collection<ServiceInfo> provide(ServiceCall call);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ private ServiceScanner() {
* @return list of {@code ServiceRegistration}-s
*/
public static List<ServiceRegistration> scanServiceInfo(ServiceInfo serviceInfo) {
return Arrays.stream(serviceInfo.serviceInstance().getClass().getInterfaces())
.filter(serviceInterface -> serviceInterface.isAnnotationPresent(Service.class))
return Reflect.serviceInterfaces(serviceInfo.type())
.map(
serviceInterface -> {
Map<String, String> serviceInfoTags = serviceInfo.tags();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.scalecube.services;

import java.util.Collection;
import reactor.core.publisher.Mono;

@FunctionalInterface
public interface ServicesProvider {

Mono<Collection<ServiceInfo>> provide(Microservices microservices);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
import java.lang.reflect.Method;
import java.util.Optional;
import java.util.StringJoiner;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Supplier;

import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
Expand All @@ -25,11 +28,12 @@ public final class ServiceMethodInvoker {
private static final Object NO_PRINCIPAL = new Object();

private final Method method;
private final Object service;
private final Supplier<Object> service;
private final MethodInfo methodInfo;
private final ServiceProviderErrorMapper errorMapper;
private final ServiceMessageDataDecoder dataDecoder;
private final Authenticator<Object> authenticator;
private final Class<?> serviceType;

/**
* Constructs a service method invoker out of real service object instance and method info.
Expand All @@ -41,15 +45,26 @@ public final class ServiceMethodInvoker {
* @param dataDecoder data decoder
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public ServiceMethodInvoker(
public <T> ServiceMethodInvoker(
Class<?> serviceType,
Method method,
Object service,
Supplier<Object> service,
MethodInfo methodInfo,
ServiceProviderErrorMapper errorMapper,
ServiceMessageDataDecoder dataDecoder,
Authenticator authenticator) {
this.serviceType = serviceType;
this.method = method;
this.service = service;
this.service =
new Supplier<Object>() {
private final AtomicReference<Object> instance = new AtomicReference<>();

@Override
public Object get() {
instance.compareAndSet(null, service.get());
return instance.get();
}
};
this.methodInfo = methodInfo;
this.errorMapper = errorMapper;
this.dataDecoder = dataDecoder;
Expand Down Expand Up @@ -114,10 +129,10 @@ private Publisher<?> invoke(Object request, Object principal) {
Throwable throwable = null;
try {
if (methodInfo.parameterCount() == 0) {
result = (Publisher<?>) method.invoke(service);
result = (Publisher<?>) method.invoke(service.get());
} else {
Object[] arguments = prepareArguments(request, principal);
result = (Publisher<?>) method.invoke(service, arguments);
result = (Publisher<?>) method.invoke(service.get(), arguments);
}
if (result == null) {
result = Mono.empty();
Expand Down Expand Up @@ -199,8 +214,13 @@ private void applyRequestReleaser(ServiceMessage request, Consumer<Object> reque
}
}

public Class<?> serviceType() {
return serviceType;
}

@Deprecated
public Object service() {
return service;
return service.get();
}

public MethodInfo methodInfo() {
Expand All @@ -211,7 +231,7 @@ public MethodInfo methodInfo() {
public String toString() {
return new StringJoiner(", ", ServiceMethodInvoker.class.getSimpleName() + "[", "]")
.add("method=" + method)
.add("service=" + service)
.add("service=" + serviceType)
.add("methodInfo=" + methodInfo)
.add("errorMapper=" + errorMapper)
.add("dataDecoder=" + dataDecoder)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,12 @@ void testInvokeOneWhenReturnNull() throws Exception {
false,
AUTH);

// FIXME: 19.02.2020
serviceMethodInvoker =
new ServiceMethodInvoker(
stubService.getClass(),
method,
stubService,
() -> stubService,
methodInfo,
DefaultErrorMapper.INSTANCE,
dataDecoder,
Expand Down Expand Up @@ -81,11 +83,12 @@ void testInvokeManyWhenReturnNull() throws Exception {
Void.TYPE,
false,
AUTH);

// FIXME: 19.02.2020
serviceMethodInvoker =
new ServiceMethodInvoker(
stubService.getClass(),
method,
stubService,
() -> stubService,
methodInfo,
DefaultErrorMapper.INSTANCE,
dataDecoder,
Expand Down Expand Up @@ -116,10 +119,12 @@ void testInvokeBidirectionalWhenReturnNull() throws Exception {
false,
AUTH);

// FIXME: 19.02.2020
serviceMethodInvoker =
new ServiceMethodInvoker(
stubService.getClass(),
method,
stubService,
() -> stubService,
methodInfo,
DefaultErrorMapper.INSTANCE,
dataDecoder,
Expand Down Expand Up @@ -152,10 +157,12 @@ void testInvokeOneWhenThrowException() throws Exception {
false,
AUTH);

// FIXME: 19.02.2020
serviceMethodInvoker =
new ServiceMethodInvoker(
stubService.getClass(),
method,
stubService,
() -> stubService,
methodInfo,
DefaultErrorMapper.INSTANCE,
dataDecoder,
Expand Down Expand Up @@ -189,10 +196,12 @@ void testInvokeManyWhenThrowException() throws Exception {
false,
AUTH);

// FIXME: 19.02.2020
serviceMethodInvoker =
new ServiceMethodInvoker(
stubService.getClass(),
method,
stubService,
() -> stubService,
methodInfo,
DefaultErrorMapper.INSTANCE,
dataDecoder,
Expand Down Expand Up @@ -226,10 +235,12 @@ void testInvokeBidirectionalWhenThrowException() throws Exception {
false,
AUTH);

// FIXME: 19.02.2020
serviceMethodInvoker =
new ServiceMethodInvoker(
stubService.getClass(),
method,
stubService,
() -> stubService,
methodInfo,
DefaultErrorMapper.INSTANCE,
dataDecoder,
Expand Down
Loading