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.appender.jms;
018    
019    import java.io.Serializable;
020    
021    import org.apache.logging.log4j.core.Filter;
022    import org.apache.logging.log4j.core.Layout;
023    import org.apache.logging.log4j.core.LogEvent;
024    import org.apache.logging.log4j.core.appender.AbstractAppender;
025    import org.apache.logging.log4j.core.appender.AppenderLoggingException;
026    import org.apache.logging.log4j.core.config.plugins.Plugin;
027    import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
028    import org.apache.logging.log4j.core.config.plugins.PluginElement;
029    import org.apache.logging.log4j.core.config.plugins.PluginFactory;
030    import org.apache.logging.log4j.core.layout.SerializedLayout;
031    import org.apache.logging.log4j.core.net.jms.JmsTopicManager;
032    import org.apache.logging.log4j.core.util.Booleans;
033    
034    /**
035     * Appender to write to a JMS Topic.
036     */
037    @Plugin(name = "JMSTopic", category = "Core", elementType = "appender", printObject = true)
038    public final class JmsTopicAppender extends AbstractAppender {
039    
040        private final JmsTopicManager manager;
041    
042        private JmsTopicAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout,
043                                 final JmsTopicManager manager, final boolean ignoreExceptions) {
044            super(name, filter, layout, ignoreExceptions);
045            this.manager = manager;
046        }
047    
048        /**
049         * Actual writing occurs here.
050         * <p/>
051         * @param event The LogEvent.
052         */
053        @Override
054        public void append(final LogEvent event) {
055            try {
056                manager.send(getLayout().toSerializable(event));
057            } catch (final Exception ex) {
058                throw new AppenderLoggingException(ex);
059            }
060        }
061    
062        /**
063         * Create a JmsTopicAppender.
064         * @param name The name of the Appender.
065         * @param factoryName The fully qualified class name of the InitialContextFactory.
066         * @param providerURL The URL of the provider to use.
067         * @param urlPkgPrefixes A colon-separated list of package prefixes for the class name of the factory class that
068         * will create a URL context factory
069         * @param securityPrincipalName The name of the identity of the Principal.
070         * @param securityCredentials The security credentials of the Principal.
071         * @param factoryBindingName The name to locate in the Context that provides the TopicConnectionFactory.
072         * @param topicBindingName The name to use to locate the Topic.
073         * @param userName The userid to use to create the Topic Connection.
074         * @param password The password to use to create the Topic Connection.
075         * @param layout The layout to use (defaults to SerializedLayout).
076         * @param filter The Filter or null.
077         * @param ignore If {@code "true"} (default) exceptions encountered when appending events are logged; otherwise
078         *               they are propagated to the caller.
079         * @return The JmsTopicAppender.
080         */
081        @PluginFactory
082        public static JmsTopicAppender createAppender(
083                @PluginAttribute("name") final String name,
084                @PluginAttribute("factoryName") final String factoryName,
085                @PluginAttribute("providerURL") final String providerURL,
086                @PluginAttribute("urlPkgPrefixes") final String urlPkgPrefixes,
087                @PluginAttribute("securityPrincipalName") final String securityPrincipalName,
088                @PluginAttribute("securityCredentials") final String securityCredentials,
089                @PluginAttribute("factoryBindingName") final String factoryBindingName,
090                @PluginAttribute("topicBindingName") final String topicBindingName,
091                @PluginAttribute("userName") final String userName,
092                @PluginAttribute("password") final String password,
093                @PluginElement("Layout") Layout<? extends Serializable> layout,
094                @PluginElement("Filters") final Filter filter,
095                @PluginAttribute("ignoreExceptions") final String ignore) {
096    
097            if (name == null) {
098                LOGGER.error("No name provided for JmsQueueAppender");
099                return null;
100            }
101            final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
102            final JmsTopicManager manager = JmsTopicManager.getJmsTopicManager(factoryName, providerURL, urlPkgPrefixes,
103                securityPrincipalName, securityCredentials, factoryBindingName, topicBindingName, userName, password);
104            if (manager == null) {
105                return null;
106            }
107            if (layout == null) {
108                layout = SerializedLayout.createLayout();
109            }
110            return new JmsTopicAppender(name, filter, layout, manager, ignoreExceptions);
111        }
112    }