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 @@ ...@@ -17,6 +17,7 @@
17 17
18 package org.onosproject.cord.gui; 18 package org.onosproject.cord.gui;
19 19
20 +import com.fasterxml.jackson.databind.JsonNode;
20 import com.fasterxml.jackson.databind.node.ArrayNode; 21 import com.fasterxml.jackson.databind.node.ArrayNode;
21 import com.fasterxml.jackson.databind.node.ObjectNode; 22 import com.fasterxml.jackson.databind.node.ObjectNode;
22 import com.google.common.collect.ImmutableList; 23 import com.google.common.collect.ImmutableList;
...@@ -34,6 +35,7 @@ import java.util.Map; ...@@ -34,6 +35,7 @@ import java.util.Map;
34 import java.util.TreeMap; 35 import java.util.TreeMap;
35 36
36 import static com.google.common.base.Preconditions.checkNotNull; 37 import static com.google.common.base.Preconditions.checkNotNull;
38 +import static org.onosproject.cord.gui.model.XosFunctionDescriptor.URL_FILTER;
37 39
38 /** 40 /**
39 * In memory cache of the model of the subscriber's account. 41 * In memory cache of the model of the subscriber's account.
...@@ -43,13 +45,7 @@ public class CordModelCache extends JsonFactory { ...@@ -43,13 +45,7 @@ public class CordModelCache extends JsonFactory {
43 private static final String BUNDLE = "bundle"; 45 private static final String BUNDLE = "bundle";
44 private static final String USERS = "users"; 46 private static final String USERS = "users";
45 private static final String SUB_ID = "subId"; 47 private static final String SUB_ID = "subId";
46 - 48 + private static final String LEVEL = "level";
47 -
48 - // faked for the demo
49 - private static final String MAC_1 = "010203040506";
50 - private static final String MAC_2 = "010203040507";
51 - private static final String MAC_3 = "010203040508";
52 - private static final String MAC_4 = "010203040509";
53 49
54 private int subscriberId; 50 private int subscriberId;
55 private Bundle currentBundle; 51 private Bundle currentBundle;
...@@ -59,26 +55,37 @@ public class CordModelCache extends JsonFactory { ...@@ -59,26 +55,37 @@ public class CordModelCache extends JsonFactory {
59 new TreeMap<Integer, SubscriberUser>(); 55 new TreeMap<Integer, SubscriberUser>();
60 56
61 /** 57 /**
62 - * Constructs a model cache, initializing it with basic bundle. 58 + * Constructs a model cache, (retrieving demo subscriber ID),
59 + * initializing it with basic bundle, and fetching the list of users.
63 */ 60 */
64 CordModelCache() { 61 CordModelCache() {
62 + subscriberId = XosManager.INSTANCE.initDemoSubscriber();
65 currentBundle = new Bundle(BundleFactory.BASIC_BUNDLE); 63 currentBundle = new Bundle(BundleFactory.BASIC_BUNDLE);
66 - subscriberId = XosManager.INSTANCE.getSubscriberId(); 64 + initUsers();
67 } 65 }
68 66
69 - /**
70 - * Used to initialize users for the demo. These are currently fake.
71 - */
72 - @Deprecated
73 private void initUsers() { 67 private void initUsers() {
74 - userMap.put(1, createUser(1, "Mom's MacBook", MAC_1)); 68 + ArrayNode users = XosManager.INSTANCE.getUserList();
75 - userMap.put(2, createUser(2, "Dad's iPad", MAC_2)); 69 + for (JsonNode u: users) {
76 - userMap.put(3, createUser(3, "Dick's laptop", MAC_3)); 70 + ObjectNode user = (ObjectNode) u;
77 - userMap.put(4, createUser(4, "Jane's laptop", MAC_4)); 71 +
72 + int id = user.get("id").asInt();
73 + String name = user.get("name").asText();
74 + String mac = user.get("mac").asText();
75 + String level = user.get("level").asText();
76 +
77 + // NOTE: We are just storing the current "url-filter" level.
78 + // Since we are starting with the BASIC bundle, (that does
79 + // not include URL_FILTER), we don't yet have the URL_FILTER
80 + // memento in which to store the level.
81 + SubscriberUser su = createUser(id, name, mac, level);
82 + userMap.put(id, su);
83 + }
78 } 84 }
79 85
80 - private SubscriberUser createUser(int uid, String name, String mac) { 86 + private SubscriberUser createUser(int uid, String name, String mac,
81 - SubscriberUser user = new SubscriberUser(uid, name, mac); 87 + String level) {
88 + SubscriberUser user = new SubscriberUser(uid, name, mac, level);
82 for (XosFunction f: currentBundle.functions()) { 89 for (XosFunction f: currentBundle.functions()) {
83 user.setMemento(f.descriptor(), f.createMemento()); 90 user.setMemento(f.descriptor(), f.createMemento());
84 } 91 }
...@@ -108,10 +115,13 @@ public class CordModelCache extends JsonFactory { ...@@ -108,10 +115,13 @@ public class CordModelCache extends JsonFactory {
108 user.clearMementos(); 115 user.clearMementos();
109 for (XosFunction f: currentBundle.functions()) { 116 for (XosFunction f: currentBundle.functions()) {
110 user.setMemento(f.descriptor(), f.createMemento()); 117 user.setMemento(f.descriptor(), f.createMemento());
118 + if (f.descriptor().equals(URL_FILTER)) {
119 + applyUrlFilterLevel(user, user.urlFilterLevel());
120 + }
111 } 121 }
112 } 122 }
113 123
114 - XosManager.INSTANCE.setNewBundle(subscriberId, currentBundle); 124 + XosManager.INSTANCE.setNewBundle(currentBundle);
115 } 125 }
116 126
117 127
...@@ -125,7 +135,8 @@ public class CordModelCache extends JsonFactory { ...@@ -125,7 +135,8 @@ public class CordModelCache extends JsonFactory {
125 } 135 }
126 136
127 /** 137 /**
128 - * Applies a function parameter change for a user. 138 + * Applies a function parameter change for a user, pushing that
139 + * change through to XOS.
129 * 140 *
130 * @param userId user identifier 141 * @param userId user identifier
131 * @param funcId function identifier 142 * @param funcId function identifier
...@@ -144,13 +155,26 @@ public class CordModelCache extends JsonFactory { ...@@ -144,13 +155,26 @@ public class CordModelCache extends JsonFactory {
144 155
145 XosFunction func = currentBundle.findFunction(xfd); 156 XosFunction func = currentBundle.findFunction(xfd);
146 checkNotNull(func, "function not part of bundle: " + funcId); 157 checkNotNull(func, "function not part of bundle: " + funcId);
147 - 158 + applyParam(func, user, param, value, true);
148 - func.applyParam(user, param, value);
149 - XosManager.INSTANCE.apply(subscriberId, func, user);
150 } 159 }
151 160
152 // ============= 161 // =============
153 162
163 + private void applyUrlFilterLevel(SubscriberUser user, String level) {
164 + XosFunction urlFilter = currentBundle.findFunction(URL_FILTER);
165 + if (urlFilter != null) {
166 + applyParam(urlFilter, user, LEVEL, level, false);
167 + }
168 + }
169 +
170 + private void applyParam(XosFunction func, SubscriberUser user,
171 + String param, String value, boolean punchThrough) {
172 + func.applyParam(user, param, value);
173 + if (punchThrough) {
174 + XosManager.INSTANCE.apply(func, user);
175 + }
176 + }
177 +
154 private ArrayNode userJsonArray() { 178 private ArrayNode userJsonArray() {
155 ArrayNode userList = arrayNode(); 179 ArrayNode userList = arrayNode();
156 for (SubscriberUser user: userMap.values()) { 180 for (SubscriberUser user: userMap.values()) {
......
...@@ -40,66 +40,83 @@ public class XosManager { ...@@ -40,66 +40,83 @@ public class XosManager {
40 40
41 private static final String TEST_XOS_SERVER_ADDRESS = "10.254.1.22"; 41 private static final String TEST_XOS_SERVER_ADDRESS = "10.254.1.22";
42 private static final int TEST_XOS_SERVER_PORT = 8000; 42 private static final int TEST_XOS_SERVER_PORT = 8000;
43 - private static final String URI_BASE = "/rs/subscriber/"; 43 + private static final String URI_RS = "/rs/";
44 + private static final String URI_SUBSCRIBER = "/rs/subscriber/%d/";
44 45
45 - private final XosManagerRestUtils xosUtils = 46 + private final XosManagerRestUtils xosUtilsRs =
46 new XosManagerRestUtils(TEST_XOS_SERVER_ADDRESS, 47 new XosManagerRestUtils(TEST_XOS_SERVER_ADDRESS,
47 - TEST_XOS_SERVER_PORT, URI_BASE); 48 + TEST_XOS_SERVER_PORT, URI_RS);
49 +
50 + private XosManagerRestUtils xosUtils;
51 +
52 +
48 private final Logger log = LoggerFactory.getLogger(getClass()); 53 private final Logger log = LoggerFactory.getLogger(getClass());
49 54
55 + private int demoId;
56 +
50 /** 57 /**
51 * No instantiation (except via unit test). 58 * No instantiation (except via unit test).
52 */ 59 */
53 XosManager() {} 60 XosManager() {}
54 61
55 /** 62 /**
56 - * Returns the subscriber ID to use for calls to the XOS backend. 63 + * Queries XOS for the Demo Subscriber ID and caches it for future calls.
57 - * Right now, this is implemented to get a list of all subscribers
58 - * in the system and return the first one.
59 - *
60 - * @return subscriber ID
61 */ 64 */
62 - public int getSubscriberId() { 65 + public int initDemoSubscriber() {
63 - log.info("getSubscriberId() called"); 66 + log.info("intDemoSubscriber() called");
64 - String result = xosUtils.getRest(); 67 + String result = xosUtilsRs.getRest("initdemo/");
65 log.info("from XOS: {}", result); 68 log.info("from XOS: {}", result);
66 69
67 JsonNode node; 70 JsonNode node;
68 try { 71 try {
69 node = MAPPER.readTree(result); 72 node = MAPPER.readTree(result);
70 } catch (IOException e) { 73 } catch (IOException e) {
71 - log.error("failed to read subscriber JSON", e); 74 + log.error("failed to read demo subscriber JSON", e);
72 return 0; 75 return 0;
73 } 76 }
74 77
75 - ArrayNode subscribers = (ArrayNode) node.get("subscribers"); 78 + ObjectNode obj = (ObjectNode) node;
76 - if (subscribers.size() == 0) { 79 + demoId = obj.get("id").asInt();
77 - log.error("no subscribers found"); 80 + log.info("Using DEMO subscriber ID {}.", demoId);
78 - return 0;
79 - }
80 81
81 - ObjectNode first = (ObjectNode) subscribers.get(0); 82 + String uri = String.format(URI_SUBSCRIBER, demoId);
82 - int id = first.get("id").asInt(); 83 + xosUtils = new XosManagerRestUtils(TEST_XOS_SERVER_ADDRESS,
83 - log.info("Using subscriber id {}.", id); 84 + TEST_XOS_SERVER_PORT, uri);
84 - return id; 85 + return demoId;
85 } 86 }
86 87
88 + /**
89 + * Returns the array of users for the subscriber.
90 + *
91 + * @return list of users
92 + */
93 + public ArrayNode getUserList() {
94 + log.info("getUserList() called");
95 + String result = xosUtils.getRest("users/");
96 +
97 + JsonNode node;
98 + try {
99 + node = MAPPER.readTree(result);
100 + } catch (IOException e) {
101 + log.error("failed to read user list JSON", e);
102 + return null;
103 + }
87 104
88 - private String subId(int subscriberId) { 105 + ObjectNode obj = (ObjectNode) node;
89 - return String.format("%d/", subscriberId); 106 + return (ArrayNode) obj.get("users");
90 } 107 }
91 108
109 +
92 /** 110 /**
93 * Configure XOS to enable the functions that compose the given bundle, 111 * Configure XOS to enable the functions that compose the given bundle,
94 * and disable all the others, for the given subscriber. 112 * and disable all the others, for the given subscriber.
95 * 113 *
96 - * @param subscriberId subscriber identifier
97 * @param bundle new bundle to set 114 * @param bundle new bundle to set
98 */ 115 */
99 - public void setNewBundle(int subscriberId, Bundle bundle) { 116 + public void setNewBundle(Bundle bundle) {
100 log.info("\n>> Set New Bundle : " + bundle.descriptor().id()); 117 log.info("\n>> Set New Bundle : " + bundle.descriptor().id());
101 118
102 - String uriFmt = subId(subscriberId) + "services/%s/%s"; 119 + String uriFmt = "services/%s/%s";
103 Set<XosFunctionDescriptor> inBundle = bundle.descriptor().functions(); 120 Set<XosFunctionDescriptor> inBundle = bundle.descriptor().functions();
104 for (XosFunctionDescriptor xfd: XosFunctionDescriptor.values()) { 121 for (XosFunctionDescriptor xfd: XosFunctionDescriptor.values()) {
105 // only process the functions that have a real back-end on XOS 122 // only process the functions that have a real back-end on XOS
...@@ -115,14 +132,13 @@ public class XosManager { ...@@ -115,14 +132,13 @@ public class XosManager {
115 * Configure XOS with new setting for given user and function, for the 132 * Configure XOS with new setting for given user and function, for the
116 * given subscriber account. 133 * given subscriber account.
117 * 134 *
118 - * @param subscriberId subscriber identifier
119 * @param func specific XOS function 135 * @param func specific XOS function
120 * @param user user (containing function state) 136 * @param user user (containing function state)
121 */ 137 */
122 - public void apply(int subscriberId, XosFunction func, SubscriberUser user) { 138 + public void apply(XosFunction func, SubscriberUser user) {
123 log.info("\n>> Apply : " + func + " for " + user); 139 log.info("\n>> Apply : " + func + " for " + user);
124 140
125 - String uriPrefix = subId(subscriberId) + "users/" + user.id() + "/"; 141 + String uriPrefix = "users/" + user.id() + "/";
126 String uri = uriPrefix + func.xosUrlApply(user); 142 String uri = uriPrefix + func.xosUrlApply(user);
127 String result = xosUtils.putRest(uri); 143 String result = xosUtils.putRest(uri);
128 // TODO: convert JSON result to object and check (if we care) 144 // TODO: convert JSON result to object and check (if we care)
......
...@@ -28,6 +28,10 @@ public class SubscriberUser { ...@@ -28,6 +28,10 @@ public class SubscriberUser {
28 private final String name; 28 private final String name;
29 private final String mac; 29 private final String mac;
30 30
31 + // this is "duplicated" in the URL_FILTER memento, but, oh well...
32 + // -- the level, as returned from XOS, when we create this user object.
33 + private String level;
34 +
31 private final Map<XosFunctionDescriptor, XosFunction.Memento> mementos = 35 private final Map<XosFunctionDescriptor, XosFunction.Memento> mementos =
32 new HashMap<XosFunctionDescriptor, XosFunction.Memento>(); 36 new HashMap<XosFunctionDescriptor, XosFunction.Memento>();
33 37
...@@ -37,11 +41,13 @@ public class SubscriberUser { ...@@ -37,11 +41,13 @@ public class SubscriberUser {
37 * @param id internal identifier 41 * @param id internal identifier
38 * @param name display name 42 * @param name display name
39 * @param mac MAC address of the associated device 43 * @param mac MAC address of the associated device
44 + * @param level URL filter level
40 */ 45 */
41 - public SubscriberUser(int id, String name, String mac) { 46 + public SubscriberUser(int id, String name, String mac, String level) {
42 this.id = id; 47 this.id = id;
43 this.name = name; 48 this.name = name;
44 this.mac = mac; 49 this.mac = mac;
50 + this.level = level;
45 } 51 }
46 52
47 /** 53 /**
...@@ -72,6 +78,24 @@ public class SubscriberUser { ...@@ -72,6 +78,24 @@ public class SubscriberUser {
72 } 78 }
73 79
74 /** 80 /**
81 + * Returns the URL filter level.
82 + *
83 + * @return URL filter level
84 + */
85 + public String urlFilterLevel() {
86 + return level;
87 + }
88 +
89 + /**
90 + * Sets the URL filter level.
91 + *
92 + * @param level URL filter level
93 + */
94 + public void setUrlFilterLevel(String level) {
95 + this.level = level;
96 + }
97 +
98 + /**
75 * Stores a memento for the given XOS function. 99 * Stores a memento for the given XOS function.
76 * 100 *
77 * @param f XOS function 101 * @param f XOS function
......
...@@ -53,6 +53,10 @@ public class UrlFilterFunction extends DefaultXosFunction { ...@@ -53,6 +53,10 @@ public class UrlFilterFunction extends DefaultXosFunction {
53 if (LEVEL.equals(param)) { 53 if (LEVEL.equals(param)) {
54 Level newLevel = Level.valueOf(value.toUpperCase()); 54 Level newLevel = Level.valueOf(value.toUpperCase());
55 ufMemo.setLevel(newLevel); 55 ufMemo.setLevel(newLevel);
56 +
57 + // Also store the (string version) of the level
58 + // (not in the memento). Hackish, but that's how it is for now.
59 + user.setUrlFilterLevel(value);
56 } 60 }
57 } 61 }
58 62
......
...@@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.JsonNode; ...@@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.JsonNode;
21 import com.fasterxml.jackson.databind.ObjectMapper; 21 import com.fasterxml.jackson.databind.ObjectMapper;
22 import com.fasterxml.jackson.databind.node.ObjectNode; 22 import com.fasterxml.jackson.databind.node.ObjectNode;
23 import org.junit.Before; 23 import org.junit.Before;
24 +import org.junit.Ignore;
24 import org.junit.Test; 25 import org.junit.Test;
25 import org.onosproject.cord.gui.model.BundleFactory; 26 import org.onosproject.cord.gui.model.BundleFactory;
26 import org.onosproject.cord.gui.model.SubscriberUser; 27 import org.onosproject.cord.gui.model.SubscriberUser;
...@@ -34,6 +35,7 @@ import static org.junit.Assert.assertTrue; ...@@ -34,6 +35,7 @@ import static org.junit.Assert.assertTrue;
34 /** 35 /**
35 * Unit tests for {@link CordModelCache}. 36 * Unit tests for {@link CordModelCache}.
36 */ 37 */
38 +@Ignore("How to test against a live XOS system??")
37 public class CoreModelCacheTest { 39 public class CoreModelCacheTest {
38 40
39 private CordModelCache cache; 41 private CordModelCache cache;
......
...@@ -28,7 +28,7 @@ import static org.junit.Assert.assertTrue; ...@@ -28,7 +28,7 @@ import static org.junit.Assert.assertTrue;
28 */ 28 */
29 public class UrlFilterFunctionTest { 29 public class UrlFilterFunctionTest {
30 30
31 - private SubscriberUser user = new SubscriberUser(1, "foo", "fooMAC"); 31 + private SubscriberUser user = new SubscriberUser(1, "foo", "fooMAC", "levelX");
32 private UrlFilterFunction fn; 32 private UrlFilterFunction fn;
33 33
34 @Before 34 @Before
......