ExtendedCommunity c = null;
switch (comm.getCommType()) {
case AS_TYPE_TRANS:
- ShortAsNumber as = new ShortAsNumber((long) buffer.readUnsignedShort());
- byte[] value = ByteArray.readBytes(buffer, AS_LOCAL_ADMIN_LENGTH);
- if (comm.getCommSubType() == ROUTE_TARGET_SUBTYPE) {
- c = new RouteTargetExtendedCommunityCaseBuilder().setRouteTargetExtendedCommunity(
- new RouteTargetExtendedCommunityBuilder().setGlobalAdministrator(as).setLocalAdministrator(value).build()).build();
- } else if (comm.getCommSubType() == ROUTE_ORIGIN_SUBTYPE) {
- c = new RouteOriginExtendedCommunityCaseBuilder().setRouteOriginExtendedCommunity(
- new RouteOriginExtendedCommunityBuilder().setGlobalAdministrator(as).setLocalAdministrator(value).build()).build();
- } else {
- c = new AsSpecificExtendedCommunityCaseBuilder().setAsSpecificExtendedCommunity(
- new AsSpecificExtendedCommunityBuilder().setTransitive(false).setGlobalAdministrator(as).setLocalAdministrator(value).build()).build();
- }
+ c = parseAsTransCommunity(comm, buffer);
break;
case AS_TYPE_NON_TRANS:
- as = new ShortAsNumber((long) buffer.readUnsignedShort());
- value = ByteArray.readBytes(buffer, AS_LOCAL_ADMIN_LENGTH);
+ ShortAsNumber as = new ShortAsNumber((long) buffer.readUnsignedShort());
+ byte[] value = ByteArray.readBytes(buffer, AS_LOCAL_ADMIN_LENGTH);
c = new AsSpecificExtendedCommunityCaseBuilder().setAsSpecificExtendedCommunity(
new AsSpecificExtendedCommunityBuilder().setTransitive(true).setGlobalAdministrator(as).setLocalAdministrator(value).build()).build();
break;
}
break;
case INET_TYPE_TRANS:
- if (comm.getCommSubType() == ROUTE_TARGET_SUBTYPE) {
- c = new RouteTargetExtendedCommunityCaseBuilder().setRouteTargetExtendedCommunity(
- new RouteTargetExtendedCommunityBuilder().setGlobalAdministrator(new ShortAsNumber((long) buffer.readUnsignedShort()))
- .setLocalAdministrator(ByteArray.readBytes(buffer, AS_LOCAL_ADMIN_LENGTH)).build()).build();
- } else if (comm.getCommSubType() == ROUTE_ORIGIN_SUBTYPE) {
- c = new RouteOriginExtendedCommunityCaseBuilder().setRouteOriginExtendedCommunity(
- new RouteOriginExtendedCommunityBuilder().setGlobalAdministrator(new ShortAsNumber((long) buffer.readUnsignedShort()))
- .setLocalAdministrator(ByteArray.readBytes(buffer, AS_LOCAL_ADMIN_LENGTH)).build()).build();
- } else {
- c = new Inet4SpecificExtendedCommunityCaseBuilder().setInet4SpecificExtendedCommunity(
- new Inet4SpecificExtendedCommunityBuilder().setTransitive(false).setGlobalAdministrator(
- Ipv4Util.addressForByteBuf(buffer)).setLocalAdministrator(
- ByteArray.readBytes(buffer, INET_LOCAL_ADMIN_LENGTH)).build()).build();
- }
+ c = parseInetTypeCommunity(comm, buffer);
break;
case INET_TYPE_NON_TRANS:
c = new Inet4SpecificExtendedCommunityCaseBuilder().setInet4SpecificExtendedCommunity(
return comm.setExtendedCommunity(c).build();
}
+ private static ExtendedCommunity parseAsTransCommunity(final ExtendedCommunitiesBuilder comm, final ByteBuf buffer) {
+ final ShortAsNumber as = new ShortAsNumber((long) buffer.readUnsignedShort());
+ final byte[] value = ByteArray.readBytes(buffer, AS_LOCAL_ADMIN_LENGTH);
+ if (comm.getCommSubType() == ROUTE_TARGET_SUBTYPE) {
+ return new RouteTargetExtendedCommunityCaseBuilder().setRouteTargetExtendedCommunity(
+ new RouteTargetExtendedCommunityBuilder().setGlobalAdministrator(as).setLocalAdministrator(value).build()).build();
+ }
+ if (comm.getCommSubType() == ROUTE_ORIGIN_SUBTYPE) {
+ return new RouteOriginExtendedCommunityCaseBuilder().setRouteOriginExtendedCommunity(
+ new RouteOriginExtendedCommunityBuilder().setGlobalAdministrator(as).setLocalAdministrator(value).build()).build();
+ }
+ return new AsSpecificExtendedCommunityCaseBuilder().setAsSpecificExtendedCommunity(
+ new AsSpecificExtendedCommunityBuilder().setTransitive(false).setGlobalAdministrator(as).setLocalAdministrator(value).build()).build();
+ }
+
+ private static ExtendedCommunity parseInetTypeCommunity(final ExtendedCommunitiesBuilder comm, final ByteBuf buffer) {
+ if (comm.getCommSubType() == ROUTE_TARGET_SUBTYPE) {
+ return new RouteTargetExtendedCommunityCaseBuilder().setRouteTargetExtendedCommunity(
+ new RouteTargetExtendedCommunityBuilder().setGlobalAdministrator(new ShortAsNumber((long) buffer.readUnsignedShort()))
+ .setLocalAdministrator(ByteArray.readBytes(buffer, AS_LOCAL_ADMIN_LENGTH)).build()).build();
+ }
+ if (comm.getCommSubType() == ROUTE_ORIGIN_SUBTYPE) {
+ return new RouteOriginExtendedCommunityCaseBuilder().setRouteOriginExtendedCommunity(
+ new RouteOriginExtendedCommunityBuilder().setGlobalAdministrator(new ShortAsNumber((long) buffer.readUnsignedShort()))
+ .setLocalAdministrator(ByteArray.readBytes(buffer, AS_LOCAL_ADMIN_LENGTH)).build()).build();
+ }
+ return new Inet4SpecificExtendedCommunityCaseBuilder().setInet4SpecificExtendedCommunity(
+ new Inet4SpecificExtendedCommunityBuilder().setTransitive(false).setGlobalAdministrator(
+ Ipv4Util.addressForByteBuf(buffer)).setLocalAdministrator(
+ ByteArray.readBytes(buffer, INET_LOCAL_ADMIN_LENGTH)).build()).build();
+ }
+
@Override
public void serializeAttribute(final DataObject attribute, final ByteBuf byteAggregator) {
Preconditions.checkArgument(attribute instanceof PathAttributes, "Attribute parameter is not a PathAttribute object.");
final NodeDescriptors node, final NodeAttributes na) {
final org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.ospf.topology.rev131021.ospf.node.attributes.ospf.node.attributes.TedBuilder tb = new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.ospf.topology.rev131021.ospf.node.attributes.ospf.node.attributes.TedBuilder();
final OspfNodeAttributesBuilder ab = new OspfNodeAttributesBuilder();
-
if (na != null) {
if (na.getIpv4RouterId() != null) {
tb.setTeRouterIdIpv4(na.getIpv4RouterId());
if (na.getTopologyIdentifier() != null) {
ab.setMultiTopologyId(nodeMultiTopology(na.getTopologyIdentifier()));
}
- }
-
- final CRouterIdentifier ri = node.getCRouterIdentifier();
- if (ri instanceof OspfPseudonodeCase) {
- final OspfPseudonode pn = ((OspfPseudonodeCase) ri).getOspfPseudonode();
-
- ab.setRouterType(new PseudonodeBuilder().setPseudonode(Boolean.TRUE).build());
- ab.setDrInterfaceId(pn.getLanInterface().getValue());
- } else if (ri instanceof OspfNodeCase && na != null && na.getNodeFlags() != null) {
- // TODO: what should we do with in.getOspfRouterId()?
-
- final NodeFlagBits nf = na.getNodeFlags();
- if (nf.isAbr()) {
- ab.setRouterType(new AbrBuilder().setAbr(Boolean.TRUE).build());
- } else if (!nf.isExternal()) {
- ab.setRouterType(new InternalBuilder().setInternal(Boolean.TRUE).build());
+ final CRouterIdentifier ri = node.getCRouterIdentifier();
+ if (ri instanceof OspfPseudonodeCase) {
+ final OspfPseudonode pn = ((OspfPseudonodeCase) ri).getOspfPseudonode();
+
+ ab.setRouterType(new PseudonodeBuilder().setPseudonode(Boolean.TRUE).build());
+ ab.setDrInterfaceId(pn.getLanInterface().getValue());
+ } else if (ri instanceof OspfNodeCase && na.getNodeFlags() != null) {
+ // TODO: what should we do with in.getOspfRouterId()?
+
+ final NodeFlagBits nf = na.getNodeFlags();
+ if (nf.isAbr() != null) {
+ ab.setRouterType(new AbrBuilder().setAbr(nf.isAbr()).build());
+ } else if (nf.isExternal() != null) {
+ ab.setRouterType(new InternalBuilder().setInternal(!nf.isExternal()).build());
+ }
}
}
-
ab.setTed(tb.build());
-
return new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.ospf.topology.rev131021.IgpNodeAttributes1Builder().setOspfNodeAttributes(
ab.build()).build();
}
+ private void augmentProtocolId(final LinkstateRoute value, final IgpNodeAttributesBuilder inab, final NodeAttributes na, final NodeDescriptors nd) {
+ switch (value.getProtocolId()) {
+ case Direct:
+ case Static:
+ case Unknown:
+ break;
+ case IsisLevel1:
+ case IsisLevel2:
+ inab.addAugmentation(
+ org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.isis.topology.rev131021.IgpNodeAttributes1.class,
+ isisNodeAttributes(nd, na));
+ break;
+ case Ospf:
+ inab.addAugmentation(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.ospf.topology.rev131021.IgpNodeAttributes1.class,
+ ospfNodeAttributes(nd, na));
+ break;
+ }
+ }
+
private void createNode(final WriteTransaction trans, final UriBuilder base,
final LinkstateRoute value, final NodeCase n, final Attributes attributes) {
final NodeAttributes na = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.linkstate.routes.linkstate.routes.linkstate.route.attributes.attribute.type.NodeCase) attributes.getAugmentation(Attributes1.class).getAttributeType()).getNodeAttributes();
final IgpNodeAttributesBuilder inab = new IgpNodeAttributesBuilder();
-
final List<IpAddress> ids = new ArrayList<>();
if (na != null) {
if (na.getIpv4RouterId() != null) {
inab.setName(new DomainName(na.getDynamicHostname()));
}
}
-
if (!ids.isEmpty()) {
inab.setRouterId(ids);
}
-
- switch (value.getProtocolId()) {
- case Direct:
- case Static:
- case Unknown:
- break;
- case IsisLevel1:
- case IsisLevel2:
- inab.addAugmentation(
- org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.isis.topology.rev131021.IgpNodeAttributes1.class,
- isisNodeAttributes(n.getNodeDescriptors(), na));
- break;
- case Ospf:
- inab.addAugmentation(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.ospf.topology.rev131021.IgpNodeAttributes1.class,
- ospfNodeAttributes(n.getNodeDescriptors(), na));
- break;
- }
+ augmentProtocolId(value, inab, na, n.getNodeDescriptors());
final NodeId nid = buildNodeId(base, n.getNodeDescriptors());
final NodeHolder nh = getNode(nid);
-
/*
* Eventhough the the holder creates a dummy structure, we need to duplicate it here,
* as that is the API requirement. The reason for it is the possible presence of supporting
}
}
+ private void augmentProtocolId(final LinkstateRoute value, final PrefixAttributes pa, final PrefixBuilder pb) {
+ switch (value.getProtocolId()) {
+ case Direct:
+ case IsisLevel1:
+ case IsisLevel2:
+ case Static:
+ case Unknown:
+ break;
+ case Ospf:
+ if (pa != null && pa.getOspfForwardingAddress() != null) {
+ pb.addAugmentation(
+ Prefix1.class,
+ new Prefix1Builder().setOspfPrefixAttributes(
+ new OspfPrefixAttributesBuilder().setForwardingAddress(pa.getOspfForwardingAddress().getIpv4Address()).build()).build());
+ }
+ break;
+ }
+ }
+
private void createPrefix(final WriteTransaction trans, final UriBuilder base,
final LinkstateRoute value, final PrefixCase p, final Attributes attributes) {
final IpPrefix ippfx = p.getIpReachabilityInformation();
LOG.warn("IP reachability not present in prefix {} route {}, skipping it", p, value);
return;
}
-
final PrefixBuilder pb = new PrefixBuilder();
pb.setKey(new PrefixKey(ippfx));
pb.setPrefix(ippfx);
final PrefixAttributes pa;
-
// Very defensive lookup
final Attributes1 attr = attributes.getAugmentation(Attributes1.class);
if (attr != null) {
LOG.debug("Missing attributes in IP {} prefix {} route {}, skipping it", ippfx, p, value);
pa = null;
}
-
if (pa != null) {
pb.setMetric(pa.getPrefixMetric().getValue());
}
-
- switch (value.getProtocolId()) {
- case Direct:
- case IsisLevel1:
- case IsisLevel2:
- case Static:
- case Unknown:
- break;
- case Ospf:
- if (pa != null && pa.getOspfForwardingAddress() != null) {
- pb.addAugmentation(
- Prefix1.class,
- new Prefix1Builder().setOspfPrefixAttributes(
- new OspfPrefixAttributesBuilder().setForwardingAddress(pa.getOspfForwardingAddress().getIpv4Address()).build()).build());
- }
- break;
- }
+ augmentProtocolId(value, pa, pb);
final Prefix pfx = pb.build();
return this;
}
+ /**
+ * Creates a String representation of ISO system identifier
+ * in format XX.XX.XXm where X is one byte.
+ *
+ * @param bytes byte array with fixed length of 6 bytes
+ * @return String representation of ISO Identifier
+ */
private String isoId(final byte[] bytes) {
final StringBuilder sBuilder = new StringBuilder();
- sBuilder.append(Hex.encodeHexString(new byte[] { bytes[0], bytes[1] }));
- sBuilder.append('.');
- sBuilder.append(Hex.encodeHexString(new byte[] { bytes[2], bytes[3] }));
- sBuilder.append('.');
- sBuilder.append(Hex.encodeHexString(new byte[] { bytes[4], bytes[5] }));
+ int i = 0;
+ while (i < bytes.length) {
+ sBuilder.append(Hex.encodeHexString(new byte[] { bytes[i++], bytes[i++] }));
+ if (i != bytes.length) {
+ sBuilder.append('.');
+ }
+ }
return sBuilder.toString();
}
import java.util.Arrays;
import java.util.List;
import javax.annotation.concurrent.Immutable;
+import org.opendaylight.protocol.util.ByteArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
if (b == UnsignedBytes.MAX_VALUE) {
final int start = i;
int ffCount = 0;
- for (int j = i; j < i + (17); j++) {
+ for (int j = i; j <= i + MARKER_LENGTH; j++) {
// Check marker
if (byteArray[j] == UnsignedBytes.MAX_VALUE) {
ffCount++;
} else if (ffCount == MARKER_LENGTH) {
if (j == (i + MARKER_LENGTH)) {
// Parse length
- final int length = UnsignedBytes.toInt(byteArray[j]) * 256 + UnsignedBytes.toInt(byteArray[j + 1]);
+ final int length = ByteArray.bytesToInt(new byte[]{ byteArray[j], byteArray[j + 1] });
Preconditions.checkArgument(length >= MINIMAL_LENGTH, "Invalid message at index " + start
+ ", length atribute is lower than " + MINIMAL_LENGTH);
public static List<byte[]> parseMessages(final String c) {
final String content = clearWhiteSpaceToUpper(c);
+ final int sixteen = 16;
+ final int four = 4;
// search for 16 FFs
final List<byte[]> messages = Lists.newLinkedList();
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;
+ final int lengthIdx = idx + sixteen * 2;
+ final int messageIdx = lengthIdx + four;
final String hexLength = content.substring(lengthIdx, messageIdx);
byte[] byteLength = null;
try {
final LspBuilder builder = new LspBuilder();
builder.setIgnore(header.isIgnore());
builder.setProcessingRule(header.isProcessingRule());
- int[] plspIdRaw = { bytes.readUnsignedByte(), bytes.readUnsignedByte(), bytes.getUnsignedByte(2) };
+ final int[] plspIdRaw = { bytes.readUnsignedByte(), bytes.readUnsignedByte(), bytes.getUnsignedByte(2) };
builder.setPlspId(new PlspId((long) ((plspIdRaw[0] << ONE_B_OFFSET) | (plspIdRaw[1] << TWO_B_OFFSET) | (plspIdRaw[2] >> TWO_B_OFFSET))));
final BitSet flags = ByteArray.bytesToBitSet(ByteArray.readBytes(bytes, FLAGS_SIZE));
builder.setDelegate(flags.get(DELEGATE_FLAG_OFFSET));
Preconditions.checkArgument(plsp != null, "PLSP-ID not present");
writeMedium(plsp.getValue().intValue() << TWO_B_OFFSET, body);
- BitSet flags = new BitSet(2 * Byte.SIZE);
- if (specObj.isDelegate() != null && specObj.isDelegate()) {
- flags.set(DELEGATE_FLAG_OFFSET);
+ final BitSet flags = new BitSet(2 * Byte.SIZE);
+ if (specObj.isDelegate() != null) {
+ flags.set(DELEGATE_FLAG_OFFSET, specObj.isDelegate());
}
- if (specObj.isRemove() != null && specObj.isRemove()) {
- flags.set(REMOVE_FLAG_OFFSET);
+ if (specObj.isRemove() != null) {
+ flags.set(REMOVE_FLAG_OFFSET, specObj.isRemove());
}
- if (specObj.isSync() != null && specObj.isSync()) {
- flags.set(SYNC_FLAG_OFFSET);
+ if (specObj.isSync() != null) {
+ flags.set(SYNC_FLAG_OFFSET, specObj.isSync());
}
- if (specObj.isOperational() != null && specObj.isOperational()) {
- flags.set(OPERATIONAL_FLAG_OFFSET);
+ if (specObj.isOperational() != null) {
+ flags.set(OPERATIONAL_FLAG_OFFSET, specObj.isOperational());
}
body.writeByte(ByteArray.bitSetToBytes(flags, FLAGS_SIZE)[1]);
serializeTlvs(specObj.getTlvs(), body);
*/
package org.opendaylight.protocol.pcep.ietf.initiated00;
+import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeMedium;
+
import com.google.common.base.Preconditions;
+import com.google.common.primitives.UnsignedBytes;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import java.util.BitSet;
private static final int CREATE_FLAG_OFFSET = 8;
- public CInitiated00LspObjectParser(TlvRegistry tlvReg, VendorInformationTlvRegistry viTlvReg) {
+ public CInitiated00LspObjectParser(final TlvRegistry tlvReg, final VendorInformationTlvRegistry viTlvReg) {
super(tlvReg, viTlvReg);
}
final LspBuilder builder = new LspBuilder();
builder.setIgnore(header.isIgnore());
builder.setProcessingRule(header.isProcessingRule());
- int[] plspIdRaw = new int[] { bytes.readUnsignedByte(), bytes.readUnsignedByte(), bytes.getUnsignedByte(2), };
+ final int[] plspIdRaw = new int[] { bytes.readUnsignedByte(), bytes.readUnsignedByte(), bytes.getUnsignedByte(2), };
builder.setPlspId(new PlspId((long) ((plspIdRaw[0] << TWELVE_BITS_SHIFT) | (plspIdRaw[1] << FOUR_BITS_SHIFT) | (plspIdRaw[2] >> FOUR_BITS_SHIFT))));
final BitSet flags = ByteArray.bytesToBitSet(ByteArray.readBytes(bytes, 2));
builder.setDelegate(flags.get(DELEGATE_FLAG_OFFSET));
Preconditions.checkArgument(object instanceof Lsp, "Wrong instance of PCEPObject. Passed %s. Needed LspObject.", object.getClass());
final Lsp specObj = (Lsp) object;
final ByteBuf body = Unpooled.buffer();
-
- final byte[] retBytes = new byte[BODY_LENGTH];
-
Preconditions.checkArgument(specObj.getPlspId() != null, "PLSP-ID not present");
- final int lspID = specObj.getPlspId().getValue().intValue();
- retBytes[0] = (byte) (lspID >> TWELVE_BITS_SHIFT);
- retBytes[1] = (byte) (lspID >> FOUR_BITS_SHIFT);
- retBytes[2] = (byte) (lspID << FOUR_BITS_SHIFT);
- if (specObj.isDelegate() != null && specObj.isDelegate()) {
- retBytes[FLAGS_INDEX] |= 1 << (Byte.SIZE - (DELEGATE_FLAG_OFFSET - Byte.SIZE) - 1);
+ writeMedium(specObj.getPlspId().getValue().intValue() << FOUR_BITS_SHIFT, body);
+ final BitSet flags = new BitSet(2 * Byte.SIZE);
+ if (specObj.isDelegate() != null) {
+ flags.set(DELEGATE_FLAG_OFFSET, specObj.isDelegate());
}
- if (specObj.isRemove() != null && specObj.isRemove()) {
- retBytes[FLAGS_INDEX] |= 1 << (Byte.SIZE - (REMOVE_FLAG_OFFSET - Byte.SIZE) - 1);
+ if (specObj.isRemove() != null) {
+ flags.set(REMOVE_FLAG_OFFSET, specObj.isRemove());
}
- if (specObj.isSync() != null && specObj.isSync()) {
- retBytes[FLAGS_INDEX] |= 1 << (Byte.SIZE - (SYNC_FLAG_OFFSET - Byte.SIZE) - 1);
+ if (specObj.isSync() != null) {
+ flags.set(SYNC_FLAG_OFFSET, specObj.isSync());
}
- if (specObj.isAdministrative() != null && specObj.isAdministrative()) {
- retBytes[FLAGS_INDEX] |= 1 << (Byte.SIZE - (ADMINISTRATIVE_FLAG_OFFSET - Byte.SIZE) - 1);
+ if (specObj.isAdministrative() != null) {
+ flags.set(ADMINISTRATIVE_FLAG_OFFSET, specObj.isAdministrative());
}
- if (specObj.getAugmentation(Lsp1.class) != null && specObj.getAugmentation(Lsp1.class).isCreate()) {
- retBytes[FLAGS_INDEX] |= 1 << (Byte.SIZE - (CREATE_FLAG_OFFSET - Byte.SIZE) - 1);
+ if (specObj.getAugmentation(Lsp1.class) != null && specObj.getAugmentation(Lsp1.class).isCreate() != null) {
+ flags.set(CREATE_FLAG_OFFSET, specObj.getAugmentation(Lsp1.class).isCreate());
}
+ byte op = 0;
if (specObj.getOperational() != null) {
- final int op = specObj.getOperational().getIntValue();
- retBytes[FLAGS_INDEX] |= (op & OP_VALUE_BITS_OFFSET) << FOUR_BITS_SHIFT;
+ op = UnsignedBytes.checkedCast(specObj.getOperational().getIntValue());
+ op = (byte) (op << FOUR_BITS_SHIFT);
}
- body.writeBytes(retBytes);
+ body.writeByte(ByteArray.bitSetToBytes(flags, 2)[1] | op);
serializeTlvs(specObj.getTlvs(), body);
ObjectUtil.formatSubobject(TYPE, CLASS, object.isProcessingRule(), object.isIgnore(), body, buffer);
}
if (objects.isEmpty()) {
throw new PCEPDeserializerException("Error message is empty.");
}
-
final List<Rps> requestParameters = new ArrayList<>();
final List<Srps> srps = new ArrayList<>();
final List<Errors> errorObjects = new ArrayList<>();
final PcerrMessageBuilder b = new PcerrMessageBuilder();
-
- Object obj;
+ Object obj = objects.get(0);
State state = State.Init;
- obj = objects.get(0);
-
if (obj instanceof ErrorObject) {
final ErrorObject o = (ErrorObject) obj;
errorObjects.add(new ErrorsBuilder().setErrorObject(o).build());
state = State.ErrorIn;
- objects.remove(0);
} else if (obj instanceof Rp) {
final Rp o = (Rp) obj;
if (o.isProcessingRule()) {
}
requestParameters.add(new RpsBuilder().setRp(o).build());
state = State.RpIn;
- objects.remove(0);
} else if (obj instanceof Srp) {
final Srp s = (Srp) obj;
srps.add(new SrpsBuilder().setSrp(s).build());
state = State.SrpIn;
+ }
+ if (!state.equals(State.Init)) {
objects.remove(0);
}
-
while (!objects.isEmpty()) {
obj = objects.get(0);
-
if (obj instanceof UnknownObject) {
return new PcerrBuilder().setPcerrMessage(b.setErrors(((UnknownObject) obj).getErrors()).build()).build();
}
-
switch (state) {
case ErrorIn:
state = State.Open;
objects.remove(0);
}
}
-
if (errorObjects.isEmpty()) {
throw new PCEPDeserializerException("At least one PCEPErrorObject is mandatory.");
}
-
if (!objects.isEmpty()) {
throw new PCEPDeserializerException("Unprocessed Objects: " + objects);
}
if (!srps.isEmpty()) {
b.setErrorType(new StatefulCaseBuilder().setStateful(new StatefulBuilder().setSrps(srps).build()).build());
}
-
return new PcerrBuilder().setPcerrMessage(b.setErrors(errorObjects).build()).build();
}
public static final int TYPE = 18;
- private static final int EX_TUNNEL_ID4_F_LENGTH = 4;
-
private static final int V4_LENGTH = 16;
@Override
*/
package org.opendaylight.protocol.pcep.ietf.stateful07;
+import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeMedium;
+
import com.google.common.base.Preconditions;
+import com.google.common.primitives.UnsignedBytes;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import java.util.BitSet;
final LspBuilder builder = new LspBuilder();
builder.setIgnore(header.isIgnore());
builder.setProcessingRule(header.isProcessingRule());
- int[] plspIdRaw = new int[] { bytes.readUnsignedByte(), bytes.readUnsignedByte(), bytes.getUnsignedByte(2), };
+ final int[] plspIdRaw = new int[] { bytes.readUnsignedByte(), bytes.readUnsignedByte(), bytes.getUnsignedByte(2), };
builder.setPlspId(new PlspId((long) ((plspIdRaw[0] << TWELVE_BITS_SHIFT) | (plspIdRaw[1] << FOUR_BITS_SHIFT) | (plspIdRaw[2] >> FOUR_BITS_SHIFT))));
final BitSet flags = ByteArray.bytesToBitSet(ByteArray.readBytes(bytes, 2));
builder.setDelegate(flags.get(DELEGATE_FLAG_OFFSET));
Preconditions.checkArgument(object instanceof Lsp, "Wrong instance of PCEPObject. Passed %s . Needed LspObject.", object.getClass());
final Lsp specObj = (Lsp) object;
final ByteBuf body = Unpooled.buffer();
-
- final byte[] retBytes = new byte[BODY_LENGTH];
-
Preconditions.checkArgument(specObj.getPlspId() != null, "PLSP-ID not present");
- final int lspID = specObj.getPlspId().getValue().intValue();
- retBytes[0] = (byte) (lspID >> TWELVE_BITS_SHIFT);
- retBytes[1] = (byte) (lspID >> FOUR_BITS_SHIFT);
- retBytes[2] = (byte) (lspID << FOUR_BITS_SHIFT);
- if (specObj.isDelegate() != null && specObj.isDelegate()) {
- retBytes[FLAGS_INDEX] |= 1 << (Byte.SIZE - (DELEGATE_FLAG_OFFSET - Byte.SIZE) - 1);
+ writeMedium(specObj.getPlspId().getValue().intValue() << FOUR_BITS_SHIFT, body);
+ final BitSet flags = new BitSet(2 * Byte.SIZE);
+ if (specObj.isDelegate() != null) {
+ flags.set(DELEGATE_FLAG_OFFSET, specObj.isDelegate());
}
- if (specObj.isRemove() != null && specObj.isRemove()) {
- retBytes[FLAGS_INDEX] |= 1 << (Byte.SIZE - (REMOVE_FLAG_OFFSET - Byte.SIZE) - 1);
+ if (specObj.isRemove() != null) {
+ flags.set(REMOVE_FLAG_OFFSET, specObj.isRemove());
}
- if (specObj.isSync() != null && specObj.isSync()) {
- retBytes[FLAGS_INDEX] |= 1 << (Byte.SIZE - (SYNC_FLAG_OFFSET - Byte.SIZE) - 1);
+ if (specObj.isSync() != null) {
+ flags.set(SYNC_FLAG_OFFSET, specObj.isSync());
}
- if (specObj.isAdministrative() != null && specObj.isAdministrative()) {
- retBytes[FLAGS_INDEX] |= 1 << (Byte.SIZE - (ADMINISTRATIVE_FLAG_OFFSET - Byte.SIZE) - 1);
+ if (specObj.isAdministrative() != null) {
+ flags.set(ADMINISTRATIVE_FLAG_OFFSET, specObj.isAdministrative());
}
+ byte op = 0;
if (specObj.getOperational() != null) {
- final int op = specObj.getOperational().getIntValue();
- retBytes[FLAGS_INDEX] |= (op & OP_VALUE_BITS_OFFSET) << FOUR_BITS_SHIFT;
+ op = UnsignedBytes.checkedCast(specObj.getOperational().getIntValue());
+ op = (byte) (op << FOUR_BITS_SHIFT);
}
- body.writeBytes(retBytes);
+ body.writeByte(ByteArray.bitSetToBytes(flags, 2)[1] | op);
serializeTlvs(specObj.getTlvs(), body);
ObjectUtil.formatSubobject(TYPE, CLASS, object.isProcessingRule(), object.isIgnore(), body, buffer);
}
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
-
import io.netty.channel.Channel;
import io.netty.util.concurrent.Promise;
-
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-
import org.opendaylight.protocol.framework.AbstractSessionNegotiator;
import org.opendaylight.protocol.pcep.spi.PCEPErrors;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Keepalive;
LOG.info("PCEP session with {} started, sent proposal {}", this.channel, this.localPrefs);
}
+ private boolean handleMessageKeepWait(final Message msg) {
+ if (msg instanceof Keepalive) {
+ this.localOK = true;
+ if (this.remoteOK) {
+ LOG.info("PCEP peer {} completed negotiation", this.channel);
+ negotiationSuccessful(createSession(this.channel, this.localPrefs, this.remotePrefs));
+ this.state = State.Finished;
+ } else {
+ scheduleFailTimer();
+ this.state = State.OpenWait;
+ LOG.debug("Channel {} moved to OpenWait state with localOK=1", this.channel);
+ }
+ return true;
+ } else if (msg instanceof Pcerr) {
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.PcerrMessage err = ((Pcerr) msg).getPcerrMessage();
+ if (err.getErrorType() == null) {
+ final ErrorObject obj = err.getErrors().get(0).getErrorObject();
+ LOG.warn("Unexpected error received from PCC: type {} value {}", obj.getType(), obj.getValue());
+ negotiationFailed(new IllegalStateException("Unexpected error received from PCC."));
+ this.state = State.Idle;
+ return true;
+ }
+ this.localPrefs = getRevisedProposal(((SessionCase) err.getErrorType()).getSession().getOpen());
+ if (this.localPrefs == null) {
+ sendErrorMessage(PCEPErrors.PCERR_NON_ACC_SESSION_CHAR);
+ negotiationFailed(new IllegalStateException("Peer suggested unacceptable retry proposal"));
+ this.state = State.Finished;
+ return true;
+ }
+ this.sendMessage(new OpenBuilder().setOpenMessage(new OpenMessageBuilder().setOpen(this.localPrefs).build()).build());
+ if (!this.remoteOK) {
+ this.state = State.OpenWait;
+ }
+ scheduleFailTimer();
+ return true;
+ }
+ return false;
+ }
+
+ private boolean handleMessageOpenWait(final Message msg) {
+ if (msg instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Open) {
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.message.OpenMessage o = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Open) msg).getOpenMessage();
+ final Open open = o.getOpen();
+ if (isProposalAcceptable(open)) {
+ this.sendMessage(KEEPALIVE);
+ this.remotePrefs = open;
+ this.remoteOK = true;
+ if (this.localOK) {
+ negotiationSuccessful(createSession(this.channel, this.localPrefs, this.remotePrefs));
+ LOG.info("PCEP peer {} completed negotiation", this.channel);
+ this.state = State.Finished;
+ } else {
+ scheduleFailTimer();
+ this.state = State.KeepWait;
+ LOG.debug("Channel {} moved to KeepWait state with remoteOK=1", this.channel);
+ }
+ return true;
+ }
+
+ if (this.openRetry) {
+ sendErrorMessage(PCEPErrors.SECOND_OPEN_MSG);
+ negotiationFailed(new IllegalStateException("OPEN renegotiation failed"));
+ this.state = State.Finished;
+ return true;
+ }
+
+ final Open newPrefs = getCounterProposal(open);
+ if (newPrefs == null) {
+ sendErrorMessage(PCEPErrors.NON_ACC_NON_NEG_SESSION_CHAR);
+ negotiationFailed(new IllegalStateException("Peer sent unacceptable session parameters"));
+ this.state = State.Finished;
+ return true;
+ }
+
+ this.sendMessage(Util.createErrorMessage(PCEPErrors.NON_ACC_NEG_SESSION_CHAR, newPrefs));
+
+ this.openRetry = true;
+ this.state = this.localOK ? State.OpenWait : State.KeepWait;
+ scheduleFailTimer();
+ return true;
+ }
+ return false;
+ }
+
@Override
protected final void handleMessage(final Message msg) {
this.failTimer.cancel(false);
case Idle:
throw new IllegalStateException("Unexpected handleMessage in state " + this.state);
case KeepWait:
- if (msg instanceof Keepalive) {
- this.localOK = true;
- if (this.remoteOK) {
- LOG.info("PCEP peer {} completed negotiation", this.channel);
- negotiationSuccessful(createSession(this.channel, this.localPrefs, this.remotePrefs));
- this.state = State.Finished;
- } else {
- scheduleFailTimer();
- this.state = State.OpenWait;
- LOG.debug("Channel {} moved to OpenWait state with localOK=1", this.channel);
- }
-
- return;
- } else if (msg instanceof Pcerr) {
- final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.PcerrMessage err = ((Pcerr) msg).getPcerrMessage();
- if (err.getErrorType() == null) {
- final ErrorObject obj = err.getErrors().get(0).getErrorObject();
- LOG.warn("Unexpected error received from PCC: type {} value {}", obj.getType(), obj.getValue());
- negotiationFailed(new IllegalStateException("Unexpected error received from PCC."));
- this.state = State.Idle;
- return;
- }
- this.localPrefs = getRevisedProposal(((SessionCase) err.getErrorType()).getSession().getOpen());
- if (this.localPrefs == null) {
- sendErrorMessage(PCEPErrors.PCERR_NON_ACC_SESSION_CHAR);
- negotiationFailed(new IllegalStateException("Peer suggested unacceptable retry proposal"));
- this.state = State.Finished;
- return;
- }
- this.sendMessage(new OpenBuilder().setOpenMessage(new OpenMessageBuilder().setOpen(this.localPrefs).build()).build());
- if (!this.remoteOK) {
- this.state = State.OpenWait;
- }
- scheduleFailTimer();
+ if (handleMessageKeepWait(msg)) {
return;
}
-
break;
case OpenWait:
- if (msg instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Open) {
- final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.message.OpenMessage o = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Open) msg).getOpenMessage();
- final Open open = o.getOpen();
- if (isProposalAcceptable(open)) {
- this.sendMessage(KEEPALIVE);
- this.remotePrefs = open;
- this.remoteOK = true;
- if (this.localOK) {
- negotiationSuccessful(createSession(this.channel, this.localPrefs, this.remotePrefs));
- LOG.info("PCEP peer {} completed negotiation", this.channel);
- this.state = State.Finished;
- } else {
- scheduleFailTimer();
- this.state = State.KeepWait;
- LOG.debug("Channel {} moved to KeepWait state with remoteOK=1", this.channel);
- }
- return;
- }
-
- if (this.openRetry) {
- sendErrorMessage(PCEPErrors.SECOND_OPEN_MSG);
- negotiationFailed(new IllegalStateException("OPEN renegotiation failed"));
- this.state = State.Finished;
- return;
- }
-
- final Open newPrefs = getCounterProposal(open);
- if (newPrefs == null) {
- sendErrorMessage(PCEPErrors.NON_ACC_NON_NEG_SESSION_CHAR);
- negotiationFailed(new IllegalStateException("Peer sent unacceptable session parameters"));
- this.state = State.Finished;
- return;
- }
-
- this.sendMessage(Util.createErrorMessage(PCEPErrors.NON_ACC_NEG_SESSION_CHAR, newPrefs));
-
- this.openRetry = true;
- this.state = this.localOK ? State.OpenWait : State.KeepWait;
- scheduleFailTimer();
+ if (handleMessageOpenWait(msg)) {
return;
}
-
break;
}
-
LOG.warn("Channel {} in state {} received unexpected message {}", this.channel, this.state, msg);
sendErrorMessage(PCEPErrors.NON_OR_INVALID_OPEN_MSG);
negotiationFailed(new Exception("Illegal message encountered"));
*/
package org.opendaylight.protocol.pcep.impl;
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.HashBiMap;
-import com.google.common.primitives.UnsignedBytes;
-
import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelFutureListener;
import io.netty.util.concurrent.Promise;
-
-import java.net.InetSocketAddress;
-import java.util.Comparator;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.concurrent.GuardedBy;
-
-import org.opendaylight.protocol.framework.AbstractSessionNegotiator;
import org.opendaylight.protocol.framework.SessionListenerFactory;
import org.opendaylight.protocol.framework.SessionNegotiator;
import org.opendaylight.protocol.framework.SessionNegotiatorFactory;
*/
public abstract class AbstractPCEPSessionNegotiatorFactory implements
SessionNegotiatorFactory<Message, PCEPSessionImpl, PCEPSessionListener> {
- private static final Comparator<byte[]> COMPARATOR = UnsignedBytes.lexicographicalComparator();
- private static final Logger LOG = LoggerFactory.getLogger(AbstractPCEPSessionNegotiatorFactory.class);
-
- /**
- * The total amount of time we should remember a peer having been present, unless some other pressure forces us to
- * forget about it due to {@link PEER_CACHE_SIZE}.
- */
- private static final long PEER_CACHE_SECONDS = 24 * 3600;
-
- /**
- * Maximum total number of peers we keep track of. Combined with {@link PEER_CACHE_SECONDS}, this defines how many
- * peers we can see turn around.
- */
- private static final long PEER_CACHE_SIZE = 1024;
-
- /**
- * The maximum lifetime for which we should hold on to a session ID before assuming it is okay to reuse it.
- */
- private static final long ID_CACHE_SECONDS = 3 * 3600;
-
- @GuardedBy("this")
- private final BiMap<byte[], SessionReference> sessions = HashBiMap.create();
- @GuardedBy("this")
- private final Cache<byte[], PeerRecord> formerClients = CacheBuilder.newBuilder().expireAfterAccess(PEER_CACHE_SECONDS,
- TimeUnit.SECONDS).maximumSize(PEER_CACHE_SIZE).build();
-
- private interface SessionReference extends AutoCloseable {
- Short getSessionId();
- }
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractPCEPSessionNegotiatorFactory.class);
/**
* Create a new negotiator. This method needs to be implemented by subclasses to actually provide a negotiator.
public final SessionNegotiator<PCEPSessionImpl> getSessionNegotiator(final SessionListenerFactory<PCEPSessionListener> factory,
final Channel channel, final Promise<PCEPSessionImpl> promise) {
- final Object lock = this;
-
LOG.debug("Instantiating bootstrap negotiator for channel {}", channel);
- return new AbstractSessionNegotiator<Message, PCEPSessionImpl>(promise, channel) {
- @Override
- protected void startNegotiation() throws ExecutionException {
- LOG.debug("Bootstrap negotiation for channel {} started", this.channel);
-
- /*
- * We have a chance to see if there's a client session already
- * registered for this client.
- */
- final byte[] clientAddress = ((InetSocketAddress) this.channel.remoteAddress()).getAddress().getAddress();
-
- synchronized (lock) {
- if (AbstractPCEPSessionNegotiatorFactory.this.sessions.containsKey(clientAddress)) {
- final byte[] serverAddress = ((InetSocketAddress) this.channel.localAddress()).getAddress().getAddress();
- if (COMPARATOR.compare(serverAddress, clientAddress) > 0) {
- final SessionReference n = AbstractPCEPSessionNegotiatorFactory.this.sessions.remove(clientAddress);
- try {
- n.close();
- } catch (final Exception e) {
- LOG.error("Unexpected failure to close old session", e);
- }
- } else {
- negotiationFailed(new IllegalStateException("A conflicting session for address "
- + ((InetSocketAddress) this.channel.remoteAddress()).getAddress() + " found."));
- return;
- }
- }
-
- final Short sessionId = nextSession(clientAddress);
- final AbstractPCEPSessionNegotiator n = createNegotiator(promise, factory.getSessionListener(), this.channel, sessionId);
-
- AbstractPCEPSessionNegotiatorFactory.this.sessions.put(clientAddress, new SessionReference() {
- @Override
- public void close() throws ExecutionException {
- try {
- formerClients.get(clientAddress, new Callable<PeerRecord>() {
- @Override
- public PeerRecord call() {
- return new PeerRecord(ID_CACHE_SECONDS, getSessionId());
- }
- });
- } finally {
- channel.close();
- }
- }
-
- @Override
- public Short getSessionId() {
- return sessionId;
- }
- });
-
- this.channel.closeFuture().addListener(new ChannelFutureListener() {
- @Override
- public void operationComplete(final ChannelFuture future) {
- synchronized (lock) {
- AbstractPCEPSessionNegotiatorFactory.this.sessions.inverse().remove(this);
- }
- }
- });
-
- LOG.info("Replacing bootstrap negotiator for channel {}", this.channel);
- this.channel.pipeline().replace(this, "negotiator", n);
- n.startNegotiation();
- }
- }
-
- @Override
- protected void handleMessage(final Message msg) {
- throw new IllegalStateException("Bootstrap negotiator should have been replaced");
- }
- };
+ return new PCEPSessionNegotiator(channel, promise, factory, this);
}
- @GuardedBy("this")
- private Short nextSession(final byte[] clientAddress) throws ExecutionException {
- final PeerRecord peer = formerClients.get(clientAddress, new Callable<PeerRecord>() {
- @Override
- public PeerRecord call() {
- return new PeerRecord(ID_CACHE_SECONDS, null);
- }
- });
-
- return peer.allocId();
- }
}
this.sendErrorMessage(error);
if (error == PCEPErrors.CAPABILITY_NOT_SUPPORTED) {
this.unknownMessagesTimes.add(ct);
- while (ct - this.unknownMessagesTimes.peek() > 60 * 1E9) {
+ while (ct - this.unknownMessagesTimes.peek() > TimeUnit.MINUTES.toNanos(1)) {
this.unknownMessagesTimes.poll();
}
if (this.unknownMessagesTimes.size() > this.maxUnknownMessages) {
--- /dev/null
+/*
+ * Copyright (c) 2014 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.pcep.impl;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import com.google.common.primitives.UnsignedBytes;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.util.concurrent.Promise;
+import java.net.InetSocketAddress;
+import java.util.Comparator;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.protocol.framework.AbstractSessionNegotiator;
+import org.opendaylight.protocol.framework.SessionListenerFactory;
+import org.opendaylight.protocol.pcep.PCEPSessionListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PCEPSessionNegotiator extends AbstractSessionNegotiator<Message, PCEPSessionImpl> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(PCEPSessionNegotiator.class);
+
+ private static final Comparator<byte[]> COMPARATOR = UnsignedBytes.lexicographicalComparator();
+
+ /**
+ * The maximum lifetime for which we should hold on to a session ID before assuming it is okay to reuse it.
+ */
+ private static final long ID_CACHE_SECONDS = 3 * 3600;
+
+ /**
+ * The total amount of time we should remember a peer having been present, unless some other pressure forces us to
+ * forget about it due to {@link PEER_CACHE_SIZE}.
+ */
+ private static final long PEER_CACHE_SECONDS = 24 * 3600;
+
+ /**
+ * Maximum total number of peers we keep track of. Combined with {@link PEER_CACHE_SECONDS}, this defines how many
+ * peers we can see turn around.
+ */
+ private static final long PEER_CACHE_SIZE = 1024;
+
+ @GuardedBy("this")
+ private final Cache<byte[], PeerRecord> formerClients = CacheBuilder.newBuilder().expireAfterAccess(PEER_CACHE_SECONDS,
+ TimeUnit.SECONDS).maximumSize(PEER_CACHE_SIZE).build();
+
+ private final Channel channel;
+
+ private final Promise<PCEPSessionImpl> promise;
+
+ private final SessionListenerFactory<PCEPSessionListener> factory;
+
+ private final AbstractPCEPSessionNegotiatorFactory negFactory;
+
+ @GuardedBy("this")
+ private final BiMap<byte[], SessionReference> sessions = HashBiMap.create();
+
+ private interface SessionReference extends AutoCloseable {
+ Short getSessionId();
+ }
+
+ public PCEPSessionNegotiator(final Channel channel, final Promise<PCEPSessionImpl> promise, final SessionListenerFactory<PCEPSessionListener> factory,
+ final AbstractPCEPSessionNegotiatorFactory negFactory) {
+ super(promise, channel);
+ this.channel = channel;
+ this.promise = promise;
+ this.factory = factory;
+ this.negFactory = negFactory;
+ }
+
+ @Override
+ protected void startNegotiation() throws ExecutionException {
+ final Object lock = this;
+
+ LOG.debug("Bootstrap negotiation for channel {} started", this.channel);
+
+ /*
+ * We have a chance to see if there's a client session already
+ * registered for this client.
+ */
+ final byte[] clientAddress = ((InetSocketAddress) this.channel.remoteAddress()).getAddress().getAddress();
+
+ synchronized (lock) {
+ if (this.sessions.containsKey(clientAddress)) {
+ final byte[] serverAddress = ((InetSocketAddress) this.channel.localAddress()).getAddress().getAddress();
+ if (COMPARATOR.compare(serverAddress, clientAddress) > 0) {
+ final SessionReference n = this.sessions.remove(clientAddress);
+ try {
+ n.close();
+ } catch (final Exception e) {
+ LOG.error("Unexpected failure to close old session", e);
+ }
+ } else {
+ negotiationFailed(new IllegalStateException("A conflicting session for address "
+ + ((InetSocketAddress) this.channel.remoteAddress()).getAddress() + " found."));
+ return;
+ }
+ }
+
+ final Short sessionId = nextSession(clientAddress);
+ final AbstractPCEPSessionNegotiator n = this.negFactory.createNegotiator(this.promise, this.factory.getSessionListener(), this.channel, sessionId);
+
+ this.sessions.put(clientAddress, new SessionReference() {
+ @Override
+ public void close() throws ExecutionException {
+ try {
+ PCEPSessionNegotiator.this.formerClients.get(clientAddress, new Callable<PeerRecord>() {
+ @Override
+ public PeerRecord call() {
+ return new PeerRecord(ID_CACHE_SECONDS, getSessionId());
+ }
+ });
+ } finally {
+ PCEPSessionNegotiator.this.channel.close();
+ }
+ }
+
+ @Override
+ public Short getSessionId() {
+ return sessionId;
+ }
+ });
+
+ this.channel.closeFuture().addListener(new ChannelFutureListener() {
+ @Override
+ public void operationComplete(final ChannelFuture future) {
+ synchronized (lock) {
+ PCEPSessionNegotiator.this.sessions.inverse().remove(this);
+ }
+ }
+ });
+
+ LOG.info("Replacing bootstrap negotiator for channel {}", this.channel);
+ this.channel.pipeline().replace(this, "negotiator", n);
+ n.startNegotiation();
+ }
+ }
+
+ @GuardedBy("this")
+ protected Short nextSession(final byte[] clientAddress) throws ExecutionException {
+ final PeerRecord peer = this.formerClients.get(clientAddress, new Callable<PeerRecord>() {
+ @Override
+ public PeerRecord call() {
+ return new PeerRecord(ID_CACHE_SECONDS, null);
+ }
+ });
+
+ return peer.allocId();
+ }
+
+ @Override
+ protected void handleMessage(final Message msg) {
+ throw new IllegalStateException("Bootstrap negotiator should have been replaced");
+ }
+}
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
+import java.util.ArrayList;
import java.util.List;
import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
import org.opendaylight.protocol.pcep.spi.MessageUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.PcntfMessage;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.notification.object.CNotification;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.PcntfMessageBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.notifications.Notifications;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.Notifications;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.notifications.NotificationsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.notifications.Rps;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.notifications.RpsBuilder;
@Override
public void serializeMessage(final Message message, final ByteBuf out) {
Preconditions.checkArgument(message instanceof PcntfMessage, "Wrong instance of Message. Passed instance of %s. Need PcntfMessage.", message.getClass());
- final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.PcntfMessage msg = ((PcntfMessage) message).getPcntfMessage();
-
- ByteBuf buffer = Unpooled.buffer();
- for (final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.Notifications n : msg.getNotifications()) {
- if (n.getRps() != null && !n.getRps().isEmpty()) {
+ final ByteBuf buffer = Unpooled.buffer();
+ for (final Notifications n : ((PcntfMessage) message).getPcntfMessage().getNotifications()) {
+ if (n.getRps() != null) {
for (final Rps rps : n.getRps()) {
serializeObject(rps.getRp(), buffer);
}
}
if (n.getNotifications() == null || n.getNotifications().isEmpty()) {
throw new IllegalArgumentException("Message must contain at least one notification object");
- } else {
- for (final Notifications not : n.getNotifications()) {
- serializeObject(not.getCNotification(), buffer);
- }
+ }
+ for (final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.notifications.Notifications not : n.getNotifications()) {
+ serializeObject(not.getCNotification(), buffer);
}
}
MessageUtil.formatMessage(TYPE, buffer, out);
throw new PCEPDeserializerException("Notification message cannot be empty.");
}
- final List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.Notifications> compositeNotifications = Lists.newArrayList();
+ final List<Notifications> compositeNotifications = new ArrayList<>();
while (!objects.isEmpty()) {
- org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.Notifications comObj;
- comObj = getValidNotificationComposite(objects, errors);
-
+ final Notifications comObj = getValidNotificationComposite(objects, errors);
if (comObj == null) {
break;
}
return new PcntfBuilder().setPcntfMessage(new PcntfMessageBuilder().setNotifications(compositeNotifications).build()).build();
}
- private static org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.Notifications getValidNotificationComposite(
- final List<Object> objects, final List<Message> errors) {
- final List<Rps> requestParameters = Lists.newArrayList();
- final List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.notifications.Notifications> notifications = Lists.newArrayList();
+ private static Notifications getValidNotificationComposite(final List<Object> objects, final List<Message> errors) {
+ final List<Rps> requestParameters = new ArrayList<>();
+ final List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.notifications.Notifications> notifications = new ArrayList<>();
Object obj;
State state = State.Init;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
+import java.util.ArrayList;
import java.util.List;
import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
import org.opendaylight.protocol.pcep.spi.MessageUtil;
protected void serializeReply(final Replies reply, final ByteBuf buffer) {
serializeObject(reply.getRp(), buffer);
serializeVendorInformationObjects(reply.getVendorInformationObject(), buffer);
- if (reply.getResult() != null) {
- if (reply.getResult() instanceof FailureCase) {
- final FailureCase f = ((FailureCase) reply.getResult());
- if (f != null) {
- serializeObject(f.getNoPath(), buffer);
- serializeObject(f.getLspa(), buffer);
- serializeObject(f.getBandwidth(), buffer);
- if (f.getMetrics() != null && !f.getMetrics().isEmpty()) {
- for (final Metrics m : f.getMetrics()) {
- serializeObject(m.getMetric(), buffer);
- }
+ if (reply.getResult() == null) {
+ return;
+ }
+ if (reply.getResult() instanceof FailureCase) {
+ final FailureCase f = ((FailureCase) reply.getResult());
+ if (f != null) {
+ serializeObject(f.getNoPath(), buffer);
+ serializeObject(f.getLspa(), buffer);
+ serializeObject(f.getBandwidth(), buffer);
+ if (f.getMetrics() != null) {
+ for (final Metrics m : f.getMetrics()) {
+ serializeObject(m.getMetric(), buffer);
}
- serializeObject(f.getIro(), buffer);
}
- } else {
- final SuccessCase s = (SuccessCase) reply.getResult();
- if (s != null && s.getSuccess() != null) {
- for (final Paths p : s.getSuccess().getPaths()) {
- serializeObject(p.getEro(), buffer);
- serializeObject(p.getLspa(), buffer);
- serializeObject(p.getOf(), buffer);
- serializeObject(p.getBandwidth(), buffer);
- if (p.getMetrics() != null && !p.getMetrics().isEmpty()) {
- for (final Metrics m : p.getMetrics()) {
- serializeObject(m.getMetric(), buffer);
- }
- }
- serializeObject(p.getIro(), buffer);
+ serializeObject(f.getIro(), buffer);
+ }
+ return;
+ }
+ final SuccessCase s = (SuccessCase) reply.getResult();
+ if (s != null && s.getSuccess() != null) {
+ for (final Paths p : s.getSuccess().getPaths()) {
+ serializeObject(p.getEro(), buffer);
+ serializeObject(p.getLspa(), buffer);
+ serializeObject(p.getOf(), buffer);
+ serializeObject(p.getBandwidth(), buffer);
+ if (p.getMetrics() != null) {
+ for (final Metrics m : p.getMetrics()) {
+ serializeObject(m.getMetric(), buffer);
}
- serializeVendorInformationObjects(s.getSuccess().getVendorInformationObject(), buffer);
}
+ serializeObject(p.getIro(), buffer);
}
+ serializeVendorInformationObjects(s.getSuccess().getVendorInformationObject(), buffer);
}
}
if (objects.isEmpty()) {
throw new PCEPDeserializerException("Pcrep message cannot be empty.");
}
- final List<Replies> replies = Lists.newArrayList();
+ final List<Replies> replies = new ArrayList<>();
while (!objects.isEmpty()) {
final Replies r = this.getValidReply(objects, errors);
if (r != null) {
final Ero ero = (Ero) objects.get(0);
objects.remove(0);
final SuccessBuilder builder = new SuccessBuilder();
- final List<Paths> paths = Lists.newArrayList();
+ final List<Paths> paths = new ArrayList<>();
final PathsBuilder pBuilder = new PathsBuilder();
pBuilder.setEro(ero);
while (!objects.isEmpty()) {
}
protected void parseAttributes(final FailureCaseBuilder builder, final List<Object> objects) {
- final List<Metrics> pathMetrics = Lists.newArrayList();
+ final List<Metrics> pathMetrics = new ArrayList<>();
Object obj;
State state = State.Init;
}
protected void parsePath(final PathsBuilder builder, final List<Object> objects) {
- final List<Metrics> pathMetrics = Lists.newArrayList();
+ final List<Metrics> pathMetrics = new ArrayList<>();
Object obj;
State state = State.Init;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
+import java.util.ArrayList;
import java.util.List;
import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
import org.opendaylight.protocol.pcep.spi.MessageUtil;
if (objects == null) {
throw new IllegalArgumentException("Passed list can't be null.");
}
-
- final List<Requests> requests = Lists.newArrayList();
- final List<Svec> svecList = Lists.newArrayList();
+ final List<Requests> requests = new ArrayList<>();
+ final List<Svec> svecList = new ArrayList<>();
while (!objects.isEmpty()) {
final RequestsBuilder rBuilder = new RequestsBuilder();
Rp rpObj = null;
protected SegmentComputation getSegmentComputation(final P2pBuilder builder, final List<Object> objects, final List<Message> errors,
final Rp rp) {
- final List<Metrics> metrics = Lists.newArrayList();
- final List<VendorInformationObject> viObjects = Lists.newArrayList();
+ final List<Metrics> metrics = new ArrayList<>();
+ final List<VendorInformationObject> viObjects = new ArrayList<>();
State state = State.Init;
while (!objects.isEmpty() && state != State.End) {
if (objects == null || objects.isEmpty()) {
throw new IllegalArgumentException("List cannot be null or empty.");
}
-
- if (objects.get(0) instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.svec.object.Svec) {
- builder.setSvec((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.svec.object.Svec) objects.get(0));
- objects.remove(0);
- } else {
+ if (!(objects.get(0) instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.svec.object.Svec)) {
return null;
}
+ builder.setSvec((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.svec.object.Svec) objects.get(0));
+ objects.remove(0);
- final List<Metrics> metrics = Lists.newArrayList();
- final List<VendorInformationObject> viObjects = Lists.newArrayList();
+ final List<Metrics> metrics = new ArrayList<>();
+ final List<VendorInformationObject> viObjects = new ArrayList<>();
Object obj = null;
SvecState state = SvecState.Init;
try (final StatefulActivator activator07 = new StatefulActivator()) {
activator07.start(ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance());
- final PCEPDispatcherImpl dispatcher = new PCEPDispatcherImpl(ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance().getMessageHandlerRegistry(), new DefaultPCEPSessionNegotiatorFactory(prefs, 5), new NioEventLoopGroup(), new NioEventLoopGroup());
-
- dispatcher.createServer(address, new TestingSessionListenerFactory()).get();
+ try (final PCEPDispatcherImpl dispatcher = new PCEPDispatcherImpl(ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance().getMessageHandlerRegistry(), new DefaultPCEPSessionNegotiatorFactory(prefs, 5), new NioEventLoopGroup(), new NioEventLoopGroup())) {
+ dispatcher.createServer(address, new TestingSessionListenerFactory()).get();
+ }
}
}
}
return snb.build();
}
+ private void handleSni(final InstanceIdentifier<Node> sni, final Node n, final Boolean inControl, final ReadWriteTransaction trans) {
+ if (sni != null) {
+ final NodeKey k = InstanceIdentifier.keyOf(sni);
+ boolean have = false;
+ /*
+ * We may have found a termination point which has been created as a destination,
+ * so it does not have a supporting node pointer. Since we now know what it is,
+ * fill it in.
+ */
+ if (n.getSupportingNode() != null) {
+ for (final SupportingNode sn : n.getSupportingNode()) {
+ if (sn.getNodeRef().equals(k.getNodeId())) {
+ have = true;
+ break;
+ }
+ }
+ }
+ if (!have) {
+ final SupportingNode sn = createSupportingNode(k.getNodeId(), inControl);
+ trans.put(LogicalDatastoreType.OPERATIONAL, this.target.child(Node.class, n.getKey()).child(
+ SupportingNode.class, sn.getKey()), sn);
+ }
+ }
+ }
+
private InstanceIdentifier<TerminationPoint> getIpTerminationPoint(final ReadWriteTransaction trans, final IpAddress addr,
final InstanceIdentifier<Node> sni, final Boolean inControl) throws ReadFailedException {
final Topology topo = trans.read(LogicalDatastoreType.OPERATIONAL, this.target).checkedGet().get();
- if (topo.getNode() != null && !topo.getNode().isEmpty()) {
+ if (topo.getNode() != null) {
for (final Node n : topo.getNode()) {
- if(n.getTerminationPoint() != null && !n.getTerminationPoint().isEmpty()) {
+ if(n.getTerminationPoint() != null) {
for (final TerminationPoint tp : n.getTerminationPoint()) {
final TerminationPoint1 tpa = tp.getAugmentation(TerminationPoint1.class);
-
if (tpa != null) {
final TerminationPointType tpt = tpa.getIgpTerminationPointAttributes().getTerminationPointType();
-
if (tpt instanceof Ip) {
for (final IpAddress a : ((Ip) tpt).getIpAddress()) {
if (addr.equals(a)) {
- if (sni != null) {
- final NodeKey k = InstanceIdentifier.keyOf(sni);
- boolean have = false;
-
- /*
- * We may have found a termination point which has been created as a destination,
- * so it does not have a supporting node pointer. Since we now know what it is,
- * fill it in.
- */
- if (n.getSupportingNode() != null) {
- for (final SupportingNode sn : n.getSupportingNode()) {
- if (sn.getNodeRef().equals(k.getNodeId())) {
- have = true;
- break;
- }
- }
- }
-
- if (!have) {
- final SupportingNode sn = createSupportingNode(k.getNodeId(), inControl);
-
- trans.put(LogicalDatastoreType.OPERATIONAL, this.target.child(Node.class, n.getKey()).child(
- SupportingNode.class, sn.getKey()), sn);
- }
- }
+ handleSni(sni, n, inControl, trans);
return this.target.builder().child(Node.class, n.getKey()).child(TerminationPoint.class, tp.getKey()).toInstance();
}
}
}
}
}
-
LOG.debug("Termination point for {} not found, creating a new one", addr);
+ return createTP(addr, sni, inControl, trans);
+ }
+ private InstanceIdentifier<TerminationPoint> createTP(final IpAddress addr, final InstanceIdentifier<Node> sni,
+ final Boolean inControl, final ReadWriteTransaction trans) {
final String url = "ip://" + addr.toString();
final TerminationPointKey tpk = new TerminationPointKey(new TpId(url));
final TerminationPointBuilder tpb = new TerminationPointBuilder();
if (sni != null) {
nb.setSupportingNode(Lists.newArrayList(createSupportingNode(InstanceIdentifier.keyOf(sni).getNodeId(), inControl)));
}
-
final InstanceIdentifier<Node> nid = this.target.child(Node.class, nb.getKey());
trans.put(LogicalDatastoreType.OPERATIONAL, nid, nb.build());
return nid.child(TerminationPoint.class, tpb.getKey());
return;
}
- final Link l = (Link) ol.get();
+ final Link l = ol.get();
LOG.debug("Removing link {} (was {})", li, l);
trans.delete(LogicalDatastoreType.OPERATIONAL, li);
final Optional<Topology> ot = trans.read(LogicalDatastoreType.OPERATIONAL, this.target).checkedGet();
Preconditions.checkState(ot.isPresent());
- final Topology t = (Topology) ot.get();
- NodeId srcNode = l.getSource().getSourceNode();
- NodeId dstNode = l.getDestination().getDestNode();
- TpId srcTp = l.getSource().getSourceTp();
- TpId dstTp = l.getDestination().getDestTp();
+ final Topology t = ot.get();
+ final NodeId srcNode = l.getSource().getSourceNode();
+ final NodeId dstNode = l.getDestination().getDestNode();
+ final TpId srcTp = l.getSource().getSourceTp();
+ final TpId dstTp = l.getDestination().getDestTp();
boolean orphSrcNode = true, orphDstNode = true, orphDstTp = true, orphSrcTp = true;
for (final Link lw : t.getLink()) {
if (oldValue != null) {
try {
remove(trans, i, oldValue);
- } catch (ReadFailedException e) {
+ } catch (final ReadFailedException e) {
LOG.warn("Failed to remove LSP {}", i, e);
}
}
if (newValue != null) {
try {
create(trans, i, newValue);
- } catch (ReadFailedException e) {
+ } catch (final ReadFailedException e) {
LOG.warn("Failed to add LSP {}", i, e);
}
}
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
-
import io.netty.util.Timeout;
-
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-
import javax.annotation.concurrent.GuardedBy;
-
import org.opendaylight.bgpcep.programming.spi.ExecutionResult;
import org.opendaylight.bgpcep.programming.spi.Instruction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.CancelFailure;
}
InstructionId getId() {
- return id;
+ return this.id;
}
synchronized InstructionStatus getStatus() {
synchronized void setStatus(final InstructionStatus status, final Details details) {
// Set the status
this.status = status;
- LOG.debug("Instruction {} transitioned to status {}", id, status);
+ LOG.debug("Instruction {} transitioned to status {}", this.id, status);
// Send out a notification
this.queue.instructionUpdated(status, details);
@GuardedBy("this")
private void cancelTimeout() {
- if (timeout != null) {
- timeout.cancel();
- timeout = null;
+ if (this.timeout != null) {
+ this.timeout.cancel();
+ this.timeout = null;
}
}
public synchronized void timeout() {
- if (timeout != null) {
- timeout = null;
-
- switch (status) {
- case Cancelled:
- case Failed:
- case Successful:
- LOG.debug("Instruction {} has status {}, timeout is a no-op", id, status);
- break;
- case Unknown:
- LOG.warn("Instruction {} has status {} before timeout completed", id, status);
- break;
- case Executing:
- LOG.info("Instruction {} timed out while executing, transitioning into Unknown", id);
- setStatus(InstructionStatus.Unknown, null);
- cancelDependants();
- break;
- case Queued:
- LOG.debug("Instruction {} timed out while Queued, cancelling it", id);
-
- final List<InstructionId> ids = new ArrayList<>();
- for (final InstructionImpl d : dependencies) {
- if (d.getStatus() != InstructionStatus.Successful) {
- ids.add(d.getId());
- }
+ if (this.timeout == null) {
+ return;
+ }
+ this.timeout = null;
+ switch (this.status) {
+ case Cancelled:
+ case Failed:
+ case Successful:
+ LOG.debug("Instruction {} has status {}, timeout is a no-op", this.id, this.status);
+ break;
+ case Unknown:
+ LOG.warn("Instruction {} has status {} before timeout completed", this.id, this.status);
+ break;
+ case Executing:
+ LOG.info("Instruction {} timed out while executing, transitioning into Unknown", this.id);
+ setStatus(InstructionStatus.Unknown, null);
+ cancelDependants();
+ break;
+ case Queued:
+ LOG.debug("Instruction {} timed out while Queued, cancelling it", this.id);
+ final List<InstructionId> ids = new ArrayList<>();
+ for (final InstructionImpl d : this.dependencies) {
+ if (d.getStatus() != InstructionStatus.Successful) {
+ ids.add(d.getId());
}
-
- cancel(new DetailsBuilder().setUnmetDependencies(ids).build());
- break;
- case Scheduled:
- LOG.debug("Instruction {} timed out while Scheduled, cancelling it", id);
- cancel(heldUpDetails);
- break;
}
+ cancel(new DetailsBuilder().setUnmetDependencies(ids).build());
+ break;
+ case Scheduled:
+ LOG.debug("Instruction {} timed out while Scheduled, cancelling it", this.id);
+ cancel(this.heldUpDetails);
+ break;
}
}
@GuardedBy("this")
private void cancelDependants() {
- final Details details = new DetailsBuilder().setUnmetDependencies(ImmutableList.of(id)).build();
- for (final InstructionImpl d : dependants) {
+ final Details details = new DetailsBuilder().setUnmetDependencies(ImmutableList.of(this.id)).build();
+ for (final InstructionImpl d : this.dependants) {
d.tryCancel(details);
}
}
@GuardedBy("this")
private void cancel(final Details details) {
cancelTimeout();
- schedulingFuture.cancel(false);
+ this.schedulingFuture.cancel(false);
setStatus(InstructionStatus.Cancelled, details);
}
synchronized Class<? extends CancelFailure> tryCancel(final Details details) {
- switch (status) {
+ switch (this.status) {
case Cancelled:
case Executing:
case Failed:
case Successful:
case Unknown:
- LOG.debug("Instruction {} can no longer be cancelled due to status {}", id, status);
+ LOG.debug("Instruction {} can no longer be cancelled due to status {}", this.id, this.status);
return UncancellableInstruction.class;
case Queued:
case Scheduled:
return null;
}
- throw new IllegalStateException("Unhandled instruction state " + status);
+ throw new IllegalStateException("Unhandled instruction state " + this.status);
}
@Override
public synchronized boolean checkedExecutionStart() {
- if (status != InstructionStatus.Scheduled) {
+ if (this.status != InstructionStatus.Scheduled) {
return false;
}
@Override
public synchronized boolean executionHeldUp(final Details details) {
- if (status != InstructionStatus.Scheduled) {
+ if (this.status != InstructionStatus.Scheduled) {
return false;
}
@Override
public synchronized void executionCompleted(final InstructionStatus status, final Details details) {
- Preconditions.checkState(executionFuture != null);
+ Preconditions.checkState(this.executionFuture != null);
cancelTimeout();
// We reuse the preconditions set down in this class
final ExecutionResult<Details> result = new ExecutionResult<Details>(status, details);
setStatus(status, details);
- executionFuture.set(result);
+ this.executionFuture.set(result);
}
synchronized void addDependant(final InstructionImpl d) {
- dependants.add(d);
+ this.dependants.add(d);
}
private synchronized void removeDependant(final InstructionImpl d) {
- dependants.remove(d);
+ this.dependants.remove(d);
}
private synchronized void removeDependency(final InstructionImpl other) {
- dependencies.remove(other);
+ this.dependencies.remove(other);
}
synchronized Iterator<InstructionImpl> getDependants() {
- return dependants.iterator();
+ return this.dependants.iterator();
}
synchronized void clean() {
- for (final Iterator<InstructionImpl> it = dependencies.iterator(); it.hasNext();) {
+ for (final Iterator<InstructionImpl> it = this.dependencies.iterator(); it.hasNext();) {
it.next().removeDependant(this);
}
- dependencies.clear();
+ this.dependencies.clear();
- for (final Iterator<InstructionImpl> it = dependants.iterator(); it.hasNext();) {
+ for (final Iterator<InstructionImpl> it = this.dependants.iterator(); it.hasNext();) {
it.next().removeDependency(this);
}
- dependants.clear();
+ this.dependants.clear();
this.queue.instructionRemoved();
}
- synchronized ListenableFuture<ExecutionResult<Details>> ready() {
- Preconditions.checkState(status == InstructionStatus.Queued);
- Preconditions.checkState(executionFuture == null);
-
- /*
- * Check all vertices we depend on. We start off as ready for
- * scheduling. If we encounter a cancelled/failed/unknown
- * dependency, we cancel this instruction (and cascade). If we
- * encounter an executing/queued/scheduled dependency, we hold
- * of scheduling this one.
- */
+ private Boolean checkDependencies() {
boolean ready = true;
-
final List<InstructionId> unmet = new ArrayList<>();
- for (final InstructionImpl d : dependencies) {
+ for (final InstructionImpl d : this.dependencies) {
switch (d.getStatus()) {
case Cancelled:
case Failed:
break;
}
}
-
if (!unmet.isEmpty()) {
- LOG.warn("Instruction {} was Queued, while some dependencies were resolved unsuccessfully, cancelling it", id);
+ LOG.warn("Instruction {} was Queued, while some dependencies were resolved unsuccessfully, cancelling it", this.id);
cancel(new DetailsBuilder().setUnmetDependencies(unmet).build());
return null;
}
+ return ready;
+ }
- if (!ready) {
+ synchronized ListenableFuture<ExecutionResult<Details>> ready() {
+ Preconditions.checkState(this.status == InstructionStatus.Queued);
+ Preconditions.checkState(this.executionFuture == null);
+ /*
+ * Check all vertices we depend on. We start off as ready for
+ * scheduling. If we encounter a cancelled/failed/unknown
+ * dependency, we cancel this instruction (and cascade). If we
+ * encounter an executing/queued/scheduled dependency, we hold
+ * of scheduling this one.
+ */
+ final Boolean ready = checkDependencies();
+ if (ready == null || !ready) {
return null;
}
-
- LOG.debug("Instruction {} is ready for execution", id);
+ LOG.debug("Instruction {} is ready for execution", this.id);
setStatus(InstructionStatus.Scheduled, null);
- executionFuture = SettableFuture.create();
- schedulingFuture.set(this);
- return executionFuture;
+ this.executionFuture = SettableFuture.create();
+ this.schedulingFuture.set(this);
+ return this.executionFuture;
}
-}
\ No newline at end of file
+}
private final InstructionBuilder builder = new InstructionBuilder();
InstructionPusher(final InstructionId id, final Nanotime deadline) {
- builder.setDeadline(deadline);
- builder.setId(id);
- builder.setKey(new InstructionKey(id));
- builder.setStatus(InstructionStatus.Queued);
+ this.builder.setDeadline(deadline);
+ this.builder.setId(id);
+ this.builder.setKey(new InstructionKey(id));
+ this.builder.setStatus(InstructionStatus.Queued);
}
@Override
public void instructionUpdated(final InstructionStatus status, final Details details) {
- if (!status.equals(builder.getStatus())) {
- builder.setStatus(status);
+ if (!status.equals(this.builder.getStatus())) {
+ this.builder.setStatus(status);
- final WriteTransaction t = dataProvider.newWriteOnlyTransaction();
+ final WriteTransaction t = ProgrammingServiceImpl.this.dataProvider.newWriteOnlyTransaction();
t.put(LogicalDatastoreType.OPERATIONAL,
- qid.child(
+ ProgrammingServiceImpl.this.qid.child(
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.instruction.queue.Instruction.class,
- new InstructionKey(builder.getId())), builder.build());
+ new InstructionKey(this.builder.getId())), this.builder.build());
t.submit();
}
- notifs.publish(new InstructionStatusChangedBuilder().setId(builder.getId()).setStatus(status).setDetails(details).build());
+ ProgrammingServiceImpl.this.notifs.publish(new InstructionStatusChangedBuilder().setId(this.builder.getId()).setStatus(status).setDetails(details).build());
}
@Override
public void instructionRemoved() {
- final WriteTransaction t = dataProvider.newWriteOnlyTransaction();
- t.delete(LogicalDatastoreType.OPERATIONAL, qid.child(
+ final WriteTransaction t = ProgrammingServiceImpl.this.dataProvider.newWriteOnlyTransaction();
+ t.delete(LogicalDatastoreType.OPERATIONAL, ProgrammingServiceImpl.this.qid.child(
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.instruction.queue.Instruction.class,
- new InstructionKey(builder.getId())));
+ new InstructionKey(this.builder.getId())));
t.submit();
}
}
this.notifs = Preconditions.checkNotNull(notifs);
this.executor = Preconditions.checkNotNull(executor);
this.timer = Preconditions.checkNotNull(timer);
- qid = InstanceIdentifier.builder(InstructionsQueue.class).toInstance();
+ this.qid = InstanceIdentifier.builder(InstructionsQueue.class).toInstance();
final ReadWriteTransaction t = dataProvider.newReadWriteTransaction();
try {
- Preconditions.checkState(!t.read(LogicalDatastoreType.OPERATIONAL, qid).get().isPresent(), "Conflicting instruction queue found");
+ Preconditions.checkState(!t.read(LogicalDatastoreType.OPERATIONAL, this.qid).get().isPresent(), "Conflicting instruction queue found");
} catch (InterruptedException | ExecutionException e) {
throw new IllegalStateException("Failed to acquire instruction queue", e);
}
- t.put(LogicalDatastoreType.OPERATIONAL, qid,
+ t.put(LogicalDatastoreType.OPERATIONAL, this.qid,
new InstructionsQueueBuilder().setInstruction(
Collections.<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.instruction.queue.Instruction> emptyList()).build());
t.submit();
return SuccessfulRpcResult.create(ob.build());
}
- @Override
- public synchronized ListenableFuture<Instruction> scheduleInstruction(final SubmitInstructionInput input) throws SchedulerException {
- final InstructionId id = input.getId();
- if (this.insns.get(id) != null) {
- LOG.info("Instruction ID {} already present", id);
- throw new SchedulerException("Instruction ID currently in use", new FailureBuilder().setType(DuplicateInstructionId.class).build());
- }
-
- // First things first: check the deadline
- final Nanotime now = NanotimeUtil.currentTime();
- final BigInteger left = input.getDeadline().getValue().subtract(now.getValue());
-
- if (left.compareTo(BigInteger.ZERO) <= 0) {
- LOG.debug("Instruction {} deadline has already passed by {}ns", id, left);
- throw new SchedulerException("Instruction arrived after specified deadline", new FailureBuilder().setType(DeadOnArrival.class).build());
- }
-
- // Resolve dependencies
+ private List<InstructionImpl> checkDependencies(final SubmitInstructionInput input) throws SchedulerException {
final List<InstructionImpl> dependencies = new ArrayList<>();
for (final InstructionId pid : input.getPreconditions()) {
final InstructionImpl i = this.insns.get(pid);
if (i == null) {
- LOG.info("Instruction {} depends on {}, which is not a known instruction", id, pid);
+ LOG.info("Instruction {} depends on {}, which is not a known instruction", input.getId(), pid);
throw new SchedulerException("Unknown dependency ID specified", new FailureBuilder().setType(UnknownPreconditionId.class).build());
}
-
dependencies.add(i);
}
-
// Check if all dependencies are non-failed
final List<InstructionId> unmet = new ArrayList<>();
for (final InstructionImpl d : dependencies) {
break;
}
}
-
/*
* Some dependencies have failed, declare the request dead-on-arrival
* and fail the operation.
throw new SchedulerException("Instruction's dependencies are already unsuccessful", new FailureBuilder().setType(
DeadOnArrival.class).setFailedPreconditions(unmet).build());
}
+ return dependencies;
+ }
+
+ @Override
+ public synchronized ListenableFuture<Instruction> scheduleInstruction(final SubmitInstructionInput input) throws SchedulerException {
+ final InstructionId id = input.getId();
+ if (this.insns.get(id) != null) {
+ LOG.info("Instruction ID {} already present", id);
+ throw new SchedulerException("Instruction ID currently in use", new FailureBuilder().setType(DuplicateInstructionId.class).build());
+ }
+
+ // First things first: check the deadline
+ final Nanotime now = NanotimeUtil.currentTime();
+ final BigInteger left = input.getDeadline().getValue().subtract(now.getValue());
+
+ if (left.compareTo(BigInteger.ZERO) <= 0) {
+ LOG.debug("Instruction {} deadline has already passed by {}ns", id, left);
+ throw new SchedulerException("Instruction arrived after specified deadline", new FailureBuilder().setType(DeadOnArrival.class).build());
+ }
+
+ // Resolve dependencies
+ final List<InstructionImpl> dependencies = checkDependencies(input);
/*
* All pre-flight checks done are at this point, the following
@Override
public synchronized void close() {
try {
- for (InstructionImpl i : insns.values()) {
+ for (final InstructionImpl i : this.insns.values()) {
i.tryCancel(null);
}
} finally {
- final WriteTransaction t = dataProvider.newWriteOnlyTransaction();
- t.delete(LogicalDatastoreType.OPERATIONAL, qid);
+ final WriteTransaction t = this.dataProvider.newWriteOnlyTransaction();
+ t.delete(LogicalDatastoreType.OPERATIONAL, this.qid);
t.submit();
}
}