View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements. See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache license, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License. You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the license for the specific language governing permissions and
    15   * limitations under the license.
    16   */
    17
    18  package org.apache.logging.log4j.core.net;
    19
    20  import java.util.Properties;
    21
    22  import javax.naming.Context;
    23  import javax.naming.InitialContext;
    24  import javax.naming.NamingException;
    25
    26  import org.apache.logging.log4j.core.appender.AbstractManager;
    27  import org.apache.logging.log4j.core.appender.ManagerFactory;
    28  import org.apache.logging.log4j.core.util.JndiCloser;
    29
    30  /**
    31   * JNDI {@link javax.naming.Context} manager.
    32   *
    33   * @since 2.1
    34   */
    35  public class JndiManager extends AbstractManager {
    36
    37      private static final JndiManagerFactory FACTORY = new JndiManagerFactory();
    38
    39      private final Context context;
    40
    41      private JndiManager(final String name, final Context context) {
    42          super(name);
    43          this.context = context;
    44      }
    45
    46      /**
    47       * Gets the default JndiManager using the default {@link javax.naming.InitialContext}.
    48       *
    49       * @return the default JndiManager
    50       */
    51      public static JndiManager getDefaultManager() {
    52          return getManager(JndiManager.class.getName(), FACTORY, null);
    53      }
    54
    55      /**
    56       * Gets a named JndiManager using the default {@link javax.naming.InitialContext}.
    57       * @param name the name of the JndiManager instance to create or use if available
    58       * @return a default JndiManager
    59       */
    60      public static JndiManager getDefaultManager(final String name) {
    61          return getManager(name, FACTORY, null);
    62      }
    63
    64      /**
    65       * Gets a JndiManager with the provided configuration information.
    66       *
    67       * @param initialContextFactoryName Fully qualified class name of an implementation of
    68       *                                  {@link javax.naming.spi.InitialContextFactory}.
    69       * @param providerURL               The provider URL to use for the JNDI connection (specific to the above factory).
    70       * @param urlPkgPrefixes            A colon-separated list of package prefixes for the class name of the factory
    71       *                                  class that will create a URL context factory
    72       * @param securityPrincipal         The name of the identity of the Principal.
    73       * @param securityCredentials       The security credentials of the Principal.
    74       * @param additionalProperties      Any additional JNDI environment properties to set or {@code null} for none.
    75       * @return the JndiManager for the provided parameters.
    76       */
    77      public static JndiManager getJndiManager(final String initialContextFactoryName,
    78                                               final String providerURL,
    79                                               final String urlPkgPrefixes,
    80                                               final String securityPrincipal,
    81                                               final String securityCredentials,
    82                                               final Properties additionalProperties) {
    83          final String name = JndiManager.class.getName() + '@' + JndiManager.class.hashCode();
    84          if (initialContextFactoryName == null) {
    85              return getManager(name, FACTORY, null);
    86          }
    87          final Properties properties = new Properties();
    88          properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, initialContextFactoryName);
    89          if (providerURL != null) {
    90              properties.setProperty(Context.PROVIDER_URL, providerURL);
    91          } else {
    92              LOGGER.warn("The JNDI InitialContextFactory class name [{}] was provided, but there was no associated " +
    93                  "provider URL. This is likely to cause problems.", initialContextFactoryName);
    94          }
    95          if (urlPkgPrefixes != null) {
    96              properties.setProperty(Context.URL_PKG_PREFIXES, urlPkgPrefixes);
    97          }
    98          if (securityPrincipal != null) {
    99              properties.setProperty(Context.SECURITY_PRINCIPAL, securityPrincipal);
    100             if (securityCredentials != null) {
    101                 properties.setProperty(Context.SECURITY_CREDENTIALS, securityCredentials);
    102             } else {
    103                 LOGGER.warn("A security principal [{}] was provided, but with no corresponding security credentials.",
    104                     securityPrincipal);
    105             }
    106         }
    107         if (additionalProperties != null) {
    108             properties.putAll(additionalProperties);
    109         }
    110         return getManager(name, FACTORY, properties);
    111     }
    112
    113     @Override
    114     protected void releaseSub() {
    115         JndiCloser.closeSilently(this.context);
    116     }
    117
    118     /**
    119      * Looks up a named object through this JNDI context.
    120      *
    121      * @param name name of the object to look up.
    122      * @param <T>  the type of the object.
    123      * @return the named object if it could be located.
    124      * @throws NamingException
    125      */
    126     @SuppressWarnings("unchecked")
    127     public <T> T lookup(final String name) throws NamingException {
    128         return (T) this.context.lookup(name);
    129     }
    130
    131     private static class JndiManagerFactory implements ManagerFactory<JndiManager, Properties> {
    132
    133         @Override
    134         public JndiManager createManager(final String name, final Properties data) {
    135             try {
    136                 return new JndiManager(name, new InitialContext(data));
    137             } catch (final NamingException e) {
    138                 LOGGER.error("Error creating JNDI InitialContext.", e);
    139                 return null;
    140             }
    141         }
    142     }
    143 }