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

org.jdiameter.server.impl.MetaDataImpl Maven / Gradle / Ivy

There is a newer version: 2.0.5
Show newest version
/*
 * TeleStax, Open Source Cloud Communications
 * Copyright 2011-2016, TeleStax Inc. and individual contributors
 * by the @authors tag.
 *
 * This program is free software: you can redistribute it and/or modify
 * under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see 
 *
 * This file incorporates work covered by the following copyright and
 * permission notice:
 *
 *   JBoss, Home of Professional Open Source
 *   Copyright 2007-2011, Red Hat, Inc. and individual contributors
 *   by the @authors tag. See the copyright.txt in the distribution for a
 *   full listing of individual contributors.
 *
 *   This is free software; you can redistribute it and/or modify it
 *   under the terms of the GNU Lesser General Public License as
 *   published by the Free Software Foundation; either version 2.1 of
 *   the License, or (at your option) any later version.
 *
 *   This software is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *   Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this software; if not, write to the Free
 *   Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 *   02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.jdiameter.server.impl;

import static org.jdiameter.client.impl.helpers.Parameters.OwnIPAddress;
import static org.jdiameter.server.impl.helpers.Parameters.OwnIPAddresses;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.jdiameter.api.ApplicationId;
import org.jdiameter.api.Avp;
import org.jdiameter.api.Configuration;
import org.jdiameter.api.Network;
import org.jdiameter.api.NetworkReqListener;
import org.jdiameter.api.OverloadException;
import org.jdiameter.api.PeerTable;
import org.jdiameter.api.StackType;
import org.jdiameter.client.api.IContainer;
import org.jdiameter.client.api.IMessage;
import org.jdiameter.client.api.ISessionFactory;
import org.jdiameter.client.api.controller.IPeer;
import org.jdiameter.client.api.io.TransportException;
import org.jdiameter.client.impl.helpers.IPConverter;
import org.jdiameter.common.api.statistic.IStatisticManager;
import org.jdiameter.server.api.IMetaData;
import org.jdiameter.server.api.IMutablePeerTable;
import org.jdiameter.server.api.INetwork;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author [email protected]
 * @author  Alexandre Mendonca 
 * @author  Bartosz Baranowski 
 */
@SuppressWarnings("all") //3rd party lib
public class MetaDataImpl extends org.jdiameter.client.impl.MetaDataImpl implements IMetaData {

    private static final Logger logger = LoggerFactory.getLogger(MetaDataImpl.class);

    private final Object lock = new Object();

    public MetaDataImpl(IContainer s) {
        super(s);
    }

    public MetaDataImpl(IContainer s, IStatisticManager factory) {
        super(s, factory);
    }

    @Override
    public StackType getStackType() {
        return StackType.TYPE_SERVER;
    }

    @Override
    protected IPeer newLocalPeer(IStatisticManager statisticFactory) {
        return new ServerLocalPeer(statisticFactory);
    }

