001: /*
002: * ChainBuilder ESB
003: * Visual Enterprise Integration
004: *
005: * Copyright (C) 2006 Bostech Corporation
006: *
007: * This program is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License as published by the
009: * Free Software Foundation; either version 2 of the License, or (at your option)
010: * any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
014: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
015: * for more details.
016: *
017: * You should have received a copy of the GNU General Public License along with
018: * this program; if not, write to the Free Software Foundation, Inc.,
019: * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: *
021: *JmsUtil.java
022: *LPS
023: *Dec 14, 2007
024: */
025: package com.bostechcorp.cbesb.runtime.jms;
026:
027: import java.io.FileInputStream;
028: import java.io.FileNotFoundException;
029: import java.io.IOException;
030: import java.io.InputStream;
031: import java.util.Arrays;
032: import java.util.Enumeration;
033: import java.util.Iterator;
034: import java.util.List;
035: import java.util.Properties;
036:
037: import javax.jms.Message;
038:
039: import org.apache.commons.logging.Log;
040: import org.apache.commons.logging.LogFactory;
041:
042: import com.bostechcorp.cbesb.common.util.EsbPathHelper;
043:
044: /**
045: * @author LPS
046: *
047: */
048: public class JMSUtility {
049: //TODO:
050: //MID does not work at all, need to implement it, as comma separated
051: //id list and also like interval
052: //
053: protected static Log log = LogFactory.getLog(JMSUtility.class);
054: protected static String CONSTANTS_INITIALCONTEXTFACTORY = "InitialContextFactory";
055: protected static String CONSTANTS_PROVIDERURL = "ProviderUrl";
056: protected static String CONSTANTS_CONNECTIONFACTORYNAME = "ConnectionFactoryName";
057: protected static String CONSTANTS_USERNAME = "UserName";
058: protected static String CONSTANTS_PASSWORD = "Password";
059: private static final String PROPERTY_FILE = "jms.properties";
060:
061: /*Some operations identifiers*/
062: private static final String[] LIST_LITERALS = { "-list", "-l",
063: "-lst" };
064: private static final String[] MOVE_LITERALS = { "-move", "-m",
065: "-mv", };
066: private static final String[] CLEAN_LITERALS = { "-clean", "-c",
067: "-cln" };
068: private static final String[] SOURCE_LITERALS = { "-source", "-s",
069: "-src" };
070: private static final String[] DESTINATION_LITERALS = {
071: "-destination", "-d", "-dest" };
072: private static final String[] FIRST_LITERALS = { "-first", "-f",
073: "-fst" };
074: private static final String[] ALL_LITERALS = { "-all", "-a" };
075: private static final String[] MID_LITERALS = { "-MID", "-mid" };
076:
077: private static final String HELP = ""
078: + "\n"
079: + " JMSUtility -operation [-MID mid] -s sourceQueue [-d destinationQueue] [-all] [-first nm]"
080: + "\n\n"
081: + " Where the parameters are :"
082: + "\n"
083: + "--------------------------\n"
084: + " -list(-l;-lst) - print out the content of the source queue"
085: + "\n"
086: + " -move(-m;-mv) - move all (or first nm) mesages from the source queue \n\t\t to destination queue"
087: + "\n"
088: + " -clean(-c) - removed all (or first nm) mesages from the source queue"
089: + "\n\n"
090: + " -MID(-mid) - Message ID as comma separated list or interval of Message ID in the source queue. \n"
091: + " -source(-s;-src) - name of the source queue"
092: + "\n"
093: + " -destination(-d;-dest) - name of the destination queue, used only for move operation"
094: + "\n"
095: + " -all - execute operation on all messages from the queue; (default behavior)"
096: + "\n"
097: + " -first [nm] - execute operation on the first nm mesages in the queue."
098: + "\n"
099: + " If not specified then the operation will be executed as -all parameter"
100: + "\n" + " " + "\n";
101: /*Some parameters*/
102: private String operation = "";
103: private String source = "";
104: private String destination = "";
105: private String first = "-1";
106: private String mid = "";
107:
108: String initialContextFactory = null;
109: String providerUrl = null;
110: String connectionFactoryName = null;
111: String userName = null;
112: String password = null;
113: String destinationStyle = "queue";
114:
115: /**
116: * JmsUtil -[operation] -s [sourceQueue] [-d destinationQueue] [-first nn]
117: *
118: * <b>Operations</b>:
119: * <p>-list (-l;-lst) - print out the content of the source queue
120: * <p>-move (-m;-mv) - move
121: * <p>-clean (-c) - removed all (or first nn) mesages from the source queue
122: *
123: * <b>Parameters:</b>
124: * <p>-source (-s;-src) - name of the queue to be
125: * <p>-destination (-d;-dest)
126: * <p>-all - execute operation on all messages from the queue; default
127: * <p>-first [nn] - execute opeeration on the first nn
128: * mesages in the queue. If not specified it will be
129: * executed as -all
130: *
131: * @param args
132: */
133: public static void main(String[] args) {
134: JMSUtility util = new JMSUtility();
135: try {
136: util.parseArguments(args);
137: util.executeOperation();
138: } catch (Exception e) {
139: log.info(e);
140: log.info(HELP);
141: }
142: }
143:
144: private void executeOperation() {
145: debug();
146: try {
147: if (in(operation, LIST_LITERALS))
148: list();
149: else if (in(operation, MOVE_LITERALS))
150: move();
151: else if (in(operation, CLEAN_LITERALS))
152: clean();
153: else
154: log.info(HELP);
155: } catch (Exception e) {
156: log.error("Exception in executing the operation +'"
157: + operation + "': ", e);
158: }
159: }
160:
161: private void debug() {
162: log.info("Operation=" + operation);
163: log.info("Source=" + source);
164: log.info("Destination=" + destination);
165: log.info("First=" + first);
166: }
167:
168: /**
169: * execute clean operation
170: * @throws Exception
171: */
172: private void clean() throws Exception {
173:
174: JMSHandler jmsHandler = null;
175: //parameters check
176: if (source.equals(""))
177: throw new Exception(
178: "The source queue is empty. Please specify the source queue to be cleaned.");
179: //
180: try {
181: init();
182: jmsHandler = new JMSConsumerHandler(initialContextFactory,
183: providerUrl, connectionFactoryName, userName,
184: password, destinationStyle, source, null, false,
185: null);
186:
187: int count = Integer.parseInt(first);
188: int i = jmsHandler.cleanQueuedMessages("", count);
189: log.info(i + " messages in queue '" + source
190: + "' have been removed.");
191: } catch (Exception e) {
192: log.error("Failed to execute the 'Clean' operation: ", e);
193: } finally {
194: if (jmsHandler != null) {
195: jmsHandler.close();
196: }
197: }
198: }
199:
200: /**
201: * Execute move operation
202: */
203: private void move() {
204: JMSHandler jmsHandler = null;
205: try {
206: init();
207: //parameters check
208: if (source.equals(""))
209: throw new Exception(
210: "The source queue is empty. Please specify the source queue.");
211: if (destination.equals(""))
212: throw new Exception(
213: "The destination queue is empty. Please specify destination queue.");
214: //
215: jmsHandler = new JMSHandler(initialContextFactory,
216: providerUrl, connectionFactoryName, userName,
217: password, destinationStyle, source, destination,
218: null, false, null);
219:
220: StringBuffer buf = new StringBuffer("");
221: if (mid.length() > 0) {
222: if (mid.indexOf(",") > -1) {
223: buf.append("JmsMessageID in (").append(mid).append(
224: ")");
225: } else if (mid.indexOf("-") > -1) {
226: String[] mids = mid.split("-");
227: if (mids.length > 1) {
228: buf.append("JmsMessageID between ").append(
229: mids[0]).append(" and ")
230: .append(mids[1]);
231: }
232: }
233: }
234: String filter = "";
235: if (buf.length() > 0) {
236: filter = "" + buf.toString();
237: }
238: int count = Integer.parseInt(first);
239: int i = jmsHandler.move(filter, count);
240:
241: log.info("Move " + i + " messages in from '" + source
242: + "' to '" + destination + "'.");
243: } catch (Exception e) {
244: //e.printStackTrace();
245: log.error("Failed to execute 'Move' operation: ", e);
246: } finally {
247: if (jmsHandler != null) {
248: jmsHandler.close();
249: }
250:
251: }
252: }
253:
254: /**
255: * Execute list Operation
256: * @throws Exception
257: */
258: private void list() throws Exception {
259: JMSHandler jmsHandler = null;
260: //parameters check
261: if (source.equals(""))
262: throw new Exception(
263: "The source queue is empty. Please specify the source queue to be listed.");
264: //
265: try {
266: init();
267: jmsHandler = new JMSConsumerHandler(initialContextFactory,
268: providerUrl, connectionFactoryName, userName,
269: password, destinationStyle, source, null, false,
270: null);
271:
272: Enumeration list = jmsHandler.listQueuedMessages();
273: int count = Integer.parseInt(first);
274: int i = 0;
275: while (list.hasMoreElements()) {
276: Message message = (Message) list.nextElement();
277: log.info("MessageID=" + message.getJMSMessageID()
278: + ";content="
279: + jmsHandler.messageToString(message));
280: i++;
281: if (count > -1 && i == count)
282: break;
283:
284: }
285:
286: log.info("There are " + i + " messages in queue '"
287: + source + "'.");
288: } catch (Exception e) {
289: log.error("Failed to execute the 'List' operation: ", e);
290: //e.printStackTrace();
291: } finally {
292: if (jmsHandler != null) {
293: jmsHandler.close();
294: }
295: }
296:
297: }
298:
299: /**
300: * return true if argumets are right.
301: * @param arg
302: * @return
303: * It is deprecated due to the very Rigid position oriented argument requiremetnts.
304: * Use parseArguments instead
305: */
306: @Deprecated
307: public boolean processArguments(String[] arg) {
308: if (arg.length == 0) {
309: log.info("Please specify an operation.");
310: return false;
311: }
312: // process 1st argument - operation
313: if (in(arg[0], LIST_LITERALS)) {
314: operation = LIST_LITERALS[0];
315: } else if (in(arg[0], MOVE_LITERALS)) {
316: operation = MOVE_LITERALS[0];
317: } else if (in(arg[0], CLEAN_LITERALS)) {
318: operation = CLEAN_LITERALS[0];
319: } else {
320: log
321: .info("Operation '"
322: + arg[0]
323: + "' not supported. See the help for more details.");
324: return false;
325: }
326: // process 2nd argument -source
327: // process 3rd argument -source name
328:
329: int index = 1;
330: if (in(operation, LIST_LITERALS)) {
331: if (in(arg[index], SOURCE_LITERALS)) {
332: if (arg.length < index + 2) {
333: log.info("Please specify the source.");
334: return false;
335: }
336: index++;
337: source = arg[index++];
338: } else {
339: if (arg.length > index + 1) {
340: source = arg[index++];
341: } else {
342: log
343: .info("Specify -source and the name of source queue. See the help for more details.");
344: return false;
345: }
346: }
347:
348: }
349: // process 4th argument
350:
351: else if (in(operation, MOVE_LITERALS)) // check for destination
352: {
353:
354: if (in(arg[index], MID_LITERALS)) {
355: if (arg.length < index + 2) {
356: log.info("Please specify the MID.");
357: return false;
358: }
359: index++;
360: mid = arg[index++];
361:
362: }
363:
364: if (in(arg[index], SOURCE_LITERALS)) {
365: if (arg.length < index + 2) {
366: log.info("Please specify the source.");
367: return false;
368: }
369: index++;
370: source = arg[index++];
371: } else {
372: if (arg.length > index + 1) {
373: source = arg[index++];
374: } else {
375: log
376: .info("Specify -source and the name of source queue. See the help for more details.");
377: return false;
378: }
379: }
380: if (in(arg[index], DESTINATION_LITERALS)) {
381: if (arg.length < index + 2) {
382: log.info("Please specify the destination.");
383: return false;
384: }
385: index++;
386: destination = arg[index++];
387: } else {
388: if (arg.length > index + 1) {
389: destination = arg[index++];
390: } else {
391: log
392: .info("Specify -destination and the name of detination queue. See the help for more details.");
393: return false;
394: }
395: }
396: }
397:
398: // check for -first nn argument
399: if (arg.length > index + 1) {
400: if (in(arg[index], FIRST_LITERALS)) {
401: if (arg.length < index + 2) {
402: log
403: .info("Please specify a non-negative integer for -nm.");
404: return false;
405: }
406: index++;
407: first = arg[index++];
408: } else {
409: first = "-1";
410: }
411: }
412: // check for -first nn arfument
413: return true;
414: }
415:
416: private static boolean in(String s, String[] list) {
417: for (int i = 0; i < list.length; i++) {
418: if (s.equalsIgnoreCase(list[i]))
419: return true;
420: }
421: return false;
422: }
423:
424: public Properties getProperties() throws FileNotFoundException,
425: IOException {
426: Properties result = new Properties();
427: InputStream inStream;
428: try {
429: inStream = new FileInputStream(EsbPathHelper
430: .getCbesbHomeDir()
431: + "/config/" + PROPERTY_FILE);
432: } catch (FileNotFoundException e) {
433: inStream = JMSUtility.class.getClassLoader()
434: .getResourceAsStream(JMSUtility.PROPERTY_FILE);
435: if (inStream == null) {
436: //if the classloader also does not find the resource then
437: //the file really does not exist; throw the caught exception.
438: //actually the file will always exist in source it should exist
439: throw e;
440: }
441: }
442: result.load(inStream);
443: return result;
444: }
445:
446: private void init() throws FileNotFoundException, IOException {
447:
448: Properties properties = getProperties();
449: initialContextFactory = properties
450: .getProperty(CONSTANTS_INITIALCONTEXTFACTORY);
451: providerUrl = properties.getProperty(CONSTANTS_PROVIDERURL);
452: connectionFactoryName = properties
453: .getProperty(CONSTANTS_CONNECTIONFACTORYNAME);
454: userName = properties.getProperty(CONSTANTS_USERNAME);
455: password = properties.getProperty(CONSTANTS_PASSWORD);
456: }
457:
458: /**
459: * @param args
460: */
461: private void parseArguments(String[] args) throws Exception {
462: List<String> s = Arrays.asList(args);
463: /*
464: * private static final String[] LIST_LITERALS={"-list", "-l", "-lst"};
465: * private static final String[] MOVE_LITERALS={"-move", "-m", "-mv",};
466: * private static final String[] CLEAN_LITERALS={"-clean", "-c",
467: * "-cln"}; private static final String[] SOURCE_LITERALS={"-source",
468: * "-s", "-src"}; private static final String[]
469: * DESTINATION_LITERALS={"-destination", "-d", "-dest"}; private static
470: * final String[] FIRST_LITERALS={"-first", "-f", "-fst"}; private
471: * static final String[] MID_LITERALS={"-MID","-mid"};
472: */
473: Iterator<String> i = s.iterator();
474: String string = "";
475: String next = "";
476: boolean checkNext = true;
477: while (i.hasNext()) {
478: if (checkNext) {
479: string = i.next();
480: } else {
481: string = next;
482: }
483: // check for operations
484: if (in(string, LIST_LITERALS)) {
485: operation = LIST_LITERALS[0];
486: } else if (in(string, MOVE_LITERALS)) {
487: operation = MOVE_LITERALS[0];
488: } else if (in(string, CLEAN_LITERALS)) {
489: operation = CLEAN_LITERALS[0];
490: } else
491: // check for source sintagm
492: if (in(string, SOURCE_LITERALS)) {
493: if (i.hasNext()) {
494: next = i.next();
495: if (next.startsWith("-")) {
496: source = null;
497: checkNext = false;
498: } else {
499: source = next;
500: checkNext = true;
501: }
502: } else
503: throw new Exception("The '-source' not specified.");
504: } else
505: // check for destination sintagm
506: if (in(string, DESTINATION_LITERALS)) {
507: if (i.hasNext()) {
508: next = i.next();
509: if (next.startsWith("-")) {
510: destination = null;
511: checkNext = false;
512: } else {
513: destination = next;
514: checkNext = true;
515: }
516: } else
517: throw new Exception(
518: "The '-destination' not specified.");
519: } else
520: // check for first sintagm
521: if (in(string, FIRST_LITERALS)) {
522: if (i.hasNext()) {
523: next = i.next();
524: if (next.startsWith("-")) {
525: first = null;
526: checkNext = false;
527: } else {
528: first = next;
529: try {
530: Long.parseLong(first);
531: } catch (Exception e) {
532: throw new Exception(
533: "The Parameter '-first' is not a number");
534: }
535: checkNext = true;
536: }
537: } else
538: throw new Exception("The '-first' not specified.");
539: } else
540: //check for -all
541: if (in(string, ALL_LITERALS)) {
542: first = "-1";
543: } else
544: //parameter unknown
545: {
546: throw new Exception("Unknown parameter '" + string
547: + "'.");
548: }
549: }
550: }
551: }
|