use of org.redkale.net.http.WebSocketNode 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);
}
}
Aggregations