init
This commit is contained in:
134
test/org/apache/catalina/tribes/TesterMulticast.java
Normal file
134
test/org/apache/catalina/tribes/TesterMulticast.java
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes;
|
||||
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MulticastSocket;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
/**
|
||||
* A simple multicast test that replicates the core elements of Tomcat's
|
||||
* multicast membership. If this works then multicast membership should work.
|
||||
* Useful notes for various operating systems follow.<p>
|
||||
* OSX
|
||||
* <ul>
|
||||
* <li>The firewall blocks multicast between processes on the local machine so
|
||||
* you will need to disable the OSX firewall before the test below will
|
||||
* work.</li>
|
||||
* </ul>
|
||||
* Windows Server 2008
|
||||
* <ul>
|
||||
* <li>This works out of the box</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class TesterMulticast {
|
||||
|
||||
private static final String ADDRESS = "228.0.0.4";
|
||||
private static final int PORT = 56565;
|
||||
private static final InetAddress INET_ADDRESS;
|
||||
|
||||
static {
|
||||
InetAddress result = null;
|
||||
try {
|
||||
result = InetAddress.getByName(ADDRESS);
|
||||
} catch (UnknownHostException e) {
|
||||
// deal with later
|
||||
}
|
||||
INET_ADDRESS = result;
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Start Rx Thread
|
||||
Rx rx = new Rx();
|
||||
Thread rxThread = new Thread(rx);
|
||||
rxThread.setDaemon(true);
|
||||
rxThread.start();
|
||||
|
||||
// Start Tx Thread
|
||||
Tx tx = new Tx();
|
||||
Thread txThread = new Thread(tx);
|
||||
txThread.setDaemon(true);
|
||||
txThread.start();
|
||||
|
||||
|
||||
Thread.sleep(10000);
|
||||
|
||||
tx.stop();
|
||||
rx.stop();
|
||||
}
|
||||
|
||||
private static class Rx implements Runnable {
|
||||
|
||||
private volatile boolean run = true;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try (MulticastSocket s = new MulticastSocket(PORT)) {
|
||||
s.setLoopbackMode(false);
|
||||
s.joinGroup(INET_ADDRESS);
|
||||
DatagramPacket p = new DatagramPacket(new byte[4], 4);
|
||||
p.setAddress(INET_ADDRESS);
|
||||
p.setPort(PORT);
|
||||
while (run) {
|
||||
s.receive(p);
|
||||
String d = new String (p.getData());
|
||||
System.out.println("Rx: " + d);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
run = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Tx implements Runnable {
|
||||
|
||||
private volatile boolean run = true;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try (MulticastSocket s = new MulticastSocket(PORT)) {
|
||||
s.setLoopbackMode(false);
|
||||
s.joinGroup(INET_ADDRESS);
|
||||
DatagramPacket p = new DatagramPacket(new byte[4], 4);
|
||||
p.setAddress(INET_ADDRESS);
|
||||
p.setPort(PORT);
|
||||
long counter = 0;
|
||||
String msg;
|
||||
while (run) {
|
||||
msg = String.format("%04d", Long.valueOf(counter));
|
||||
p.setData(msg.getBytes());
|
||||
System.out.println("Tx: " + msg);
|
||||
s.send(p);
|
||||
counter++;
|
||||
Thread.sleep(500);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
run = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
52
test/org/apache/catalina/tribes/TesterUtil.java
Normal file
52
test/org/apache/catalina/tribes/TesterUtil.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes;
|
||||
|
||||
import org.apache.catalina.tribes.group.interceptors.DomainFilterInterceptor;
|
||||
import org.apache.catalina.tribes.util.UUIDGenerator;
|
||||
|
||||
/**
|
||||
* Utility methods for use by multiple tests.
|
||||
*/
|
||||
public class TesterUtil {
|
||||
|
||||
private TesterUtil() {
|
||||
// Hide default constructor
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Configures a set of channels to use a random domain. Use to ensure that
|
||||
* multiple instance of the test suite do not interfere when running on the
|
||||
* same machine. This may happen in a CI system or when a developer is
|
||||
* running tests for multiple branches in parallel.
|
||||
*/
|
||||
public static void addRandomDomain(ManagedChannel[] channels) {
|
||||
if (channels == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] domain = UUIDGenerator.randomUUID(false);
|
||||
|
||||
for (ManagedChannel channel : channels) {
|
||||
channel.getMembershipService().setDomain(domain);
|
||||
DomainFilterInterceptor filter = new DomainFilterInterceptor();
|
||||
filter.setDomain(domain);
|
||||
channel.addInterceptor(filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
255
test/org/apache/catalina/tribes/demos/ChannelCreator.java
Normal file
255
test/org/apache/catalina/tribes/demos/ChannelCreator.java
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.demos;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.ManagedChannel;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.group.GroupChannel;
|
||||
import org.apache.catalina.tribes.group.interceptors.DomainFilterInterceptor;
|
||||
import org.apache.catalina.tribes.group.interceptors.FragmentationInterceptor;
|
||||
import org.apache.catalina.tribes.group.interceptors.GzipInterceptor;
|
||||
import org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor;
|
||||
import org.apache.catalina.tribes.group.interceptors.OrderInterceptor;
|
||||
import org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor;
|
||||
import org.apache.catalina.tribes.group.interceptors.TcpFailureDetector;
|
||||
import org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor;
|
||||
import org.apache.catalina.tribes.membership.McastService;
|
||||
import org.apache.catalina.tribes.membership.MemberImpl;
|
||||
import org.apache.catalina.tribes.transport.MultiPointSender;
|
||||
import org.apache.catalina.tribes.transport.ReceiverBase;
|
||||
import org.apache.catalina.tribes.transport.ReplicationTransmitter;
|
||||
|
||||
/**
|
||||
* <p>Title: </p>
|
||||
*
|
||||
* <p>Description: </p>
|
||||
*
|
||||
*
|
||||
* <p>Company: </p>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ChannelCreator {
|
||||
|
||||
|
||||
public static StringBuilder usage() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("\n\t\t[-bind tcpbindaddress]")
|
||||
.append("\n\t\t[-tcpselto tcpselectortimeout]")
|
||||
.append("\n\t\t[-tcpthreads tcpthreadcount]")
|
||||
.append("\n\t\t[-port tcplistenport]")
|
||||
.append("\n\t\t[-autobind tcpbindtryrange]")
|
||||
.append("\n\t\t[-ackto acktimeout]")
|
||||
.append("\n\t\t[-receiver org.apache.catalina.tribes.transport.nio.NioReceiver|org.apache.catalina.tribes.transport.bio.BioReceiver|]")
|
||||
.append("\n\t\t[-transport org.apache.catalina.tribes.transport.nio.PooledParallelSender|org.apache.catalina.tribes.transport.bio.PooledMultiSender]")
|
||||
.append("\n\t\t[-transport.xxx transport specific property]")
|
||||
.append("\n\t\t[-maddr multicastaddr]")
|
||||
.append("\n\t\t[-mport multicastport]")
|
||||
.append("\n\t\t[-mbind multicastbindaddr]")
|
||||
.append("\n\t\t[-mfreq multicastfrequency]")
|
||||
.append("\n\t\t[-mdrop multicastdroptime]")
|
||||
.append("\n\t\t[-gzip]")
|
||||
.append("\n\t\t[-static hostname:port (-static localhost:9999 -static 127.0.0.1:8888 can be repeated)]")
|
||||
.append("\n\t\t[-order]")
|
||||
.append("\n\t\t[-ordersize maxorderqueuesize]")
|
||||
.append("\n\t\t[-frag]")
|
||||
.append("\n\t\t[-fragsize maxmsgsize]")
|
||||
.append("\n\t\t[-throughput]")
|
||||
.append("\n\t\t[-failuredetect]")
|
||||
.append("\n\t\t[-async]")
|
||||
.append("\n\t\t[-asyncsize maxqueuesizeinkilobytes]");
|
||||
return buf;
|
||||
|
||||
}
|
||||
|
||||
public static Channel createChannel(String[] args) throws Exception {
|
||||
String bind = "auto";
|
||||
int port = 4001;
|
||||
String mbind = null;
|
||||
boolean gzip = false;
|
||||
int tcpseltimeout = 5000;
|
||||
int tcpthreadcount = 4;
|
||||
int acktimeout = 15000;
|
||||
String mcastaddr = "228.0.0.5";
|
||||
int mcastport = 45565;
|
||||
long mcastfreq = 500;
|
||||
long mcastdrop = 2000;
|
||||
boolean order = false;
|
||||
int ordersize = Integer.MAX_VALUE;
|
||||
boolean frag = false;
|
||||
int fragsize = 1024;
|
||||
int autoBind = 10;
|
||||
ArrayList<Member> staticMembers = new ArrayList<>();
|
||||
Properties transportProperties = new Properties();
|
||||
String transport = "org.apache.catalina.tribes.transport.nio.PooledParallelSender";
|
||||
String receiver = "org.apache.catalina.tribes.transport.nio.NioReceiver";
|
||||
boolean async = false;
|
||||
int asyncsize = 1024*1024*50; //50MB
|
||||
boolean throughput = false;
|
||||
boolean failuredetect = false;
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if ("-bind".equals(args[i])) {
|
||||
bind = args[++i];
|
||||
} else if ("-port".equals(args[i])) {
|
||||
port = Integer.parseInt(args[++i]);
|
||||
} else if ("-autobind".equals(args[i])) {
|
||||
autoBind = Integer.parseInt(args[++i]);
|
||||
} else if ("-tcpselto".equals(args[i])) {
|
||||
tcpseltimeout = Integer.parseInt(args[++i]);
|
||||
} else if ("-tcpthreads".equals(args[i])) {
|
||||
tcpthreadcount = Integer.parseInt(args[++i]);
|
||||
} else if ("-gzip".equals(args[i])) {
|
||||
gzip = true;
|
||||
} else if ("-async".equals(args[i])) {
|
||||
async = true;
|
||||
} else if ("-failuredetect".equals(args[i])) {
|
||||
failuredetect = true;
|
||||
} else if ("-asyncsize".equals(args[i])) {
|
||||
asyncsize = Integer.parseInt(args[++i]);
|
||||
System.out.println("Setting MessageDispatchInterceptor.maxQueueSize="+asyncsize);
|
||||
} else if ("-static".equals(args[i])) {
|
||||
String d = args[++i];
|
||||
String h = d.substring(0,d.indexOf(':'));
|
||||
String p = d.substring(h.length()+1);
|
||||
Member m = new MemberImpl(h,Integer.parseInt(p),2000);
|
||||
staticMembers.add(m);
|
||||
} else if ("-throughput".equals(args[i])) {
|
||||
throughput = true;
|
||||
} else if ("-order".equals(args[i])) {
|
||||
order = true;
|
||||
} else if ("-ordersize".equals(args[i])) {
|
||||
ordersize = Integer.parseInt(args[++i]);
|
||||
System.out.println("Setting OrderInterceptor.maxQueue="+ordersize);
|
||||
} else if ("-frag".equals(args[i])) {
|
||||
frag = true;
|
||||
} else if ("-fragsize".equals(args[i])) {
|
||||
fragsize = Integer.parseInt(args[++i]);
|
||||
System.out.println("Setting FragmentationInterceptor.maxSize="+fragsize);
|
||||
} else if ("-ackto".equals(args[i])) {
|
||||
acktimeout = Integer.parseInt(args[++i]);
|
||||
} else if ("-transport".equals(args[i])) {
|
||||
transport = args[++i];
|
||||
} else if (args[i]!=null && args[i].startsWith("transport.")) {
|
||||
String key = args[i];
|
||||
String val = args[++i];
|
||||
transportProperties.setProperty(key,val);
|
||||
} else if ("-receiver".equals(args[i])) {
|
||||
receiver = args[++i];
|
||||
} else if ("-maddr".equals(args[i])) {
|
||||
mcastaddr = args[++i];
|
||||
} else if ("-mport".equals(args[i])) {
|
||||
mcastport = Integer.parseInt(args[++i]);
|
||||
} else if ("-mfreq".equals(args[i])) {
|
||||
mcastfreq = Long.parseLong(args[++i]);
|
||||
} else if ("-mdrop".equals(args[i])) {
|
||||
mcastdrop = Long.parseLong(args[++i]);
|
||||
} else if ("-mbind".equals(args[i])) {
|
||||
mbind = args[++i];
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Creating receiver class="+receiver);
|
||||
Class<?> cl = Class.forName(receiver, true,
|
||||
ChannelCreator.class.getClassLoader());
|
||||
ReceiverBase rx = (ReceiverBase)cl.getConstructor().newInstance();
|
||||
rx.setAddress(bind);
|
||||
rx.setPort(port);
|
||||
rx.setSelectorTimeout(tcpseltimeout);
|
||||
rx.setMaxThreads(tcpthreadcount);
|
||||
rx.setMinThreads(tcpthreadcount);
|
||||
rx.getBind();
|
||||
rx.setRxBufSize(43800);
|
||||
rx.setTxBufSize(25188);
|
||||
rx.setAutoBind(autoBind);
|
||||
|
||||
|
||||
ReplicationTransmitter ps = new ReplicationTransmitter();
|
||||
System.out.println("Creating transport class="+transport);
|
||||
MultiPointSender sender = (MultiPointSender)Class.forName(
|
||||
transport,true,ChannelCreator.class.getClassLoader()).getConstructor().newInstance();
|
||||
sender.setTimeout(acktimeout);
|
||||
sender.setMaxRetryAttempts(2);
|
||||
sender.setRxBufSize(43800);
|
||||
sender.setTxBufSize(25188);
|
||||
|
||||
Iterator<Object> i = transportProperties.keySet().iterator();
|
||||
while ( i.hasNext() ) {
|
||||
String key = (String)i.next();
|
||||
IntrospectionUtils.setProperty(sender,key,transportProperties.getProperty(key));
|
||||
}
|
||||
ps.setTransport(sender);
|
||||
|
||||
McastService service = new McastService();
|
||||
service.setAddress(mcastaddr);
|
||||
if (mbind != null) service.setMcastBindAddress(mbind);
|
||||
service.setFrequency(mcastfreq);
|
||||
service.setMcastDropTime(mcastdrop);
|
||||
service.setPort(mcastport);
|
||||
|
||||
ManagedChannel channel = new GroupChannel();
|
||||
channel.setChannelReceiver(rx);
|
||||
channel.setChannelSender(ps);
|
||||
channel.setMembershipService(service);
|
||||
|
||||
if ( throughput ) channel.addInterceptor(new ThroughputInterceptor());
|
||||
if (gzip) channel.addInterceptor(new GzipInterceptor());
|
||||
if ( frag ) {
|
||||
FragmentationInterceptor fi = new FragmentationInterceptor();
|
||||
fi.setMaxSize(fragsize);
|
||||
channel.addInterceptor(fi);
|
||||
}
|
||||
if (order) {
|
||||
OrderInterceptor oi = new OrderInterceptor();
|
||||
oi.setMaxQueue(ordersize);
|
||||
channel.addInterceptor(oi);
|
||||
}
|
||||
|
||||
if ( async ) {
|
||||
MessageDispatchInterceptor mi = new MessageDispatchInterceptor();
|
||||
mi.setMaxQueueSize(asyncsize);
|
||||
channel.addInterceptor(mi);
|
||||
System.out.println("Added MessageDispatchInterceptor");
|
||||
}
|
||||
|
||||
if ( failuredetect ) {
|
||||
TcpFailureDetector tcpfi = new TcpFailureDetector();
|
||||
channel.addInterceptor(tcpfi);
|
||||
}
|
||||
if ( staticMembers.size() > 0 ) {
|
||||
StaticMembershipInterceptor smi = new StaticMembershipInterceptor();
|
||||
for (int x=0; x<staticMembers.size(); x++ ) {
|
||||
smi.addStaticMember(staticMembers.get(x));
|
||||
}
|
||||
channel.addInterceptor(smi);
|
||||
}
|
||||
|
||||
|
||||
byte[] domain = new byte[] {1,2,3,4,5,6,7,8,9,0};
|
||||
((McastService)channel.getMembershipService()).setDomain(domain);
|
||||
DomainFilterInterceptor filter = new DomainFilterInterceptor();
|
||||
filter.setDomain(domain);
|
||||
channel.addInterceptor(filter);
|
||||
return channel;
|
||||
}
|
||||
|
||||
}
|
||||
378
test/org/apache/catalina/tribes/demos/CoordinationDemo.java
Normal file
378
test/org/apache/catalina/tribes/demos/CoordinationDemo.java
Normal file
@@ -0,0 +1,378 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.demos;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.group.GroupChannel;
|
||||
import org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor;
|
||||
import org.apache.catalina.tribes.group.interceptors.NonBlockingCoordinator;
|
||||
import org.apache.catalina.tribes.group.interceptors.TcpFailureDetector;
|
||||
import org.apache.catalina.tribes.transport.ReceiverBase;
|
||||
import org.apache.catalina.tribes.util.Arrays;
|
||||
|
||||
|
||||
public class CoordinationDemo {
|
||||
static int CHANNEL_COUNT = 5;
|
||||
static int SCREEN_WIDTH = 120;
|
||||
static long SLEEP_TIME = 10;
|
||||
static int CLEAR_SCREEN = 30;
|
||||
static boolean MULTI_THREAD = false;
|
||||
static boolean[] VIEW_EVENTS = new boolean[255];
|
||||
StringBuilder statusLine = new StringBuilder();
|
||||
Status[] status = null;
|
||||
BufferedReader reader = null;
|
||||
/**
|
||||
* Construct and show the application.
|
||||
*/
|
||||
public CoordinationDemo() {
|
||||
// Default constructor
|
||||
}
|
||||
|
||||
public void init() {
|
||||
reader = new BufferedReader(new InputStreamReader(System.in));
|
||||
status = new Status[CHANNEL_COUNT];
|
||||
}
|
||||
|
||||
|
||||
public void clearScreen() {
|
||||
StringBuilder buf = new StringBuilder(700);
|
||||
for (int i=0; i<CLEAR_SCREEN; i++ ) buf.append("\n");
|
||||
System.out.println(buf);
|
||||
}
|
||||
|
||||
public void printMenuOptions() {
|
||||
System.out.println("Commands:");
|
||||
System.out.println("\tstart [member id]");
|
||||
System.out.println("\tstop [member id]");
|
||||
System.out.println("\tprint (refresh)");
|
||||
System.out.println("\tquit");
|
||||
System.out.print("Enter command:");
|
||||
}
|
||||
|
||||
public synchronized void printScreen() {
|
||||
clearScreen();
|
||||
System.out.println(" ###."+getHeader());
|
||||
for ( int i=0; i<status.length; i++ ) {
|
||||
System.out.print(leftfill(String.valueOf(i+1)+".",5," "));
|
||||
if ( status[i] != null ) System.out.print(status[i].getStatusLine());
|
||||
}
|
||||
System.out.println("\n\n");
|
||||
System.out.println("Overall status:"+statusLine);
|
||||
printMenuOptions();
|
||||
|
||||
}
|
||||
|
||||
public String getHeader() {
|
||||
//member - 30
|
||||
//running- 10
|
||||
//coord - 30
|
||||
//view-id - 24
|
||||
//view count - 8
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(leftfill("Member",30," "));
|
||||
buf.append(leftfill("Running",10," "));
|
||||
buf.append(leftfill("Coord",30," "));
|
||||
buf.append(leftfill("View-id(short)",24," "));
|
||||
buf.append(leftfill("Count",8," "));
|
||||
buf.append("\n");
|
||||
|
||||
buf.append(rightfill("==="+new java.sql.Timestamp(System.currentTimeMillis()).toString(),SCREEN_WIDTH,"="));
|
||||
buf.append("\n");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String[] tokenize(String line) {
|
||||
StringTokenizer tz = new StringTokenizer(line," ");
|
||||
String[] result = new String[tz.countTokens()];
|
||||
for (int i=0; i<result.length; i++ ) result[i] = tz.nextToken();
|
||||
return result;
|
||||
}
|
||||
|
||||
public void waitForInput() throws IOException {
|
||||
for ( int i=0; i<status.length; i++ ) status[i] = new Status(this);
|
||||
printScreen();
|
||||
String l = reader.readLine();
|
||||
String[] args;
|
||||
if (l == null) {
|
||||
args = new String[] {};
|
||||
} else {
|
||||
args = tokenize(l);
|
||||
}
|
||||
while ( args.length >= 1 && (!"quit".equalsIgnoreCase(args[0]))) {
|
||||
if ("start".equalsIgnoreCase(args[0])) {
|
||||
cmdStart(args);
|
||||
} else if ("stop".equalsIgnoreCase(args[0])) {
|
||||
cmdStop(args);
|
||||
|
||||
}
|
||||
printScreen();
|
||||
l = reader.readLine();
|
||||
if (l != null) {
|
||||
args = tokenize(l);
|
||||
}
|
||||
}
|
||||
for ( int i=0; i<status.length; i++ ) status[i].stop();
|
||||
}
|
||||
|
||||
private void cmdStop(String[] args) {
|
||||
if ( args.length == 1 ) {
|
||||
setSystemStatus("System shutting down...");
|
||||
Thread[] t = new Thread[CHANNEL_COUNT];
|
||||
for (int i = 0; i < status.length; i++) {
|
||||
final int j = i;
|
||||
t[j] = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
status[j].stop();
|
||||
}
|
||||
};
|
||||
}
|
||||
for (int i = 0; i < status.length; i++) if (MULTI_THREAD ) t[i].start(); else t[i].run();
|
||||
setSystemStatus("System stopped.");
|
||||
} else {
|
||||
int index = -1;
|
||||
try { index = Integer.parseInt(args[1])-1;}catch ( Exception x ) {setSystemStatus("Invalid index:"+args[1]);}
|
||||
if ( index >= 0 ) {
|
||||
setSystemStatus("Stopping member:"+(index+1));
|
||||
status[index].stop();
|
||||
setSystemStatus("Member stopped:"+(index+1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void cmdStart(String[] args) {
|
||||
if ( args.length == 1 ) {
|
||||
setSystemStatus("System starting up...");
|
||||
Thread[] t = new Thread[CHANNEL_COUNT];
|
||||
for (int i = 0; i < status.length; i++) {
|
||||
final int j = i;
|
||||
t[j] = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
status[j].start();
|
||||
}
|
||||
};
|
||||
}
|
||||
for (int i = 0; i < status.length; i++) if (MULTI_THREAD ) t[i].start(); else t[i].run();
|
||||
setSystemStatus("System started.");
|
||||
} else {
|
||||
int index = -1;
|
||||
try { index = Integer.parseInt(args[1])-1;}catch ( Exception x ) {setSystemStatus("Invalid index:"+args[1]);}
|
||||
if ( index >= 0 ) {
|
||||
setSystemStatus("Starting member:"+(index+1));
|
||||
status[index].start();
|
||||
setSystemStatus("Member started:"+(index+1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setSystemStatus(String status) {
|
||||
statusLine.delete(0,statusLine.length());
|
||||
statusLine.append(status);
|
||||
}
|
||||
|
||||
|
||||
public static void setEvents(String events) {
|
||||
java.util.Arrays.fill(VIEW_EVENTS,false);
|
||||
StringTokenizer t = new StringTokenizer(events,",");
|
||||
while (t.hasMoreTokens() ) {
|
||||
int idx = Integer.parseInt(t.nextToken());
|
||||
VIEW_EVENTS[idx] = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void run(String[] args,CoordinationDemo demo) throws Exception {
|
||||
usage();
|
||||
java.util.Arrays.fill(VIEW_EVENTS,true);
|
||||
|
||||
for (int i=0; i<args.length; i++ ) {
|
||||
if ( "-c".equals(args[i]) )
|
||||
CHANNEL_COUNT = Integer.parseInt(args[++i]);
|
||||
else if ( "-t".equals(args[i]) )
|
||||
MULTI_THREAD = Boolean.parseBoolean(args[++i]);
|
||||
else if ( "-s".equals(args[i]) )
|
||||
SLEEP_TIME = Long.parseLong(args[++i]);
|
||||
else if ( "-sc".equals(args[i]) )
|
||||
CLEAR_SCREEN = Integer.parseInt(args[++i]);
|
||||
else if ( "-p".equals(args[i]) )
|
||||
setEvents(args[++i]);
|
||||
else if ( "-h".equals(args[i]) ) System.exit(0);
|
||||
}
|
||||
demo.init();
|
||||
demo.waitForInput();
|
||||
}
|
||||
|
||||
private static void usage() {
|
||||
System.out.println("Usage:");
|
||||
System.out.println("\tjava org.apache.catalina.tribes.demos.CoordinationDemo -c channel-count(int) -t multi-thread(true|false) -s sleep-time(ms) -sc clear-screen(int) -p view_events_csv(1,2,5,7)");
|
||||
System.out.println("Example:");
|
||||
System.out.println("\tjava o.a.c.t.d.CoordinationDemo -> starts demo single threaded start/stop with 5 channels");
|
||||
System.out.println("\tjava o.a.c.t.d.CoordinationDemo -c 10 -> starts demo single threaded start/stop with 10 channels");
|
||||
System.out.println("\tjava o.a.c.t.d.CoordinationDemo -c 7 -t true -s 1000 -sc 50-> starts demo multi threaded start/stop with 7 channels and 1 second sleep time between events and 50 lines to clear screen");
|
||||
System.out.println("\tjava o.a.c.t.d.CoordinationDemo -t true -p 12 -> starts demo multi threaded start/stop with 5 channels and only prints the EVT_CONF_RX event");
|
||||
System.out.println();
|
||||
}
|
||||
public static void main(String[] args) throws Exception {
|
||||
CoordinationDemo demo = new CoordinationDemo();
|
||||
run(args,demo);
|
||||
}
|
||||
|
||||
public static String leftfill(String value, int length, String ch) {
|
||||
return fill(value,length,ch,true);
|
||||
}
|
||||
|
||||
public static String rightfill(String value, int length, String ch) {
|
||||
return fill(value,length,ch,false);
|
||||
}
|
||||
|
||||
public static String fill(String value, int length, String ch, boolean left) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
if ( !left ) buf.append(value.trim());
|
||||
for (int i=value.trim().length(); i<length; i++ ) buf.append(ch);
|
||||
if ( left ) buf.append(value.trim());
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
|
||||
public static class Status {
|
||||
public CoordinationDemo parent;
|
||||
public GroupChannel channel;
|
||||
NonBlockingCoordinator interceptor = null;
|
||||
public String status;
|
||||
public Exception error;
|
||||
public String startstatus = "new";
|
||||
|
||||
public Status(CoordinationDemo parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public String getStatusLine() {
|
||||
//member - 30
|
||||
//running- 10
|
||||
//coord - 30
|
||||
//view-id - 24
|
||||
//view count - 8
|
||||
StringBuilder buf = new StringBuilder();
|
||||
String local = "";
|
||||
String coord = "";
|
||||
String viewId = "";
|
||||
String count = "0";
|
||||
if ( channel != null ) {
|
||||
Member lm = channel.getLocalMember(false);
|
||||
local = lm!=null?lm.getName():"";
|
||||
coord = interceptor!=null && interceptor.getCoordinator()!=null?interceptor.getCoordinator().getName():"";
|
||||
if (interceptor != null) {
|
||||
viewId = getByteString(interceptor.getViewId()!=null?interceptor.getViewId().getBytes():new byte[0]);
|
||||
count = String.valueOf(interceptor.getView().length);
|
||||
}
|
||||
}
|
||||
buf.append(leftfill(local,30," "));
|
||||
buf.append(leftfill(startstatus, 10, " "));
|
||||
buf.append(leftfill(coord, 30, " "));
|
||||
buf.append(leftfill(viewId, 24, " "));
|
||||
buf.append(leftfill(count, 8, " "));
|
||||
buf.append("\n");
|
||||
buf.append("Status:"+status);
|
||||
buf.append("\n");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String getByteString(byte[] b) {
|
||||
if ( b == null ) return "{}";
|
||||
return Arrays.toString(b,0,Math.min(b.length,4));
|
||||
}
|
||||
|
||||
public void start() {
|
||||
try {
|
||||
if ( channel == null ) {
|
||||
channel = createChannel();
|
||||
startstatus = "starting";
|
||||
channel.start(Channel.DEFAULT);
|
||||
startstatus = "running";
|
||||
} else {
|
||||
status = "Channel already started.";
|
||||
}
|
||||
} catch ( Exception x ) {
|
||||
synchronized (System.err) {
|
||||
System.err.println("Start failed:");
|
||||
StackTraceElement[] els = x.getStackTrace();
|
||||
for (int i = 0; i < els.length; i++) System.err.println(els[i].toString());
|
||||
}
|
||||
status = "Start failed:"+x.getMessage();
|
||||
error = x;
|
||||
startstatus = "failed";
|
||||
try { channel.stop(Channel.DEFAULT);}catch(Exception ignore){
|
||||
// Ignore
|
||||
}
|
||||
channel = null;
|
||||
interceptor = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
try {
|
||||
if ( channel != null ) {
|
||||
channel.stop(Channel.DEFAULT);
|
||||
status = "Channel Stopped";
|
||||
} else {
|
||||
status = "Channel Already Stopped";
|
||||
}
|
||||
}catch ( Exception x ) {
|
||||
synchronized (System.err) {
|
||||
System.err.println("Stop failed:");
|
||||
StackTraceElement[] els = x.getStackTrace();
|
||||
for (int i = 0; i < els.length; i++) System.err.println(els[i].toString());
|
||||
}
|
||||
|
||||
status = "Stop failed:"+x.getMessage();
|
||||
error = x;
|
||||
}finally {
|
||||
startstatus = "stopped";
|
||||
channel = null;
|
||||
interceptor = null;
|
||||
}
|
||||
}
|
||||
|
||||
public GroupChannel createChannel() {
|
||||
channel = new GroupChannel();
|
||||
((ReceiverBase)channel.getChannelReceiver()).setAutoBind(100);
|
||||
interceptor = new NonBlockingCoordinator() {
|
||||
@Override
|
||||
public void fireInterceptorEvent(InterceptorEvent event) {
|
||||
status = event.getEventTypeDesc();
|
||||
int type = event.getEventType();
|
||||
boolean display = VIEW_EVENTS[type];
|
||||
if ( display ) parent.printScreen();
|
||||
try { Thread.sleep(SLEEP_TIME); }catch ( Exception x){
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
};
|
||||
channel.addInterceptor(interceptor);
|
||||
channel.addInterceptor(new TcpFailureDetector());
|
||||
channel.addInterceptor(new MessageDispatchInterceptor());
|
||||
return channel;
|
||||
}
|
||||
}
|
||||
}
|
||||
206
test/org/apache/catalina/tribes/demos/EchoRpcTest.java
Normal file
206
test/org/apache/catalina/tribes/demos/EchoRpcTest.java
Normal file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.demos;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.ManagedChannel;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.group.Response;
|
||||
import org.apache.catalina.tribes.group.RpcCallback;
|
||||
import org.apache.catalina.tribes.group.RpcChannel;
|
||||
|
||||
public class EchoRpcTest implements RpcCallback, Runnable {
|
||||
|
||||
Channel channel;
|
||||
int count;
|
||||
String message;
|
||||
long pause;
|
||||
RpcChannel rpc;
|
||||
int options;
|
||||
long timeout;
|
||||
String name;
|
||||
|
||||
public EchoRpcTest(Channel channel, String name, int count, String message, long pause, int options, long timeout) {
|
||||
this.channel = channel;
|
||||
this.count = count;
|
||||
this.message = message;
|
||||
this.pause = pause;
|
||||
this.options = options;
|
||||
this.rpc = new RpcChannel(name.getBytes(),channel,this);
|
||||
this.timeout = timeout;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the reply has already been sent to the requesting thread, the rpc
|
||||
* callback can handle any data that comes in after the fact.
|
||||
*
|
||||
* @param msg Serializable
|
||||
* @param sender Member
|
||||
*/
|
||||
@Override
|
||||
public void leftOver(Serializable msg, Member sender) {
|
||||
System.out.println("Received a left over message from ["+sender.getName()+"] with data ["+msg+"]");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param msg Serializable
|
||||
* @param sender Member
|
||||
* @return Serializable - null if no reply should be sent
|
||||
*/
|
||||
@Override
|
||||
public Serializable replyRequest(Serializable msg, Member sender) {
|
||||
System.out.println("Received a reply request message from ["+sender.getName()+"] with data ["+msg+"]");
|
||||
return "Reply("+name+"):"+msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long counter = 0;
|
||||
while (counter<count) {
|
||||
String msg = message + " cnt="+(++counter);
|
||||
try {
|
||||
System.out.println("Sending ["+msg+"]");
|
||||
long start = System.currentTimeMillis();
|
||||
Response[] resp = rpc.send(channel.getMembers(),msg,options,Channel.SEND_OPTIONS_DEFAULT,timeout);
|
||||
System.out.println("Send of ["+msg+"] completed. Nr of responses="+resp.length+" Time:"+(System.currentTimeMillis()-start)+" ms.");
|
||||
for ( int i=0; i<resp.length; i++ ) {
|
||||
System.out.println("Received a response message from ["+resp[i].getSource().getName()+"] with data ["+resp[i].getMessage()+"]");
|
||||
}
|
||||
Thread.sleep(pause);
|
||||
}catch(Exception x){
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void usage() {
|
||||
System.out.println("Tribes RPC tester.");
|
||||
System.out.println("Usage:\n\t"+
|
||||
"java EchoRpcTest [options]\n\t"+
|
||||
"Options:\n\t\t"+
|
||||
"[-mode all|first|majority] \n\t\t"+
|
||||
"[-debug] \n\t\t"+
|
||||
"[-count messagecount] \n\t\t"+
|
||||
"[-timeout timeoutinms] \n\t\t"+
|
||||
"[-stats statinterval] \n\t\t"+
|
||||
"[-pause nrofsecondstopausebetweensends] \n\t\t"+
|
||||
"[-message message] \n\t\t"+
|
||||
"[-name rpcname] \n\t\t"+
|
||||
"[-break (halts execution on exception)]\n"+
|
||||
"\tChannel options:"+
|
||||
ChannelCreator.usage()+"\n\n"+
|
||||
"Example:\n\t"+
|
||||
"java EchoRpcTest -port 4004\n\t"+
|
||||
"java EchoRpcTest -bind 192.168.0.45 -port 4005\n\t"+
|
||||
"java EchoRpcTest -bind 192.168.0.45 -port 4005 -mbind 192.168.0.45 -count 100 -stats 10\n");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
long pause = 3000;
|
||||
int count = 1000000;
|
||||
int stats = 10000;
|
||||
String name = "EchoRpcId";
|
||||
int options = RpcChannel.ALL_REPLY;
|
||||
long timeout = 15000;
|
||||
String message = "EchoRpcMessage";
|
||||
if (args.length == 0) {
|
||||
usage();
|
||||
System.exit(1);
|
||||
}
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if ("-threads".equals(args[i])) {
|
||||
// Not used
|
||||
} else if ("-count".equals(args[i])) {
|
||||
count = Integer.parseInt(args[++i]);
|
||||
System.out.println("Sending "+count+" messages.");
|
||||
} else if ("-pause".equals(args[i])) {
|
||||
pause = Long.parseLong(args[++i])*1000;
|
||||
} else if ("-break".equals(args[i])) {
|
||||
// Not used
|
||||
} else if ("-stats".equals(args[i])) {
|
||||
stats = Integer.parseInt(args[++i]);
|
||||
System.out.println("Stats every "+stats+" message");
|
||||
} else if ("-timeout".equals(args[i])) {
|
||||
timeout = Long.parseLong(args[++i]);
|
||||
} else if ("-message".equals(args[i])) {
|
||||
message = args[++i];
|
||||
} else if ("-name".equals(args[i])) {
|
||||
name = args[++i];
|
||||
} else if ("-mode".equals(args[i])) {
|
||||
if ( "all".equals(args[++i]) ) options = RpcChannel.ALL_REPLY;
|
||||
else if ( "first".equals(args[i]) ) options = RpcChannel.FIRST_REPLY;
|
||||
else if ( "majority".equals(args[i]) ) options = RpcChannel.MAJORITY_REPLY;
|
||||
} else if ("-debug".equals(args[i])) {
|
||||
// Not used
|
||||
} else if ("-help".equals(args[i])) {
|
||||
usage();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ManagedChannel channel = (ManagedChannel)ChannelCreator.createChannel(args);
|
||||
EchoRpcTest test = new EchoRpcTest(channel,name,count,message,pause,options,timeout);
|
||||
channel.start(Channel.DEFAULT);
|
||||
Runtime.getRuntime().addShutdownHook(new Shutdown(channel));
|
||||
test.run();
|
||||
|
||||
System.out.println("System test complete, sleeping to let threads finish.");
|
||||
Thread.sleep(60*1000*60);
|
||||
}
|
||||
|
||||
public static class Shutdown extends Thread {
|
||||
ManagedChannel channel = null;
|
||||
public Shutdown(ManagedChannel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println("Shutting down...");
|
||||
SystemExit exit = new SystemExit(5000);
|
||||
exit.setDaemon(true);
|
||||
exit.start();
|
||||
try {
|
||||
channel.stop(Channel.DEFAULT);
|
||||
|
||||
}catch ( Exception x ) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
System.out.println("Channel stopped.");
|
||||
}
|
||||
}
|
||||
public static class SystemExit extends Thread {
|
||||
private long delay;
|
||||
public SystemExit(long delay) {
|
||||
this.delay = delay;
|
||||
}
|
||||
@Override
|
||||
public void run () {
|
||||
try {
|
||||
Thread.sleep(delay);
|
||||
}catch ( Exception x ) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
System.exit(0);
|
||||
|
||||
}
|
||||
}}
|
||||
216
test/org/apache/catalina/tribes/demos/IntrospectionUtils.java
Normal file
216
test/org/apache/catalina/tribes/demos/IntrospectionUtils.java
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.demos;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import org.apache.juli.logging.Log;
|
||||
import org.apache.juli.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Utils for introspection and reflection
|
||||
*/
|
||||
public final class IntrospectionUtils {
|
||||
|
||||
|
||||
private static final Log log = LogFactory.getLog(IntrospectionUtils.class);
|
||||
|
||||
/*
|
||||
* Find a method with the right name If found, call the method ( if param is
|
||||
* int or boolean we'll convert value to the right type before) - that means
|
||||
* you can have setDebug(1).
|
||||
*/
|
||||
@SuppressWarnings("null")
|
||||
public static boolean setProperty(Object o, String name, String value) {
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("IntrospectionUtils: setProperty(" +
|
||||
o.getClass() + " " + name + "=" + value + ")");
|
||||
|
||||
String setter = "set" + capitalize(name);
|
||||
|
||||
try {
|
||||
Method methods[] = findMethods(o.getClass());
|
||||
Method setPropertyMethodVoid = null;
|
||||
Method setPropertyMethodBool = null;
|
||||
|
||||
// First, the ideal case - a setFoo( String ) method
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
Class<?> paramT[] = methods[i].getParameterTypes();
|
||||
if (setter.equals(methods[i].getName()) && paramT.length == 1
|
||||
&& "java.lang.String".equals(paramT[0].getName())) {
|
||||
|
||||
methods[i].invoke(o, new Object[] { value });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Try a setFoo ( int ) or ( boolean )
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
boolean ok = true;
|
||||
if (setter.equals(methods[i].getName())
|
||||
&& methods[i].getParameterTypes().length == 1) {
|
||||
|
||||
// match - find the type and invoke it
|
||||
Class<?> paramType = methods[i].getParameterTypes()[0];
|
||||
Object params[] = new Object[1];
|
||||
|
||||
// Try a setFoo ( int )
|
||||
if ("java.lang.Integer".equals(paramType.getName())
|
||||
|| "int".equals(paramType.getName())) {
|
||||
try {
|
||||
params[0] = Integer.valueOf(value);
|
||||
} catch (NumberFormatException ex) {
|
||||
ok = false;
|
||||
}
|
||||
// Try a setFoo ( long )
|
||||
}else if ("java.lang.Long".equals(paramType.getName())
|
||||
|| "long".equals(paramType.getName())) {
|
||||
try {
|
||||
params[0] = Long.valueOf(value);
|
||||
} catch (NumberFormatException ex) {
|
||||
ok = false;
|
||||
}
|
||||
|
||||
// Try a setFoo ( boolean )
|
||||
} else if ("java.lang.Boolean".equals(paramType.getName())
|
||||
|| "boolean".equals(paramType.getName())) {
|
||||
params[0] = Boolean.valueOf(value);
|
||||
|
||||
// Try a setFoo ( InetAddress )
|
||||
} else if ("java.net.InetAddress".equals(paramType
|
||||
.getName())) {
|
||||
try {
|
||||
params[0] = InetAddress.getByName(value);
|
||||
} catch (UnknownHostException exc) {
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("IntrospectionUtils: Unable to resolve host name:" + value);
|
||||
ok = false;
|
||||
}
|
||||
|
||||
// Unknown type
|
||||
} else {
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("IntrospectionUtils: Unknown type " +
|
||||
paramType.getName());
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
methods[i].invoke(o, params);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// save "setProperty" for later
|
||||
if ("setProperty".equals(methods[i].getName())) {
|
||||
if (methods[i].getReturnType()==Boolean.TYPE){
|
||||
setPropertyMethodBool = methods[i];
|
||||
}else {
|
||||
setPropertyMethodVoid = methods[i];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Ok, no setXXX found, try a setProperty("name", "value")
|
||||
if (setPropertyMethodBool != null || setPropertyMethodVoid != null) {
|
||||
Object params[] = new Object[2];
|
||||
params[0] = name;
|
||||
params[1] = value;
|
||||
if (setPropertyMethodBool != null) {
|
||||
try {
|
||||
return ((Boolean) setPropertyMethodBool.invoke(o,
|
||||
params)).booleanValue();
|
||||
}catch (IllegalArgumentException biae) {
|
||||
//the boolean method had the wrong
|
||||
//parameter types. lets try the other
|
||||
if (setPropertyMethodVoid!=null) {
|
||||
setPropertyMethodVoid.invoke(o, params);
|
||||
return true;
|
||||
}else {
|
||||
throw biae;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setPropertyMethodVoid.invoke(o, params);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (IllegalArgumentException ex2) {
|
||||
log.warn("IAE " + o + " " + name + " " + value, ex2);
|
||||
} catch (SecurityException ex1) {
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("IntrospectionUtils: SecurityException for " +
|
||||
o.getClass() + " " + name + "=" + value + ")", ex1);
|
||||
} catch (IllegalAccessException iae) {
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("IntrospectionUtils: IllegalAccessException for " +
|
||||
o.getClass() + " " + name + "=" + value + ")", iae);
|
||||
} catch (InvocationTargetException ie) {
|
||||
Throwable cause = ie.getCause();
|
||||
if (cause instanceof ThreadDeath) {
|
||||
throw (ThreadDeath) cause;
|
||||
}
|
||||
if (cause instanceof VirtualMachineError) {
|
||||
throw (VirtualMachineError) cause;
|
||||
}
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("IntrospectionUtils: InvocationTargetException for " +
|
||||
o.getClass() + " " + name + "=" + value + ")", ie);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reverse of Introspector.decapitalize
|
||||
*/
|
||||
public static String capitalize(String name) {
|
||||
if (name == null || name.length() == 0) {
|
||||
return name;
|
||||
}
|
||||
char chars[] = name.toCharArray();
|
||||
chars[0] = Character.toUpperCase(chars[0]);
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
// -------------------- other utils --------------------
|
||||
/**
|
||||
* @deprecated Not used, but code must be updated to call it
|
||||
*/
|
||||
@Deprecated
|
||||
public static void clear() {
|
||||
objectMethods.clear();
|
||||
}
|
||||
|
||||
static Hashtable<Class<?>,Method[]> objectMethods = new Hashtable<>();
|
||||
|
||||
public static Method[] findMethods(Class<?> c) {
|
||||
Method methods[] = objectMethods.get(c);
|
||||
if (methods != null)
|
||||
return methods;
|
||||
|
||||
methods = c.getMethods();
|
||||
objectMethods.put(c, methods);
|
||||
return methods;
|
||||
}
|
||||
|
||||
}
|
||||
409
test/org/apache/catalina/tribes/demos/LoadTest.java
Normal file
409
test/org/apache/catalina/tribes/demos/LoadTest.java
Normal file
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.demos;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Random;
|
||||
|
||||
import org.apache.catalina.tribes.ByteMessage;
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.ChannelException;
|
||||
import org.apache.catalina.tribes.ChannelListener;
|
||||
import org.apache.catalina.tribes.ManagedChannel;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.MembershipListener;
|
||||
import org.apache.juli.logging.Log;
|
||||
import org.apache.juli.logging.LogFactory;
|
||||
|
||||
public class LoadTest implements MembershipListener,ChannelListener, Runnable {
|
||||
private static final Log log = LogFactory.getLog(LoadTest.class);
|
||||
public static int size = 24000;
|
||||
public static final Object mutex = new Object();
|
||||
public boolean doRun = true;
|
||||
|
||||
public long bytesReceived = 0;
|
||||
public float mBytesReceived = 0;
|
||||
public int messagesReceived = 0;
|
||||
public boolean send = true;
|
||||
public boolean debug = false;
|
||||
public int msgCount = 100;
|
||||
ManagedChannel channel=null;
|
||||
public int statsInterval = 10000;
|
||||
public long pause = 0;
|
||||
public boolean breakonChannelException = false;
|
||||
public boolean async = false;
|
||||
public long receiveStart = 0;
|
||||
public int channelOptions = Channel.SEND_OPTIONS_DEFAULT;
|
||||
|
||||
static int messageSize = 0;
|
||||
|
||||
public static long messagesSent = 0;
|
||||
public static long messageStartSendTime = 0;
|
||||
public static long messageEndSendTime = 0;
|
||||
public static int threadCount = 0;
|
||||
|
||||
public static synchronized void startTest() {
|
||||
threadCount++;
|
||||
if ( messageStartSendTime == 0 ) messageStartSendTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public static synchronized void endTest() {
|
||||
threadCount--;
|
||||
if ( messageEndSendTime == 0 && threadCount==0 ) messageEndSendTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
|
||||
public static synchronized long addSendStats(long count) {
|
||||
messagesSent+=count;
|
||||
return 0l;
|
||||
}
|
||||
|
||||
private static void printSendStats(long counter, int messageSize) {
|
||||
float cnt = counter;
|
||||
float size = messageSize;
|
||||
float time = (System.currentTimeMillis()-messageStartSendTime) / 1000f;
|
||||
log.info("****SEND STATS-"+Thread.currentThread().getName()+"*****"+
|
||||
"\n\tMessage count:"+counter+
|
||||
"\n\tTotal bytes :"+(long)(size*cnt)+
|
||||
"\n\tTotal seconds:"+(time)+
|
||||
"\n\tBytes/second :"+(size*cnt/time)+
|
||||
"\n\tMBytes/second:"+(size*cnt/time/1024f/1024f));
|
||||
}
|
||||
|
||||
|
||||
public LoadTest(ManagedChannel channel,
|
||||
boolean send,
|
||||
int msgCount,
|
||||
boolean debug,
|
||||
long pause,
|
||||
int stats,
|
||||
boolean breakOnEx) {
|
||||
this.channel = channel;
|
||||
this.send = send;
|
||||
this.msgCount = msgCount;
|
||||
this.debug = debug;
|
||||
this.pause = pause;
|
||||
this.statsInterval = stats;
|
||||
this.breakonChannelException = breakOnEx;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
long counter = 0;
|
||||
long total = 0;
|
||||
LoadMessage msg = new LoadMessage();
|
||||
|
||||
try {
|
||||
startTest();
|
||||
while (total < msgCount) {
|
||||
if (channel.getMembers().length == 0 || (!send)) {
|
||||
synchronized (mutex) {
|
||||
try {
|
||||
mutex.wait();
|
||||
} catch (InterruptedException x) {
|
||||
log.info("Thread interrupted from wait");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
//msg.setMsgNr((int)++total);
|
||||
counter++;
|
||||
if (debug) {
|
||||
printArray(msg.getMessage());
|
||||
}
|
||||
channel.send(channel.getMembers(), msg, channelOptions);
|
||||
if ( pause > 0 ) {
|
||||
if ( debug) System.out.println("Pausing sender for "+pause+" ms.");
|
||||
Thread.sleep(pause);
|
||||
}
|
||||
} catch (ChannelException x) {
|
||||
if ( debug ) log.error("Unable to send message:"+x.getMessage(),x);
|
||||
log.error("Unable to send message:"+x.getMessage());
|
||||
ChannelException.FaultyMember[] faulty = x.getFaultyMembers();
|
||||
for (int i=0; i<faulty.length; i++ ) log.error("Faulty: "+faulty[i]);
|
||||
--counter;
|
||||
if ( this.breakonChannelException ) throw x;
|
||||
}
|
||||
}
|
||||
if ( (counter % statsInterval) == 0 && (counter > 0)) {
|
||||
//add to the global counter
|
||||
counter = addSendStats(counter);
|
||||
//print from the global counter
|
||||
//printSendStats(LoadTest.messagesSent, LoadTest.messageSize, LoadTest.messageSendTime);
|
||||
printSendStats(LoadTest.messagesSent, LoadTest.messageSize);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}catch ( Exception x ) {
|
||||
log.error("Captured error while sending:"+x.getMessage());
|
||||
if ( debug ) log.error("",x);
|
||||
printSendStats(LoadTest.messagesSent, LoadTest.messageSize);
|
||||
}
|
||||
endTest();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* memberAdded
|
||||
*
|
||||
* @param member Member
|
||||
* TODO Implement this org.apache.catalina.tribes.MembershipListener
|
||||
* method
|
||||
*/
|
||||
@Override
|
||||
public void memberAdded(Member member) {
|
||||
log.info("Member added:"+member);
|
||||
synchronized (mutex) {
|
||||
mutex.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* memberDisappeared
|
||||
*
|
||||
* @param member Member
|
||||
* TODO Implement this org.apache.catalina.tribes.MembershipListener
|
||||
* method
|
||||
*/
|
||||
@Override
|
||||
public void memberDisappeared(Member member) {
|
||||
log.info("Member disappeared:"+member);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Serializable msg, Member mbr){
|
||||
return (msg instanceof LoadMessage) || (msg instanceof ByteMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageReceived(Serializable msg, Member mbr){
|
||||
if ( receiveStart == 0 ) receiveStart = System.currentTimeMillis();
|
||||
if ( debug ) {
|
||||
if ( msg instanceof LoadMessage ) {
|
||||
printArray(((LoadMessage)msg).getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if ( msg instanceof ByteMessage && !(msg instanceof LoadMessage)) {
|
||||
LoadMessage tmp = new LoadMessage();
|
||||
tmp.setMessage(((ByteMessage)msg).getMessage());
|
||||
msg = tmp;
|
||||
tmp = null;
|
||||
}
|
||||
|
||||
|
||||
bytesReceived+=((LoadMessage)msg).getMessage().length;
|
||||
mBytesReceived+=(((LoadMessage)msg).getMessage().length)/1024f/1024f;
|
||||
messagesReceived++;
|
||||
if ( (messagesReceived%statsInterval)==0 || (messagesReceived==msgCount)) {
|
||||
float bytes = (((LoadMessage)msg).getMessage().length*messagesReceived);
|
||||
float seconds = (System.currentTimeMillis()-receiveStart) / 1000f;
|
||||
log.info("****RECEIVE STATS-"+Thread.currentThread().getName()+"*****"+
|
||||
"\n\tMessage count :"+(long)messagesReceived+
|
||||
"\n\tMessage/sec :"+messagesReceived/seconds+
|
||||
"\n\tTotal bytes :"+(long)bytes+
|
||||
"\n\tTotal mbytes :"+(long)mBytesReceived+
|
||||
"\n\tTime since 1st:"+seconds+" seconds"+
|
||||
"\n\tBytes/second :"+(bytes/seconds)+
|
||||
"\n\tMBytes/second :"+(mBytesReceived/seconds)+"\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void printArray(byte[] data) {
|
||||
System.out.print("{");
|
||||
for (int i=0; i<data.length; i++ ) {
|
||||
System.out.print(data[i]);
|
||||
System.out.print(",");
|
||||
}
|
||||
System.out.println("} size:"+data.length);
|
||||
}
|
||||
|
||||
|
||||
public static class LoadMessage extends ByteMessage {
|
||||
|
||||
public static byte[] outdata = new byte[size];
|
||||
public static final Random r = new Random();
|
||||
public static int getMessageSize (LoadMessage msg) {
|
||||
return msg.getMessage().length;
|
||||
}
|
||||
static {
|
||||
r.nextBytes(outdata);
|
||||
}
|
||||
|
||||
protected byte[] message = getMessage();
|
||||
|
||||
public LoadMessage() {
|
||||
// Default constructor
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getMessage() {
|
||||
if ( message == null ) {
|
||||
message = outdata;
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMessage(byte[] data) {
|
||||
this.message = data;
|
||||
}
|
||||
}
|
||||
|
||||
public static void usage() {
|
||||
System.out.println("Tribes Load tester.");
|
||||
System.out.println("The load tester can be used in sender or received mode or both");
|
||||
System.out.println("Usage:\n\t"+
|
||||
"java LoadTest [options]\n\t"+
|
||||
"Options:\n\t\t"+
|
||||
"[-mode receive|send|both] \n\t\t"+
|
||||
"[-startoptions startflags (default is Channel.DEFAULT) ] \n\t\t"+
|
||||
"[-debug] \n\t\t"+
|
||||
"[-count messagecount] \n\t\t"+
|
||||
"[-stats statinterval] \n\t\t"+
|
||||
"[-pause nrofsecondstopausebetweensends] \n\t\t"+
|
||||
"[-threads numberofsenderthreads] \n\t\t"+
|
||||
"[-size messagesize] \n\t\t"+
|
||||
"[-sendoptions channeloptions] \n\t\t"+
|
||||
"[-break (halts execution on exception)]\n"+
|
||||
"[-shutdown (issues a channel.stop() command after send is completed)]\n"+
|
||||
"\tChannel options:"+
|
||||
ChannelCreator.usage()+"\n\n"+
|
||||
"Example:\n\t"+
|
||||
"java LoadTest -port 4004\n\t"+
|
||||
"java LoadTest -bind 192.168.0.45 -port 4005\n\t"+
|
||||
"java LoadTest -bind 192.168.0.45 -port 4005 -mbind 192.168.0.45 -count 100 -stats 10\n");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
boolean send = true;
|
||||
boolean debug = false;
|
||||
long pause = 0;
|
||||
int count = 1000000;
|
||||
int stats = 10000;
|
||||
boolean breakOnEx = false;
|
||||
int threads = 1;
|
||||
boolean shutdown = false;
|
||||
int startoptions = Channel.DEFAULT;
|
||||
int channelOptions = Channel.SEND_OPTIONS_DEFAULT;
|
||||
if ( args.length == 0 ) {
|
||||
args = new String[] {"-help"};
|
||||
}
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if ("-threads".equals(args[i])) {
|
||||
threads = Integer.parseInt(args[++i]);
|
||||
} else if ("-count".equals(args[i])) {
|
||||
count = Integer.parseInt(args[++i]);
|
||||
System.out.println("Sending "+count+" messages.");
|
||||
} else if ("-pause".equals(args[i])) {
|
||||
pause = Long.parseLong(args[++i])*1000;
|
||||
} else if ("-break".equals(args[i])) {
|
||||
breakOnEx = true;
|
||||
} else if ("-shutdown".equals(args[i])) {
|
||||
shutdown = true;
|
||||
} else if ("-stats".equals(args[i])) {
|
||||
stats = Integer.parseInt(args[++i]);
|
||||
System.out.println("Stats every "+stats+" message");
|
||||
} else if ("-sendoptions".equals(args[i])) {
|
||||
channelOptions = Integer.parseInt(args[++i]);
|
||||
System.out.println("Setting send options to "+channelOptions);
|
||||
} else if ("-startoptions".equals(args[i])) {
|
||||
startoptions = Integer.parseInt(args[++i]);
|
||||
System.out.println("Setting start options to "+startoptions);
|
||||
} else if ("-size".equals(args[i])) {
|
||||
size = Integer.parseInt(args[++i])-4;
|
||||
System.out.println("Message size will be:"+(size+4)+" bytes");
|
||||
} else if ("-mode".equals(args[i])) {
|
||||
if ( "receive".equals(args[++i]) ) send = false;
|
||||
} else if ("-debug".equals(args[i])) {
|
||||
debug = true;
|
||||
} else if ("-help".equals(args[i]))
|
||||
{
|
||||
usage();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
ManagedChannel channel = (ManagedChannel)ChannelCreator.createChannel(args);
|
||||
|
||||
LoadTest test = new LoadTest(channel,send,count,debug,pause,stats,breakOnEx);
|
||||
test.channelOptions = channelOptions;
|
||||
LoadMessage msg = new LoadMessage();
|
||||
|
||||
messageSize = LoadMessage.getMessageSize(msg);
|
||||
channel.addChannelListener(test);
|
||||
channel.addMembershipListener(test);
|
||||
channel.start(startoptions);
|
||||
Runtime.getRuntime().addShutdownHook(new Shutdown(channel));
|
||||
while ( threads > 1 ) {
|
||||
Thread t = new Thread(test);
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
threads--;
|
||||
test = new LoadTest(channel,send,count,debug,pause,stats,breakOnEx);
|
||||
test.channelOptions = channelOptions;
|
||||
}
|
||||
test.run();
|
||||
if ( shutdown && send ) channel.stop(Channel.DEFAULT);
|
||||
System.out.println("System test complete, sleeping to let threads finish.");
|
||||
Thread.sleep(60*1000*60);
|
||||
}
|
||||
|
||||
public static class Shutdown extends Thread {
|
||||
ManagedChannel channel = null;
|
||||
public Shutdown(ManagedChannel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println("Shutting down...");
|
||||
SystemExit exit = new SystemExit(5000);
|
||||
exit.setDaemon(true);
|
||||
exit.start();
|
||||
try {
|
||||
channel.stop(Channel.DEFAULT);
|
||||
|
||||
}catch ( Exception x ) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
System.out.println("Channel stopped.");
|
||||
}
|
||||
}
|
||||
public static class SystemExit extends Thread {
|
||||
private long delay;
|
||||
public SystemExit(long delay) {
|
||||
this.delay = delay;
|
||||
}
|
||||
@Override
|
||||
public void run () {
|
||||
try {
|
||||
Thread.sleep(delay);
|
||||
}catch ( Exception x ) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
System.exit(0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
552
test/org/apache/catalina/tribes/demos/MapDemo.java
Normal file
552
test/org/apache/catalina/tribes/demos/MapDemo.java
Normal file
File diff suppressed because it is too large
Load Diff
123
test/org/apache/catalina/tribes/demos/MembersWithProperties.java
Normal file
123
test/org/apache/catalina/tribes/demos/MembersWithProperties.java
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.demos;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.ManagedChannel;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.MembershipListener;
|
||||
import org.apache.catalina.tribes.util.Arrays;
|
||||
import org.apache.catalina.tribes.util.UUIDGenerator;
|
||||
|
||||
public class MembersWithProperties implements MembershipListener{
|
||||
static Thread main;
|
||||
|
||||
public MembersWithProperties(Channel channel, Properties props) throws IOException {
|
||||
channel.addMembershipListener(this);
|
||||
ManagedChannel mchannel = (ManagedChannel)channel;
|
||||
mchannel.getMembershipService().setPayload(getPayload(props));
|
||||
}
|
||||
|
||||
byte[] getPayload(Properties props) throws IOException {
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
props.store(bout,"");
|
||||
return bout.toByteArray();
|
||||
}
|
||||
|
||||
Properties getProperties(byte[] payload) throws IOException {
|
||||
ByteArrayInputStream bin = new ByteArrayInputStream(payload);
|
||||
Properties props = new Properties();
|
||||
props.load(bin);
|
||||
return props;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void memberAdded(Member member) {
|
||||
try {
|
||||
System.out.println("Received member added:"+member);
|
||||
System.out.println("Payload["+member+"] :");
|
||||
getProperties(member.getPayload()).store(System.out,"");
|
||||
}catch ( Exception x ) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void memberDisappeared(Member member) {
|
||||
try {
|
||||
System.out.println("Received member disappeared:"+member);
|
||||
System.out.println("Payload["+member+"] :");
|
||||
getProperties(member.getPayload()).store(System.out,"");
|
||||
}catch ( Exception x ) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void usage() {
|
||||
System.out.println("Tribes Member Properties demo.");
|
||||
System.out.println("Usage:\n\t" +
|
||||
"java MemberWithProperties \n\t" +
|
||||
"Channel options:" +
|
||||
ChannelCreator.usage() + "\n\n" +
|
||||
"Example:\n\t" +
|
||||
"java MembersWithProperties -port 4004\n\t" +
|
||||
"java MembersWithProperties -bind 192.168.0.45 -port 4005\n\t" +
|
||||
"java MembersWithProperties -bind 192.168.0.45 -port 4005 -mbind 192.168.0.45 -count 100 -stats 10\n");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length==0) usage();
|
||||
main = Thread.currentThread();
|
||||
ManagedChannel channel = (ManagedChannel) ChannelCreator.createChannel(args);
|
||||
Properties props = new Properties();
|
||||
props.setProperty("mydomainkey","mydomainvalue");
|
||||
props.setProperty("someotherkey", Arrays.toString(UUIDGenerator.randomUUID(true)));
|
||||
new MembersWithProperties(channel, props);
|
||||
channel.start(Channel.DEFAULT);
|
||||
Runtime.getRuntime().addShutdownHook(new Shutdown(channel));
|
||||
try {
|
||||
Thread.sleep(Long.MAX_VALUE);
|
||||
}catch(InterruptedException ix) {
|
||||
Thread.sleep(5000);//allow everything to shutdown
|
||||
}
|
||||
}
|
||||
|
||||
public static class Shutdown extends Thread {
|
||||
ManagedChannel channel = null;
|
||||
public Shutdown(ManagedChannel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println("Shutting down...");
|
||||
try {
|
||||
channel.stop(Channel.DEFAULT);
|
||||
} catch (Exception x) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
System.out.println("Channel stopped.");
|
||||
main.interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.group;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.ManagedChannel;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.MembershipListener;
|
||||
import org.apache.catalina.tribes.TesterUtil;
|
||||
|
||||
public class TestGroupChannelMemberArrival {
|
||||
private static int count = 10;
|
||||
private ManagedChannel[] channels = new ManagedChannel[count];
|
||||
private TestMbrListener[] listeners = new TestMbrListener[count];
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
for (int i = 0; i < channels.length; i++) {
|
||||
channels[i] = new GroupChannel();
|
||||
channels[i].getMembershipService().setPayload( ("Channel-" + (i + 1)).getBytes("ASCII"));
|
||||
listeners[i] = new TestMbrListener( ("Listener-" + (i + 1)));
|
||||
channels[i].addMembershipListener(listeners[i]);
|
||||
}
|
||||
TesterUtil.addRandomDomain(channels);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMemberArrival() throws Exception {
|
||||
//purpose of this test is to make sure that we have received all the members
|
||||
//that we can expect before the start method returns
|
||||
Thread[] threads = new Thread[channels.length];
|
||||
for (int i=0; i<channels.length; i++ ) {
|
||||
final Channel channel = channels[i];
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
channel.start(Channel.DEFAULT);
|
||||
}catch ( Exception x ) {
|
||||
throw new RuntimeException(x);
|
||||
}
|
||||
}
|
||||
};
|
||||
threads[i] = t;
|
||||
}
|
||||
for (int i = 0; i < threads.length; i++) {
|
||||
threads[i].start();
|
||||
}
|
||||
for (int i = 0; i < threads.length; i++) {
|
||||
threads[i].join();
|
||||
}
|
||||
Thread.sleep(5000);
|
||||
System.out.println(System.currentTimeMillis()
|
||||
+ " All channels started.");
|
||||
StringBuilder arrivalLengthErrors = new StringBuilder();
|
||||
for (int i = listeners.length - 1; i >= 0; i--) {
|
||||
TestMbrListener listener = listeners[i];
|
||||
synchronized (listener.members) {
|
||||
if (channels.length - 1 != listener.members.size()) {
|
||||
arrivalLengthErrors.append("Checking member arrival length for [");
|
||||
arrivalLengthErrors.append(listener.name);
|
||||
arrivalLengthErrors.append("]. Was [");
|
||||
arrivalLengthErrors.append(listener.members.size());
|
||||
arrivalLengthErrors.append("] but should have been [");
|
||||
arrivalLengthErrors.append(channels.length - 1);
|
||||
arrivalLengthErrors.append("]");
|
||||
arrivalLengthErrors.append('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
// Note if this fails for all listeners check multicast is working with
|
||||
// org.apache.catalina.tribes.TesterMulticast
|
||||
Assert.assertTrue(arrivalLengthErrors.toString(), arrivalLengthErrors.length() == 0);
|
||||
System.out.println(System.currentTimeMillis()
|
||||
+ " Members arrival counts checked.");
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
|
||||
for (int i = 0; i < channels.length; i++) {
|
||||
try {
|
||||
channels[i].stop(Channel.DEFAULT);
|
||||
} catch (Exception ignore) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestMbrListener
|
||||
implements MembershipListener {
|
||||
public String name = null;
|
||||
public TestMbrListener(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public ArrayList<Member> members = new ArrayList<>(1);
|
||||
|
||||
@Override
|
||||
public void memberAdded(Member member) {
|
||||
String msg;
|
||||
int count;
|
||||
synchronized (members) {
|
||||
if (!members.contains(member)) {
|
||||
members.add(member);
|
||||
msg = "member added";
|
||||
} else {
|
||||
msg = "member added called, but member is already in the list";
|
||||
}
|
||||
count = members.size();
|
||||
}
|
||||
report(msg, member, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void memberDisappeared(Member member) {
|
||||
String msg;
|
||||
int count;
|
||||
synchronized (members) {
|
||||
if (members.contains(member)) {
|
||||
members.remove(member);
|
||||
msg = "member disappeared";
|
||||
} else {
|
||||
msg = "member disappeared called, but there is no such member in the list";
|
||||
}
|
||||
count = members.size();
|
||||
}
|
||||
report(msg, member, count);
|
||||
}
|
||||
|
||||
private void report(String event, Member member, int count) {
|
||||
StringBuilder message = new StringBuilder(100);
|
||||
message.append(System.currentTimeMillis());
|
||||
message.append(' ');
|
||||
message.append(name);
|
||||
message.append(':');
|
||||
message.append(event);
|
||||
message.append(", has ");
|
||||
message.append(count);
|
||||
message.append(" members now. Member:[");
|
||||
message.append("host: ");
|
||||
appendByteArrayToString(message, member.getHost());
|
||||
message.append(", port: ");
|
||||
message.append(member.getPort());
|
||||
message.append(", id: ");
|
||||
appendByteArrayToString(message, member.getUniqueId());
|
||||
message.append(", payload: ");
|
||||
try {
|
||||
message.append(new String(member.getPayload(), "ASCII"));
|
||||
} catch (Exception x) {
|
||||
message.append("unknown");
|
||||
}
|
||||
Thread t = Thread.currentThread();
|
||||
message.append("]; Thread:").append(t.getName()).append(", hash:")
|
||||
.append(t.hashCode());
|
||||
System.out.println(message);
|
||||
}
|
||||
|
||||
private void appendByteArrayToString(StringBuilder sb, byte[] input) {
|
||||
if (input == null) {
|
||||
sb.append("null");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < input.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append('.');
|
||||
}
|
||||
sb.append(input[i] & 0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.group;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.ChannelException;
|
||||
import org.apache.catalina.tribes.ChannelInterceptor;
|
||||
|
||||
public class TestGroupChannelOptionFlag {
|
||||
private GroupChannel channel = null;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
channel = new GroupChannel();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (channel != null) {
|
||||
try {
|
||||
channel.stop(Channel.DEFAULT);
|
||||
} catch (Exception ignore) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
channel = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOptionConflict() throws Exception {
|
||||
boolean error = false;
|
||||
channel.setOptionCheck(true);
|
||||
ChannelInterceptor i = new TestInterceptor();
|
||||
i.setOptionFlag(128);
|
||||
channel.addInterceptor(i);
|
||||
i = new TestInterceptor();
|
||||
i.setOptionFlag(128);
|
||||
channel.addInterceptor(i);
|
||||
try {
|
||||
channel.start(Channel.DEFAULT);
|
||||
}catch ( ChannelException x ) {
|
||||
if ( x.getMessage().indexOf("option flag conflict") >= 0 ) error = true;
|
||||
}
|
||||
Assert.assertTrue(error);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOptionNoConflict() throws Exception {
|
||||
boolean error = false;
|
||||
channel.setOptionCheck(true);
|
||||
ChannelInterceptor i = new TestInterceptor();
|
||||
i.setOptionFlag(128);
|
||||
channel.addInterceptor(i);
|
||||
i = new TestInterceptor();
|
||||
i.setOptionFlag(64);
|
||||
channel.addInterceptor(i);
|
||||
i = new TestInterceptor();
|
||||
i.setOptionFlag(256);
|
||||
channel.addInterceptor(i);
|
||||
try {
|
||||
channel.start(Channel.DEFAULT);
|
||||
}catch ( ChannelException x ) {
|
||||
if ( x.getMessage().indexOf("option flag conflict") >= 0 ) error = true;
|
||||
}
|
||||
Assert.assertFalse(error);
|
||||
}
|
||||
|
||||
public static class TestInterceptor extends ChannelInterceptorBase {
|
||||
// Just use base class
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.group;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.startup.LoggingBaseTest;
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.ChannelListener;
|
||||
import org.apache.catalina.tribes.ManagedChannel;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.TesterUtil;
|
||||
import org.apache.catalina.tribes.transport.ReplicationTransmitter;
|
||||
|
||||
public class TestGroupChannelSenderConnections extends LoggingBaseTest {
|
||||
private static final int count = 2;
|
||||
private ManagedChannel[] channels = new ManagedChannel[count];
|
||||
private TestMsgListener[] listeners = new TestMsgListener[count];
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
for (int i = 0; i < channels.length; i++) {
|
||||
channels[i] = new GroupChannel();
|
||||
channels[i].getMembershipService().setPayload( ("Channel-" + (i + 1)).getBytes("ASCII"));
|
||||
listeners[i] = new TestMsgListener( ("Listener-" + (i + 1)));
|
||||
channels[i].addChannelListener(listeners[i]);
|
||||
}
|
||||
TesterUtil.addRandomDomain(channels);
|
||||
for (int i = 0; i < channels.length; i++) {
|
||||
channels[i].start(Channel.SND_RX_SEQ|Channel.SND_TX_SEQ);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMessages(long delay, long sleep) throws Exception {
|
||||
resetMessageCounters();
|
||||
Member local = channels[0].getLocalMember(true);
|
||||
Member dest = channels[1].getLocalMember(true);
|
||||
int n = 3;
|
||||
log.info("Sending " + n + " messages from [" + local.getName()
|
||||
+ "] to [" + dest.getName() + "] with delay of " + delay
|
||||
+ " ms between them.");
|
||||
for (int i = 0; i < n; i++) {
|
||||
channels[0].send(new Member[] { dest }, new TestMsg(), 0);
|
||||
boolean last = (i == n - 1);
|
||||
if (!last && delay > 0) {
|
||||
Thread.sleep(delay);
|
||||
}
|
||||
}
|
||||
log.info("Messages sent. Waiting no more than " + (sleep / 1000)
|
||||
+ " seconds for them to be received");
|
||||
long startTime = System.currentTimeMillis();
|
||||
int countReceived;
|
||||
while ((countReceived = getReceivedMessageCount()) != n) {
|
||||
long time = System.currentTimeMillis();
|
||||
if ((time - startTime) > sleep) {
|
||||
Assert.fail("Only " + countReceived + " out of " + n
|
||||
+ " messages have been received in " + (sleep / 1000)
|
||||
+ " seconds");
|
||||
break;
|
||||
}
|
||||
Thread.sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectionLinger() throws Exception {
|
||||
sendMessages(0,15000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeepAliveCount() throws Exception {
|
||||
log.info("Setting keep alive count to 0");
|
||||
for (int i = 0; i < channels.length; i++) {
|
||||
ReplicationTransmitter t = (ReplicationTransmitter)channels[0].getChannelSender();
|
||||
t.getTransport().setKeepAliveCount(0);
|
||||
}
|
||||
sendMessages(1000,15000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeepAliveTime() throws Exception {
|
||||
log.info("Setting keep alive count to 1 second");
|
||||
for (int i = 0; i < channels.length; i++) {
|
||||
ReplicationTransmitter t = (ReplicationTransmitter)channels[0].getChannelSender();
|
||||
t.getTransport().setKeepAliveTime(1000);
|
||||
}
|
||||
sendMessages(2000,15000);
|
||||
}
|
||||
|
||||
@After
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
try {
|
||||
for (int i = 0; i < channels.length; i++) {
|
||||
channels[i].stop(Channel.DEFAULT);
|
||||
}
|
||||
} finally {
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
||||
|
||||
private void resetMessageCounters() {
|
||||
for (TestMsgListener listener: listeners) {
|
||||
listener.reset();
|
||||
}
|
||||
}
|
||||
|
||||
private int getReceivedMessageCount() {
|
||||
int count = 0;
|
||||
for (TestMsgListener listener: listeners) {
|
||||
count += listener.getReceivedCount();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// Test message. The message size is random.
|
||||
public static class TestMsg implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static Random r = new Random();
|
||||
private HashMap<Integer, ArrayList<Object>> map = new HashMap<>();
|
||||
public TestMsg() {
|
||||
int size = Math.abs(r.nextInt() % 200);
|
||||
for (int i=0; i<size; i++ ) {
|
||||
int length = Math.abs(r.nextInt() %65000);
|
||||
ArrayList<Object> list = new ArrayList<>(length);
|
||||
map.put(Integer.valueOf(i),list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TestMsgListener implements ChannelListener {
|
||||
private final String name;
|
||||
private final AtomicInteger counter = new AtomicInteger();
|
||||
public TestMsgListener(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
counter.set(0);
|
||||
}
|
||||
|
||||
public int getReceivedCount() {
|
||||
return counter.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageReceived(Serializable msg, Member sender) {
|
||||
counter.incrementAndGet();
|
||||
log.info("["+name+"] Received message:"+msg+" from " + sender.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Serializable msg, Member sender) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.group;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.transport.ReceiverBase;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
*/
|
||||
public class TestGroupChannelStartStop {
|
||||
private GroupChannel channel = null;
|
||||
private int udpPort = 45543;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
channel = new GroupChannel();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
try {
|
||||
channel.stop(Channel.DEFAULT);
|
||||
} catch (Exception ignore) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoubleFullStart() throws Exception {
|
||||
int count = 0;
|
||||
try {
|
||||
channel.start(Channel.DEFAULT);
|
||||
count++;
|
||||
} catch ( Exception x){x.printStackTrace();}
|
||||
try {
|
||||
channel.start(Channel.DEFAULT);
|
||||
count++;
|
||||
} catch ( Exception x){x.printStackTrace();}
|
||||
Assert.assertEquals(count,2);
|
||||
channel.stop(Channel.DEFAULT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScrap() throws Exception {
|
||||
System.out.println(channel.getChannelReceiver().getClass());
|
||||
((ReceiverBase)channel.getChannelReceiver()).setMaxThreads(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoublePartialStart() throws Exception {
|
||||
//try to double start the RX
|
||||
int count = 0;
|
||||
try {
|
||||
channel.start(Channel.SND_RX_SEQ);
|
||||
channel.start(Channel.MBR_RX_SEQ);
|
||||
count++;
|
||||
} catch ( Exception x){x.printStackTrace();}
|
||||
try {
|
||||
channel.start(Channel.MBR_RX_SEQ);
|
||||
count++;
|
||||
} catch ( Exception x){
|
||||
// expected
|
||||
}
|
||||
Assert.assertEquals(count,1);
|
||||
channel.stop(Channel.DEFAULT);
|
||||
//double the membership sender
|
||||
count = 0;
|
||||
try {
|
||||
channel.start(Channel.SND_RX_SEQ);
|
||||
channel.start(Channel.MBR_TX_SEQ);
|
||||
count++;
|
||||
} catch ( Exception x){x.printStackTrace();}
|
||||
try {
|
||||
channel.start(Channel.MBR_TX_SEQ);
|
||||
count++;
|
||||
} catch ( Exception x){
|
||||
// expected
|
||||
}
|
||||
Assert.assertEquals(count,1);
|
||||
channel.stop(Channel.DEFAULT);
|
||||
|
||||
count = 0;
|
||||
try {
|
||||
channel.start(Channel.SND_RX_SEQ);
|
||||
count++;
|
||||
} catch ( Exception x){x.printStackTrace();}
|
||||
try {
|
||||
channel.start(Channel.SND_RX_SEQ);
|
||||
count++;
|
||||
} catch ( Exception x){
|
||||
// expected
|
||||
}
|
||||
Assert.assertEquals(count,1);
|
||||
channel.stop(Channel.DEFAULT);
|
||||
|
||||
count = 0;
|
||||
try {
|
||||
channel.start(Channel.SND_TX_SEQ);
|
||||
count++;
|
||||
} catch ( Exception x){x.printStackTrace();}
|
||||
try {
|
||||
channel.start(Channel.SND_TX_SEQ);
|
||||
count++;
|
||||
} catch ( Exception x){
|
||||
// expected
|
||||
}
|
||||
Assert.assertEquals(count,1);
|
||||
channel.stop(Channel.DEFAULT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFalseOption() throws Exception {
|
||||
int flag = 0xFFF0;//should get ignored by the underlying components
|
||||
int count = 0;
|
||||
try {
|
||||
channel.start(flag);
|
||||
count++;
|
||||
} catch ( Exception x){x.printStackTrace();}
|
||||
try {
|
||||
channel.start(flag);
|
||||
count++;
|
||||
} catch ( Exception x){
|
||||
// expected
|
||||
}
|
||||
Assert.assertEquals(count,2);
|
||||
channel.stop(Channel.DEFAULT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUdpReceiverStart() throws Exception {
|
||||
ReceiverBase rb = (ReceiverBase)channel.getChannelReceiver();
|
||||
rb.setUdpPort(udpPort);
|
||||
channel.start(Channel.DEFAULT);
|
||||
Thread.sleep(1000);
|
||||
channel.stop(Channel.DEFAULT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.group.interceptors;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.ManagedChannel;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.MembershipListener;
|
||||
import org.apache.catalina.tribes.group.GroupChannel;
|
||||
import org.apache.catalina.tribes.util.UUIDGenerator;
|
||||
|
||||
public class TestDomainFilterInterceptor {
|
||||
private static int count = 10;
|
||||
private ManagedChannel[] channels = new ManagedChannel[count];
|
||||
private TestMbrListener[] listeners = new TestMbrListener[count];
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
for (int i = 0; i < channels.length; i++) {
|
||||
channels[i] = new GroupChannel();
|
||||
channels[i].getMembershipService().setPayload( ("Channel-" + (i + 1)).getBytes("ASCII"));
|
||||
listeners[i] = new TestMbrListener( ("Listener-" + (i + 1)));
|
||||
channels[i].addMembershipListener(listeners[i]);
|
||||
DomainFilterInterceptor filter = new DomainFilterInterceptor();
|
||||
filter.setDomain(UUIDGenerator.randomUUID(false));
|
||||
channels[i].addInterceptor(filter);
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
for (int i = 0; i < channels.length; i++) {
|
||||
listeners[i].members.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMemberArrival() throws Exception {
|
||||
//purpose of this test is to make sure that we have received all the members
|
||||
//that we can expect before the start method returns
|
||||
Thread[] threads = new Thread[channels.length];
|
||||
for (int i=0; i<channels.length; i++ ) {
|
||||
final Channel channel = channels[i];
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
channel.start(Channel.DEFAULT);
|
||||
}catch ( Exception x ) {
|
||||
throw new RuntimeException(x);
|
||||
}
|
||||
}
|
||||
};
|
||||
threads[i] = t;
|
||||
}
|
||||
for (int i=0; i<threads.length; i++ ) threads[i].start();
|
||||
for (int i=0; i<threads.length; i++ ) threads[i].join();
|
||||
System.out.println("All channels started.");
|
||||
for (int i=listeners.length-1; i>=0; i-- ) {
|
||||
Assert.assertEquals("Checking member arrival length",0,listeners[i].members.size());
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
|
||||
for (int i = 0; i < channels.length; i++) {
|
||||
try {
|
||||
channels[i].stop(Channel.DEFAULT);
|
||||
} catch (Exception ignore) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestMbrListener
|
||||
implements MembershipListener {
|
||||
public String name = null;
|
||||
public TestMbrListener(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public ArrayList<Member> members = new ArrayList<>();
|
||||
@Override
|
||||
public void memberAdded(Member member) {
|
||||
if (!members.contains(member)) {
|
||||
members.add(member);
|
||||
try {
|
||||
System.out.println(name + ":member added[" + new String(member.getPayload(), "ASCII") + "; Thread:"+Thread.currentThread().getName()+"]");
|
||||
} catch (Exception x) {
|
||||
System.out.println(name + ":member added[unknown]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void memberDisappeared(Member member) {
|
||||
if (members.contains(member)) {
|
||||
members.remove(member);
|
||||
try {
|
||||
System.out.println(name + ":member disappeared[" + new String(member.getPayload(), "ASCII") + "; Thread:"+Thread.currentThread().getName()+"]");
|
||||
} catch (Exception x) {
|
||||
System.out.println(name + ":member disappeared[unknown]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.group.interceptors;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestGzipInterceptor {
|
||||
|
||||
@Test
|
||||
public void testSmallerThanBufferSize() throws Exception {
|
||||
doCompressDecompress(GzipInterceptor.DEFAULT_BUFFER_SIZE / 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJustSmallerThanBufferSize() throws Exception {
|
||||
doCompressDecompress(GzipInterceptor.DEFAULT_BUFFER_SIZE -1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExactBufferSize() throws Exception {
|
||||
doCompressDecompress(GzipInterceptor.DEFAULT_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJustLargerThanBufferSize() throws Exception {
|
||||
doCompressDecompress(GzipInterceptor.DEFAULT_BUFFER_SIZE + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFactor2BufferSize() throws Exception {
|
||||
doCompressDecompress(GzipInterceptor.DEFAULT_BUFFER_SIZE * 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFactor4BufferSize() throws Exception {
|
||||
doCompressDecompress(GzipInterceptor.DEFAULT_BUFFER_SIZE * 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMuchLargerThanBufferSize() throws Exception {
|
||||
doCompressDecompress(GzipInterceptor.DEFAULT_BUFFER_SIZE * 10 + 1000);
|
||||
}
|
||||
|
||||
private void doCompressDecompress(int size) throws Exception {
|
||||
byte[] data = new byte[size];
|
||||
Arrays.fill(data, (byte)1);
|
||||
byte[] compress = GzipInterceptor.compress(data);
|
||||
byte[] result = GzipInterceptor.decompress(compress);
|
||||
Assert.assertTrue(Arrays.equals(data, result));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.group.interceptors;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.TesterUtil;
|
||||
import org.apache.catalina.tribes.group.GroupChannel;
|
||||
|
||||
public class TestNonBlockingCoordinator {
|
||||
|
||||
private static final int CHANNEL_COUNT = 10;
|
||||
|
||||
private GroupChannel[] channels = null;
|
||||
private NonBlockingCoordinator[] coordinators = null;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
System.out.println("Setup");
|
||||
channels = new GroupChannel[CHANNEL_COUNT];
|
||||
coordinators = new NonBlockingCoordinator[CHANNEL_COUNT];
|
||||
Thread[] threads = new Thread[CHANNEL_COUNT];
|
||||
for ( int i=0; i<CHANNEL_COUNT; i++ ) {
|
||||
channels[i] = new GroupChannel();
|
||||
coordinators[i] = new NonBlockingCoordinator();
|
||||
channels[i].addInterceptor(coordinators[i]);
|
||||
channels[i].addInterceptor(new TcpFailureDetector());
|
||||
final int j = i;
|
||||
threads[i] = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
channels[j].start(Channel.DEFAULT);
|
||||
Thread.sleep(50);
|
||||
} catch (Exception x) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
TesterUtil.addRandomDomain(channels);
|
||||
for (int i = 0; i < CHANNEL_COUNT; i++) {
|
||||
threads[i].start();
|
||||
}
|
||||
for (int i = 0; i < CHANNEL_COUNT; i++) {
|
||||
threads[i].join();
|
||||
}
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCoord1() throws Exception {
|
||||
int expectedCount = channels[0].getMembers().length;
|
||||
for (int i = 1; i < CHANNEL_COUNT; i++) {
|
||||
Assert.assertEquals("Message count expected to be equal.", expectedCount,
|
||||
channels[i].getMembers().length);
|
||||
}
|
||||
Member member = coordinators[0].getCoordinator();
|
||||
int cnt = 0;
|
||||
while (member == null && (cnt++ < 100)) {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
member = coordinators[0].getCoordinator();
|
||||
} catch (Exception x) {
|
||||
/* Ignore */
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < CHANNEL_COUNT; i++) {
|
||||
Assert.assertEquals(member, coordinators[i].getCoordinator());
|
||||
}
|
||||
System.out.println("Coordinator[1] is:" + member);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCoord2() throws Exception {
|
||||
Member member = coordinators[1].getCoordinator();
|
||||
System.out.println("Coordinator[2a] is:" + member);
|
||||
int index = -1;
|
||||
for ( int i=0; i<CHANNEL_COUNT; i++ ) {
|
||||
if ( channels[i].getLocalMember(false).equals(member) ) {
|
||||
System.out.println("Shutting down:" + channels[i].getLocalMember(true).toString());
|
||||
channels[i].stop(Channel.DEFAULT);
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
int dead = index;
|
||||
Thread.sleep(1000);
|
||||
if (index == 0) {
|
||||
index = 1;
|
||||
} else {
|
||||
index = 0;
|
||||
}
|
||||
System.out.println("Member count:"+channels[index].getMembers().length);
|
||||
member = coordinators[index].getCoordinator();
|
||||
for (int i = 1; i < CHANNEL_COUNT; i++) {
|
||||
if (i != dead) {
|
||||
Assert.assertEquals(member, coordinators[i].getCoordinator());
|
||||
}
|
||||
}
|
||||
System.out.println("Coordinator[2b] is:" + member);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
System.out.println("tearDown");
|
||||
for ( int i=0; i<CHANNEL_COUNT; i++ ) {
|
||||
channels[i].stop(Channel.DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.group.interceptors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.ChannelException;
|
||||
import org.apache.catalina.tribes.ChannelListener;
|
||||
import org.apache.catalina.tribes.ChannelMessage;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.TesterUtil;
|
||||
import org.apache.catalina.tribes.group.ChannelInterceptorBase;
|
||||
import org.apache.catalina.tribes.group.GroupChannel;
|
||||
import org.apache.catalina.tribes.group.InterceptorPayload;
|
||||
|
||||
public class TestOrderInterceptor {
|
||||
|
||||
GroupChannel[] channels = null;
|
||||
OrderInterceptor[] orderitcs = null;
|
||||
MangleOrderInterceptor[] mangleitcs = null;
|
||||
TestListener[] test = null;
|
||||
int channelCount = 2;
|
||||
Thread[] threads = null;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
System.out.println("Setup");
|
||||
channels = new GroupChannel[channelCount];
|
||||
orderitcs = new OrderInterceptor[channelCount];
|
||||
mangleitcs = new MangleOrderInterceptor[channelCount];
|
||||
test = new TestListener[channelCount];
|
||||
threads = new Thread[channelCount];
|
||||
for ( int i=0; i<channelCount; i++ ) {
|
||||
channels[i] = new GroupChannel();
|
||||
|
||||
orderitcs[i] = new OrderInterceptor();
|
||||
mangleitcs[i] = new MangleOrderInterceptor();
|
||||
orderitcs[i].setExpire(Long.MAX_VALUE);
|
||||
channels[i].addInterceptor(orderitcs[i]);
|
||||
channels[i].addInterceptor(mangleitcs[i]);
|
||||
test[i] = new TestListener(i);
|
||||
channels[i].addChannelListener(test[i]);
|
||||
final int j = i;
|
||||
threads[i] = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
channels[j].start(Channel.DEFAULT);
|
||||
Thread.sleep(50);
|
||||
} catch (Exception x) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
TesterUtil.addRandomDomain(channels);
|
||||
for ( int i=0; i<channelCount; i++ ) threads[i].start();
|
||||
for ( int i=0; i<channelCount; i++ ) threads[i].join();
|
||||
Thread.sleep(1500);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrder1() throws Exception {
|
||||
Member[] dest = channels[0].getMembers();
|
||||
final AtomicInteger value = new AtomicInteger(0);
|
||||
for ( int i=0; i<100; i++ ) {
|
||||
channels[0].send(dest,Integer.valueOf(value.getAndAdd(1)),0);
|
||||
}
|
||||
Thread.sleep(5000);
|
||||
for ( int i=0; i<test.length; i++ ) {
|
||||
Assert.assertFalse(test[i].fail);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrder2() throws Exception {
|
||||
final Member[] dest = channels[0].getMembers();
|
||||
final AtomicInteger value = new AtomicInteger(0);
|
||||
final Queue<Exception> exceptionQueue = new ConcurrentLinkedQueue<>();
|
||||
Runnable run = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
try {
|
||||
synchronized (channels[0]) {
|
||||
channels[0].send(dest, Integer.valueOf(value.getAndAdd(1)), 0);
|
||||
}
|
||||
}catch ( Exception x ) {
|
||||
exceptionQueue.add(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Thread[] threads = new Thread[5];
|
||||
for (int i=0;i<threads.length;i++) {
|
||||
threads[i] = new Thread(run);
|
||||
}
|
||||
for (int i=0;i<threads.length;i++) {
|
||||
threads[i].start();
|
||||
}
|
||||
for (int i=0;i<threads.length;i++) {
|
||||
threads[i].join();
|
||||
}
|
||||
if (!exceptionQueue.isEmpty()) {
|
||||
Assert.fail("Exception while sending in threads: "
|
||||
+ exceptionQueue.remove().toString());
|
||||
}
|
||||
Thread.sleep(5000);
|
||||
for ( int i=0; i<test.length; i++ ) {
|
||||
Assert.assertFalse(test[i].fail);
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
System.out.println("tearDown");
|
||||
for ( int i=0; i<channelCount; i++ ) {
|
||||
channels[i].stop(Channel.DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
org.junit.runner.JUnitCore.main(TestOrderInterceptor.class.getName());
|
||||
}
|
||||
|
||||
public static class TestListener implements ChannelListener {
|
||||
int id = -1;
|
||||
public TestListener(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
int cnt = 0;
|
||||
int total = 0;
|
||||
volatile boolean fail = false;
|
||||
@Override
|
||||
public synchronized void messageReceived(Serializable msg, Member sender) {
|
||||
total++;
|
||||
Integer i = (Integer)msg;
|
||||
if ( i.intValue() != cnt ) fail = true;
|
||||
else cnt++;
|
||||
System.out.println("Listener["+id+"] Message received:"+i+" Count:"+total+" Fail:"+fail);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Serializable msg, Member sender) {
|
||||
return (msg instanceof Integer);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MangleOrderInterceptor extends ChannelInterceptorBase {
|
||||
ChannelMessage hold = null;
|
||||
Member[] dest = null;
|
||||
@Override
|
||||
public synchronized void sendMessage(Member[] destination, ChannelMessage msg, InterceptorPayload payload) throws ChannelException {
|
||||
if ( hold == null ) {
|
||||
//System.out.println("Skipping message:"+msg);
|
||||
hold = (ChannelMessage)msg.deepclone();
|
||||
dest = new Member[destination.length];
|
||||
System.arraycopy(destination,0,dest,0,dest.length);
|
||||
} else {
|
||||
//System.out.println("Sending message:"+msg);
|
||||
super.sendMessage(destination,msg,payload);
|
||||
//System.out.println("Sending message:"+hold);
|
||||
super.sendMessage(dest,hold,null);
|
||||
hold = null;
|
||||
dest = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.group.interceptors;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.tribes.ByteMessage;
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.ChannelException;
|
||||
import org.apache.catalina.tribes.ManagedChannel;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.MembershipListener;
|
||||
import org.apache.catalina.tribes.TesterUtil;
|
||||
import org.apache.catalina.tribes.group.GroupChannel;
|
||||
|
||||
public class TestTcpFailureDetector {
|
||||
private TcpFailureDetector tcpFailureDetector1 = null;
|
||||
private TcpFailureDetector tcpFailureDetector2 = null;
|
||||
private ManagedChannel channel1 = null;
|
||||
private ManagedChannel channel2 = null;
|
||||
private TestMbrListener mbrlist1 = null;
|
||||
private TestMbrListener mbrlist2 = null;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
channel1 = new GroupChannel();
|
||||
channel2 = new GroupChannel();
|
||||
channel1.getMembershipService().setPayload("Channel-1".getBytes("ASCII"));
|
||||
channel2.getMembershipService().setPayload("Channel-2".getBytes("ASCII"));
|
||||
mbrlist1 = new TestMbrListener("Channel-1");
|
||||
mbrlist2 = new TestMbrListener("Channel-2");
|
||||
tcpFailureDetector1 = new TcpFailureDetector();
|
||||
tcpFailureDetector2 = new TcpFailureDetector();
|
||||
channel1.addInterceptor(tcpFailureDetector1);
|
||||
channel2.addInterceptor(tcpFailureDetector2);
|
||||
channel1.addMembershipListener(mbrlist1);
|
||||
channel2.addMembershipListener(mbrlist2);
|
||||
TesterUtil.addRandomDomain(new ManagedChannel[] {channel1, channel2});
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
mbrlist1.members.clear();
|
||||
mbrlist2.members.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTcpSendFailureMemberDrop() throws Exception {
|
||||
System.out.println("testTcpSendFailureMemberDrop()");
|
||||
clear();
|
||||
channel1.start(Channel.DEFAULT);
|
||||
channel2.start(Channel.DEFAULT);
|
||||
//Thread.sleep(1000);
|
||||
Assert.assertEquals("Expecting member count to be equal",mbrlist1.members.size(),mbrlist2.members.size());
|
||||
channel2.stop(Channel.SND_RX_SEQ);
|
||||
ByteMessage msg = new ByteMessage(new byte[1024]);
|
||||
try {
|
||||
channel1.send(channel1.getMembers(), msg, 0);
|
||||
Assert.fail("Message send should have failed.");
|
||||
} catch ( ChannelException x ) {
|
||||
// Ignore
|
||||
}
|
||||
Assert.assertEquals("Expecting member count to not be equal",mbrlist1.members.size()+1,mbrlist2.members.size());
|
||||
channel1.stop(Channel.DEFAULT);
|
||||
channel2.stop(Channel.DEFAULT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTcpFailureMemberAdd() throws Exception {
|
||||
System.out.println("testTcpFailureMemberAdd()");
|
||||
clear();
|
||||
channel1.start(Channel.DEFAULT);
|
||||
channel2.start(Channel.SND_RX_SEQ);
|
||||
channel2.start(Channel.SND_TX_SEQ);
|
||||
channel2.start(Channel.MBR_RX_SEQ);
|
||||
channel2.stop(Channel.SND_RX_SEQ);
|
||||
channel2.start(Channel.MBR_TX_SEQ);
|
||||
//Thread.sleep(1000);
|
||||
Assert.assertEquals("Expecting member count to not be equal",mbrlist1.members.size()+1,mbrlist2.members.size());
|
||||
channel1.stop(Channel.DEFAULT);
|
||||
channel2.stop(Channel.DEFAULT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTcpMcastFail() throws Exception {
|
||||
System.out.println("testTcpMcastFail()");
|
||||
clear();
|
||||
channel1.start(Channel.DEFAULT);
|
||||
channel2.start(Channel.DEFAULT);
|
||||
//Thread.sleep(1000);
|
||||
Assert.assertEquals("Expecting member count to be equal",mbrlist1.members.size(),mbrlist2.members.size());
|
||||
channel2.stop(Channel.MBR_TX_SEQ);
|
||||
ByteMessage msg = new ByteMessage(new byte[1024]);
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
Assert.assertEquals("Expecting member count to be equal",mbrlist1.members.size(),mbrlist2.members.size());
|
||||
channel1.send(channel1.getMembers(), msg, 0);
|
||||
} catch ( ChannelException x ) {
|
||||
Assert.fail("Message send should have succeeded.");
|
||||
}
|
||||
channel1.stop(Channel.DEFAULT);
|
||||
channel2.stop(Channel.DEFAULT);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
tcpFailureDetector1 = null;
|
||||
tcpFailureDetector2 = null;
|
||||
try {
|
||||
channel1.stop(Channel.DEFAULT);
|
||||
} catch (Exception ignore) {
|
||||
// Ignore
|
||||
}
|
||||
channel1 = null;
|
||||
try {
|
||||
channel2.stop(Channel.DEFAULT);
|
||||
} catch (Exception ignore) {
|
||||
// Ignore
|
||||
}
|
||||
channel2 = null;
|
||||
}
|
||||
|
||||
public static class TestMbrListener implements MembershipListener {
|
||||
public String name = null;
|
||||
public TestMbrListener(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public ArrayList<Member> members = new ArrayList<>();
|
||||
@Override
|
||||
public void memberAdded(Member member) {
|
||||
if ( !members.contains(member) ) {
|
||||
members.add(member);
|
||||
try{
|
||||
System.out.println(name + ":member added[" + new String(member.getPayload(), "ASCII") + "]");
|
||||
}catch ( Exception x ) {
|
||||
System.out.println(name + ":member added[unknown]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void memberDisappeared(Member member) {
|
||||
if ( members.contains(member) ) {
|
||||
members.remove(member);
|
||||
try{
|
||||
System.out.println(name + ":member disappeared[" + new String(member.getPayload(), "ASCII") + "]");
|
||||
}catch ( Exception x ) {
|
||||
System.out.println(name + ":member disappeared[unknown]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
38
test/org/apache/catalina/tribes/io/TestXByteBuffer.java
Normal file
38
test/org/apache/catalina/tribes/io/TestXByteBuffer.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.io;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestXByteBuffer {
|
||||
|
||||
@Test
|
||||
public void testEmptyArray() throws Exception {
|
||||
Object obj = XByteBuffer.deserialize(new byte[0]);
|
||||
Assert.assertNull(obj);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializationString() throws Exception {
|
||||
String test = "This is as test.";
|
||||
byte[] msg = XByteBuffer.serialize(test);
|
||||
Object obj = XByteBuffer.deserialize(msg);
|
||||
Assert.assertTrue(obj instanceof String);
|
||||
Assert.assertEquals(test, obj);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.membership;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.tribes.Member;
|
||||
|
||||
public class TestMemberImplSerialization {
|
||||
private MemberImpl m1, m2, p1,p2;
|
||||
private byte[] payload = null;
|
||||
private int udpPort = 3445;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
payload = new byte[333];
|
||||
Arrays.fill(payload,(byte)1);
|
||||
m1 = new MemberImpl("localhost",3333,1,payload);
|
||||
m2 = new MemberImpl("localhost",3333,1);
|
||||
payload = new byte[333];
|
||||
Arrays.fill(payload,(byte)2);
|
||||
p1 = new MemberImpl("127.0.0.1",3333,1,payload);
|
||||
p2 = new MemberImpl("localhost",3331,1,payload);
|
||||
m1.setDomain(new byte[] {1,2,3,4,5,6,7,8,9});
|
||||
m2.setDomain(new byte[] {1,2,3,4,5,6,7,8,9});
|
||||
m1.setCommand(new byte[] {1,2,4,5,6,7,8,9});
|
||||
m2.setCommand(new byte[] {1,2,4,5,6,7,8,9});
|
||||
m1.setUdpPort(udpPort);
|
||||
m2.setUdpPort(m1.getUdpPort());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompare() throws Exception {
|
||||
Assert.assertTrue(m1.equals(m2));
|
||||
Assert.assertTrue(m2.equals(m1));
|
||||
Assert.assertTrue(p1.equals(m2));
|
||||
Assert.assertFalse(m1.equals(p2));
|
||||
Assert.assertFalse(m1.equals(p2));
|
||||
Assert.assertFalse(m2.equals(p2));
|
||||
Assert.assertFalse(p1.equals(p2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUdpPort() throws Exception {
|
||||
byte[] md1 = m1.getData();
|
||||
byte[] md2 = m2.getData();
|
||||
|
||||
Member a1 = MemberImpl.getMember(md1);
|
||||
Member a2 = MemberImpl.getMember(md2);
|
||||
|
||||
Assert.assertTrue(a1.getUdpPort()==a2.getUdpPort());
|
||||
Assert.assertTrue(a1.getUdpPort()==udpPort);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializationOne() throws Exception {
|
||||
Member m = m1;
|
||||
byte[] md1 = m.getData(false,true);
|
||||
byte[] mda1 = m.getData(false,false);
|
||||
Assert.assertTrue(Arrays.equals(md1,mda1));
|
||||
Assert.assertTrue(md1==mda1);
|
||||
mda1 = m.getData(true,true);
|
||||
Member ma1 = MemberImpl.getMember(mda1);
|
||||
Assert.assertTrue(compareMembers(m,ma1));
|
||||
mda1 = p1.getData(false);
|
||||
Assert.assertFalse(Arrays.equals(md1,mda1));
|
||||
ma1 = MemberImpl.getMember(mda1);
|
||||
Assert.assertTrue(compareMembers(p1,ma1));
|
||||
|
||||
md1 = m.getData(true,true);
|
||||
Thread.sleep(50);
|
||||
mda1 = m.getData(true,true);
|
||||
Member a1 = MemberImpl.getMember(md1);
|
||||
Member a2 = MemberImpl.getMember(mda1);
|
||||
Assert.assertTrue(a1.equals(a2));
|
||||
Assert.assertFalse(Arrays.equals(md1,mda1));
|
||||
|
||||
|
||||
}
|
||||
|
||||
public boolean compareMembers(Member impl1, Member impl2) {
|
||||
boolean result = true;
|
||||
result = result && Arrays.equals(impl1.getHost(),impl2.getHost());
|
||||
result = result && Arrays.equals(impl1.getPayload(),impl2.getPayload());
|
||||
result = result && Arrays.equals(impl1.getUniqueId(),impl2.getUniqueId());
|
||||
result = result && impl1.getPort() == impl2.getPort();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
110
test/org/apache/catalina/tribes/test/NioSenderTest.java
Normal file
110
test/org/apache/catalina/tribes/test/NioSenderTest.java
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.test;
|
||||
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.io.ChannelData;
|
||||
import org.apache.catalina.tribes.io.XByteBuffer;
|
||||
import org.apache.catalina.tribes.membership.MemberImpl;
|
||||
import org.apache.catalina.tribes.transport.nio.NioSender;
|
||||
|
||||
public class NioSenderTest {
|
||||
private Selector selector = null;
|
||||
private int counter = 0;
|
||||
Member mbr;
|
||||
private static int testOptions = Channel.SEND_OPTIONS_DEFAULT;
|
||||
public NioSenderTest() {
|
||||
// Default constructor
|
||||
}
|
||||
|
||||
public synchronized int inc() {
|
||||
return ++counter;
|
||||
}
|
||||
|
||||
public synchronized ChannelData getMessage(Member mbr) {
|
||||
String msg = "Thread-"+Thread.currentThread().getName()+" Message:"+inc();
|
||||
ChannelData data = new ChannelData(true);
|
||||
data.setMessage(new XByteBuffer(msg.getBytes(),false));
|
||||
data.setAddress(mbr);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public void init() throws Exception {
|
||||
selector = Selector.open();
|
||||
mbr = new MemberImpl("localhost",4444,0);
|
||||
NioSender sender = new NioSender();
|
||||
sender.setDestination(mbr);
|
||||
sender.setDirectBuffer(true);
|
||||
sender.setSelector(selector);
|
||||
sender.setMessage(XByteBuffer.createDataPackage(getMessage(mbr)));
|
||||
sender.connect();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (true) {
|
||||
|
||||
int selectedKeys = 0;
|
||||
try {
|
||||
selectedKeys = selector.select(100);
|
||||
// if ( selectedKeys == 0 ) {
|
||||
// System.out.println("No registered interests. Sleeping for a second.");
|
||||
// Thread.sleep(100);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (selectedKeys == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Iterator<SelectionKey> it = selector.selectedKeys().iterator();
|
||||
while (it.hasNext()) {
|
||||
SelectionKey sk = it.next();
|
||||
it.remove();
|
||||
try {
|
||||
int readyOps = sk.readyOps();
|
||||
sk.interestOps(sk.interestOps() & ~readyOps);
|
||||
NioSender sender = (NioSender) sk.attachment();
|
||||
if ( sender.process(sk, (testOptions&Channel.SEND_OPTIONS_USE_ACK)==Channel.SEND_OPTIONS_USE_ACK) ) {
|
||||
System.out.println("Message completed for handler:"+sender);
|
||||
Thread.sleep(2000);
|
||||
sender.reset();
|
||||
sender.setMessage(XByteBuffer.createDataPackage(getMessage(mbr)));
|
||||
}
|
||||
|
||||
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
NioSenderTest sender = new NioSenderTest();
|
||||
sender.init();
|
||||
sender.run();
|
||||
}
|
||||
}
|
||||
53
test/org/apache/catalina/tribes/test/TribesTestSuite.java
Normal file
53
test/org/apache/catalina/tribes/test/TribesTestSuite.java
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.test;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
|
||||
import org.apache.catalina.tribes.group.TestGroupChannelMemberArrival;
|
||||
import org.apache.catalina.tribes.group.TestGroupChannelOptionFlag;
|
||||
import org.apache.catalina.tribes.group.TestGroupChannelSenderConnections;
|
||||
import org.apache.catalina.tribes.group.TestGroupChannelStartStop;
|
||||
import org.apache.catalina.tribes.group.interceptors.TestDomainFilterInterceptor;
|
||||
import org.apache.catalina.tribes.group.interceptors.TestNonBlockingCoordinator;
|
||||
import org.apache.catalina.tribes.group.interceptors.TestOrderInterceptor;
|
||||
import org.apache.catalina.tribes.group.interceptors.TestTcpFailureDetector;
|
||||
import org.apache.catalina.tribes.io.TestXByteBuffer;
|
||||
import org.apache.catalina.tribes.membership.TestMemberImplSerialization;
|
||||
import org.apache.catalina.tribes.test.channel.TestDataIntegrity;
|
||||
import org.apache.catalina.tribes.test.channel.TestMulticastPackages;
|
||||
import org.apache.catalina.tribes.test.channel.TestRemoteProcessException;
|
||||
import org.apache.catalina.tribes.test.channel.TestUdpPackages;
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses({
|
||||
// o.a.catalina.tribes.test.channel
|
||||
TestGroupChannelStartStop.class, TestGroupChannelOptionFlag.class,
|
||||
TestDataIntegrity.class, TestMulticastPackages.class,
|
||||
TestRemoteProcessException.class, TestUdpPackages.class,
|
||||
// o.a.catalina.tribes.test.interceptors
|
||||
TestNonBlockingCoordinator.class, TestOrderInterceptor.class,
|
||||
// o.a.catalina.tribes.test.io
|
||||
TestGroupChannelSenderConnections.class, TestXByteBuffer.class,
|
||||
// o.a.catalina.tribes.test.membership
|
||||
TestMemberImplSerialization.class, TestDomainFilterInterceptor.class,
|
||||
TestGroupChannelMemberArrival.class, TestTcpFailureDetector.class })
|
||||
public class TribesTestSuite {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.test.channel;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.ChannelListener;
|
||||
import org.apache.catalina.tribes.ManagedChannel;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.TesterUtil;
|
||||
import org.apache.catalina.tribes.group.GroupChannel;
|
||||
import org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor;
|
||||
|
||||
public class TestDataIntegrity {
|
||||
private int msgCount = 500;
|
||||
private int threadCount = 20;
|
||||
private GroupChannel channel1;
|
||||
private GroupChannel channel2;
|
||||
private Listener listener1;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
channel1 = new GroupChannel();
|
||||
channel1.addInterceptor(new MessageDispatchInterceptor());
|
||||
channel2 = new GroupChannel();
|
||||
channel2.addInterceptor(new MessageDispatchInterceptor());
|
||||
listener1 = new Listener();
|
||||
channel2.addChannelListener(listener1);
|
||||
TesterUtil.addRandomDomain(new ManagedChannel[] {channel1, channel2});
|
||||
channel1.start(Channel.DEFAULT);
|
||||
channel2.start(Channel.DEFAULT);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
channel1.stop(Channel.DEFAULT);
|
||||
channel2.stop(Channel.DEFAULT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSendNO_ACK() throws Exception {
|
||||
System.err.println("Starting NO_ACK");
|
||||
Thread[] threads = new Thread[threadCount];
|
||||
for (int x=0; x<threads.length; x++ ) {
|
||||
threads[x] = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
long start = System.currentTimeMillis();
|
||||
for (int i = 0; i < msgCount; i++) channel1.send(new Member[] {channel2.getLocalMember(false)}, Data.createRandomData(),0);
|
||||
System.out.println("Thread["+this.getName()+"] sent "+msgCount+" messages in "+(System.currentTimeMillis()-start)+" ms.");
|
||||
}catch ( Exception x ) {
|
||||
x.printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
for (int x=0; x<threads.length; x++ ) { threads[x].start();}
|
||||
for (int x=0; x<threads.length; x++ ) { threads[x].join();}
|
||||
//sleep for 50 sec, let the other messages in
|
||||
long start = System.currentTimeMillis();
|
||||
while ( (System.currentTimeMillis()-start)<15000 && msgCount*threadCount!=listener1.count) Thread.sleep(500);
|
||||
System.err.println("Finished NO_ACK ["+listener1.count+"]");
|
||||
Assert.assertEquals("Checking success messages.",msgCount*threadCount,listener1.count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSendASYNCM() throws Exception {
|
||||
System.err.println("Starting ASYNC MULTI THREAD");
|
||||
Thread[] threads = new Thread[threadCount];
|
||||
for (int x=0; x<threads.length; x++ ) {
|
||||
threads[x] = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
long start = System.currentTimeMillis();
|
||||
for (int i = 0; i < msgCount; i++) channel1.send(new Member[] {channel2.getLocalMember(false)}, Data.createRandomData(),Channel.SEND_OPTIONS_ASYNCHRONOUS);
|
||||
System.out.println("Thread["+this.getName()+"] sent "+msgCount+" messages in "+(System.currentTimeMillis()-start)+" ms.");
|
||||
}catch ( Exception x ) {
|
||||
x.printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
for (int x=0; x<threads.length; x++ ) { threads[x].start();}
|
||||
for (int x=0; x<threads.length; x++ ) { threads[x].join();}
|
||||
//sleep for 50 sec, let the other messages in
|
||||
long start = System.currentTimeMillis();
|
||||
while ( (System.currentTimeMillis()-start)<25000 && msgCount*threadCount!=listener1.count) Thread.sleep(500);
|
||||
System.err.println("Finished ASYNC MULTI THREAD ["+listener1.count+"]");
|
||||
Assert.assertEquals("Checking success messages.",msgCount*threadCount,listener1.count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSendASYNC() throws Exception {
|
||||
System.err.println("Starting ASYNC");
|
||||
for (int i=0; i<msgCount; i++) channel1.send(new Member[] {channel2.getLocalMember(false)},Data.createRandomData(),Channel.SEND_OPTIONS_ASYNCHRONOUS);
|
||||
//sleep for 50 sec, let the other messages in
|
||||
long start = System.currentTimeMillis();
|
||||
while ( (System.currentTimeMillis()-start)<5000 && msgCount!=listener1.count) Thread.sleep(500);
|
||||
System.err.println("Finished ASYNC");
|
||||
Assert.assertEquals("Checking success messages.",msgCount,listener1.count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSendACK() throws Exception {
|
||||
System.err.println("Starting ACK");
|
||||
for (int i=0; i<msgCount; i++) channel1.send(new Member[] {channel2.getLocalMember(false)},Data.createRandomData(),Channel.SEND_OPTIONS_USE_ACK);
|
||||
Thread.sleep(250);
|
||||
System.err.println("Finished ACK");
|
||||
Assert.assertEquals("Checking success messages.",msgCount,listener1.count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSendSYNCACK() throws Exception {
|
||||
System.err.println("Starting SYNC_ACK");
|
||||
for (int i=0; i<msgCount; i++) channel1.send(new Member[] {channel2.getLocalMember(false)},Data.createRandomData(),Channel.SEND_OPTIONS_SYNCHRONIZED_ACK|Channel.SEND_OPTIONS_USE_ACK);
|
||||
Thread.sleep(250);
|
||||
System.err.println("Finished SYNC_ACK");
|
||||
Assert.assertEquals("Checking success messages.",msgCount,listener1.count);
|
||||
}
|
||||
|
||||
public static class Listener implements ChannelListener {
|
||||
long count = 0;
|
||||
@Override
|
||||
public boolean accept(Serializable s, Member m) {
|
||||
return (s instanceof Data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageReceived(Serializable s, Member m) {
|
||||
Data d = (Data)s;
|
||||
if ( !Data.verify(d) ) {
|
||||
System.err.println("ERROR");
|
||||
} else {
|
||||
count++;
|
||||
if ((count %1000) ==0 ) {
|
||||
System.err.println("SUCCESS:"+count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Data implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
public int length;
|
||||
public byte[] data;
|
||||
public byte key;
|
||||
public static final Random r = new Random();
|
||||
public static Data createRandomData() {
|
||||
int i = r.nextInt();
|
||||
i = ( i % 127 );
|
||||
int length = Math.abs(r.nextInt() % 65555);
|
||||
Data d = new Data();
|
||||
d.length = length;
|
||||
d.key = (byte)i;
|
||||
d.data = new byte[length];
|
||||
Arrays.fill(d.data,d.key);
|
||||
return d;
|
||||
}
|
||||
|
||||
public static boolean verify(Data d) {
|
||||
boolean result = (d.length == d.data.length);
|
||||
for ( int i=0; result && (i<d.data.length); i++ ) result = result && d.data[i] == d.key;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.test.channel;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.ChannelListener;
|
||||
import org.apache.catalina.tribes.ChannelReceiver;
|
||||
import org.apache.catalina.tribes.ManagedChannel;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.TesterUtil;
|
||||
import org.apache.catalina.tribes.group.GroupChannel;
|
||||
import org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor;
|
||||
import org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor;
|
||||
import org.apache.catalina.tribes.io.XByteBuffer;
|
||||
import org.apache.catalina.tribes.transport.AbstractSender;
|
||||
import org.apache.catalina.tribes.transport.ReceiverBase;
|
||||
import org.apache.catalina.tribes.transport.ReplicationTransmitter;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class TestMulticastPackages {
|
||||
private int msgCount = 500;
|
||||
private int threadCount = 20;
|
||||
private GroupChannel channel1;
|
||||
private GroupChannel channel2;
|
||||
private Listener listener1;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
channel1 = new GroupChannel();
|
||||
channel1.addInterceptor(new MessageDispatchInterceptor());
|
||||
channel2 = new GroupChannel();
|
||||
channel2.addInterceptor(new MessageDispatchInterceptor());
|
||||
ThroughputInterceptor tint = new ThroughputInterceptor();
|
||||
tint.setInterval(500);
|
||||
ThroughputInterceptor tint2 = new ThroughputInterceptor();
|
||||
tint2.setInterval(500);
|
||||
//channel1.addInterceptor(tint);
|
||||
channel2.addInterceptor(tint2);
|
||||
listener1 = new Listener();
|
||||
ReceiverBase rb1 = (ReceiverBase)channel1.getChannelReceiver();
|
||||
ReceiverBase rb2 = (ReceiverBase)channel2.getChannelReceiver();
|
||||
rb1.setUdpPort(50000);
|
||||
rb2.setUdpPort(50000);
|
||||
channel2.addChannelListener(listener1);
|
||||
TesterUtil.addRandomDomain(new ManagedChannel[] {channel1, channel2});
|
||||
channel1.start(Channel.DEFAULT);
|
||||
channel2.start(Channel.DEFAULT);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
channel1.stop(Channel.DEFAULT);
|
||||
channel2.stop(Channel.DEFAULT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleDataSendNO_ACK() throws Exception {
|
||||
AbstractSender s1 =(AbstractSender) ((ReplicationTransmitter)channel1.getChannelSender()).getTransport();
|
||||
AbstractSender s2 =(AbstractSender) ((ReplicationTransmitter)channel2.getChannelSender()).getTransport();
|
||||
s1.setTimeout(Long.MAX_VALUE); //for debugging
|
||||
s2.setTimeout(Long.MAX_VALUE); //for debugging
|
||||
|
||||
System.err.println("Starting Single package NO_ACK");
|
||||
channel1.send(new Member[] {channel2.getLocalMember(false)}, Data.createRandomData(1024),Channel.SEND_OPTIONS_MULTICAST);
|
||||
Thread.sleep(500);
|
||||
System.err.println("Finished Single package NO_ACK ["+listener1.count+"]");
|
||||
Assert.assertEquals("Checking success messages.",1,listener1.count.get());
|
||||
}
|
||||
|
||||
|
||||
public static void printMissingMsgs(int[] msgs, int maxIdx) {
|
||||
for (int i=0; i<maxIdx && i<msgs.length; i++) {
|
||||
if (msgs[i]==0) System.out.print(i+", ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSendASYNCM() throws Exception {
|
||||
final AtomicInteger counter = new AtomicInteger(0);
|
||||
ReceiverBase rb1 = (ReceiverBase)channel1.getChannelReceiver();
|
||||
ReceiverBase rb2 = (ReceiverBase)channel2.getChannelReceiver();
|
||||
rb1.setUdpRxBufSize(1024*1024*10);
|
||||
rb2.setUdpRxBufSize(1024*1024*10);
|
||||
rb1.setUdpTxBufSize(1024*1024*10);
|
||||
rb2.setUdpTxBufSize(1024*1024*10);
|
||||
System.err.println("Starting NO_ACK");
|
||||
Thread[] threads = new Thread[threadCount];
|
||||
for (int x=0; x<threads.length; x++ ) {
|
||||
threads[x] = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
long start = System.currentTimeMillis();
|
||||
for (int i = 0; i < msgCount; i++) {
|
||||
int cnt = counter.getAndAdd(1);
|
||||
channel1.send(new Member[] {channel2.getLocalMember(false)}, Data.createRandomData(1024,cnt),Channel.SEND_OPTIONS_MULTICAST|Channel.SEND_OPTIONS_ASYNCHRONOUS);
|
||||
//Thread.currentThread().sleep(10);
|
||||
}
|
||||
System.out.println("Thread["+this.getName()+"] sent "+msgCount+" messages in "+(System.currentTimeMillis()-start)+" ms.");
|
||||
}catch ( Exception x ) {
|
||||
x.printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
for (int x=0; x<threads.length; x++ ) { threads[x].start();}
|
||||
for (int x=0; x<threads.length; x++ ) { threads[x].join();}
|
||||
//sleep for 50 sec, let the other messages in
|
||||
long start = System.currentTimeMillis();
|
||||
while ( (System.currentTimeMillis()-start)<25000 && msgCount*threadCount!=listener1.count.get()) Thread.sleep(500);
|
||||
System.err.println("Finished NO_ACK ["+listener1.count+"]");
|
||||
System.out.println("Sent "+counter.get()+ " messages. Received "+listener1.count+" Highest msg received:"+listener1.maxIdx);
|
||||
System.out.print("Missing messages:");
|
||||
printMissingMsgs(listener1.nrs,counter.get());
|
||||
Assert.assertEquals("Checking success messages.",msgCount*threadCount,listener1.count.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSendASYNC() throws Exception {
|
||||
System.err.println("Starting ASYNC");
|
||||
for (int i=0; i<msgCount; i++) channel1.send(new Member[] {channel2.getLocalMember(false)},Data.createRandomData(1024),Channel.SEND_OPTIONS_ASYNCHRONOUS|Channel.SEND_OPTIONS_MULTICAST);
|
||||
//sleep for 50 sec, let the other messages in
|
||||
long start = System.currentTimeMillis();
|
||||
while ( (System.currentTimeMillis()-start)<5000 && msgCount!=listener1.count.get()) Thread.sleep(500);
|
||||
System.err.println("Finished ASYNC");
|
||||
Assert.assertEquals("Checking success messages.",msgCount,listener1.count.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSendACK() throws Exception {
|
||||
System.err.println("Starting ACK");
|
||||
for (int i=0; i<msgCount; i++) channel1.send(new Member[] {channel2.getLocalMember(false)},Data.createRandomData(1024),Channel.SEND_OPTIONS_USE_ACK|Channel.SEND_OPTIONS_MULTICAST);
|
||||
Thread.sleep(250);
|
||||
System.err.println("Finished ACK");
|
||||
Assert.assertEquals("Checking success messages.",msgCount,listener1.count.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSendSYNCACK() throws Exception {
|
||||
System.err.println("Starting SYNC_ACK");
|
||||
for (int i=0; i<msgCount; i++) channel1.send(new Member[] {channel2.getLocalMember(false)},Data.createRandomData(1024),Channel.SEND_OPTIONS_SYNCHRONIZED_ACK|Channel.SEND_OPTIONS_USE_ACK|Channel.SEND_OPTIONS_MULTICAST);
|
||||
Thread.sleep(250);
|
||||
System.err.println("Finished SYNC_ACK");
|
||||
Assert.assertEquals("Checking success messages.",msgCount,listener1.count.get());
|
||||
}
|
||||
|
||||
public static class Listener implements ChannelListener {
|
||||
AtomicLong count = new AtomicLong(0);
|
||||
int maxIdx = -1;
|
||||
int[] nrs = new int[1000000];
|
||||
public Listener() {
|
||||
Arrays.fill(nrs, 0);
|
||||
}
|
||||
@Override
|
||||
public boolean accept(Serializable s, Member m) {
|
||||
return (s instanceof Data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageReceived(Serializable s, Member m) {
|
||||
try {
|
||||
Data d = (Data)s;
|
||||
if ( !Data.verify(d) ) {
|
||||
System.err.println("ERROR - Unable to verify data package");
|
||||
} else {
|
||||
long c = count.addAndGet(1);
|
||||
if ((c%1000) ==0 ) {
|
||||
System.err.println("SUCCESS:"+c);
|
||||
}
|
||||
int nr = d.getNumber();
|
||||
if (nr>=0 && nr<nrs.length) {
|
||||
maxIdx = Math.max(maxIdx, nr);
|
||||
nrs[nr] = 1;
|
||||
}
|
||||
}
|
||||
}catch (Exception x ) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Data implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
public int length;
|
||||
public byte[] data;
|
||||
public byte key;
|
||||
public boolean hasNr = false;
|
||||
public static final Random r = new Random();
|
||||
public static Data createRandomData() {
|
||||
return createRandomData(ChannelReceiver.MAX_UDP_SIZE);
|
||||
}
|
||||
public static Data createRandomData(int size) {
|
||||
return createRandomData(size,-1);
|
||||
}
|
||||
|
||||
public static Data createRandomData(int size, int number) {
|
||||
int i = r.nextInt();
|
||||
i = ( i % 127 );
|
||||
int length = Math.abs(r.nextInt() % size);
|
||||
if (length<100) length += 100;
|
||||
Data d = new Data();
|
||||
d.length = length;
|
||||
d.key = (byte)i;
|
||||
d.data = new byte[length];
|
||||
Arrays.fill(d.data,d.key);
|
||||
if (number>0 && d.data.length>=4) {
|
||||
//populate number
|
||||
d.hasNr = true;
|
||||
XByteBuffer.toBytes(number,d.data, 0);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
public int getNumber() {
|
||||
if (!hasNr) return -1;
|
||||
return XByteBuffer.toInt(this.data, 0);
|
||||
}
|
||||
|
||||
public static boolean verify(Data d) {
|
||||
boolean result = (d.length == d.data.length);
|
||||
for ( int i=(d.hasNr?4:0); result && (i<d.data.length); i++ ) result = result && d.data[i] == d.key;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.test.channel;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.ChannelException;
|
||||
import org.apache.catalina.tribes.ChannelListener;
|
||||
import org.apache.catalina.tribes.ManagedChannel;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.TesterUtil;
|
||||
import org.apache.catalina.tribes.group.GroupChannel;
|
||||
|
||||
public class TestRemoteProcessException {
|
||||
private int msgCount = 10000;
|
||||
private GroupChannel channel1;
|
||||
private GroupChannel channel2;
|
||||
private Listener listener1;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
channel1 = new GroupChannel();
|
||||
channel2 = new GroupChannel();
|
||||
listener1 = new Listener();
|
||||
channel2.addChannelListener(listener1);
|
||||
TesterUtil.addRandomDomain(new ManagedChannel[] {channel1, channel2});
|
||||
channel1.start(Channel.DEFAULT);
|
||||
channel2.start(Channel.DEFAULT);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
channel1.stop(Channel.DEFAULT);
|
||||
channel2.stop(Channel.DEFAULT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSendSYNCACK() throws Exception {
|
||||
System.err.println("Starting SYNC_ACK");
|
||||
int errC=0, nerrC=0;
|
||||
for (int i=0; i<msgCount; i++) {
|
||||
boolean error = Data.r.nextBoolean();
|
||||
try {
|
||||
channel1.send(channel1.getMembers(),
|
||||
Data.createRandomData(error),
|
||||
Channel.SEND_OPTIONS_SYNCHRONIZED_ACK
|
||||
| Channel.SEND_OPTIONS_USE_ACK);
|
||||
if (error) {
|
||||
Assert.fail("A ChannelException was expected");
|
||||
}
|
||||
} catch (ChannelException e) {
|
||||
if (!error) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
if ( error ) errC++; else nerrC++;
|
||||
}
|
||||
System.err.println("Finished SYNC_ACK");
|
||||
|
||||
// The listener sees 3 copies of the first "error" message,
|
||||
// as it is being re-sent. Thus the listener1 count is off by +2.
|
||||
final int duplicate = 2;
|
||||
|
||||
Assert.assertEquals("Checking failure messages.", errC + duplicate,
|
||||
listener1.errCnt);
|
||||
Assert.assertEquals("Checking success messages.", nerrC, listener1.noErrCnt);
|
||||
Assert.assertEquals("Checking all messages.", msgCount + duplicate,
|
||||
listener1.noErrCnt + listener1.errCnt);
|
||||
System.out.println("Listener 1 stats:");
|
||||
listener1.printStats(System.out);
|
||||
}
|
||||
|
||||
public static class Listener implements ChannelListener {
|
||||
long noErrCnt = 0;
|
||||
long errCnt = 0;
|
||||
@Override
|
||||
public boolean accept(Serializable s, Member m) {
|
||||
return (s instanceof Data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageReceived(Serializable s, Member m) {
|
||||
Data d = (Data)s;
|
||||
if ( !Data.verify(d) ) {
|
||||
System.err.println("ERROR");
|
||||
} else {
|
||||
if (d.error) {
|
||||
errCnt++;
|
||||
if ( (errCnt % 100) == 0) {
|
||||
printStats(System.err);
|
||||
}
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
noErrCnt++;
|
||||
if ( (noErrCnt % 100) == 0) {
|
||||
printStats(System.err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void printStats(PrintStream stream) {
|
||||
stream.println("NORMAL:" + noErrCnt);
|
||||
stream.println("FAILURES:" + errCnt);
|
||||
stream.println("TOTAL:" + (errCnt+noErrCnt));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Data implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
public int length;
|
||||
public byte[] data;
|
||||
public byte key;
|
||||
public boolean error = false;
|
||||
public static final Random r = new Random();
|
||||
public static Data createRandomData(boolean error) {
|
||||
int i = r.nextInt();
|
||||
i = ( i % 127 );
|
||||
int length = Math.abs(r.nextInt() % 65555);
|
||||
Data d = new Data();
|
||||
d.length = length;
|
||||
d.key = (byte)i;
|
||||
d.data = new byte[length];
|
||||
Arrays.fill(d.data,d.key);
|
||||
d.error = error;
|
||||
return d;
|
||||
}
|
||||
|
||||
public static boolean verify(Data d) {
|
||||
boolean result = (d.length == d.data.length);
|
||||
for ( int i=0; result && (i<d.data.length); i++ ) result = result && d.data[i] == d.key;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.test.channel;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.ChannelListener;
|
||||
import org.apache.catalina.tribes.ChannelReceiver;
|
||||
import org.apache.catalina.tribes.ManagedChannel;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.TesterUtil;
|
||||
import org.apache.catalina.tribes.group.GroupChannel;
|
||||
import org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor;
|
||||
import org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor;
|
||||
import org.apache.catalina.tribes.io.XByteBuffer;
|
||||
import org.apache.catalina.tribes.transport.AbstractSender;
|
||||
import org.apache.catalina.tribes.transport.ReceiverBase;
|
||||
import org.apache.catalina.tribes.transport.ReplicationTransmitter;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class TestUdpPackages {
|
||||
private int msgCount = 500;
|
||||
private int threadCount = 20;
|
||||
private GroupChannel channel1;
|
||||
private GroupChannel channel2;
|
||||
private Listener listener1;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
channel1 = new GroupChannel();
|
||||
channel1.addInterceptor(new MessageDispatchInterceptor());
|
||||
channel2 = new GroupChannel();
|
||||
channel2.addInterceptor(new MessageDispatchInterceptor());
|
||||
ThroughputInterceptor tint = new ThroughputInterceptor();
|
||||
tint.setInterval(500);
|
||||
ThroughputInterceptor tint2 = new ThroughputInterceptor();
|
||||
tint2.setInterval(500);
|
||||
//channel1.addInterceptor(tint);
|
||||
channel2.addInterceptor(tint2);
|
||||
listener1 = new Listener();
|
||||
ReceiverBase rb1 = (ReceiverBase)channel1.getChannelReceiver();
|
||||
ReceiverBase rb2 = (ReceiverBase)channel2.getChannelReceiver();
|
||||
rb1.setUdpPort(50000);
|
||||
rb2.setUdpPort(50000);
|
||||
channel2.addChannelListener(listener1);
|
||||
TesterUtil.addRandomDomain(new ManagedChannel[] {channel1, channel2});
|
||||
channel1.start(Channel.DEFAULT);
|
||||
channel2.start(Channel.DEFAULT);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
channel1.stop(Channel.DEFAULT);
|
||||
channel2.stop(Channel.DEFAULT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleDataSendNO_ACK() throws Exception {
|
||||
AbstractSender s1 =(AbstractSender) ((ReplicationTransmitter)channel1.getChannelSender()).getTransport();
|
||||
AbstractSender s2 =(AbstractSender) ((ReplicationTransmitter)channel2.getChannelSender()).getTransport();
|
||||
s1.setTimeout(Long.MAX_VALUE); //for debugging
|
||||
s2.setTimeout(Long.MAX_VALUE); //for debugging
|
||||
|
||||
System.err.println("Starting Single package NO_ACK");
|
||||
channel1.send(new Member[] {channel2.getLocalMember(false)}, Data.createRandomData(1024),Channel.SEND_OPTIONS_UDP);
|
||||
Thread.sleep(500);
|
||||
System.err.println("Finished Single package NO_ACK ["+listener1.count+"]");
|
||||
Assert.assertEquals("Checking success messages.",1,listener1.count.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSendNO_ACK() throws Exception {
|
||||
final AtomicInteger counter = new AtomicInteger(0);
|
||||
ReceiverBase rb1 = (ReceiverBase)channel1.getChannelReceiver();
|
||||
ReceiverBase rb2 = (ReceiverBase)channel2.getChannelReceiver();
|
||||
rb1.setUdpRxBufSize(1024*1024*10);
|
||||
rb2.setUdpRxBufSize(1024*1024*10);
|
||||
rb1.setUdpTxBufSize(1024*1024*10);
|
||||
rb2.setUdpTxBufSize(1024*1024*10);
|
||||
System.err.println("Starting NO_ACK");
|
||||
Thread[] threads = new Thread[threadCount];
|
||||
for (int x=0; x<threads.length; x++ ) {
|
||||
threads[x] = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
long start = System.currentTimeMillis();
|
||||
for (int i = 0; i < msgCount; i++) {
|
||||
int cnt = counter.getAndAdd(1);
|
||||
channel1.send(new Member[] {channel2.getLocalMember(false)}, Data.createRandomData(1024,cnt),Channel.SEND_OPTIONS_UDP);
|
||||
//Thread.currentThread().sleep(10);
|
||||
}
|
||||
System.out.println("Thread["+this.getName()+"] sent "+msgCount+" messages in "+(System.currentTimeMillis()-start)+" ms.");
|
||||
}catch ( Exception x ) {
|
||||
x.printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
for (int x=0; x<threads.length; x++ ) { threads[x].start();}
|
||||
for (int x=0; x<threads.length; x++ ) { threads[x].join();}
|
||||
//sleep for 50 sec, let the other messages in
|
||||
long start = System.currentTimeMillis();
|
||||
while ( (System.currentTimeMillis()-start)<25000 && msgCount*threadCount!=listener1.count.get()) Thread.sleep(500);
|
||||
System.err.println("Finished NO_ACK ["+listener1.count+"]");
|
||||
System.out.println("Sent "+counter.get()+ " messages. Received "+listener1.count+" Highest msg received:"+listener1.maxIdx);
|
||||
System.out.print("Missing messages:");
|
||||
printMissingMsgs(listener1.nrs,counter.get());
|
||||
Assert.assertEquals("Checking success messages.",msgCount*threadCount,listener1.count.get());
|
||||
}
|
||||
|
||||
public static void printMissingMsgs(int[] msgs, int maxIdx) {
|
||||
for (int i=0; i<maxIdx && i<msgs.length; i++) {
|
||||
if (msgs[i]==0) System.out.print(i+", ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSendASYNCM() throws Exception {
|
||||
final AtomicInteger counter = new AtomicInteger(0);
|
||||
ReceiverBase rb1 = (ReceiverBase)channel1.getChannelReceiver();
|
||||
ReceiverBase rb2 = (ReceiverBase)channel2.getChannelReceiver();
|
||||
rb1.setUdpRxBufSize(1024*1024*10);
|
||||
rb2.setUdpRxBufSize(1024*1024*10);
|
||||
rb1.setUdpTxBufSize(1024*1024*10);
|
||||
rb2.setUdpTxBufSize(1024*1024*10);
|
||||
System.err.println("Starting NO_ACK");
|
||||
Thread[] threads = new Thread[threadCount];
|
||||
for (int x=0; x<threads.length; x++ ) {
|
||||
threads[x] = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
long start = System.currentTimeMillis();
|
||||
for (int i = 0; i < msgCount; i++) {
|
||||
int cnt = counter.getAndAdd(1);
|
||||
channel1.send(new Member[] {channel2.getLocalMember(false)}, Data.createRandomData(1024,cnt),Channel.SEND_OPTIONS_UDP|Channel.SEND_OPTIONS_ASYNCHRONOUS);
|
||||
//Thread.currentThread().sleep(10);
|
||||
}
|
||||
System.out.println("Thread["+this.getName()+"] sent "+msgCount+" messages in "+(System.currentTimeMillis()-start)+" ms.");
|
||||
}catch ( Exception x ) {
|
||||
x.printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
for (int x=0; x<threads.length; x++ ) { threads[x].start();}
|
||||
for (int x=0; x<threads.length; x++ ) { threads[x].join();}
|
||||
//sleep for 50 sec, let the other messages in
|
||||
long start = System.currentTimeMillis();
|
||||
while ( (System.currentTimeMillis()-start)<25000 && msgCount*threadCount!=listener1.count.get()) Thread.sleep(500);
|
||||
System.err.println("Finished NO_ACK ["+listener1.count+"]");
|
||||
System.out.println("Sent "+counter.get()+ " messages. Received "+listener1.count+" Highest msg received:"+listener1.maxIdx);
|
||||
System.out.print("Missing messages:");
|
||||
printMissingMsgs(listener1.nrs,counter.get());
|
||||
Assert.assertEquals("Checking success messages.",msgCount*threadCount,listener1.count.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSendASYNC() throws Exception {
|
||||
System.err.println("Starting ASYNC");
|
||||
for (int i=0; i<msgCount; i++) channel1.send(new Member[] {channel2.getLocalMember(false)},Data.createRandomData(1024),Channel.SEND_OPTIONS_ASYNCHRONOUS|Channel.SEND_OPTIONS_UDP);
|
||||
//sleep for 50 sec, let the other messages in
|
||||
long start = System.currentTimeMillis();
|
||||
while ( (System.currentTimeMillis()-start)<5000 && msgCount!=listener1.count.get()) Thread.sleep(500);
|
||||
System.err.println("Finished ASYNC");
|
||||
Assert.assertEquals("Checking success messages.",msgCount,listener1.count.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSendACK() throws Exception {
|
||||
System.err.println("Starting ACK");
|
||||
for (int i=0; i<msgCount; i++) channel1.send(new Member[] {channel2.getLocalMember(false)},Data.createRandomData(1024),Channel.SEND_OPTIONS_USE_ACK|Channel.SEND_OPTIONS_UDP);
|
||||
Thread.sleep(250);
|
||||
System.err.println("Finished ACK");
|
||||
Assert.assertEquals("Checking success messages.",msgCount,listener1.count.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSendSYNCACK() throws Exception {
|
||||
System.err.println("Starting SYNC_ACK");
|
||||
for (int i=0; i<msgCount; i++) channel1.send(new Member[] {channel2.getLocalMember(false)},Data.createRandomData(1024),Channel.SEND_OPTIONS_SYNCHRONIZED_ACK|Channel.SEND_OPTIONS_USE_ACK|Channel.SEND_OPTIONS_UDP);
|
||||
Thread.sleep(250);
|
||||
System.err.println("Finished SYNC_ACK");
|
||||
Assert.assertEquals("Checking success messages.",msgCount,listener1.count.get());
|
||||
}
|
||||
|
||||
public static class Listener implements ChannelListener {
|
||||
AtomicLong count = new AtomicLong(0);
|
||||
int maxIdx = -1;
|
||||
int[] nrs = new int[1000000];
|
||||
public Listener() {
|
||||
Arrays.fill(nrs, 0);
|
||||
}
|
||||
@Override
|
||||
public boolean accept(Serializable s, Member m) {
|
||||
return (s instanceof Data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageReceived(Serializable s, Member m) {
|
||||
try {
|
||||
Data d = (Data)s;
|
||||
if ( !Data.verify(d) ) {
|
||||
System.err.println("ERROR - Unable to verify data package");
|
||||
} else {
|
||||
long c = count.addAndGet(1);
|
||||
if ((c%1000) ==0 ) {
|
||||
System.err.println("SUCCESS:"+c);
|
||||
}
|
||||
int nr = d.getNumber();
|
||||
if (nr>=0 && nr<nrs.length) {
|
||||
maxIdx = Math.max(maxIdx, nr);
|
||||
nrs[nr] = 1;
|
||||
}
|
||||
}
|
||||
}catch (Exception x ) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Data implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
public int length;
|
||||
public byte[] data;
|
||||
public byte key;
|
||||
public boolean hasNr = false;
|
||||
public static final Random r = new Random();
|
||||
public static Data createRandomData() {
|
||||
return createRandomData(ChannelReceiver.MAX_UDP_SIZE);
|
||||
}
|
||||
public static Data createRandomData(int size) {
|
||||
return createRandomData(size,-1);
|
||||
}
|
||||
|
||||
public static Data createRandomData(int size, int number) {
|
||||
int i = r.nextInt();
|
||||
i = ( i % 127 );
|
||||
int length = Math.abs(r.nextInt() % size);
|
||||
if (length<100) length += 100;
|
||||
Data d = new Data();
|
||||
d.length = length;
|
||||
d.key = (byte)i;
|
||||
d.data = new byte[length];
|
||||
Arrays.fill(d.data,d.key);
|
||||
if (number>0 && d.data.length>=4) {
|
||||
//populate number
|
||||
d.hasNr = true;
|
||||
XByteBuffer.toBytes(number,d.data, 0);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
public int getNumber() {
|
||||
if (!hasNr) return -1;
|
||||
return XByteBuffer.toInt(this.data, 0);
|
||||
}
|
||||
|
||||
public static boolean verify(Data d) {
|
||||
boolean result = (d.length == d.data.length);
|
||||
for ( int i=(d.hasNr?4:0); result && (i<d.data.length); i++ ) result = result && d.data[i] == d.key;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.test.transport;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import org.apache.catalina.tribes.ChannelMessage;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.MessageListener;
|
||||
import org.apache.catalina.tribes.io.ChannelData;
|
||||
import org.apache.catalina.tribes.io.XByteBuffer;
|
||||
import org.apache.catalina.tribes.membership.MemberImpl;
|
||||
import org.apache.catalina.tribes.transport.nio.NioReceiver;
|
||||
|
||||
public class SocketNioReceive {
|
||||
static int count = 0;
|
||||
static int accept = 0;
|
||||
static long start = 0;
|
||||
static double mb = 0;
|
||||
static int len = 0;
|
||||
static DecimalFormat df = new DecimalFormat("##.00");
|
||||
static double seconds = 0;
|
||||
|
||||
protected static final Object mutex = new Object();
|
||||
public static void main(String[] args) throws Exception {
|
||||
Member mbr = new MemberImpl("localhost", 9999, 0);
|
||||
ChannelData data = new ChannelData();
|
||||
data.setAddress(mbr);
|
||||
byte[] buf = new byte[8192 * 4];
|
||||
data.setMessage(new XByteBuffer(buf, false));
|
||||
buf = XByteBuffer.createDataPackage(data);
|
||||
len = buf.length;
|
||||
NioReceiver receiver = new NioReceiver();
|
||||
receiver.setPort(9999);
|
||||
receiver.setHost("localhost");
|
||||
MyList list = new MyList();
|
||||
receiver.setMessageListener(list);
|
||||
receiver.start();
|
||||
System.out.println("Listening on 9999");
|
||||
while (true) {
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
if ( start != 0 ) {
|
||||
System.out.println("Throughput " + df.format(mb / seconds) + " MB/seconds, messages "+count+" accepts "+accept+", total "+mb+" MB.");
|
||||
}
|
||||
}catch (Throwable x) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyList implements MessageListener {
|
||||
boolean first = true;
|
||||
|
||||
|
||||
@Override
|
||||
public void messageReceived(ChannelMessage msg) {
|
||||
if (first) {
|
||||
first = false;
|
||||
start = System.currentTimeMillis();
|
||||
}
|
||||
mb += ( (double) len) / 1024 / 1024;
|
||||
synchronized (this) {count++;}
|
||||
if ( ( (count) % 10000) == 0) {
|
||||
long time = System.currentTimeMillis();
|
||||
seconds = ( (double) (time - start)) / 1000;
|
||||
System.out.println("Throughput " + df.format(mb / seconds) + " MB/seconds, messages "+count+", total "+mb+" MB.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(ChannelMessage msg) {
|
||||
synchronized (this) {accept++;}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.test.transport;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.io.ChannelData;
|
||||
import org.apache.catalina.tribes.io.XByteBuffer;
|
||||
import org.apache.catalina.tribes.membership.MemberImpl;
|
||||
import org.apache.catalina.tribes.transport.nio.NioSender;
|
||||
|
||||
public class SocketNioSend {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Selector selector = Selector.open();
|
||||
Member mbr = new MemberImpl("localhost", 9999, 0);
|
||||
ChannelData data = new ChannelData();
|
||||
data.setOptions(Channel.SEND_OPTIONS_BYTE_MESSAGE);
|
||||
data.setAddress(mbr);
|
||||
byte[] buf = new byte[8192 * 4];
|
||||
data.setMessage(new XByteBuffer(buf,false));
|
||||
buf = XByteBuffer.createDataPackage(data);
|
||||
int len = buf.length;
|
||||
BigDecimal total = new BigDecimal((double)0);
|
||||
BigDecimal bytes = new BigDecimal((double)len);
|
||||
NioSender sender = new NioSender();
|
||||
sender.setDestination(mbr);
|
||||
sender.setDirectBuffer(true);
|
||||
sender.setSelector(selector);
|
||||
sender.setTxBufSize(1024*1024);
|
||||
sender.connect();
|
||||
sender.setMessage(buf);
|
||||
System.out.println("Writing to 9999");
|
||||
long start = 0;
|
||||
double mb = 0;
|
||||
boolean first = true;
|
||||
int count = 0;
|
||||
DecimalFormat df = new DecimalFormat("##.00");
|
||||
while (count<100000) {
|
||||
if (first) {
|
||||
first = false;
|
||||
start = System.currentTimeMillis();
|
||||
}
|
||||
sender.setMessage(buf);
|
||||
int selectedKeys = 0;
|
||||
try {
|
||||
selectedKeys = selector.select(0);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (selectedKeys == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Iterator<SelectionKey> it = selector.selectedKeys().iterator();
|
||||
while (it.hasNext()) {
|
||||
SelectionKey sk = it.next();
|
||||
it.remove();
|
||||
try {
|
||||
int readyOps = sk.readyOps();
|
||||
sk.interestOps(sk.interestOps() & ~readyOps);
|
||||
if (sender.process(sk, false)) {
|
||||
total = total.add(bytes);
|
||||
sender.reset();
|
||||
sender.setMessage(buf);
|
||||
mb += ( (double) len) / 1024 / 1024;
|
||||
if ( ( (++count) % 10000) == 0) {
|
||||
long time = System.currentTimeMillis();
|
||||
double seconds = ( (double) (time - start)) / 1000;
|
||||
System.out.println("Throughput " + df.format(mb / seconds) + " MB/seconds, total "+mb+" MB, total "+total+" bytes.");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
selector.selectedKeys().clear();
|
||||
}
|
||||
System.out.println("Complete, sleeping 15 seconds");
|
||||
Thread.sleep(15000);
|
||||
}
|
||||
}
|
||||
@@ -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 org.apache.catalina.tribes.test.transport;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.membership.MemberImpl;
|
||||
import org.apache.catalina.tribes.transport.nio.NioSender;
|
||||
|
||||
public class SocketNioValidateSend {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Selector selector = Selector.open();
|
||||
Member mbr = new MemberImpl("localhost", 9999, 0);
|
||||
byte seq = 0;
|
||||
byte[] buf = new byte[50000];
|
||||
Arrays.fill(buf,seq);
|
||||
int len = buf.length;
|
||||
BigDecimal total = new BigDecimal((double)0);
|
||||
BigDecimal bytes = new BigDecimal((double)len);
|
||||
NioSender sender = new NioSender();
|
||||
sender.setDestination(mbr);
|
||||
sender.setDirectBuffer(true);
|
||||
sender.setSelector(selector);
|
||||
sender.connect();
|
||||
sender.setMessage(buf);
|
||||
System.out.println("Writing to 9999");
|
||||
long start = 0;
|
||||
double mb = 0;
|
||||
boolean first = true;
|
||||
int count = 0;
|
||||
|
||||
DecimalFormat df = new DecimalFormat("##.00");
|
||||
while (count<100000) {
|
||||
if (first) {
|
||||
first = false;
|
||||
start = System.currentTimeMillis();
|
||||
}
|
||||
sender.setMessage(buf);
|
||||
int selectedKeys = 0;
|
||||
try {
|
||||
selectedKeys = selector.select(0);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (selectedKeys == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Iterator<SelectionKey> it = selector.selectedKeys().iterator();
|
||||
while (it.hasNext()) {
|
||||
SelectionKey sk = it.next();
|
||||
it.remove();
|
||||
try {
|
||||
int readyOps = sk.readyOps();
|
||||
sk.interestOps(sk.interestOps() & ~readyOps);
|
||||
if (sender.process(sk, false)) {
|
||||
total = total.add(bytes);
|
||||
sender.reset();
|
||||
seq++;
|
||||
Arrays.fill(buf,seq);
|
||||
sender.setMessage(buf);
|
||||
mb += ( (double) len) / 1024 / 1024;
|
||||
if ( ( (++count) % 10000) == 0) {
|
||||
long time = System.currentTimeMillis();
|
||||
double seconds = ( (double) (time - start)) / 1000;
|
||||
System.out.println("Throughput " + df.format(mb / seconds) + " MB/seconds, total "+mb+" MB, total "+total+" bytes.");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("Complete, sleeping 15 seconds");
|
||||
Thread.sleep(15000);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.test.transport;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class SocketReceive {
|
||||
static long start = 0;
|
||||
static double mb = 0;
|
||||
static byte[] buf = new byte[8192 * 4];
|
||||
static boolean first = true;
|
||||
static int count = 0;
|
||||
static DecimalFormat df = new DecimalFormat("##.00");
|
||||
static BigDecimal total = new BigDecimal(0);
|
||||
static BigDecimal bytes = new BigDecimal(32871);
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
try (ServerSocket srvSocket = new ServerSocket(9999)) {
|
||||
System.out.println("Listening on 9999");
|
||||
Socket socket = srvSocket.accept();
|
||||
socket.setReceiveBufferSize(43800);
|
||||
InputStream in = socket.getInputStream();
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
while ( true ) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
printStats(start, mb, count, df, total);
|
||||
}catch ( Exception x ) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
|
||||
while ( true ) {
|
||||
if ( first ) {
|
||||
first = false; start = System.currentTimeMillis();
|
||||
}
|
||||
int len = in.read(buf);
|
||||
if ( len == -1 ) {
|
||||
printStats(start, mb, count, df, total);
|
||||
System.exit(1);
|
||||
}
|
||||
if ( bytes.intValue() != len ) {
|
||||
bytes = new BigDecimal((double)len);
|
||||
}
|
||||
total = total.add(bytes);
|
||||
mb += ( (double) len) / 1024 / 1024;
|
||||
if ( ((++count) % 10000) == 0 ) {
|
||||
printStats(start, mb, count, df, total);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void printStats(long start, double mb, int count,
|
||||
DecimalFormat df, BigDecimal total) {
|
||||
long time = System.currentTimeMillis();
|
||||
double seconds = ((double)(time-start))/1000;
|
||||
System.out.println("Throughput " + df.format(mb/seconds) +
|
||||
" MB/seconds messages " + count + ", total " + mb +
|
||||
" MB, total " + total + " bytes.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.test.transport;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.Socket;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.io.ChannelData;
|
||||
import org.apache.catalina.tribes.io.XByteBuffer;
|
||||
import org.apache.catalina.tribes.membership.MemberImpl;
|
||||
|
||||
public class SocketSend {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
|
||||
Member mbr = new MemberImpl("localhost", 9999, 0);
|
||||
ChannelData data = new ChannelData();
|
||||
data.setOptions(Channel.SEND_OPTIONS_BYTE_MESSAGE);
|
||||
data.setAddress(mbr);
|
||||
byte[] buf = new byte[8192 * 4];
|
||||
data.setMessage(new XByteBuffer(buf,false));
|
||||
buf = XByteBuffer.createDataPackage(data);
|
||||
int len = buf.length;
|
||||
System.out.println("Message size:"+len+" bytes");
|
||||
BigDecimal total = new BigDecimal((double)0);
|
||||
BigDecimal bytes = new BigDecimal((double)len);
|
||||
try (Socket socket = new Socket("localhost",9999)) {
|
||||
System.out.println("Writing to 9999");
|
||||
OutputStream out = socket.getOutputStream();
|
||||
long start = 0;
|
||||
double mb = 0;
|
||||
boolean first = true;
|
||||
int count = 0;
|
||||
DecimalFormat df = new DecimalFormat("##.00");
|
||||
while ( count<1000000 ) {
|
||||
if ( first ) {
|
||||
first = false; start = System.currentTimeMillis();
|
||||
}
|
||||
out.write(buf,0,buf.length);
|
||||
mb += ( (double) buf.length) / 1024 / 1024;
|
||||
total = total.add(bytes);
|
||||
if ( ((++count) % 10000) == 0 ) {
|
||||
long time = System.currentTimeMillis();
|
||||
double seconds = ((double)(time-start))/1000;
|
||||
System.out.println("Throughput " + df.format(mb/seconds) +
|
||||
" MB/seconds messages " + count + ", total " + mb +
|
||||
" MB, total " + total + " bytes.");
|
||||
}
|
||||
}
|
||||
out.flush();
|
||||
System.out.println("Complete, sleeping 5 seconds");
|
||||
Thread.sleep(5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 org.apache.catalina.tribes.test.transport;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import org.apache.catalina.tribes.io.XByteBuffer;
|
||||
|
||||
public class SocketTribesReceive {
|
||||
static long start = 0;
|
||||
static double mb = 0;
|
||||
//static byte[] buf = new byte[32871];
|
||||
static byte[] buf = new byte[32871];
|
||||
static boolean first = true;
|
||||
static int count = 0;
|
||||
static DecimalFormat df = new DecimalFormat("##.00");
|
||||
static BigDecimal total = new BigDecimal((double)0);
|
||||
static BigDecimal bytes = new BigDecimal((double)32871);
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
int size = 43800;
|
||||
if (args.length > 0 ) {
|
||||
try {
|
||||
size = Integer.parseInt(args[0]);
|
||||
} catch (Exception e){
|
||||
/* Ignore */
|
||||
}
|
||||
}
|
||||
XByteBuffer xbuf = new XByteBuffer(43800,true);
|
||||
try (ServerSocket srvSocket = new ServerSocket(9999)) {
|
||||
System.out.println("Listening on 9999");
|
||||
Socket socket = srvSocket.accept();
|
||||
socket.setReceiveBufferSize(size);
|
||||
InputStream in = socket.getInputStream();
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
while ( true ) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
printStats(start, mb, count, df, total);
|
||||
}catch ( Exception x ) { /* Ignore */ }
|
||||
}
|
||||
}
|
||||
};
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
|
||||
while ( true ) {
|
||||
if ( first ) {
|
||||
first = false; start = System.currentTimeMillis();
|
||||
}
|
||||
int len = in.read(buf);
|
||||
if ( len == -1 ) {
|
||||
printStats(start, mb, count, df, total);
|
||||
System.exit(1);
|
||||
}
|
||||
xbuf.append(buf,0,len);
|
||||
if ( bytes.intValue() != len ) {
|
||||
bytes = new BigDecimal((double)len);
|
||||
}
|
||||
total = total.add(bytes);
|
||||
while ( xbuf.countPackages(true) > 0 ) {
|
||||
xbuf.extractPackage(true);
|
||||
count++;
|
||||
}
|
||||
mb += ( (double) len) / 1024 / 1024;
|
||||
if ( ((count) % 10000) == 0 ) {
|
||||
printStats(start, mb, count, df, total);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void printStats(long start, double mb, int count,
|
||||
DecimalFormat df, BigDecimal total) {
|
||||
long time = System.currentTimeMillis();
|
||||
double seconds = ((double)(time-start))/1000;
|
||||
System.out.println("Throughput " + df.format(mb/seconds) +
|
||||
" MB/seconds messages " + count + ", total " + mb +
|
||||
" MB, total " + total + " bytes.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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 org.apache.catalina.tribes.test.transport;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class SocketValidateReceive {
|
||||
static long start = 0;
|
||||
static double mb = 0;
|
||||
static byte[] buf = new byte[8192 * 4];
|
||||
static boolean first = true;
|
||||
static int count = 0;
|
||||
static DecimalFormat df = new DecimalFormat("##.00");
|
||||
static BigDecimal total = new BigDecimal(0);
|
||||
static BigDecimal bytes = new BigDecimal(32871);
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
int size = 43800;
|
||||
if (args.length > 0 ) try {size=Integer.parseInt(args[0]);}catch(Exception x){ /* Ignore */ }
|
||||
|
||||
try(ServerSocket srvSocket = new ServerSocket(9999)) {
|
||||
System.out.println("Listening on 9999");
|
||||
Socket socket = srvSocket.accept();
|
||||
socket.setReceiveBufferSize(size);
|
||||
InputStream in = socket.getInputStream();
|
||||
MyDataReader reader = new MyDataReader(50000);
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
while ( true ) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
printStats(start, mb, count, df, total);
|
||||
}catch ( Exception x ) { /* Ignore */ }
|
||||
}
|
||||
}
|
||||
};
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
|
||||
while ( true ) {
|
||||
if ( first ) {
|
||||
first = false; start = System.currentTimeMillis();
|
||||
}
|
||||
int len = in.read(buf);
|
||||
if ( len == -1 ) {
|
||||
printStats(start, mb, count, df, total);
|
||||
System.exit(1);
|
||||
}
|
||||
count += reader.append(buf,0,len);
|
||||
|
||||
if ( bytes.intValue() != len ) {
|
||||
bytes = new BigDecimal((double)len);
|
||||
}
|
||||
total = total.add(bytes);
|
||||
mb += ( (double) len) / 1024 / 1024;
|
||||
if ( ((count) % 10000) == 0 ) {
|
||||
printStats(start, mb, count, df, total);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void printStats(long start, double mb, int count,
|
||||
DecimalFormat df, BigDecimal total) {
|
||||
long time = System.currentTimeMillis();
|
||||
double seconds = ((double)(time-start))/1000;
|
||||
System.out.println("Throughput " + df.format(mb/seconds) +
|
||||
" MB/seconds messages " + count + ", total " + mb +
|
||||
" MB, total " + total + " bytes.");
|
||||
}
|
||||
|
||||
public static class MyDataReader {
|
||||
int length = 10;
|
||||
int cur = 0;
|
||||
byte seq = 0;
|
||||
public MyDataReader(int len) {
|
||||
length = len;
|
||||
}
|
||||
|
||||
public int append(byte[] b, int off, int len) throws Exception {
|
||||
int packages = 0;
|
||||
for ( int i=off; i<len; i++ ) {
|
||||
if ( cur == length ) {
|
||||
cur = 0;
|
||||
seq++;
|
||||
packages++;
|
||||
}
|
||||
if ( b[i] != seq ) throw new Exception("mismatch on seq:"+seq+" and byte nr:"+cur+" count:"+count+" packages:"+packages);
|
||||
cur++;
|
||||
}
|
||||
return packages;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user