Simon Hunt
Committed by Gerrit Code Review

CORD Subscriber GUI - Final wiring : we should be good for the demo.

Change-Id: Iad7444503bcce9e23556dcdc21f98088e6e10a5a
......@@ -17,6 +17,7 @@
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;
......@@ -34,6 +35,7 @@ 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.
......@@ -43,13 +45,7 @@ public class CordModelCache extends JsonFactory {
private static final String BUNDLE = "bundle";
private static final String USERS = "users";
private static final String SUB_ID = "subId";
// faked for the demo
private static final String MAC_1 = "010203040506";
private static final String MAC_2 = "010203040507";
private static final String MAC_3 = "010203040508";
private static final String MAC_4 = "010203040509";
private static final String LEVEL = "level";
private int subscriberId;
private Bundle currentBundle;
......@@ -59,26 +55,37 @@ public class CordModelCache extends JsonFactory {
new TreeMap<Integer, SubscriberUser>();
/**
* Constructs a model cache, initializing it with basic bundle.
* Constructs a model cache, (retrieving demo subscriber ID),
* initializing it with basic bundle, and fetching the list of users.
*/
CordModelCache() {
subscriberId = XosManager.INSTANCE.initDemoSubscriber();
currentBundle = new Bundle(BundleFactory.BASIC_BUNDLE);
subscriberId = XosManager.INSTANCE.getSubscriberId();
initUsers();
}
/**
* Used to initialize users for the demo. These are currently fake.
*/
@Deprecated
private void initUsers() {
userMap.put(1, createUser(1, "Mom's MacBook", MAC_1));
userMap.put(2, createUser(2, "Dad's iPad", MAC_2));
userMap.put(3, createUser(3, "Dick's laptop", MAC_3));
userMap.put(4, createUser(4, "Jane's laptop", MAC_4));
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);
}
}
private SubscriberUser createUser(int uid, String name, String mac) {
SubscriberUser user = new SubscriberUser(uid, name, mac);
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());
}
......@@ -108,10 +115,13 @@ public class CordModelCache extends JsonFactory {
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(subscriberId, currentBundle);
XosManager.INSTANCE.setNewBundle(currentBundle);
}
......@@ -125,7 +135,8 @@ public class CordModelCache extends JsonFactory {
}
/**
* Applies a function parameter change for a user.
* Applies a function parameter change for a user, pushing that
* change through to XOS.
*
* @param userId user identifier
* @param funcId function identifier
......@@ -144,13 +155,26 @@ public class CordModelCache extends JsonFactory {
XosFunction func = currentBundle.findFunction(xfd);
checkNotNull(func, "function not part of bundle: " + funcId);
func.applyParam(user, param, value);
XosManager.INSTANCE.apply(subscriberId, func, user);
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()) {
......
......@@ -40,66 +40,83 @@ public class XosManager {
private static final String TEST_XOS_SERVER_ADDRESS = "10.254.1.22";
private static final int TEST_XOS_SERVER_PORT = 8000;
private static final String URI_BASE = "/rs/subscriber/";
private static final String URI_RS = "/rs/";
private static final String URI_SUBSCRIBER = "/rs/subscriber/%d/";
private final XosManagerRestUtils xosUtils =
private final XosManagerRestUtils xosUtilsRs =
new XosManagerRestUtils(TEST_XOS_SERVER_ADDRESS,
TEST_XOS_SERVER_PORT, URI_BASE);
TEST_XOS_SERVER_PORT, URI_RS);
private XosManagerRestUtils xosUtils;
private final Logger log = LoggerFactory.getLogger(getClass());
private int demoId;
/**
* No instantiation (except via unit test).
*/
XosManager() {}
/**
* Returns the subscriber ID to use for calls to the XOS backend.
* Right now, this is implemented to get a list of all subscribers
* in the system and return the first one.
*
* @return subscriber ID
* Queries XOS for the Demo Subscriber ID and caches it for future calls.
*/
public int getSubscriberId() {
log.info("getSubscriberId() called");
String result = xosUtils.getRest();
public int initDemoSubscriber() {
log.info("intDemoSubscriber() called");
String result = xosUtilsRs.getRest("initdemo/");
log.info("from XOS: {}", result);
JsonNode node;
try {
node = MAPPER.readTree(result);
} catch (IOException e) {
log.error("failed to read subscriber JSON", e);
log.error("failed to read demo subscriber JSON", e);
return 0;
}
ArrayNode subscribers = (ArrayNode) node.get("subscribers");
if (subscribers.size() == 0) {
log.error("no subscribers found");
return 0;
}
ObjectNode obj = (ObjectNode) node;
demoId = obj.get("id").asInt();
log.info("Using DEMO subscriber ID {}.", demoId);
ObjectNode first = (ObjectNode) subscribers.get(0);
int id = first.get("id").asInt();
log.info("Using subscriber id {}.", id);
return id;
String uri = String.format(URI_SUBSCRIBER, demoId);
xosUtils = new XosManagerRestUtils(TEST_XOS_SERVER_ADDRESS,
TEST_XOS_SERVER_PORT, uri);
return demoId;
}
/**
* Returns the array of users for the subscriber.
*
* @return list of users
*/
public ArrayNode getUserList() {
log.info("getUserList() called");
String result = xosUtils.getRest("users/");
JsonNode node;
try {
node = MAPPER.readTree(result);
} catch (IOException e) {
log.error("failed to read user list JSON", e);
return null;
}
private String subId(int subscriberId) {
return String.format("%d/", subscriberId);
ObjectNode obj = (ObjectNode) node;
return (ArrayNode) obj.get("users");
}
/**
* Configure XOS to enable the functions that compose the given bundle,
* and disable all the others, for the given subscriber.
*
* @param subscriberId subscriber identifier
* @param bundle new bundle to set
*/
public void setNewBundle(int subscriberId, Bundle bundle) {
public void setNewBundle(Bundle bundle) {
log.info("\n>> Set New Bundle : " + bundle.descriptor().id());
String uriFmt = subId(subscriberId) + "services/%s/%s";
String uriFmt = "services/%s/%s";
Set<XosFunctionDescriptor> inBundle = bundle.descriptor().functions();
for (XosFunctionDescriptor xfd: XosFunctionDescriptor.values()) {
// only process the functions that have a real back-end on XOS
......@@ -115,14 +132,13 @@ public class XosManager {
* Configure XOS with new setting for given user and function, for the
* given subscriber account.
*
* @param subscriberId subscriber identifier
* @param func specific XOS function
* @param user user (containing function state)
*/
public void apply(int subscriberId, XosFunction func, SubscriberUser user) {
public void apply(XosFunction func, SubscriberUser user) {
log.info("\n>> Apply : " + func + " for " + user);
String uriPrefix = subId(subscriberId) + "users/" + user.id() + "/";
String uriPrefix = "users/" + user.id() + "/";
String uri = uriPrefix + func.xosUrlApply(user);
String result = xosUtils.putRest(uri);
// TODO: convert JSON result to object and check (if we care)
......
......@@ -28,6 +28,10 @@ public class SubscriberUser {
private final String name;
private final String mac;
// this is "duplicated" in the URL_FILTER memento, but, oh well...
// -- the level, as returned from XOS, when we create this user object.
private String level;
private final Map<XosFunctionDescriptor, XosFunction.Memento> mementos =
new HashMap<XosFunctionDescriptor, XosFunction.Memento>();
......@@ -37,11 +41,13 @@ public class SubscriberUser {
* @param id internal identifier
* @param name display name
* @param mac MAC address of the associated device
* @param level URL filter level
*/
public SubscriberUser(int id, String name, String mac) {
public SubscriberUser(int id, String name, String mac, String level) {
this.id = id;
this.name = name;
this.mac = mac;
this.level = level;
}
/**
......@@ -72,6 +78,24 @@ public class SubscriberUser {
}
/**
* Returns the URL filter level.
*
* @return URL filter level
*/
public String urlFilterLevel() {
return level;
}
/**
* Sets the URL filter level.
*
* @param level URL filter level
*/
public void setUrlFilterLevel(String level) {
this.level = level;
}
/**
* Stores a memento for the given XOS function.
*
* @param f XOS function
......
......@@ -53,6 +53,10 @@ public class UrlFilterFunction extends DefaultXosFunction {
if (LEVEL.equals(param)) {
Level newLevel = Level.valueOf(value.toUpperCase());
ufMemo.setLevel(newLevel);
// Also store the (string version) of the level
// (not in the memento). Hackish, but that's how it is for now.
user.setUrlFilterLevel(value);
}
}
......
......@@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.onosproject.cord.gui.model.BundleFactory;
import org.onosproject.cord.gui.model.SubscriberUser;
......@@ -34,6 +35,7 @@ import static org.junit.Assert.assertTrue;
/**
* Unit tests for {@link CordModelCache}.
*/
@Ignore("How to test against a live XOS system??")
public class CoreModelCacheTest {
private CordModelCache cache;
......
......@@ -28,7 +28,7 @@ import static org.junit.Assert.assertTrue;
*/
public class UrlFilterFunctionTest {
private SubscriberUser user = new SubscriberUser(1, "foo", "fooMAC");
private SubscriberUser user = new SubscriberUser(1, "foo", "fooMAC", "levelX");
private UrlFilterFunction fn;
@Before
......