}
}
}
-
final byte[] msgBody = new byte[MIN_MSG_LENGTH + optParamsLength];
int offset = 0;
if (openAS > Values.UNSIGNED_SHORT_MAX_VALUE) {
openAS = AS_TRANS;
}
-
System.arraycopy(ByteArray.longToBytes(openAS, AS_SIZE), 0, msgBody, offset, AS_SIZE);
offset += AS_SIZE;
index += entry.getValue();
}
}
-
final byte[] ret = MessageUtil.formatMessage(TYPE, msgBody);
logger.trace("Open message serialized to: {}", Arrays.toString(ret));
return ret;
if (UnsignedBytes.toInt(body[0]) != BGP_VERSION) {
throw new BGPDocumentedException("BGP Protocol version " + UnsignedBytes.toInt(body[0]) + " not supported.", BGPError.VERSION_NOT_SUPPORTED);
}
-
int offset = VERSION_SIZE;
final AsNumber as = new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(body, offset, AS_SIZE)));
offset += AS_SIZE;
if (holdTime == 1 || holdTime == 2) {
throw new BGPDocumentedException("Hold time value not acceptable.", BGPError.HOLD_TIME_NOT_ACC);
}
-
Ipv4Address bgpId = null;
try {
bgpId = Ipv4Util.addressForBytes(ByteArray.subByte(body, offset, BGP_ID_SIZE));
if (bytes == null || bytes.length == 0) {
throw new IllegalArgumentException("Byte array cannot be null or empty.");
}
-
logger.trace("Started parsing of BGP parameter: {}", Arrays.toString(bytes));
int byteOffset = 0;
while (byteOffset < bytes.length) {
if (byteOffset + 2 >= bytes.length) {
- // FIXME: throw a BGPDocumentedException here?
- throw new IllegalArgumentException("Malformed parameter encountered (" + (bytes.length - byteOffset) + " bytes left)");
+ throw new BGPDocumentedException("Malformed parameter encountered (" + (bytes.length - byteOffset) + " bytes left)", BGPError.OPT_PARAM_NOT_SUPPORTED);
}
-
final int paramType = UnsignedBytes.toInt(bytes[byteOffset++]);
final int paramLength = UnsignedBytes.toInt(bytes[byteOffset++]);
final byte[] paramBody = ByteArray.subByte(bytes, byteOffset, paramLength);
} catch (final BGPParsingException e) {
throw new BGPDocumentedException("Optional parameter not parsed", BGPError.UNSPECIFIC_OPEN_ERROR, e);
}
-
if (param != null) {
params.add(param);
} else {
logger.debug("Ignoring BGP Parameter type: {}", paramType);
}
}
-
logger.trace("Parsed BGP parameters: {}", Arrays.toString(params.toArray()));
}
}
public final class BGPSessionNegotiator extends AbstractSessionNegotiator<Notification, BGPSessionImpl> {
// 4 minutes recommended in http://tools.ietf.org/html/rfc4271#section-8.2.2
- // FIXME to actual value
- protected static final int INITIAL_HOLDTIMER = 1;
+ protected static final int INITIAL_HOLDTIMER = 4;
@VisibleForTesting
public enum State {
@Immutable
public final class HexDumpBGPFileParser {
private static final int MINIMAL_LENGTH = 19;
- private static final Logger logger = LoggerFactory.getLogger(HexDumpBGPFileParser.class);
+ private static final Logger LOG = LoggerFactory.getLogger(HexDumpBGPFileParser.class);
private static final String FF_16 = Strings.repeat("FF", 16);
private HexDumpBGPFileParser() {
// search for 16 FFs
final List<byte[]> messages = Lists.newLinkedList();
- int idx = 0;
- while ((idx = content.indexOf(FF_16, idx)) > -1) {
+ int idx = content.indexOf(FF_16, 0);
+ while (idx > -1) {
// next 2 bytes are length
final int lengthIdx = idx + 16 * 2;
final int messageIdx = lengthIdx + 4;
}
messages.add(message);
idx = messageEndIdx;
+ idx = content.indexOf(FF_16, idx);
}
- logger.info("Succesfully extracted {} messages", messages.size());
+ LOG.info("Succesfully extracted {} messages", messages.size());
return messages;
}
static String clearWhiteSpaceToUpper(final String line) {
return line.replaceAll("\\s", "").toUpperCase();
}
-
}
@Override
public boolean isCancelled() {
- // TODO Auto-generated method stub
return false;
}
@Override
public RpcResult<TransactionStatus> get() throws InterruptedException, ExecutionException {
- // TODO Auto-generated method stub
return null;
}
@Override
public RpcResult<TransactionStatus> get(final long timeout, final TimeUnit unit) throws InterruptedException,
- ExecutionException, TimeoutException {
- // TODO Auto-generated method stub
+ ExecutionException, TimeoutException {
return null;
}
}).when(this.mockedTransaction).commit();
--- /dev/null
+Received PCEP Open message. Length:28.
+
+20 01 00 1c 01 10 00 18 20 1e 78 03 00 10 00 04
+00 00 00 05 00 1a 00 04 00 00 00 b4
+
+Received PCEP Keepalive message. Length:4.
+
+20 02 00 04
+
+Received PCEPReport message. Length:12.
+
+20 0a 00 0c 20 10 00 08 00 00 00 00
+
+Received PCEPReport message. Length:56.
+
+20 0a 00 38 20 10 00 34 00 00 50 01 00 11 00 28
+74 75 6e 6e 65 6c 5f 66 72 6f 6d 5f 4f 66 2d 39
+6b 2d 30 32 5f 74 6f 5f 4f 66 2d 39 6b 2d 30 33
+4f 66 2d 39 6b 2d 30 32
+
+Received PCEPReport message. Length:120.
+
+20 0a 00 78 20 10 00 44 00 00 50 05 00 11 00 28
+74 75 6e 6e 65 6c 5f 66 72 6f 6d 5f 4f 66 2d 39
+6b 2d 30 32 5f 74 6f 5f 4f 66 2d 39 6b 2d 30 33
+4f 66 2d 39 6b 2d 30 32 00 12 00 0c 2a 2a 2a 2a
+00 00 00 04 2a 2a 2a 2a 07 10 00 14 01 08 c6 14
+a0 2b 20 00 01 08 2b 2b 2b 2b 20 00 09 10 00 14
+00 00 00 00 00 00 00 00 00 00 00 00 07 07 00 00
+05 20 00 08 00 00 00 00
+
+Received PCEPReport message. Length:56.
+
+20 0a 00 38 20 10 00 34 00 00 50 0c 00 11 00 28
+74 75 6e 6e 65 6c 5f 66 72 6f 6d 5f 4f 66 2d 39
+6b 2d 30 32 5f 74 6f 5f 4f 66 2d 39 6b 2d 30 33
+4f 66 2d 39 6b 2d 30 32
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.Open;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.OpenBuilder;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
public final class DefaultPCEPSessionNegotiator extends AbstractPCEPSessionNegotiator {
}
@Override
- protected PCEPSessionImpl createSession(final Timer timer, final Channel channel, final Open localPrefs, final Open remotePrefs) {
+ @VisibleForTesting
+ public PCEPSessionImpl createSession(final Timer timer, final Channel channel, final Open localPrefs, final Open remotePrefs) {
return new PCEPSessionImpl(timer, this.listener, this.maxUnknownMessages, channel, localPrefs, remotePrefs);
}
}
@Override
- protected void sessionUp() {
+ @VisibleForTesting
+ public void sessionUp() {
this.listener.onSessionUp(this);
}
@Override
protected KeepaliveMessage validate(final List<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
- // FIXME: keepalive shouldn't have objects
-
+ if (objects != null && !objects.isEmpty()) {
+ throw new PCEPDeserializerException("Keepalive message should not contain any objects.");
+ }
return MESSAGE;
}
}
byteOffset += USER_VALUE_F_LENGTH;
error.setDescription(ByteArray.bytesToHRString(ByteArray.subByte(valueBytes, byteOffset, errDescrLength)));
byteOffset += errDescrLength;
- // TODO: if we have any subobjects
+ // if we have any subobjects, place the implementation here
return new UserBuilder().setUserError(error.build()).build();
}
final byte[] value = ByteArray.intToBytes(ue.getValue(), USER_VALUE_F_LENGTH);
final byte[] desc = (ue.getDescription() == null) ? new byte[0] : ue.getDescription().getBytes();
final byte descLen = UnsignedBytes.checkedCast(desc.length);
- // TODO: if we have any subobjects
+ // if we have any subobjects, place the implementation here
final byte[] bytes = new byte[2 + ENTERPRISE_F_LENGTH + SUB_ORG_F_LENGTH + USER_VALUE_F_LENGTH + ERR_DESCR_LENGTH_F_LENGTH
+ desc.length];
bytes[0] = UnsignedBytes.checkedCast(USER_ERROR_CLASS_NUM);
buf = Unpooled.buffer(result.length);
parser.serializeMessage(new PcreqBuilder().setPcreqMessage(builder.build()).build(), buf);
assertArrayEquals(result, buf.array());
-
- // specMessages.clear();
- // requests = new ArrayList<CompositeRequestObject>();
- // requests.add(new CompositeRequestObject(this.requestParameter, new PCEPEndPointsObject<IPv4Address>(new
- // IPv4Address(ipAdress2), new IPv4Address(ipAdress2)), null, null, null, null, null, null, null, null, null));
- // specMessages.add(new PCEPRequestMessage(requests));
- //
- // final byte[] ipAdress3 = { (byte) 0x7F, (byte) 0x00, (byte) 0x30, (byte) 0x01 };
- // requests = new ArrayList<CompositeRequestObject>();
- // requests.add(new CompositeRequestObject(new PCEPRequestParameterObject(false, false, false, false, false,
- // false,
- // false, false, (short) 4, 1, true, false), new PCEPEndPointsObject<IPv4Address>(new IPv4Address(ipAdress3),
- // new
- // IPv4Address(ipAdress2)), null, null, null, null, null, null, null, null, null));
- // specMessages.add(new PCEPRequestMessage(requests));
- //
- // final byte[] ipAdress4 = { (byte) 0x7F, (byte) 0x30, (byte) 0x00, (byte) 0x01 };
- // requests = new ArrayList<CompositeRequestObject>();
- // requests.add(new CompositeRequestObject(this.requestParameter, new PCEPEndPointsObject<IPv4Address>(new
- // IPv4Address(ipAdress2), new IPv4Address(ipAdress4)), null, null, null, null, null, null, null, null, null));
- // specMessages.add(new PCEPRequestMessage(requests));
- //
- // final byte[] ipAdress5 = { (byte) 0x7F, (byte) 0xd0, (byte) 0x00, (byte) 0x01 };
- // requests = new ArrayList<CompositeRequestObject>();
- // requests.add(new CompositeRequestObject(new PCEPRequestParameterObject(true, false, false, false, false,
- // false,
- // false, false, (short) 1, 1, true, false), new PCEPEndPointsObject<IPv4Address>(new IPv4Address(ipAdress5),
- // new
- // IPv4Address(ipAdress5)), null, null, null, null, null, null, null, null, null));
- //
- // specMessages.add(new PCEPRequestMessage(requests));
- // deserMsgs = deserMsg("src/test/resources/PCReq.4.bin");
- // assertEquals(deserMsgs.toString(), specMessages.toString());
- //
- // specMessages.clear();
- // svecList = new ArrayList<CompositeRequestSvecObject>();
- // svecList.add(new CompositeRequestSvecObject(new PCEPSvecObject(true, false, false, false, false,
- // this.requestIds,
- // false)));
- // svecList.add(new CompositeRequestSvecObject(new PCEPSvecObject(false, true, true, false, false,
- // this.requestIds,
- // false), new PCEPObjectiveFunctionObject(PCEPOFCodes.MCC, true, false), new
- // PCEPGlobalConstraintsObject((short)
- // 0x55, (short) 1, (short) 100, (short) 0x26, true, false), new PCEPExcludeRouteObject(new
- // ArrayList<ExcludeRouteSubobject>() {
- // private static final long serialVersionUID = 1L;
- //
- // {
- // this.add(new XROAsNumberSubobject(new AsNumber((long) 0x12), true));
- // }
- // }, true, true, false), new ArrayList<PCEPMetricObject>() {
- // private static final long serialVersionUID = 1L;
- //
- // {
- // this.add(new PCEPMetricObject(true, true, new TEMetric(123456L), true, false));
- // }
- // }));
- //
- // requests = new ArrayList<CompositeRequestObject>();
- // requests.add(new CompositeRequestObject(this.requestParameter, new PCEPEndPointsObject<IPv4Address>(new
- // IPv4Address(ipAdress2), new IPv4Address(ipAdress2)), null, null, PCEPValidatorTest.lspa, new
- // PCEPRequestedPathBandwidthObject(new Bandwidth(ByteArray.floatToBytes(1000)), false, false), new
- // ArrayList<PCEPMetricObject>() {
- // private static final long serialVersionUID = 1L;
- //
- // {
- // this.add(new PCEPMetricObject(true, true, new IGPMetric(53L), false, false));
- // this.add(new PCEPMetricObject(true, true, new IGPMetric(5335L), false, false));
- // this.add(new PCEPMetricObject(true, true, new IGPMetric(128256), false, false));
- // }
- // }, new PCEPReportedRouteObject(this.rroSubobjects, false), new PCEPExistingPathBandwidthObject(new
- // Bandwidth(ByteArray.floatToBytes(5353)), false, false), new PCEPIncludeRouteObject(this.eroSubobjects, false,
- // false), new PCEPLoadBalancingObject(5, new Bandwidth(ByteArray.floatToBytes(3)), false)));
- //
- // final byte[] ipAdress6 = { (byte) 0x7F, (byte) 0xF0, (byte) 0x00, (byte) 0x01 };
- // specMessages.add(new PCEPRequestMessage(svecList, requests));
- //
- // requests = new ArrayList<CompositeRequestObject>();
- // requests.add(new CompositeRequestObject(this.requestParameter, new PCEPEndPointsObject<IPv4Address>(new
- // IPv4Address(ipAdress6), new IPv4Address(ipAdress6)), null, null, PCEPValidatorTest.lspa, new
- // PCEPRequestedPathBandwidthObject(new Bandwidth(ByteArray.floatToBytes(1000)), false, false), new
- // ArrayList<PCEPMetricObject>() {
- // private static final long serialVersionUID = 1L;
- //
- // {
- // this.add(new PCEPMetricObject(true, true, new IGPMetric(53L), false, false));
- // }
- // }, new PCEPReportedRouteObject(this.rroSubobjects, false), new PCEPExistingPathBandwidthObject(new
- // Bandwidth(ByteArray.floatToBytes(5353)), false, false), new PCEPIncludeRouteObject(this.eroSubobjects, false,
- // false), new PCEPLoadBalancingObject(5, new Bandwidth(ByteArray.floatToBytes(3f)), false)));
- // deserMsgs = deserMsg("src/test/resources/PCReq.5.bin");
- // specMessages.add(new PCEPRequestMessage(svecList, requests));
- // // FIXME
- // // assertEquals(deserMsgs, specMessages);
- //
- // // FIXME: need construct with invalid processed parameter
- // // assertEquals(deserMsg("src/test/resources/PCReq.6.invalid.bin"),
- // // asList(
- // // new PCEPErrorMessage(new CompositeErrorObject(new
- // // PCEPRequestParameterObject(true, false, false, false, false, false,
- // // false, false, (short) 3,
- // // 1L, false, false), new PCEPErrorObject(PCEPErrors.P_FLAG_NOT_SET))),
- // // new PCEPRequestMessage(asList(new
- // // CompositeRequestObject(this.requestParameter, new
- // // PCEPEndPointsObject<IPv4Address>(IPv4Address
- // // .getNetworkAddressFactory().getNetworkAddressForBytes(new byte[] {
- // // 127, 0, 0, 1 }), IPv4Address.getNetworkAddressFactory()
- // // .getNetworkAddressForBytes(new byte[] { 127, 0, 0, 1 })), null, null,
- // // null, null, null, null, null, null, new PCEPLoadBalancingObject(
- // // 3, new Bandwidth(1024.75), false))))));
- //
- // }
- //
- // @Test
- // public void testRequestMessageValidationFromRawMsg() throws PCEPDeserializerException {
- // List<PCEPObject> objs = new ArrayList<PCEPObject>();
- // List<Message> msgs;
- // PCEPRequestParameterObject tmpRP;
- //
- // // test unrecognized object in svec list
- // objs.add(this.svecObj);
- // objs.add(new UnknownObject(true, false, PCEPErrors.UNRECOGNIZED_OBJ_CLASS));
- // objs.add(new PCEPSvecObject(true, true, true, false, false, PCEPValidatorTest.this.requestIds, true));
- //
- // msgs = PCEPMessageValidator.getValidator(PCEPMessageType.REQUEST).validate(objs);
- //
- // assertEquals(msgs.get(0).toString(), new PCEPErrorMessage(new ArrayList<PCEPErrorObject>() {
- // private static final long serialVersionUID = 1L;
- //
- // {
- // this.add(new PCEPErrorObject(PCEPErrors.UNRECOGNIZED_OBJ_CLASS));
- // }
- // }).toString());
- //
- // // test with request p flag not set and ignoracion of more than one
- // // end-points objects
- // objs = new ArrayList<PCEPObject>();
- // objs.add(this.svecObj);
- // objs.add(this.svecObj);
- // tmpRP = new PCEPRequestParameterObject(true, false, false, false, false, false, false, false, (short) 3, 1,
- // false, false);
- // objs.add(tmpRP);
- // objs.add(this.endPoints);
- //
- // objs.add(this.requestParameter);
- // objs.add(this.endPoints);
- // objs.add(this.endPoints);
- // // FIXME:mv use object constructor with set processed flag
- // // objs.add(this.classTypeProvider);
- // // objs.add(this.requestParameter);
- // // objs.add(this.endPointsProvider);
- // // objs.add(new PCEPClassTypeObjectProvider((short) 7, false));
- //
- // msgs = PCEPMessageValidator.getValidator(PCEPMessageType.REQUEST).validate(objs);
- // // FIXME:mv use object constructor with set processed flag
- // // assertEquals(msgs.get(0), new PCEPErrorMessage(new
- // // CompositeErrorObject(tmpRP, new
- // // PCEPErrorObject(PCEPErrors.P_FLAG_NOT_SET))));
- // // assertEquals(
- // // msgs.get(1),
- // // new PCEPRequestMessage(asList(new
- // // CompositeRequestSvecObject(this.svecObj), new
- // // CompositeRequestSvecObject(this.svecObj)), Util
- // // .asList(new CompositeRequestObject(this.requestParameter,
- // // this.endPoints, this.classType, null, null, null, null, null, null,
- // // null,
- // // null))));
- // // assertEquals(msgs.get(2), new PCEPErrorMessage(new
- // // CompositeErrorObject(tmpRP, new
- // // PCEPErrorObject(PCEPErrors.P_FLAG_NOT_SET))));
}
@Test
<groupId>${project.groupId}</groupId>
<artifactId>mockito-configuration</artifactId>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>pcep-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
</dependencies>
<build>
import io.netty.util.concurrent.FutureListener;
import java.net.InetAddress;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.concurrent.ExecutionException;
import javax.annotation.concurrent.GuardedBy;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.OperationResult;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.PccSyncState;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.RemoveLspArgs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.TopologyTypes1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.TopologyTypes1Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.UpdateLspArgs;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.PathComputationClient;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.PathComputationClientBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.ReportedLsps;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.ReportedLspsKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.StatefulTlvBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.topology.pcep.type.TopologyPcepBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypesBuilder;
import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
/**
*
*/
-final class ServerSessionManager implements SessionListenerFactory<PCEPSessionListener> {
+final class ServerSessionManager implements SessionListenerFactory<PCEPSessionListener>, AutoCloseable {
private static String createNodeId(final InetAddress addr) {
return "pcc://" + addr.getHostAddress();
}
final DataModificationTransaction trans = ServerSessionManager.this.dataProvider.beginTransaction();
// The session went down. Undo all the Topology changes we have done.
- trans.removeRuntimeData(this.topologyAugment);
+ trans.removeOperationalData(this.topologyAugment);
if (this.ownsTopology) {
- trans.removeRuntimeData(this.topologyNode);
+ trans.removeOperationalData(this.topologyNode);
}
- Futures.addCallback(JdkFutureAdapters.listenInPoolThread(trans.commit()),
- new FutureCallback<RpcResult<TransactionStatus>>() {
+ Futures.addCallback(JdkFutureAdapters.listenInPoolThread(trans.commit()), new FutureCallback<RpcResult<TransactionStatus>>() {
@Override
public void onSuccess(final RpcResult<TransactionStatus> result) {
// Nothing to do
}
private InstanceIdentifier<ReportedLsps> lspIdentifier(final SymbolicPathName name) {
- return InstanceIdentifier.builder(this.topologyAugment).
- child(PathComputationClient.class).
- child(ReportedLsps.class, new ReportedLspsKey(name.getPathName())).toInstance();
+ return InstanceIdentifier.builder(this.topologyAugment).child(PathComputationClient.class).child(ReportedLsps.class,
+ new ReportedLspsKey(name.getPathName())).toInstance();
}
@Override
if (lsp.isRemove()) {
final SymbolicPathName name = this.lsps.remove(id);
if (name != null) {
- trans.removeRuntimeData(lspIdentifier(name));
+ trans.removeOperationalData(lspIdentifier(name));
}
LOG.debug("LSP {} removed", lsp);
// TODO: what should we do here?
continue;
}
+ this.lsps.put(id, name);
}
final SymbolicPathName name = this.lsps.get(id);
}
}
- Futures.addCallback(JdkFutureAdapters.listenInPoolThread(trans.commit()),
- new FutureCallback<RpcResult<TransactionStatus>>() {
+ Futures.addCallback(JdkFutureAdapters.listenInPoolThread(trans.commit()), new FutureCallback<RpcResult<TransactionStatus>>() {
@Override
public void onSuccess(final RpcResult<TransactionStatus> result) {
// Nothing to do
public ServerSessionManager(final DataProviderService dataProvider, final InstanceIdentifier<Topology> topology) {
this.dataProvider = Preconditions.checkNotNull(dataProvider);
this.topology = Preconditions.checkNotNull(topology);
+
+ // Make sure the topology does not exist
+ final Object c = dataProvider.readOperationalData(topology);
+ Preconditions.checkArgument(c == null, "Topology %s already exists", topology);
+
+ // Now create the base topology
+ final TopologyKey k = InstanceIdentifier.keyOf(topology);
+ final DataModificationTransaction t = dataProvider.beginTransaction();
+ t.putOperationalData(
+ topology,
+ new TopologyBuilder().setKey(k).setTopologyId(k.getTopologyId()).setTopologyTypes(
+ new TopologyTypesBuilder().addAugmentation(TopologyTypes1.class,
+ new TopologyTypes1Builder().setTopologyPcep(new TopologyPcepBuilder().build()).build()).build()).setNode(
+ new ArrayList<Node>()).build());
+
+ // FIXME: attach to the future to notify of failures
+ t.commit();
+
}
@Override
}
// Make sure there is no such LSP
- final InstanceIdentifier<ReportedLsps> lsp = InstanceIdentifier.builder(l.topologyAugment).
- child(PathComputationClient.class).
- child(ReportedLsps.class, new ReportedLspsKey(input.getName())).toInstance();
+ final InstanceIdentifier<ReportedLsps> lsp = InstanceIdentifier.builder(l.topologyAugment).child(PathComputationClient.class).child(
+ ReportedLsps.class, new ReportedLspsKey(input.getName())).toInstance();
if (this.dataProvider.readOperationalData(lsp) != null) {
LOG.debug("Node {} already contains lsp {} at {}", input.getNode(), input.getName(), lsp);
return Futures.immediateFuture(OPERATION_UNSENT);
}
// Make sure the LSP exists, we need it for PLSP-ID
- final InstanceIdentifier<ReportedLsps> lsp = InstanceIdentifier.builder(l.topologyAugment).
- child(PathComputationClient.class).
- child(ReportedLsps.class, new ReportedLspsKey(input.getName())).toInstance();
+ final InstanceIdentifier<ReportedLsps> lsp = InstanceIdentifier.builder(l.topologyAugment).child(PathComputationClient.class).child(
+ ReportedLsps.class, new ReportedLspsKey(input.getName())).toInstance();
final ReportedLsps rep = (ReportedLsps) this.dataProvider.readOperationalData(lsp);
if (rep == null) {
LOG.debug("Node {} does not contain LSP {}", input.getNode(), input.getName());
}
// Make sure the LSP exists
- final InstanceIdentifier<ReportedLsps> lsp = InstanceIdentifier.builder(l.topologyAugment).
- child(PathComputationClient.class).
- child(ReportedLsps.class, new ReportedLspsKey(input.getName())).toInstance();
+ final InstanceIdentifier<ReportedLsps> lsp = InstanceIdentifier.builder(l.topologyAugment).child(PathComputationClient.class).child(
+ ReportedLsps.class, new ReportedLspsKey(input.getName())).toInstance();
final ReportedLsps rep = (ReportedLsps) this.dataProvider.readOperationalData(lsp);
if (rep == null) {
LOG.debug("Node {} does not contain LSP {}", input.getNode(), input.getName());
return Futures.immediateFuture(OPERATION_UNSENT);
}
}
+
+ @Override
+ public void close() throws InterruptedException, ExecutionException {
+ final DataModificationTransaction t = this.dataProvider.beginTransaction();
+ t.removeOperationalData(this.topology);
+ t.commit().get();
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.bgpcep.pcep.topology.provider;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelPipeline;
+import io.netty.util.HashedWheelTimer;
+import io.netty.util.concurrent.Promise;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.protocol.pcep.impl.DefaultPCEPSessionNegotiator;
+import org.opendaylight.protocol.pcep.impl.PCEPSessionImpl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Pcrpt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.PcrptBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.PlspId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.SymbolicPathName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lsp.object.LspBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.Open;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.OpenBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.open.TlvsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrpt.message.PcrptMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrpt.message.pcrpt.message.Reports;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrpt.message.pcrpt.message.ReportsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.stateful.capability.tlv.StatefulBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.symbolic.path.name.tlv.SymbolicPathNameBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.Notification;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
+
+public class ParserToSalTest {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ParserToSalTest.class);
+
+ private List<Notification> receivedMsgs;
+
+ private PCEPSessionImpl session;
+
+ @Mock
+ private Channel clientListener;
+
+ @Mock
+ private ChannelPipeline pipeline;
+
+ @Mock
+ DataProviderService providerService;
+
+ @Mock
+ DataModificationTransaction mockedTransaction;
+
+ private final Open localPrefs = new OpenBuilder().setDeadTimer((short) 30).setKeepalive((short) 10).setTlvs(
+ new TlvsBuilder().setStateful(new StatefulBuilder().build()).build()).build();
+
+ private Pcrpt rptmsg;
+
+ @Before
+ public void setUp() throws IOException {
+ MockitoAnnotations.initMocks(this);
+
+ doAnswer(new Answer<Object>() {
+ @Override
+ public Object answer(final InvocationOnMock invocation) {
+ final Object[] args = invocation.getArguments();
+ ParserToSalTest.this.receivedMsgs.add((Notification) args[0]);
+ return mock(ChannelFuture.class);
+ }
+ }).when(this.clientListener).writeAndFlush(any(Notification.class));
+ doReturn("TestingChannel").when(this.clientListener).toString();
+ doReturn(this.pipeline).when(this.clientListener).pipeline();
+ doReturn(this.pipeline).when(this.pipeline).replace(any(ChannelHandler.class), any(String.class), any(ChannelHandler.class));
+ doReturn(true).when(this.clientListener).isActive();
+ final SocketAddress sa = new InetSocketAddress("127.0.0.1", 4189);
+ doReturn(sa).when(this.clientListener).remoteAddress();
+ doReturn(mock(ChannelFuture.class)).when(this.clientListener).close();
+
+ Mockito.doReturn(this.mockedTransaction).when(this.providerService).beginTransaction();
+ Mockito.doReturn(new Future<RpcResult<TransactionStatus>>() {
+ int i = 0;
+
+ @Override
+ public boolean cancel(final boolean mayInterruptIfRunning) {
+ LOG.debug("Cancel.");
+ return false;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ LOG.debug("Is cancelled.");
+ return false;
+ }
+
+ @Override
+ public boolean isDone() {
+ this.i++;
+ LOG.debug("Done. {}", this.i);
+ return true;
+ }
+
+ @Override
+ public RpcResult<TransactionStatus> get() throws InterruptedException, ExecutionException {
+ return null;
+ }
+
+ @Override
+ public RpcResult<TransactionStatus> get(final long timeout, final TimeUnit unit) throws InterruptedException,
+ ExecutionException, TimeoutException {
+ return null;
+ }
+ }).when(this.mockedTransaction).commit();
+
+ final HashMap<Object, Object> data = new HashMap<>();
+
+ Mockito.doAnswer(new Answer<Object>() {
+ @Override
+ public Object answer(final InvocationOnMock invocation) throws Throwable {
+ final Object[] args = invocation.getArguments();
+ LOG.debug("Get key {}", args[0]);
+ return data.get(args[0]);
+ }
+
+ }).when(this.mockedTransaction).readOperationalData(Matchers.any(InstanceIdentifier.class));
+
+ Mockito.doAnswer(new Answer<Object>() {
+ @Override
+ public Object answer(final InvocationOnMock invocation) throws Throwable {
+ final Object[] args = invocation.getArguments();
+ LOG.debug("Get key {}", args[0]);
+ return data.get(args[0]);
+ }
+
+ }).when(this.providerService).readOperationalData(Matchers.any(InstanceIdentifier.class));
+
+ Mockito.doAnswer(new Answer<String>() {
+ @Override
+ public String answer(final InvocationOnMock invocation) throws Throwable {
+ final Object[] args = invocation.getArguments();
+ LOG.debug("Put key {} value {}", args[0]);
+ LOG.debug("Put value {}", args[1]);
+ data.put(args[0], args[1]);
+ return null;
+ }
+
+ }).when(this.mockedTransaction).putOperationalData(Matchers.any(InstanceIdentifier.class), Matchers.any(DataObject.class));
+
+ final ServerSessionManager manager = new ServerSessionManager(this.providerService, InstanceIdentifier.builder(
+ NetworkTopology.class).child(Topology.class, new TopologyKey(new TopologyId("testtopo"))).toInstance());
+ final DefaultPCEPSessionNegotiator neg = new DefaultPCEPSessionNegotiator(new HashedWheelTimer(), mock(Promise.class), this.clientListener, manager.getSessionListener(), (short) 1, 5, this.localPrefs);
+ this.session = neg.createSession(new HashedWheelTimer(), this.clientListener, this.localPrefs, this.localPrefs);
+
+ final List<Reports> reports = Lists.newArrayList(new ReportsBuilder().setLsp(
+ new LspBuilder().setPlspId(new PlspId(5L)).setSync(false).setRemove(false).setTlvs(
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lsp.object.lsp.TlvsBuilder().setSymbolicPathName(
+ new SymbolicPathNameBuilder().setPathName(new SymbolicPathName(new byte[] { 22, 34 })).build()).build()).build()).build());
+ this.rptmsg = new PcrptBuilder().setPcrptMessage(new PcrptMessageBuilder().setReports(reports).build()).build();
+ }
+
+ @Test
+ public void testUnknownLsp() {
+ this.session.sessionUp();
+ this.session.handleMessage(this.rptmsg);
+ Mockito.verify(this.mockedTransaction, Mockito.times(4)).putOperationalData(Matchers.any(InstanceIdentifier.class),
+ Matchers.any(DataObject.class));
+ Mockito.verify(this.mockedTransaction, Mockito.times(3)).commit();
+ }
+}
<artifactId>commons-codec</artifactId>
<version>${commonscodec.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
<!-- Testing dependencies -->
<dependency>
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.List;
+
+import org.apache.commons.codec.DecoderException;
+import org.apache.commons.codec.binary.Hex;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import com.google.common.io.CharStreams;
+
+/**
+ * Parses PCEP messages from a text file. Messages need to follow this formatting:
+ *
+ * Received PCEP Open message. Length:28.
+ *
+ * 20 01 00 1c 01 10 00 18 20 1e 78 03 00 10 00 04 00 00 00 05 00 1a 00 04 00 00 00 b4
+ *
+ */
+public class PCEPHexDumpParser {
+ private static final int MINIMAL_LENGTH = 4;
+ private static final Logger LOG = LoggerFactory.getLogger(PCEPHexDumpParser.class);
+ private static final String LENGTH = "LENGTH:";
+
+ private PCEPHexDumpParser() {
+
+ }
+
+ public static List<byte[]> parseMessages(final File file) throws IOException {
+ Preconditions.checkArgument(file != null, "Filename cannot be null");
+ return parseMessages(new FileInputStream(file));
+ }
+
+ public static List<byte[]> parseMessages(final InputStream is) throws IOException {
+ Preconditions.checkNotNull(is);
+ try (InputStreamReader isr = new InputStreamReader(is)) {
+ return parseMessages(CharStreams.toString(isr));
+ } finally {
+ is.close();
+ }
+ }
+
+ private static List<byte[]> parseMessages(final String c) {
+ final String content = clearWhiteSpaceToUpper(c);
+
+ final List<byte[]> messages = Lists.newLinkedList();
+ int idx = content.indexOf(LENGTH, 0);
+ while (idx > -1) {
+ // next chars are final length, ending with '.'
+ final int lengthIdx = idx + LENGTH.length();
+ final int messageIdx = content.indexOf('.', lengthIdx);
+
+ final int length = Integer.valueOf(content.substring(lengthIdx, messageIdx));
+ final int messageEndIdx = idx + length * 2;
+
+ // Assert that message is longer than minimum 4(header.length == 4)
+ // If length in PCEP message would be 0, loop would never end
+ Preconditions.checkArgument(length >= MINIMAL_LENGTH, "Invalid message at index " + idx + ", length atribute is lower than "
+ + MINIMAL_LENGTH);
+
+ final String hexMessage = content.substring(idx, messageEndIdx);
+ byte[] message = null;
+ try {
+ message = Hex.decodeHex(hexMessage.toCharArray());
+ } catch (final DecoderException e) {
+ new RuntimeException(e);
+ }
+ messages.add(message);
+ idx = messageEndIdx;
+ idx = content.indexOf(LENGTH, idx);
+ }
+ LOG.info("Succesfully extracted {} messages", messages.size());
+ return messages;
+ }
+
+ private static String clearWhiteSpaceToUpper(final String line) {
+ return line.replaceAll("\\s", "").toUpperCase();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.junit.matchers.JUnitMatchers.containsString;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.List;
+
+import org.junit.Test;
+
+public class PCEPHexDumpParserTest {
+
+ public static final String hexDumpFileName = "/pcep-hex.txt";
+ private final int expectedSize = 6;
+
+ @Test
+ public void testParsing() throws Exception {
+ final List<byte[]> result = PCEPHexDumpParser.parseMessages(getClass().getResourceAsStream(PCEPHexDumpParserTest.hexDumpFileName));
+ assertEquals(this.expectedSize, result.size());
+ }
+
+ @Test
+ public void testParsingInvalidFile() throws Exception {
+ try {
+ PCEPHexDumpParser.parseMessages(new File("bad file name"));
+ fail("Exception should have occured.");
+ } catch (final FileNotFoundException e) {
+ assertThat(e.getMessage(), containsString("bad file name (No such file or directory)"));
+ }
+ }
+}
--- /dev/null
+Received PCEP Open message. Length:28.
+
+20 01 00 1c 01 10 00 18 20 1e 78 03 00 10 00 04
+00 00 00 05 00 1a 00 04 00 00 00 b4
+
+Received PCEP Keepalive message. Length:4.
+
+20 02 00 04
+
+Received PCEPReport message. Length:12.
+
+20 0a 00 0c 20 10 00 08 00 00 00 00
+
+Received PCEPReport message. Length:56.
+
+20 0a 00 38 20 10 00 34 00 00 50 01 00 11 00 28
+74 75 6e 6e 65 6c 5f 66 72 6f 6d 5f 4f 66 2d 39
+6b 2d 30 32 5f 74 6f 5f 4f 66 2d 39 6b 2d 30 33
+4f 66 2d 39 6b 2d 30 32
+
+Received PCEPReport message. Length:120.
+
+20 0a 00 78 20 10 00 44 00 00 50 05 00 11 00 28
+74 75 6e 6e 65 6c 5f 66 72 6f 6d 5f 4f 66 2d 39
+6b 2d 30 32 5f 74 6f 5f 4f 66 2d 39 6b 2d 30 33
+4f 66 2d 39 6b 2d 30 32 00 12 00 0c 2a 2a 2a 2a
+00 00 00 04 2a 2a 2a 2a 07 10 00 14 01 08 c6 14
+a0 2b 20 00 01 08 2b 2b 2b 2b 20 00 09 10 00 14
+00 00 00 00 00 00 00 00 00 00 00 00 07 07 00 00
+05 20 00 08 00 00 00 00
+
+Received PCEPReport message. Length:56.
+
+20 0a 00 38 20 10 00 34 00 00 50 0c 00 11 00 28
+74 75 6e 6e 65 6c 5f 66 72 6f 6d 5f 4f 66 2d 39
+6b 2d 30 32 5f 74 6f 5f 4f 66 2d 39 6b 2d 30 33
+4f 66 2d 39 6b 2d 30 32