001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.activemq.benchmark;
018    
019    import java.text.NumberFormat;
020    import java.util.ArrayList;
021    import java.util.List;
022    import java.util.concurrent.atomic.AtomicInteger;
023    
024    import javax.jms.Connection;
025    import javax.jms.Destination;
026    import javax.jms.JMSException;
027    import javax.jms.Session;
028    
029    import org.apache.activemq.ActiveMQConnectionFactory;
030    import org.apache.activemq.util.IdGenerator;
031    
032    /**
033     * Abstract base class for some simple benchmark tools
034     * 
035     * @author James Strachan
036     * @version $Revision$
037     */
038    public class BenchmarkSupport {
039    
040        protected int connectionCount = 1;
041        protected int batch = 1000;
042        protected Destination destination;
043        protected String[] subjects;
044    
045        private boolean topic = true;
046        private boolean durable;
047        private ActiveMQConnectionFactory factory;
048        private String url;
049        private int counter;
050        private List<Object> resources = new ArrayList<Object>();
051        private NumberFormat formatter = NumberFormat.getInstance();
052        private AtomicInteger connectionCounter = new AtomicInteger(0);
053        private IdGenerator idGenerator = new IdGenerator();
054        private boolean timerLoop;
055    
056        public BenchmarkSupport() {
057        }
058    
059        public void start() {
060            System.out.println("Using: " + connectionCount + " connection(s)");
061            subjects = new String[connectionCount];
062            for (int i = 0; i < connectionCount; i++) {
063                subjects[i] = "BENCHMARK.FEED" + i;
064            }
065            if (useTimerLoop()) {
066                Thread timer = new Thread() {
067                    public void run() {
068                        timerLoop();
069                    }
070                };
071                timer.start();
072            }
073        }
074    
075        public String getUrl() {
076            return url;
077        }
078    
079        public void setUrl(String url) {
080            this.url = url;
081        }
082    
083        public boolean isTopic() {
084            return topic;
085        }
086    
087        public void setTopic(boolean topic) {
088            this.topic = topic;
089        }
090    
091        public ActiveMQConnectionFactory getFactory() {
092            return factory;
093        }
094    
095        public void setFactory(ActiveMQConnectionFactory factory) {
096            this.factory = factory;
097        }
098    
099        public void setSubject(String subject) {
100            connectionCount = 1;
101            subjects = new String[] {
102                subject
103            };
104        }
105    
106        public boolean isDurable() {
107            return durable;
108        }
109    
110        public void setDurable(boolean durable) {
111            this.durable = durable;
112        }
113    
114        public int getConnectionCount() {
115            return connectionCount;
116        }
117    
118        public void setConnectionCount(int connectionCount) {
119            this.connectionCount = connectionCount;
120        }
121    
122        protected Session createSession() throws JMSException {
123            if (factory == null) {
124                factory = createFactory();
125            }
126            Connection connection = factory.createConnection();
127            int value = connectionCounter.incrementAndGet();
128            System.out.println("Created connection: " + value + " = " + connection);
129            if (durable) {
130                connection.setClientID(idGenerator.generateId());
131            }
132            addResource(connection);
133            connection.start();
134    
135            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
136            addResource(session);
137            return session;
138        }
139    
140        protected ActiveMQConnectionFactory createFactory() {
141            ActiveMQConnectionFactory answer = new ActiveMQConnectionFactory(getUrl());
142            return answer;
143        }
144    
145        protected synchronized void count(int count) {
146            counter += count;
147            /*
148             * if (counter > batch) { counter = 0; long current =
149             * System.currentTimeMillis(); double end = current - time; end /= 1000;
150             * time = current; System.out.println("Processed " + batch + " messages
151             * in " + end + " (secs)"); }
152             */
153        }
154    
155        protected synchronized int resetCount() {
156            int answer = counter;
157            counter = 0;
158            return answer;
159        }
160    
161        protected void timerLoop() {
162            int times = 0;
163            int total = 0;
164            int dumpVmStatsFrequency = 10;
165            Runtime runtime = Runtime.getRuntime();
166    
167            while (true) {
168                try {
169                    Thread.sleep(1000);
170                } catch (InterruptedException e) {
171                    e.printStackTrace();
172                }
173                int processed = resetCount();
174                double average = 0;
175                if (processed > 0) {
176                    total += processed;
177                    times++;
178                }
179                if (times > 0) {
180                    average = total / (double) times;
181                }
182    
183                System.out.println(getClass().getName() + " Processed: " + processed + " messages this second. Average: " + average);
184    
185                if ((times % dumpVmStatsFrequency) == 0 && times != 0) {
186                    System.out.println("Used memory: " + asMemoryString(runtime.totalMemory() - runtime.freeMemory()) + " Free memory: " + asMemoryString(runtime.freeMemory()) + " Total memory: "
187                                       + asMemoryString(runtime.totalMemory()) + " Max memory: " + asMemoryString(runtime.maxMemory()));
188                }
189    
190            }
191        }
192    
193        protected String asMemoryString(long value) {
194            return formatter.format(value / 1024) + " K";
195        }
196    
197        protected boolean useTimerLoop() {
198            return timerLoop;
199        }
200    
201        protected Destination createDestination(Session session, String subject) throws JMSException {
202            if (topic) {
203                return session.createTopic(subject);
204            } else {
205                return session.createQueue(subject);
206            }
207        }
208    
209        protected void addResource(Object resource) {
210            resources.add(resource);
211        }
212    
213        public int getCounter() {
214            return counter;
215        }
216    
217        public void setTimerLoop(boolean timerLoop) {
218            this.timerLoop = timerLoop;
219        }
220    
221        protected static boolean parseBoolean(String text) {
222            return text.equalsIgnoreCase("true");
223        }
224    }