/* * 2012-3 Red Hat Inc. and/or its affiliates and other contributors. * * Licensed 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.overlord.rtgov.samples.jbossas.activityclient; import java.util.Random; import java.util.Scanner; import javax.transaction.TransactionManager; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.type.TypeReference; import org.overlord.rtgov.activity.collector.ActivityCollector; import org.overlord.rtgov.activity.collector.CollectorContext; import org.overlord.rtgov.activity.collector.activity.server.ActivityServerLogger; import org.overlord.rtgov.activity.embedded.EmbeddedActivityCollector; import org.overlord.rtgov.activity.model.ActivityType; import org.overlord.rtgov.activity.model.soa.ResponseReceived; import org.overlord.rtgov.activity.model.soa.ResponseSent; import org.overlord.rtgov.activity.server.rest.client.RESTActivityServer; /** * This class provides a test client for sending sample activity * types to the activity server via the collector mechanism. * */ public class ActivityClient { private String _activityServerURL=null; private String _activityServerUsername=null; private String _activityServerPassword=null; private ActivityCollector _collector=null; private Random _random=new Random(); private java.util.Map<String, java.io.File> _txnFileMap= new java.util.HashMap<String, java.io.File>(); private java.util.List<String> _txnList=new java.util.Vector<String>(); private static final String[] CUSTOMERS={ "Fred", "Joe", "Jane", "Lee", "Rachel", "Tina", "Kurt", "David", "Eric", "Kev", "Gary" }; private static final ObjectMapper MAPPER=new ObjectMapper(); static { MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); MAPPER.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT); } /** * The main method. * * @param args The arguments to the client */ public static void main(String[] args) { if (args.length != 3) { System.err.println("Usage: ActivityClient <url> <filename> <numOfTxns>\r\n" +"Set numOfTxns to -1 for continous"); System.exit(1); } Scanner scanner=new Scanner(System.in); System.out.print("Enter username: "); String username = scanner.nextLine(); System.out.print("Enter password: "); String password = scanner.nextLine(); scanner.close(); ActivityClient ac=new ActivityClient(args[0], username, password); ac.init(); ac.loadTransactions(args[1]); try { ac.scheduleTxns(Integer.parseInt(args[2])); } catch (Exception e) { e.printStackTrace(); } ac.close(); } /** * The constructor initializing the server URL, username and password. * * @param url The server URL * @param username The username * @param password The password */ public ActivityClient(String url, String username, String password) { _activityServerURL = url; _activityServerUsername = username; _activityServerPassword = password; } /** * The initialization method. */ public void init() { // Initialize the activity collector _collector = new EmbeddedActivityCollector(); RESTActivityServer restc=new RESTActivityServer(); restc.setServerURL(_activityServerURL); restc.setServerUsername(_activityServerUsername); restc.setServerPassword(_activityServerPassword); ActivityServerLogger activityUnitLogger=new ActivityServerLogger(); activityUnitLogger.setActivityServer(restc); activityUnitLogger.init(); ((EmbeddedActivityCollector)_collector).setActivityUnitLogger(activityUnitLogger); ((EmbeddedActivityCollector)_collector).setCollectorContext(new TestCollectorContext()); } /** * Close the activity client. */ public void close() { // Wait before closing, to ensure all messages // have been flushed try { synchronized (this) { wait(2000); } } catch (Exception e) { e.printStackTrace(); } if (_collector instanceof EmbeddedActivityCollector) { ((EmbeddedActivityCollector)_collector).getActivityUnitLogger().close(); } } /** * This method pre-processes the supplied activity type. * * @param actType The activity type * @param txnId A transaction id */ protected void preProcess(ActivityType actType, int txnId) { if (actType instanceof org.overlord.rtgov.activity.model.soa.RPCActivityType) { org.overlord.rtgov.activity.model.soa.RPCActivityType rpcType= (org.overlord.rtgov.activity.model.soa.RPCActivityType)actType; rpcType.setMessageId(txnId+"-"+rpcType.getMessageId()); if (rpcType instanceof ResponseSent) { ((ResponseSent)rpcType).setReplyToId(txnId+"-" +((ResponseSent)rpcType).getReplyToId()); } if (rpcType instanceof ResponseReceived) { ((ResponseReceived)rpcType).setReplyToId(txnId+"-" +((ResponseReceived)rpcType).getReplyToId()); } } } /** * This method loads the information from the transaction properties * file. * * @param filename The transaction properties file */ public void loadTransactions(String filename) { try { java.io.File f=null; java.net.URL url=ClassLoader.getSystemResource(filename); if (url == null) { f = new java.io.File(filename); if (!f.exists()) { f = null; } } else { f = new java.io.File(url.getFile()); } if (f == null) { throw new java.io.FileNotFoundException(filename); } java.io.FileInputStream is=new java.io.FileInputStream(f); java.util.Properties props=new java.util.Properties(); props.load(is); is.close(); // Scan properties for file names for (String key : props.stringPropertyNames()) { if (key.endsWith(".txn")) { String fn=props.getProperty(key); String name=key.substring(0, key.length()-4); java.io.File txnFile=new java.io.File(f.getParentFile(), fn); if (!txnFile.exists()) { System.err.println("Could not find transaction ("+name +") file '"+fn+"' relative to: "+f.getParentFile()); continue; } _txnFileMap.put(name, txnFile); String w=props.getProperty(name+".weight"); if (w != null) { try { int weight=Integer.parseInt(w); for (int i=0; i < weight; i++) { _txnList.add(name); } } catch (Exception e) { e.printStackTrace(); } } else { System.err.println("Weight for '"+name+"' not found"); } } } } catch (Exception e) { e.printStackTrace(); } } /** * This method performs a random series of business transactions. * * @param num The number of transactions */ public void scheduleTxns(int num) { Random rand=new Random(System.currentTimeMillis()); int count=0; while (num == -1 || count < num) { int txnpos=Math.abs(rand.nextInt()) % _txnList.size(); int custpos=Math.abs(rand.nextInt()) % CUSTOMERS.length; send(_txnList.get(txnpos), CUSTOMERS[custpos], count); count++; } } /** * This method sends the contents of the named transaction to the activity * server. * * @param txnName The txnName * @param customer The customer * @param count The number */ public void send(String txnName, String customer, int count) { try { int id=count; java.io.InputStream is=new java.io.FileInputStream(_txnFileMap.get(txnName)); byte[] b=new byte[is.available()]; is.read(b); is.close(); // Transform any ID fields in the txn with the unique id, and set a random customer String txn=new String(b); txn = txn.replaceAll("\\{ID\\}", ""+id); txn = txn.replaceAll("\\{CUSTOMER\\}", customer); is = new java.io.ByteArrayInputStream(txn.getBytes()); java.util.List<ActivityType> actTypes= MAPPER.readValue(is, new TypeReference<java.util.List<ActivityType>>(){}); is.close(); _collector.startScope(); for (ActivityType actType : actTypes) { // Preprocess message ids preProcess(actType, id); // Check the timestamp, to see if a delay should occur if (actType.getTimestamp() > 0) { synchronized (this) { int variation=_random.nextInt() % 20; wait(actType.getTimestamp()+variation); } } _collector.record(actType); } _collector.endScope(); } catch (Exception e) { e.printStackTrace(); } } /** * A dummy collector context for use with the activity * client. * */ public class TestCollectorContext implements CollectorContext { /** * {@inheritDoc} */ public String getPrincipal() { return "ActivityClient"; } /** * {@inheritDoc} */ public String getHost() { // TODO Auto-generated method stub return "MyHost"; } /** * {@inheritDoc} */ public String getNode() { // TODO Auto-generated method stub return "MyNode"; } /** * {@inheritDoc} */ public String getPort() { // TODO Auto-generated method stub return "8080"; } /** * {@inheritDoc} */ public TransactionManager getTransactionManager() { // TODO Auto-generated method stub return null; } } }