mirror of https://github.com/longtai-cn/hippo4j
fix : Add set multiple ChannelHandler(#812)
parent
6a88b2bd0a
commit
fbb6d05dee
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.hippo4j.rpc.handler;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Manage the Handler used in the processing.<br>
|
||||
* The Handler must be able to exist multiple times and be invoked once in a single execution
|
||||
*/
|
||||
public interface HandlerManager<T> {
|
||||
|
||||
/**
|
||||
* Add handler to the end of the Handler chain
|
||||
*
|
||||
* @param name name
|
||||
* @param handler handler
|
||||
*/
|
||||
HandlerManager<T> addLast(String name, T handler);
|
||||
|
||||
/**
|
||||
* Add handler to the head of the Handler chain
|
||||
*
|
||||
* @param name name
|
||||
* @param handler handler
|
||||
*/
|
||||
HandlerManager<T> addFirst(String name, T handler);
|
||||
|
||||
/**
|
||||
* Add handler to the end of the Handler chain, without specifying a name
|
||||
*
|
||||
* @param handler handler
|
||||
*/
|
||||
HandlerManager<T> addLast(T handler);
|
||||
|
||||
/**
|
||||
* Adds handler to the head of the Handler chain, without specifying a name
|
||||
*
|
||||
* @param handler handler
|
||||
*/
|
||||
HandlerManager<T> addFirst(T handler);
|
||||
|
||||
/**
|
||||
* Create a handler
|
||||
*
|
||||
* @param order order
|
||||
* @param handler Handler
|
||||
* @param name Handler name
|
||||
* @return HandlerEntity
|
||||
*/
|
||||
default HandlerEntity<T> getHandlerEntity(long order, T handler, String name) {
|
||||
return new HandlerEntity<>(order, handler, name);
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
class HandlerEntity<T> implements Comparable<HandlerEntity<T>>{
|
||||
|
||||
/**
|
||||
* order, The Handler with a larger value is executed after the Handler with a smaller value
|
||||
*/
|
||||
long order;
|
||||
|
||||
/**
|
||||
* handler
|
||||
*/
|
||||
T handler;
|
||||
|
||||
/**
|
||||
* A high level summary of handler functionality
|
||||
*/
|
||||
String name;
|
||||
|
||||
@Override
|
||||
public int compareTo(HandlerEntity<T> o) {
|
||||
return (int) (this.getOrder() - o.getOrder());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.hippo4j.rpc.handler;
|
||||
|
||||
import cn.hippo4j.common.toolkit.Assert;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Processor manager for ChannelHandler in netty
|
||||
*/
|
||||
public abstract class NettyHandlerManager implements HandlerManager<ChannelHandler> {
|
||||
|
||||
protected final List<HandlerEntity<ChannelHandler>> handlers;
|
||||
|
||||
AtomicLong firstIndex = new AtomicLong(-1);
|
||||
|
||||
AtomicLong lastIndex = new AtomicLong(0);
|
||||
|
||||
protected NettyHandlerManager(List<ChannelHandler> handlers) {
|
||||
this.handlers = handlers.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(c -> getHandlerEntity(lastIndex.getAndIncrement(), c, null))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
protected NettyHandlerManager(ChannelHandler... handlers) {
|
||||
this(handlers != null ? Arrays.asList(handlers) : Collections.emptyList());
|
||||
}
|
||||
|
||||
protected NettyHandlerManager() {
|
||||
this.handlers = new LinkedList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @param name name
|
||||
* @param handler handler
|
||||
* @return NettyHandlerManager
|
||||
*/
|
||||
public NettyHandlerManager addLast(String name, ChannelHandler handler) {
|
||||
Assert.notNull(handler);
|
||||
this.handlers.add(getHandlerEntity(lastIndex.getAndIncrement(), handler, name));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @param name name
|
||||
* @param handler handler
|
||||
* @return NettyHandlerManager
|
||||
*/
|
||||
public NettyHandlerManager addFirst(String name, ChannelHandler handler) {
|
||||
Assert.notNull(handler);
|
||||
this.handlers.add(getHandlerEntity(firstIndex.getAndIncrement(), handler, name));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @param handler handler
|
||||
* @return NettyHandlerManager
|
||||
*/
|
||||
public NettyHandlerManager addLast(ChannelHandler handler) {
|
||||
Assert.notNull(handler);
|
||||
this.handlers.add(getHandlerEntity(lastIndex.getAndIncrement(), handler, null));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @param handler handler
|
||||
* @return NettyHandlerManager
|
||||
*/
|
||||
public NettyHandlerManager addFirst(ChannelHandler handler) {
|
||||
Assert.notNull(handler);
|
||||
this.handlers.add(getHandlerEntity(firstIndex.getAndDecrement(), handler, null));
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.hippo4j.rpc.client;
|
||||
|
||||
import cn.hippo4j.rpc.handler.NettyClientPoolHandler;
|
||||
import cn.hippo4j.rpc.handler.NettyClientTakeHandler;
|
||||
import cn.hippo4j.rpc.handler.NettyServerTakeHandler;
|
||||
import cn.hippo4j.rpc.request.DefaultRequest;
|
||||
import cn.hippo4j.rpc.request.Request;
|
||||
import cn.hippo4j.rpc.response.Response;
|
||||
import cn.hippo4j.rpc.server.NettyServerConnection;
|
||||
import cn.hippo4j.rpc.server.RPCServer;
|
||||
import cn.hippo4j.rpc.server.ServerConnection;
|
||||
import cn.hippo4j.rpc.support.ClassRegistry;
|
||||
import cn.hippo4j.rpc.support.DefaultInstance;
|
||||
import cn.hippo4j.rpc.support.Instance;
|
||||
import io.netty.channel.pool.ChannelPoolHandler;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class RPCClientTest {
|
||||
|
||||
String host = "localhost";
|
||||
int port = 8888;
|
||||
int portTest = 8889;
|
||||
|
||||
@Test
|
||||
public void connection() throws IOException {
|
||||
Class<CallManager> cls = CallManager.class;
|
||||
String className = cls.getName();
|
||||
ClassRegistry.put(className, cls);
|
||||
// The mode connection was denied when the server was started on the specified port
|
||||
Instance instance = new DefaultInstance();
|
||||
NettyServerTakeHandler handler = new NettyServerTakeHandler(instance);
|
||||
ServerConnection connection = new NettyServerConnection(handler);
|
||||
RPCServer rpcServer = new RPCServer(port, connection);
|
||||
CompletableFuture.runAsync(rpcServer::bind);
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(3);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
ChannelPoolHandler channelPoolHandler = new NettyClientPoolHandler(new NettyClientTakeHandler());
|
||||
NettyClientConnection clientConnection = new NettyClientConnection(host, port, channelPoolHandler);
|
||||
RPCClient rpcClient = new RPCClient(clientConnection);
|
||||
Request request = new DefaultRequest("127.0.0.18888", className, "call", null, null);
|
||||
for (int i = 0; i < 100; i++) {
|
||||
Response response = rpcClient.connection(request);
|
||||
boolean active = rpcClient.isActive();
|
||||
Assert.assertTrue(active);
|
||||
Assert.assertEquals(response.getObj(), 1);
|
||||
}
|
||||
rpcClient.close();
|
||||
rpcServer.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* This test case can be overridden under the handler and coder packages
|
||||
*/
|
||||
@Test
|
||||
public void connectionTest() throws IOException {
|
||||
Class<CallManager> cls = CallManager.class;
|
||||
String className = cls.getName();
|
||||
ClassRegistry.put(className, cls);
|
||||
// The mode connection was denied when the server was started on the specified port
|
||||
Instance instance = new DefaultInstance();
|
||||
NettyServerTakeHandler handler = new NettyServerTakeHandler(instance);
|
||||
ServerConnection connection = new NettyServerConnection(handler);
|
||||
RPCServer rpcServer = new RPCServer(portTest, connection);
|
||||
CompletableFuture.runAsync(rpcServer::bind);
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(3);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
ChannelPoolHandler channelPoolHandler = new NettyClientPoolHandler(new NettyClientTakeHandler());
|
||||
NettyClientConnection clientConnection = new NettyClientConnection(host, portTest, channelPoolHandler);
|
||||
RPCClient rpcClient = new RPCClient(clientConnection);
|
||||
Class<?>[] classes = new Class<?>[2];
|
||||
classes[0] = Integer.class;
|
||||
classes[1] = Integer.class;
|
||||
Object[] objects = new Object[2];
|
||||
objects[0] = 1;
|
||||
objects[1] = 2;
|
||||
Request request = new DefaultRequest("127.0.0.18889", className, "callTest", classes, objects);
|
||||
Response response = rpcClient.connection(request);
|
||||
boolean active = rpcClient.isActive();
|
||||
Assert.assertTrue(active);
|
||||
Assert.assertEquals(response.getObj(), 3);
|
||||
rpcClient.close();
|
||||
rpcServer.close();
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.hippo4j.config.rpc.client;
|
||||
|
||||
import cn.hippo4j.config.rpc.request.DefaultRequest;
|
||||
import cn.hippo4j.config.rpc.request.Request;
|
||||
import cn.hippo4j.config.rpc.response.Response;
|
||||
import cn.hippo4j.config.rpc.server.NettyServerConnection;
|
||||
import cn.hippo4j.config.rpc.server.RPCServer;
|
||||
import cn.hippo4j.config.rpc.server.ServerConnection;
|
||||
import cn.hippo4j.config.rpc.support.DefaultInstance;
|
||||
import cn.hippo4j.config.rpc.support.Instance;
|
||||
import cn.hippo4j.config.rpc.support.ClassRegistry;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class RPCClientTest {
|
||||
|
||||
String host = "localhost";
|
||||
int port = 8888;
|
||||
|
||||
@Test
|
||||
public void connection() throws IOException {
|
||||
|
||||
Class<CallManager> cls = CallManager.class;
|
||||
String className = cls.getName();
|
||||
ClassRegistry.put(className, cls);
|
||||
// The mode connection was denied when the server was started on the specified port
|
||||
Instance instance = new DefaultInstance();
|
||||
ServerConnection connection = new NettyServerConnection(instance);
|
||||
RPCServer rpcServer = new RPCServer(port, connection);
|
||||
CompletableFuture.runAsync(rpcServer::bind);
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(3);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
NettyClientConnection clientConnection = new NettyClientConnection(host, port);
|
||||
RPCClient rpcClient = new RPCClient(clientConnection);
|
||||
Request request = new DefaultRequest("127.0.0.18888", className, "call", null, null);
|
||||
for (int i = 0; i < 100; i++) {
|
||||
Response response = rpcClient.connection(request);
|
||||
Assert.assertEquals(response.getObj(), 1);
|
||||
}
|
||||
rpcClient.close();
|
||||
rpcServer.close();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in new issue