"Determines the state of the path-id";
}
+ // Generation algorithm
+
+ typedef generation-algorithm-enum {
+ type enumeration {
+ enum random {
+ value 1;
+ description
+ "Random Path-id generation";
+ }
+ enum sequential {
+ value 2;
+ description
+ "Sequential Path-id generation";
+ }
+ }
+ description
+ "The path-id generation algorithm";
+ }
+
container service-path-ids {
config false;
description
}
}
leaf generation-algorithm {
- type uint8;
+ type generation-algorithm-enum;
description
"The algorithm used to generate path-ids";
}
}
}
}
+
+ rpc set-generation-algorithm {
+ description
+ "Set the path-id generation algorithm to be used";
+ input {
+ leaf generation-algorithm {
+ type generation-algorithm-enum;
+ }
+ }
+ output {
+ leaf result {
+ type boolean;
+ description
+ "True if the generation-algorithm was set successfully,
+ otherwise false";
+ }
+ }
+ }
+
}
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
import org.opendaylight.sfc.provider.*;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.ServicePathIdService;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.RenderedServicePathService;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.ServiceFunctionService;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.ServiceFunctionChainService;
.addRpcImplementation(RenderedServicePathService.class,
sfcProviderRpc);
+ final BindingAwareBroker.RpcRegistration<ServicePathIdService> srvPathIdRpcRegistration =
+ getRpcRegistryDependency()
+ .addRpcImplementation(ServicePathIdService.class,
+ sfcProviderRpc);
+
// close()
final class AutoCloseableSfc implements AutoCloseable {
sfRpcRegistration.close();
sfcRpcRegistration.close();
rspRpcRegistration.close();
+ srvPathIdRpcRegistration.close();
try
{
import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI;
import org.opendaylight.sfc.provider.api.SfcProviderServiceFunctionAPI;
import org.opendaylight.sfc.provider.api.SfcProviderServicePathAPI;
+import org.opendaylight.sfc.provider.api.SfcServicePathId;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.AllocatePathIdInput;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.AllocatePathIdOutput;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.DeletePathIdInput;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.DeletePathIdOutput;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.ReadPathIdInput;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.ReadPathIdOutput;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.ReservePathIdRangeInput;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.ReservePathIdRangeOutput;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.ServicePathIdService;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.SetGenerationAlgorithmInput;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.SetGenerationAlgorithmOutput;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.SetGenerationAlgorithmOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.RspName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfcName;
* @since 2014-06-30
*/
-public class SfcProviderRpc implements ServiceFunctionService, ServiceFunctionChainService, RenderedServicePathService {
+public class SfcProviderRpc implements ServiceFunctionService, ServiceFunctionChainService, RenderedServicePathService, ServicePathIdService {
private static final Logger LOG = LoggerFactory.getLogger(SfcProviderRpc.class);
private OpendaylightSfc odlSfc = OpendaylightSfc.getOpendaylightSfcObj();
return null;
}
+ @Override
+ public Future<RpcResult<ReservePathIdRangeOutput>> reservePathIdRange(
+ ReservePathIdRangeInput input) {
+ return null;
+ }
+
+ @Override
+ public Future<RpcResult<ReadPathIdOutput>> readPathId(ReadPathIdInput input) {
+ return null;
+ }
+
+ @Override
+ public Future<RpcResult<AllocatePathIdOutput>> allocatePathId(
+ AllocatePathIdInput input) {
+ return null;
+ }
+
+ @Override
+ public Future<RpcResult<DeletePathIdOutput>> deletePathId(
+ DeletePathIdInput input) {
+ return null;
+ }
+
+ @Override
+ public Future<RpcResult<SetGenerationAlgorithmOutput>> setGenerationAlgorithm(
+ SetGenerationAlgorithmInput input) {
+
+ boolean result = SfcServicePathId.setGenerationAlgorithm(input.getGenerationAlgorithm());
+
+ SetGenerationAlgorithmOutputBuilder setGenerationAlgorithmOutputBuilder =
+ new SetGenerationAlgorithmOutputBuilder();
+ setGenerationAlgorithmOutputBuilder.setResult(result);
+ RpcResultBuilder<SetGenerationAlgorithmOutput> rpcResultBuilder =
+ RpcResultBuilder.success(setGenerationAlgorithmOutputBuilder.build());
+
+ return Futures.immediateFuture(rpcResultBuilder.build());
+ }
+
}
package org.opendaylight.sfc.provider.api;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.GenerationAlgorithmEnum;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.ServicePathIds;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.ServicePathIdsBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.service.path.ids.ServicePathId;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.service.path.ids.ServicePathIdBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.service.path.ids.ServicePathIdKey;
*/
private final static int MAX_PATH_ID = (int) Math.pow(2, 12) - 1;
private final static int MIN_PATH_ID = 0;
+ private final static int DEFAULT_GENERATION_ALGORITHM = GenerationAlgorithmEnum.Random.getIntValue();
private static final Random randomGenerator = new Random();
- //private static int next_pathid = (randomGenerator.nextInt() % (MAX_PATH_ID + 1));
private static int next_pathid = 0;
private final static int num_pathid = MAX_PATH_ID - MIN_PATH_ID + 1;
* @return Pathid or error if none available
*/
public static int generatePathIdRandomIncrements() {
-
int pathid;
-
int count = num_pathid;
do {
next_pathid = next_pathid + (randomGenerator.nextInt(num_pathid) % N) + 1;
pathid = MIN_PATH_ID + (next_pathid % num_pathid);
- if (check_suitable_pathid(pathid))
+ if (check_suitable_pathid(pathid)) {
+ return pathid;
+ }
+
+ count--;
+ } while (count > 0);
+
+ return -1;
+ }
+
+ /**
+ * Algorithm to sequentially generate pathIds.
+ *
+ * <p>
+ * @return Pathid or error if none available
+ */
+ public static int generatePathIdSequentialIncrements() {
+ int pathid;
+ int count = num_pathid;
+
+ do {
+ next_pathid = next_pathid + 1;
+ pathid = MIN_PATH_ID + next_pathid;
+
+ if (check_suitable_pathid(pathid) && allocate_pathid(pathid)) {
return pathid;
+ }
count--;
} while (count > 0);
}
}
-
/**
* Check and allocate symmetric Pathid if available
*
public static long check_and_allocate_symmetric_pathid(long pathid) {
if (SfcConcurrencyAPI.getPathIdLock()) {
try {
- long symmetric_id = pathid ^ (1 << 23);
- if (check_suitable_pathid(symmetric_id) && allocate_pathid(symmetric_id)) {
+ long symmetric_id = -1;
+ GenerationAlgorithmEnum genAlg = getGenerationAlgorithm();
+ if(genAlg == GenerationAlgorithmEnum.Random) {
+ symmetric_id = pathid ^ (1 << 23);
+ if(!check_suitable_pathid(symmetric_id)) {
+ symmetric_id = -1;
+ }
+ } else if(genAlg == GenerationAlgorithmEnum.Sequential) {
+ symmetric_id = generatePathIdSequentialIncrements();
+ }
+
+ if ((symmetric_id >= MIN_PATH_ID) && allocate_pathid(symmetric_id)) {
return symmetric_id;
} else {
return -1;
public static long check_and_allocate_pathid() {
if (SfcConcurrencyAPI.getPathIdLock()) {
try {
- long pathId = generatePathIdRandomIncrements();
+ long pathId = -1;
+ GenerationAlgorithmEnum genAlg = getGenerationAlgorithm();
+ if(genAlg == GenerationAlgorithmEnum.Random) {
+ pathId = generatePathIdRandomIncrements();
+ } else if(genAlg == GenerationAlgorithmEnum.Sequential) {
+ pathId = generatePathIdSequentialIncrements();
+ }
+
if ((pathId >= MIN_PATH_ID) && allocate_pathid(pathId)) {
return pathId;
} else {
}
return false;
}
+
+ /**
+ * Get the Path-Id Generation-algorithm from the data-store.
+ *
+ * If its not present, create it with the default value.
+ *
+ * <p>
+ * @return generation-algorithm enum value
+ */
+ public static GenerationAlgorithmEnum getGenerationAlgorithm() {
+ InstanceIdentifier<ServicePathIds> spIID =
+ InstanceIdentifier.builder(ServicePathIds.class).build();
+ ServicePathIds servicePathIds =
+ SfcDataStoreAPI.
+ readTransactionAPI(spIID, LogicalDatastoreType.OPERATIONAL);
+
+ if(servicePathIds == null) {
+ setGenerationAlgorithm(DEFAULT_GENERATION_ALGORITHM);
+ return GenerationAlgorithmEnum.forValue(DEFAULT_GENERATION_ALGORITHM);
+ }
+
+ GenerationAlgorithmEnum genAlgorithm = servicePathIds.getGenerationAlgorithm();
+
+ if(genAlgorithm == null) {
+ setGenerationAlgorithm(DEFAULT_GENERATION_ALGORITHM);
+ return GenerationAlgorithmEnum.forValue(DEFAULT_GENERATION_ALGORITHM);
+ } else {
+ return genAlgorithm;
+ }
+ }
+
+ /**
+ * Set the PathId Generate-algorithm in the data-store.
+ *
+ * <p>
+ * @param genAlgorithm integer value as taken from service-path-id.yang
+ * @return True if successful, otherwise false
+ */
+ public static boolean setGenerationAlgorithm(int genAlgorithm) {
+ return setGenerationAlgorithm(GenerationAlgorithmEnum.forValue(genAlgorithm));
+ }
+
+ /**
+ * Set the PathId Generate-algorithm in the data-store.
+ *
+ * <p>
+ * @param genAlgorithm enum string value as taken from service-path-id.yang
+ * @return True if successful, otherwise false
+ */
+ public static boolean setGenerationAlgorithm(GenerationAlgorithmEnum genAlgorithm) {
+ InstanceIdentifier<ServicePathIds> spIID
+ = InstanceIdentifier.builder(ServicePathIds.class).build();
+
+ ServicePathIdsBuilder servicePathIdsBuilder = new ServicePathIdsBuilder();
+ servicePathIdsBuilder.setGenerationAlgorithm(genAlgorithm);
+
+ return SfcDataStoreAPI.
+ writeMergeTransactionAPI(spIID, servicePathIdsBuilder.build(), LogicalDatastoreType.OPERATIONAL);
+ }
+
}
package org.opendaylight.sfc.provider.api;
import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.service.path.id.rev150804.GenerationAlgorithmEnum;
import java.util.Arrays;
import java.util.LinkedHashSet;
assertTrue(SfcServicePathId.check_suitable_pathid(pathId));
}
}
+
+ /**
+ *
+ * Method: setGenerationAlgorithm(), check_and_allocate_pathid()
+ *
+ */
+ @Test
+ public void testSequentialGenerationAlgorithm() throws Exception {
+ SfcServicePathId.setGenerationAlgorithm(GenerationAlgorithmEnum.Sequential);
+ long firstPathId = SfcServicePathId.check_and_allocate_pathid();
+ int numPathIds = 20;
+
+ // Verify the pathIds are created sequentially
+ for (long pathId = firstPathId+1; pathId < firstPathId+numPathIds; ++pathId) {
+ assertEquals(SfcServicePathId.check_and_allocate_pathid(), pathId);
+ }
+ // Free the previously allocated pathIds
+ for (long pathId = firstPathId; pathId < firstPathId+numPathIds+1; ++pathId) {
+ assertTrue(SfcServicePathId.free_pathid(pathId));
+ }
+ }
+
+ /**
+ *
+ * Method: setGenerationAlgorithm(), check_and_allocate_pathid(), check_and_allocate_symmetric_pathid()
+ *
+ */
+ @Test
+ public void testSequentialGenerationAlgorithmSymmetric() throws Exception {
+ SfcServicePathId.setGenerationAlgorithm(GenerationAlgorithmEnum.Sequential);
+ long firstPathId = SfcServicePathId.check_and_allocate_pathid();
+ int numPathIds = 40;
+
+ // Verify the pathIds are created sequentially both for the normal and the symmetric cases
+ for (long pathId = firstPathId+1; pathId < firstPathId+numPathIds; pathId+=2) {
+ long id = SfcServicePathId.check_and_allocate_pathid();
+ assertEquals(id, pathId);
+ assertEquals(SfcServicePathId.check_and_allocate_symmetric_pathid(id), pathId+1);
+ }
+ // Free the previously allocated pathIds
+ for (long pathId = firstPathId; pathId < firstPathId+numPathIds+1; ++pathId) {
+ assertTrue(SfcServicePathId.free_pathid(pathId));
+ }
+ }
+
}