//package sum; 

import java.net.URL; 
import java.util.Vector; 
import java.util.*;
import org.apache.soap.SOAPException; 
import org.apache.soap.Constants; 
import org.apache.soap.Fault; 
import org.apache.soap.rpc.Call; 
import org.apache.soap.rpc.Parameter; 
import org.apache.soap.rpc.Response; 

public class Client 
{ 
	public static void main(String[] args)
	{ 
		try 
		{ 
			URL url = null;
			int threads = 500;
			if(args.length >= 1 && !args[0].equals("-?")) 
			{ 
				url = new URL(args[0]);
				if (args.length >= 2)
					threads = Integer.parseInt(args[1]);
			} 
			else if (args.length == 0)
			{ 
				url = new URL("http://localhost:8080/soap/servlet/rpcrouter"); 
			}
			else
			{
				System.err.println("Usage: java Client [SOAP-router-URL] [threads]"); 
				System.exit (1); 
			}
			ThreadGroup g = new ThreadGroup("ClientThreads");
			ClientThread ct[] = new ClientThread[threads]; 
			for (int i = 0; i < threads; i++)
			{
				ct[i] = new ClientThread(g, i, url);
				ct[i].start();
			}
			while (g.activeCount() > 0) {
				try {
					Thread.currentThread().sleep(1000);
				} catch (Exception e) {
				}
			}

			long[] st = new long[1];
			int s;
			int f;
			s = ClientThread.getSuccesses(st);
			f = ClientThread.getFailures();
			System.out.println("Failures: " + f + " Successes: " + s + " Avg Time: " + (s != 0 ? (st[0] / (long) s) : (long) 0));
		}
		catch(Exception e) 
		{ 
			e.printStackTrace(); 
		} 
	} 
} 

class ClientThread extends Thread
{
	private static int successes = 0;
	private static int failures = 0;
	private static long successTime = 0;
	private static synchronized void addSuccess(long time) {
		successes++;
		successTime += time;
	}
	private static synchronized void addFailure() {
		failures++;
	}
	public static synchronized int getSuccesses(long[] successTime) {
		successTime[0] = ClientThread.successTime;
		return successes;
	}
	public static synchronized int getFailures() {
		return failures;
	}

	private int i;
	private int count = 0;
	private URL url;
	public ClientThread(ThreadGroup g, int i, URL url)
	{
		super(g, "ClientThread " + i);
		this.i = i;
		this.url = url;
	}
	public void run()
	{
		// Build the call. 
		String op1 = "10";
		String op2 = "10";
		try {
			System.out.println("starting thread " + i);
			Call call = new Call(); 
			call.setTargetObjectURI("urn:Sum"); 
			call.setMethodName("findSum"); 
			call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); 
			Vector params = new Vector(); 
			params.addElement(new Parameter("op1", String.class, op1, null)); 
			params.addElement(new Parameter("op2", String.class, op2, null)); 
			call.setParams(params); 

			// Invoke the call. 
			Response resp = null; 
			Date date = new Date();
			try 
			{ 
				resp = call.invoke(url, ""); 
			} 
			catch (SOAPException e ) 
			{ 
				System.out.println("ending thread " + i + ": Caught SOAPException (" + e.getFaultCode() + "): " + 
					e.getMessage());
				addFailure();
				return;
			}

			// Check the response. 
			if( !resp.generatedFault() ) 
			{ 
				Parameter ret = resp.getReturnValue(); 
				Object value = ret.getValue(); 
				Date tempdate = new Date();
				long elaptime = -(date.getTime()-tempdate.getTime());
				System.out.println("ending thread " + i + " sum = " + value + " time elapsed = " + elaptime);
				addSuccess(elaptime);
			}
			else 
			{ 
				Fault fault = resp.getFault(); 
				System.err.println("Generated fault: "); 
				System.out.println (" Fault Code = " + fault.getFaultCode()); 
				System.out.println (" Fault String = " + fault.getFaultString()); 
				addFailure();
			} 
		}
		catch(Exception e)
		{
			e.printStackTrace();
			addFailure();
		}
	}
}
