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

org.apache.activemq.artemis.core.server.cluster.impl.BroadcastGroupImpl 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.cluster.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
import org.apache.activemq.artemis.api.core.BroadcastEndpoint;
import org.apache.activemq.artemis.api.core.BroadcastEndpointFactory;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.TransportConfiguration;
import org.apache.activemq.artemis.api.core.management.CoreNotificationType;
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
import org.apache.activemq.artemis.core.server.NodeManager;
import org.apache.activemq.artemis.core.server.cluster.BroadcastGroup;
import org.apache.activemq.artemis.core.server.management.Notification;
import org.apache.activemq.artemis.core.server.management.NotificationService;
import org.apache.activemq.artemis.utils.UUIDGenerator;
import org.apache.activemq.artemis.utils.collections.TypedProperties;
import org.jboss.logging.Logger;

/**
 * 

This class will use the {@link BroadcastEndpoint} to send periodical updates on the list for connections * used by this server.

* *

This is totally generic to the mechanism used on the transmission. It originally only had UDP but this got refactored * into sub classes of {@link BroadcastEndpoint}

*/ public class BroadcastGroupImpl implements BroadcastGroup, Runnable { private static final Logger logger = Logger.getLogger(BroadcastGroupImpl.class); private final NodeManager nodeManager; private final String name; private final List connectors = new ArrayList<>(); private boolean started; private final long broadCastPeriod; private final ScheduledExecutorService scheduledExecutor; private ScheduledFuture future; private boolean loggedBroadcastException = false; // Each broadcast group has a unique id - we use this to detect when more than one group broadcasts the same node id // on the network which would be an error private final String uniqueID; private NotificationService notificationService; private BroadcastEndpoint endpoint; public BroadcastGroupImpl(final NodeManager nodeManager, final String name, final long broadCastPeriod, final ScheduledExecutorService scheduledExecutor, final BroadcastEndpointFactory endpointFactory) throws Exception { this.nodeManager = nodeManager; this.name = name; this.scheduledExecutor = scheduledExecutor; this.broadCastPeriod = broadCastPeriod; this.endpoint = endpointFactory.createBroadcastEndpoint(); uniqueID = UUIDGenerator.getInstance().generateStringUUID(); } @Override public void setNotificationService(final NotificationService notificationService) { this.notificationService = notificationService; } @Override public synchronized void start() throws Exception { if (started) { return; } endpoint.openBroadcaster(); started = true; if (notificationService != null) { TypedProperties props = new TypedProperties(); props.putSimpleStringProperty(new SimpleString("name"), new SimpleString(name)); Notification notification = new Notification(nodeManager.getNodeId().toString(), CoreNotificationType.BROADCAST_GROUP_STARTED, props); notificationService.sendNotification(notification); } activate(); } @Override public synchronized void stop() { if (!started) { return; } if (future != null) { future.cancel(false); } try { endpoint.close(true); } catch (Exception e1) { ActiveMQServerLogger.LOGGER.broadcastGroupClosed(e1); } started = false; if (notificationService != null) { TypedProperties props = new TypedProperties(); props.putSimpleStringProperty(new SimpleString("name"), new SimpleString(name)); Notification notification = new Notification(nodeManager.getNodeId().toString(), CoreNotificationType.BROADCAST_GROUP_STOPPED, props); try { notificationService.sendNotification(notification); } catch (Exception e) { ActiveMQServerLogger.LOGGER.broadcastGroupClosed(e); } } } @Override public synchronized boolean isStarted() { return started; } @Override public String getName() { return name; } @Override public synchronized void addConnector(final TransportConfiguration tcConfig) { connectors.add(tcConfig); } @Override public synchronized void removeConnector(final TransportConfiguration tcConfig) { connectors.remove(tcConfig); } @Override public synchronized int size() { return connectors.size(); } private synchronized void activate() { if (scheduledExecutor != null) { future = scheduledExecutor.scheduleWithFixedDelay(this, 0L, broadCastPeriod, TimeUnit.MILLISECONDS); } } @Override public synchronized void broadcastConnectors() throws Exception { ActiveMQBuffer buff = ActiveMQBuffers.dynamicBuffer(4096); buff.writeString(nodeManager.getNodeId().toString()); buff.writeString(uniqueID); buff.writeInt(connectors.size()); for (TransportConfiguration tcConfig : connectors) { tcConfig.encode(buff); } // Only send as many bytes as we need. byte[] data = new byte[buff.readableBytes()]; buff.getBytes(buff.readerIndex(), data); endpoint.broadcast(data); } @Override public void run() { if (!started) { return; } try { broadcastConnectors(); loggedBroadcastException = false; } catch (Exception e) { // only log the exception at ERROR level once, even if it fails multiple times in a row - HORNETQ-919 if (!loggedBroadcastException) { ActiveMQServerLogger.LOGGER.errorBroadcastingConnectorConfigs(e); loggedBroadcastException = true; } else { logger.debug("Failed to broadcast connector configs...again", e); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy