diff options
author | Ashlee Young <ashlee@onosfw.com> | 2015-09-09 22:15:21 -0700 |
---|---|---|
committer | Ashlee Young <ashlee@onosfw.com> | 2015-09-09 22:15:21 -0700 |
commit | 13d05bc8458758ee39cb829098241e89616717ee (patch) | |
tree | 22a4d1ce65f15952f07a3df5af4b462b4697cb3a /framework/src/onos/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/CordModelCache.java | |
parent | 6139282e1e93c2322076de4b91b1c85d0bc4a8b3 (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.java | 382 |
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(); +} |