
org.restcomm.protocols.ss7.m3ua.impl.AsImpl Maven / Gradle / Ivy
/*
* TeleStax, Open Source Cloud Communications Copyright 2012.
* 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.restcomm.protocols.ss7.m3ua.impl;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import javolution.util.FastList;
import javolution.util.FastSet;
import javolution.xml.XMLFormat;
import javolution.xml.XMLSerializable;
import javolution.xml.stream.XMLStreamException;
import org.apache.log4j.Logger;
import org.restcomm.protocols.ss7.m3ua.As;
import org.restcomm.protocols.ss7.m3ua.Asp;
import org.restcomm.protocols.ss7.m3ua.ExchangeType;
import org.restcomm.protocols.ss7.m3ua.Functionality;
import org.restcomm.protocols.ss7.m3ua.IPSPType;
import org.restcomm.protocols.ss7.m3ua.State;
import org.restcomm.protocols.ss7.m3ua.impl.fsm.FSM;
import org.restcomm.protocols.ss7.m3ua.impl.message.MessageFactoryImpl;
import org.restcomm.protocols.ss7.m3ua.impl.oam.M3UAOAMMessages;
import org.restcomm.protocols.ss7.m3ua.impl.parameter.NetworkAppearanceImpl;
import org.restcomm.protocols.ss7.m3ua.impl.parameter.ParameterFactoryImpl;
import org.restcomm.protocols.ss7.m3ua.impl.parameter.RoutingContextImpl;
import org.restcomm.protocols.ss7.m3ua.impl.parameter.TrafficModeTypeImpl;
import org.restcomm.protocols.ss7.m3ua.message.MessageFactory;
import org.restcomm.protocols.ss7.m3ua.message.transfer.PayloadData;
import org.restcomm.protocols.ss7.m3ua.parameter.NetworkAppearance;
import org.restcomm.protocols.ss7.m3ua.parameter.ParameterFactory;
import org.restcomm.protocols.ss7.m3ua.parameter.RoutingContext;
import org.restcomm.protocols.ss7.m3ua.parameter.TrafficModeType;
import org.restcomm.protocols.ss7.mtp.RoutingLabelFormat;
/**
*
* @author amit bhayani
*
*/
public class AsImpl implements XMLSerializable, As {
private static final Logger logger = Logger.getLogger(AsImpl.class);
private static final String NAME = "name";
private static final String ROUTING_CONTEXT = "routingContext";
private static final String NETWORK_APPEARANCE = "networkAppearance";
private static final String TRAFFIC_MODE = "trafficMode";
private static final String DEFAULT_TRAFFIC_MODE = "defTrafficMode";
private static final String ASP_LIST = "asps";
private static final String MIN_ASP_ACT_LB = "minAspActiveForLb";
public static final String ATTRIBUTE_ASP = "asp";
protected int minAspActiveForLb = 1;
// List of all the ASP's for this AS
protected FastList appServerProcs = new FastList();
// List of As state listeners
private FastSet asStateListeners = new FastSet();
private AspTrafficListener aspTrafficListener;
protected String name;
protected RoutingContext rc;
protected TrafficModeType trMode;
protected TrafficModeType defaultTrafModType;
protected ConcurrentLinkedQueue penQueue = new ConcurrentLinkedQueue();
/**
* Peer FSM maintains state such that it receives the NTFY from other side
*/
private FSM peerFSM;
/**
* Local FSM maintains state such that it sends the NTFY to other side
*/
private FSM localFSM;
protected ParameterFactory parameterFactory = new ParameterFactoryImpl();
protected MessageFactory messageFactory = new MessageFactoryImpl();
protected M3UAManagementImpl m3UAManagementImpl = null;
private Functionality functionality = null;
private ExchangeType exchangeType = null;
private IPSPType ipspType = null;
private NetworkAppearance networkAppearance = null;
private final int[] slsVsAspTable = new int[256];
private int aspSlsMask = 0x07;
private int aspSlsShiftPlaces = 0x00;
protected State state = AsState.DOWN;
public AsImpl() {
}
public AsImpl(String name, RoutingContext rc, TrafficModeType trMode, int minAspActiveForLoadbalance,
Functionality functionality, ExchangeType exchangeType, IPSPType ipspType, NetworkAppearance networkAppearance) {
this.name = name;
this.rc = rc;
this.trMode = trMode;
this.minAspActiveForLb = minAspActiveForLoadbalance;
this.functionality = functionality;
this.exchangeType = exchangeType;
this.ipspType = ipspType;
this.defaultTrafModType = this.parameterFactory.createTrafficModeType(TrafficModeType.Loadshare);
this.networkAppearance = networkAppearance;
init();
}
public void init() {
switch (this.functionality) {
case IPSP:
if (this.exchangeType == ExchangeType.SE) {
if (this.ipspType == IPSPType.CLIENT) {
// If this AS is IPSP and client side, it should wait for
// NTFY from other side
this.initPeerFSM();
} else {
// else this will send NTFY to other side
this.initLocalFSM();
}
} else {
// If this is IPSP and DE, it should maintain two states. One
// for sending NTFY to other side and other for receiving NTFY
// form other side
this.initPeerFSM();
this.initLocalFSM();
}
break;
case AS:
if (this.exchangeType == ExchangeType.SE) {
// If this is AS side, it should always receive NTFY from other
// side
this.initPeerFSM();
} else {
// If DE, it should maintain two states.
this.initPeerFSM();
this.initLocalFSM();
}
break;
case SGW:
if (this.exchangeType == ExchangeType.SE) {
// If this is SGW, it should always send the NTFY to other side
this.initLocalFSM();
} else {
// If DE, it should maintain two states.
this.initPeerFSM();
this.initLocalFSM();
}
break;
}
}
/**
* Initialize FSM for AS side
**/
private void initPeerFSM() {
this.peerFSM = new FSM(this.name + "_PEER");
// Define states
this.peerFSM.createState(AsState.DOWN.toString()).setOnEnter(new SEHPeerAsStateEnterDown(this));
this.peerFSM.createState(AsState.ACTIVE.toString()).setOnEnter(new SEHPeerAsStateEnterActive(this));
this.peerFSM.createState(AsState.INACTIVE.toString()).setOnEnter(new SEHPeerAsStateEnterInactive(this));
this.peerFSM.createState(AsState.PENDING.toString()).setOnTimeOut(new AsStatePenTimeout(this, this.peerFSM), 2000)
.setOnEnter(new SEHPeerAsStateEnterPen(this, this.peerFSM));
this.peerFSM.setStart(AsState.DOWN.toString());
this.peerFSM.setEnd(AsState.DOWN.toString());
// Define Transitions
// ******************************************************************/
// STATE DOWN /
// ******************************************************************/
this.peerFSM.createTransition(TransitionState.AS_STATE_CHANGE_INACTIVE, AsState.DOWN.toString(),
AsState.INACTIVE.toString());
this.peerFSM.createTransition(TransitionState.ASP_DOWN, AsState.DOWN.toString(), AsState.DOWN.toString());
this.peerFSM.createTransition(TransitionState.AS_STATE_CHANGE_ACTIVE, AsState.DOWN.toString(),
AsState.ACTIVE.toString()).setHandler(new THPeerAsInActToAct(this, this.peerFSM));
// ******************************************************************/
// STATE INACTIVE /
// ******************************************************************/
this.peerFSM.createTransition(TransitionState.AS_STATE_CHANGE_INACTIVE, AsState.INACTIVE.toString(),
AsState.INACTIVE.toString());
this.peerFSM.createTransition(TransitionState.AS_STATE_CHANGE_ACTIVE, AsState.INACTIVE.toString(),
AsState.ACTIVE.toString()).setHandler(new THPeerAsInActToAct(this, this.peerFSM));
this.peerFSM.createTransition(TransitionState.ASP_DOWN, AsState.INACTIVE.toString(), AsState.DOWN.toString())
.setHandler(new THPeerAsInActToDwn(this, this.peerFSM));
// ******************************************************************/
// STATE ACTIVE /
// ******************************************************************/
this.peerFSM.createTransition(TransitionState.AS_STATE_CHANGE_ACTIVE, AsState.ACTIVE.toString(),
AsState.ACTIVE.toString());
this.peerFSM.createTransition(TransitionState.OTHER_ALTERNATE_ASP_ACTIVE, AsState.ACTIVE.toString(),
AsState.ACTIVE.toString()).setHandler(new THPeerAsActToActNtfyAltAspAct(this, this.peerFSM));
this.peerFSM.createTransition(TransitionState.OTHER_INSUFFICIENT_ASP, AsState.ACTIVE.toString(),
AsState.ACTIVE.toString()).setHandler(new THPeerAsActToActNtfyInsAsp(this, this.peerFSM));
this.peerFSM.createTransition(TransitionState.AS_STATE_CHANGE_PENDING, AsState.ACTIVE.toString(),
AsState.PENDING.toString());
this.peerFSM.createTransition(TransitionState.ASP_DOWN, AsState.ACTIVE.toString(), AsState.PENDING.toString())
.setHandler(new THPeerAsActToPen(this, this.peerFSM));
// ******************************************************************/
// STATE PENDING /
// ******************************************************************/
// As transitions to DOWN from PENDING when Pending Timer timesout
this.peerFSM.createTransition(TransitionState.AS_DOWN, AsState.PENDING.toString(), AsState.DOWN.toString());
// As transitions to INACTIVE from PENDING when Pending Timer
// timesout
this.peerFSM.createTransition(TransitionState.AS_INACTIVE, AsState.PENDING.toString(), AsState.INACTIVE.toString());
// If in PENDING and one of the ASP is ACTIVE again
this.peerFSM.createTransition(TransitionState.AS_STATE_CHANGE_ACTIVE, AsState.PENDING.toString(),
AsState.ACTIVE.toString()).setHandler(new THPeerAsPendToAct(this, this.peerFSM));
// If As is PENDING and far end sends INACTIVE we still remain
// PENDING as that message from pending queue can be sent once As
// becomes ACTIVE before T(r) expires
this.peerFSM.createTransition(TransitionState.AS_STATE_CHANGE_INACTIVE, AsState.PENDING.toString(),
AsState.INACTIVE.toString()).setHandler(new THNoTrans());
this.peerFSM.createTransition(TransitionState.ASP_DOWN, AsState.PENDING.toString(), AsState.PENDING.toString())
.setHandler(new THNoTrans());
}
/**
* Initialize FSM for SGW side
**/
private void initLocalFSM() {
this.localFSM = new FSM(this.name + "_LOCAL");
// Define states
this.localFSM.createState(AsState.DOWN.toString()).setOnEnter(new SEHLocalAsStateEnterDown(this));
this.localFSM.createState(AsState.ACTIVE.toString()).setOnEnter(new SEHLocalAsStateEnterActive(this));
this.localFSM.createState(AsState.INACTIVE.toString()).setOnEnter(new SEHLocalAsStateEnterInactive(this));
this.localFSM.createState(AsState.PENDING.toString()).setOnTimeOut(new RemAsStatePenTimeout(this, this.localFSM), 2000)
.setOnEnter(new SEHLocalAsStateEnterPen(this, this.localFSM));
this.localFSM.setStart(AsState.DOWN.toString());
this.localFSM.setEnd(AsState.DOWN.toString());
// Define Transitions
// ******************************************************************/
// STATE DOWN /
// ******************************************************************/
this.localFSM.createTransition(TransitionState.ASP_UP, AsState.DOWN.toString(), AsState.INACTIVE.toString())
.setHandler(new THLocalAsDwnToInact(this, this.localFSM));
this.localFSM.createTransition(TransitionState.ASP_DOWN, AsState.DOWN.toString(), AsState.DOWN.toString());
// ******************************************************************/
// STATE INACTIVE /
// ******************************************************************/
// TODO : Add Pluggable policy for AS?
this.localFSM.createTransition(TransitionState.ASP_ACTIVE, AsState.INACTIVE.toString(), AsState.ACTIVE.toString())
.setHandler(new THLocalAsInactToAct(this, this.localFSM));
this.localFSM.createTransition(TransitionState.ASP_DOWN, AsState.INACTIVE.toString(), AsState.DOWN.toString())
.setHandler(new THLocalAsInactToDwn(this, this.localFSM));
this.localFSM.createTransition(TransitionState.ASP_UP, AsState.INACTIVE.toString(), AsState.INACTIVE.toString())
.setHandler(new THLocalAsInactToInact(this, this.localFSM));
// ******************************************************************/
// STATE ACTIVE /
// ******************************************************************/
this.localFSM.createTransition(TransitionState.ASP_INACTIVE, AsState.ACTIVE.toString(), AsState.PENDING.toString())
.setHandler(new THLocalAsActToPendRemAspInac(this, this.localFSM));
this.localFSM.createTransition(TransitionState.ASP_DOWN, AsState.ACTIVE.toString(), AsState.PENDING.toString())
.setHandler(new THLocalAsActToPendRemAspDwn(this, this.localFSM));
this.localFSM.createTransition(TransitionState.ASP_ACTIVE, AsState.ACTIVE.toString(), AsState.ACTIVE.toString())
.setHandler(new THLocalAsActToActRemAspAct(this, this.localFSM));
this.localFSM.createTransition(TransitionState.ASP_UP, AsState.ACTIVE.toString(), AsState.PENDING.toString())
.setHandler(new THLocalAsActToPendRemAspInac(this, this.localFSM));
// ******************************************************************/
// STATE PENDING /
// ******************************************************************/
this.localFSM.createTransition(TransitionState.ASP_DOWN, AsState.PENDING.toString(), AsState.DOWN.toString())
.setHandler(new THNoTrans());
this.localFSM.createTransition(TransitionState.ASP_UP, AsState.PENDING.toString(), AsState.INACTIVE.toString())
.setHandler(new THNoTrans());
this.localFSM.createTransition(TransitionState.ASP_ACTIVE, AsState.PENDING.toString(), AsState.ACTIVE.toString())
.setHandler(new THLocalAsPendToAct(this, this.localFSM));
this.localFSM.createTransition(TransitionState.AS_DOWN, AsState.PENDING.toString(), AsState.DOWN.toString());
this.localFSM.createTransition(TransitionState.AS_INACTIVE, AsState.PENDING.toString(), AsState.INACTIVE.toString());
}
/**
* Every As has unique name
*
* @return String name of this As
*/
public String getName() {
return this.name;
}
public AspTrafficListener getAspTrafficListener() {
return aspTrafficListener;
}
public void setAspTrafficListener(AspTrafficListener aspTrafficListener) {
this.aspTrafficListener = aspTrafficListener;
}
public boolean isConnected() {
return this.isUp();
}
public boolean isUp() {
return this.state.getName().equals(State.STATE_ACTIVE);
}
public State getState() {
return this.state;
}
protected void setM3UAManagement(M3UAManagementImpl m3uaManagement) {
this.m3UAManagementImpl = m3uaManagement;
RoutingLabelFormat routingLabelFormat = this.m3UAManagementImpl.getRoutingLabelFormat();
switch (this.m3UAManagementImpl.getMaxAsForRoute()) {
case 1:
case 2:
if (this.m3UAManagementImpl.isUseLsbForLinksetSelection()) {
this.aspSlsMask = 0xfe;
this.aspSlsShiftPlaces = 0x01;
} else {
this.aspSlsMask = 0x7f;
this.aspSlsShiftPlaces = 0x00;
}
break;
case 3:
case 4:
if (this.m3UAManagementImpl.isUseLsbForLinksetSelection()) {
this.aspSlsMask = 0xfc;
this.aspSlsShiftPlaces = 0x02;
} else {
this.aspSlsMask = 0x3f;
this.aspSlsShiftPlaces = 0x00;
}
break;
case 5:
case 6:
case 7:
case 8:
if (this.m3UAManagementImpl.isUseLsbForLinksetSelection()) {
this.aspSlsMask = 0xf8;
this.aspSlsShiftPlaces = 0x04;
} else {
this.aspSlsMask = 0x1f;
this.aspSlsShiftPlaces = 0x00;
}
break;
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
if (this.m3UAManagementImpl.isUseLsbForLinksetSelection()) {
this.aspSlsMask = 0xf0;
this.aspSlsShiftPlaces = 0x04;
} else {
this.aspSlsMask = 0x0f;
this.aspSlsShiftPlaces = 0x00;
}
break;
default:
if (this.m3UAManagementImpl.isUseLsbForLinksetSelection()) {
this.aspSlsMask = 0xfe;
this.aspSlsShiftPlaces = 0x01;
} else {
this.aspSlsMask = 0x7f;
this.aspSlsShiftPlaces = 0x00;
}
break;
}
}
protected M3UAManagementImpl getM3UAManagement() {
return m3UAManagementImpl;
}
protected MessageFactory getMessageFactory() {
return messageFactory;
}
protected ParameterFactory getParameterFactory() {
return parameterFactory;
}
/**
* Get the list of {@link AspImpl} for this As
*
* @return
*/
public List getAspList() {
return this.appServerProcs.unmodifiable();
}
/**
* Get the {@link AsState} of this As
*
* @return
*/
// public AsState getState() {
// return AsState.getState(this.peerFSM.getState().getName());
// }
public FSM getPeerFSM() {
return peerFSM;
}
public FSM getLocalFSM() {
return localFSM;
}
/**
* Get the {@link RoutingContext} for this As
*
* @return
*/
public RoutingContext getRoutingContext() {
return this.rc;
}
public Functionality getFunctionality() {
return functionality;
}
public ExchangeType getExchangeType() {
return exchangeType;
}
public IPSPType getIpspType() {
return ipspType;
}
public NetworkAppearance getNetworkAppearance() {
return networkAppearance;
}
/**
* Set the {@link TrafficModeType}
*
* @param trMode
*/
protected void setTrafficModeType(TrafficModeType trMode) {
// TODO : Check if TrafficModeType is not null throw error?
this.trMode = trMode;
}
/**
* Get the {@link TrafficModeType}
*
* @return
*/
public TrafficModeType getTrafficModeType() {
return this.trMode;
}
/**
* Set default {@link TrafficModeType} which is loadshare
*/
protected void setDefaultTrafficModeType() {
// TODO : Check if TrafficModeType is not null throw error?
this.trMode = this.defaultTrafModType;
}
public TrafficModeType getDefaultTrafficModeType() {
return this.defaultTrafModType;
}
/**
* If the {@link TrafficModeType} is loadshare, set the minimum number of {@link AspImpl} that should be
* {@link org.restcomm.protocols.ss7.m3ua.impl.AspState#ACTIVE} before state of this As becomes {@link AsState#ACTIVE}
*
* @param lb
*/
protected void setMinAspActiveForLb(int lb) {
this.minAspActiveForLb = lb;
}
/**
* Get the minimum number of {@link AspImpl} that should be {@link org.restcomm.protocols.ss7.m3ua.impl.AspState#ACTIVE}
* before state of this As becomes {@link AsState#ACTIVE}. Used only if {@link TrafficModeType} is loadshare
*
* @return
*/
public int getMinAspActiveForLb() {
return this.minAspActiveForLb;
}
/**
* Add new {@link AspImpl} for this As.
*
* @param aspImpl
* @throws Exception throws exception if the Asp with same name already exist
*/
protected void addAppServerProcess(AspImpl aspImpl) throws Exception {
aspImpl.setAs(this);
appServerProcs.add(aspImpl);
this.resetSlsVsAspTable();
}
protected AspImpl removeAppServerProcess(String aspName) throws Exception {
AspImpl aspImpl = null;
for (FastList.Node n = this.appServerProcs.head(), end = this.appServerProcs.tail(); (n = n.getNext()) != end;) {
AspImpl aspTemp = (AspImpl) n.getValue();
if (aspTemp.getName().equals(aspName)) {
aspImpl = aspTemp;
break;
}
}
if (aspImpl == null) {
throw new Exception(String.format(M3UAOAMMessages.NO_ASP_FOUND, aspName));
}
FSM aspLocalFSM = aspImpl.getLocalFSM();
if (aspLocalFSM != null) {
AspState aspLocalState = AspState.getState(aspLocalFSM.getState().getName());
if (aspLocalState != AspState.DOWN) {
throw new Exception(String.format("ASP=%s local FSM is still %s. Bring it DOWN before removing from this As",
aspName, aspLocalState));
}
}
FSM aspPeerFSM = aspImpl.getPeerFSM();
if (aspPeerFSM != null) {
AspState aspPeerState = AspState.getState(aspPeerFSM.getState().getName());
if (aspPeerState != AspState.DOWN) {
throw new Exception(String.format("ASP=%s peer FSM is still %s. Bring it DOWN before removing from this As",
aspName, aspPeerState));
}
}
this.appServerProcs.remove(aspImpl);
aspImpl.setAs(null);
if (aspLocalFSM != null) {
aspLocalFSM.cancel();
}
if (aspPeerFSM != null) {
aspPeerFSM.cancel();
}
this.resetSlsVsAspTable();
return aspImpl;
}
/**
* write the {@link PayloadData} to underlying {@link AspImpl}. If the state of As is PENDING, the PayloadData is stored in
* pending queue.
*
* @param message
* @throws IOException
*/
protected void write(PayloadData message) throws IOException {
FSM fsm = null;
boolean isASPLocalFsm = true;
if (this.functionality == Functionality.AS
|| (this.functionality == Functionality.SGW && this.exchangeType == ExchangeType.DE)
|| (this.functionality == Functionality.IPSP && this.ipspType == IPSPType.CLIENT)
|| (this.functionality == Functionality.IPSP && this.ipspType == IPSPType.SERVER && this.exchangeType == ExchangeType.DE)) {
fsm = this.peerFSM;
} else {
fsm = this.localFSM;
isASPLocalFsm = false;
}
int sls = message.getData().getSLS();
switch (AsState.getState(fsm.getState().getName())) {
case ACTIVE:
boolean aspFound = false;
// TODO : Algo to select correct ASP
int aspIndex = (sls & this.aspSlsMask);
aspIndex = (aspIndex >> this.aspSlsShiftPlaces);
AspImpl aspCong = null;
for (int i = 0; i < this.appServerProcs.size(); i++) {
AspImpl aspTemp = (AspImpl) this.appServerProcs.get(this.slsVsAspTable[aspIndex++]);
FSM aspFsm = null;
if (isASPLocalFsm) {
aspFsm = aspTemp.getLocalFSM();
} else {
aspFsm = aspTemp.getPeerFSM();
}
if (AspState.getState(aspFsm.getState().getName()) == AspState.ACTIVE) {
if (aspTemp.getAspFactory().getAssociation().getCongestionLevel() > 1) {
aspCong = aspTemp;
} else {
aspTemp.getAspFactory().write(message);
aspFound = true;
if (aspTrafficListener != null) {
try {
aspTrafficListener.onAspMessage(aspTemp.getName(), message.getData().getData());
} catch (Exception e) {
logger.error(String.format(
"Error while calling aspTrafficListener=%s onAspMessage method for Asp=%s",
aspTrafficListener, aspTemp));
}
}
break;
}
}
}// for
if (!aspFound) {
if (aspCong != null) {
aspCong.getAspFactory().write(message);
aspFound = true;
if (aspTrafficListener != null) {
try {
aspTrafficListener.onAspMessage(aspCong.getName(), message.getData().getData());
} catch (Exception e) {
logger.error(String.format(
"Error while calling aspTrafficListener=%s onAspMessage method for Asp=%s",
aspTrafficListener, aspCong));
}
}
}
}
if (!aspFound) {
// This should never happen.
logger.error(String.format("Tx : no ACTIVE Asp for message=%s", message));
}
break;
case PENDING:
if (logger.isInfoEnabled()) {
logger.info(String.format("Adding the PayloadData=%s to PendingQueue for AS=%s", message.toString(),
this.name));
}
this.penQueue.add(message);
break;
default:
throw new IOException(String.format("As name=%s is not ACTIVE", this.name));
}
}
protected void clearPendingQueue() {
if (logger.isDebugEnabled()) {
if (this.penQueue.size() > 0) {
logger.debug(String.format("Cleaning %d PayloadData message from pending queue of As name=%s",
this.penQueue.size(), this.name));
}
}
this.penQueue.clear();
}
protected void sendPendingPayloadData(AspImpl aspImpl) {
PayloadData payload = null;
while ((payload = this.penQueue.poll()) != null) {
aspImpl.getAspFactory().write(payload);
}
}
/**
* XML Serialization/Deserialization
*/
protected static final XMLFormat AS_XML = new XMLFormat(AsImpl.class) {
@Override
public void read(javolution.xml.XMLFormat.InputElement xml, AsImpl asImpl) throws XMLStreamException {
asImpl.name = xml.getAttribute(NAME, "");
asImpl.minAspActiveForLb = xml.getAttribute(MIN_ASP_ACT_LB).toInt();
asImpl.functionality = Functionality.getFunctionality(xml.getAttribute("functionality", ""));
asImpl.exchangeType = ExchangeType.getExchangeType(xml.getAttribute("exchangeType", ""));
asImpl.ipspType = IPSPType.getIPSPType(xml.getAttribute("ipspType", ""));
asImpl.rc = xml.get(ROUTING_CONTEXT, RoutingContextImpl.class);
asImpl.networkAppearance = xml.get(NETWORK_APPEARANCE, NetworkAppearanceImpl.class);
asImpl.trMode = xml.get(TRAFFIC_MODE, TrafficModeTypeImpl.class);
asImpl.defaultTrafModType = xml.get(DEFAULT_TRAFFIC_MODE, TrafficModeTypeImpl.class);
asImpl.appServerProcs = xml.get(ASP_LIST, FastList.class);
asImpl.init();
}
@Override
public void write(AsImpl asImpl, javolution.xml.XMLFormat.OutputElement xml) throws XMLStreamException {
xml.setAttribute(NAME, asImpl.name);
xml.setAttribute(MIN_ASP_ACT_LB, asImpl.minAspActiveForLb);
xml.setAttribute("functionality", asImpl.functionality.getType());
xml.setAttribute("exchangeType", asImpl.exchangeType.getType());
if (asImpl.ipspType != null) {
xml.setAttribute("ipspType", asImpl.ipspType.getType());
}
xml.add((RoutingContextImpl) asImpl.rc, ROUTING_CONTEXT, RoutingContextImpl.class);
xml.add((NetworkAppearanceImpl) asImpl.networkAppearance, NETWORK_APPEARANCE, NetworkAppearanceImpl.class);
xml.add((TrafficModeTypeImpl) asImpl.trMode, TRAFFIC_MODE, TrafficModeTypeImpl.class);
xml.add((TrafficModeTypeImpl) asImpl.defaultTrafModType, DEFAULT_TRAFFIC_MODE, TrafficModeTypeImpl.class);
xml.add(asImpl.appServerProcs, ASP_LIST, FastList.class);
}
};
public void show(StringBuffer sb) {
sb.append(M3UAOAMMessages.SHOW_AS_NAME).append(this.name).append(M3UAOAMMessages.SHOW_FUNCTIONALITY)
.append(this.functionality).append(M3UAOAMMessages.SHOW_MODE).append(this.exchangeType);
if (this.functionality == Functionality.IPSP) {
sb.append(M3UAOAMMessages.SHOW_IPSP_TYPE).append(this.ipspType);
}
if (this.rc != null) {
sb.append(" rc=").append(Arrays.toString(this.rc.getRoutingContexts()));
}
if (this.trMode != null) {
sb.append(" trMode=").append(this.trMode.getMode());
}
sb.append(" defaultTrMode=").append(this.defaultTrafModType.getMode());
if (this.networkAppearance != null) {
sb.append(" na=").append(this.networkAppearance.getNetApp());
}
if (this.getLocalFSM() != null) {
sb.append(M3UAOAMMessages.SHOW_LOCAL_FSM_STATE).append(this.getLocalFSM().getState());
}
if (this.getPeerFSM() != null) {
sb.append(M3UAOAMMessages.SHOW_PEER_FSM_STATE).append(this.getPeerFSM().getState());
}
sb.append(M3UAOAMMessages.NEW_LINE);
sb.append(M3UAOAMMessages.SHOW_ASSIGNED_TO);
for (FastList.Node n = this.appServerProcs.head(), end = this.appServerProcs.tail(); (n = n.getNext()) != end;) {
AspImpl aspTemp = (AspImpl) n.getValue();
AspFactoryImpl aspFactoryImpl = aspTemp.getAspFactory();
sb.append(M3UAOAMMessages.TAB).append(M3UAOAMMessages.SHOW_ASP_NAME).append(aspFactoryImpl.getName())
.append(M3UAOAMMessages.SHOW_STARTED).append(aspFactoryImpl.getStatus());
sb.append(M3UAOAMMessages.NEW_LINE);
}
}
/**
* Add the {@link AsStateListener} listening for As state
*
* @param listener
*/
protected void addAsStateListener(AsStateListener listener) {
this.asStateListeners.add(listener);
}
/**
* Remove already added {@link AsStateListener}
*
* @param listener
*/
protected void removeAsStateListener(AsStateListener listener) {
this.asStateListeners.remove(listener);
}
public FastSet getAsStateListeners() {
return asStateListeners;
}
private void resetSlsVsAspTable() {
int aspNumber = 0;
for (int count = 0; count < 256; count++) {
if (aspNumber >= this.appServerProcs.size()) {
aspNumber = 0;
}
this.slsVsAspTable[count] = aspNumber++;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy