use of org.redkale.mq.MessageAgent in project redkale by redkale.
the class NodeHttpServer method loadRestServlet.
@SuppressWarnings("unchecked")
protected void loadRestServlet(final ClassFilter<? extends WebSocket> webSocketFilter, final AnyValue restConf, final List<Object> restedObjects, final StringBuilder sb, final List<AbstractMap.SimpleEntry<String, String[]>> rests, final List<AbstractMap.SimpleEntry<String, String[]>> webss) throws Exception {
if (!rest)
return;
// 不存在REST服务
if (restConf == null)
return;
String prefix0 = restConf.getValue("path", "");
if (!prefix0.isEmpty() && prefix0.charAt(prefix0.length() - 1) == '/')
prefix0 = prefix0.substring(0, prefix0.length() - 1);
if (!prefix0.isEmpty() && prefix0.charAt(0) != '/')
prefix0 = '/' + prefix0;
final String localThreadName = "[" + Thread.currentThread().getName() + "] ";
String mqname = restConf.getValue("mq");
MessageAgent agent0 = null;
if (mqname != null) {
agent0 = application.getMessageAgent(mqname);
if (agent0 == null)
throw new RuntimeException("not found " + MessageAgent.class.getSimpleName() + " config for (name=" + mqname + ")");
}
final MessageAgent messageAgent = agent0;
// 开启MQ时,prefix字段失效
if (messageAgent != null)
prefix0 = "";
final String prefix = prefix0;
final boolean autoload = restConf.getBoolValue("autoload", true);
{
// 加载RestService
String userTypeStr = restConf.getValue("usertype");
final Class userType = userTypeStr == null ? null : this.serverClassLoader.loadClass(userTypeStr);
final Class baseServletType = this.serverClassLoader.loadClass(restConf.getValue("base", HttpServlet.class.getName()));
final Set<String> includeValues = new HashSet<>();
final Set<String> excludeValues = new HashSet<>();
for (AnyValue item : restConf.getAnyValues("service")) {
if (item.getBoolValue("ignore", false)) {
excludeValues.add(item.getValue("value", ""));
} else {
includeValues.add(item.getValue("value", ""));
}
}
final ClassFilter restFilter = ClassFilter.create(serverClassLoader, null, application.isCompileMode() ? "" : restConf.getValue("includes", ""), application.isCompileMode() ? "" : restConf.getValue("excludes", ""), includeValues, excludeValues);
final CountDownLatch scdl = new CountDownLatch(super.interceptorServices.size());
Stream<Service> stream = super.interceptorServices.stream();
// 不能并行,否则在maven plugin运行环境下ClassLoader不对
if (!application.isCompileMode())
stream = stream.parallel();
stream.forEach((service) -> {
try {
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;
final String stypename = stype.getName();
if (!autoload && !includeValues.contains(stypename))
return;
if (!restFilter.accept(stypename))
return;
synchronized (restedObjects) {
if (restedObjects.contains(service)) {
logger.log(Level.WARNING, stype.getName() + " repeat create rest servlet, so ignore");
return;
}
// 避免重复创建Rest对象
restedObjects.add(service);
}
HttpServlet servlet = httpServer.addRestServlet(serverClassLoader, service, userType, baseServletType, prefix);
// 没有HttpMapping方法的HttpServlet调用Rest.createRestServlet就会返回null
if (servlet == null)
return;
String prefix2 = prefix;
WebServlet ws = servlet.getClass().getAnnotation(WebServlet.class);
if (ws != null && !ws.repair())
prefix2 = "";
resourceFactory.inject(servlet, NodeHttpServer.this);
dynServletMap.put(service, servlet);
if (messageAgent != null)
messageAgent.putService(this, service, servlet);
// if (finest) logger.finest(localThreadName + " Create RestServlet(resource.name='" + name + "') = " + servlet);
if (rests != null) {
String[] mappings = servlet.getClass().getAnnotation(WebServlet.class).value();
for (int i = 0; i < mappings.length; i++) {
mappings[i] = prefix2 + mappings[i];
}
synchronized (rests) {
rests.add(new AbstractMap.SimpleEntry<>(Sncp.getServiceType(service).getName() + "#" + name, mappings));
}
}
} finally {
scdl.countDown();
}
});
scdl.await();
}
if (webSocketFilter != null) {
// 加载RestWebSocket
final Set<String> includeValues = new HashSet<>();
final Set<String> excludeValues = new HashSet<>();
for (AnyValue item : restConf.getAnyValues("websocket")) {
if (item.getBoolValue("ignore", false)) {
excludeValues.add(item.getValue("value", ""));
} else {
includeValues.add(item.getValue("value", ""));
}
}
final ClassFilter restFilter = ClassFilter.create(serverClassLoader, null, application.isCompileMode() ? "" : restConf.getValue("includes", ""), application.isCompileMode() ? "" : restConf.getValue("excludes", ""), includeValues, excludeValues);
final boolean finest = logger.isLoggable(Level.FINEST);
List<FilterEntry<? extends WebSocket>> list = new ArrayList(webSocketFilter.getFilterEntrys());
for (FilterEntry<? extends WebSocket> en : list) {
Class<WebSocket> clazz = (Class<WebSocket>) en.getType();
if (Modifier.isAbstract(clazz.getModifiers())) {
logger.log(Level.FINE, clazz.getName() + " cannot abstract on rest websocket, so ignore");
continue;
}
if (Modifier.isFinal(clazz.getModifiers())) {
logger.log(Level.FINE, clazz.getName() + " cannot final on rest websocket, so ignore");
continue;
}
final Class<? extends WebSocket> stype = en.getType();
if (stype.getAnnotation(Rest.RestDyn.class) != null)
continue;
RestWebSocket rs = stype.getAnnotation(RestWebSocket.class);
if (rs == null || rs.ignore())
continue;
final String stypename = stype.getName();
if (!autoload && !includeValues.contains(stypename))
continue;
if (!restFilter.accept(stypename))
continue;
if (restedObjects.contains(stype)) {
logger.log(Level.WARNING, stype.getName() + " repeat create rest websocket, so ignore");
continue;
}
// 避免重复创建Rest对象
restedObjects.add(stype);
WebSocketServlet servlet = httpServer.addRestWebSocketServlet(serverClassLoader, stype, messageAgent, prefix, en.getProperty());
// 没有RestOnMessage方法的HttpServlet调用Rest.createRestWebSocketServlet就会返回null
if (servlet == null)
continue;
String prefix2 = prefix;
WebServlet ws = servlet.getClass().getAnnotation(WebServlet.class);
if (ws != null && !ws.repair())
prefix2 = "";
resourceFactory.inject(servlet, NodeHttpServer.this);
if (finest)
logger.finest(localThreadName + " " + stype.getName() + " create a RestWebSocketServlet");
if (webss != null) {
String[] mappings = servlet.getClass().getAnnotation(WebServlet.class).value();
for (int i = 0; i < mappings.length; i++) {
mappings[i] = prefix2 + mappings[i];
}
synchronized (webss) {
webss.add(new AbstractMap.SimpleEntry<>(stype.getName() + "#" + rs.name(), mappings));
}
}
}
}
if (messageAgent != null)
this.messageAgents.put(messageAgent.getName(), messageAgent);
}
use of org.redkale.mq.MessageAgent in project redkale by redkale.
the class NodeServer method initResource.
private void initResource() {
final NodeServer self = this;
// ---------------------------------------------------------------------------------------------
final ResourceFactory appResFactory = application.getResourceFactory();
final TransportFactory appSncpTranFactory = application.getSncpTransportFactory();
final AnyValue resources = application.config.getAnyValue("resources");
final String confURI = appResFactory.find(RESNAME_APP_CONF, String.class);
final Map<String, SimpleEntry<Class, AnyValue>> cacheResource = new HashMap<>();
final Map<String, SimpleEntry<Class, AnyValue>> dataResources = new HashMap<>();
if (resources != null) {
for (AnyValue sourceConf : resources.getAnyValues("source")) {
try {
String classval = sourceConf.getValue("value");
Class type = null;
if (classval == null || classval.isEmpty()) {
RedkaleClassLoader.putServiceLoader(CacheSourceProvider.class);
List<CacheSourceProvider> providers = new ArrayList<>();
Iterator<CacheSourceProvider> it = ServiceLoader.load(CacheSourceProvider.class, serverClassLoader).iterator();
while (it.hasNext()) {
CacheSourceProvider s = it.next();
if (s != null)
RedkaleClassLoader.putReflectionPublicConstructors(s.getClass(), s.getClass().getName());
if (s != null && s.acceptsConf(sourceConf)) {
providers.add(s);
}
}
Collections.sort(providers, (a, b) -> {
Priority p1 = a == null ? null : a.getClass().getAnnotation(Priority.class);
Priority p2 = b == null ? null : b.getClass().getAnnotation(Priority.class);
return (p2 == null ? 0 : p2.value()) - (p1 == null ? 0 : p1.value());
});
for (CacheSourceProvider provider : providers) {
type = provider.sourceClass();
if (type != null)
break;
}
} else {
type = serverClassLoader.loadClass(classval);
}
if (type == DataSource.class) {
type = DataMemorySource.class;
for (AnyValue itemConf : sourceConf.getAnyValues("property")) {
if (itemConf.getValue("name", "").contains(DataSources.JDBC_URL)) {
type = DataJdbcSource.class;
break;
}
}
}
if (!Service.class.isAssignableFrom(type)) {
logger.log(Level.SEVERE, "load application source resource, but not Service error: " + sourceConf);
} else if (CacheSource.class.isAssignableFrom(type)) {
cacheResource.put(sourceConf.getValue("name", ""), new SimpleEntry(type, sourceConf));
} else if (DataSource.class.isAssignableFrom(type)) {
dataResources.put(sourceConf.getValue("name", ""), new SimpleEntry(type, sourceConf));
} else {
logger.log(Level.SEVERE, "load application source resource, but not CacheSource error: " + sourceConf);
}
} catch (Exception e) {
logger.log(Level.SEVERE, "load application source resource error: " + sourceConf, e);
}
}
}
// ------------------------------------- 注册 Resource --------------------------------------------------------
resourceFactory.register((ResourceFactory rf, final Object src, String resourceName, Field field, final Object attachment) -> {
try {
Resource res = field.getAnnotation(Resource.class);
if (res == null || !res.name().startsWith("properties."))
return;
// 远程模式不得注入 DataSource
if ((src instanceof Service) && Sncp.isRemote((Service) src))
return;
Class type = field.getType();
if (type != AnyValue.class && type != AnyValue[].class)
return;
Object resource = null;
final AnyValue properties = resources == null ? null : resources.getAnyValue("properties");
if (properties != null && type == AnyValue.class) {
resource = properties.getAnyValue(res.name().substring("properties.".length()));
appResFactory.register(resourceName, AnyValue.class, resource);
} else if (properties != null && type == AnyValue[].class) {
resource = properties.getAnyValues(res.name().substring("properties.".length()));
appResFactory.register(resourceName, AnyValue[].class, resource);
}
field.set(src, resource);
} catch (Exception e) {
logger.log(Level.SEVERE, "Resource inject error", e);
}
}, AnyValue.class, AnyValue[].class);
// ------------------------------------- 注册 Local AutoLoad(false) Service --------------------------------------------------------
resourceFactory.register((ResourceFactory rf, final Object src, String resourceName, Field field, final Object attachment) -> {
Class<Service> resServiceType = Service.class;
try {
if (field.getAnnotation(Resource.class) == null)
return;
// 远程模式不得注入 AutoLoad Service
if ((src instanceof Service) && Sncp.isRemote((Service) src))
return;
if (!Service.class.isAssignableFrom(field.getType()))
return;
resServiceType = (Class) field.getType();
if (resServiceType.getAnnotation(Local.class) == null)
return;
AutoLoad al = resServiceType.getAnnotation(AutoLoad.class);
if (al == null || al.value())
return;
// ResourceFactory resfactory = (isSNCP() ? appResFactory : resourceFactory);
SncpClient client = src instanceof Service ? Sncp.getSncpClient((Service) src) : null;
final InetSocketAddress sncpAddr = client == null ? null : client.getClientAddress();
final Set<String> groups = new HashSet<>();
Service service = Modifier.isFinal(resServiceType.getModifiers()) ? (Service) resServiceType.getConstructor().newInstance() : Sncp.createLocalService(serverClassLoader, resourceName, resServiceType, null, appResFactory, appSncpTranFactory, sncpAddr, groups, null);
appResFactory.register(resourceName, resServiceType, service);
field.set(src, service);
// 给其可能包含@Resource的字段赋值;
rf.inject(service, self);
if (!application.isCompileMode())
service.init(null);
logger.info("[" + Thread.currentThread().getName() + "] Load Service(@Local @AutoLoad service = " + resServiceType.getSimpleName() + ", resourceName = '" + resourceName + "')");
} catch (Exception e) {
logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] Load @Local @AutoLoad(false) Service inject " + resServiceType + " to " + src + " error", e);
}
}, Service.class);
// ------------------------------------- 注册 DataSource --------------------------------------------------------
resourceFactory.register((ResourceFactory rf, final Object src, String resourceName, Field field, final Object attachment) -> {
try {
if (field.getAnnotation(Resource.class) == null)
return;
// 远程模式不得注入 DataSource
if ((src instanceof Service) && Sncp.isRemote((Service) src))
return;
SimpleEntry<Class, AnyValue> resEntry = dataResources.get(resourceName);
AnyValue sourceConf = resEntry == null ? null : resEntry.getValue();
DataSource source = null;
if (sourceConf != null) {
final Class sourceType = resEntry.getKey();
if (sourceType == DataJdbcSource.class) {
source = DataSources.createDataSource(resourceName, sourceConf);
} else {
boolean can = false;
RedkaleClassLoader.putReflectionPublicConstructors(sourceType, sourceType.getName());
for (Constructor cr : sourceType.getConstructors()) {
if (cr.getParameterCount() == 0) {
can = true;
break;
}
}
if (DataSource.class.isAssignableFrom(sourceType) && can) {
// 必须有空构造函数
if (Modifier.isFinal(sourceType.getModifiers()) || sourceType.getAnnotation(Local.class) != null) {
source = (DataSource) sourceType.getConstructor().newInstance();
RedkaleClassLoader.putReflectionPublicConstructors(sourceType, sourceType.getName());
} else {
final Service srcService = (Service) src;
SncpClient client = Sncp.getSncpClient(srcService);
final InetSocketAddress sncpAddr = client == null ? null : client.getClientAddress();
final Set<String> groups = new HashSet<>();
source = (DataSource) Sncp.createLocalService(serverClassLoader, resourceName, sourceType, client == null ? null : client.getMessageAgent(), appResFactory, appSncpTranFactory, sncpAddr, groups, Sncp.getConf(srcService));
}
}
}
}
if (source == null) {
// 从persistence.xml配置中创建
source = DataSources.createDataSource(confURI, resourceName);
}
RedkaleClassLoader.putReflectionPublicConstructors(source.getClass(), source.getClass().getName());
application.dataSources.add(source);
ResourceType rt = source.getClass().getAnnotation(ResourceType.class);
if (rt != null && rt.value() != DataSource.class) {
appResFactory.register(resourceName, rt.value(), source);
} else if (source instanceof SearchSource) {
appResFactory.register(resourceName, SearchSource.class, source);
}
appResFactory.register(resourceName, DataSource.class, source);
field.set(src, source);
// 给AsyncGroup和其他@Resource的字段赋值;
rf.inject(source, self);
// NodeServer.this.watchFactory.inject(src);
if (!application.isCompileMode() && source instanceof Service)
((Service) source).init(sourceConf);
logger.info("[" + Thread.currentThread().getName() + "] Load DataSource (type = " + source.getClass().getSimpleName() + ", resourceName = '" + resourceName + "')");
} catch (Exception e) {
logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] DataSource inject to " + src + " error", e);
}
}, DataSource.class);
// ------------------------------------- 注册 CacheSource --------------------------------------------------------
resourceFactory.register(new ResourceFactory.ResourceLoader() {
@Override
public void load(ResourceFactory rf, final Object src, final String resourceName, Field field, final Object attachment) {
try {
if (field.getAnnotation(Resource.class) == null)
return;
if (!(src instanceof Service))
throw new RuntimeException("CacheSource must be inject in Service, cannot " + src);
// 远程模式不需要注入 CacheSource
if ((src instanceof Service) && Sncp.isRemote((Service) src))
return;
final Service srcService = (Service) src;
SncpClient client = Sncp.getSncpClient(srcService);
final InetSocketAddress sncpAddr = client == null ? null : client.getClientAddress();
SimpleEntry<Class, AnyValue> resEntry = cacheResource.get(resourceName);
AnyValue sourceConf = resEntry == null ? null : resEntry.getValue();
if (sourceConf == null) {
SimpleEntry<Class, AnyValue> resEntry2 = dataResources.get(resourceName);
sourceConf = resEntry2 == null ? null : resEntry2.getValue();
}
Class sourceType0 = CacheMemorySource.class;
if (sourceConf != null) {
String classval = sourceConf.getValue("value");
if (classval == null || classval.isEmpty()) {
RedkaleClassLoader.putServiceLoader(CacheSourceProvider.class);
List<CacheSourceProvider> providers = new ArrayList<>();
Iterator<CacheSourceProvider> it = ServiceLoader.load(CacheSourceProvider.class, serverClassLoader).iterator();
while (it.hasNext()) {
CacheSourceProvider s = it.next();
if (s != null)
RedkaleClassLoader.putReflectionPublicConstructors(s.getClass(), s.getClass().getName());
if (s != null && s.acceptsConf(sourceConf)) {
providers.add(s);
}
}
Collections.sort(providers, (a, b) -> {
Priority p1 = a == null ? null : a.getClass().getAnnotation(Priority.class);
Priority p2 = b == null ? null : b.getClass().getAnnotation(Priority.class);
return (p2 == null ? 0 : p2.value()) - (p1 == null ? 0 : p1.value());
});
for (CacheSourceProvider provider : providers) {
sourceType0 = provider.sourceClass();
if (sourceType0 != null)
break;
}
} else {
sourceType0 = serverClassLoader.loadClass(classval);
}
}
final Class sourceType = sourceType0;
Object source = null;
if (CacheSource.class.isAssignableFrom(sourceType)) {
// CacheSource
RedkaleClassLoader.putReflectionPublicConstructors(sourceType, sourceType.getName());
source = sourceType == CacheMemorySource.class ? new CacheMemorySource(resourceName) : (Modifier.isFinal(sourceType.getModifiers()) || sourceType.getAnnotation(Local.class) != null) ? sourceType.getConstructor().newInstance() : (CacheSource) Sncp.createLocalService(serverClassLoader, resourceName, sourceType, client == null ? null : client.getMessageAgent(), appResFactory, appSncpTranFactory, sncpAddr, null, Sncp.getConf(srcService));
Type genericType = field.getGenericType();
application.cacheSources.add((CacheSource) source);
appResFactory.register(resourceName, CacheSource.class, source);
if (genericType != CacheSource.class) {
appResFactory.register(resourceName, genericType, source);
}
}
field.set(src, source);
//
rf.inject(source, self);
if (!application.isCompileMode() && source instanceof Service)
((Service) source).init(sourceConf);
if ((src instanceof org.redkale.net.http.WebSocketNodeService) && sncpAddr != null) {
// 只有WebSocketNodeService的服务才需要给SNCP服务注入CacheMemorySource
NodeSncpServer sncpServer = application.findNodeSncpServer(sncpAddr);
if (source != null && source.getClass().getAnnotation(Local.class) == null) {
// 本地模式的Service不生成SncpServlet
sncpServer.getSncpServer().addSncpServlet((Service) source);
}
// logger.info("[" + Thread.currentThread().getName() + "] Load Service " + source);
}
logger.info("[" + Thread.currentThread().getName() + "] Load CacheSource (type = " + source.getClass().getSimpleName() + ", resourceName = '" + resourceName + "')");
} catch (Exception e) {
logger.log(Level.SEVERE, "DataSource inject error", e);
}
}
@Override
public boolean autoNone() {
return false;
}
}, CacheSource.class);
// ------------------------------------- 注册 WebSocketNode --------------------------------------------------------
resourceFactory.register(new ResourceFactory.ResourceLoader() {
@Override
public void load(ResourceFactory rf, final Object src, final String resourceName, Field field, final Object attachment) {
try {
if (field.getAnnotation(Resource.class) == null)
return;
// 远程模式不需要注入 WebSocketNode
if ((src instanceof Service) && Sncp.isRemote((Service) src))
return;
Service nodeService = (Service) rf.find(resourceName, WebSocketNode.class);
if (nodeService == null) {
final HashSet<String> groups = new HashSet<>();
if (groups.isEmpty() && isSNCP() && NodeServer.this.sncpGroup != null)
groups.add(NodeServer.this.sncpGroup);
nodeService = Sncp.createLocalService(serverClassLoader, resourceName, org.redkale.net.http.WebSocketNodeService.class, Sncp.getMessageAgent((Service) src), application.getResourceFactory(), application.getSncpTransportFactory(), NodeServer.this.sncpAddress, groups, (AnyValue) null);
(isSNCP() ? appResFactory : resourceFactory).register(resourceName, WebSocketNode.class, nodeService);
((org.redkale.net.http.WebSocketNodeService) nodeService).setName(resourceName);
}
resourceFactory.inject(nodeService, self);
MessageAgent messageAgent = Sncp.getMessageAgent((Service) src);
if (messageAgent != null && Sncp.getMessageAgent(nodeService) == null)
Sncp.setMessageAgent(nodeService, messageAgent);
field.set(src, nodeService);
if (Sncp.isRemote(nodeService)) {
remoteServices.add(nodeService);
} else {
// 动态加载的Service也存在按需加载的注入资源
rf.inject(nodeService);
localServices.add(nodeService);
interceptorServices.add(nodeService);
if (consumer != null)
consumer.accept(null, nodeService);
}
} catch (Exception e) {
logger.log(Level.SEVERE, "WebSocketNode inject error", e);
}
}
@Override
public boolean autoNone() {
return false;
}
}, WebSocketNode.class);
}
use of org.redkale.mq.MessageAgent in project redkale by redkale.
the class Sncp method createRemoteService.
/**
* <blockquote><pre>
* @Resource(name = "")
* @SncpDyn(remote = true)
* @ResourceType(TestService.class)
* public final class _DynRemoteTestService extends TestService{
*
* private AnyValue _redkale_conf;
*
* private SncpClient _redkale_client;
*
* @Override
* public void createSomeThing(TestBean bean){
* _redkale_client.remote(0, bean);
* }
*
* @Override
* public String findSomeThing(){
* return _redkale_client.remote(1);
* }
*
* @Override
* public String updateSomeThing(String id){
* return _redkale_client.remote(2, id);
* }
* }
* </pre></blockquote>
*
* 创建远程模式的Service实例
*
* @param <T> Service泛型
* @param classLoader ClassLoader
* @param name 资源名
* @param serviceTypeOrImplClass Service类
* @param messageAgent MQ管理器
* @param transportFactory TransportFactory
* @param clientAddress 本地IP地址
* @param groups0 所有的组节点,包含自身
* @param conf 启动配置项
*
* @return Service的远程模式实例
*/
@SuppressWarnings("unchecked")
public static <T extends Service> T createRemoteService(final ClassLoader classLoader, final String name, final Class<T> serviceTypeOrImplClass, final MessageAgent messageAgent, final TransportFactory transportFactory, final InetSocketAddress clientAddress, final Set<String> groups0, final AnyValue conf) {
if (serviceTypeOrImplClass == null)
return null;
if (!Service.class.isAssignableFrom(serviceTypeOrImplClass))
return null;
final Set<String> groups = groups0 == null ? new HashSet<>() : groups0;
ResourceFactory.checkResourceName(name);
final int mod = serviceTypeOrImplClass.getModifiers();
boolean realed = !(java.lang.reflect.Modifier.isAbstract(mod) || serviceTypeOrImplClass.isInterface());
if (!java.lang.reflect.Modifier.isPublic(mod))
return null;
final String supDynName = serviceTypeOrImplClass.getName().replace('.', '/');
final String clientName = SncpClient.class.getName().replace('.', '/');
final String resDesc = Type.getDescriptor(Resource.class);
final String clientDesc = Type.getDescriptor(SncpClient.class);
final String sncpDynDesc = Type.getDescriptor(SncpDyn.class);
final String anyValueDesc = Type.getDescriptor(AnyValue.class);
final ClassLoader loader = classLoader == null ? Thread.currentThread().getContextClassLoader() : classLoader;
// final String newDynName = supDynName.substring(0, supDynName.lastIndexOf('/') + 1) + REMOTEPREFIX + serviceTypeOrImplClass.getSimpleName();
final String newDynName = "org/redkaledyn/service/remote/_DynRemoteService__" + serviceTypeOrImplClass.getName().replace('.', '_').replace('$', '_');
try {
Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
Class newClazz = clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz;
T service = (T) newClazz.getDeclaredConstructor().newInstance();
SncpClient client = new SncpClient(name, serviceTypeOrImplClass, service, messageAgent, transportFactory, true, realed ? createLocalServiceClass(loader, name, serviceTypeOrImplClass) : serviceTypeOrImplClass, clientAddress);
client.setRemoteGroups(groups);
if (transportFactory != null)
client.setRemoteGroupTransport(transportFactory.loadTransport(clientAddress, groups));
{
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_client");
c.setAccessible(true);
c.set(service, client);
}
if (messageAgent != null) {
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_messageagent");
c.setAccessible(true);
c.set(service, messageAgent);
if (service instanceof WebSocketNode) {
c = WebSocketNode.class.getDeclaredField("messageAgent");
c.setAccessible(true);
c.set(service, messageAgent);
}
}
{
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_conf");
c.setAccessible(true);
c.set(service, conf);
}
if (transportFactory != null)
transportFactory.addSncpService(service);
return service;
} catch (Throwable ex) {
}
// ------------------------------------------------------------------------------
ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
FieldVisitor fv;
MethodDebugVisitor mv;
AnnotationVisitor av0;
cw.visit(V11, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, serviceTypeOrImplClass.isInterface() ? "java/lang/Object" : supDynName, serviceTypeOrImplClass.isInterface() ? new String[] { supDynName } : null);
{
av0 = cw.visitAnnotation(resDesc, true);
av0.visit("name", name);
av0.visitEnd();
}
{
av0 = cw.visitAnnotation(Type.getDescriptor(ResourceType.class), true);
ResourceType rty = serviceTypeOrImplClass.getAnnotation(ResourceType.class);
av0.visit("value", Type.getType(Type.getDescriptor(rty == null ? serviceTypeOrImplClass : rty.value())));
av0.visitEnd();
}
{
av0 = cw.visitAnnotation(sncpDynDesc, true);
av0.visit("remote", Boolean.TRUE);
av0.visitEnd();
}
{
// 给新类加上 原有的Annotation
for (Annotation ann : serviceTypeOrImplClass.getAnnotations()) {
if (ann instanceof Resource || ann instanceof SncpDyn || ann instanceof ResourceType)
continue;
MethodDebugVisitor.visitAnnotation(cw.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann);
}
}
{
fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_conf", anyValueDesc, null, null);
fv.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_client", clientDesc, null, null);
fv.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_messageagent", Type.getDescriptor(MessageAgent.class), null, null);
fv.visitEnd();
}
{
// 构造函数
mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null));
// mv.setDebug(true);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, serviceTypeOrImplClass.isInterface() ? "java/lang/Object" : supDynName, "<init>", "()V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
// init
mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "init", "(" + anyValueDesc + ")V", null, null));
mv.visitInsn(RETURN);
mv.visitMaxs(0, 2);
mv.visitEnd();
}
{
// stop
mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "stop", "(" + anyValueDesc + ")V", null, null));
mv.visitInsn(RETURN);
mv.visitMaxs(0, 2);
mv.visitEnd();
}
{
// destroy
mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "destroy", "(" + anyValueDesc + ")V", null, null));
mv.visitInsn(RETURN);
mv.visitMaxs(0, 2);
mv.visitEnd();
}
{
// toString()
mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null));
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, FIELDPREFIX + "_client", clientDesc);
Label l1 = new Label();
mv.visitJumpInsn(IFNONNULL, l1);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;", false);
Label l2 = new Label();
mv.visitJumpInsn(GOTO, l2);
mv.visitLabel(l1);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, FIELDPREFIX + "_client", clientDesc);
mv.visitMethodInsn(INVOKEVIRTUAL, clientName, "toSimpleString", "()Ljava/lang/String;", false);
mv.visitLabel(l2);
mv.visitInsn(ARETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
int i = -1;
for (final SncpAction entry : SncpClient.getSncpActions(realed ? createLocalServiceClass(loader, name, serviceTypeOrImplClass) : serviceTypeOrImplClass)) {
final int index = ++i;
final java.lang.reflect.Method method = entry.method;
{
mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, method.getName(), Type.getMethodDescriptor(method), null, null));
// mv.setDebug(true);
{
// 给参数加上 Annotation
final Annotation[][] anns = method.getParameterAnnotations();
for (int k = 0; k < anns.length; k++) {
for (Annotation ann : anns[k]) {
MethodDebugVisitor.visitAnnotation(mv.visitParameterAnnotation(k, Type.getDescriptor(ann.annotationType()), true), ann);
}
}
}
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, FIELDPREFIX + "_client", clientDesc);
MethodDebugVisitor.pushInt(mv, index);
{
// 传参数
int paramlen = entry.paramTypes.length;
MethodDebugVisitor.pushInt(mv, paramlen);
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
java.lang.reflect.Type[] paramtypes = entry.paramTypes;
int insn = 0;
for (int j = 0; j < paramtypes.length; j++) {
final java.lang.reflect.Type pt = paramtypes[j];
mv.visitInsn(DUP);
insn++;
MethodDebugVisitor.pushInt(mv, j);
if (pt instanceof Class && ((Class) pt).isPrimitive()) {
if (pt == long.class) {
mv.visitVarInsn(LLOAD, insn++);
} else if (pt == float.class) {
mv.visitVarInsn(FLOAD, insn++);
} else if (pt == double.class) {
mv.visitVarInsn(DLOAD, insn++);
} else {
mv.visitVarInsn(ILOAD, insn);
}
Class bigclaz = java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance((Class) pt, 1), 0).getClass();
mv.visitMethodInsn(INVOKESTATIC, bigclaz.getName().replace('.', '/'), "valueOf", "(" + Type.getDescriptor((Class) pt) + ")" + Type.getDescriptor(bigclaz), false);
} else {
mv.visitVarInsn(ALOAD, insn);
}
mv.visitInsn(AASTORE);
}
}
mv.visitMethodInsn(INVOKEVIRTUAL, clientName, "remote", "(I[Ljava/lang/Object;)Ljava/lang/Object;", false);
// mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false);
if (method.getGenericReturnType() == void.class) {
mv.visitInsn(POP);
mv.visitInsn(RETURN);
} else {
Class returnclz = method.getReturnType();
Class bigPrimitiveClass = returnclz.isPrimitive() ? java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance(returnclz, 1), 0).getClass() : returnclz;
mv.visitTypeInsn(CHECKCAST, (returnclz.isPrimitive() ? bigPrimitiveClass : returnclz).getName().replace('.', '/'));
if (returnclz.isPrimitive()) {
String bigPrimitiveName = bigPrimitiveClass.getName().replace('.', '/');
try {
java.lang.reflect.Method pm = bigPrimitiveClass.getMethod(returnclz.getSimpleName() + "Value");
mv.visitMethodInsn(INVOKEVIRTUAL, bigPrimitiveName, pm.getName(), Type.getMethodDescriptor(pm), false);
} catch (Exception ex) {
// 不可能会发生
throw new RuntimeException(ex);
}
if (returnclz == long.class) {
mv.visitInsn(LRETURN);
} else if (returnclz == float.class) {
mv.visitInsn(FRETURN);
} else if (returnclz == double.class) {
mv.visitInsn(DRETURN);
} else {
mv.visitInsn(IRETURN);
}
} else {
mv.visitInsn(ARETURN);
}
}
mv.visitMaxs(20, 20);
mv.visitEnd();
}
}
cw.visitEnd();
byte[] bytes = cw.toByteArray();
Class<?> newClazz = new ClassLoader(loader) {
public final Class<?> loadClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length);
}
}.loadClass(newDynName.replace('/', '.'), bytes);
RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, newClazz);
RedkaleClassLoader.putReflectionPublicConstructors(newClazz, newDynName.replace('/', '.'));
RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynName.replace('/', '.'));
try {
T service = (T) newClazz.getDeclaredConstructor().newInstance();
SncpClient client = new SncpClient(name, serviceTypeOrImplClass, service, messageAgent, transportFactory, true, realed ? createLocalServiceClass(loader, name, serviceTypeOrImplClass) : serviceTypeOrImplClass, clientAddress);
client.setRemoteGroups(groups);
if (transportFactory != null)
client.setRemoteGroupTransport(transportFactory.loadTransport(clientAddress, groups));
{
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_client");
c.setAccessible(true);
c.set(service, client);
RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), c);
}
if (messageAgent != null) {
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_messageagent");
c.setAccessible(true);
c.set(service, messageAgent);
RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), c);
if (service instanceof WebSocketNode) {
c = WebSocketNode.class.getDeclaredField("messageAgent");
c.setAccessible(true);
c.set(service, messageAgent);
RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), c);
}
}
{
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_conf");
c.setAccessible(true);
c.set(service, conf);
RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), c);
}
if (transportFactory != null)
transportFactory.addSncpService(service);
return service;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
use of org.redkale.mq.MessageAgent in project redkale by redkale.
the class NodeHttpServer method initWebSocketService.
private void initWebSocketService() {
final NodeServer self = this;
final ResourceFactory regFactory = application.getResourceFactory();
resourceFactory.register((ResourceFactory rf, final Object src, final String resourceName, Field field, Object attachment) -> {
// 主要用于单点的服务
try {
if (field.getAnnotation(Resource.class) == null)
return;
if (!(src instanceof WebSocketServlet))
return;
ResourceFactory.ResourceLoader loader = null;
ResourceFactory sncpResFactory = null;
for (NodeServer ns : application.servers) {
if (!ns.isSNCP())
continue;
sncpResFactory = ns.resourceFactory;
loader = sncpResFactory.findLoader(WebSocketNode.class, field);
if (loader != null)
break;
}
if (loader != null)
loader.load(sncpResFactory, src, resourceName, field, attachment);
synchronized (regFactory) {
Service nodeService = (Service) rf.find(resourceName, WebSocketNode.class);
if (sncpResFactory != null && resourceFactory.find(RESNAME_SNCP_ADDR, String.class) == null) {
resourceFactory.register(RESNAME_SNCP_ADDR, InetSocketAddress.class, sncpResFactory.find(RESNAME_SNCP_ADDR, InetSocketAddress.class));
resourceFactory.register(RESNAME_SNCP_ADDR, SocketAddress.class, sncpResFactory.find(RESNAME_SNCP_ADDR, SocketAddress.class));
resourceFactory.register(RESNAME_SNCP_ADDR, String.class, sncpResFactory.find(RESNAME_SNCP_ADDR, String.class));
}
if (nodeService == null) {
MessageAgent messageAgent = null;
try {
Field c = WebSocketServlet.class.getDeclaredField("messageAgent");
c.setAccessible(true);
messageAgent = (MessageAgent) c.get(src);
} catch (Exception ex) {
logger.log(Level.WARNING, "WebSocketServlet getMessageAgent error", ex);
}
nodeService = Sncp.createLocalService(serverClassLoader, resourceName, org.redkale.net.http.WebSocketNodeService.class, messageAgent, application.getResourceFactory(), application.getSncpTransportFactory(), (InetSocketAddress) null, (Set<String>) null, (AnyValue) null);
regFactory.register(resourceName, WebSocketNode.class, nodeService);
}
resourceFactory.inject(nodeService, self);
field.set(src, nodeService);
logger.fine("[" + Thread.currentThread().getName() + "] Load Service " + nodeService);
}
} catch (Exception e) {
logger.log(Level.SEVERE, "WebSocketNode inject error", e);
}
}, WebSocketNode.class);
}
Aggregations