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.
/*
* 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.client.impl.parser;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.jdiameter.api.Answer;
import org.jdiameter.api.ApplicationId;
import org.jdiameter.api.Avp;
import org.jdiameter.api.AvpDataException;
import org.jdiameter.api.AvpSet;
import org.jdiameter.api.InternalException;
import org.jdiameter.client.api.IEventListener;
import org.jdiameter.client.api.IMessage;
import org.jdiameter.client.api.controller.IPeer;
import org.jdiameter.client.impl.router.RouterImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Represents a Diameter message.
*
* @author [email protected]
* @author Alexandre Mendonca
* @author Bartosz Baranowski
*/
@SuppressWarnings("all") //3rd party lib
public class MessageImpl implements IMessage {
private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(MessageImpl.class);
private static final MessageParser parser = new MessageParser();
int state = STATE_NOT_SENT;
short version = 1, flags;
int commandCode;
long applicationId;
long hopByHopId;
boolean notMutableHopByHop;
long endToEndId;
AvpSetImpl avpSet;
boolean isNetworkRequest = false;
transient IPeer peer;
transient TimerTask timerTask;
transient IEventListener listener;
// Cached result for getApplicationIdAvps() method. It is called extensively and takes some time.
// Potential place for dirt, but Application IDs don't change during message life time.
transient List applicationIds;
/**
* Create empty message
*
* @param parser
* @param commandCode
* @param appId
*/
MessageImpl(int commandCode, long appId) {
this.commandCode = commandCode;
this.applicationId = appId;
this.avpSet = new AvpSetImpl();
this.endToEndId = parser.getNextEndToEndId();
}
/**
* Create empty message
*
* @param parser
* @param commandCode
* @param applicationId
* @param flags
* @param hopByHopId
* @param endToEndId
* @param avpSet
*/
MessageImpl(int commandCode, long applicationId, short flags, long hopByHopId, long endToEndId, AvpSetImpl avpSet) {
this(commandCode, applicationId);
this.flags = flags;
this.hopByHopId = hopByHopId;
this.endToEndId = endToEndId;
if (avpSet != null) {
this.avpSet = avpSet;
}
}
// /**
// * Create empty message
// *
// * @param metaData
// * @param parser
// * @param commandCode
// * @param appId
// */
// MessageImpl(MetaData metaData, MessageParser parser, int commandCode, long appId) {
// this(commandCode, appId);
// try {
// getAvps().addAvp(Avp.ORIGIN_HOST, metaData.getLocalPeer().getUri().getFQDN(), true, false, true);
// getAvps().addAvp(Avp.ORIGIN_REALM, metaData.getLocalPeer().getRealmName(), true, false, true);
// }
// catch (Exception e) {
// logger.debug("Can not create message", e);
// }
// }
/**
* Create Answer
*
* @param request parent request
*/
private MessageImpl(MessageImpl request) {
this(request.getCommandCode(), request.getHeaderApplicationId());
copyHeader(request);
setRequest(false);
parser.copyBasicAvps(this, request, true);
// if we set REQUEST_TABLE_SIZE to 0, we store routing info at answer
if (RouterImpl.REQUEST_TABLE_SIZE == 0) {
addRoutingInfo(request);
}
}
private String[] routingInfo = { null, null };
private void addRoutingInfo(MessageImpl request) {
for (Avp a : request.getAvps()) {
if (a.getCode() == Avp.ORIGIN_HOST) {
try {
routingInfo[0] = a.getDiameterIdentity();
if (routingInfo[1] != null) {
return;
}
} catch (AvpDataException e) {
logger.error("Unable to read Origin-Host AVP value for storing Routing Info", e);
}
} else if (a.getCode() == Avp.ORIGIN_REALM) {
try {
routingInfo[1] = a.getDiameterIdentity();
if (routingInfo[0] != null) {
return;
}
} catch (AvpDataException e) {
logger.error("Unable to read Origin-Realm AVP value for storing Routing Info", e);
}
}
}
}
public String[] getRoutingInfo() {
return routingInfo;
}
@Override
public byte getVersion() {
return (byte) version;
}
@Override
public boolean isRequest() {
return (flags & 0x80) != 0;
}
@Override
public void setRequest(boolean b) {
if (b) {
flags |= 0x80;
} else {
flags &= 0x7F;
}
}
@Override
public boolean isProxiable() {
return (flags & 0x40) != 0;
}
@Override
public void setProxiable(boolean b) {
if (b) {
flags |= 0x40;
} else {
flags &= 0xBF;
}
}
@Override
public boolean isError() {
return (flags & 0x20) != 0;
}
@Override
public void setError(boolean b) {
if (b) {
flags |= 0x20;
} else {
flags &= 0xDF;
}
}
@Override
public boolean isReTransmitted() {
return (flags & 0x10) != 0;
}
@Override
public void setReTransmitted(boolean b) {
if (b) {
flags |= 0x10;
} else {
flags &= 0xEF;
}
}
@Override
public int getCommandCode() {
return this.commandCode;
}
@Override
public String getSessionId() {
try {
Avp avpSessionId = avpSet.getAvp(Avp.SESSION_ID);
return avpSessionId != null ? avpSessionId.getUTF8String() : null;
} catch (AvpDataException ade) {
logger.error("Failed to fetch Session-Id", ade);
return null;
}
}
@Override
public Answer createAnswer() {
MessageImpl answer = new MessageImpl(this);
return answer;
}
@Override
public Answer createAnswer(long resultCode) {
MessageImpl answer = new MessageImpl(this);
try {
answer.getAvps().addAvp(Avp.RESULT_CODE, resultCode, true, false, true);
} catch (Exception e) {
logger.debug("Can not create answer message", e);
}
//Its set in constructor.
//answer.setRequest(false);
return answer;
}
@Override
public Answer createAnswer(long vendorId, long experimentalResultCode) {
MessageImpl answer = new MessageImpl(this);
try {
AvpSet exp_code = answer.getAvps().addGroupedAvp(297, true, false);
exp_code.addAvp(Avp.VENDOR_ID, vendorId, true, false, true);
exp_code.addAvp(Avp.EXPERIMENTAL_RESULT_CODE, experimentalResultCode, true, false, true);
} catch (Exception e) {
logger.debug("Can not create answer message", e);
}
answer.setRequest(false);
return answer;
}
@Override
public long getApplicationId() {
return applicationId;
}
@Override
public ApplicationId getSingleApplicationId() {
return getSingleApplicationId(this.applicationId);
}
@Override
public List getApplicationIdAvps() {
if (this.applicationIds != null) {
return this.applicationIds;
}
List rc = new ArrayList();
try {
AvpSet authAppId = avpSet.getAvps(Avp.AUTH_APPLICATION_ID);
for (Avp anAuthAppId : authAppId) {
rc.add(ApplicationId.createByAuthAppId((anAuthAppId).getInteger32()));
}
AvpSet accAppId = avpSet.getAvps(Avp.ACCT_APPLICATION_ID);
for (Avp anAccAppId : accAppId) {
rc.add(ApplicationId.createByAccAppId((anAccAppId).getInteger32()));
}
AvpSet specAppId = avpSet.getAvps(Avp.VENDOR_SPECIFIC_APPLICATION_ID);
for (Avp aSpecAppId : specAppId) {
long vendorId = 0, acctApplicationId = 0, authApplicationId = 0;
AvpSet avps = (aSpecAppId).getGrouped();
for (Avp localAvp : avps) {
if (localAvp.getCode() == Avp.VENDOR_ID) {
vendorId = localAvp.getUnsigned32();
}
if (localAvp.getCode() == Avp.AUTH_APPLICATION_ID) {
authApplicationId = localAvp.getUnsigned32();
}
if (localAvp.getCode() == Avp.ACCT_APPLICATION_ID) {
acctApplicationId = localAvp.getUnsigned32();
}
}
if (authApplicationId != 0) {
rc.add(ApplicationId.createByAuthAppId(vendorId, authApplicationId));
}
if (acctApplicationId != 0) {
rc.add(ApplicationId.createByAccAppId(vendorId, acctApplicationId));
}
}
} catch (Exception exception) {
return new ArrayList();
}
this.applicationIds = rc;
return this.applicationIds;
}
@Override
public ApplicationId getSingleApplicationId(long applicationId) {
logger.debug("In getSingleApplicationId for application id [{}]", applicationId);
List appIds = getApplicationIdAvps();
logger.debug("Application Ids in this message are:");
ApplicationId firstOverall = null;
ApplicationId firstWithZeroVendor = null;
ApplicationId firstWithNonZeroVendor = null;
for (ApplicationId id : appIds) {
logger.debug("[{}]", id);
if (firstOverall == null) {
firstOverall = id;
}
if (applicationId != 0) {
if (firstWithZeroVendor == null && id.getVendorId() == 0
&& (applicationId == id.getAuthAppId() || applicationId == id.getAcctAppId())) {
firstWithZeroVendor = id;
}
if (firstWithNonZeroVendor == null && id.getVendorId() != 0
&& (applicationId == id.getAuthAppId() || applicationId == id.getAcctAppId())) {
firstWithNonZeroVendor = id;
break;
}
}
}
ApplicationId toReturn = null;
if (firstWithNonZeroVendor != null) {
toReturn = firstWithNonZeroVendor;
logger.debug("Returning [{}] as the first application id because its the first vendor specific one found",
toReturn);
} else if (firstWithZeroVendor != null) {
toReturn = firstWithZeroVendor;
logger.debug("Returning [{}] as the first application id because there are no vendor specific ones found",
toReturn);
} else {
toReturn = firstOverall;
logger.debug("Returning [{}] as the first application id because none with the requested app ids were found",
toReturn);
}
if (toReturn == null) {
// TODO: ammendonca: improve this (find vendor? use common app list map?)
logger.debug(
"There are no Application-Id AVPs. Using the value in the header and assuming as Auth Application-Id [{}]",
this.applicationId);
toReturn = ApplicationId.createByAuthAppId(this.applicationId);
}
return toReturn;
}
@Override
public long getHopByHopIdentifier() {
return hopByHopId;
}
@Override
public long getEndToEndIdentifier() {
return endToEndId;
}
@Override
public AvpSet getAvps() {
return avpSet;
}
protected void copyHeader(MessageImpl request) {
endToEndId = request.endToEndId;
hopByHopId = request.hopByHopId;
version = request.version;
flags = request.flags;
peer = request.peer;
}
@Override
public Avp getResultCode() {
return getAvps().getAvp(Avp.RESULT_CODE);
}
@Override
public void setNetworkRequest(boolean isNetworkRequest) {
this.isNetworkRequest = isNetworkRequest;
}
@Override
public boolean isNetworkRequest() {
return isNetworkRequest;
}
@Override
public boolean isWrapperFor(Class> aClass) throws InternalException {
return false;
}
@Override
public T unwrap(Class aClass) throws InternalException {
return null;
}
// Inner API
@Override
public void setHopByHopIdentifier(long hopByHopId) {
if (hopByHopId < 0) {
this.hopByHopId = -hopByHopId;
this.notMutableHopByHop = true;
} else {
if (!this.notMutableHopByHop) {
this.hopByHopId = hopByHopId;
}
}
}
@Override
public void setEndToEndIdentifier(long endByEndId) {
this.endToEndId = endByEndId;
}
@Override
public IPeer getPeer() {
return peer;
}
@Override
public void setPeer(IPeer peer) {
this.peer = peer;
}
@Override
public int getState() {
return state;
}
@Override
public long getHeaderApplicationId() {
return applicationId;
}
@Override
public void setHeaderApplicationId(long applicationId) {
this.applicationId = applicationId;
}
@Override
public int getFlags() {
return flags;
}
@Override
public void setState(int newState) {
state = newState;
}
@Override
public void createTimer(ScheduledExecutorService scheduledFacility, long timeOut, TimeUnit timeUnit) {
timerTask = new TimerTask(this);
timerTask.setTimerHandler(scheduledFacility, scheduledFacility.schedule(timerTask, timeOut, timeUnit));
}
@Override
public void runTimer() {
if (timerTask != null && !timerTask.isDone() && !timerTask.isCancelled()) {
timerTask.run();
}
}
@Override
public boolean isTimeOut() {
return timerTask != null && timerTask.isDone() && !timerTask.isCancelled();
}
@Override
public void setListener(IEventListener listener) {
this.listener = listener;
}
@Override
public IEventListener getEventListener() {
return listener;
}
@Override
public void clearTimer() {
if (timerTask != null) {
timerTask.cancel();
}
}
@Override
public String toString() {
return "MessageImpl{" + "commandCode=" + commandCode + ", flags=" + flags + '}';
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
MessageImpl message = (MessageImpl) o;
return applicationId == message.applicationId && commandCode == message.commandCode &&
endToEndId == message.endToEndId && hopByHopId == message.hopByHopId;
}
@Override
public int hashCode() {
long result;
result = commandCode;
result = 31 * result + applicationId;
result = 31 * result + hopByHopId;
result = 31 * result + endToEndId;
return Long.valueOf(result).hashCode();
}
@Override
public String getDuplicationKey() {
try {
return getDuplicationKey(getAvps().getAvp(Avp.ORIGIN_HOST).getDiameterIdentity(), getEndToEndIdentifier());
} catch (AvpDataException e) {
throw new IllegalArgumentException(e);
}
}
@Override
public String getDuplicationKey(String host, long endToEndId) {
return host + endToEndId;
}
@Override
public Object clone() {
try {
return parser.createMessage(parser.encodeMessage(this));
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
protected static class TimerTask implements Runnable {
ScheduledFuture timerHandler;
MessageImpl message;
ScheduledExecutorService scheduledFacility;
public TimerTask(MessageImpl message) {
this.message = message;
}
public void setTimerHandler(ScheduledExecutorService scheduledFacility, ScheduledFuture timerHandler) {
this.scheduledFacility = scheduledFacility;
this.timerHandler = timerHandler;
}
@Override
public void run() {
try {
if (message != null && message.state != STATE_ANSWERED) {
IEventListener listener = null;
if (message.listener instanceof IEventListener) {
listener = message.listener;
}
if (listener != null && listener.isValid()) {
if (message.peer != null) {
message.peer.remMessage(message);
}
message.listener.timeoutExpired(message);
}
}
} catch (Throwable e) {
logger.debug("Can not process timeout", e);
}
}
public void cancel() {
if (timerHandler != null) {
timerHandler.cancel(true);
if (scheduledFacility instanceof ThreadPoolExecutor && timerHandler instanceof Runnable) {
((ThreadPoolExecutor) scheduledFacility).remove((Runnable) timerHandler);
}
}
message = null;
}
public boolean isDone() {
return timerHandler != null && timerHandler.isDone();
}
public boolean isCancelled() {
return timerHandler == null || timerHandler.isCancelled();
}
}
}