changing structure
diff --git a/apps/fpcagent/BUCK b/apps/fpcagent/BUCK
index a3d15fb..4396a00 100644
--- a/apps/fpcagent/BUCK
+++ b/apps/fpcagent/BUCK
@@ -10,6 +10,7 @@
'//lib:javax.ws.rs-api',
'//utils/rest:onlab-rest',
'//core/store/serializers:onos-core-serializers',
+ '//apps/restconf/utils:onos-apps-restconf-utils',
':zeromq',
':json',
]
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcManager.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcManager.java
index 6b4e016..1896cc4 100644
--- a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcManager.java
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcManager.java
@@ -20,8 +20,6 @@
import com.google.common.collect.Maps;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.felix.scr.annotations.*;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
import org.onosproject.config.DynamicConfigService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
@@ -31,34 +29,30 @@
import org.onosproject.fpcagent.workers.ZMQSBSubscriberManager;
import org.onosproject.net.config.*;
import org.onosproject.net.config.basics.SubjectFactories;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.IetfDmmFpcagentOpParam;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.IetfDmmFpcagentService;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.DefaultTenants;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.ErrorTypeId;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.Result;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configure.DefaultConfigureInput;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configure.DefaultConfigureOutput;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configuredpn.DefaultConfigureDpnInput;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configuredpn.DefaultConfigureDpnOutput;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.instructions.instructions.instrtype.Instr3GppMob;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.opheader.OpTypeEnum;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.opinput.opbody.CreateOrUpdate;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.opinput.opbody.DeleteOrQuery;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.payload.Contexts;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.result.ResultEnum;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.resultbody.resulttype.DefaultCommonSuccess;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.resultbody.resulttype.DefaultErr;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.resultbodydpn.resulttype.DefaultEmptyCase;
import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.mobilityinfo.mobprofileparameters.ThreegppTunnel;
-import org.onosproject.yang.gen.v1.ietfdmmthreegpp.rev20160803.ietfdmmthreegpp.threegppinstr.Bits;
import org.onosproject.yang.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Optional;
-import static org.onosproject.fpcagent.helpers.Converter.getFpcIdentity;
+import static org.onosproject.fpcagent.FpcUtil.*;
/**
* Fpc Manager.
@@ -66,22 +60,21 @@
@Component(immediate = true)
@Service
public class FpcManager implements IetfDmmFpcagentService, FpcService {
- static final Logger log = LoggerFactory.getLogger(FpcManager.class);
+ private static final Logger log = LoggerFactory.getLogger(FpcManager.class);
- private static final String FPC_APP_ID = "org.onosproject.fpcagent";
private static final Class<FpcConfig> CONFIG_CLASS = FpcConfig.class;
private final InternalNetworkConfigListener configListener =
new InternalNetworkConfigListener();
/* Services */
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected TenantService tenantService;
+ private TenantService tenantService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- ModelConverter modelConverter;
+ private ModelConverter modelConverter;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- DynamicConfigService dynamicConfigService;
+ private DynamicConfigService dynamicConfigService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
private RpcRegistry rpcRegistry;
@@ -96,10 +89,7 @@
private CoreService coreService;
/* Variables */
- private ApplicationId appId;
private FpcConfig fpcConfig;
- private IetfDmmFpcagentOpParam fpcData;
-
private HashMap<String, ArrayList<Contexts>> sessionContextsMap = Maps.newHashMap();
private HashMap<String, String> nodeNetworkMap = Maps.newHashMap();
@@ -115,32 +105,12 @@
@Activate
protected void activate() {
- appId = coreService.registerApplication(FPC_APP_ID);
+ coreService.registerApplication(FPC_APP_ID);
configService.addListener(configListener);
registry.registerConfigFactory(fpcConfigConfigFactory);
- fpcData = new IetfDmmFpcagentOpParam();
-
rpcRegistry.registerRpcService(this);
- tenantService.addTenant(getFpcIdentity.apply("default"));
-
- DefaultTenants defaultTenants = new DefaultTenants();
- fpcData.tenants(defaultTenants);
- defaultTenants.addToTenant(tenantService.getTenant(getFpcIdentity.apply("default")).get());
-
- ResourceData dataNode = modelConverter.createDataNode(
- DefaultModelObjectData.builder()
- .addModelObject(defaultTenants)
- .build()
- );
-
-
- log.info("resourceData {} ", dataNode.dataNodes().size());
- dataNode.dataNodes().forEach(
- node -> dynamicConfigService.createNode(dataNode.resourceId(), node)
- );
-
log.info("FPC Agent Started");
}
@@ -188,34 +158,23 @@
@Override
public RpcOutput configureDpn(RpcInput rpcInput) {
- log.info("RPC configure {}", rpcInput);
-
- DefaultConfigureDpnOutput defaultConfigureDpnOutput = new DefaultConfigureDpnOutput();
- defaultConfigureDpnOutput.result(Result.of(ResultEnum.OK));
- defaultConfigureDpnOutput.resultType(new DefaultEmptyCase());
+ DefaultConfigureDpnOutput output = new DefaultConfigureDpnOutput();
+ output.result(Result.of(ResultEnum.OK));
+ output.resultType(new DefaultEmptyCase());
try {
- ResourceData data = DefaultResourceData.builder()
- .addDataNode(rpcInput.data())
- .resourceId(
- ResourceId.builder()
- .addBranchPointSchema("configureDpn", "urn:ietf:params:xml:ns:yang:fpcagent")
- .build())
- .build();
-
- ModelObjectData model = modelConverter.createModel(data);
- model.modelObjects().parallelStream().forEach(
+ tenantService.getModelObjects(rpcInput.data(), configureDpnResourceId).forEach(
modelObject -> {
DefaultConfigureDpnInput input = (DefaultConfigureDpnInput) modelObject;
String dpnId = input.inputDpnId().fpcIdentity().union().string();
switch (input.operation().enumeration()) {
case ADD:
log.info("Adding DPN {}", dpnId);
- nodeNetworkMap.put(dpnId, dpnId + "/" + dpnId);
+ // TODO
break;
case REMOVE:
log.info("Removing DPN {}", dpnId);
- nodeNetworkMap.remove(dpnId);
+ // TODO
break;
}
});
@@ -224,223 +183,107 @@
}
ResourceData dataNode = modelConverter.createDataNode(
- DefaultModelObjectData.builder().addModelObject(defaultConfigureDpnOutput).build()
+ DefaultModelObjectData.builder().addModelObject(output).build()
);
return new RpcOutput(RpcOutput.Status.RPC_SUCCESS, dataNode.dataNodes().get(0));
}
@Override
public RpcOutput configure(RpcInput rpcInput) {
- log.info("RPC configure {}", rpcInput);
-
DefaultConfigureOutput configureOutput = new DefaultConfigureOutput();
- configureOutput.result(Result.of(ResultEnum.OK));
- configureOutput.resultType(new DefaultCommonSuccess());
try {
- ResourceData data = DefaultResourceData.builder()
- .addDataNode(rpcInput.data())
- .resourceId(
- ResourceId.builder()
- .addBranchPointSchema("configure", "urn:ietf:params:xml:ns:yang:fpcagent")
- .build())
- .build();
-
- ModelObjectData model = modelConverter.createModel(data);
- model.modelObjects().parallelStream().forEach(
- modelObject -> {
- DefaultConfigureInput input = (DefaultConfigureInput) modelObject;
- configureOutput.opId(input.opId());
- switch (input.opType()) {
- case CREATE:
- case UPDATE:
- if (input.opBody() instanceof CreateOrUpdate) {
- log.info("Create Or Update");
- CreateOrUpdate createOrUpdate = (CreateOrUpdate) input.opBody();
- createOrUpdate.contexts().forEach(
- context -> {
- log.info("Context {}", context);
- String key = context.contextId().fpcIdentity().union().string();
- sessionContextsMap.computeIfAbsent(key, k -> new ArrayList<>()).add(context);
- context.dpns().forEach(
- dpn -> {
- if (context.instructions().instrType() instanceof Instr3GppMob) {
- log.info("3GPP Instructions");
- Instr3GppMob instr3GppMob = (Instr3GppMob) context.instructions().instrType();
- String commands = Bits.toString(instr3GppMob.instr3GppMob().bits());
-
- Ip4Address ulLocalAddress = Ip4Address.valueOf(context.ul().tunnelLocalAddress().toString()),
- dlRemoteAddress = Ip4Address.valueOf(context.dl().tunnelRemoteAddress().toString()),
- dlLocalAddress = Ip4Address.valueOf(context.dl().tunnelLocalAddress().toString());
-
- long s1u_sgw_gtpu_teid, s1u_enb_gtpu_teid,
- clientId = input.clientId().fpcIdentity().union().int64(),
- contextId = context.contextId().fpcIdentity().union().int64();
-
- BigInteger opId = input.opId().uint64(),
- imsi = context.imsi().uint64();
-
- short ebi = context.ebi().uint8(),
- lbi = context.lbi().uint8();
+ for (ModelObject modelObject : tenantService.getModelObjects(rpcInput.data(), configureResourceId)) {
+ DefaultConfigureInput input = (DefaultConfigureInput) modelObject;
+ switch (input.opType()) {
+ case CREATE:
+ case UPDATE:
+ if (input.opBody() instanceof CreateOrUpdate) {
+ CreateOrUpdate createOrUpdate = (CreateOrUpdate) input.opBody();
+ if (input.opType().equals(OpTypeEnum.CREATE)) {
+ configureOutput = tenantService.configureCreate(
+ createOrUpdate,
+ input.clientId(),
+ input.opId()
+ );
+ } else {
+ configureOutput = tenantService.configureUpdate(
+ createOrUpdate,
+ input.clientId(),
+ input.opId()
+ );
+ }
+ }
+ break;
+ case QUERY:
+ break;
+ case DELETE:
+ if (input.opBody() instanceof DeleteOrQuery) {
+ DeleteOrQuery deleteOrQuery = (DeleteOrQuery) input.opBody();
+ // TODO: move to tenant service
+ deleteOrQuery.targets().forEach(
+ target -> {
+ log.info("target {}", target);
+ String targetStr = target.target().union().string();
+ sessionContextsMap.getOrDefault(targetStr, Lists.newArrayList()).parallelStream().forEach(
+ context -> {
+ log.info("context {}", context);
+ context.dpns().forEach(
+ dpn -> {
+ log.info("DPN {}", dpn);
+ Long teid;
+ if (context.ul().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel) {
+ teid = ((ThreegppTunnel) context.ul().mobilityTunnelParameters().mobprofileParameters()).tunnelIdentifier();
+ } else {
+ return;
+ }
Short dpnTopic = DpnApi.getTopicFromNode(nodeNetworkMap.get(dpn.dpnId().fpcIdentity().union().string()));
- if (context.ul().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel) {
- s1u_sgw_gtpu_teid = ((ThreegppTunnel) context.ul().mobilityTunnelParameters().mobprofileParameters()).tunnelIdentifier();
+ if (targetStr.endsWith("ul") || targetStr.endsWith("dl")) {
+ log.info("DELETE Bearer");
+ DpnApi.delete_bearer(
+ dpnTopic,
+ teid
+ );
} else {
- return;
- }
- if (context.dl().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel) {
- s1u_enb_gtpu_teid = ((ThreegppTunnel) context.dl().mobilityTunnelParameters().mobprofileParameters()).tunnelIdentifier();
- } else {
- return;
- }
-
- if (input.opType().equals(OpTypeEnum.CREATE)) {
- if (commands.contains("session")) {
- log.info("CREATE session");
- DpnApi.create_session(
- dpnTopic,
- imsi,
- Ip4Prefix.valueOf(context.delegatingIpPrefixes().get(0).toString()).address(),
- ebi,
- ulLocalAddress,
- s1u_sgw_gtpu_teid,
- clientId,
- opId,
- contextId
- );
-
- if (commands.contains("downlink")) {
- log.info("CREATE session downlink");
- DpnApi.modify_bearer_dl(
- dpnTopic,
- s1u_sgw_gtpu_teid,
- dlRemoteAddress,
- s1u_enb_gtpu_teid,
- clientId,
- opId
- );
- }
- } else if (commands.contains("indirect-forward")) {
- // TODO - Modify API for Indirect Forwarding to/from another SGW
- } else if (commands.contains("uplink")) {
- log.info("CREATE uplink");
- DpnApi.create_bearer_ul(
- dpnTopic,
- imsi,
- lbi,
- ebi,
- ulLocalAddress,
- s1u_sgw_gtpu_teid
- );
- }
- } else {
- if (commands.contains("downlink")) {
- log.info("UPDATE downlink");
- if (context.dl().lifetime() >= 0L) {
- DpnApi.modify_bearer_dl(
- dpnTopic,
- dlRemoteAddress,
- s1u_enb_gtpu_teid,
- dlLocalAddress,
- clientId,
- opId,
- contextId
- );
- } else {
- DpnApi.delete_bearer(
- dpnTopic,
- s1u_enb_gtpu_teid
- );
- }
- }
- if (commands.contains("uplink")) {
- log.info("UPDATE uplink");
- if (context.ul().lifetime() >= 0L) {
- DpnApi.modify_bearer_ul(
- dpnTopic,
- ulLocalAddress,
- s1u_enb_gtpu_teid,
- s1u_sgw_gtpu_teid
- );
- } else {
- DpnApi.delete_bearer(
- dpnTopic,
- s1u_sgw_gtpu_teid
- );
- }
- }
+ log.info("DELETE session");
+ DpnApi.delete_session(
+ dpnTopic,
+ context.lbi().uint8(),
+ teid,
+ input.clientId().fpcIdentity().union().int64(),
+ input.opId().uint64(),
+ context.contextId().fpcIdentity().union().int64()
+ );
}
}
- }
- );
- }
- );
- }
- break;
- case QUERY:
- break;
- case DELETE:
- if (input.opBody() instanceof DeleteOrQuery) {
- DeleteOrQuery deleteOrQuery = (DeleteOrQuery) input.opBody();
- log.info("Delete Or Query");
-
- deleteOrQuery.targets().forEach(
- target -> {
- log.info("target {}", target);
- String targetStr = target.target().union().string();
- sessionContextsMap.getOrDefault(targetStr, Lists.newArrayList()).parallelStream().forEach(
- context -> {
- log.info("context {}", context);
- context.dpns().forEach(
- dpn -> {
- log.info("DPN {}", dpn);
- Long teid;
- if (context.ul().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel) {
- teid = ((ThreegppTunnel) context.ul().mobilityTunnelParameters().mobprofileParameters()).tunnelIdentifier();
- } else {
- return;
- }
-
- Short dpnTopic = DpnApi.getTopicFromNode(nodeNetworkMap.get(dpn.dpnId().fpcIdentity().union().string()));
-
- if (targetStr.endsWith("ul") || targetStr.endsWith("dl")) {
- log.info("DELETE Bearer");
- DpnApi.delete_bearer(
- dpnTopic,
- teid
- );
- } else {
- log.info("DELETE session");
- DpnApi.delete_session(
- dpnTopic,
- context.lbi().uint8(),
- teid,
- input.clientId().fpcIdentity().union().int64(),
- input.opId().uint64(),
- context.contextId().fpcIdentity().union().int64()
- );
- }
- }
- );
- }
- );
- }
- );
- }
- break;
+ );
+ }
+ );
+ }
+ );
}
- }
- );
-
-
+ break;
+ }
+ configureOutput.opId(input.opId());
+ }
} catch (Exception e) {
+ DefaultErr defaultErr = new DefaultErr();
+ defaultErr.errorInfo(ExceptionUtils.getFullStackTrace(e));
+ defaultErr.errorTypeId(ErrorTypeId.of(0));
+ configureOutput.resultType(defaultErr);
+ configureOutput.result(Result.of(ResultEnum.ERR));
+
log.error(ExceptionUtils.getFullStackTrace(e));
+ } finally {
+ tenantService.getTenants().ifPresent(tenants -> tenantService.updateNode(tenants));
}
ResourceData dataNode = modelConverter.createDataNode(
- DefaultModelObjectData.builder().addModelObject(configureOutput).build()
+ DefaultModelObjectData.builder()
+ .addModelObject(configureOutput)
+ .build()
);
return new RpcOutput(RpcOutput.Status.RPC_SUCCESS, dataNode.dataNodes().get(0));
}
@@ -465,16 +308,6 @@
return null;
}
-// @Override
-// public void registerClient(RegisterClientInput input) {
-// tenantService.registerClient(input.clientId(), input.tenantId());
-// }
-//
-// @Override
-// public void deregisterClient(DeregisterClientInput input) {
-// tenantService.deregisterClient(input.clientId());
-// }
-
private class InternalNetworkConfigListener implements NetworkConfigListener {
@Override
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcUtil.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcUtil.java
new file mode 100644
index 0000000..c3a6a77
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcUtil.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.fpcagent;
+
+import org.onosproject.restconf.utils.RestconfUtils;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.DefaultResourceData;
+import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.model.ResourceId;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+/**
+ * Helper class which stores all the static variables.
+ */
+class FpcUtil {
+ static final int MAX_EVENTS = 1000;
+ static final int MAX_BATCH_MS = 5000;
+ static final int MAX_IDLE_MS = 1000;
+ static final String TIMER = "dynamic-config-fpcagent-timer";
+ static final String UNKNOWN_EVENT = "FPC Agent listener: unknown event: {}";
+ static final String EVENT_NULL = "Event cannot be null";
+ static final String FPC_APP_ID = "org.onosproject.fpcagent";
+
+ // Resource ID for Configure DPN RPC command
+ static ResourceId configureDpnResourceId;
+ // Resource ID for Configure RPC command
+ static ResourceId configureResourceId;
+ // Resource ID for tenants data
+ static ResourceId tenantsResourceId;
+ static ResourceId registerClientResourceId;
+ static ResourceId deregisterClientResourceId;
+
+ static {
+ try {
+ configureDpnResourceId = RestconfUtils.convertUriToRid(
+ new URI("/onos/restconf/operations/ietf-dmm-fpcagent:configure-dpn")
+ );
+ configureResourceId = RestconfUtils.convertUriToRid(
+ new URI("/onos/restconf/operations/ietf-dmm-fpcagent:configure")
+ );
+ tenantsResourceId = RestconfUtils.convertUriToRid(
+ new URI("/onos/restconf/data/ietf-dmm-fpcagent:tenants")
+ );
+ registerClientResourceId = RestconfUtils.convertUriToRid(
+ new URI("/onos/restconf/data/fpc:register-client")
+ );
+ deregisterClientResourceId = RestconfUtils.convertUriToRid(
+ new URI("/onos/restconf/data/fpc:deregister-client")
+ );
+ } catch (URISyntaxException ignored) {
+ }
+ }
+
+ /**
+ * Returns the resource data from the data node and the resource id.
+ *
+ * @param dataNode data node
+ * @param resId resource id
+ * @return resource data
+ */
+ static ResourceData getResourceData(DataNode dataNode, ResourceId resId) {
+ if (resId != null) {
+ return DefaultResourceData.builder()
+ .addDataNode(dataNode)
+ .resourceId(resId)
+ .build();
+ } else {
+ return DefaultResourceData.builder()
+ .addDataNode(dataNode)
+ .build();
+ }
+ }
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantManager.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantManager.java
index e51efed..f197bdb 100644
--- a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantManager.java
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantManager.java
@@ -1,28 +1,49 @@
package org.onosproject.fpcagent;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Service;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.ClientIdentifier;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.felix.scr.annotations.*;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.util.AbstractAccumulator;
+import org.onlab.util.Accumulator;
+import org.onosproject.config.DynamicConfigEvent;
+import org.onosproject.config.DynamicConfigListener;
+import org.onosproject.config.DynamicConfigService;
+import org.onosproject.config.Filter;
+import org.onosproject.fpcagent.helpers.DpnApi;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.IetfDmmFpcagentOpParam;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.*;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configure.DefaultConfigureOutput;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.instructions.instructions.instrtype.Instr3GppMob;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.opinput.opbody.CreateOrUpdate;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.payload.Contexts;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.result.ResultEnum;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.resultbody.resulttype.DefaultCommonSuccess;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.resultbody.resulttype.DefaultErr;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.DefaultTenant;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.Tenant;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.tenant.DefaultFpcMobility;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.tenant.DefaultFpcPolicy;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.tenant.DefaultFpcTopology;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.tenant.FpcTopology;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.tenant.fpctopology.Dpns;
-import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.FpcDpnId;
import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.FpcIdentity;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.fpccontext.Dpns;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.mobilityinfo.mobprofileparameters.ThreegppTunnel;
+import org.onosproject.yang.gen.v1.ietfdmmthreegpp.rev20160803.ietfdmmthreegpp.threegppinstr.Bits;
+import org.onosproject.yang.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
+import java.math.BigInteger;
+import java.util.*;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.fpcagent.FpcUtil.*;
+import static org.onosproject.fpcagent.helpers.Converter.convertContext;
import static org.onosproject.fpcagent.helpers.Converter.getFpcIdentity;
@Component(immediate = true)
@@ -30,34 +51,74 @@
public class TenantManager implements TenantService {
private final Logger log = LoggerFactory.getLogger(getClass());
- private Map<FpcIdentity, Tenant> tenantMap = Maps.newHashMap();
- private Map<ClientIdentifier, Tenant> clientIdMap = Maps.newHashMap();
+ private final IetfDmmFpcagentOpParam fpcAgentData = new IetfDmmFpcagentOpParam();
- private Map<FpcDpnId, List<FpcDpnId>> vdpnDpnsMap = Maps.newConcurrentMap();
- private Map<FpcDpnId, Contexts> vdpnContextsMap = Maps.newConcurrentMap();
+ private final Map<ClientIdentifier, Tenant> clientIdMap = Maps.newHashMap();
+
+ private final InternalConfigListener listener = new InternalConfigListener();
+
+ private final Accumulator<DynamicConfigEvent> accumulator = new InternalEventAccumulator();
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ private ModelConverter modelConverter;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ private DynamicConfigService dynamicConfigService;
@Activate
protected void activate() {
+ dynamicConfigService.addListener(listener);
+
+ // Create the Default Tenant on activate
+ DefaultTenants tenants = new DefaultTenants();
+
+ DefaultTenant tenant = new DefaultTenant();
+ tenant.tenantId(getFpcIdentity.apply("default"));
+
+ tenant.fpcTopology(new DefaultFpcTopology());
+
+ tenant.fpcPolicy(new DefaultFpcPolicy());
+
+ tenant.fpcMobility(new DefaultFpcMobility());
+
+ tenants.addToTenant(tenant);
+
+ DefaultFpcAgentInfo fpcAgentInfo = new DefaultFpcAgentInfo();
+
+ fpcAgentData.tenants(tenants);
+ fpcAgentData.fpcAgentInfo(fpcAgentInfo);
+
+ createNode(tenants);
+ createNode(fpcAgentInfo);
+
log.info("Tenant Service Started");
}
@Deactivate
protected void deactivate() {
+ dynamicConfigService.removeListener(listener);
log.info("Tenant Service Stopped");
}
- public void addTenant(FpcIdentity tenantId) {
- Tenant tenant = new DefaultTenant();
- tenant.tenantId(tenantId);
- tenant.fpcTopology(new DefaultFpcTopology());
- tenant.fpcMobility(new DefaultFpcMobility());
- tenant.fpcPolicy(new DefaultFpcPolicy());
+ @Override
+ public Optional<Tenant> getDefaultTenant() {
+ return fpcAgentData.tenants().tenant().stream()
+ .filter(tenant -> tenant.tenantId().equals(getFpcIdentity.apply("default")))
+ .findFirst();
+ }
- tenantMap.put(tenantId, tenant);
+ @Override
+ public Optional<DefaultTenants> getTenants() {
+ if (fpcAgentData.tenants() instanceof DefaultTenants) {
+ return Optional.ofNullable((DefaultTenants) fpcAgentData.tenants());
+ }
+ return Optional.empty();
}
public Optional<Tenant> getTenant(FpcIdentity tenantId) {
- return Optional.ofNullable(tenantMap.get(tenantId));
+ return fpcAgentData.tenants().tenant().stream()
+ .filter(tenant -> tenant.tenantId().equals(tenantId))
+ .findFirst();
}
public Optional<Tenant> getTenant(ClientIdentifier clientId) {
@@ -68,33 +129,380 @@
return getTenant(tenantId).map(tenant -> clientIdMap.put(clientId, tenant));
}
- public Tenant deregisterClient(ClientIdentifier clientId) {
- return clientIdMap.remove(clientId);
+ public Optional<Tenant> deregisterClient(ClientIdentifier clientId) {
+ return Optional.ofNullable(clientIdMap.remove(clientId));
}
- private boolean dpnIdExists(FpcIdentity tenantId, FpcDpnId fpcDpnId) {
- return getTenant(tenantId).map(
- tenant -> {
- FpcTopology fpcTopology = tenant.fpcTopology();
- return fpcTopology.dpns() != null &&
- fpcTopology.dpns().stream().anyMatch(dpn -> dpn.dpnId().equals(fpcDpnId));
+ private ResourceData getResourceData(DataNode dataNode, ResourceId resId) {
+ if (resId != null) {
+ return DefaultResourceData.builder()
+ .addDataNode(dataNode)
+ .resourceId(resId)
+ .build();
+ } else {
+ return DefaultResourceData.builder()
+ .addDataNode(dataNode)
+ .build();
+ }
+ }
+
+ public List<ModelObject> getModelObjects(DataNode dataNode, ResourceId resourceId) {
+ ResourceData data = getResourceData(dataNode, resourceId);
+ ModelObjectData modelData = modelConverter.createModel(data);
+ return modelData.modelObjects();
+ }
+
+ public void createNode(InnerModelObject innerModelObject) {
+ ResourceData dataNode = modelConverter.createDataNode(
+ DefaultModelObjectData.builder()
+ .addModelObject(innerModelObject)
+ .build()
+ );
+ dataNode.dataNodes().forEach(
+ node -> dynamicConfigService.createNode(dataNode.resourceId(), node)
+ );
+ }
+
+ public void updateNode(InnerModelObject innerModelObject) {
+ ResourceData dataNode = modelConverter.createDataNode(
+ DefaultModelObjectData.builder()
+ .addModelObject(innerModelObject)
+ .build()
+ );
+ dataNode.dataNodes().forEach(
+ node -> dynamicConfigService.updateNode(dataNode.resourceId(), node)
+ );
+ }
+
+ public DefaultConfigureOutput configureCreate(
+ CreateOrUpdate create,
+ ClientIdentifier clientId,
+ OpIdentifier operationId
+ ) {
+ DefaultConfigureOutput configureOutput = new DefaultConfigureOutput();
+ Collection<Callable<Object>> tasks = new ArrayList<>();
+
+ try {
+ DefaultCommonSuccess defaultCommonSuccess = new DefaultCommonSuccess();
+ for (Contexts context : create.contexts()) {
+ defaultCommonSuccess.addToContexts(context);
+
+ if (getDefaultTenant().map(
+ tenant -> tenant.fpcMobility().contexts() != null && tenant.fpcMobility()
+ .contexts()
+ .stream()
+ .anyMatch(contexts -> contexts.contextId().equals(context.contextId()))
+ ).orElse(false)) {
+ throw new IllegalStateException("Context already exists.");
}
- ).orElse(false);
- }
- private Optional<FpcDpnId> getDpnId(String nodeId, String networkId) {
- return getTenant(getFpcIdentity.apply("default")).map(
- tenant -> {
- FpcTopology fpcTopology = tenant.fpcTopology();
- if (fpcTopology.dpns() != null) {
- return fpcTopology.dpns().stream()
- .filter(dpn -> dpn.nodeId().equals(nodeId))
- .filter(dpn -> dpn.networkId().equals(networkId))
- .findFirst()
- .map(Dpns::dpnId);
+ for (Dpns dpn : context.dpns()) {
+ if (!getDefaultTenant().map(
+ tenant -> tenant.fpcTopology().dpns() != null &&
+ tenant.fpcTopology().dpns().stream()
+ .anyMatch(dpns -> dpns.dpnId().equals(dpn.dpnId()))
+ ).orElse(false)) {
+ throw new IllegalStateException("DPN ID is not registered to the topology.");
}
- return Optional.<FpcDpnId>empty();
+
+ if (context.instructions().instrType() instanceof Instr3GppMob) {
+ Instr3GppMob instr3GppMob = (Instr3GppMob) context.instructions().instrType();
+ String commands = Bits.toString(instr3GppMob.instr3GppMob().bits());
+
+ Ip4Address ulLocalAddress = Ip4Address.valueOf(context.ul().tunnelLocalAddress().toString()),
+ dlRemoteAddress = Ip4Address.valueOf(context.dl().tunnelRemoteAddress().toString());
+
+ long s1u_sgw_gtpu_teid, s1u_enb_gtpu_teid,
+ cId = clientId.fpcIdentity().union().int64(),
+ contextId = context.contextId().fpcIdentity().union().int64();
+
+ BigInteger opId = operationId.uint64(),
+ imsi = context.imsi().uint64();
+
+ short ebi = context.ebi().uint8(),
+ lbi = context.lbi().uint8();
+
+ Short dpnTopic = DpnApi.getTopicFromNode(dpn.dpnId().toString());
+
+ if (context.ul().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel) {
+ s1u_sgw_gtpu_teid = ((ThreegppTunnel) context.ul().mobilityTunnelParameters().mobprofileParameters()).tunnelIdentifier();
+ } else {
+ throw new IllegalArgumentException("mobprofileParameters are not instance of ThreegppTunnel");
+ }
+ if (context.dl().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel) {
+ s1u_enb_gtpu_teid = ((ThreegppTunnel) context.dl().mobilityTunnelParameters().mobprofileParameters()).tunnelIdentifier();
+ } else {
+ throw new IllegalArgumentException("mobprofileParameters are not instance of ThreegppTunnel");
+ }
+
+
+ if (commands.contains("session")) {
+ tasks.add(Executors.callable(() -> DpnApi.create_session(
+ dpnTopic,
+ imsi,
+ Ip4Prefix.valueOf(context.delegatingIpPrefixes().get(0).toString()).address(),
+ ebi,
+ ulLocalAddress,
+ s1u_sgw_gtpu_teid,
+ cId,
+ opId,
+ contextId
+ )));
+
+ if (commands.contains("downlink")) {
+ tasks.add(Executors.callable(() -> DpnApi.modify_bearer_dl(
+ dpnTopic,
+ s1u_sgw_gtpu_teid,
+ dlRemoteAddress,
+ s1u_enb_gtpu_teid,
+ cId,
+ opId
+ )));
+ }
+ } else if (commands.contains("indirect-forward")) {
+ // TODO - Modify API for Indirect Forwarding to/from another SGW
+ } else if (commands.contains("uplink")) {
+ tasks.add(Executors.callable(() -> DpnApi.create_bearer_ul(
+ dpnTopic,
+ imsi,
+ lbi,
+ ebi,
+ ulLocalAddress,
+ s1u_sgw_gtpu_teid
+ )));
+ }
+ }
}
- ).orElse(Optional.empty());
+ }
+
+ ExecutorService executor = Executors.newWorkStealingPool();
+ executor.invokeAll(tasks).forEach(
+ future -> {
+ try {
+ future.get();
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ );
+
+ configureOutput.resultType(defaultCommonSuccess);
+ configureOutput.result(Result.of(ResultEnum.OK));
+
+ create.contexts().forEach(
+ contexts -> getDefaultTenant().ifPresent(
+ tenant -> tenant.fpcMobility().addToContexts(convertContext(contexts))
+ )
+ );
+ } catch (Exception e) {
+ DefaultErr defaultErr = new DefaultErr();
+ configureOutput.resultType(defaultErr);
+ defaultErr.errorInfo(ExceptionUtils.getFullStackTrace(e));
+ defaultErr.errorTypeId(ErrorTypeId.of(0));
+ }
+
+ return configureOutput;
+ }
+
+ public DefaultConfigureOutput configureUpdate(
+ CreateOrUpdate update,
+ ClientIdentifier clientId,
+ OpIdentifier operationId
+ ) {
+ DefaultConfigureOutput configureOutput = new DefaultConfigureOutput();
+ Collection<Callable<Object>> tasks = new ArrayList<>();
+
+ try {
+ DefaultCommonSuccess defaultCommonSuccess = new DefaultCommonSuccess();
+ for (Contexts context : update.contexts()) {
+ defaultCommonSuccess.addToContexts(context);
+
+ if (getDefaultTenant().map(
+ tenant -> tenant.fpcMobility()
+ .contexts()
+ .parallelStream()
+ .anyMatch(contexts -> contexts.contextId().equals(context.contextId()))
+ ).orElse(false)) {
+ throw new IllegalStateException("Context already exists.");
+ }
+
+ for (Dpns dpn : context.dpns()) {
+ if (!getDefaultTenant().map(
+ tenant -> tenant.fpcTopology().dpns()
+ .stream()
+ .anyMatch(dpns -> dpns.dpnId().equals(dpn.dpnId()))
+ ).orElse(false)) {
+ throw new IllegalStateException("DPN ID is not registered to the topology.");
+ }
+
+ if (context.instructions().instrType() instanceof Instr3GppMob) {
+ Instr3GppMob instr3GppMob = (Instr3GppMob) context.instructions().instrType();
+ String commands = Bits.toString(instr3GppMob.instr3GppMob().bits());
+
+ Ip4Address ulLocalAddress = Ip4Address.valueOf(context.ul().tunnelLocalAddress().toString()),
+ dlRemoteAddress = Ip4Address.valueOf(context.dl().tunnelRemoteAddress().toString()),
+ dlLocalAddress = Ip4Address.valueOf(context.dl().tunnelLocalAddress().toString());
+
+ long s1u_sgw_gtpu_teid, s1u_enb_gtpu_teid,
+ cId = clientId.fpcIdentity().union().int64(),
+ contextId = context.contextId().fpcIdentity().union().int64();
+
+ BigInteger opId = operationId.uint64();
+
+
+ Short dpnTopic = DpnApi.getTopicFromNode(dpn.dpnId().toString());
+
+ if (context.ul().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel) {
+ s1u_sgw_gtpu_teid = ((ThreegppTunnel) context.ul().mobilityTunnelParameters().mobprofileParameters()).tunnelIdentifier();
+ } else {
+ throw new IllegalArgumentException("mobprofileParameters are not instance of ThreegppTunnel");
+ }
+ if (context.dl().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel) {
+ s1u_enb_gtpu_teid = ((ThreegppTunnel) context.dl().mobilityTunnelParameters().mobprofileParameters()).tunnelIdentifier();
+ } else {
+ throw new IllegalArgumentException("mobprofileParameters are not instance of ThreegppTunnel");
+ }
+
+
+ if (commands.contains("downlink")) {
+ if (context.dl().lifetime() >= 0L) {
+ tasks.add(Executors.callable(() ->
+ DpnApi.modify_bearer_dl(
+ dpnTopic,
+ dlRemoteAddress,
+ s1u_enb_gtpu_teid,
+ dlLocalAddress,
+ cId,
+ opId,
+ contextId
+ )
+ ));
+ } else {
+ tasks.add(Executors.callable(() ->
+ DpnApi.delete_bearer(
+ dpnTopic,
+ s1u_enb_gtpu_teid
+ )
+ ));
+ }
+ }
+ if (commands.contains("uplink")) {
+ if (context.ul().lifetime() >= 0L) {
+ tasks.add(Executors.callable(() ->
+ DpnApi.modify_bearer_ul(
+ dpnTopic,
+ ulLocalAddress,
+ s1u_enb_gtpu_teid,
+ s1u_sgw_gtpu_teid
+ )
+ ));
+ } else {
+ tasks.add(Executors.callable(() ->
+ DpnApi.delete_bearer(
+ dpnTopic,
+ s1u_sgw_gtpu_teid
+ )
+ ));
+ }
+ }
+ }
+ }
+ }
+
+ ExecutorService executor = Executors.newWorkStealingPool();
+ executor.invokeAll(tasks).forEach(
+ future -> {
+ try {
+ future.get();
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ );
+
+ configureOutput.resultType(defaultCommonSuccess);
+ configureOutput.result(Result.of(ResultEnum.OK));
+
+ update.contexts().forEach(
+ contexts -> getDefaultTenant().ifPresent(
+ tenant -> tenant.fpcMobility().addToContexts(convertContext(contexts))
+ )
+ );
+ } catch (Exception e) {
+ DefaultErr defaultErr = new DefaultErr();
+ defaultErr.errorInfo(ExceptionUtils.getFullStackTrace(e));
+ defaultErr.errorTypeId(ErrorTypeId.of(0));
+ configureOutput.resultType(defaultErr);
+ configureOutput.result(Result.of(ResultEnum.ERR));
+ }
+
+ return configureOutput;
+ }
+
+ /**
+ * Accumulates events to allow processing after a desired number of
+ * events were accumulated.
+ */
+ private class InternalEventAccumulator extends AbstractAccumulator<DynamicConfigEvent> {
+
+ /**
+ * Constructs the event accumulator with timer and event limit.
+ */
+ private InternalEventAccumulator() {
+ super(new Timer(TIMER), MAX_EVENTS, MAX_BATCH_MS, MAX_IDLE_MS);
+ }
+
+ @Override
+ public void processItems(List<DynamicConfigEvent> events) {
+ DynamicConfigEvent event = Iterables.getLast(events);
+ log.debug("processItems {}", event);
+ checkNotNull(event, EVENT_NULL);
+ switch (event.type()) {
+ case NODE_ADDED:
+ case NODE_DELETED:
+ Filter filter = Filter.builder().build();
+ DataNode node = dynamicConfigService.readNode(tenantsResourceId, filter);
+ getModelObjects(node, null).forEach(
+ modelObject -> fpcAgentData.tenants((DefaultTenants) modelObject)
+ );
+ break;
+ case NODE_UPDATED:
+ case NODE_REPLACED:
+ break;
+ default:
+ log.warn(UNKNOWN_EVENT, event.type());
+ break;
+ }
+ }
+
+ }
+
+ /**
+ * Representation of internal listener, listening for dynamic config event.
+ */
+ private class InternalConfigListener implements DynamicConfigListener {
+ /**
+ * Returns true if the event resource id points to the root level node
+ * only and event is for addition and deletion; false otherwise.
+ *
+ * @param event config event
+ * @return true if event is supported; false otherwise
+ */
+ private boolean isSupported(DynamicConfigEvent event) {
+ ResourceId rsId = event.subject();
+ List<NodeKey> storeKeys = rsId.nodeKeys();
+ List<NodeKey> tenantKeys = tenantsResourceId.nodeKeys();
+ return storeKeys.size() >= 2 && storeKeys.get(0).equals(tenantKeys.get(1));
+ }
+
+ @Override
+ public boolean isRelevant(DynamicConfigEvent event) {
+ return isSupported(event);
+ }
+
+ @Override
+ public void event(DynamicConfigEvent event) {
+ accumulator.add(event);
+ }
}
}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantService.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantService.java
index f0f11a5..60118ff 100644
--- a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantService.java
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantService.java
@@ -1,13 +1,32 @@
package org.onosproject.fpcagent;
+import com.google.common.annotations.Beta;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.ClientIdentifier;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.DefaultTenants;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.OpIdentifier;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configure.DefaultConfigureOutput;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.opinput.opbody.CreateOrUpdate;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.Tenant;
import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.FpcIdentity;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.InnerModelObject;
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.ResourceId;
+import java.util.List;
import java.util.Optional;
+@Beta
public interface TenantService {
- void addTenant(FpcIdentity tenantId);
+ Optional<DefaultTenants> getTenants();
+
+ void createNode(InnerModelObject innerModelObject);
+
+ void updateNode(InnerModelObject innerModelObject);
+
+ List<ModelObject> getModelObjects(DataNode dataNode, ResourceId appId);
+
+ Optional<Tenant> getDefaultTenant();
Optional<Tenant> getTenant(FpcIdentity tenantId);
@@ -15,5 +34,17 @@
Optional<Tenant> registerClient(ClientIdentifier clientId, FpcIdentity tenantId);
- Tenant deregisterClient(ClientIdentifier clientId);
+ Optional<Tenant> deregisterClient(ClientIdentifier clientId);
+
+ DefaultConfigureOutput configureCreate(
+ CreateOrUpdate create,
+ ClientIdentifier clientId,
+ OpIdentifier operationId
+ );
+
+ DefaultConfigureOutput configureUpdate(
+ CreateOrUpdate create,
+ ClientIdentifier clientId,
+ OpIdentifier operationId
+ );
}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/helpers/Converter.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/helpers/Converter.java
index 6573ae8..d023cb8 100644
--- a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/helpers/Converter.java
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/helpers/Converter.java
@@ -1,11 +1,23 @@
package org.onosproject.fpcagent.helpers;
import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.ClientIdentifier;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.tenant.fpcmobility.Contexts;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.tenant.fpcmobility.DefaultContexts;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.FpcContextId;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.FpcDpnGroupId;
import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.FpcIdentity;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.FpcPortId;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.fpccontext.Dl;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.fpccontext.Dpns;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.fpccontext.Ul;
import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.fpcidentity.FpcIdentityUnion;
+import org.onosproject.yang.gen.v1.ietfdmmthreegpp.rev20160803.ietfdmmthreegpp.EbiType;
+import org.onosproject.yang.gen.v1.ietfdmmthreegpp.rev20160803.ietfdmmthreegpp.ImsiType;
+import org.onosproject.yang.gen.v1.ietfinettypes.rev20130715.ietfinettypes.IpPrefix;
import java.math.BigInteger;
import java.util.Arrays;
+import java.util.List;
import java.util.function.Function;
public class Converter {
@@ -101,4 +113,55 @@
public static Function<String, FpcIdentity> getFpcIdentity = (v) -> new FpcIdentity(new FpcIdentityUnion(v));
public static Function<String, ClientIdentifier> getClientIdentity = (v) -> new ClientIdentifier(getFpcIdentity.apply(v));
+ public static Contexts convertContext(org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.payload.Contexts contexts) {
+ Contexts ctx = new DefaultContexts();
+ FpcContextId fpcContextId = contexts.contextId();
+ List<IpPrefix> ipPrefixes = contexts.delegatingIpPrefixes();
+ Dl dl = contexts.dl();
+ Ul ul = contexts.ul();
+ boolean dormant = contexts.dormant();
+ FpcDpnGroupId fpcDpnGroupId = contexts.dpnGroup();
+ List<Dpns> dpns = contexts.dpns();
+ EbiType ebi = contexts.ebi();
+ EbiType lbi = contexts.lbi();
+ ImsiType imsi = contexts.imsi();
+ FpcContextId fpcContextId1 = contexts.parentContext();
+ List<FpcPortId> ports = contexts.ports();
+
+ if (fpcContextId != null) {
+ ctx.contextId(fpcContextId);
+ }
+ if (ipPrefixes != null) {
+ ctx.delegatingIpPrefixes(ipPrefixes);
+ }
+ if (dl != null) {
+ ctx.dl(dl);
+ }
+ if (ul != null) {
+ ctx.ul(ul);
+ }
+ ctx.dormant(dormant);
+ if (fpcDpnGroupId != null) {
+ ctx.dpnGroup(fpcDpnGroupId);
+ }
+ if (dpns != null) {
+ ctx.dpns(dpns);
+ }
+ if (ebi != null) {
+ ctx.ebi(ebi);
+ }
+ if (lbi != null) {
+ ctx.lbi(lbi);
+ }
+ if (imsi != null) {
+ ctx.imsi(imsi);
+ }
+ if (fpcContextId1 != null) {
+ ctx.parentContext(fpcContextId1);
+ }
+ if (ports != null) {
+ ctx.ports(ports);
+ }
+ return ctx;
+ }
}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/helpers/DpnApi.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/helpers/DpnApi.java
index 4ea7b39..43d4759 100644
--- a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/helpers/DpnApi.java
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/helpers/DpnApi.java
@@ -29,6 +29,8 @@
*/
public class DpnApi {
protected static final Logger log = LoggerFactory.getLogger(DpnApi.class);
+ private static final Map<String, FpcDpnId> uplinkDpnMap;
+ private static final Map<String, Short> topicToNodeMap;
/**
* Topic for broadcasting
*/
@@ -44,7 +46,6 @@
private static byte BYE = 0b0000_1001;
private static byte SEND_ADC_TYPE = 0b001_0001;
private static byte DDN_ACK = 0b0000_0110;
-
private static byte DPN_HELLO = 0b0000_0001;
private static byte DPN_BYE = 0b0000_0010;
private static byte DOWNLINK_DATA_NOTIFICATION = 0b0000_0101;
@@ -52,8 +53,6 @@
private static byte DPN_OVERLOAD_INDICATION = 0b0000_0101;
private static byte DPN_REPLY = 0b0000_0100;
private static String DOWNLINK_DATA_NOTIFICATION_STRING = "Downlink-Data-Notification";
- private static final Map<String, FpcDpnId> uplinkDpnMap;
- private static final Map<String, Short> topicToNodeMap;
static {
uplinkDpnMap = Maps.newConcurrentMap();
@@ -312,9 +311,9 @@
* @param sponsor_ID - Sponsor ID
*/
public static void send_ADC_rules(Short topic,
- String domain_name, String ip,
- Short drop, Long rating_group,
- Long service_ID, String sponsor_ID) {
+ String domain_name, String ip,
+ Short drop, Long rating_group,
+ Long service_ID, String sponsor_ID) {
Ip4Prefix ip_prefix = null;
if (ip != null) {
ip_prefix = Ip4Prefix.valueOf(ip);
@@ -409,9 +408,11 @@
status = DPNStatusIndication.Status.OVERLOAD_INDICATION;
} else if (buf[3] == DPN_HELLO) {
status = DPNStatusIndication.Status.HELLO;
+ log.info("Hello {} on topic {}", key, buf[2]);
topicToNodeMap.put(key, (short) buf[2]);
} else if (buf[3] == DPN_BYE) {
status = DPNStatusIndication.Status.BYE;
+ log.info("Bye {}", key);
topicToNodeMap.remove(key);
}
return new AbstractMap.SimpleEntry<>(uplinkDpnMap.get(key), new DPNStatusIndication(status, key));
@@ -441,6 +442,7 @@
* Node Reference of the DPN
*/
public Short nodeRef;
+
/**
* Constructor providing the DPN and its associated Status.
*
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/NBWorkManager.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/NBWorkManager.java
deleted file mode 100644
index d79cf69..0000000
--- a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/NBWorkManager.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.onosproject.fpcagent.workers;
-
-import org.apache.commons.lang.exception.ExceptionUtils;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configure.ConfigureInput;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configurebundles.ConfigureBundlesInput;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.eventderegister.EventDeregisterInput;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.eventregister.EventRegisterInput;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.probe.ProbeInput;
-import org.onosproject.yang.model.RpcInput;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.LinkedBlockingQueue;
-
-public class NBWorkManager implements AutoCloseable {
- private static final Logger log = LoggerFactory.getLogger(NBWorkManager.class);
-
- // TODO: add store
- private static NBWorkManager _instance = null;
- private final BlockingQueue<Object> blockingQueue;
- private final int poolSize;
- private boolean run;
-
- protected NBWorkManager(int poolSize) {
- this.blockingQueue = new LinkedBlockingQueue<>();
- this.poolSize = poolSize;
- this.run = true;
- }
-
- public static NBWorkManager createInstance(int poolSize) {
- if (_instance == null) {
- _instance = new NBWorkManager(poolSize);
- }
- return _instance;
- }
-
- public static NBWorkManager getInstance() {
- return _instance;
- }
-
- public void submit(RpcInput input) {
- try {
- blockingQueue.put(input);
- } catch (InterruptedException e) {
- log.error(ExceptionUtils.getFullStackTrace(e));
- }
- }
-
- public void open() {
- ExecutorService executorService = Executors.newFixedThreadPool(this.poolSize);
- executorService.submit(() -> {
- while ((!Thread.currentThread().isInterrupted()) && run) {
- try {
- Object o = blockingQueue.take();
- if (o instanceof ConfigureInput) {
-
- } else if (o instanceof ConfigureBundlesInput) {
-
- } else if (o instanceof EventRegisterInput) {
-
- } else if (o instanceof EventDeregisterInput) {
-
- } else if (o instanceof ProbeInput) {
-
- }
- } catch (InterruptedException e) {
- log.error(ExceptionUtils.getFullStackTrace(e));
- }
- }
- });
- }
-
- @Override
- public void close() throws Exception {
- run = false;
- }
-}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/ZMQSBPublisherManager.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/ZMQSBPublisherManager.java
index 35701fe..ec7321e 100644
--- a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/ZMQSBPublisherManager.java
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/ZMQSBPublisherManager.java
@@ -7,10 +7,7 @@
import org.zeromq.ZMQ;
import java.nio.ByteBuffer;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.*;
public class ZMQSBPublisherManager implements AutoCloseable {
private static final Logger log = LoggerFactory.getLogger(ZMQSBPublisherManager.class);
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/ZMQSBSubscriberManager.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/ZMQSBSubscriberManager.java
index cddd6d4..09617c0 100644
--- a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/ZMQSBSubscriberManager.java
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/ZMQSBSubscriberManager.java
@@ -195,6 +195,7 @@
byte[] contents = subscriber.recv();
byte topic = contents[0];
byte messageType = contents[1];
+ log.info("Received {}", contents);
switch (topic) {
case 1:
if (messageType == ASSIGN_CONFLICT && toInt(contents, 3) != controllerSourceId) {
@@ -207,10 +208,8 @@
Map.Entry<FpcDpnId, Object> entry = DpnApi.decode(contents);
if (entry != null) {
if (entry.getValue() instanceof DownlinkDataNotification) {
-// log.info("DownlinkDataNotification");
} else if (entry.getValue() instanceof DpnApi.DPNStatusIndication) {
DpnApi.DPNStatusIndication dpnStatus = (DpnApi.DPNStatusIndication) entry.getValue();
-// log.info("DPNStatusIndication");
if (dpnStatus.getStatus() == DpnApi.DPNStatusIndication.Status.HELLO) {
sendHelloReply(dpnStatus);
}
diff --git a/models/fpcagent/src/main/yang/fpc-config.yang b/models/fpcagent/src/main/yang/fpc-config.yang
index 10a656c..9e28370 100644
--- a/models/fpcagent/src/main/yang/fpc-config.yang
+++ b/models/fpcagent/src/main/yang/fpc-config.yang
@@ -1,6 +1,6 @@
module fpc-config {
yang-version 1;
- namespace "urn:opendaylight:fpc:config";
+ namespace "urn:onos:fpc:config";
prefix fpc-config;
description
diff --git a/models/fpcagent/src/main/yang/fpc.yang b/models/fpcagent/src/main/yang/fpc.yang
index 5cd95f4..2996283 100644
--- a/models/fpcagent/src/main/yang/fpc.yang
+++ b/models/fpcagent/src/main/yang/fpc.yang
@@ -1,6 +1,6 @@
module fpc {
yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:fpc";
+ namespace "urn:onos:params:xml:ns:yang:fpc";
prefix "fpc";
import ietf-dmm-fpcagent { prefix fpcagent; }
@@ -145,7 +145,7 @@
}
}
- rpc register_client {
+ rpc register-client {
input {
uses fpc:connection-config;
}
@@ -154,7 +154,7 @@
}
}
- rpc deregister_client {
+ rpc deregister-client {
input {
leaf client-id {
type fpcagent:client-identifier;
diff --git a/scripts/addDPN.sh b/scripts/addDPN.sh
old mode 100644
new mode 100755
index 00f0609..9a07776
--- a/scripts/addDPN.sh
+++ b/scripts/addDPN.sh
@@ -1,13 +1,13 @@
curl -i --header "Content-type: application/json" --request POST -u onos:rocks --data '{
"dpns": [
{
- "dpn-id": "dpn1",
+ "dpn-id": "1",
"dpn-name": "site1-anchor1",
"dpn-groups": [
"foo"
],
- "node-id": "node1",
- "network-id": "network1"
+ "node-id": "node1",
+ "network-id": "network1"
}
]
-}' http://localhost:8181/onos/restconf/data/ietf-dmm-fpcagent:tenants/tenant=default/fpc-topology
\ No newline at end of file
+}' 'http://localhost:8181/onos/restconf/data/ietf-dmm-fpcagent:tenants/tenant=default/fpc-topology'
diff --git a/scripts/createRPC.sh b/scripts/createRPC.sh
old mode 100644
new mode 100755
index dc2fb9e..e920070
--- a/scripts/createRPC.sh
+++ b/scripts/createRPC.sh
@@ -5,7 +5,45 @@
"client-id": "1",
"contexts": [
{
- "context-id": 202374885,
+ "context-id": 202374886,
+ "delegating-ip-prefixes": [
+ "192.168.1.5/32"
+ ],
+ "dl": {
+ "dpn-parameters": {},
+ "mobility-tunnel-parameters": {
+ "tunnel-identifier": "2222",
+ "tunnel-type": "gtpv1"
+ },
+ "tunnel-local-address": "192.168.1.1",
+ "tunnel-remote-address": "10.1.1.1"
+ },
+ "dpn-group": "foo",
+ "dpns": [
+ {
+ "direction": "uplink",
+ "dpn-id": "1",
+ "dpn-parameters": {}
+ }
+ ],
+ "ebi": "5",
+ "imsi": "9135551234",
+ "instructions": {
+ "instr-3gpp-mob": "session uplink"
+ },
+ "lbi": "5",
+ "ul": {
+ "dpn-parameters": {},
+ "mobility-tunnel-parameters": {
+ "tunnel-identifier": "1111",
+ "tunnel-type": "gtpv1"
+ },
+ "tunnel-local-address": "192.168.1.1",
+ "tunnel-remote-address": "10.1.1.1"
+ }
+ },
+ {
+ "context-id": 202374887,
"delegating-ip-prefixes": [
"192.168.1.5/32"
],
@@ -48,4 +86,4 @@
"op-type": "create",
"session-state": "complete"
}
-}' 'http://localhost:8181/onos/restconf/operations/ietf-dmm-fpcagent:configure'
+}' 'http://localhost:8181/onos/restconf/operations/ietf-dmm-fpcagent:configure' | python -m json.tool
diff --git a/scripts/deleteDPN.sh b/scripts/deleteDPN.sh
old mode 100644
new mode 100755
index 570da07..08b0dd4
--- a/scripts/deleteDPN.sh
+++ b/scripts/deleteDPN.sh
@@ -1,2 +1,2 @@
#!/bin/bash
-curl -X DELETE -u onos:rocks 'http://localhost:8181/onos/restconf/data/ietf-dmm-fpcagent:tenants/tenant=default/fpc-topology/dpns=dpn1'
\ No newline at end of file
+curl -X DELETE -u onos:rocks 'http://localhost:8181/onos/restconf/data/ietf-dmm-fpcagent:tenants/tenant=default/fpc-topology/dpns=1'
diff --git a/scripts/deleteRPC.sh b/scripts/deleteRPC.sh
old mode 100644
new mode 100755
diff --git a/scripts/forwarder_device.py b/scripts/forwarder_device.py
new file mode 100755
index 0000000..04f2a18
--- /dev/null
+++ b/scripts/forwarder_device.py
@@ -0,0 +1,38 @@
+#!/usr/bin/python
+# coding: utf8
+#Copyright © 2016 - 2017 Copyright (c) Sprint, 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
+
+import zmq
+
+def main():
+
+ try:
+ context = zmq.Context(1)
+
+ # Socket facing clients
+ frontend = context.socket(zmq.SUB)
+ frontend.bind("tcp://*:5559")
+
+ frontend.setsockopt(zmq.SUBSCRIBE, "")
+
+ # Socket facing services
+ backend = context.socket(zmq.PUB)
+ backend.bind("tcp://*:5560")
+
+
+ zmq.device(zmq.FORWARDER, frontend, backend)
+ except Exception, e:
+ print e
+ print "bringing down zmq device"
+ finally:
+ pass
+ frontend.close()
+ backend.close()
+ context.term()
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/scripts/forwarder_subscriber_with_ACK.py b/scripts/forwarder_subscriber_with_ACK.py
new file mode 100755
index 0000000..e3826a5
--- /dev/null
+++ b/scripts/forwarder_subscriber_with_ACK.py
@@ -0,0 +1,253 @@
+#!/usr/bin/python
+# coding: utf8
+#Copyright © 2016 - 2017 Copyright (c) Sprint, 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
+
+import signal
+import sys
+import zmq
+import struct
+import socket as socketlib
+import datetime
+import time
+import random
+import thread
+from multiprocessing.pool import ThreadPool
+
+pool = ThreadPool(processes=1)
+
+conflict = False
+topicId = None
+#nodeId = "node3"
+#networkId = "network4"
+nodeId = "node"+sys.argv[1]
+networkId = "network"+sys.argv[2]
+toSend = sys.argv[3]
+source = random.randrange(0,65535)
+topicId = random.randrange(4,255)
+
+def signal_handler(signal, frame):
+ print "\nExiting... Sending DPN Status Indication message with Status = GOODBYE"
+ pub_socket.send("%s" % (struct.pack("!BBBBIB",2,12,topicId,2,source,len(nodeId)) + nodeId + struct.pack('!B',len(networkId)) + networkId))
+ count = 0
+ while True:
+ time.sleep(1)
+ sys.stdout.write("\r"+str(5-count)+" ")
+ sys.stdout.flush()
+ count += 1
+ if(count > 5):
+ print "\n"
+ sys.exit(0)
+
+signal.signal(signal.SIGINT, signal_handler)
+
+def sendAssignId(pub_socket):
+ global conflict
+ global topicId
+ time.sleep(1)
+ pub_socket.send("%s" % (struct.pack('!BBBIB',1,10,topicId,source,len(nodeId)) + nodeId + struct.pack('!B',len(networkId)) + networkId))
+ count = 0
+ while True:
+ time.sleep(1)
+ sys.stdout.write("\r"+str(9-count)+" ")
+ sys.stdout.flush()
+ count += 1
+ if conflict:
+ conflict = False
+ sendAssignId(pub_socket)
+ return
+ if count > 9:
+ break
+ print "\nDPN Topic = ", topicId
+ print "Node Id = ", nodeId
+ print "Network Id = ", networkId
+ print "Source Id = ", source
+ print "Sending Hello Message . . ."
+ pub_socket.send("%s" % (struct.pack("!BBBBIB",2,12,topicId,1,source,len(nodeId)) + nodeId + struct.pack('!B',len(networkId)) + networkId))
+
+ print "Ready to receive messages. Press Ctrl+C when ready to exit."
+
+rec_port = "5560"
+send_port = "5559"
+# Socket to talk to server
+context = zmq.Context()
+socket = context.socket(zmq.SUB)
+pub_socket = context.socket(zmq.PUB)
+socket.connect ("tcp://localhost:%s" % rec_port)
+pub_socket.connect("tcp://localhost:%s" % send_port)
+topicfilter = ""
+controller_topic= 252
+socket.setsockopt(zmq.SUBSCRIBE, topicfilter)
+print "Listening to port ", rec_port
+print "DPN Lifecycle start up . . . Please wait."
+
+async_result = pool.apply_async(sendAssignId,(pub_socket,))
+
+count = 0
+msgnum1count = 0
+msgnum2count = 0
+msgnum3count = 0
+msgnum4count = 0
+msgnum5count = 0
+msgnum6count = 0
+for update_nbr in range(900000):
+ string = socket.recv()
+ ts = time.time()
+ st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
+
+ topic,msgnum = struct.unpack('!BB',string[:2])
+
+ if topic == 1 and msgnum == 10: #Assign_Id
+ top,msg,topId,src,nodeIdLen = struct.unpack('!BBBIB',string[:8])
+ top,msg,topId,src,nodeIdLen,nodeId1,networkIdLen = struct.unpack('!BBBIB'+str(nodeIdLen)+'sB',string[:8+nodeIdLen+1])
+ top,msg,topId,src,nodeIdLen,nodeId1,networkIdLen,networkId1 = struct.unpack('!BBBIB'+str(nodeIdLen)+'sB'+str(networkIdLen)+'s',string[:8+nodeIdLen+1+networkIdLen])
+ #print nodeId1, networkId1
+ if src != source and (topId == topicId or nodeId1 == nodeId):
+ pub_socket.send("%s" % struct.pack('!BBBIBsBs',1,11,topicId,source,len(nodeId),nodeId,len(networkId),networkId))
+ continue
+
+ elif topic == 1 and msgnum == 11: #Assign_Conflict
+ top,msg,topId,src,nodeIdLen = struct.unpack('!BBBIB',string[:8])
+ top,msg,topId,src,nodeIdLen,nodeId1,networkIdLen = struct.unpack('!BBBIB'+str(nodeIdLen)+'sB',string[:8+nodeIdLen+1])
+ top,msg,topId,src,nodeIdLen,nodeId1,networkIdLen,networkId1 = struct.unpack('!BBBIB'+str(nodeIdLen)+'sB'+str(networkIdLen)+'s',string[:8+nodeIdLen+1+networkIdLen])
+
+ if src != source:
+ if(nodeId == nodeId1):
+ print "Received assign conflict for node id. Change the node id and restart this script."
+ exit(0)
+ if(networkId == networkId1):
+ print "Received assign conflict for network id. Change the network id and restart this script."
+ exit(0)
+ if(top == topicId):
+ print "Received assign conflict for topic id. Generating new topic id and resending Assign Topic Id Message."
+ topicId = random.randrange(0,255)
+ conflict = True
+ continue
+
+ elif topic == topicId and msgnum == 13:
+ top, msg, controller_topic, controller_status = struct.unpack('!BBBB',string[:4])
+ print "DPN Status ACK received. Controller Topic = ",controller_topic
+ continue
+
+ elif topic == 3 and msgnum == 14:
+ top, msg, controller_topic, controller_status = struct.unpack('!BBBB',string[:4])
+ if controller_status == 1:
+ print "Received controller Hello. Controller Topic = ",controller_topic
+ print "Sending Hello To Controller that has a topic id of ", controller_topic
+ pub_socket.send("%s" % (struct.pack("!BBBBIB",controller_topic,12,topicId,1,source,len(nodeId)) + nodeId + struct.pack('!B',len(networkId)) + networkId))
+
+ elif controller_status == 2:
+ print "Received controller Goodbye. Controller Topic = ",controller_topic
+
+ if topic != topicId:
+ continue
+ print 'Receiving message', count, ' at ', st, ' ..... '
+ count += 1
+ print 'length of message = ', len(string)
+ print 'topic =', topic
+ print 'msgnum =', msgnum
+
+ if msgnum == 1:
+ msgnum1count += 1
+ topic,msgnum, imsi, default_ebi, ue_ip, s1u_sgw_gtpu_teid, s1u_sgw_gtpu_ipv4, sessionid, ctopic, cid, opid = struct.unpack('!cBQBLLLQBLL',string[:40])
+ print 'imsi = ', imsi
+ ipa = socketlib.inet_ntoa(struct.pack('!L',ue_ip))
+ print 'ue_ip = ', ipa
+ print 'default_ebi = ', default_ebi
+ s1u_sgw_gtpu_ipv4a = socketlib.inet_ntoa(struct.pack('!L',s1u_sgw_gtpu_ipv4))
+ print 's1u_sgw_gtpu_ipv4 = ', s1u_sgw_gtpu_ipv4a
+ print 's1u_sgw_gtpu_teid = ', s1u_sgw_gtpu_teid
+ print 'sessionid = ', sessionid
+ print 'controller topic = ', ctopic
+ print 'cid = ', cid
+ print 'opid = ', opid
+ responsedata = struct.pack('!BBBLL',controller_topic,4, 16, cid, opid)
+ if toSend == "true":
+ pub_socket.send("%s" % (responsedata))
+ #uncomment the following lines to send a DDN for every create session message
+ #time.sleep(5)
+ #pub_socket.send("%s" % (struct.pack('!BBQLLB'+str(len(nodeId))+'sB'+str(len(networkId))+'s',controller_topic,5,sessionid,cid,opid,len(nodeId),nodeId,len(networkId),networkId)))
+
+ elif msgnum == 2:
+ msgnum2count += 1
+ topic, msgnum, s1u_enb_gtpu_ipv4, s1u_enb_gtpu_teid, s1u_sgw_gtpu_ipv4, sessionid, ctopic, cid, opid = struct.unpack("!cBLLLQBLL",string[:31])
+ s1u_enb_gtpu_ipv4a = socketlib.inet_ntoa(struct.pack('!L',s1u_enb_gtpu_ipv4))
+ print 's1u_enb_gtpu_ipv4 = ', s1u_enb_gtpu_ipv4a
+ print 'dl s1u_enb_gtpu_teid = ', s1u_enb_gtpu_teid
+ print 'dl s1u_sgw_gtpu_ipv4 = ', socketlib.inet_ntoa(struct.pack('!L',s1u_sgw_gtpu_ipv4))
+ print 'sessionid = ', sessionid
+ print 'controller topic = ', ctopic
+ print 'cid = ', cid
+ print 'opid = ', opid
+ responsedata = struct.pack('!BBBLL',controller_topic,4, 16, cid, opid)
+ if toSend == "true":
+ pub_socket.send("%s" % (responsedata))
+
+ elif msgnum == 3:
+ msgnum3count += 1
+ topic, msgnum, sessionid, ctopic, cid, opid = struct.unpack("!cBQBLL",string[:19])
+ print 'sessionid = ', sessionid
+ print 'controller topic = ', ctopic
+ print 'cid = ', cid
+ print 'opid = ', opid
+ responsedata = struct.pack('!BBBLL',controller_topic,4, 0, cid, opid)
+ if toSend == "true":
+ pub_socket.send("%s" % (responsedata))
+
+ elif msgnum == 6:
+ if(len(string)==14):
+ #topic,msgnum,bufduration,bufcount,controller_topic,cid,opid = struct.unpack('!BBBHBLL',string[:14])
+ topic,msgnum,controller_topic,cid,opid = struct.unpack('!BBBLL',string[:11])
+ #print "dl-buffering-duration",bufduration
+ #print "dl-buffering-suggested-count",bufcount
+ print "Controller Topic = ",controller_topic
+ print "Client id = ", cid
+ print "Op Id = ", opid
+
+ elif msgnum == 17:
+ print "-------------------------------------------------------------"
+ print "ADC Rule received. Details:"
+ topic,msgnum,selector_type = struct.unpack('!BBB',string[:3])
+
+ #Domain
+ if(selector_type == 0):
+ domain_name_length, = struct.unpack('!B',string[3:4])
+ domain_name, = struct.unpack('!'+str(domain_name_length)+'s',string[4:4+int(domain_name_length)])
+ next_index = 4+int(domain_name_length)
+ print "Domain Name = ",domain_name
+
+ #IP Address
+ if(selector_type == 1 or selector_type == 2):
+ ip_address, = struct.unpack('!L',string[3:7])
+ ip_addressa = socketlib.inet_ntoa(struct.pack('!L',ip_address))
+ next_index = 7
+ print "IP Address = ",ip_addressa
+
+ #IP Prefix
+ if selector_type == 2:
+ ip_prefix, = struct.unpack('!H',string[7:9])
+ next_index += 2
+ print "IP Prefix = ",ip_prefix
+
+ #rule_id, = struct.unpack('!L',string[rule_id_index:rule_id_index+4])
+ #print "Rule Id = ", rule_id
+
+ #rating_group,service_id,sponsor_id_length = struct.unpack('!LLB', string[rule_id_index+4:rule_id_index+4+9])
+ drop,rating_group,service_id,sponsor_id_length = struct.unpack('!BLLB', string[next_index:next_index+10])
+ print "Drop = ", drop
+ print "Rating Group = ", rating_group
+ print "Service Id = ", service_id
+ #print "Sponsor Length = ", sponsor_id_length
+ #sponsor_id, = struct.unpack('!'+str(sponsor_id_length)+'s',string[rule_id_index+4+9:rule_id_index+4+9+int(sponsor_id_length)])
+ sponsor_id, = struct.unpack('!'+str(sponsor_id_length)+'s',string[next_index+10:next_index+10+int(sponsor_id_length)])
+ print "Sponsor = ", sponsor_id
+ print "-------------------------------------------------------------"
+ #precedence, = struct.unpack('!L',string[rule_id_index+4+9+int(sponsor_id_length):rule_id_index+4+9+int(sponsor_id_length)+4])
+ #print "precedence = ", precedence
+
+ print '================'
+ print 'Total = ', count, 'msgnum1 count', msgnum1count, 'msgnum2 count', msgnum2count, 'msgnum3 count', msgnum3count, 'msgnum4 count', msgnum4count,'msgnum5 count', msgnum5count, 'msgnum6 count', msgnum6count
+socket.close()
diff --git a/scripts/getFpcAgentInfo.sh b/scripts/getFpcAgentInfo.sh
new file mode 100755
index 0000000..4a45b20
--- /dev/null
+++ b/scripts/getFpcAgentInfo.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+curl -u onos:rocks http://localhost:8181/onos/restconf/data/ietf-dmm-fpcagent:fpc-agent-info
diff --git a/scripts/getTenants.sh b/scripts/getTenants.sh
old mode 100644
new mode 100755
index bf4b6e1..abe3bd1
--- a/scripts/getTenants.sh
+++ b/scripts/getTenants.sh
@@ -1,2 +1,2 @@
#!/bin/bash
-curl -u onos:rocks http://localhost:8181/onos/restconf/data/ietf-dmm-fpcagent:tenants
\ No newline at end of file
+curl -u onos:rocks http://localhost:8181/onos/restconf/data/ietf-dmm-fpcagent:tenants | python -m json.tool