    @Override
    public void addApplicationId(ApplicationId applicationId) {
        synchronized (lock) {
            if (appIds.contains(applicationId)) {
                return;
            }
            appIds.add(applicationId);
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Adding application id of auth [{}] acct [{}] vendor [{}]",
                    new Object[] { applicationId.getAuthAppId(), applicationId.getAcctAppId(), applicationId.getVendorId() });
        }
    }

    @Override
    public void remApplicationId(ApplicationId applicationId) {
        synchronized (lock) {
            appIds.remove(applicationId);
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Removing application id of auth [{}] acct [{}] vendor [{}]",
                    new Object[] { applicationId.getAuthAppId(), applicationId.getAcctAppId(), applicationId.getVendorId() });
        }
    }

    @Override
    public void reload() {
        // Reload common application ids from configuration
        synchronized (lock) {
            appIds.clear();
            logger.debug("Clearing out application ids");
            getLocalPeer().getCommonApplications();
            // Reload ip addresses from configuration
            ((ServerLocalPeer) peer).resetAddresses();
            peer.getIPAddresses();
        }
    }

    protected class ServerLocalPeer extends ClientLocalPeer {

        protected INetwork net = null;
        protected IMutablePeerTable manager = null;
        protected ISessionFactory factory = null;
        // XXX: FT/HA // protected Map slc = null;
        Map peerRequests = new ConcurrentHashMap();

        public ServerLocalPeer(IStatisticManager statisticFactory) {
            super(statisticFactory);
        }

        @Override
        public Set getCommonApplications() {
            Set set;
            synchronized (lock) {
                set = super.getCommonApplications();
            }
            return set;
        }

        @Override
        public InetAddress[] getIPAddresses() {
            if (addresses.length == 0) {
                Configuration[] ipAddresses = stack.getConfiguration().getChildren(OwnIPAddresses.ordinal());
                List list = new ArrayList();
                if (ipAddresses != null) {
                    for (Configuration address : ipAddresses) {
                        if (address != null) {
                            InetAddress iaddress = getAddress(address);
                            if (iaddress != null) {
                                list.add(iaddress);
                            }
                        }
                    }
                } else {
                    InetAddress address = getDefaultIpAddress();
                    if (address != null) {
                        list.add(address);
                    }
                }
                addresses = list.toArray(new InetAddress[list.size()]);
            }
            return addresses;
        }

        private InetAddress getAddress(Configuration configuration) {
            InetAddress rc;
            String address = configuration.getStringValue(OwnIPAddress.ordinal(), null);
            if (address == null || address.length() == 0) {
                rc = getDefaultIpAddress();
            } else {
                try {
                    rc = InetAddress.getByName(address);
                } catch (UnknownHostException e) {
                    logger.debug("Unable to retrieve IP by Address [{}]", address, e);
                    rc = IPConverter.InetAddressByIPv4(address);
                    if (rc == null) {
                        rc = IPConverter.InetAddressByIPv6(address);
                    }
                    if (rc == null) {
                        rc = getDefaultIpAddress();
                    }
                }
            }
            return rc;
        }

        private InetAddress getDefaultIpAddress() {
            try {
                return InetAddress.getByName(getLocalPeer().getUri().getFQDN());
            } catch (Exception e1) {
                logger.debug("Unable to retrieve IP by URI [{}]", getLocalPeer().getUri().getFQDN(), e1);
                try {
                    return InetAddress.getLocalHost();
                } catch (Exception e2) {
                    logger.debug("Unable to retrieve IP for localhost", e2);
                }
            }
            return null;
        }

        // Local processing message
        @Override
        @SuppressWarnings("unchecked")
        public boolean sendMessage(IMessage message) throws TransportException, OverloadException {
            logger.debug("Sending Message in Server Local Peer");
            try {
                if (net == null || manager == null) {
                    try {
                        logger.debug("Unwrapping network and manager");
                        net = (INetwork) stack.unwrap(Network.class);
                        manager = (IMutablePeerTable) stack.unwrap(PeerTable.class);
                        factory = manager.getSessionFactory();
                        // XXX: FT/HA // slc = manager.getSessionReqListeners();
                    } catch (Exception e) {
                        logger.warn("Error initialising for message send", e);
                    }
                }

                IMessage answer = null;
                if (message.isRequest()) {
                    logger.debug("Message is a request");
                    message.setHopByHopIdentifier(peer.getHopByHopIdentifier());
                    peerRequests.put(message.getHopByHopIdentifier(), message);
                    NetworkReqListener listener = net.getListener(message);
                    if (listener != null) {
                        // This is duplicate code from PeerImpl
                        answer = manager.isDuplicate(message);
                        if (answer != null) {
                            logger.debug("Found message in duplicates. No need to invoke listener, will send previous answer.");
                            answer.setProxiable(message.isProxiable());
                            answer.getAvps().removeAvp(Avp.PROXY_INFO);
                            for (Avp avp : message.getAvps().getAvps(Avp.PROXY_INFO)) {
                                answer.getAvps().addAvp(avp);
                            }
                            answer.setHopByHopIdentifier(message.getHopByHopIdentifier());
                        } else {
                            String avpSessionId = message.getSessionId();
                            if (avpSessionId != null) {
                                // XXX: FT/HA // NetworkReqListener sessionListener = slc.get(avpSessionId);
                                NetworkReqListener sessionListener = sessionDataSource.getSessionListener(avpSessionId);
                                if (sessionListener != null) {
                                    logger.debug(
                                            "Giving message to sessionListener to process as Session-Id AVP existed in message "
                                                    + "and was used to get a session from Session DataSource");
                                    answer = (IMessage) sessionListener.processRequest(message);
                                } else {
                                    try {
                                        logger.debug("Giving message to listener to process. Listener was retrieved from net");
                                        answer = (IMessage) listener.processRequest(message);
                                        if (answer != null) {
                                            manager.saveToDuplicate(message.getDuplicationKey(), answer);
                                        }
                                    } catch (Exception e) {
                                        logger.debug("Error during processing message by listener", e);
                                    }
                                }
                            }
                        }
                    } else {
                        if (logger.isDebugEnabled()) {
                            logger.debug("Unable to find handler {} for message {}", message.getSingleApplicationId(), message);
                        }
                    }
                    if (answer != null) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("Removing message with HbH Identifier [{}] from Peer Requests Map",
                                    message.getHopByHopIdentifier());
                        }
                        peerRequests.remove(message.getHopByHopIdentifier());
                    }
                } else {
                    if (logger.isDebugEnabled()) {
                        logger.debug(
                                "Message is an answer. Setting answer to the message and fetching message from Peer Requests Map using HbH Identifier [{}]",
                                message.getHopByHopIdentifier());
                    }
                    answer = message;
                    message = peerRequests.get(answer.getHopByHopIdentifier());
                }
                // Process answer
                if (message != null && !message.isTimeOut() && answer != null) {
                    logger.debug("Clearing timer on message and notifying event listeners of receiving success message");
                    message.clearTimer();
                    message.setState(IMessage.STATE_ANSWERED);
                    message.getEventListener().receivedSuccessMessage(message, answer);
                }
                return true;
            } catch (Exception e) {
                logger.warn("Unable to process message {}", message, e);
            }
            return false;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy