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

io.joynr.messaging.routing.AddressManager Maven / Gradle / Ivy

/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2017 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */
package io.joynr.messaging.routing;

import java.util.HashSet;
import java.util.Set;

import com.google.inject.Inject;
import com.google.inject.name.Named;
import io.joynr.exceptions.JoynrIllegalStateException;
import io.joynr.exceptions.JoynrRuntimeException;
import io.joynr.messaging.MessagingPropertyKeys;
import joynr.ImmutableMessage;
import joynr.Message;
import joynr.system.RoutingTypes.Address;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AddressManager {
    private static final Logger logger = LoggerFactory.getLogger(AddressManager.class);

    private final MulticastReceiverRegistry multicastReceiversRegistry;

    private RoutingTable routingTable;
    private MulticastAddressCalculator multicastAddressCalculator;

    protected static class PrimaryGlobalTransportHolder {
        @Inject(optional = true)
        @Named(MessagingPropertyKeys.PROPERTY_MESSAGING_PRIMARYGLOBALTRANSPORT)
        private String primaryGlobalTransport;

        public PrimaryGlobalTransportHolder() {
        }

        // For testing only
        protected PrimaryGlobalTransportHolder(String primaryGlobalTransport) {
            this.primaryGlobalTransport = primaryGlobalTransport;
        }

        public String get() {
            return primaryGlobalTransport;
        }
    }

    @Inject
    public AddressManager(RoutingTable routingTable,
                          PrimaryGlobalTransportHolder primaryGlobalTransport,
                          Set multicastAddressCalculators,
                          MulticastReceiverRegistry multicastReceiverRegistry) {
        logger.trace("Initialised with routingTable: {} primaryGlobalTransport: {} multicastAddressCalculators: {} multicastReceiverRegistry: {}",
                     routingTable,
                     primaryGlobalTransport.get(),
                     multicastAddressCalculators,
                     multicastReceiverRegistry);
        this.routingTable = routingTable;
        this.multicastReceiversRegistry = multicastReceiverRegistry;
        if (multicastAddressCalculators.size() > 1 && primaryGlobalTransport.get() == null) {
            throw new JoynrIllegalStateException("Multiple multicast address calculators registered, but no primary global transport set.");
        }
        if (multicastAddressCalculators.size() == 1) {
            this.multicastAddressCalculator = multicastAddressCalculators.iterator().next();
        } else {
            for (MulticastAddressCalculator multicastAddressCalculator : multicastAddressCalculators) {
                if (multicastAddressCalculator.supports(primaryGlobalTransport.get())) {
                    this.multicastAddressCalculator = multicastAddressCalculator;
                    break;
                }
            }
        }
    }

    /**
     * Get the address to which the passed in message should be sent to.
     * This can be an address contained in the {@link RoutingTable}, or a
     * multicast address calculated from the header content of the message.
     *
     * @param message the message for which we want to find an address to send it to.
     * @return the address to send the message to. Will not be null, because if an address can't be determined an exception is thrown.
     * @throws JoynrMessageNotSentException if no address can be determined / found for the given message.
     */
    public Set
getAddresses(ImmutableMessage message) { Set
result = new HashSet<>(); String toParticipantId = message.getRecipient(); if (Message.VALUE_MESSAGE_TYPE_MULTICAST.equals(message.getType())) { handleMulticastMessage(message, result); } else if (toParticipantId != null && routingTable.containsKey(toParticipantId)) { Address address = routingTable.get(toParticipantId); if (address != null) { result.add(address); } } logger.trace("Found the following addresses for {}: {}", new Object[]{ message, result }); return result; } private void handleMulticastMessage(ImmutableMessage message, Set
result) { if (!message.isReceivedFromGlobal() && multicastAddressCalculator != null) { if (multicastAddressCalculator.createsGlobalTransportAddresses()) { // only global providers should multicast to the "outside world" if (isProviderGloballyVisible(message.getSender())) { addMulticastReceiverAddressFromAddressCalculator(message, result); } } else { // in case the address calculator does not provide an address // to the "outside world" it is safe to forward the message // regardless of the provider being globally visible or not addMulticastReceiverAddressFromAddressCalculator(message, result); } } addLocalMulticastReceiverAddressesFromRegistry(message, result); } private boolean isProviderGloballyVisible(String participantId) { boolean isGloballyVisible = false; try { isGloballyVisible = routingTable.getIsGloballyVisible(participantId); } catch (JoynrRuntimeException e) { // This should never happen logger.error("No routing entry found for Multicast Provider {}. " + "The message will not be published globally.", participantId); } return isGloballyVisible; } private void addMulticastReceiverAddressFromAddressCalculator(ImmutableMessage message, Set
result) { Address calculatedAddress = multicastAddressCalculator.calculate(message); if (calculatedAddress != null) { result.add(calculatedAddress); } } private void addLocalMulticastReceiverAddressesFromRegistry(ImmutableMessage message, Set
result) { Set receivers = multicastReceiversRegistry.getReceivers(message.getRecipient()); for (String receiverParticipantId : receivers) { Address address = routingTable.get(receiverParticipantId); if (address != null) { result.add(address); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy