001/*
002 * JPPF.
003 * Copyright (C) 2005-2015 JPPF Team.
004 * http://www.jppf.org
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.jppf.server.node;
020
021import java.util.List;
022import java.util.concurrent.atomic.AtomicBoolean;
023
024import org.jppf.classloader.AbstractJPPFClassLoader;
025import org.jppf.management.JMXServer;
026import org.jppf.node.AbstractNode;
027import org.jppf.node.protocol.*;
028import org.jppf.utils.*;
029import org.slf4j.*;
030
031/**
032 * This class is used as a container for common methods that cannot be implemented in {@link AbstractNode}.
033 * @author Laurent Cohen
034 */
035public abstract class AbstractCommonNode extends AbstractNode {
036  /**
037   * Logger for this class.
038   */
039  private static Logger log = LoggerFactory.getLogger(JPPFNode.class);
040  /**
041   * Determines whether the debug level is enabled in the logging configuration, without the cost of a method call.
042   */
043  private static boolean debugEnabled = LoggingUtils.isDebugEnabled(log);
044  /**
045   * Manages the class loaders and how they are used.
046   * @exclude
047   */
048  protected AbstractClassLoaderManager classLoaderManager = null;
049  /**
050   * Flag which determines whether a reset of the resource caches
051   * should be performed at the next opportunity.
052   * @exclude
053   */
054  AtomicBoolean cacheResetFlag = new AtomicBoolean(false);
055  /**
056   * Flag indicating whether a node shutdown or restart has been requested.
057   * @since 5.0
058   */
059  final AtomicBoolean shutdownRequestFlag = new AtomicBoolean(false);
060  /**
061   * Flag indicating whether it is a shutdown or restart that was last requested.
062   * @since 5.0
063   */
064  final AtomicBoolean restart = new AtomicBoolean(false);
065  /**
066   * Determines whetehr the node is currently processing tasks.
067   * @since 5.0
068   */
069  boolean executing = false;
070
071  /**
072   * Add management parameters to the specified bundle, before sending it back to a server.
073   * @param bundle the bundle to add parameters to.
074   * @exclude
075   */
076  protected void setupManagementParameters(final TaskBundle bundle) {
077    try {
078      JMXServer jmxServer = getJmxServer();
079      bundle.setParameter(BundleParameter.NODE_MANAGEMENT_PORT_PARAM, jmxServer.getManagementPort());
080      bundle.setParameter(BundleParameter.NODE_PROVISIONING_MASTER, isMasterNode());
081      bundle.setParameter(BundleParameter.NODE_PROVISIONING_SLAVE, isSlaveNode());
082      bundle.setParameter(BundleParameter.NODE_DOTNET_CAPABLE, isDotnetCapable());
083    } catch(Exception e) {
084      if (debugEnabled) log.debug(e.getMessage(), e);
085      else log.warn(ExceptionUtils.getMessage(e));
086    }
087  }
088
089  /**
090   * Get the main classloader for the node. This method performs a lazy initialization of the classloader.
091   * @return a <code>ClassLoader</code> used for loading the classes of the framework.
092   */
093  public AbstractJPPFClassLoader getClassLoader() {
094    return classLoaderManager.getClassLoader();
095  }
096
097  /**
098   * Set the main classloader for the node.
099   * @param cl the class loader to set.
100   * @exclude
101   */
102  public void setClassLoader(final AbstractJPPFClassLoader cl) {
103    classLoaderManager.setClassLoader(cl);
104  }
105
106  /**
107   * Get a reference to the JPPF container associated with an application uuid.
108   * @param uuidPath the uuid path containing the key to the container.
109   * @return a <code>JPPFContainer</code> instance.
110   * @throws Exception if an error occurs while getting the container.
111   * @exclude
112   */
113  public JPPFContainer getContainer(final List<String> uuidPath) throws Exception {
114    return classLoaderManager.getContainer(uuidPath);
115  }
116
117  /**
118   * Clear the resource caches of all class loaders managed by this object.
119   * @exclude
120   */
121  protected void clearResourceCachesIfRequested() {
122    if (cacheResetFlag.get()) {
123      try {
124        classLoaderManager.clearResourceCaches();
125      } finally {
126        cacheResetFlag.set(false);
127      }
128    }
129  }
130
131  /**
132   * Request a reset of the class loaders resource caches.
133   * This method merely sets a floag, the actual reset will
134   * be performed at the next opportunity, when it is safe to do so.
135   */
136  public void requestResourceCacheReset() {
137    cacheResetFlag.compareAndSet(false, true);
138  }
139
140  /**
141   * Request that the node be shut down or restarted when it is no longer executing tasks.
142   * @param restart {@code true} to restart the node, {@code false} to shut it down.
143   * @return {@code true} if the node had no pending action and the request succeeded, {@code false} otherwise.
144   * @since 5.0
145   * @exclude
146   */
147  public boolean requestShutdown(final boolean restart) {
148    if (shutdownRequestFlag.compareAndSet(false, true)) {
149      this.restart.set(restart);
150    }
151    return shutdownRequestFlag.get();
152  }
153
154  /**
155   * Cancel a previous deferred shutdown or restart request, if any.
156   * @return {@code true} if the node has a pending action and it was cancelled, {@code false} otherwise.
157   * @since 5.0
158   * @exclude
159   */
160  public boolean cancelShutdownRequest() {
161    return shutdownRequestFlag.compareAndSet(true, false);
162  }
163
164  /**
165   * Determine whether a node shurdown or restart was requested..
166   * @return {@code true} if a shudown or restart was requested, {@code false} otherwise.
167   * @since 5.0
168   * @exclude
169   */
170  public boolean isShutdownRequested() {
171    return shutdownRequestFlag.get();
172  }
173
174  /**
175   * Determine whether a restart or shutdown was requested.
176   * @return {@code true} if a restart was requested, false if a {@code shutdown} was requested.
177   * @since 5.0
178   * @exclude
179   */
180  public boolean isRestart() {
181    return restart.get();
182  }
183
184  /**
185   * Determine whether the node is currently processing tasks.
186   * @return {@code true} if the node is processing tasks, {@code false} otherwise.
187   * @since 5.0
188   * @exclude
189   */
190  public boolean isExecuting() {
191    return executing;
192  }
193
194  /**
195   * Specifiy whether the node is currently processing tasks.
196   * @param executing {@code true} to specify that the node is processing tasks, {@code false} otherwise.
197   * @since 5.0
198   * @exclude
199   */
200  public void setExecuting(final boolean executing) {
201    this.executing = executing;
202  }
203}