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

org.jppf.client.AbstractJPPFClient Maven / Gradle / Ivy

The newest version!
/*
 * JPPF.
 * Copyright (C) 2005-2019 JPPF Team.
 * http://www.jppf.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jppf.client;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.*;
import java.util.regex.Pattern;

import org.jppf.client.event.*;
import org.jppf.utils.*;
import org.jppf.utils.collections.*;
import org.slf4j.*;

/**
 * This class provides an API to submit execution requests and administration commands,
 * and request server information data.
* It has its own unique identifier, used by the nodes, to determine whether classes from * the submitting application should be dynamically reloaded or not, depending on whether * the uuid has changed or not. * @author Laurent Cohen */ public abstract class AbstractJPPFClient implements ClientConnectionStatusListener, AutoCloseable { /** * Logger for this class. */ private static Logger log = LoggerFactory.getLogger(AbstractJPPFClient.class); /** * Determines whether the debug level is enabled in the logging configuration, without the cost of a method call. */ private static boolean debugEnabled = LoggingUtils.isDebugEnabled(log); /** * Name of the default SerializationHelper implementation class. */ static String SERIALIZATION_HELPER_IMPL = "org.jppf.utils.SerializationHelperImpl"; /** * Name of the SerializationHelper implementation class for the JCA connector. * @exclude */ protected static String JCA_SERIALIZATION_HELPER = "org.jppf.jca.serialization.JcaSerializationHelperImpl"; /** * A sequence number used as an id for connection pools. */ final AtomicInteger poolSequence = new AtomicInteger(0); /** * Contains all the connections pools in ascending priority order. */ final CollectionMap pools = new LinkedListSortedMap<>(new DescendingIntegerComparator()); /** * Unique universal identifier for this JPPF client. */ private String uuid = null; /** * List of listeners to this JPPF client. */ private final List connectionPoolListeners = new CopyOnWriteArrayList<>(); /** * Determines whether this JPPF client is closed. */ final AtomicBoolean closed = new AtomicBoolean(false); /** * Determines whether this JPPF client is resetting. */ final AtomicBoolean resetting = new AtomicBoolean(false); /** * Fully qualified name of the serilaization helper class to use. */ private String serializationHelperClassName; /** * The JPPF configuration properties. */ protected TypedProperties config; /** * Initialize this client with a specified application UUID. * @param uuid the unique identifier for this local client. */ protected AbstractJPPFClient(final String uuid) { this.uuid = (uuid == null) ? JPPFUuid.normalUUID() : uuid; if (debugEnabled) log.debug("Instantiating JPPF client with uuid=" + this.uuid); VersionUtils.logVersionInformation("client", this.uuid); SystemUtils.printPidAndUuid("client", this.uuid); } /** * Get JPPF configuration properties. These properties are unmodifiable. * @return {@code TypedProperties} instance. With JPPF configuration. */ public TypedProperties getConfig() { return config; } /** * Read all client connection information from the configuration and initialize * the connection pools accordingly. * @param config the JPPF configuration properties. */ abstract void initPools(final TypedProperties config); /** * Get count of all client connections handled by this JPPFClient. * @return count of {@link JPPFClientConnection} instances. */ public int getAllConnectionsCount() { int count = 0; for (JPPFConnectionPool pool: pools) count += pool.connectionCount(); return count; } /** * Get a connection with the specified priority that matches one of the specified statuses. * @param priority the priority of the connetion to find. * @param statuses a set of statuses, one of which must match the status of the connection to find. * @return a {@link JPPFClientConnection} that matches one of the specified statuses, or {@code null} if none could be found. * @since 4.2 */ public JPPFClientConnection getClientConnection(final int priority, final JPPFClientConnectionStatus...statuses) { synchronized(pools) { final Collection pls = pools.getValues(priority); if (pls == null) return null; for (final JPPFConnectionPool pool: pls) { final List list = pool.getConnections(statuses); if (!list.isEmpty()) return list.get(0); } } return null; } /** * Invoked when the status of a client connection has changed. * @param event the event to notify of. * @exclude */ @Override public void statusChanged(final ClientConnectionStatusEvent event) { final JPPFClientConnection c = event.getClientConnection(); if (c.getStatus().isTerminatedStatus() && !event.getOldStatus().isTerminatedStatus()) connectionFailed(c); } /** * Invoked when the status of a connection has changed to {@link JPPFClientConnectionStatus#FAILED}. * @param c the connection that failed. */ abstract void connectionFailed(final JPPFClientConnection c); /** * Remove a connection from the set of connections handled by this client. * @param connection the connection to remove. * @return {@code true} if the pool holding the connection became empty and was also removed, {@code false} otherwise. */ boolean removeClientConnection(final JPPFClientConnection connection) { if (connection == null) throw new IllegalArgumentException("connection is null"); if (debugEnabled) log.debug("removing connection {}", connection); connection.removeClientConnectionStatusListener(this); final JPPFConnectionPool pool = connection.getConnectionPool(); boolean poolRemoved = false; if (pool != null) { pool.remove(connection); if (pool.isEmpty()) { synchronized (pools) { pools.removeValue(pool.getPriority(), pool); } poolRemoved = true; } } return poolRemoved; } /** * Close this client and release all the resources it is using. */ @Override public void close() { for (JPPFConnectionPool pool: getConnectionPools()) pool.close(); this.pools.clear(); } /** * Add a listener to the list of listeners to this client. * @param listener the listener to add. */ public void addConnectionPoolListener(final ConnectionPoolListener listener) { connectionPoolListeners.add(listener); } /** * Remove a listener from the list of listeners to this client. * @param listener the listener to remove. */ public void removeConnectionPoolListener(final ConnectionPoolListener listener) { connectionPoolListeners.remove(listener); } /** * Notify all listeners to this client that a connection failed. * @param c the connection that triggered the event. */ void fireConnectionRemoved(final JPPFClientConnection c) { final ConnectionPoolEvent event = new ConnectionPoolEvent(c.getConnectionPool(), c); for (final ConnectionPoolListener listener : connectionPoolListeners) listener.connectionRemoved(event); } /** * Notify all listeners to this client that a new connection was added. * @param c the connection that was added. */ void fireConnectionAdded(final JPPFClientConnection c) { final ConnectionPoolEvent event = new ConnectionPoolEvent(c.getConnectionPool(), c); for (final ConnectionPoolListener listener : connectionPoolListeners) listener.connectionAdded(event); } /** * Notify all listeners to this client that a connection pool was removed. * @param pool the connection pool that triggered the event. */ void fireConnectionPoolRemoved(final JPPFConnectionPool pool) { final ConnectionPoolEvent event = new ConnectionPoolEvent(pool); for (final ConnectionPoolListener listener : connectionPoolListeners) listener.connectionPoolRemoved(event); } /** * Notify all listeners to this client that a new connection pool was added. * @param pool the connection pool that was added. */ void fireConnectionPoolAdded(final JPPFConnectionPool pool) { final ConnectionPoolEvent event = new ConnectionPoolEvent(pool); for (final ConnectionPoolListener listener : connectionPoolListeners) listener.connectionPoolAdded(event); } /** * Notify all listeners that a new connection was created. * @param c the connection that was created. * @exclude */ void newConnection(final JPPFClientConnectionImpl c) { fireConnectionAdded(c); } /** * Get the unique universal identifier for this JPPF client. * @return the uuid as a string. */ public String getUuid() { return uuid; } /** * Determine whether this JPPF client is closed. * @return {@code true} if this client is closed, {@code false} otherwise. */ public boolean isClosed() { return closed.get(); } /** * Get the name of the serialization helper implementation class name to use. * @return the fully qualified class name of a {@code SerializationHelper} implementation. * @exclude */ protected String getSerializationHelperClassName() { if (serializationHelperClassName == null) serializationHelperClassName = getConfig().getString("jppf.serialization.helper.class", SERIALIZATION_HELPER_IMPL); return serializationHelperClassName; } /** * Find the connection pool with the specified priority and id. * @param priority the priority of the pool, helps speedup the search. * @param poolId the id of the pool to find. * @return a {@link JPPFConnectionPool} instance, or {@code null} if no pool witht he specified id could be found. * @since 4.1 */ public ConnectionPool findConnectionPool(final int priority, final int poolId) { ConnectionPool pool = null; synchronized (pools) { final Collection priorityPools = pools.getValues(priority); if (priorityPools != null) { for (final JPPFConnectionPool p: priorityPools) { if (p.getId() == poolId) { pool = p; break; } } } } return pool; } /** * Find the connection pool with the specified id. * @param poolId the id of the pool to find. * @return a {@link JPPFConnectionPool} instance, or {@code null} if no pool with the specified id could be found. * @since 4.1 */ public JPPFConnectionPool findConnectionPool(final int poolId) { synchronized (pools) { for (JPPFConnectionPool pool: pools) { if (pool.getId() == poolId) return pool; } } return null; } /** * Find the connection pool with the specified id. * @param name the name of the pool to find. * @return a {@link JPPFConnectionPool} instance, or {@code null} if no pool with the specified name could be found. * @since 4.1 */ public JPPFConnectionPool findConnectionPool(final String name) { synchronized (pools) { for (JPPFConnectionPool pool: pools) { if (pool.getName().equals(name)) return pool; } } return null; } /** * Find the connection pools that have a least one connection matching one of the specified statuses. * @param statuses a set of statuses of which at least one must be matched by at least one connection in any of the returned pools. * @return a list of {@link JPPFConnectionPool} instances, possibly empty if none were found matching the specified statuses. * The pools in the list are ordered by descending priority. * @since 4.2 */ public List findConnectionPools(final JPPFClientConnectionStatus...statuses) { final List list = new ArrayList<>(); synchronized (pools) { for (final JPPFConnectionPool pool: pools) { if (!pool.getConnections(statuses).isEmpty()) list.add(pool); } } return list; } /** * Find the connection pools that pass the specified filter. * @param filter an implementation of the {@link ConnectionPoolFilter} interface. A {@code null} value is interpreted as no filter (all pools are accepted). * @return a list of {@link JPPFConnectionPool} instances, possibly empty if none passed the specified filter. * The pools in the list are ordered by descending priority. * @since 4.2 */ public List findConnectionPools(final ConnectionPoolFilter filter) { final List list = new ArrayList<>(); synchronized (pools) { for (final JPPFConnectionPool pool: pools) { if ((filter == null) || filter.accepts(pool)) list.add(pool); } } return list; } /** * Find the connection pools whose name matches the specified {@link Pattern regular expression}. * @param pattern the regular expression to match against. * @return a list of {@link JPPFConnectionPool} instances whose name match the input pattern, possibly empty but never {@code null}. * @since 4.2 */ public List findConnectionPools(final String pattern) { final Pattern p = Pattern.compile(pattern); final List result = new ArrayList<>(); synchronized (pools) { for (final JPPFConnectionPool pool: pools) { if (p.matcher(pool.getName()).matches()) result.add(pool); } } return result; } /** * Get a pool with at least one {@link JPPFClientConnectionStatus#ACTIVE active} connection and with the highest possible priority. * @return a {@link JPPFConnectionPool} instance, or {@code null} if no pool was found with an active connection. * @since 4.2 */ public JPPFConnectionPool getConnectionPool() { final List list = findConnectionPools(JPPFClientConnectionStatus.ACTIVE); return list.isEmpty() ? null : list.get(0); } /** * Get a set of existing connection pools with the specified priority. * @param priority the priority of the pool, helps speedup the search. * @return a list of {@link JPPFConnectionPool} instances, possibly empty but never {@code null}. * @since 4.1 */ public List getConnectionPools(final int priority) { final Collection coll; synchronized(pools) { if ((coll = pools.getValues(priority)) != null) { final List list = new ArrayList<>(coll.size()); list.addAll(coll); return list; } } return Collections.emptyList(); } /** * Get a list of all priorities for the currently existing pools, ordered by descending priority. * @return a list of integers represent the priorities, possibly empty but never {@code null}. * @since 4.1 */ public List getPoolPriorities() { synchronized(pools) { return new ArrayList<>(pools.keySet()); } } /** * Get a list of existing connection pools, ordered by descending priority. * @return a list of {@link JPPFConnectionPool} instances, possibly empty but never {@code null}. * @since 4.1 */ public List getConnectionPools() { synchronized(pools) { return new ArrayList<>(pools.allValues()); } } /** * Determine whether this client is resetting. * @return {@code true} if this client is resetting, {@code false} otherwise. * @exclude */ public boolean isResetting() { return resetting.get(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy