fixed cache
diff --git a/.gitignore b/.gitignore
index bff2d76..22535db 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
*.iml
+*.log
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 7c15f01..430fb09 100644
--- a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcManager.java
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcManager.java
@@ -22,6 +22,7 @@
import org.onosproject.config.DynamicConfigService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
+import org.onosproject.fpcagent.util.CacheManager;
import org.onosproject.fpcagent.util.ConfigHelper;
import org.onosproject.fpcagent.workers.ZMQSBPublisherManager;
import org.onosproject.fpcagent.workers.ZMQSBSubscriberManager;
@@ -184,6 +185,10 @@
DefaultModelObjectData.builder().addModelObject(output).build()
);
log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
+ log.debug("Stats:\nContexts: {}\nDpns: {}",
+ CacheManager.getInstance().contextsCache.stats(),
+ CacheManager.getInstance().dpnsCache.stats()
+ );
return new RpcOutput(RpcOutput.Status.RPC_SUCCESS, dataNode.dataNodes().get(0));
}
@@ -224,7 +229,7 @@
} catch (Exception e) {
// if there is an exception respond with an error.
DefaultErr defaultErr = new DefaultErr();
- defaultErr.errorInfo(ExceptionUtils.getMessage(e));
+ defaultErr.errorInfo(ExceptionUtils.getFullStackTrace(e));
defaultErr.errorTypeId(ErrorTypeId.of(0));
configureOutput.resultType(defaultErr);
configureOutput.result(Result.of(ResultEnum.ERR));
@@ -236,6 +241,10 @@
.build()
);
log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
+ log.debug("Stats:\nContexts: {}\nDpns: {}",
+ CacheManager.getInstance().contextsCache.stats(),
+ CacheManager.getInstance().dpnsCache.stats()
+ );
return new RpcOutput(RpcOutput.Status.RPC_SUCCESS, dataNode.dataNodes().get(0));
}
@@ -292,6 +301,10 @@
.build()
);
log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
+ log.debug("Stats:\nContexts: {}\nDpns: {}",
+ CacheManager.getInstance().contextsCache.stats(),
+ CacheManager.getInstance().dpnsCache.stats()
+ );
return new RpcOutput(RpcOutput.Status.RPC_SUCCESS, dataNode.dataNodes().get(0));
}
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 9fb67ff..8862ffc 100644
--- a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantManager.java
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantManager.java
@@ -148,6 +148,16 @@
.findFirst();
}
+ public Optional<DefaultTenant> getDefaultTenant() {
+ Filter filter = Filter.builder().build();
+ DataNode dataNode = dynamicConfigService.readNode(defaultTenant, filter);
+
+ return getModelObjects(dataNode, tenants)
+ .stream()
+ .map(modelObject -> (DefaultTenant) modelObject)
+ .findFirst();
+ }
+
@Override
public Optional<DefaultTenant> getTenant(ClientIdentifier clientId) {
return Optional.ofNullable(clientIdMap.get(clientId));
@@ -289,7 +299,8 @@
.addChild(DefaultFpcMobility.class)
.build();
createNode(convertContext, modelObjectId);
- cacheManager.contextsCache.invalidate(context.contextId());
+// cacheManager.contextsCache.invalidate(context.contextId());
+ cacheManager.contextsCache.put(convertContext.contextId(), Optional.of(convertContext));
}));
if (commands.contains("downlink")) {
@@ -308,28 +319,15 @@
.addChild(DefaultFpcMobility.class)
.build();
createNode(convertContext, modelObjectId);
- cacheManager.contextsCache.invalidate(context.contextId());
+// cacheManager.contextsCache.invalidate(context.contextId());
+ cacheManager.contextsCache.put(convertContext.contextId(), Optional.of(convertContext));
}));
}
} 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(() -> {
-// dpnCommunicationService.create_bearer_ul(
-// topic_id,
-// imsi,
-// lbi,
-// default_ebi,
-// ulLocalAddress,
-// s1u_sgw_gtpu_teid
-// );
-//
-// getDefaultTenant().ifPresent(
-// tenant -> tenant.fpcMobility().addToContexts(convertContext(context))
-// );
-// }));
+ // TODO create bearer ul
}
-
}
}
@@ -353,7 +351,7 @@
log.error(ExceptionUtils.getFullStackTrace(e));
DefaultErr defaultErr = new DefaultErr();
configureOutput.resultType(defaultErr);
- defaultErr.errorInfo(ExceptionUtils.getMessage(e));
+ defaultErr.errorInfo(ExceptionUtils.getFullStackTrace(e));
defaultErr.errorTypeId(ErrorTypeId.of(0));
}
return configureOutput;
@@ -438,15 +436,11 @@
.addChild(DefaultFpcMobility.class)
.build();
updateNode(convertContext, modelObjectId);
- cacheManager.contextsCache.invalidate(context.contextId());
+// cacheManager.contextsCache.invalidate(context.contextId());
+ cacheManager.contextsCache.put(convertContext.contextId(), Optional.of(convertContext));
}));
} else {
-// tasks.add(Executors.callable(() ->
-// dpnCommunicationService.delete_bearer(
-// topic_id,
-// s1u_enb_gtpu_teid
-// )
-// ));
+ // TODO delete bearer
}
}
if (commands.contains("uplink")) {
@@ -466,15 +460,11 @@
.addChild(DefaultFpcMobility.class)
.build();
updateNode(convertContext, modelObjectId);
- cacheManager.contextsCache.invalidate(context.contextId());
+// cacheManager.contextsCache.invalidate(context.contextId());
+ cacheManager.contextsCache.put(convertContext.contextId(), Optional.of(convertContext));
}));
} else {
-// tasks.add(Executors.callable(() ->
-// dpnCommunicationService.delete_bearer(
-// topic_id,
-// s1u_sgw_gtpu_teid
-// )
-// ));
+ // TODO delete bearer
}
}
@@ -502,7 +492,7 @@
// if there is an exception respond with an error.
log.error(ExceptionUtils.getFullStackTrace(e));
DefaultErr defaultErr = new DefaultErr();
- defaultErr.errorInfo(ExceptionUtils.getMessage(e));
+ defaultErr.errorInfo(ExceptionUtils.getFullStackTrace(e));
defaultErr.errorTypeId(ErrorTypeId.of(0));
configureOutput.resultType(defaultErr);
configureOutput.result(Result.of(ResultEnum.ERR));
@@ -592,6 +582,7 @@
.addChild(DefaultContexts.class, contextsKeys)
.build());
dynamicConfigService.deleteNode(resourceVal);
+ cacheManager.contextsCache.invalidate(context.contextId());
}));
}
}
@@ -618,7 +609,7 @@
log.error(ExceptionUtils.getFullStackTrace(e));
DefaultErr defaultErr = new DefaultErr();
configureOutput.resultType(defaultErr);
- defaultErr.errorInfo(ExceptionUtils.getMessage(e));
+ defaultErr.errorInfo(ExceptionUtils.getFullStackTrace(e));
defaultErr.errorTypeId(ErrorTypeId.of(0));
}
@@ -671,7 +662,15 @@
// Filter filter = Filter.builder().build();
// DataNode node = dynamicConfigService.readNode(FpcUtil.tenants, filter);
// getModelObjects(node, null).forEach(
-// modelObject -> fpcAgentData.tenants((DefaultTenants) modelObject)
+// modelObject -> {
+// DefaultTenants tenants = (DefaultTenants) modelObject;
+// tenants.tenant()
+// .parallelStream()
+// .forEach(tenant -> cacheManager.tenantCache.put(
+// tenant.tenantId(),
+// Optional.of((DefaultTenant) tenant))
+// );
+// }
// );
break;
default:
@@ -696,10 +695,6 @@
* @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 = FpcUtil.tenants.nodeKeys();
-// return storeKeys.size() >= 2 && storeKeys.get(0).equals(tenantKeys.get(1));
return true;
}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/CacheManager.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/CacheManager.java
new file mode 100644
index 0000000..6b9c86a
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/CacheManager.java
@@ -0,0 +1,111 @@
+/*
+ * 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.util;
+
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import org.onosproject.fpcagent.TenantManager;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.DefaultTenant;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.tenant.fpcmobility.DefaultContexts;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.tenant.fpctopology.DefaultDpns;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.FpcContextId;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.FpcDpnId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Optional;
+
+public class CacheManager {
+
+ public static CacheManager _instance;
+ private final Logger log = LoggerFactory.getLogger(getClass());
+ public LoadingCache<FpcContextId, Optional<DefaultContexts>> contextsCache;
+ public LoadingCache<FpcDpnId, Optional<DefaultDpns>> dpnsCache;
+
+ private TenantManager tenantManager;
+
+ private CacheManager() {
+ contextsCache = CacheBuilder.newBuilder()
+ .maximumSize(100)
+ .build(
+ new CacheLoader<FpcContextId, Optional<DefaultContexts>>() {
+ @Override
+ public Optional<DefaultContexts> load(FpcContextId fpcContextId) throws Exception {
+ try {
+ Optional<DefaultTenant> defaultTenant = tenantManager.getDefaultTenant();
+ if (defaultTenant.isPresent()) {
+ DefaultTenant tenant = defaultTenant.get();
+ log.debug("tenant {}", defaultTenant);
+ if (tenant.fpcMobility().contexts() != null) {
+ return tenant.fpcMobility().contexts().stream()
+ .filter(contexts -> contexts.contextId().equals(fpcContextId))
+ .findFirst()
+ .map(c -> (DefaultContexts) c);
+ }
+ }
+ } catch (Exception e) {
+ Thread.sleep(1000);
+ return load(fpcContextId);
+ }
+ return Optional.empty();
+ }
+ }
+ );
+
+ dpnsCache = CacheBuilder.newBuilder()
+ .maximumSize(100)
+ .build(
+ new CacheLoader<FpcDpnId, Optional<DefaultDpns>>() {
+ @Override
+ public Optional<DefaultDpns> load(FpcDpnId fpcDpnId) throws Exception {
+ try {
+ Optional<DefaultTenant> defaultTenant = tenantManager.getDefaultTenant();
+ if (defaultTenant.isPresent()) {
+ DefaultTenant tenant = defaultTenant.get();
+ log.debug("tenant {}", tenant);
+ if (tenant.fpcTopology().dpns() != null) {
+ return tenant.fpcTopology().dpns().stream()
+ .filter(dpns -> dpns.dpnId().equals(fpcDpnId))
+ .findFirst()
+ .map(d -> (DefaultDpns) d);
+ }
+ }
+ } catch (Exception e) {
+ Thread.sleep(1000);
+ return load(fpcDpnId);
+ }
+ return Optional.empty();
+ }
+ }
+ );
+ }
+
+ public static CacheManager getInstance() {
+ if (_instance == null) {
+ _instance = new CacheManager();
+ }
+
+ return _instance;
+ }
+
+ public void addManager(TenantManager manager) {
+ this.tenantManager = manager;
+ }
+
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/ConfigHelper.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/ConfigHelper.java
new file mode 100644
index 0000000..20868af
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/ConfigHelper.java
@@ -0,0 +1,315 @@
+package org.onosproject.fpcagent.util;
+
+import com.fasterxml.jackson.annotation.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "monitor-threads",
+ "scheduled-monitors-poolsize",
+ "dpn-subscriber-uri",
+ "dpn-listener-id",
+ "dpn-publisher-uri",
+ "dpn-client-threads",
+ "metricsupdate-ms",
+ "mobilityupdate-ms",
+ "activation-threads",
+ "target-read-limit",
+ "http-notifier-clients",
+ "zmq-nbi-server-poolsize",
+ "zmq-nbi-server-uri",
+ "zmq-nbi-inproc-uri",
+ "zmq-nbi-handler-poolsize",
+ "http-nio2-nb-poolsize",
+ "http-nio2-nb-port",
+ "node-id",
+ "network-id",
+ "zmq-broadcast-controllers",
+ "zmq-broadcast-dpns",
+ "zmq-broadcast-all"
+})
+public class ConfigHelper {
+ @JsonProperty("monitor-threads")
+ private Integer monitorThreads;
+ @JsonProperty("scheduled-monitors-poolsize")
+ private Integer scheduledMonitorsPoolsize;
+ @JsonProperty("dpn-subscriber-uri")
+ private String dpnSubscriberUri;
+ @JsonProperty("dpn-listener-id")
+ private Integer dpnListenerId;
+ @JsonProperty("dpn-publisher-uri")
+ private String dpnPublisherUri;
+ @JsonProperty("dpn-client-threads")
+ private Integer dpnClientThreads;
+ @JsonProperty("metricsupdate-ms")
+ private Integer metricsupdateMs;
+ @JsonProperty("mobilityupdate-ms")
+ private Integer mobilityupdateMs;
+ @JsonProperty("activation-threads")
+ private Integer activationThreads;
+ @JsonProperty("target-read-limit")
+ private Integer targetReadLimit;
+ @JsonProperty("http-notifier-clients")
+ private Integer httpNotifierClients;
+ @JsonProperty("zmq-nbi-server-poolsize")
+ private Integer zmqNbiServerPoolsize;
+ @JsonProperty("zmq-nbi-server-uri")
+ private String zmqNbiServerUri;
+ @JsonProperty("zmq-nbi-inproc-uri")
+ private String zmqNbiInprocUri;
+ @JsonProperty("zmq-nbi-handler-poolsize")
+ private Integer zmqNbiHandlerPoolsize;
+ @JsonProperty("http-nio2-nb-poolsize")
+ private Integer httpNio2NbPoolsize;
+ @JsonProperty("http-nio2-nb-port")
+ private Integer httpNio2NbPort;
+ @JsonProperty("node-id")
+ private String nodeId;
+ @JsonProperty("network-id")
+ private String networkId;
+ @JsonProperty("zmq-broadcast-controllers")
+ private String zmqBroadcastControllers;
+ @JsonProperty("zmq-broadcast-dpns")
+ private String zmqBroadcastDpns;
+ @JsonProperty("zmq-broadcast-all")
+ private String zmqBroadcastAll;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<>();
+
+ /**
+ * No args constructor for use in serialization
+ */
+ public ConfigHelper() {
+ }
+
+
+ public Integer monitorThreads() {
+ return monitorThreads;
+ }
+
+
+ public void setMonitorThreads(Integer monitorThreads) {
+ this.monitorThreads = monitorThreads;
+ }
+
+
+ public Integer scheduledMonitorsPoolsize() {
+ return scheduledMonitorsPoolsize;
+ }
+
+
+ public void setScheduledMonitorsPoolsize(Integer scheduledMonitorsPoolsize) {
+ this.scheduledMonitorsPoolsize = scheduledMonitorsPoolsize;
+ }
+
+
+ public String dpnSubscriberUri() {
+ return dpnSubscriberUri;
+ }
+
+
+ public void setDpnSubscriberUri(String dpnSubscriberUri) {
+ this.dpnSubscriberUri = dpnSubscriberUri;
+ }
+
+
+ public Integer dpnListenerId() {
+ return dpnListenerId;
+ }
+
+
+ public void setDpnListenerId(Integer dpnListenerId) {
+ this.dpnListenerId = dpnListenerId;
+ }
+
+
+ public String dpnPublisherUri() {
+ return dpnPublisherUri;
+ }
+
+ public void setDpnPublisherUri(String dpnPublisherUri) {
+ this.dpnPublisherUri = dpnPublisherUri;
+ }
+
+
+ public Integer dpnClientThreads() {
+ return dpnClientThreads;
+ }
+
+
+ public void setDpnClientThreads(Integer dpnClientThreads) {
+ this.dpnClientThreads = dpnClientThreads;
+ }
+
+
+ public Integer metricUpdateMs() {
+ return metricsupdateMs;
+ }
+
+
+ public void setMetricsupdateMs(Integer metricsupdateMs) {
+ this.metricsupdateMs = metricsupdateMs;
+ }
+
+
+ public Integer mobilityUpdateMs() {
+ return mobilityupdateMs;
+ }
+
+
+ public void setMobilityupdateMs(Integer mobilityupdateMs) {
+ this.mobilityupdateMs = mobilityupdateMs;
+ }
+
+
+ public Integer activationThreads() {
+ return activationThreads;
+ }
+
+
+ public void setActivationThreads(Integer activationThreads) {
+ this.activationThreads = activationThreads;
+ }
+
+
+ public Integer targetReadLimit() {
+ return targetReadLimit;
+ }
+
+
+ public void setTargetReadLimit(Integer targetReadLimit) {
+ this.targetReadLimit = targetReadLimit;
+ }
+
+
+ public Integer httpNotifierClients() {
+ return httpNotifierClients;
+ }
+
+
+ public void setHttpNotifierClients(Integer httpNotifierClients) {
+ this.httpNotifierClients = httpNotifierClients;
+ }
+
+
+ public Integer zmqServerPoolsize() {
+ return zmqNbiServerPoolsize;
+ }
+
+
+ public void setZmqNbiServerPoolsize(Integer zmqNbiServerPoolsize) {
+ this.zmqNbiServerPoolsize = zmqNbiServerPoolsize;
+ }
+
+
+ public String zmqServerUri() {
+ return zmqNbiServerUri;
+ }
+
+
+ public void setZmqNbiServerUri(String zmqNbiServerUri) {
+ this.zmqNbiServerUri = zmqNbiServerUri;
+ }
+
+
+ public String zmqInprocUri() {
+ return zmqNbiInprocUri;
+ }
+
+
+ public void setZmqNbiInprocUri(String zmqNbiInprocUri) {
+ this.zmqNbiInprocUri = zmqNbiInprocUri;
+ }
+
+
+ public Integer zmqHandlerPoolsize() {
+ return zmqNbiHandlerPoolsize;
+ }
+
+
+ public void setZmqNbiHandlerPoolsize(Integer zmqNbiHandlerPoolsize) {
+ this.zmqNbiHandlerPoolsize = zmqNbiHandlerPoolsize;
+ }
+
+
+ public Integer httpNio2Poolsize() {
+ return httpNio2NbPoolsize;
+ }
+
+
+ public void setHttpNio2NbPoolsize(Integer httpNio2NbPoolsize) {
+ this.httpNio2NbPoolsize = httpNio2NbPoolsize;
+ }
+
+
+ public Integer httpNio2Port() {
+ return httpNio2NbPort;
+ }
+
+
+ public void setHttpNio2NbPort(Integer httpNio2NbPort) {
+ this.httpNio2NbPort = httpNio2NbPort;
+ }
+
+
+ public String nodeId() {
+ return nodeId;
+ }
+
+
+ public void setNodeId(String node_id) {
+ this.nodeId = node_id;
+ }
+
+
+ public String networkId() {
+ return networkId;
+ }
+
+
+ public void setNetworkId(String network_id) {
+ this.networkId = network_id;
+ }
+
+
+ public String zmqBroadcastControllers() {
+ return zmqBroadcastControllers;
+ }
+
+
+ public void setZmqBroadcastControllers(String zmqBroadcastControllers) {
+ this.zmqBroadcastControllers = zmqBroadcastControllers;
+ }
+
+ public String zmqBroadcastDpns() {
+ return zmqBroadcastDpns;
+ }
+
+
+ public void setZmqBroadcastDpns(String zmqBroadcastDpns) {
+ this.zmqBroadcastDpns = zmqBroadcastDpns;
+ }
+
+
+ public String zmqBroadcastAll() {
+ return zmqBroadcastAll;
+ }
+
+
+ public void setZmqBroadcastAll(String zmqBroadcastAll) {
+ this.zmqBroadcastAll = zmqBroadcastAll;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/Converter.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/Converter.java
new file mode 100644
index 0000000..5c6b3ce
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/Converter.java
@@ -0,0 +1,169 @@
+package org.onosproject.fpcagent.util;
+
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.ClientIdentifier;
+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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Function;
+
+public class Converter {
+ private static final Logger log = LoggerFactory.getLogger(Converter.class);
+ /**
+ * Short to Byte
+ *
+ * @param value - Short
+ * @return byte value
+ */
+ public static byte toUint8(Short value) {
+ return value.byteValue();
+ }
+
+ /**
+ * Short to byte array
+ *
+ * @param value - Short
+ * @return byte array
+ */
+ public static byte[] toUint16(Short value) {
+ return new byte[]{(byte) (value >>> 8), (byte) (value & 0xFF)};
+ }
+
+ /**
+ * Lower two bytes of an integer to byte array
+ *
+ * @param value - integer value
+ * @return byte array
+ */
+ public static byte[] toUint16(Integer value) {
+ return new byte[]{(byte) (value >>> 8), (byte) (value & 0xFF)};
+ }
+
+ /**
+ * Long to byte array.
+ *
+ * @param value - long
+ * @return byte array
+ */
+ public static byte[] toUint32(long value) {
+ return new byte[]{(byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), (byte) (value & 0xFF)};
+ }
+
+ /**
+ * BigInteger to byte array.
+ *
+ * @param value - BigInteger
+ * @return byte array
+ */
+ public static byte[] toUint64(BigInteger value) {
+ return new byte[]{value.shiftRight(56).byteValue(), value.shiftRight(48).byteValue(), value.shiftRight(40).byteValue(),
+ value.shiftRight(32).byteValue(), value.shiftRight(24).byteValue(), value.shiftRight(16).byteValue(),
+ value.shiftRight(8).byteValue(), value.and(BigInteger.valueOf(0xFF)).byteValue()};
+ }
+
+ /**
+ * Decodes a 32 bit value
+ *
+ * @param source - byte array
+ * @param offset - offset in the array where the 8 bytes begins
+ * @return integer
+ */
+ public static int toInt(byte[] source, int offset) {
+ return new BigInteger(Arrays.copyOfRange(source, offset, offset + 4)).intValue();
+ }
+
+ /**
+ * Converts a byte array to BigInteger
+ *
+ * @param source - byte array
+ * @param offset - offset in the array where the 8 bytes begins
+ * @return BigInteger representing a Uint64
+ */
+ public static BigInteger toBigInt(byte[] source, int offset) {
+ return new BigInteger(Arrays.copyOfRange(source, offset, offset + 8));
+ }
+
+ /**
+ * Converts an integer to a long (used for larger unsigned integers)
+ *
+ * @param source - message buffer (byte array)
+ * @param offset - offset in the array where the 4 bytes begins
+ * @return Long value of the unsigned integer
+ */
+ public static long fromIntToLong(byte[] source, int offset) {
+ long value = 0;
+ for (int i = offset; i < offset + 4; i++) {
+ value = (value << 8) + (source[i] & 0xff);
+ }
+ return value;
+ }
+
+ 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 DefaultContexts convertContext(org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.payload.Contexts contexts) {
+ DefaultContexts 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/util/DpnCommunicationService.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/DpnCommunicationService.java
new file mode 100644
index 0000000..e1bcd17
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/DpnCommunicationService.java
@@ -0,0 +1,109 @@
+/*
+ * 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.util;
+
+import org.onlab.packet.Ip4Address;
+
+import java.math.BigInteger;
+
+/**
+ * Communication Service which sends packets to desired DPNs.
+ */
+public interface DpnCommunicationService {
+
+ /**
+ * Creates Mobility Session.
+ *
+ * @param topic_id - DPN Topic ID
+ * @param imsi - IMSI identifier
+ * @param default_ebi - EBI
+ * @param ue_ipv4 - UE IPv4 Address
+ * @param s1u_sgw_teid - SGW Tunnel Identifier
+ * @param s1u_sgw_ipv4 - SGW IPv4
+ * @param session_id - Context Identifier
+ * @param client_id - Client Identifier
+ * @param op_id - Operation Identifier
+ */
+ void create_session(
+ Short topic_id,
+ BigInteger imsi,
+ Short default_ebi,
+ Ip4Address ue_ipv4,
+ Long s1u_sgw_teid,
+ Ip4Address s1u_sgw_ipv4,
+ Long session_id,
+ Long client_id,
+ BigInteger op_id
+ );
+
+ /**
+ * Modifies Bearer.
+ *
+ * @param topic_id - DPN Topic ID
+ * @param s1u_sgw_ipv4 - SGW IPv4 Address
+ * @param s1u_enodeb_teid - ENodeB Tunnel Identifier
+ * @param s1u_enodeb_ipv4 - ENodeB IPv4 Address
+ * @param session_id - Context Identifier
+ * @param client_id - Client Identifier
+ * @param op_id - Operation Identifier
+ */
+ void modify_bearer(
+ Short topic_id,
+ Ip4Address s1u_sgw_ipv4,
+ Long s1u_enodeb_teid,
+ Ip4Address s1u_enodeb_ipv4,
+ Long session_id,
+ Long client_id,
+ BigInteger op_id
+ );
+
+ /**
+ * Deletes Mobility Session.
+ *
+ * @param topic_id - DPN Topic ID
+ * @param session_id - Context Identifier
+ * @param client_id - Client Identifier
+ * @param op_id - Operation Identifier
+ */
+ void delete_session(
+ Short topic_id,
+ Long session_id,
+ Long client_id,
+ BigInteger op_id
+ );
+
+ /**
+ * Creates the byte buffer to send ADC rules over ZMQ
+ *
+ * @param topic - DPN Topic ID
+ * @param domain_name - domain
+ * @param ip - ipaddress/ipprefix (i.e. 127.0.0.1/32)
+ * @param drop - Drop if 1
+ * @param rating_group - Rating Group
+ * @param service_ID - Service ID
+ * @param sponsor_ID - Sponsor ID
+ */
+ void send_ADC_rules(
+ Short topic,
+ String domain_name,
+ String ip,
+ Short drop,
+ Long rating_group,
+ Long service_ID,
+ String sponsor_ID
+ );
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/DpnNgicCommunicator.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/DpnNgicCommunicator.java
new file mode 100644
index 0000000..82618f4
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/DpnNgicCommunicator.java
@@ -0,0 +1,232 @@
+/*
+ * 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.util;
+
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onosproject.fpcagent.workers.ZMQSBPublisherManager;
+import org.onosproject.fpcagent.workers.ZMQSBSubscriberManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+
+import static org.onosproject.fpcagent.util.Converter.*;
+
+/**
+ * DPDK DPN API over ZeroMQ for NGIC.
+ */
+public class DpnNgicCommunicator implements DpnCommunicationService {
+ protected static final Logger log = LoggerFactory.getLogger(DpnNgicCommunicator.class);
+
+ @Override
+ public void create_session(
+ Short topic_id,
+ BigInteger imsi,
+ Short default_ebi,
+ Ip4Address ue_ipv4,
+ Long s1u_sgw_teid,
+ Ip4Address s1u_sgw_ipv4,
+ Long session_id,
+ Long client_id,
+ BigInteger op_id
+ ) {
+ /* NGIC Create Session expected buffer:
+ uint8_t topic_id;
+ uint8_t type;
+ struct create_session_t {
+ uint64_t imsi;
+ uint8_t default_ebi;
+ uint32_t ue_ipv4;
+ uint32_t s1u_sgw_teid;
+ uint32_t s1u_sgw_ipv4;
+ uint64_t session_id;
+ uint8_t controller_topic;
+ uint32_t client_id;
+ uint32_t op_id;
+ } create_session_msg;
+ */
+ // TODO: check if subscriber is open.
+ ByteBuffer bb = ByteBuffer.allocate(41)
+ .put(toUint8(topic_id))
+ .put(s11MsgType.CREATE_SESSION.getType())
+ .put(toUint64(imsi))
+ .put(toUint8(default_ebi))
+ .put(toUint32(ue_ipv4.toInt()))
+ .put(toUint32(s1u_sgw_teid))
+ .put(toUint32(s1u_sgw_ipv4.toInt()))
+ .put(toUint64(BigInteger.valueOf(session_id)))
+ .put(toUint8(ZMQSBSubscriberManager.getControllerTopic()))
+ .put(toUint32(client_id))
+ .put(toUint32(op_id.longValue()));
+
+ log.debug("create_session: {}", bb.array());
+ ZMQSBPublisherManager.getInstance().send(bb);
+ }
+
+ @Override
+ public void modify_bearer(
+ Short topic_id,
+ Ip4Address s1u_sgw_ipv4,
+ Long s1u_enodeb_teid,
+ Ip4Address s1u_enodeb_ipv4,
+ Long session_id,
+ Long client_id,
+ BigInteger op_id
+ ) {
+ /*
+ NGIC Modify Session expected buffer:
+ uint8_t topic_id;
+ uint8_t type;
+ struct modify_bearer_t {
+ uint32_t s1u_sgw_ipv4;
+ uint32_t s1u_enodeb_teid;
+ uint32_t s1u_enodeb_ipv4;
+ uint64_t session_id;
+ uint8_t controller_topic;
+ uint32_t client_id;
+ uint32_t op_id;
+ } modify_bearer_msg;
+ */
+ ByteBuffer bb = ByteBuffer.allocate(32)
+ .put(toUint8(topic_id))
+ .put(s11MsgType.MODIFY_BEARER.getType())
+ .put(toUint32(s1u_sgw_ipv4.toInt()))
+ .put(toUint32(s1u_enodeb_teid))
+ .put(toUint32(s1u_enodeb_ipv4.toInt()))
+ .put(toUint64(BigInteger.valueOf(session_id)))
+ .put(toUint8(ZMQSBSubscriberManager.getControllerTopic()))
+ .put(toUint32(client_id))
+ .put(toUint32(op_id.longValue()));
+
+ log.debug("modify_bearer: {}", bb.array());
+ ZMQSBPublisherManager.getInstance().send(bb);
+ }
+
+ @Override
+ public void delete_session(
+ Short topic_id,
+ Long session_id,
+ Long client_id,
+ BigInteger op_id
+ ) {
+ /*
+ NGIC Delete Session expected buffer:
+ uint8_t topic_id;
+ uint8_t type;
+ struct delete_session_t {
+ uint64_t session_id;
+ uint8_t controller_topic;
+ uint32_t client_id;
+ uint32_t op_id;
+ } delete_session_msg;
+ */
+ ByteBuffer bb = ByteBuffer.allocate(19)
+ .put(toUint8(topic_id))
+ .put(s11MsgType.DELETE_SESSION.getType())
+ .put(toUint64(BigInteger.valueOf(session_id)))
+ .put(toUint8(ZMQSBSubscriberManager.getControllerTopic()))
+ .put(toUint32(client_id))
+ .put(toUint32(op_id.longValue()));
+
+ log.debug("delete_session: {}", bb.array());
+ ZMQSBPublisherManager.getInstance().send(bb);
+ }
+
+ @Override
+ public void send_ADC_rules(
+ Short topic,
+ String domain_name,
+ String ip,
+ Short drop,
+ Long rating_group,
+ Long service_ID, String sponsor_ID
+ ) {
+ // TODO take a look for this function. Not tested.
+ Ip4Prefix ip_prefix = null;
+ if (ip != null) {
+ ip_prefix = Ip4Prefix.valueOf(ip);
+ }
+ Short selector_type = (short) (domain_name != null ? 0 : ip_prefix != null ? 2 : ip_prefix.address() != null ? 1 : 255);
+ if (selector_type == 255) {
+ log.warn("Domain/IP not found, failed to send rules");
+ return;
+ }
+ ByteBuffer bb = ByteBuffer.allocate(200);
+ bb.put(toUint8(topic))
+ .put(s11MsgType.ADC_RULE.getType())
+ .put(toUint8(selector_type));
+ if (selector_type == 0) {
+ bb.put(toUint8((short) domain_name.length()))
+ .put(domain_name.getBytes());
+ }
+ if ((selector_type == 1) || (selector_type == 2)) {
+ int ip_address_long = ip_prefix.address().toInt();
+ bb.put(toUint32(ip_address_long));
+ }
+ if (selector_type == 2) {
+ bb.put(toUint16(ip_prefix.prefixLength()));
+ }
+ if (drop != null)
+ bb.put(toUint8(drop));
+ if (rating_group != null)
+ bb.put(toUint32(rating_group));
+ if (service_ID != null)
+ bb.put(toUint32(service_ID));
+ if (sponsor_ID != null && (short) sponsor_ID.length() > 0) {
+ bb.put(toUint8((short) sponsor_ID.length()))
+ .put(sponsor_ID.getBytes());
+ }
+ bb.put(toUint8(ZMQSBSubscriberManager.getControllerTopic()));
+
+ log.info("send_ADC_rules: {}", bb.array());
+ ZMQSBPublisherManager.getInstance().send(bb);
+ }
+
+ /**
+ * Following the NGIC message types.
+ *
+ * This type structure is defined in NGIC at interface/zmq/zmqsub.h:51
+ */
+ enum s11MsgType {
+ CREATE_SESSION(1),
+ MODIFY_BEARER(2),
+ DELETE_SESSION(3),
+ DPN_RESPONSE(4),
+ DDN(5),
+ ASSIGN_TOPIC(10),
+ ASSIGN_CONFLICT(11),
+ DPN_STATUS_INDICATION(12),
+ DPN_STATUS_ACK(13),
+ CONTROLLER_STATUS_INDICATION(14),
+ ADC_RULE(17),
+ PCC_RULE(18),
+ METER_RULE(19),
+ SDF_RULE(20);
+
+ private byte type;
+
+ s11MsgType(int type) {
+ this.type = (byte) type;
+ }
+
+ public byte getType() {
+ return type;
+ }
+ }
+}
\ No newline at end of file
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/FpcUtil.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/FpcUtil.java
new file mode 100644
index 0000000..a0ff5f7
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/FpcUtil.java
@@ -0,0 +1,302 @@
+/*
+ * 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.util;
+
+import com.google.common.collect.Maps;
+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.tenants.DefaultTenant;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.TenantKeys;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.yangautoprefixnotify.value.DefaultDownlinkDataNotification;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.yangautoprefixnotify.value.DownlinkDataNotification;
+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.fpcidentity.FpcIdentityUnion;
+import org.onosproject.yang.model.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Map;
+
+import static org.onosproject.fpcagent.util.Converter.*;
+
+/**
+ * Helper class which stores all the static variables.
+ */
+public class FpcUtil {
+ public static final int MAX_EVENTS = 1000;
+ public static final int MAX_BATCH_MS = 5000;
+ public static final int MAX_IDLE_MS = 1000;
+ public static final String TIMER = "dynamic-config-fpcagent-timer";
+ public static final String UNKNOWN_EVENT = "FPC Agent listener: unknown event: {}";
+ public static final String EVENT_NULL = "Event cannot be null";
+ public static final String FPC_APP_ID = "org.onosproject.fpcagent";
+ protected static final Logger log = LoggerFactory.getLogger(FpcUtil.class);
+ private static final Map<String, FpcDpnId> uplinkDpnMap = Maps.newConcurrentMap();
+ private static final Map<String, Short> nodeToTopicMap = Maps.newConcurrentMap();
+ public static ModelConverter modelConverter = null;
+ // Resource ID for Configure DPN RPC command
+ public static ResourceId configureDpn;
+ // Resource ID for Configure RPC command
+ public static ResourceId configure;
+ // Resource ID for tenants data
+ public static ResourceId tenants;
+ public static ResourceId defaultTenant;
+ public static ResourceId configureBundles;
+ public static ResourceId module;
+ public static ResourceId registerClientResourceId;
+ public static ResourceId deregisterClientResourceId;
+
+ public static FpcIdentity defaultIdentity = getFpcIdentity.apply("default");
+
+ private static byte DPN_HELLO = 0b0000_0001;
+ private static byte DPN_BYE = 0b0000_0010;
+ private static byte DOWNLINK_DATA_NOTIFICATION = 0b0000_0101;
+ private static byte DPN_STATUS_INDICATION = 0b0000_1100;
+ 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";
+
+ /**
+ * Returns resource id from model converter.
+ *
+ * @param modelId model object id
+ * @return resource id
+ */
+ public static ResourceId getResourceVal(ModelObjectId modelId) {
+ DefaultModelObjectData.Builder data = DefaultModelObjectData.builder()
+ .identifier(modelId);
+ ResourceData resData = modelConverter.createDataNode(data.build());
+ return resData.resourceId();
+ }
+
+ /**
+ * Returns the resource id, after constructing model object id and
+ * converting it.
+ */
+ public static void getResourceId() {
+ ModelObjectId moduleId = ModelObjectId.builder().build();
+ module = getResourceVal(moduleId);
+
+ ModelObjectId tenantsId = ModelObjectId.builder()
+ .addChild(DefaultTenants.class)
+ .build();
+
+ tenants = getResourceVal(tenantsId);
+
+ TenantKeys tenantKeys = new TenantKeys();
+ tenantKeys.tenantId(defaultIdentity);
+
+ ModelObjectId defaultTenantId = ModelObjectId.builder()
+ .addChild(DefaultTenants.class)
+ .addChild(DefaultTenant.class, tenantKeys)
+ .build();
+
+ defaultTenant = getResourceVal(defaultTenantId);
+
+ configure = ResourceId.builder()
+ .addBranchPointSchema("/", null)
+ .addBranchPointSchema("configure", "urn:ietf:params:xml:ns:yang:fpcagent")
+ .build();
+
+ configureDpn = ResourceId.builder()
+ .addBranchPointSchema("/", null)
+ .addBranchPointSchema("configure-dpn", "urn:ietf:params:xml:ns:yang:fpcagent")
+ .build();
+
+ configureBundles = ResourceId.builder()
+ .addBranchPointSchema("/", null)
+ .addBranchPointSchema("configure-bundles", "urn:ietf:params:xml:ns:yang:fpcagent")
+ .build();
+ }
+
+ public static ModelObjectId.Builder defaultTenantBuilder() {
+ TenantKeys tenantKeys = new TenantKeys();
+ tenantKeys.tenantId(defaultIdentity);
+
+ return ModelObjectId.builder()
+ .addChild(DefaultTenants.class)
+ .addChild(DefaultTenant.class, tenantKeys);
+ }
+
+ /**
+ * Returns resource id for the specific tenant ID.
+ *
+ * @param tenantId tenant id
+ * @return resource ids
+ */
+ public static ResourceId getTenantResourceId(FpcIdentity tenantId) {
+ TenantKeys tenantKeys = new TenantKeys();
+ tenantKeys.tenantId(tenantId);
+
+ return getResourceVal(ModelObjectId.builder()
+ .addChild(DefaultTenants.class)
+ .addChild(DefaultTenant.class, tenantKeys)
+ .build());
+ }
+
+ /**
+ * 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();
+ }
+ }
+
+ /**
+ * Ensures the session id is an unsigned 64 bit integer
+ *
+ * @param sessionId - session id received from the DPN
+ * @return unsigned session id
+ */
+ private static BigInteger checkSessionId(BigInteger sessionId) {
+ if (sessionId.compareTo(BigInteger.ZERO) < 0) {
+ sessionId = sessionId.add(BigInteger.ONE.shiftLeft(64));
+ }
+ return sessionId;
+ }
+
+ /**
+ * Decodes a DownlinkDataNotification
+ *
+ * @param buf - message buffer
+ * @param key - Concatenation of node id + / + network id
+ * @return DownlinkDataNotification or null if it could not be successfully decoded
+ */
+ private static DownlinkDataNotification processDDN(byte[] buf, String key) {
+ DownlinkDataNotification ddnB = new DefaultDownlinkDataNotification();
+ ddnB.sessionId(checkSessionId(toBigInt(buf, 2)));
+ ddnB.notificationMessageType(DOWNLINK_DATA_NOTIFICATION_STRING);
+ ddnB.clientId(ClientIdentifier.of(FpcIdentity.of(FpcIdentityUnion.of(fromIntToLong(buf, 10)))));
+ ddnB.opId(OpIdentifier.of(BigInteger.valueOf(fromIntToLong(buf, 14))));
+ ddnB.notificationDpnId(uplinkDpnMap.get(key));
+ return ddnB;
+ }
+
+ /**
+ * Decodes a DPN message.
+ *
+ * @param buf - message buffer
+ * @return - A pair with the DPN Id and decoded Object
+ */
+ public static Map.Entry<FpcDpnId, Object> decode(byte[] buf) {
+ if (buf[1] == DPN_REPLY) {
+ return null;
+ } else if (buf[1] == DOWNLINK_DATA_NOTIFICATION) {
+ short nodeIdLen = buf[18];
+ short networkIdLen = buf[19 + nodeIdLen];
+ String key = new String(Arrays.copyOfRange(buf, 19, 19 + nodeIdLen)) + "/" + new String(Arrays.copyOfRange(buf, 20 + nodeIdLen, 20 + nodeIdLen + networkIdLen));
+ return uplinkDpnMap.get(key) == null ? null : new AbstractMap.SimpleEntry<>(uplinkDpnMap.get(key), processDDN(buf, key));
+ } else if (buf[1] == DPN_STATUS_INDICATION) {
+ DPNStatusIndication.Status status = null;
+
+ short nodeIdLen = buf[8];
+ short networkIdLen = buf[9 + nodeIdLen];
+ String key = new String(Arrays.copyOfRange(buf, 9, 9 + nodeIdLen)) + "/" + new String(Arrays.copyOfRange(buf, 10 + nodeIdLen, 10 + nodeIdLen + networkIdLen));
+ if (buf[3] == DPN_OVERLOAD_INDICATION) {
+ status = DPNStatusIndication.Status.OVERLOAD_INDICATION;
+ } else if (buf[3] == DPN_HELLO) {
+ status = DPNStatusIndication.Status.HELLO;
+ log.info("Hello {} on topic {}", key, buf[2]);
+ nodeToTopicMap.put(key, (short) buf[2]);
+ } else if (buf[3] == DPN_BYE) {
+ status = DPNStatusIndication.Status.BYE;
+ log.info("Bye {}", key);
+ nodeToTopicMap.remove(key);
+ }
+ return new AbstractMap.SimpleEntry<>(uplinkDpnMap.get(key), new DPNStatusIndication(status, key));
+ }
+ return null;
+ }
+
+ /**
+ * Gets the mapping for node id / network id to ZMQ Topic
+ *
+ * @param Key - Concatenation of node id + / + network id
+ * @return - ZMQ Topic
+ */
+ public static Short getTopicFromNode(String Key) {
+ return nodeToTopicMap.get(Key);
+ }
+
+ /**
+ * Provides basic status changes,
+ */
+ public static class DPNStatusIndication {
+ private final Status status;
+ private final String key; //nodeId +"/"+ networkId
+ /**
+ * Node Reference of the DPN
+ */
+ public Short nodeRef;
+
+ /**
+ * Constructor providing the DPN and its associated Status.
+ *
+ * @param status - DPN Status
+ * @param key - Combination of node id and network id
+ */
+ public DPNStatusIndication(Status status,
+ String key) {
+ this.status = status;
+ this.key = key;
+ }
+
+ /**
+ * Provides DPN Status
+ *
+ * @return Status associated to the DPN.
+ */
+ public Status getStatus() {
+ return status;
+ }
+
+ /**
+ * Provides the DPN key - nodeId +"/"+ networkId
+ *
+ * @return FpcDpnId
+ */
+ public String getKey() {
+ return this.key;
+ }
+
+ /**
+ * Basic DPN Status
+ */
+ public enum Status {
+ HELLO,
+ BYE,
+ OVERLOAD_INDICATION
+ }
+ }
+}
diff --git a/scripts/benchmark.sh b/scripts/benchmark.sh
index 1cc3b93..1d3a6ac 100755
--- a/scripts/benchmark.sh
+++ b/scripts/benchmark.sh
@@ -1,19 +1,23 @@
#!/bin/sh
+rm -rf create.log delete.log
+
./addDPN.sh 1 &> /dev/null
for (( i=1; i<=100; i++)); do
- ./configureCreateOrUpdate.sh create $i 1 &> /dev/null &
+ ./configure.sh create $i 1 >> create.log 2> /dev/null &
if ! (($i % 10)); then
wait
fi
done
-#for (( i=1; i<=100; i++)); do
-# ./configureDeleteOrQuery.sh delete $i &> /dev/null &
-# if ! (($i % 10)); then
-# wait
-# fi
-#done
+wait
+
+for (( i=1; i<=100; i++)); do
+ ./configure.sh delete $i >> delete.log 2> /dev/null &
+ if ! (($i % 10)); then
+ wait
+ fi
+done
./deleteDPN.sh 1 &> /dev/null
diff --git a/scripts/configureCreateOrUpdate.sh b/scripts/configure.sh
similarity index 71%
rename from scripts/configureCreateOrUpdate.sh
rename to scripts/configure.sh
index 5ce3bbe..a77d853 100755
--- a/scripts/configureCreateOrUpdate.sh
+++ b/scripts/configure.sh
@@ -1,6 +1,30 @@
#!/bin/bash
-if [ "$#" -eq 3 ]; then
+if [ "$#" -eq 2 ] && [ $1 == "delete" ]; then
+ echo ""
+ json='{
+ "input": {
+ "op-id": '$2',
+ "targets": [
+ {
+ "target": "/ietf-dmm-fpcagent:tenants/tenant=default/fpc-mobility/contexts='$2'"
+ }
+ ],
+ "client-id": "1",
+ "session-state": "complete",
+ "admin-state": "enabled",
+ "op-type": "'$1'",
+ "op-ref-scope": "none"
+ }
+ }'
+
+ curl -X POST \
+ --header 'Content-Type: application/json' \
+ -u onos:rocks \
+ --header 'Accept: application/json' \
+ -d "$json" \
+ 'http://localhost:8181/onos/restconf/operations/ietf-dmm-fpcagent:configure' | python -m json.tool
+elif [ "$#" -eq 3 ] && [ $1 == "create" ]; then
echo ""
json='{
"input": {
@@ -46,7 +70,7 @@
}
}
],
- "op-id": "1",
+ "op-id": '$2',
"op-ref-scope": "op",
"op-type": "'$1'",
"session-state": "complete"
@@ -61,5 +85,5 @@
'http://localhost:8181/onos/restconf/operations/ietf-dmm-fpcagent:configure' | python -m json.tool
echo ""
else
- echo "usage: "$0" type contextId dpnId"
+ echo "usage: "$0" type contextId"
fi
\ No newline at end of file
diff --git a/scripts/configureDeleteOrQuery.sh b/scripts/configureDeleteOrQuery.sh
deleted file mode 100755
index 5735d72..0000000
--- a/scripts/configureDeleteOrQuery.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-
-if [ "$#" -eq 2 ]; then
- echo ""
- json='{
- "input": {
- "op-id": "3",
- "targets": [
- {
- "target": "/ietf-dmm-fpcagent:tenants/tenant=default/fpc-mobility/contexts='$2'"
- }
- ],
- "client-id": "1",
- "session-state": "complete",
- "admin-state": "enabled",
- "op-type": "'$1'",
- "op-ref-scope": "none"
- }
- }'
-
- curl -X POST \
- --header 'Content-Type: application/json' \
- -u onos:rocks \
- --header 'Accept: application/json' \
- -d "$json" \
- 'http://localhost:8181/onos/restconf/operations/ietf-dmm-fpcagent:configure' | python -m json.tool
-else
- echo "usage: "$0" type contextId"
-fi
\ No newline at end of file