init
This commit is contained in:
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
@@ -0,0 +1,552 @@
|
||||
/*
|
||||
* 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.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.ComponentOrientation;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.Serializable;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.TableColumn;
|
||||
|
||||
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.MembershipListener;
|
||||
import org.apache.catalina.tribes.tipis.LazyReplicatedMap;
|
||||
|
||||
/**
|
||||
* Example of how the lazy replicated map works, also shows how the BackupManager
|
||||
* works in a Tomcat cluster
|
||||
* @version 1.1
|
||||
*/
|
||||
public class MapDemo implements ChannelListener, MembershipListener{
|
||||
|
||||
/**
|
||||
* The Map containing the replicated data
|
||||
*/
|
||||
protected LazyReplicatedMap<String,StringBuilder> map;
|
||||
|
||||
/**
|
||||
* Table to be displayed in Swing
|
||||
*/
|
||||
protected SimpleTableDemo table;
|
||||
|
||||
/**
|
||||
* Constructs a map demo object.
|
||||
* @param channel - the Tribes channel object to be used for communication
|
||||
* @param mapName - the name of this map
|
||||
*/
|
||||
public MapDemo(Channel channel, String mapName ) {
|
||||
//instantiate the replicated map
|
||||
map = new LazyReplicatedMap<>(null, channel, 5000, mapName, null);
|
||||
//create a gui, name it with the member name of this JVM
|
||||
table = SimpleTableDemo.createAndShowGUI(map,channel.getLocalMember(false).getName());
|
||||
//add ourself as a listener for messages
|
||||
channel.addChannelListener(this);
|
||||
//add ourself as a listener for memberships
|
||||
channel.addMembershipListener(this);
|
||||
//initialize the map by receiving a fake message
|
||||
this.messageReceived(null,null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides if the messageReceived should be invoked
|
||||
* will always return false since we rely on the
|
||||
* lazy map to do all the messaging for us
|
||||
*/
|
||||
@Override
|
||||
public boolean accept(Serializable msg, Member source) {
|
||||
//simple refresh the table model
|
||||
table.dataModel.getValueAt(-1,-1);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked if accept returns true.
|
||||
* No op for now
|
||||
* @param msg - the message received
|
||||
* @param source - the sending member
|
||||
*/
|
||||
@Override
|
||||
public void messageReceived(Serializable msg, Member source) {
|
||||
// NOOP
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when a member is added to the group
|
||||
*/
|
||||
@Override
|
||||
public void memberAdded(Member member) {
|
||||
// NOOP
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when a member leaves the group
|
||||
*/
|
||||
@Override
|
||||
public void memberDisappeared(Member member) {
|
||||
//just refresh the table model
|
||||
table.dataModel.getValueAt(-1,-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints usage
|
||||
*/
|
||||
public static void usage() {
|
||||
System.out.println("Tribes MapDemo.");
|
||||
System.out.println("Usage:\n\t" +
|
||||
"java MapDemo [channel options] mapName\n\t" +
|
||||
"\tChannel options:" +
|
||||
ChannelCreator.usage());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void main(String[] args) throws Exception {
|
||||
long start = System.currentTimeMillis();
|
||||
//create a channel object
|
||||
ManagedChannel channel = (ManagedChannel) ChannelCreator.createChannel(args);
|
||||
//define a map name, unless one is defined as a parameters
|
||||
String mapName = "MapDemo";
|
||||
if ( args.length > 0 && (!args[args.length-1].startsWith("-"))) {
|
||||
mapName = args[args.length-1];
|
||||
}
|
||||
//start the channel
|
||||
channel.start(Channel.DEFAULT);
|
||||
//listen for shutdown
|
||||
Runtime.getRuntime().addShutdownHook(new Shutdown(channel));
|
||||
//create a map demo object
|
||||
new MapDemo(channel,mapName);
|
||||
|
||||
//put the main thread to sleep until we are done
|
||||
System.out.println("System test complete, time to start="+(System.currentTimeMillis()-start)+" ms. Sleeping to let threads finish.");
|
||||
Thread.sleep(60 * 1000 * 60);
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for shutdown events, and stops this instance
|
||||
*/
|
||||
public static class Shutdown extends Thread {
|
||||
//the channel running in this demo
|
||||
ManagedChannel channel = null;
|
||||
|
||||
public Shutdown(ManagedChannel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println("Shutting down...");
|
||||
//create an exit thread that forces a shutdown if the JVM wont exit cleanly
|
||||
SystemExit exit = new SystemExit(5000);
|
||||
exit.setDaemon(true);
|
||||
exit.start();
|
||||
try {
|
||||
//stop the channel
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SimpleTableDemo extends JPanel
|
||||
implements ActionListener {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static int WIDTH = 550;
|
||||
|
||||
private LazyReplicatedMap<String,StringBuilder> map;
|
||||
private boolean DEBUG = false;
|
||||
AbstractTableModel dataModel = new AbstractTableModel() {
|
||||
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
String[] columnNames = {
|
||||
"Rownum",
|
||||
"Key",
|
||||
"Value",
|
||||
"Primary Node",
|
||||
"Backup Node",
|
||||
"isPrimary",
|
||||
"isProxy",
|
||||
"isBackup"};
|
||||
|
||||
@Override
|
||||
public int getColumnCount() { return columnNames.length; }
|
||||
|
||||
@Override
|
||||
public int getRowCount() {return map.sizeFull() +1; }
|
||||
|
||||
public StringBuilder getMemberNames(Member[] members){
|
||||
StringBuilder buf = new StringBuilder();
|
||||
if ( members!=null ) {
|
||||
for (int i=0;i<members.length; i++ ) {
|
||||
buf.append(members[i].getName());
|
||||
buf.append("; ");
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int row, int col) {
|
||||
if ( row==-1 ) {
|
||||
update();
|
||||
return "";
|
||||
}
|
||||
if ( row == 0 ) return columnNames[col];
|
||||
Object[] keys = map.keySetFull().toArray();
|
||||
String key = (String)keys [row-1];
|
||||
LazyReplicatedMap.MapEntry<String,StringBuilder> entry =
|
||||
map.getInternal(key);
|
||||
switch (col) {
|
||||
case 0: return String.valueOf(row);
|
||||
case 1: return entry.getKey();
|
||||
case 2: return entry.getValue();
|
||||
case 3: return entry.getPrimary()!=null?entry.getPrimary().getName():"null";
|
||||
case 4: return getMemberNames(entry.getBackupNodes());
|
||||
case 5: return Boolean.valueOf(entry.isPrimary());
|
||||
case 6: return Boolean.valueOf(entry.isProxy());
|
||||
case 7: return Boolean.valueOf(entry.isBackup());
|
||||
default: return "";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void update() {
|
||||
fireTableDataChanged();
|
||||
}
|
||||
};
|
||||
|
||||
JTextField txtAddKey = new JTextField(20);
|
||||
JTextField txtAddValue = new JTextField(20);
|
||||
JTextField txtRemoveKey = new JTextField(20);
|
||||
JTextField txtChangeKey = new JTextField(20);
|
||||
JTextField txtChangeValue = new JTextField(20);
|
||||
|
||||
JTable table = null;
|
||||
public SimpleTableDemo(LazyReplicatedMap<String,StringBuilder> map) {
|
||||
super();
|
||||
this.map = map;
|
||||
|
||||
this.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
|
||||
|
||||
//final JTable table = new JTable(data, columnNames);
|
||||
table = new JTable(dataModel);
|
||||
|
||||
table.setPreferredScrollableViewportSize(new Dimension(WIDTH, 150));
|
||||
for ( int i=0; i<table.getColumnCount(); i++ ) {
|
||||
TableColumn tm = table.getColumnModel().getColumn(i);
|
||||
tm.setCellRenderer(new ColorRenderer());
|
||||
}
|
||||
|
||||
|
||||
if (DEBUG) {
|
||||
table.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
printDebugData(table);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//setLayout(new GridLayout(5, 0));
|
||||
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
|
||||
|
||||
//Create the scroll pane and add the table to it.
|
||||
JScrollPane scrollPane = new JScrollPane(table);
|
||||
|
||||
//Add the scroll pane to this panel.
|
||||
add(scrollPane);
|
||||
|
||||
//create a add value button
|
||||
JPanel addpanel = new JPanel();
|
||||
addpanel.setPreferredSize(new Dimension(WIDTH,30));
|
||||
addpanel.add(createButton("Add","add"));
|
||||
addpanel.add(txtAddKey);
|
||||
addpanel.add(txtAddValue);
|
||||
addpanel.setMaximumSize(new Dimension(WIDTH,30));
|
||||
add(addpanel);
|
||||
|
||||
//create a remove value button
|
||||
JPanel removepanel = new JPanel( );
|
||||
removepanel.setPreferredSize(new Dimension(WIDTH,30));
|
||||
removepanel.add(createButton("Remove","remove"));
|
||||
removepanel.add(txtRemoveKey);
|
||||
removepanel.setMaximumSize(new Dimension(WIDTH,30));
|
||||
add(removepanel);
|
||||
|
||||
//create a change value button
|
||||
JPanel changepanel = new JPanel( );
|
||||
changepanel.add(createButton("Change","change"));
|
||||
changepanel.add(txtChangeKey);
|
||||
changepanel.add(txtChangeValue);
|
||||
changepanel.setPreferredSize(new Dimension(WIDTH,30));
|
||||
changepanel.setMaximumSize(new Dimension(WIDTH,30));
|
||||
add(changepanel);
|
||||
|
||||
|
||||
//create sync button
|
||||
JPanel syncpanel = new JPanel( );
|
||||
syncpanel.add(createButton("Synchronize","sync"));
|
||||
syncpanel.add(createButton("Replicate","replicate"));
|
||||
syncpanel.add(createButton("Random","random"));
|
||||
syncpanel.setPreferredSize(new Dimension(WIDTH,30));
|
||||
syncpanel.setMaximumSize(new Dimension(WIDTH,30));
|
||||
add(syncpanel);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public JButton createButton(String text, String command) {
|
||||
JButton button = new JButton(text);
|
||||
button.setActionCommand(command);
|
||||
button.addActionListener(this);
|
||||
return button;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
System.out.println(e.getActionCommand());
|
||||
if ( "add".equals(e.getActionCommand()) ) {
|
||||
System.out.println("Add key:"+txtAddKey.getText()+" value:"+txtAddValue.getText());
|
||||
map.put(txtAddKey.getText(),new StringBuilder(txtAddValue.getText()));
|
||||
}
|
||||
if ( "change".equals(e.getActionCommand()) ) {
|
||||
System.out.println("Change key:"+txtChangeKey.getText()+" value:"+txtChangeValue.getText());
|
||||
StringBuilder buf = map.get(txtChangeKey.getText());
|
||||
if ( buf!=null ) {
|
||||
buf.delete(0,buf.length());
|
||||
buf.append(txtChangeValue.getText());
|
||||
map.replicate(txtChangeKey.getText(),true);
|
||||
} else {
|
||||
buf = new StringBuilder();
|
||||
buf.append(txtChangeValue.getText());
|
||||
map.put(txtChangeKey.getText(),buf);
|
||||
}
|
||||
}
|
||||
if ( "remove".equals(e.getActionCommand()) ) {
|
||||
System.out.println("Remove key:"+txtRemoveKey.getText());
|
||||
map.remove(txtRemoveKey.getText());
|
||||
}
|
||||
if ( "sync".equals(e.getActionCommand()) ) {
|
||||
System.out.println("Syncing from another node.");
|
||||
map.transferState();
|
||||
}
|
||||
if ( "random".equals(e.getActionCommand()) ) {
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
String key = random(5,0,0,true,true,null);
|
||||
map.put(key, new StringBuilder(key));
|
||||
dataModel.fireTableDataChanged();
|
||||
table.paint(table.getGraphics());
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException x) {
|
||||
Thread.interrupted();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
}
|
||||
|
||||
if ( "replicate".equals(e.getActionCommand()) ) {
|
||||
System.out.println("Replicating out to the other nodes.");
|
||||
map.replicate(true);
|
||||
}
|
||||
dataModel.getValueAt(-1,-1);
|
||||
}
|
||||
|
||||
public static final Random random = new Random();
|
||||
public static String random(int count, int start, int end, boolean letters, boolean numbers,
|
||||
char[] chars ) {
|
||||
if (count == 0) {
|
||||
return "";
|
||||
} else if (count < 0) {
|
||||
throw new IllegalArgumentException("Requested random string length " + count + " is less than 0.");
|
||||
}
|
||||
if ((start == 0) && (end == 0)) {
|
||||
end = 'z' + 1;
|
||||
start = ' ';
|
||||
if (!letters && !numbers) {
|
||||
start = 0;
|
||||
end = Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
char[] buffer = new char[count];
|
||||
int gap = end - start;
|
||||
|
||||
while (count-- != 0) {
|
||||
char ch;
|
||||
if (chars == null) {
|
||||
ch = (char) (random.nextInt(gap) + start);
|
||||
} else {
|
||||
ch = chars[random.nextInt(gap) + start];
|
||||
}
|
||||
if ((letters && Character.isLetter(ch))
|
||||
|| (numbers && Character.isDigit(ch))
|
||||
|| (!letters && !numbers))
|
||||
{
|
||||
if(ch >= 56320 && ch <= 57343) {
|
||||
if(count == 0) {
|
||||
count++;
|
||||
} else {
|
||||
// low surrogate, insert high surrogate after putting it in
|
||||
buffer[count] = ch;
|
||||
count--;
|
||||
buffer[count] = (char) (55296 + random.nextInt(128));
|
||||
}
|
||||
} else if(ch >= 55296 && ch <= 56191) {
|
||||
if(count == 0) {
|
||||
count++;
|
||||
} else {
|
||||
// high surrogate, insert low surrogate before putting it in
|
||||
buffer[count] = (char) (56320 + random.nextInt(128));
|
||||
count--;
|
||||
buffer[count] = ch;
|
||||
}
|
||||
} else if(ch >= 56192 && ch <= 56319) {
|
||||
// private high surrogate, no effing clue, so skip it
|
||||
count++;
|
||||
} else {
|
||||
buffer[count] = ch;
|
||||
}
|
||||
} else {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return new String(buffer);
|
||||
}
|
||||
|
||||
private void printDebugData(JTable table) {
|
||||
int numRows = table.getRowCount();
|
||||
int numCols = table.getColumnCount();
|
||||
javax.swing.table.TableModel model = table.getModel();
|
||||
|
||||
System.out.println("Value of data: ");
|
||||
for (int i = 0; i < numRows; i++) {
|
||||
System.out.print(" row " + i + ":");
|
||||
for (int j = 0; j < numCols; j++) {
|
||||
System.out.print(" " + model.getValueAt(i, j));
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
System.out.println("--------------------------");
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the GUI and show it. For thread safety,
|
||||
* this method should be invoked from the
|
||||
* event-dispatching thread.
|
||||
*/
|
||||
public static SimpleTableDemo createAndShowGUI(
|
||||
LazyReplicatedMap<String,StringBuilder> map, String title) {
|
||||
//Make sure we have nice window decorations.
|
||||
JFrame.setDefaultLookAndFeelDecorated(true);
|
||||
|
||||
//Create and set up the window.
|
||||
JFrame frame = new JFrame("SimpleTableDemo - "+title);
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
//Create and set up the content pane.
|
||||
SimpleTableDemo newContentPane = new SimpleTableDemo(map);
|
||||
newContentPane.setOpaque(true); //content panes must be opaque
|
||||
frame.setContentPane(newContentPane);
|
||||
|
||||
//Display the window.
|
||||
frame.setSize(450,250);
|
||||
newContentPane.setSize(450,300);
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
return newContentPane;
|
||||
}
|
||||
}
|
||||
|
||||
static class ColorRenderer extends DefaultTableCellRenderer {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ColorRenderer() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent
|
||||
(JTable table, Object value, boolean isSelected,
|
||||
boolean hasFocus, int row, int column) {
|
||||
Component cell = super.getTableCellRendererComponent
|
||||
(table, value, isSelected, hasFocus, row, column);
|
||||
cell.setBackground(Color.WHITE);
|
||||
if ( row > 0 ) {
|
||||
Color color = null;
|
||||
boolean primary = ( (Boolean) table.getValueAt(row, 5)).booleanValue();
|
||||
boolean proxy = ( (Boolean) table.getValueAt(row, 6)).booleanValue();
|
||||
boolean backup = ( (Boolean) table.getValueAt(row, 7)).booleanValue();
|
||||
if (primary) color = Color.GREEN;
|
||||
else if (proxy) color = Color.RED;
|
||||
else if (backup) color = Color.BLUE;
|
||||
if ( color != null ) cell.setBackground(color);
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user