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.logging.log4j.core.net;
018    
019    import javax.jms.JMSException;
020    import javax.jms.Session;
021    import javax.jms.Topic;
022    import javax.jms.TopicConnection;
023    import javax.jms.TopicConnectionFactory;
024    import javax.jms.TopicSession;
025    import javax.jms.TopicSubscriber;
026    import javax.naming.Context;
027    import javax.naming.InitialContext;
028    import javax.naming.NamingException;
029    import java.io.BufferedReader;
030    import java.io.InputStreamReader;
031    import java.nio.charset.Charset;
032    
033    /**
034     * Receives Topic messages that contain LogEvents. This implementation expects that all messages
035     * are serialized log events.
036     */
037    public class JMSTopicReceiver extends AbstractJMSReceiver {
038    
039        /**
040         * Constructor.
041         * @param tcfBindingName The TopicConnectionFactory binding name.
042         * @param topicBindingName The Topic binding name.
043         * @param username The userid to connect to the topic.
044         * @param password The password to connect to the topic.
045         */
046        public JMSTopicReceiver(final String tcfBindingName, final String topicBindingName, final String username,
047                                final String password) {
048            try {
049                final Context ctx = new InitialContext();
050                TopicConnectionFactory topicConnectionFactory;
051                topicConnectionFactory = (TopicConnectionFactory) lookup(ctx, tcfBindingName);
052                final TopicConnection topicConnection = topicConnectionFactory.createTopicConnection(username, password);
053                topicConnection.start();
054                final TopicSession topicSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
055                final Topic topic = (Topic) ctx.lookup(topicBindingName);
056                final TopicSubscriber topicSubscriber = topicSession.createSubscriber(topic);
057                topicSubscriber.setMessageListener(this);
058            } catch (final JMSException e) {
059                logger.error("Could not read JMS message.", e);
060            } catch (final NamingException e) {
061                logger.error("Could not read JMS message.", e);
062            } catch (final RuntimeException e) {
063                logger.error("Could not read JMS message.", e);
064            }
065        }
066    
067        /**
068         * Main startup for the receiver.
069         * @param args The command line arguments.
070         * @throws Exception if an error occurs.
071         */
072        public static void main(final String[] args) throws Exception {
073            if (args.length != 4) {
074                usage("Wrong number of arguments.");
075            }
076    
077            final String tcfBindingName = args[0];
078            final String topicBindingName = args[1];
079            final String username = args[2];
080            final String password = args[3];
081    
082            new JMSTopicReceiver(tcfBindingName, topicBindingName, username, password);
083    
084            final Charset enc = Charset.defaultCharset();
085            final BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in, enc));
086            // Loop until the word "exit" is typed
087            System.out.println("Type \"exit\" to quit JMSTopicReceiver.");
088            while (true) {
089                final String s = stdin.readLine();
090                if (s.equalsIgnoreCase("exit")) {
091                    System.out.println("Exiting. Kill the application if it does not exit "
092                        + "due to daemon threads.");
093                    return;
094                }
095            }
096        }
097    
098        private static void usage(final String msg) {
099            System.err.println(msg);
100            System.err.println("Usage: java " + JMSTopicReceiver.class.getName()
101                + " TopicConnectionFactoryBindingName TopicBindingName username password");
102            System.exit(1);
103        }
104    }