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 */
017package org.apache.logging.log4j.core.net;
018
019import java.io.BufferedReader;
020import java.io.InputStreamReader;
021import java.nio.charset.Charset;
022import javax.jms.JMSException;
023import javax.jms.Session;
024import javax.jms.Topic;
025import javax.jms.TopicConnection;
026import javax.jms.TopicConnectionFactory;
027import javax.jms.TopicSession;
028import javax.jms.TopicSubscriber;
029import javax.naming.Context;
030import javax.naming.InitialContext;
031import javax.naming.NamingException;
032
033/**
034 * Receives Topic messages that contain LogEvents. This implementation expects that all messages
035 * are serialized log events.
036 */
037public 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 line = stdin.readLine();
090            if (line == null || line.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}