All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.apache.activemq.artemis.core.server.federation.FederationDownstream Maven / Gradle / Ivy
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.activemq.artemis.core.server.federation;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
import org.apache.activemq.artemis.api.core.TransportConfiguration;
import org.apache.activemq.artemis.api.core.client.SessionFailureListener;
import org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryInternal;
import org.apache.activemq.artemis.core.client.impl.ClientSessionInternal;
import org.apache.activemq.artemis.core.config.FederationConfiguration;
import org.apache.activemq.artemis.core.config.federation.FederationDownstreamConfiguration;
import org.apache.activemq.artemis.core.protocol.core.Channel;
import org.apache.activemq.artemis.core.protocol.core.CoreRemotingConnection;
import org.apache.activemq.artemis.core.protocol.core.impl.ChannelImpl.CHANNEL_ID;
import org.apache.activemq.artemis.core.protocol.core.impl.wireformat.FederationDownstreamConnectMessage;
import org.apache.activemq.artemis.core.protocol.core.impl.wireformat.FederationStreamConnectMessage;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
import org.jboss.logging.Logger;
public class FederationDownstream extends AbstractFederationStream implements SessionFailureListener {
private static final Logger logger = Logger.getLogger(FederationDownstream.class);
private FederationDownstreamConfiguration config;
private ClientSessionFactoryInternal clientSessionFactory;
private ClientSessionInternal clientSession;
private Channel channel;
private AtomicBoolean initialized = new AtomicBoolean();
private final ScheduledExecutorService scheduledExecutorService;
private final int intialConnectDelayMultiplier = 2;
private final int intialConnectDelayMax = 30;
public static final String FEDERATION_DOWNSTREAM_NAME = "federation-downstream-name";
private AtomicBoolean started = new AtomicBoolean();
private FederationConfiguration federationConfiguration;
public FederationDownstream(ActiveMQServer server, Federation federation, String name, FederationDownstreamConfiguration config,
final FederationConnection connection) {
super(server, federation, name, config, connection);
this.config = config;
this.scheduledExecutorService = server.getScheduledPool();
}
@Override
public synchronized void start() {
super.start();
callFederationStreamStartedPlugins();
try {
deploy(federationConfiguration);
} catch (ActiveMQException e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
@Override
public synchronized void stop() {
super.stop();
callFederationStreamStoppedPlugins();
}
public void deploy(FederationConfiguration federationConfiguration)
throws ActiveMQException {
this.federationConfiguration = federationConfiguration;
if (connection.isStarted() && started.compareAndSet(false, true)) {
final FederationStreamConnectMessage message = new FederationDownstreamConnectMessage();
message.setName(federationConfiguration.getName());
message.setCredentials(federationConfiguration.getCredentials());
message.setStreamConfiguration(config);
message.setFederationPolicyMap(federationConfiguration.getFederationPolicyMap());
message.setTransformerConfigurationMap(federationConfiguration.getTransformerConfigurationMap());
if (config.getUpstreamConfigurationRef() != null
&& config.getUpstreamConfiguration() == null) {
TransportConfiguration[] configs = server.getConfiguration()
.getTransportConfigurations(config.getUpstreamConfigurationRef());
if (configs != null && configs.length > 0) {
config.setUpstreamConfiguration(configs[0]);
} else {
ActiveMQServerLogger.LOGGER.federationCantFindUpstreamConnector(config.getName(), config
.getUpstreamConfigurationRef());
throw new ActiveMQException("Could not locate upstream transport configuration for federation downstream: " + config.getName()
+ "; upstream ref: " + config.getUpstreamConfigurationRef());
}
}
try {
scheduleConnect(0, message);
} catch (Exception e) {
throw new ActiveMQException(e.getMessage(), e, ActiveMQExceptionType.GENERIC_EXCEPTION);
}
ActiveMQServerLogger.LOGGER.federationDownstreamDeployed(config.getName());
}
}
public void undeploy() {
try {
if (started.compareAndSet(true, false)) {
disconnect();
ActiveMQServerLogger.LOGGER.federationDownstreamUnDeployed(config.getName());
}
} catch (ActiveMQException e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
private void scheduleConnect(final int delay, final FederationStreamConnectMessage message) {
scheduledExecutorService.schedule(() -> {
try {
connect();
if (initialized.compareAndSet(false, true)) {
channel.send(message);
}
} catch (Exception e) {
scheduleConnect(FederatedQueueConsumer.getNextDelay(delay, intialConnectDelayMultiplier, intialConnectDelayMax),
message);
}
}, delay, TimeUnit.SECONDS);
}
private void connect() throws Exception {
try {
if (clientSession == null) {
synchronized (this) {
this.clientSessionFactory = (ClientSessionFactoryInternal) getConnection().clientSessionFactory();
this.clientSession = (ClientSessionInternal) clientSessionFactory.createSession(getUser(), getPassword(), false, true, true, clientSessionFactory.getServerLocator().isPreAcknowledge(), clientSessionFactory.getServerLocator().getAckBatchSize());
this.clientSession.addFailureListener(this);
this.clientSession.addMetaData(FederatedQueueConsumer.FEDERATION_NAME, federation.getName().toString());
this.clientSession.addMetaData(FEDERATION_DOWNSTREAM_NAME, config.getName().toString());
this.clientSession.start();
CoreRemotingConnection connection = (CoreRemotingConnection) clientSessionFactory.getConnection();
channel = connection.getChannel(CHANNEL_ID.FEDERATION.id, -1);
}
}
} catch (Exception e) {
try {
if (clientSessionFactory != null) {
clientSessionFactory.cleanup();
}
disconnect();
} catch (ActiveMQException ignored) {
}
throw e;
}
}
@Override
public void connectionFailed(ActiveMQException exception, boolean failedOver) {
connectionFailed(exception, failedOver, null);
}
@Override
public void connectionFailed(ActiveMQException exception, boolean failedOver, String scaleDownTargetNodeID) {
try {
started.set(false);
initialized.set(false);
channel.close();
clientSessionFactory.cleanup();
clientSessionFactory.close();
channel = null;
clientSession = null;
clientSessionFactory = null;
} catch (Throwable dontCare) {
}
start();
}
private void disconnect() throws ActiveMQException {
initialized.set(false);
if (channel != null) {
channel.close();
}
if (clientSession != null) {
clientSession.close();
}
channel = null;
clientSession = null;
if (clientSessionFactory != null && (!getConnection().isSharedConnection() || clientSessionFactory.numSessions() == 0)) {
clientSessionFactory.close();
clientSessionFactory = null;
}
}
@Override
public void beforeReconnect(ActiveMQException exception) {
}
}