Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,30 @@

package org.jdiameter.client.impl;

import org.jdiameter.api.*;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

import org.jdiameter.api.Answer;
import org.jdiameter.api.ApplicationId;
import org.jdiameter.api.Avp;
import org.jdiameter.api.EventListener;
import org.jdiameter.api.IllegalDiameterStateException;
import org.jdiameter.api.InternalException;
import org.jdiameter.api.Message;
import org.jdiameter.api.NetworkReqListener;
import org.jdiameter.api.OverloadException;
import org.jdiameter.api.RawSession;
import org.jdiameter.api.Request;
import org.jdiameter.api.RouteException;
import org.jdiameter.client.api.IAssembler;
import org.jdiameter.client.api.IContainer;
import org.jdiameter.client.api.IMessage;
import org.jdiameter.client.api.IRequest;
import org.jdiameter.client.api.ISession;
import org.jdiameter.client.api.parser.IMessageParser;
import org.jdiameter.common.api.data.ISessionDatasource;

import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Implementation for {@link ISession}
Expand All @@ -41,6 +56,10 @@
*/
public class SessionImpl extends BaseSessionImpl implements ISession {

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

private Semaphore lock = new Semaphore(1); // container lock

SessionImpl(IContainer container) {
setContainer(container);
try {
Expand All @@ -52,8 +71,15 @@ public class SessionImpl extends BaseSessionImpl implements ISession {
}

void setContainer(IContainer container) {
this.container = container;
this.parser = (IMessageParser) container.getAssemblerFacility().getComponentInstance(IMessageParser.class);
try {
lock.acquire(); // allow container change only if not releasing
this.container = container;
this.parser = (IMessageParser) container.getAssemblerFacility().getComponentInstance(IMessageParser.class);
} catch (InterruptedException e) {
logger.error("failure getting lock", e);
} finally {
lock.release();
}
}

public void send(Message message, EventListener<Request, Answer> listener) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException {
Expand Down Expand Up @@ -132,14 +158,25 @@ public Request createRequest(Request prevRequest) {

public void release() {
isValid = false;
if (container != null) {
container.removeSessionListener(sessionId);
// FIXME
container.getAssemblerFacility().getComponentInstance(ISessionDatasource.class).removeSession(sessionId);
}
container = null;
parser = null;
reqListener = null;

try {
lock.acquire(); // prevent container NullPointerException

if (container != null) {
container.removeSessionListener(sessionId);
IAssembler assembler = container.getAssemblerFacility();
ISessionDatasource datasource = assembler.getComponentInstance(ISessionDatasource.class);
datasource.removeSession(sessionId);
}

container = null;
parser = null;
reqListener = null;
} catch (InterruptedException e) {
logger.error("failure getting lock", e);
} finally {
lock.release();
}
}

public boolean isWrapperFor(Class<?> iface) throws InternalException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.net.InetAddress;
import java.net.URISyntaxException;
import java.net.UnknownServiceException;
import java.util.Arrays;
import java.util.Date;

import org.jdiameter.api.Avp;
Expand All @@ -45,15 +46,15 @@ class AvpImpl implements Avp {

private static final long serialVersionUID = 1L;
private static final ElementParser parser = new ElementParser();
int avpCode;
long vendorID;
private int avpCode;
private long vendorID;

boolean isMandatory = false;
boolean isEncrypted = false;
boolean isVendorSpecific = false;
private boolean isMandatory = false;
private boolean isEncrypted = false;
private boolean isVendorSpecific = false;

byte[] rawData = new byte[0];
AvpSet groupedData;
private byte[] rawData = null;
private AvpSet groupedData = new AvpSetImpl();

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

Expand All @@ -65,7 +66,10 @@ class AvpImpl implements Avp {
isVendorSpecific = (flags & 0x80) != 0;
//
vendorID = vnd;
rawData = data;

if (data != null) { // any data string/int/encoded-grouped
rawData = Arrays.copyOf(data, data.length);
}
}

AvpImpl(Avp avp) {
Expand All @@ -75,13 +79,19 @@ class AvpImpl implements Avp {
isEncrypted = avp.isEncrypted();
isVendorSpecific = avp.isVendorId();
try {
rawData = avp.getRaw();
if (rawData == null || rawData.length == 0) {
groupedData = avp.getGrouped();
}
}
catch (AvpDataException e) {
logger.debug("Can not create Avp", e);
byte[] data = avp.getRaw();
if (data != null) { // simple AVP
rawData = Arrays.copyOf(data, data.length);
} else {
// grouped AVP
AvpSet grouped = avp.getGrouped();

if (grouped != null) {
groupedData = parser.decodeAvpSet(parser.encodeAvpSet(grouped)); // copy all
}
}
} catch (Exception e) {
logger.error("Can not create Avp", e);
}
}

Expand Down Expand Up @@ -224,13 +234,12 @@ public URI getDiameterURI() throws AvpDataException {

public AvpSet getGrouped() throws AvpDataException {
try {
if (groupedData == null) {
groupedData = parser.decodeAvpSet(rawData);
rawData = new byte[0];
}
return groupedData;
}
catch (Exception e) {
if (rawData != null) {
return parser.decodeAvpSet(rawData);
} else {
return groupedData;
}
} catch (Exception e) {
throw new AvpDataException(e, this);
}
}
Expand All @@ -244,7 +253,7 @@ public <T> T unwrap(Class<T> aClass) throws InternalException {
}

public byte[] getRawData() {
return (rawData == null || rawData.length == 0) ? parser.encodeAvpSet(groupedData) : rawData;
return rawData;
}

// Caching toString.. Avp shouldn't be modified once created.
Expand All @@ -253,7 +262,8 @@ public byte[] getRawData() {
@Override
public String toString() {
if(toString == null) {
this.toString = new StringBuffer("AvpImpl [avpCode=").append(avpCode).append(", vendorID=").append(vendorID).append("]@").append(super.hashCode()).toString();
this.toString = new StringBuffer("AvpImpl [avpCode=").append(avpCode).append(", vendorID=").append(vendorID)
.append(", len=").append((rawData != null) ? rawData.length : null).append("]@").append(super.hashCode()).toString();
}

return this.toString;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@
import java.util.Iterator;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.jdiameter.api.Avp;
import org.jdiameter.api.AvpDataException;
import org.jdiameter.api.AvpSet;
import org.jdiameter.api.InternalException;
import org.jdiameter.api.URI;
Expand All @@ -53,6 +56,8 @@ class AvpSetImpl implements AvpSet {

// FIXME: by default 3588.4-1 says: 'M' should be set to true;
// FIXME: by default 3588.x says: if grouped has at least on AVP with 'M' set, it also has to have 'M' set! - TODO: add backmapping.

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

private static final long serialVersionUID = 1L;
private static final ElementParser parser = new ElementParser();
Expand Down Expand Up @@ -187,10 +192,15 @@ public Avp insertAvp(int index, int avpCode, long value, long vndId, boolean mFl
}

public AvpSet insertGroupedAvp(int index, int avpCode) {
AvpImpl res = new AvpImpl(avpCode, 0, 0, new byte[0]);
res.groupedData = new AvpSetImpl();
AvpImpl res = new AvpImpl(avpCode, 0, 0, null);
this.avps.add(index, res);
return res.groupedData;

try {
return res.getGrouped();
} catch (AvpDataException e) {
logger.error("insert avp failed", e);
}
return null;
}

public int size() {
Expand Down Expand Up @@ -421,26 +431,41 @@ public Avp addAvp(int avpCode, Date value, long vndId, boolean mFlag, boolean pF
}

public AvpSet addGroupedAvp(int avpCode) {
AvpImpl res = new AvpImpl(avpCode, 0, 0, new byte[0] );
res.groupedData = new AvpSetImpl();
AvpImpl res = new AvpImpl(avpCode, 0, 0, null);
this.avps.add(res);
return res.groupedData;

try {
return res.getGrouped();
} catch (AvpDataException e) {
logger.error("add avp failed", e);
}
return null;
}

public AvpSet addGroupedAvp(int avpCode, boolean mFlag, boolean pFlag) {
int flags = ((mFlag ? 0x40:0) | (pFlag ? 0x20:0));
AvpImpl res = new AvpImpl(avpCode, flags, 0, new byte[0] );
res.groupedData = new AvpSetImpl();
AvpImpl res = new AvpImpl(avpCode, flags, 0, null);
this.avps.add(res);
return res.groupedData;

try {
return res.getGrouped();
} catch (AvpDataException e) {
logger.error("add avp failed", e);
}
return null;
}

public AvpSet addGroupedAvp(int avpCode, long vndId, boolean mFlag, boolean pFlag) {
int flags = ((vndId !=0 ? 0x80:0) | (mFlag ? 0x40:0) | (pFlag ? 0x20:0));
AvpImpl res = new AvpImpl(avpCode, flags, vndId, new byte[0] );
res.groupedData = new AvpSetImpl();
AvpImpl res = new AvpImpl(avpCode, flags, vndId, null);
this.avps.add(res);
return res.groupedData;

try {
return res.getGrouped();
} catch (AvpDataException e) {
logger.error("add avp failed", e);
}
return null;
}

public Avp insertAvp(int index, int avpCode, byte[] value) {
Expand Down Expand Up @@ -654,18 +679,28 @@ public Avp insertAvp(int index, int avpCode, Date value, long vndId, boolean mFl

public AvpSet insertGroupedAvp(int index, int avpCode, boolean mFlag, boolean pFlag) {
int flags = ((mFlag ? 0x40:0) | (pFlag ? 0x20:0));
AvpImpl res = new AvpImpl(avpCode, flags, 0, new byte[0] );
res.groupedData = new AvpSetImpl();
AvpImpl res = new AvpImpl(avpCode, flags, 0, null);
this.avps.add(index, res);
return res.groupedData;

try {
return res.getGrouped();
} catch (AvpDataException e) {
logger.error("insert avp failed", e);
}
return null;
}

public AvpSet insertGroupedAvp(int index, int avpCode, long vndId, boolean mFlag, boolean pFlag) {
int flags = ((vndId !=0 ? 0x80:0) | (mFlag ? 0x40:0) | (pFlag ? 0x20:0));
AvpImpl res = new AvpImpl(avpCode, flags, vndId, new byte[0] );
res.groupedData = new AvpSetImpl();
AvpImpl res = new AvpImpl(avpCode, flags, vndId, null);
this.avps.add(index, res);
return res.groupedData;

try {
return res.getGrouped();
} catch (AvpDataException e) {
logger.error("insert avp failed", e);
}
return null;
}

public boolean isWrapperFor(Class<?> aClass) throws InternalException {
Expand Down
Loading