org.eclipse.persistence.sessions.coordination.jms.JMSTopicTransportManager Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 1998, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
// cdelahun - Bug 214534: added JMS Cache Coordination for publishing only
package org.eclipse.persistence.sessions.coordination.jms;
import org.eclipse.persistence.exceptions.RemoteCommandManagerException;
import org.eclipse.persistence.internal.sessions.coordination.RemoteConnection;
import org.eclipse.persistence.internal.sessions.coordination.jms.JMSTopicRemoteConnection;
import org.eclipse.persistence.sessions.coordination.RemoteCommandManager;
import java.util.Map;
/**
*
* Purpose: Provide a transport implementation for the Remote Command Module (RCM) that both publishes
* and subscribes to a JMS topic.
*
* Description: This class manages two connections to the same known JMS Topic:
* external connection for publishing, local connection for receiving messages.
*
* @author Steven Vo
* @since OracleAS TopLink 10g (10.0.3)
*/
public class JMSTopicTransportManager extends JMSPublishingTransportManager {
public JMSTopicTransportManager(RemoteCommandManager rcm) {
super(rcm);
}
/**
* INTERNAL:
* JMSTopicTransportManager may have only two connections: one local and one external.
* In case the local connection doesn't exist, this method creates it.
*/
@Override
public synchronized void createLocalConnection() {
if(localConnection == null) {
try {
localConnection = createConnection(true);
} catch (RemoteCommandManagerException rcmException) {
// to recover handle RemoteCommandManagerException.ERROR_CREATING_LOCAL_JMS_CONNECTION:
// after changing something (for instance jmsHostUrl)
// call createLocalConnection method again.
rcm.handleException(rcmException);
}
}
}
/**
* INTERNAL:
* In case there's no external connection attempts to create one,
* if that's successful then (in case there is no local connection, too)
* attempts to create local connection in a separate thread.
* Returns clone of the original map.
*/
@Override
public Map getConnectionsToExternalServicesForCommandPropagation() {
if (this.localConnection == null && !this.rcm.isStopped()) {
// It's a good time to create localConnection,
// in a new thread - to return externalConnections promptly.
this.rcm.getServerPlatform().launchContainerRunnable(new Runnable() {
@Override
public void run() {
try {
createLocalConnection();
} catch (RemoteCommandManagerException ex) {
// Ignore exception - user had a chance to handle it in createLocalConnection method:
// for instance to change host url and create a new local connection.
}
}
});
}
return super.getConnectionsToExternalServicesForCommandPropagation();
}
/**
* INTERNAL:
* caches local connection, set localConnection to null, closes the cached connection in a new thread.
*/
@Override
public void removeLocalConnection() {
JMSTopicRemoteConnection connectionToRemove = (JMSTopicRemoteConnection)localConnection;
synchronized(this) {
if(connectionToRemove == localConnection) {
localConnection = null;
} else {
connectionToRemove = null;
}
}
// closing connection may take time - do it outside of the synchronized block
if(connectionToRemove != null) {
connectionToRemove.close();
}
}
}