blob: 789737b0c630dfcc8e7ff360a37fc930845e329f [file] [log] [blame]
/*
* 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.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 BUNDLE = "bundle";
private static final String USERS = "users";
private static final String SUB_ID = "subId";
private static final String LEVEL = "level";
private int subscriberId;
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 demo subscriber ID),
* initializing it with basic bundle, and fetching the list of users.
*/
CordModelCache() {
log.info("Initialize model cache");
subscriberId = XosManager.INSTANCE.initDemoSubscriber();
currentBundle = new Bundle(BundleFactory.BASIC_BUNDLE);
initUsers();
}
private void initUsers() {
ArrayNode users = XosManager.INSTANCE.getUserList();
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);
log.info("..caching user {} (id:{})", name, id);
}
}
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);
}
/**
* Returns the dashboard page data as JSON.
*
* @return dashboard page JSON data
*/
public String jsonDashboard() {
ObjectNode root = objectNode();
root.put(BUNDLE, currentBundle.descriptor().displayName());
root.set(USERS, userJsonArray());
addSubId(root);
return root.toString();
}
/**
* Returns the bundle page data as JSON.
*
* @return bundle page JSON data
*/
public String jsonBundle() {
ObjectNode root = BundleFactory.toObjectNode(currentBundle);
addSubId(root);
return root.toString();
}
/**
* Returns the users page data as JSON.
*
* @return users page JSON data
*/
public String jsonUsers() {
ObjectNode root = objectNode();
root.set(USERS, userJsonArray());
addSubId(root);
return root.toString();
}
/**
* Singleton instance.
*/
public static final CordModelCache INSTANCE = new CordModelCache();
}