All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.diagnostics.context.impl.ContextManagerImpl Maven / Gradle / Ivy

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package org.glassfish.diagnostics.context.impl;

import org.glassfish.contextpropagation.*;
import org.glassfish.diagnostics.context.Context;

import org.glassfish.contextpropagation.spi.ContextMapHelper;
import org.glassfish.diagnostics.context.ContextManager;
import org.glassfish.hk2.api.Rank;
import org.glassfish.logging.annotation.LogMessageInfo;
import org.jvnet.hk2.annotations.Service;

import java.util.EnumSet;
import java.util.HashSet;
import java.util.Set;

import java.util.logging.Level;
import java.util.logging.Logger;


/**
 * Default implementation of ContextManager.
 */
@Service
@Rank(500)
public class ContextManagerImpl
  implements ContextManager{

  private static final String CLASS_NAME = ContextManagerImpl.class.getName();

 /**
  * Implementation of Location for those (hopfefully) rare occasions
  * in which we need to hand back to our fans a Context that could
  * not be found or constructed in the usual way.
  */
  private static class HackedUnavailableLocation extends Location{
    HackedUnavailableLocation()
    {
      super((View)null);
    }

    public String getLocationId(){
      return "";
    }

    public String getOrigin(){
      return "";
    }
  }

 /**
  * Context implementation for those (hopfefully) rare occasions
  * in which we need to hand back to our fans a Context that could
  * not be found or constructed in the usual way.
  */
  private static final Context dummyContextInstance = new Context()
  {
    private final Location sLocation = new HackedUnavailableLocation();

    @Override
    public Location getLocation() {
      return sLocation;
    }

    @Override
    public  T put(String name, String value, boolean propagates) {
      return null;
    }

    @Override
    public  T put(String name, Number value, boolean propagates) {
      return null;
    }

    @Override
    public  T remove(String name) {
      return null;
    }

    @Override
    public  T get(String name) {
      return null;
    }
  };

  @LogMessageInfo(
    message = "Can not fulfill request to get diagnostics context.",
    comment = "A diagnostics context can not be found (or created).",
    cause   = "",
    action  = "",
    level   ="WARNING")
  private static final String CAN_NOT_GET_CONTEXT_AS_DIAG_3000 = "NCLS-DIAG-03000";

  @LogMessageInfo(
    message = "An exception has prevented a diagnostics context from being created.",
    comment = "A diagnostics context can not be found or created.",
    cause   = "(see underlying exception)",
    action  = "(see underlying exception)",
    level   = "WARNING")
  private static final String EXCEPTION_CREATING_CONTEXT_AS_DIAG_3001 = "NCLS-DIAG-03001";

  /**
   *  Propagation modes for data that is set as propagates in the put
   *  methods.
   *
   *  This must always match the set of modes returned from
   *  PropagationMode.defaultSetOneway to guarantee that the data
   *  of this ViewCapable are propagated over the same set of modes as
   *  the Location. We do not reference defaultSetOneway because
   *  we need to avoid propagation modes other than those we specify below.
   */
  static final EnumSet sfGlobalPropagationModes =
      EnumSet.of(PropagationMode.THREAD,
                 PropagationMode.RMI,
                 PropagationMode.JMS_QUEUE,
                 PropagationMode.SOAP,
                 PropagationMode.MIME_HEADER,
                 PropagationMode.ONEWAY);
  static final EnumSet sfLocalPropagationModes =
      EnumSet.of(PropagationMode.LOCAL);

  // Check that PropagationMode.defaultSetOneway() and sfGlobalPropagationModes
  // match (if they do not then we lose data integrity).
  static
  {
    Set tmp = new HashSet(PropagationMode.defaultSetOneway());
    tmp.removeAll(sfGlobalPropagationModes);
    if (!tmp.isEmpty())
    {
      throw new IllegalStateException(
        "Mismatched propagation modes - PropagationMode.defaultSetOneWay()" +
        " has more modes than sfGlobalPropagationModes.");
    }

    tmp = new HashSet(sfGlobalPropagationModes);
    tmp.removeAll(PropagationMode.defaultSetOneway());
    if (!tmp.isEmpty())
    {
      throw new IllegalStateException(
        "Mismatched propagation modes - sfGlobalPropagationModes has more" +
        " modes than PropagationMode.defaultSetOneWay().");
    }
  }

 // Register the DiagnosticContextViewFactory with the contextpropagation
 // framework.
  static{
    LOGGER.entering(CLASS_NAME,
      "");
    ContextMapHelper.registerContextFactoryForPrefixNamed(
      WORK_CONTEXT_KEY,
      new DiagnosticContextViewFactory());
   LOGGER.exiting(CLASS_NAME,
      "");
 }

  /**
   * ContextViewFactory class implementation that fulfills a contract
   * with contextpropagation package.
   */
  private static class DiagnosticContextViewFactory
      implements ContextViewFactory {

    @Override // ContextViewFactory
    public ContextImpl createInstance(final View view)
    {
      LOGGER.entering(CLASS_NAME, "createInstance(View)");
      final Location location =
          ContextMapHelper.getScopeAwareContextMap().getLocation();
      ContextImpl retVal = new ContextImpl(view, location);
      LOGGER.exiting(CLASS_NAME, "createInstance(View)", retVal.toString());
      return retVal;
    }

    @Override // ContextViewFactory
    public EnumSet getPropagationModes(){
      return sfGlobalPropagationModes;
    }
  }

  @Override // from ContextManager
  public Context getContext()
  {
    LOGGER.entering(CLASS_NAME, "getContext()");

    Context retVal = null;

    ContextMap contextMap = ContextMapHelper.getScopeAwareContextMap();
    try{
      retVal = contextMap.get(WORK_CONTEXT_KEY);
      if (retVal == null){
        LOGGER.logp(Level.FINEST, CLASS_NAME, "getContext()",
          "No ContextImpl found in ContextMap, creating a new one.");
        ContextImpl contextImpl = contextMap.createViewCapable(WORK_CONTEXT_KEY);
        retVal = contextImpl;
      }
    }
    catch (InsufficientCredentialException isce)
    {
      // Nothing we can do to remedy isce so log the exception and move on

      // Do we return null or a dummy Context implementation?
      // Most callers won't be looking too closely at the context and
      // they probably won't want to concern themselves with problems
      // bubbling up from the contextpropagation layer, so a dummy
      // Context is preferred - the buck stops here!
      LOGGER.logp(Level.WARNING, CLASS_NAME, "getContext()",
                     EXCEPTION_CREATING_CONTEXT_AS_DIAG_3001, isce);
      retVal = dummyContextInstance;
    }

    if (retVal == null)
    {
      LOGGER.logp(Level.WARNING, CLASS_NAME, "getContext()",
                     CAN_NOT_GET_CONTEXT_AS_DIAG_3000);
      retVal = dummyContextInstance;
    }

    LOGGER.exiting(CLASS_NAME, "getContext()", retVal);

    return retVal;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy