去掉ServiceWrapper

This commit is contained in:
Redkale
2017-04-23 20:19:07 +08:00
parent 09165127e3
commit 71ab9c9728
12 changed files with 387 additions and 357 deletions

View File

@@ -74,7 +74,7 @@ public class NodeHttpServer extends NodeServer {
synchronized (regFactory) {
Service nodeService = (Service) rf.find(resourceName, WebSocketNode.class);
if (nodeService == null) {
nodeService = Sncp.createLocalService(resourceName, getExecutor(), application.getResourceFactory(), WebSocketNodeService.class, (InetSocketAddress) null, (Transport) null, (Collection<Transport>) null);
nodeService = Sncp.createLocalService(resourceName, getExecutor(), application.getResourceFactory(), WebSocketNodeService.class, (InetSocketAddress) null, (String) null, (Set<String>) null, (AnyValue) null, (Transport) null, (Collection<Transport>) null);
regFactory.register(resourceName, WebSocketNode.class, nodeService);
resourceFactory.inject(nodeService, self);
logger.fine("[" + Thread.currentThread().getName() + "] Load Service " + nodeService);
@@ -124,9 +124,9 @@ public class NodeHttpServer extends NodeServer {
ss.add(new AbstractMap.SimpleEntry<>(clazz.getName(), mappings));
}
}
int max = 0;
if (ss != null && sb != null) {
Collections.sort(ss, (AbstractMap.SimpleEntry<String, String[]> o1, AbstractMap.SimpleEntry<String, String[]> o2) -> o1.getKey().compareTo(o2.getKey()));
int max = 0;
for (AbstractMap.SimpleEntry<String, String[]> as : ss) {
if (as.getKey().length() > max) max = as.getKey().length();
}
@@ -138,18 +138,17 @@ public class NodeHttpServer extends NodeServer {
sb.append(" mapping to ").append(Arrays.toString(as.getValue())).append(LINE_SEPARATOR);
}
}
if (sb != null && sb.length() > 0) logger.log(Level.INFO, sb.toString());
if (rest && serverConf != null) {
for (AnyValue restConf : serverConf.getAnyValues("rest")) {
loadRestServlet(prefix, restConf);
loadRestServlet(prefix, restConf, sb);
}
}
if (sb != null && sb.length() > 0) logger.log(Level.INFO, sb.toString());
}
protected void loadRestServlet(final String prefix, final AnyValue restConf) throws Exception {
protected void loadRestServlet(final String prefix, final AnyValue restConf, final StringBuilder sb) throws Exception {
if (!rest) return;
if (restConf == null) return; //不存在REST服务
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
final String threadName = "[" + Thread.currentThread().getName() + "] ";
final List<AbstractMap.SimpleEntry<String, String[]>> ss = sb == null ? null : new ArrayList<>();
@@ -170,8 +169,9 @@ public class NodeHttpServer extends NodeServer {
final ClassFilter restFilter = ClassFilter.create(restConf.getValue("includes", ""), restConf.getValue("excludes", ""), includeValues, excludeValues);
super.interceptorServiceWrappers.forEach((wrapper) -> {
final Class stype = wrapper.getType();
super.interceptorServices.forEach((service) -> {
final Class stype = Sncp.getServiceType(service);
final String name = Sncp.getResourceName(service);
RestService rs = (RestService) stype.getAnnotation(RestService.class);
if (rs != null && rs.ignore()) return;
if (mustsign && rs == null) return;
@@ -181,17 +181,15 @@ public class NodeHttpServer extends NodeServer {
if (!autoload && !includeValues.contains(stypename)) return;
if (!restFilter.accept(stypename)) return;
RestHttpServlet servlet = httpServer.addRestServlet(wrapper.getName(), stype, wrapper.getService(), baseServletClass, prefix, (AnyValue) null);
RestHttpServlet servlet = httpServer.addRestServlet(name, stype, service, baseServletClass, prefix, (AnyValue) null);
resourceFactory.inject(servlet, NodeHttpServer.this);
if (finest) logger.finest("Create RestServlet[resource=" + wrapper.getName() + "] = " + servlet);
if (finest) logger.finest(threadName + " Create RestServlet(resource.name='" + name + "') = " + servlet);
if (ss != null) {
String[] mappings = servlet.getClass().getAnnotation(WebServlet.class).value();
for (int i = 0; i < mappings.length; i++) {
mappings[i] = prefix + mappings[i];
}
if (servlet.getClass().getSimpleName().charAt(0) != '_') {
ss.add(new AbstractMap.SimpleEntry<>(servlet.getClass().getName(), mappings));
}
ss.add(new AbstractMap.SimpleEntry<>(servlet.getClass().getName(), mappings));
}
});
//输出信息
@@ -201,6 +199,7 @@ public class NodeHttpServer extends NodeServer {
for (AbstractMap.SimpleEntry<String, String[]> as : ss) {
if (as.getKey().length() > max) max = as.getKey().length();
}
sb.append(threadName).append(" ").append(LINE_SEPARATOR);
for (AbstractMap.SimpleEntry<String, String[]> as : ss) {
sb.append(threadName).append(" Load ").append(as.getKey());
for (int i = 0; i < max - as.getKey().length(); i++) {
@@ -209,6 +208,5 @@ public class NodeHttpServer extends NodeServer {
sb.append(" mapping to ").append(Arrays.toString(as.getValue())).append(LINE_SEPARATOR);
}
}
if (sb != null && sb.length() > 0) logger.log(Level.INFO, sb.toString());
}
}

View File

@@ -5,9 +5,6 @@
*/
package org.redkale.boot;
import java.util.Objects;
import org.redkale.service.Service;
/**
* NodeServer的拦截类
*
@@ -38,63 +35,4 @@ public class NodeInterceptor {
}
public static class InterceptorServiceWrapper<T extends Service> {
private String name;
private Class<T> type;
private T service;
public InterceptorServiceWrapper() {
}
public InterceptorServiceWrapper(String name, Class<T> type, T service) {
this.name = name;
this.type = type;
this.service = service;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Class<T> getType() {
return type;
}
public void setType(Class<T> type) {
this.type = type;
}
public T getService() {
return service;
}
public void setService(T service) {
this.service = service;
}
@Override
public int hashCode() {
int hash = 7;
hash = 97 * hash + Objects.hashCode(this.name);
hash = 97 * hash + Objects.hashCode(this.type);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
final InterceptorServiceWrapper<?> other = (InterceptorServiceWrapper<?>) obj;
return Objects.equals(this.name, other.name) && Objects.equals(this.type, other.type);
}
}
}

View File

@@ -69,7 +69,7 @@ public abstract class NodeServer {
private InetSocketAddress sncpAddress;
//加载Service时的处理函数
protected Consumer<ServiceWrapper> consumer;
protected Consumer<Service> consumer;
//server节点的配置
protected AnyValue serverConf;
@@ -78,13 +78,17 @@ public abstract class NodeServer {
protected NodeInterceptor interceptor;
//供interceptor使用的Service对象集合
protected final Set<NodeInterceptor.InterceptorServiceWrapper> interceptorServiceWrappers = new LinkedHashSet<>();
protected final Set<Service> interceptorServices = new LinkedHashSet<>();
//本地模式的Service对象集合
protected final Set<ServiceWrapper> localServiceWrappers = new LinkedHashSet<>();
protected final Set<Service> localServices = new LinkedHashSet<>();
//远程模式的Service对象集合
protected final Set<ServiceWrapper> remoteServiceWrappers = new LinkedHashSet<>();
protected final Set<Service> remoteServices = new LinkedHashSet<>();
private volatile int maxClassNameLength = 0;
private volatile int maxNameLength = 0;
public NodeServer(Application application, Server server) {
this.application = application;
@@ -228,16 +232,15 @@ public abstract class NodeServer {
Transport sameGroupTransport = Sncp.getSameGroupTransport((Service) src);
List<Transport> diffGroupTransports = Arrays.asList(Sncp.getDiffGroupTransports((Service) src));
final InetSocketAddress sncpAddr = client == null ? null : client.getClientAddress();
if ((src instanceof DataSource) && sncpAddr != null && resourceFactory.find(resourceName, DataCacheListener.class) == null) { //只有DataSourceService 才能赋值 DataCacheListener
Service cacheListenerService = Sncp.createLocalService(resourceName, getExecutor(), appResFactory, DataCacheListenerService.class, sncpAddr, sameGroupTransport, diffGroupTransports);
appResFactory.register(resourceName, DataCacheListener.class, cacheListenerService);
if ((src instanceof DataSource) && sncpAddr != null && resourceFactory.find(resourceName, DataCacheListener.class) == null) { //只有DataSourceService 才能赋值 DataCacheListener
final NodeSncpServer sncpServer = application.findNodeSncpServer(sncpAddr);
Set<String> gs = application.findSncpGroups(sameGroupTransport, diffGroupTransports);
ServiceWrapper wrapper = new ServiceWrapper(DataCacheListenerService.class, cacheListenerService, resourceName, sncpServer.getSncpGroup(), gs, null);
localServiceWrappers.add(wrapper);
sncpServer.consumerAccept(wrapper);
Service cacheListenerService = Sncp.createLocalService(resourceName, getExecutor(), appResFactory, DataCacheListenerService.class, sncpAddr, sncpServer.getSncpGroup(), gs, Sncp.getConf((Service) src), sameGroupTransport, diffGroupTransports);
appResFactory.register(resourceName, DataCacheListener.class, cacheListenerService);
localServices.add(cacheListenerService);
sncpServer.consumerAccept(cacheListenerService);
rf.inject(cacheListenerService, self);
logger.info("[" + Thread.currentThread().getName() + "] Load Service " + wrapper.getService());
logger.info("[" + Thread.currentThread().getName() + "] Load Service " + cacheListenerService);
}
field.set(src, source);
rf.inject(source, self); // 给其可能包含@Resource的字段赋值;
@@ -251,13 +254,13 @@ public abstract class NodeServer {
try {
if (field.getAnnotation(Resource.class) == null) return;
if ((src instanceof Service) && Sncp.isRemote((Service) src)) return; //远程模式不需要注入 CacheSource
SncpClient client = Sncp.getSncpClient((Service) src);
Transport sameGroupTransport = Sncp.getSameGroupTransport((Service) src);
final Service srcService = (Service) src;
SncpClient client = Sncp.getSncpClient(srcService);
Transport sameGroupTransport = Sncp.getSameGroupTransport(srcService);
Transport[] dts = Sncp.getDiffGroupTransports((Service) src);
List<Transport> diffGroupTransports = dts == null ? new ArrayList<>() : Arrays.asList(dts);
final InetSocketAddress sncpAddr = client == null ? null : client.getClientAddress();
final CacheMemorySource source = Sncp.createLocalService(resourceName, getExecutor(), appResFactory, CacheMemorySource.class, sncpAddr, sameGroupTransport, diffGroupTransports);
final CacheMemorySource source = Sncp.createLocalService(resourceName, getExecutor(), appResFactory, CacheMemorySource.class, sncpAddr, Sncp.getSncpGroup(srcService), Sncp.getGroups(srcService), Sncp.getConf(srcService), sameGroupTransport, diffGroupTransports);
Type genericType = field.getGenericType();
ParameterizedType pt = (genericType instanceof ParameterizedType) ? (ParameterizedType) genericType : null;
Type valType = pt == null ? null : pt.getActualTypeArguments()[1];
@@ -273,9 +276,8 @@ public abstract class NodeServer {
if ((src instanceof WebSocketNodeService) && sncpAddr != null) { //只有WebSocketNodeService的服务才需要给SNCP服务注入CacheMemorySource
NodeSncpServer sncpServer = application.findNodeSncpServer(sncpAddr);
Set<String> gs = application.findSncpGroups(sameGroupTransport, diffGroupTransports);
ServiceWrapper wrapper = new ServiceWrapper(CacheMemorySource.class, (Service) source, resourceName, sncpServer.getSncpGroup(), gs, null);
sncpServer.getSncpServer().addSncpServlet(wrapper);
logger.info("[" + Thread.currentThread().getName() + "] Load Service " + wrapper.getService());
sncpServer.getSncpServer().addSncpServlet((Service) source);
logger.info("[" + Thread.currentThread().getName() + "] Load Service " + source);
}
logger.info("[" + Thread.currentThread().getName() + "] Load Source " + source);
} catch (Exception e) {
@@ -305,7 +307,7 @@ public abstract class NodeServer {
if (entry.getName().contains("$")) throw new RuntimeException("<name> value cannot contains '$' in " + entry.getProperty());
Service oldother = resourceFactory.find(entry.getName(), serviceImplClass);
if (oldother != null) { //Server加载Service时需要判断是否已经加载过了。
interceptorServiceWrappers.add(new NodeInterceptor.InterceptorServiceWrapper(entry.getName(), serviceImplClass, oldother));
interceptorServices.add(oldother);
continue;
}
final HashSet<String> groups = entry.getGroups(); //groups.isEmpty()表示<services>没有配置groups属性。
@@ -321,26 +323,26 @@ public abstract class NodeServer {
Service service;
if (localed) { //本地模式
service = Sncp.createLocalService(entry.getName(), getExecutor(), application.getResourceFactory(), serviceImplClass,
NodeServer.this.sncpAddress, loadTransport(NodeServer.this.sncpGroup), loadTransports(groups));
NodeServer.this.sncpAddress, NodeServer.this.sncpGroup, groups, entry.getProperty(), loadTransport(NodeServer.this.sncpGroup), loadTransports(groups));
} else {
service = Sncp.createRemoteService(entry.getName(), getExecutor(), serviceImplClass, NodeServer.this.sncpAddress, loadTransport(groups));
service = Sncp.createRemoteService(entry.getName(), getExecutor(), serviceImplClass, NodeServer.this.sncpAddress, null, groups, entry.getProperty(), loadTransport(groups));
}
if (SncpClient.parseMethod(serviceImplClass).isEmpty()) return; //class没有可用的方法 通常为BaseService
final ServiceWrapper wrapper = new ServiceWrapper(serviceImplClass, service, entry.getName(), localed ? NodeServer.this.sncpGroup : null, groups, entry.getProperty());
for (final Class restype : wrapper.getTypes()) {
if (resourceFactory.find(wrapper.getName(), restype) == null) {
regFactory.register(wrapper.getName(), restype, wrapper.getService());
if (needinject) rf.inject(wrapper.getService()); //动态加载的Service也存在按需加载的注入资源
//final ServiceWrapper wrapper = new ServiceWrapper(serviceImplClass, service, entry.getName(), localed ? NodeServer.this.sncpGroup : null, groups, entry.getProperty());
for (final Class restype : Sncp.getResourceTypes(service)) {
if (resourceFactory.find(entry.getName(), restype) == null) {
regFactory.register(entry.getName(), restype, service);
if (needinject) rf.inject(service); //动态加载的Service也存在按需加载的注入资源
} else if (isSNCP() && !entry.isAutoload()) {
throw new RuntimeException(ServiceWrapper.class.getSimpleName() + "(class:" + serviceImplClass.getName() + ", name:" + entry.getName() + ", group:" + groups + ") is repeat.");
throw new RuntimeException(restype.getSimpleName() + "(class:" + serviceImplClass.getName() + ", name:" + entry.getName() + ", group:" + groups + ") is repeat.");
}
}
if (wrapper.isRemote()) {
remoteServiceWrappers.add(wrapper);
if (Sncp.isRemote(service)) {
remoteServices.add(service);
} else {
localServiceWrappers.add(wrapper);
interceptorServiceWrappers.add(new NodeInterceptor.InterceptorServiceWrapper(entry.getName(), serviceImplClass, service));
if (consumer != null) consumer.accept(wrapper);
localServices.add(service);
interceptorServices.add(service);
if (consumer != null) consumer.accept(service);
}
} catch (RuntimeException ex) {
throw ex;
@@ -352,7 +354,9 @@ public abstract class NodeServer {
ResourceFactory.ResourceLoader resourceLoader = (ResourceFactory rf, final Object src, final String resourceName, Field field, final Object attachment) -> {
runner.accept(rf, true);
};
for (final Class restype : ServiceWrapper.parseTypes(entry.getType())) {
ResourceType rty = entry.getType().getAnnotation(ResourceType.class);
Class[] resTypes = rty == null ? new Class[]{} : rty.value();
for (final Class restype : resTypes) {
resourceFactory.register(resourceLoader, restype);
}
} else {
@@ -366,30 +370,38 @@ public abstract class NodeServer {
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
//---------------- inject ----------------
new ArrayList<>(localServiceWrappers).forEach(y -> {
resourceFactory.inject(y.getService(), NodeServer.this);
new ArrayList<>(localServices).forEach(y -> {
resourceFactory.inject(y, NodeServer.this);
calcMaxLength(y);
});
new ArrayList<>(remoteServiceWrappers).forEach(y -> {
resourceFactory.inject(y.getService(), NodeServer.this);
new ArrayList<>(remoteServices).forEach(y -> {
resourceFactory.inject(y, NodeServer.this);
calcMaxLength(y);
});
if (sb != null) {
remoteServiceWrappers.forEach(y -> {
sb.append(threadName).append(y.toSimpleString()).append(" load and inject").append(LINE_SEPARATOR);
remoteServices.forEach(y -> {
sb.append(threadName).append(Sncp.toSimpleString(y, maxNameLength, maxClassNameLength)).append(" load and inject").append(LINE_SEPARATOR);
});
}
//----------------- init -----------------
List<ServiceWrapper> swlist = new ArrayList<>(localServiceWrappers);
Collections.sort(swlist);
localServiceWrappers.clear();
localServiceWrappers.addAll(swlist);
List<Service> swlist = new ArrayList<>(localServices);
Collections.sort(swlist, (o1, o2) -> {
int rs = Sncp.getResourceTypes(o1)[0].getName().compareTo(Sncp.getResourceTypes(o2)[0].getName());
if (rs == 0) rs = Sncp.getResourceName(o1).compareTo(Sncp.getResourceName(o2));
return rs;
});
localServices.clear();
localServices.addAll(swlist);
final List<String> slist = sb == null ? null : new CopyOnWriteArrayList<>();
CountDownLatch clds = new CountDownLatch(localServiceWrappers.size());
localServiceWrappers.parallelStream().forEach(y -> {
CountDownLatch clds = new CountDownLatch(localServices.size());
localServices.parallelStream().forEach(y -> {
try {
long s = System.currentTimeMillis();
y.getService().init(y.getConf());
y.init(Sncp.getConf(y));
long e = System.currentTimeMillis() - s;
if (slist != null) slist.add(new StringBuilder().append(threadName).append(y.toSimpleString()).append(" load and init in ").append(e).append(" ms").append(LINE_SEPARATOR).toString());
String serstr = Sncp.toSimpleString(y, maxNameLength, maxClassNameLength);
if (slist != null) slist.add(new StringBuilder().append(threadName).append(serstr).append(" load and init in ").append(e).append(" ms").append(LINE_SEPARATOR).toString());
} finally {
clds.countDown();
}
@@ -405,6 +417,20 @@ public abstract class NodeServer {
if (sb != null && sb.length() > 0) logger.log(Level.INFO, sb.toString());
}
private void calcMaxLength(Service y) { //计算toString中的长度
maxNameLength = Math.max(maxNameLength, Sncp.getResourceName(y).length());
StringBuilder s = new StringBuilder();
Class[] types = Sncp.getResourceTypes(y);
if (types.length == 1) {
s.append(types[0].getName());
} else {
s.append('[');
s.append(Arrays.asList(types).stream().map((Class t) -> t.getName()).collect(Collectors.joining(",")));
s.append(']');
}
maxClassNameLength = Math.max(maxClassNameLength, s.length() + 1);
}
protected List<Transport> loadTransports(final HashSet<String> groups) {
if (groups == null) return null;
final List<Transport> transports = new ArrayList<>();
@@ -559,12 +585,12 @@ public abstract class NodeServer {
public void shutdown() throws IOException {
if (interceptor != null) interceptor.preShutdown(this);
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
localServiceWrappers.forEach(y -> {
localServices.forEach(y -> {
long s = System.currentTimeMillis();
y.getService().destroy(y.getConf());
y.destroy(Sncp.getConf(y));
long e = System.currentTimeMillis() - s;
if (e > 2 && sb != null) {
sb.append(y.toSimpleString()).append(" destroy ").append(e).append("ms").append(LINE_SEPARATOR);
sb.append(Sncp.toSimpleString(y, maxNameLength, maxClassNameLength)).append(" destroy ").append(e).append("ms").append(LINE_SEPARATOR);
}
});
if (sb != null && sb.length() > 0) logger.log(Level.INFO, sb.toString());
@@ -575,16 +601,16 @@ public abstract class NodeServer {
return (T) server;
}
public Set<NodeInterceptor.InterceptorServiceWrapper> getInterceptorServiceWrappers() {
return new LinkedHashSet<>(interceptorServiceWrappers);
public Set<Service> getInterceptorServices() {
return new LinkedHashSet<>(interceptorServices);
}
public Set<ServiceWrapper> getLocalServiceWrappers() {
return new LinkedHashSet<>(localServiceWrappers);
public Set<Service> getLocalServices() {
return new LinkedHashSet<>(localServices);
}
public Set<ServiceWrapper> getRemoteServiceWrappers() {
return new LinkedHashSet<>(remoteServiceWrappers);
public Set<Service> getRemoteServices() {
return new LinkedHashSet<>(remoteServices);
}
}

View File

@@ -10,6 +10,7 @@ import java.util.*;
import java.util.logging.*;
import org.redkale.net.*;
import org.redkale.net.sncp.*;
import org.redkale.service.Service;
import org.redkale.util.*;
/**
@@ -48,8 +49,8 @@ public class NodeSncpServer extends NodeServer {
return sncpServer == null ? null : sncpServer.getSocketAddress();
}
public void consumerAccept(ServiceWrapper wrapper) {
if (this.consumer != null) this.consumer.accept(wrapper);
public void consumerAccept(Service service) {
if (this.consumer != null) this.consumer.accept(service);
}
@Override

View File

@@ -1,156 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.net.sncp;
import java.util.*;
import java.util.stream.Collectors;
import org.redkale.service.Service;
import org.redkale.util.*;
/**
* Service对象的封装类
*
*
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <T> Service的子类
*/
public final class ServiceWrapper<T extends Service> implements Comparable<ServiceWrapper> {
private static volatile int maxClassNameLength = 0;
private static volatile int maxNameLength = 0;
private final T service;
private final AnyValue conf;
private final String sncpGroup; //自身的组节点名 可能为null
private final Set<String> groups; //所有的组节点,包含自身
private final String name;
private final boolean remote;
private final Class[] types;
public ServiceWrapper(T service, String name, String sncpGroup, Set<String> groups, AnyValue conf) {
this(null, service, name, sncpGroup, groups, conf);
}
@SuppressWarnings("unchecked")
public ServiceWrapper(Class<T> type, T service, String name, String sncpGroup, Set<String> groups, AnyValue conf) {
this.service = service;
this.conf = conf;
this.sncpGroup = sncpGroup;
this.groups = groups;
this.name = name;
this.remote = Sncp.isRemote(service);
ResourceType rty = service.getClass().getAnnotation(ResourceType.class);
this.types = rty == null ? new Class[]{type == null ? (Class<T>) service.getClass() : type} : rty.value();
maxNameLength = Math.max(maxNameLength, name.length());
StringBuilder s = new StringBuilder();
if (this.types.length == 1) {
s.append(types[0].getName());
} else {
s.append('[');
s.append(Arrays.asList(this.types).stream().map((Class t) -> t.getName()).collect(Collectors.joining(",")));
s.append(']');
}
maxClassNameLength = Math.max(maxClassNameLength, s.length() + 1);
}
public static Class[] parseTypes(final Class<? extends Service> servicetype) {
ResourceType rty = servicetype.getAnnotation(ResourceType.class);
return rty == null ? new Class[]{servicetype} : rty.value();
}
@Override
public String toString() {
return toSimpleString();
}
public String toSimpleString() {
StringBuilder sb = new StringBuilder();
sb.append(remote ? "RemoteService" : "LocalService ");
int len;
if (types.length == 1) {
sb.append("(type= ").append(types[0].getName());
len = maxClassNameLength - types[0].getName().length();
} else {
StringBuilder s = new StringBuilder();
s.append('[');
s.append(Arrays.asList(this.types).stream().map((Class t) -> t.getName()).collect(Collectors.joining(",")));
s.append(']');
sb.append("(types=").append(s);
len = maxClassNameLength - s.length();
}
for (int i = 0; i < len; i++) {
sb.append(' ');
}
sb.append(", name='").append(name).append("'");
for (int i = 0; i < maxNameLength - name.length(); i++) {
sb.append(' ');
}
sb.append(")");
return sb.toString();
}
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null) return false;
if (!(obj instanceof ServiceWrapper)) return false;
ServiceWrapper other = (ServiceWrapper) obj;
return (this.types[0].equals(other.types[0]) && this.remote == other.remote && this.name.equals(other.name) && Objects.equals(this.sncpGroup, other.sncpGroup));
}
@Override
public int hashCode() {
int hash = 3;
hash = 67 * hash + Objects.hashCode(this.types[0]);
hash = 67 * hash + Objects.hashCode(this.sncpGroup);
hash = 67 * hash + Objects.hashCode(this.name);
hash = 67 * hash + (this.remote ? 1 : 0);
return hash;
}
@Override
public int compareTo(ServiceWrapper o) {
int rs = this.types[0].getName().compareTo(o.types[0].getName());
if (rs == 0) rs = this.name.compareTo(o.name);
return rs;
}
public Class[] getTypes() {
return types;
}
public Service getService() {
return service;
}
public AnyValue getConf() {
return conf;
}
public String getName() {
return name;
}
public boolean isRemote() {
return remote;
}
public Set<String> getGroups() {
return groups;
}
}

View File

@@ -11,6 +11,7 @@ import java.net.InetSocketAddress;
import java.security.*;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import static jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES;
import jdk.internal.org.objectweb.asm.*;
@@ -92,6 +93,62 @@ public abstract class Sncp {
return dyn != null && dyn.remote();
}
public static String getResourceName(Service service) {
if (service == null) return null;
Resource res = service.getClass().getAnnotation(Resource.class);
return res == null ? null : res.name();
}
public static Class getServiceType(Service service) {
if (service == null) return null;
try {
Field ts = service.getClass().getDeclaredField(FIELDPREFIX + "_service_type");
ts.setAccessible(true);
return (Class) ts.get(service);
} catch (Exception e) {
throw new RuntimeException(service + " not found " + FIELDPREFIX + "_service_type");
}
}
public static Class[] getResourceTypes(Service service) {
if (service == null) return null;
ResourceType types = service.getClass().getAnnotation(ResourceType.class);
return types == null ? new Class[]{getServiceType(service)} : types.value();
}
public static String getSncpGroup(Service service) {
if (service == null) return null;
try {
Field ts = service.getClass().getDeclaredField(FIELDPREFIX + "_sncpGroup");
ts.setAccessible(true);
return (String) ts.get(service);
} catch (Exception e) {
throw new RuntimeException(service + " not found " + FIELDPREFIX + "_sncpGroup");
}
}
public static Set<String> getGroups(Service service) {
if (service == null) return null;
try {
Field ts = service.getClass().getDeclaredField(FIELDPREFIX + "_groups");
ts.setAccessible(true);
return (Set) ts.get(service);
} catch (Exception e) {
throw new RuntimeException(service + " not found " + FIELDPREFIX + "_groups");
}
}
public static AnyValue getConf(Service service) {
if (service == null) return null;
try {
Field ts = service.getClass().getDeclaredField(FIELDPREFIX + "_conf");
ts.setAccessible(true);
return (AnyValue) ts.get(service);
} catch (Exception e) {
throw new RuntimeException(service + " not found " + FIELDPREFIX + "_conf");
}
}
public static SncpClient getSncpClient(Service service) {
if (service == null) return null;
try {
@@ -155,10 +212,43 @@ public abstract class Sncp {
throw new RuntimeException(param + "'s sncp_getParams method cannot final modifier");
} else if (m.getName().equals("sncp_setParams") && Modifier.isFinal(m.getModifiers())) {
throw new RuntimeException(param + "'s sncp_setParams method cannot final modifier");
} else if (m.getName().equals("sncp_setFuture") && Modifier.isFinal(m.getModifiers())) {
throw new RuntimeException(param + "'s sncp_setFuture method cannot final modifier");
} else if (m.getName().equals("sncp_getFuture") && Modifier.isFinal(m.getModifiers())) {
throw new RuntimeException(param + "'s sncp_getFuture method cannot final modifier");
}
}
}
public static String toSimpleString(final Service service, int maxNameLength, int maxClassNameLength) {
StringBuilder sb = new StringBuilder();
sb.append(isRemote(service) ? "RemoteService" : "LocalService ");
int len;
Class[] types = getResourceTypes(service);
String name = getResourceName(service);
if (types.length == 1) {
sb.append("(type= ").append(types[0].getName());
len = maxClassNameLength - types[0].getName().length();
} else {
StringBuilder s = new StringBuilder();
s.append('[');
s.append(Arrays.asList(types).stream().map((Class t) -> t.getName()).collect(Collectors.joining(",")));
s.append(']');
sb.append("(types=").append(s);
len = maxClassNameLength - s.length();
}
for (int i = 0; i < len; i++) {
sb.append(' ');
}
sb.append(", name='").append(name).append("'");
for (int i = 0; i < maxNameLength - name.length(); i++) {
sb.append(' ');
}
sb.append(")");
return sb.toString();
}
/**
* <blockquote><pre>
* public class TestService implements Service{
@@ -185,12 +275,20 @@ public abstract class Sncp {
* &#64;ResourceType({TestService.class})
* public final class _DynLocalTestService extends TestService{
*
* private static final Class _redkale_service_type = TestService.class;
*
* &#64;Resource
* private BsonConvert _redkale_bsonConvert;
*
* &#64;Resource
* private JsonConvert _redkale_jsonConvert;
*
* private AnyValue _redkale_conf;
*
* private String _redkale_sncpGroup; //自身的组节点名 可能为null
*
* private Set&lt;String&gt; groups; //所有的组节点,包含自身
*
* private Transport _redkale_sameGroupTransport;
*
* private Transport[] _redkale_diffGroupTransports;
@@ -235,36 +333,38 @@ public abstract class Sncp {
*
* 创建Service的本地模式Class
*
* @param <T> Service子类
* @param name 资源名
* @param serviceClass Service类
* @param <T> Service子类
* @param name 资源名
* @param serviceImplClass Service类
*
* @return Service实例
*/
@SuppressWarnings("unchecked")
protected static <T extends Service> Class<? extends T> createLocalServiceClass(final String name, final Class<T> serviceClass) {
if (serviceClass == null) return null;
if (!Service.class.isAssignableFrom(serviceClass)) return serviceClass;
int mod = serviceClass.getModifiers();
if (!java.lang.reflect.Modifier.isPublic(mod)) return serviceClass;
if (java.lang.reflect.Modifier.isAbstract(mod)) return serviceClass;
final List<Method> methods = SncpClient.parseMethod(serviceClass);
final String supDynName = serviceClass.getName().replace('.', '/');
protected static <T extends Service> Class<? extends T> createLocalServiceClass(final String name, final Class<T> serviceImplClass) {
if (serviceImplClass == null) return null;
if (!Service.class.isAssignableFrom(serviceImplClass)) return serviceImplClass;
int mod = serviceImplClass.getModifiers();
if (!java.lang.reflect.Modifier.isPublic(mod)) return serviceImplClass;
if (java.lang.reflect.Modifier.isAbstract(mod)) return serviceImplClass;
final List<Method> methods = SncpClient.parseMethod(serviceImplClass);
final String supDynName = serviceImplClass.getName().replace('.', '/');
final String clientName = SncpClient.class.getName().replace('.', '/');
final String clientDesc = Type.getDescriptor(SncpClient.class);
final String bsonConvertDesc = Type.getDescriptor(BsonConvert.class);
final String jsonConvertDesc = Type.getDescriptor(JsonConvert.class);
final String stringDesc = Type.getDescriptor(String.class);
final String anyValueDesc = Type.getDescriptor(AnyValue.class);
final String sncpDynDesc = Type.getDescriptor(SncpDyn.class);
final String transportDesc = Type.getDescriptor(Transport.class);
final String transportsDesc = Type.getDescriptor(Transport[].class);
ClassLoader loader = Sncp.class.getClassLoader();
String newDynName = supDynName.substring(0, supDynName.lastIndexOf('/') + 1) + LOCALPREFIX + serviceClass.getSimpleName();
String newDynName = supDynName.substring(0, supDynName.lastIndexOf('/') + 1) + LOCALPREFIX + serviceImplClass.getSimpleName();
if (!name.isEmpty()) {
boolean normal = true;
for (char ch : name.toCharArray()) {
if (!((ch >= '0' && ch <= '9') || ch == '_' || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))) normal = false;
}
if (!normal) throw new RuntimeException(serviceClass + "'s resource name is illegal, must be 0-9 _ a-z A-Z");
if (!normal) throw new RuntimeException(serviceImplClass + "'s resource name is illegal, must be 0-9 _ a-z A-Z");
newDynName += "_" + (normal ? name : hash(name));
}
try {
@@ -289,7 +389,7 @@ public abstract class Sncp {
av0.visitEnd();
}
{ //给新类加上 原有的Annotation
for (Annotation ann : serviceClass.getAnnotations()) {
for (Annotation ann : serviceImplClass.getAnnotations()) {
if (ann instanceof Resource || ann instanceof SncpDyn || ann instanceof ResourceType) continue;
visitAnnotation(cw.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann);
}
@@ -298,9 +398,9 @@ public abstract class Sncp {
av0 = cw.visitAnnotation(Type.getDescriptor(ResourceType.class), true);
{
AnnotationVisitor av1 = av0.visitArray("value");
ResourceType rty = serviceClass.getAnnotation(ResourceType.class);
ResourceType rty = serviceImplClass.getAnnotation(ResourceType.class);
if (rty == null) {
av1.visit(null, Type.getType(Type.getDescriptor(serviceClass)));
av1.visit(null, Type.getType(Type.getDescriptor(serviceImplClass)));
} else {
for (Class cl : rty.value()) {
av1.visit(null, Type.getType(Type.getDescriptor(cl)));
@@ -310,7 +410,10 @@ public abstract class Sncp {
}
av0.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE + ACC_FINAL + ACC_STATIC, FIELDPREFIX + "_service_type", "Ljava/lang/Class;", null, null);
fv.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_bsonConvert", bsonConvertDesc, null, null);
av0 = fv.visitAnnotation("Ljavax/annotation/Resource;", true);
@@ -323,6 +426,18 @@ public abstract class Sncp {
av0.visitEnd();
fv.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_conf", anyValueDesc, null, null);
fv.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_sncpGroup", stringDesc, null, null);
fv.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_groups", "Ljava/util/Set;", "Ljava/util/Set<Ljava/lang/String;>;", null);
fv.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_sameGroupTransport", transportDesc, null, null);
fv.visitEnd();
@@ -340,6 +455,14 @@ public abstract class Sncp {
fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_selfstring", "Ljava/lang/String;", null, null);
fv.visitEnd();
}
{//静态构造函数
mv = new AsmMethodVisitor(cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null));
mv.visitLdcInsn(Type.getType(Type.getDescriptor(serviceImplClass)));
mv.visitFieldInsn(PUTSTATIC, newDynName, FIELDPREFIX + "_service_type", "Ljava/lang/Class;");
mv.visitInsn(RETURN);
mv.visitMaxs(1, 0);
mv.visitEnd();
}
{ //构造函数
mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null));
//mv.setDebug(true);
@@ -762,6 +885,10 @@ public abstract class Sncp {
}
}
public static <T extends Service> T createSimpleLocalService(final String name, final Class<T> serviceImplClass, final InetSocketAddress clientAddress, final Transport sameGroupTransport) {
return createLocalService(name, null, ResourceFactory.root(), serviceImplClass, clientAddress, null, new HashSet<>(), null, sameGroupTransport, null);
}
/**
*
* 创建本地模式Service实例
@@ -770,16 +897,28 @@ public abstract class Sncp {
* @param name 资源名
* @param executor 线程池
* @param resourceFactory 资源容器
* @param serviceImplClass Service类
* @param serviceImplClass Service类
* @param clientAddress 本地IP地址
* @param sncpGroup 自身的组节点名 可能为null
* @param groups 所有的组节点,包含自身
* @param conf 启动配置项
* @param sameGroupTransport 同组的通信组件
* @param diffGroupTransports 异组的通信组件列表
*
* @return Service的本地模式实例
*/
@SuppressWarnings("unchecked")
public static <T extends Service> T createLocalService(final String name, final Consumer<Runnable> executor, final ResourceFactory resourceFactory,
final Class<T> serviceImplClass, final InetSocketAddress clientAddress, final Transport sameGroupTransport, final Collection<Transport> diffGroupTransports) {
public static <T extends Service> T createLocalService(
final String name,
final Consumer<Runnable> executor,
final ResourceFactory resourceFactory,
final Class<T> serviceImplClass,
final InetSocketAddress clientAddress,
final String sncpGroup,
final Set<String> groups,
final AnyValue conf,
final Transport sameGroupTransport,
final Collection<Transport> diffGroupTransports) {
try {
final Class newClazz = createLocalServiceClass(name, serviceImplClass);
T rs = (T) newClazz.newInstance();
@@ -813,7 +952,7 @@ public abstract class Sncp {
}
}
if (remoteService == null && remoteTransport != null) {
remoteService = createRemoteService(name, executor, serviceImplClass, clientAddress, remoteTransport);
remoteService = createRemoteService(name, executor, serviceImplClass, clientAddress, sncpGroup, groups, conf, remoteTransport);
}
if (remoteService != null) field.set(rs, remoteService);
}
@@ -836,13 +975,13 @@ public abstract class Sncp {
sb.append(", serviceid = ").append(client.getServiceid());
sb.append(", serviceversion = ").append(client.getServiceversion());
sb.append(", action.size = ").append(client.getActionCount());
List<String> groups = new ArrayList<>();
if (sameGroupTransport != null) groups.add(sameGroupTransport.getName());
if (diffGroupTransports != null) {
for (Transport t : diffGroupTransports) {
groups.add(t.getName());
}
}
// List<String> groups = new ArrayList<>();
// if (sameGroupTransport != null) groups.add(sameGroupTransport.getName());
// if (diffGroupTransports != null) {
// for (Transport t : diffGroupTransports) {
// groups.add(t.getName());
// }
// }
sb.append(", address = ").append(clientAddress).append(", groups = ").append(groups);
sb.append(", sameaddrs = ").append(sameGroupTransport == null ? null : Arrays.asList(sameGroupTransport.getRemoteAddresses()));
@@ -862,6 +1001,21 @@ public abstract class Sncp {
s.set(rs, sb.toString());
}
if (client == null) return rs;
{
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_sncpGroup");
c.setAccessible(true);
c.set(rs, sncpGroup);
}
{
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_groups");
c.setAccessible(true);
c.set(rs, groups);
}
{
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_conf");
c.setAccessible(true);
c.set(rs, conf);
}
{
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_sameGroupTransport");
c.setAccessible(true);
@@ -881,6 +1035,10 @@ public abstract class Sncp {
}
public static <T extends Service> T createSimpleRemoteService(final String name, final Class<T> serviceTypeOrImplClass, final InetSocketAddress clientAddress, final Transport transport) {
return createRemoteService(name, null, serviceTypeOrImplClass, clientAddress, (String) null, new HashSet<>(), (AnyValue) null, transport);
}
/**
* <blockquote><pre>
* &#64;Resource(name = "")
@@ -888,12 +1046,20 @@ public abstract class Sncp {
* &#64;ResourceType({TestService.class})
* public final class _DynRemoteTestService extends TestService{
*
* private static final Class _redkale_service_type = TestService.class;
*
* &#64;Resource
* private BsonConvert _redkale_bsonConvert;
*
* &#64;Resource
* private JsonConvert _redkale_jsonConvert;
*
* private String _redkale_sncpGroup; //自身的组节点名 可能为null
*
* private Set&lt;String&gt; groups; //所有的组节点,包含自身
*
* private AnyValue _redkale_conf;
*
* private Transport _redkale_transport;
*
* private SncpClient _redkale_client;
@@ -934,18 +1100,28 @@ public abstract class Sncp {
*
* 创建远程模式的Service实例
*
* @param <T> Service泛型
* @param name 资源名
* @param executor 线程池
* @param serviceTypeOrImplClass Service类
* @param clientAddress 本地IP地址
* @param transport 通信组件
* @param <T> Service泛型
* @param name 资源名
* @param executor 线程池
* @param serviceTypeOrImplClass Service类
* @param clientAddress 本地IP地址
* @param sncpGroup 自身的组节点名 可能为null
* @param groups 所有的组节点,包含自身
* @param conf 启动配置项
* @param transport 通信组件
*
* @return Service的远程模式实例
*/
@SuppressWarnings("unchecked")
public static <T extends Service> T createRemoteService(final String name, final Consumer<Runnable> executor, final Class<T> serviceTypeOrImplClass,
final InetSocketAddress clientAddress, final Transport transport) {
public static <T extends Service> T createRemoteService(
final String name,
final Consumer<Runnable> executor,
final Class<T> serviceTypeOrImplClass,
final InetSocketAddress clientAddress,
final String sncpGroup,
final Set<String> groups,
final AnyValue conf,
final Transport transport) {
if (serviceTypeOrImplClass == null) return null;
if (!Service.class.isAssignableFrom(serviceTypeOrImplClass)) return null;
int mod = serviceTypeOrImplClass.getModifiers();
@@ -958,6 +1134,7 @@ public abstract class Sncp {
final String bsonConvertDesc = Type.getDescriptor(BsonConvert.class);
final String jsonConvertDesc = Type.getDescriptor(JsonConvert.class);
final String transportDesc = Type.getDescriptor(Transport.class);
final String stringDesc = Type.getDescriptor(String.class);
final String anyValueDesc = Type.getDescriptor(AnyValue.class);
ClassLoader loader = Sncp.class.getClassLoader();
String newDynName = supDynName.substring(0, supDynName.lastIndexOf('/') + 1) + REMOTEPREFIX + serviceTypeOrImplClass.getSimpleName();
@@ -1026,6 +1203,10 @@ public abstract class Sncp {
visitAnnotation(cw.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann);
}
}
{
fv = cw.visitField(ACC_PRIVATE + ACC_FINAL + ACC_STATIC, FIELDPREFIX + "_service_type", "Ljava/lang/Class;", null, null);
fv.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_bsonConvert", bsonConvertDesc, null, null);
av0 = fv.visitAnnotation("Ljavax/annotation/Resource;", true);
@@ -1038,6 +1219,18 @@ public abstract class Sncp {
av0.visitEnd();
fv.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_sncpGroup", stringDesc, null, null);
fv.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_groups", "Ljava/util/Set;", "Ljava/util/Set<Ljava/lang/String;>;", null);
fv.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_conf", anyValueDesc, null, null);
fv.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_transport", transportDesc, null, null);
fv.visitEnd();
@@ -1050,6 +1243,14 @@ public abstract class Sncp {
fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_selfstring", "Ljava/lang/String;", null, null);
fv.visitEnd();
}
{//静态构造函数
mv = new AsmMethodVisitor(cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null));
mv.visitLdcInsn(Type.getType(Type.getDescriptor(serviceTypeOrImplClass)));
mv.visitFieldInsn(PUTSTATIC, newDynName, FIELDPREFIX + "_service_type", "Ljava/lang/Class;");
mv.visitInsn(RETURN);
mv.visitMaxs(1, 0);
mv.visitEnd();
}
{ //构造函数
mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null));
//mv.setDebug(true);
@@ -1199,13 +1400,32 @@ public abstract class Sncp {
}.loadClass(newDynName.replace('/', '.'), bytes);
try {
T rs = (T) newClazz.newInstance();
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_client");
c.setAccessible(true);
SncpClient client = new SncpClient(name, serviceTypeOrImplClass, rs, executor, true, realed ? createLocalServiceClass(name, serviceTypeOrImplClass) : serviceTypeOrImplClass, clientAddress);
c.set(rs, client);
Field t = newClazz.getDeclaredField(FIELDPREFIX + "_transport");
t.setAccessible(true);
t.set(rs, transport);
{
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_client");
c.setAccessible(true);
c.set(rs, client);
}
{
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_conf");
c.setAccessible(true);
c.set(rs, conf);
}
{
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_sncpGroup");
c.setAccessible(true);
c.set(rs, sncpGroup);
}
{
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_groups");
c.setAccessible(true);
c.set(rs, groups);
}
{
Field t = newClazz.getDeclaredField(FIELDPREFIX + "_transport");
t.setAccessible(true);
t.set(rs, transport);
}
{
StringBuilder sb = new StringBuilder();
sb.append(newClazz.getName()).append("{name = '").append(name);

View File

@@ -162,7 +162,7 @@ public final class SncpClient {
protected final Consumer<Runnable> executor;
public <T extends Service> SncpClient(final String serviceName, final Class<T> serviceType, final T service, final Consumer<Runnable> executor,
public <T extends Service> SncpClient(final String serviceName, final Class<T> serviceTypeOrImplClass, final T service, final Consumer<Runnable> executor,
final boolean remote, final Class serviceClass, final InetSocketAddress clientAddress) {
this.remote = remote;
this.executor = executor;
@@ -170,7 +170,10 @@ public final class SncpClient {
this.serviceversion = 0;
this.clientAddress = clientAddress;
this.name = serviceName;
this.serviceid = Sncp.hash(serviceType.getName() + ':' + serviceName);
Class tn = serviceTypeOrImplClass;
ResourceType rt = (ResourceType) tn.getAnnotation(ResourceType.class);
if (rt != null && rt.value().length > 0) tn = rt.value()[0];
this.serviceid = Sncp.hash(tn.getName() + ':' + serviceName);
final List<SncpAction> methodens = new ArrayList<>();
//------------------------------------------------------------------------------
for (java.lang.reflect.Method method : parseMethod(serviceClass)) {

View File

@@ -38,15 +38,15 @@ public final class SncpServer extends Server<DLong, SncpContext, SncpRequest, Sn
super.init(config);
}
public void addSncpServlet(ServiceWrapper entry) {
for (Class type : entry.getTypes()) {
SncpDynServlet sds = new SncpDynServlet(BsonFactory.root().getConvert(), entry.getName(), type, entry.getService());
this.prepare.addServlet(sds, null, entry.getConf());
public void addSncpServlet(Service sncpService) {
for (Class type : Sncp.getResourceTypes(sncpService)) {
SncpDynServlet sds = new SncpDynServlet(BsonFactory.root().getConvert(), Sncp.getResourceName(sncpService), type, sncpService);
this.prepare.addServlet(sds, null, Sncp.getConf(sncpService));
}
}
public <T extends Service> void addSncpServlet(Class<T> serviceType, String name, T service, AnyValue conf) {
SncpDynServlet sds = new SncpDynServlet(BsonFactory.root().getConvert(), name, serviceType, service);
public <T extends Service> void addSncpServlet(Class<T> serviceTypeClass, String name, T service, AnyValue conf) {
SncpDynServlet sds = new SncpDynServlet(BsonFactory.root().getConvert(), name, serviceTypeClass, service);
this.prepare.addServlet(sds, null, conf);
}