summaryrefslogtreecommitdiffstats
path: root/framework/src/onos/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/CordModelCache.java
diff options
context:
space:
mode:
authorAshlee Young <ashlee@onosfw.com>2015-09-09 22:15:21 -0700
committerAshlee Young <ashlee@onosfw.com>2015-09-09 22:15:21 -0700
commit13d05bc8458758ee39cb829098241e89616717ee (patch)
tree22a4d1ce65f15952f07a3df5af4b462b4697cb3a /framework/src/onos/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/CordModelCache.java
parent6139282e1e93c2322076de4b91b1c85d0bc4a8b3 (diff)
ONOS checkin based on commit tag e796610b1f721d02f9b0e213cf6f7790c10ecd60
Change-Id: Ife8810491034fe7becdba75dda20de4267bd15cd
Diffstat (limited to 'framework/src/onos/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/CordModelCache.java')
-rw-r--r--framework/src/onos/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/CordModelCache.java382
1 files changed, 382 insertions, 0 deletions
diff --git a/framework/src/onos/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/CordModelCache.java b/framework/src/onos/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/CordModelCache.java
new file mode 100644
index 00000000..dd1e42b7
--- /dev/null
+++ b/framework/src/onos/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/CordModelCache.java
@@ -0,0 +1,382 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.cord.gui;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.ImmutableList;
+import org.onosproject.cord.gui.model.Bundle;
+import org.onosproject.cord.gui.model.BundleDescriptor;
+import org.onosproject.cord.gui.model.BundleFactory;
+import org.onosproject.cord.gui.model.JsonFactory;
+import org.onosproject.cord.gui.model.SubscriberUser;
+import org.onosproject.cord.gui.model.UserFactory;
+import org.onosproject.cord.gui.model.XosFunction;
+import org.onosproject.cord.gui.model.XosFunctionDescriptor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.cord.gui.model.XosFunctionDescriptor.URL_FILTER;
+
+/**
+ * In memory cache of the model of the subscriber's account.
+ */
+public class CordModelCache extends JsonFactory {
+
+ private static final String KEY_SSID_MAP = "ssidmap";
+ private static final String KEY_SSID = "service_specific_id";
+ private static final String KEY_SUB_ID = "subscriber_id";
+
+ private static final int DEMO_SSID = 1234;
+
+ private static final String EMAIL_0 = "john@smith.org";
+ private static final String EMAIL_1 = "john@doe.org";
+
+ private static final String EMAIL = "email";
+ private static final String SSID = "ssid";
+ private static final String SUB_ID = "subId";
+
+ private static final String BUNDLE = "bundle";
+ private static final String USERS = "users";
+ private static final String LEVEL = "level";
+ private static final String LOGOUT = "logout";
+
+ private static final String BUNDLE_NAME = BUNDLE + "_name";
+ private static final String BUNDLE_DESC = BUNDLE + "_desc";
+
+ private static final Map<Integer, Integer> LOOKUP = new HashMap<>();
+
+ private String email = null;
+ private int subscriberId;
+ private int ssid;
+ private Bundle currentBundle;
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ // NOTE: use a tree map to maintain sorted order by user ID
+ private final Map<Integer, SubscriberUser> userMap =
+ new TreeMap<Integer, SubscriberUser>();
+
+ /**
+ * Constructs a model cache, retrieving a mapping of SSID to XOS Subscriber
+ * IDs from the XOS server.
+ */
+ CordModelCache() {
+ log.info("Initialize model cache");
+ ObjectNode map = XosManager.INSTANCE.initXosSubscriberLookups();
+ initLookupMap(map);
+ log.info("{} entries in SSID->SubID lookup map", LOOKUP.size());
+ }
+
+ private void initLookupMap(ObjectNode map) {
+ ArrayNode array = (ArrayNode) map.get(KEY_SSID_MAP);
+ Iterator<JsonNode> iter = array.elements();
+ StringBuilder msg = new StringBuilder();
+ while (iter.hasNext()) {
+ ObjectNode node = (ObjectNode) iter.next();
+ String ssidStr = node.get(KEY_SSID).asText();
+ int ssid = Integer.valueOf(ssidStr);
+ int subId = node.get(KEY_SUB_ID).asInt();
+ LOOKUP.put(ssid, subId);
+ msg.append(String.format("\n..binding SSID %s to sub-id %s", ssid, subId));
+ }
+ log.info(msg.toString());
+ }
+
+ private int lookupSubId(int ssid) {
+ Integer subId = LOOKUP.get(ssid);
+ if (subId == null) {
+ log.error("Unmapped SSID: {}", ssid);
+ return 0;
+ }
+ return subId;
+ }
+
+ /**
+ * Initializes the model for the subscriber account associated with
+ * the given email address.
+ *
+ * @param email the email address
+ */
+ void init(String email) {
+ // defaults to the demo account
+ int ssid = DEMO_SSID;
+
+ this.email = email;
+
+ // obviously not scalable, but good enough for demo code...
+ if (EMAIL_0.equals(email)) {
+ ssid = 0;
+ } else if (EMAIL_1.equals(email)) {
+ ssid = 1;
+ }
+
+ this.ssid = ssid;
+ subscriberId = lookupSubId(ssid);
+ XosManager.INSTANCE.setXosUtilsForSubscriber(subscriberId);
+
+ // call the initdemo API to ensure users are populated in XOS
+ XosManager.INSTANCE.initDemoSubscriber();
+
+ // NOTE: I think the following should work for non-DEMO account...
+ currentBundle = new Bundle(BundleFactory.BASIC_BUNDLE);
+ initUsers();
+ }
+
+ private void initUsers() {
+ // start with a clean slate
+ userMap.clear();
+
+ ArrayNode users = XosManager.INSTANCE.getUserList();
+ if (users == null) {
+ log.warn("no user list for SSID {} (subid {})", ssid, subscriberId);
+ return;
+ }
+
+ StringBuilder sb = new StringBuilder();
+ for (JsonNode u: users) {
+ ObjectNode user = (ObjectNode) u;
+
+ int id = user.get("id").asInt();
+ String name = user.get("name").asText();
+ String mac = user.get("mac").asText();
+ String level = user.get("level").asText();
+
+ // NOTE: We are just storing the current "url-filter" level.
+ // Since we are starting with the BASIC bundle, (that does
+ // not include URL_FILTER), we don't yet have the URL_FILTER
+ // memento in which to store the level.
+ SubscriberUser su = createUser(id, name, mac, level);
+ userMap.put(id, su);
+ sb.append(String.format("\n..cache user %s [%d], %s, %s",
+ name, id, mac, level));
+ }
+ log.info(sb.toString());
+ }
+
+ private SubscriberUser createUser(int uid, String name, String mac,
+ String level) {
+ SubscriberUser user = new SubscriberUser(uid, name, mac, level);
+ for (XosFunction f: currentBundle.functions()) {
+ user.setMemento(f.descriptor(), f.createMemento());
+ }
+ return user;
+ }
+
+ /**
+ * Returns the currently selected bundle.
+ *
+ * @return current bundle
+ */
+ public Bundle getCurrentBundle() {
+ return currentBundle;
+ }
+
+ /**
+ * Sets a new bundle.
+ *
+ * @param bundleId bundle identifier
+ * @throws IllegalArgumentException if bundle ID is unknown
+ */
+ public void setCurrentBundle(String bundleId) {
+ log.info("set new bundle : {}", bundleId);
+ BundleDescriptor bd = BundleFactory.bundleFromId(bundleId);
+ currentBundle = new Bundle(bd);
+ // update the user mementos
+ for (SubscriberUser user: userMap.values()) {
+ user.clearMementos();
+ for (XosFunction f: currentBundle.functions()) {
+ user.setMemento(f.descriptor(), f.createMemento());
+ if (f.descriptor().equals(URL_FILTER)) {
+ applyUrlFilterLevel(user, user.urlFilterLevel());
+ }
+ }
+ }
+
+ XosManager.INSTANCE.setNewBundle(currentBundle);
+ }
+
+
+ /**
+ * Returns the list of current users for this subscriber account.
+ *
+ * @return the list of users
+ */
+ public List<SubscriberUser> getUsers() {
+ return ImmutableList.copyOf(userMap.values());
+ }
+
+ /**
+ * Applies a function parameter change for a user, pushing that
+ * change through to XOS.
+ *
+ * @param userId user identifier
+ * @param funcId function identifier
+ * @param param function parameter to change
+ * @param value new value for function parameter
+ */
+ public void applyPerUserParam(String userId, String funcId,
+ String param, String value) {
+
+ int uid = Integer.parseInt(userId);
+ SubscriberUser user = userMap.get(uid);
+ checkNotNull(user, "unknown user id: " + uid);
+
+ XosFunctionDescriptor xfd =
+ XosFunctionDescriptor.valueOf(funcId.toUpperCase());
+
+ XosFunction func = currentBundle.findFunction(xfd);
+ checkNotNull(func, "function not part of bundle: " + funcId);
+ applyParam(func, user, param, value, true);
+ }
+
+ // =============
+
+ private void applyUrlFilterLevel(SubscriberUser user, String level) {
+ XosFunction urlFilter = currentBundle.findFunction(URL_FILTER);
+ if (urlFilter != null) {
+ applyParam(urlFilter, user, LEVEL, level, false);
+ }
+ }
+
+ private void applyParam(XosFunction func, SubscriberUser user,
+ String param, String value, boolean punchThrough) {
+ func.applyParam(user, param, value);
+ if (punchThrough) {
+ XosManager.INSTANCE.apply(func, user);
+ }
+ }
+
+ private ArrayNode userJsonArray() {
+ ArrayNode userList = arrayNode();
+ for (SubscriberUser user: userMap.values()) {
+ userList.add(UserFactory.toObjectNode(user));
+ }
+ return userList;
+ }
+
+ // ============= generate JSON for GUI rest calls..
+
+ private void addSubId(ObjectNode root) {
+ root.put(SUB_ID, subscriberId);
+ root.put(SSID, ssid);
+ root.put(EMAIL, email);
+ }
+
+
+ /**
+ * Returns response JSON for login request.
+ * <p>
+ * Depending on which email is used, will bind the GUI to the
+ * appropriate XOS Subscriber ID.
+ *
+ * @param email the supplied email
+ * @return JSON acknowledgement
+ */
+ public synchronized String jsonLogin(String email) {
+ log.info("jsonLogin(\"{}\")", email);
+ init(email);
+ ObjectNode root = objectNode();
+ addSubId(root);
+ return root.toString();
+ }
+
+ /**
+ * Returns the dashboard page data as JSON.
+ *
+ * @return dashboard page JSON data
+ */
+ public synchronized String jsonDashboard() {
+ log.info("jsonDashboard()");
+
+ if (email == null) {
+ return jsonLogout();
+ }
+
+ BundleDescriptor bundleDescriptor = currentBundle.descriptor();
+ ObjectNode root = objectNode();
+ root.put(BUNDLE_NAME, bundleDescriptor.displayName());
+ root.put(BUNDLE_DESC, bundleDescriptor.description());
+ root.set(USERS, userJsonArray());
+ addSubId(root);
+ return root.toString();
+ }
+
+ /**
+ * Returns the bundle page data as JSON.
+ *
+ * @return bundle page JSON data
+ */
+ public synchronized String jsonBundle() {
+ log.info("jsonBundle()");
+
+ if (email == null) {
+ return jsonLogout();
+ }
+
+ ObjectNode root = BundleFactory.toObjectNode(currentBundle);
+ addSubId(root);
+ return root.toString();
+ }
+
+ /**
+ * Returns the users page data as JSON.
+ *
+ * @return users page JSON data
+ */
+ public synchronized String jsonUsers() {
+ log.info("jsonUsers()");
+
+ if (email == null) {
+ return jsonLogout();
+ }
+
+ ObjectNode root = objectNode();
+ root.set(USERS, userJsonArray());
+ addSubId(root);
+ return root.toString();
+ }
+
+ /**
+ * Returns logout acknowledgement as JSON.
+ *
+ * @return logout acknowledgement
+ */
+ public synchronized String jsonLogout() {
+ log.info("jsonLogout()");
+ ObjectNode root = objectNode().put(LOGOUT, true);
+ addSubId(root);
+
+ email = null; // signifies no one logged in
+
+ return root.toString();
+ }
+
+ /**
+ * Singleton instance.
+ */
+ public static final CordModelCache INSTANCE = new CordModelCache();
+}