Jonathan Hart
Committed by Gerrit Code Review

Add optional "name" parameter in interface configuration.

Interfaces can now be added and deleted by name. Interfaces without names
cannot be updated or deleted.

Change-Id: Icb2188b1c9abf3017724f751a93457920a53ba03
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
17 package org.onosproject.cli.net; 17 package org.onosproject.cli.net;
18 18
19 import com.google.common.collect.Sets; 19 import com.google.common.collect.Sets;
20 +import org.apache.karaf.shell.commands.Argument;
20 import org.apache.karaf.shell.commands.Command; 21 import org.apache.karaf.shell.commands.Command;
21 import org.apache.karaf.shell.commands.Option; 22 import org.apache.karaf.shell.commands.Option;
22 import org.onlab.packet.MacAddress; 23 import org.onlab.packet.MacAddress;
...@@ -36,11 +37,15 @@ import java.util.Set; ...@@ -36,11 +37,15 @@ import java.util.Set;
36 description = "Adds a new configured interface") 37 description = "Adds a new configured interface")
37 public class InterfaceAddCommand extends AbstractShellCommand { 38 public class InterfaceAddCommand extends AbstractShellCommand {
38 39
39 - @Option(name = "-c", aliases = "--connectPoint", 40 + @Argument(index = 0, name = "port",
40 description = "Device port that the interface is associated with", 41 description = "Device port that the interface is associated with",
41 required = true, multiValued = false) 42 required = true, multiValued = false)
42 private String connectPoint = null; 43 private String connectPoint = null;
43 44
45 + @Argument(index = 1, name = "name", description = "Interface name",
46 + required = true, multiValued = false)
47 + private String name = null;
48 +
44 @Option(name = "-m", aliases = "--mac", 49 @Option(name = "-m", aliases = "--mac",
45 description = "MAC address of the interface", 50 description = "MAC address of the interface",
46 required = false, multiValued = false) 51 required = false, multiValued = false)
...@@ -72,10 +77,13 @@ public class InterfaceAddCommand extends AbstractShellCommand { ...@@ -72,10 +77,13 @@ public class InterfaceAddCommand extends AbstractShellCommand {
72 77
73 VlanId vlanId = vlan == null ? VlanId.NONE : VlanId.vlanId(Short.parseShort(vlan)); 78 VlanId vlanId = vlan == null ? VlanId.NONE : VlanId.vlanId(Short.parseShort(vlan));
74 79
75 - Interface intf = new Interface(ConnectPoint.deviceConnectPoint(connectPoint), 80 + Interface intf = new Interface(name,
81 + ConnectPoint.deviceConnectPoint(connectPoint),
76 ipAddresses, macAddr, vlanId); 82 ipAddresses, macAddr, vlanId);
77 83
78 interfaceService.add(intf); 84 interfaceService.add(intf);
85 +
86 + print("Interface added");
79 } 87 }
80 88
81 } 89 }
......
...@@ -18,7 +18,6 @@ package org.onosproject.cli.net; ...@@ -18,7 +18,6 @@ package org.onosproject.cli.net;
18 18
19 import org.apache.karaf.shell.commands.Argument; 19 import org.apache.karaf.shell.commands.Argument;
20 import org.apache.karaf.shell.commands.Command; 20 import org.apache.karaf.shell.commands.Command;
21 -import org.onlab.packet.VlanId;
22 import org.onosproject.cli.AbstractShellCommand; 21 import org.onosproject.cli.AbstractShellCommand;
23 import org.onosproject.incubator.net.intf.InterfaceAdminService; 22 import org.onosproject.incubator.net.intf.InterfaceAdminService;
24 import org.onosproject.net.ConnectPoint; 23 import org.onosproject.net.ConnectPoint;
...@@ -35,17 +34,23 @@ public class InterfaceRemoveCommand extends AbstractShellCommand { ...@@ -35,17 +34,23 @@ public class InterfaceRemoveCommand extends AbstractShellCommand {
35 required = true, multiValued = false) 34 required = true, multiValued = false)
36 private String connectPoint = null; 35 private String connectPoint = null;
37 36
38 - @Argument(index = 1, name = "vlan", 37 + @Argument(index = 1, name = "name",
39 - description = "Interface vlan", 38 + description = "Interface name",
40 required = true, multiValued = false) 39 required = true, multiValued = false)
41 - private String vlan = null; 40 + private String name = null;
42 41
43 @Override 42 @Override
44 protected void execute() { 43 protected void execute() {
45 InterfaceAdminService interfaceService = get(InterfaceAdminService.class); 44 InterfaceAdminService interfaceService = get(InterfaceAdminService.class);
46 45
47 - interfaceService.remove(ConnectPoint.deviceConnectPoint(connectPoint), 46 + boolean success = interfaceService.remove(
48 - VlanId.vlanId(Short.parseShort(vlan))); 47 + ConnectPoint.deviceConnectPoint(connectPoint), name);
48 +
49 + if (success) {
50 + print("Interface removed");
51 + } else {
52 + print("Unable to remove interface");
53 + }
49 } 54 }
50 55
51 } 56 }
......
...@@ -35,6 +35,9 @@ public class InterfacesListCommand extends AbstractShellCommand { ...@@ -35,6 +35,9 @@ public class InterfacesListCommand extends AbstractShellCommand {
35 private static final String FORMAT = 35 private static final String FORMAT =
36 "port=%s/%s, ips=%s, mac=%s, vlan=%s"; 36 "port=%s/%s, ips=%s, mac=%s, vlan=%s";
37 37
38 + private static final String NAME_FORMAT =
39 + "%s: port=%s/%s, ips=%s, mac=%s, vlan=%s";
40 +
38 @Override 41 @Override
39 protected void execute() { 42 protected void execute() {
40 InterfaceService interfaceService = get(InterfaceService.class); 43 InterfaceService interfaceService = get(InterfaceService.class);
...@@ -44,8 +47,14 @@ public class InterfacesListCommand extends AbstractShellCommand { ...@@ -44,8 +47,14 @@ public class InterfacesListCommand extends AbstractShellCommand {
44 Collections.sort(interfaces, Comparators.INTERFACES_COMPARATOR); 47 Collections.sort(interfaces, Comparators.INTERFACES_COMPARATOR);
45 48
46 for (Interface intf : interfaces) { 49 for (Interface intf : interfaces) {
50 + if (intf.name().equals(Interface.NO_INTERFACE_NAME)) {
47 print(FORMAT, intf.connectPoint().deviceId(), intf.connectPoint().port(), 51 print(FORMAT, intf.connectPoint().deviceId(), intf.connectPoint().port(),
48 intf.ipAddresses(), intf.mac(), intf.vlan()); 52 intf.ipAddresses(), intf.mac(), intf.vlan());
53 + } else {
54 + print(NAME_FORMAT, intf.name(), intf.connectPoint().deviceId(),
55 + intf.connectPoint().port(), intf.ipAddresses(),
56 + intf.mac(), intf.vlan());
57 + }
49 } 58 }
50 } 59 }
51 60
......
...@@ -358,15 +358,16 @@ ...@@ -358,15 +358,16 @@
358 </command> 358 </command>
359 <command> 359 <command>
360 <action class="org.onosproject.cli.net.InterfaceAddCommand"/> 360 <action class="org.onosproject.cli.net.InterfaceAddCommand"/>
361 - <optional-completers> 361 + <completers>
362 - <entry key="-c" value-ref="connectPointCompleter"/> 362 + <ref component-id="connectPointCompleter" />
363 - <entry key="--connectPoint" value-ref="connectPointCompleter"/> 363 + <ref component-id="placeholderCompleter" />
364 - </optional-completers> 364 + </completers>
365 </command> 365 </command>
366 <command> 366 <command>
367 <action class="org.onosproject.cli.net.InterfaceRemoveCommand"/> 367 <action class="org.onosproject.cli.net.InterfaceRemoveCommand"/>
368 <completers> 368 <completers>
369 <ref component-id="connectPointCompleter"/> 369 <ref component-id="connectPointCompleter"/>
370 + <ref component-id="placeholderCompleter" />
370 </completers> 371 </completers>
371 </command> 372 </command>
372 <command> 373 <command>
...@@ -505,4 +506,6 @@ ...@@ -505,4 +506,6 @@
505 <bean id="upDownCompleter" class="org.onosproject.cli.UpDownCompleter"/> 506 <bean id="upDownCompleter" class="org.onosproject.cli.UpDownCompleter"/>
506 <bean id="encapTypeCompleter" class="org.onosproject.cli.net.EncapTypeCompleter"/> 507 <bean id="encapTypeCompleter" class="org.onosproject.cli.net.EncapTypeCompleter"/>
507 508
509 + <bean id="placeholderCompleter" class="org.onosproject.cli.PlaceholderCompleter"/>
510 +
508 </blueprint> 511 </blueprint>
......
...@@ -28,6 +28,7 @@ import org.onosproject.net.ConnectPoint; ...@@ -28,6 +28,7 @@ import org.onosproject.net.ConnectPoint;
28 import org.onosproject.net.config.Config; 28 import org.onosproject.net.config.Config;
29 import org.onosproject.net.host.InterfaceIpAddress; 29 import org.onosproject.net.host.InterfaceIpAddress;
30 30
31 +import java.util.Iterator;
31 import java.util.Set; 32 import java.util.Set;
32 33
33 /** 34 /**
...@@ -35,6 +36,7 @@ import java.util.Set; ...@@ -35,6 +36,7 @@ import java.util.Set;
35 */ 36 */
36 @Beta 37 @Beta
37 public class InterfaceConfig extends Config<ConnectPoint> { 38 public class InterfaceConfig extends Config<ConnectPoint> {
39 + public static final String NAME = "name";
38 public static final String IPS = "ips"; 40 public static final String IPS = "ips";
39 public static final String MAC = "mac"; 41 public static final String MAC = "mac";
40 public static final String VLAN = "vlan"; 42 public static final String VLAN = "vlan";
...@@ -52,6 +54,8 @@ public class InterfaceConfig extends Config<ConnectPoint> { ...@@ -52,6 +54,8 @@ public class InterfaceConfig extends Config<ConnectPoint> {
52 54
53 try { 55 try {
54 for (JsonNode intfNode : array) { 56 for (JsonNode intfNode : array) {
57 + String name = intfNode.path(NAME).asText(null);
58 +
55 Set<InterfaceIpAddress> ips = getIps(intfNode); 59 Set<InterfaceIpAddress> ips = getIps(intfNode);
56 60
57 String mac = intfNode.path(MAC).asText(); 61 String mac = intfNode.path(MAC).asText();
...@@ -59,7 +63,7 @@ public class InterfaceConfig extends Config<ConnectPoint> { ...@@ -59,7 +63,7 @@ public class InterfaceConfig extends Config<ConnectPoint> {
59 63
60 VlanId vlan = getVlan(intfNode); 64 VlanId vlan = getVlan(intfNode);
61 65
62 - interfaces.add(new Interface(subject, ips, macAddr, vlan)); 66 + interfaces.add(new Interface(name, subject, ips, macAddr, vlan));
63 } 67 }
64 } catch (IllegalArgumentException e) { 68 } catch (IllegalArgumentException e) {
65 throw new ConfigException(CONFIG_VALUE_ERROR, e); 69 throw new ConfigException(CONFIG_VALUE_ERROR, e);
...@@ -76,6 +80,8 @@ public class InterfaceConfig extends Config<ConnectPoint> { ...@@ -76,6 +80,8 @@ public class InterfaceConfig extends Config<ConnectPoint> {
76 public void addInterface(Interface intf) { 80 public void addInterface(Interface intf) {
77 ObjectNode intfNode = array.addObject(); 81 ObjectNode intfNode = array.addObject();
78 82
83 + intfNode.put(NAME, intf.name());
84 +
79 if (intf.mac() != null) { 85 if (intf.mac() != null) {
80 intfNode.put(MAC, intf.mac().toString()); 86 intfNode.put(MAC, intf.mac().toString());
81 } 87 }
...@@ -92,12 +98,14 @@ public class InterfaceConfig extends Config<ConnectPoint> { ...@@ -92,12 +98,14 @@ public class InterfaceConfig extends Config<ConnectPoint> {
92 /** 98 /**
93 * Removes an interface from the config. 99 * Removes an interface from the config.
94 * 100 *
95 - * @param intf interface to remove 101 + * @param name name of the interface to remove
96 */ 102 */
97 - public void removeInterface(Interface intf) { 103 + public void removeInterface(String name) {
98 - for (int i = 0; i < array.size(); i++) { 104 + Iterator<JsonNode> it = array.iterator();
99 - if (intf.vlan().equals(getVlan(node))) { 105 + while (it.hasNext()) {
100 - array.remove(i); 106 + JsonNode node = it.next();
107 + if (node.path(NAME).asText().equals(name)) {
108 + it.remove();
101 break; 109 break;
102 } 110 }
103 } 111 }
......
...@@ -30,11 +30,13 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -30,11 +30,13 @@ import static com.google.common.base.Preconditions.checkNotNull;
30 30
31 /** 31 /**
32 * An Interface maps network configuration information (such as addresses and 32 * An Interface maps network configuration information (such as addresses and
33 - * vlans) to a port in the network. This is considered a L2/L3 network 33 + * vlans) to a port in the network.
34 - * interface.
35 */ 34 */
36 @Beta 35 @Beta
37 public class Interface { 36 public class Interface {
37 + public static final String NO_INTERFACE_NAME = "";
38 +
39 + private final String name;
38 private final ConnectPoint connectPoint; 40 private final ConnectPoint connectPoint;
39 private final Set<InterfaceIpAddress> ipAddresses; 41 private final Set<InterfaceIpAddress> ipAddresses;
40 private final MacAddress macAddress; 42 private final MacAddress macAddress;
...@@ -43,14 +45,16 @@ public class Interface { ...@@ -43,14 +45,16 @@ public class Interface {
43 /** 45 /**
44 * Creates new Interface with the provided configuration. 46 * Creates new Interface with the provided configuration.
45 * 47 *
48 + * @param name name of the interface
46 * @param connectPoint the connect point this interface maps to 49 * @param connectPoint the connect point this interface maps to
47 * @param ipAddresses Set of IP addresses 50 * @param ipAddresses Set of IP addresses
48 * @param macAddress MAC address 51 * @param macAddress MAC address
49 * @param vlan VLAN ID 52 * @param vlan VLAN ID
50 */ 53 */
51 - public Interface(ConnectPoint connectPoint, 54 + public Interface(String name, ConnectPoint connectPoint,
52 Set<InterfaceIpAddress> ipAddresses, 55 Set<InterfaceIpAddress> ipAddresses,
53 MacAddress macAddress, VlanId vlan) { 56 MacAddress macAddress, VlanId vlan) {
57 + this.name = name == null ? NO_INTERFACE_NAME : name;
54 this.connectPoint = checkNotNull(connectPoint); 58 this.connectPoint = checkNotNull(connectPoint);
55 this.ipAddresses = ipAddresses == null ? Sets.newHashSet() : ipAddresses; 59 this.ipAddresses = ipAddresses == null ? Sets.newHashSet() : ipAddresses;
56 this.macAddress = macAddress == null ? MacAddress.NONE : macAddress; 60 this.macAddress = macAddress == null ? MacAddress.NONE : macAddress;
...@@ -58,6 +62,29 @@ public class Interface { ...@@ -58,6 +62,29 @@ public class Interface {
58 } 62 }
59 63
60 /** 64 /**
65 + * Creates new Interface with the provided configuration.
66 + *
67 + * @param connectPoint the connect point this interface maps to
68 + * @param ipAddresses Set of IP addresses
69 + * @param macAddress MAC address
70 + * @param vlan VLAN ID
71 + */
72 + public Interface(ConnectPoint connectPoint,
73 + Set<InterfaceIpAddress> ipAddresses,
74 + MacAddress macAddress, VlanId vlan) {
75 + this(NO_INTERFACE_NAME, connectPoint, ipAddresses, macAddress, vlan);
76 + }
77 +
78 + /**
79 + * Retrieves the name of the interface.
80 + *
81 + * @return name
82 + */
83 + public String name() {
84 + return name;
85 + }
86 +
87 + /**
61 * Retrieves the connection point that this interface maps to. 88 * Retrieves the connection point that this interface maps to.
62 * 89 *
63 * @return the connection point 90 * @return the connection point
...@@ -101,7 +128,8 @@ public class Interface { ...@@ -101,7 +128,8 @@ public class Interface {
101 128
102 Interface otherInterface = (Interface) other; 129 Interface otherInterface = (Interface) other;
103 130
104 - return Objects.equals(connectPoint, otherInterface.connectPoint) && 131 + return Objects.equals(name, otherInterface.name) &&
132 + Objects.equals(connectPoint, otherInterface.connectPoint) &&
105 Objects.equals(ipAddresses, otherInterface.ipAddresses) && 133 Objects.equals(ipAddresses, otherInterface.ipAddresses) &&
106 Objects.equals(macAddress, otherInterface.macAddress) && 134 Objects.equals(macAddress, otherInterface.macAddress) &&
107 Objects.equals(vlan, otherInterface.vlan); 135 Objects.equals(vlan, otherInterface.vlan);
...@@ -109,12 +137,13 @@ public class Interface { ...@@ -109,12 +137,13 @@ public class Interface {
109 137
110 @Override 138 @Override
111 public int hashCode() { 139 public int hashCode() {
112 - return Objects.hash(connectPoint, ipAddresses, macAddress, vlan); 140 + return Objects.hash(connectPoint, name, ipAddresses, macAddress, vlan);
113 } 141 }
114 142
115 @Override 143 @Override
116 public String toString() { 144 public String toString() {
117 return MoreObjects.toStringHelper(getClass()) 145 return MoreObjects.toStringHelper(getClass())
146 + .add("name", name)
118 .add("connectPoint", connectPoint) 147 .add("connectPoint", connectPoint)
119 .add("ipAddresses", ipAddresses) 148 .add("ipAddresses", ipAddresses)
120 .add("macAddress", macAddress) 149 .add("macAddress", macAddress)
......
...@@ -16,13 +16,13 @@ ...@@ -16,13 +16,13 @@
16 16
17 package org.onosproject.incubator.net.intf; 17 package org.onosproject.incubator.net.intf;
18 18
19 -import org.onlab.packet.VlanId;
20 import org.onosproject.net.ConnectPoint; 19 import org.onosproject.net.ConnectPoint;
21 20
22 /** 21 /**
23 * Provides a means to modify the interfaces configuration. 22 * Provides a means to modify the interfaces configuration.
24 */ 23 */
25 public interface InterfaceAdminService { 24 public interface InterfaceAdminService {
25 +
26 /** 26 /**
27 * Adds a new interface configuration to the system. 27 * Adds a new interface configuration to the system.
28 * 28 *
...@@ -34,7 +34,7 @@ public interface InterfaceAdminService { ...@@ -34,7 +34,7 @@ public interface InterfaceAdminService {
34 * Removes an interface configuration from the system. 34 * Removes an interface configuration from the system.
35 * 35 *
36 * @param connectPoint connect point of the interface 36 * @param connectPoint connect point of the interface
37 - * @param vlanId vlan id 37 + * @param name name of the interface
38 */ 38 */
39 - void remove(ConnectPoint connectPoint, VlanId vlanId); 39 + boolean remove(ConnectPoint connectPoint, String name);
40 } 40 }
......
...@@ -18,6 +18,7 @@ package org.onosproject.incubator.net.intf.impl; ...@@ -18,6 +18,7 @@ package org.onosproject.incubator.net.intf.impl;
18 18
19 import com.google.common.collect.ImmutableSet; 19 import com.google.common.collect.ImmutableSet;
20 import com.google.common.collect.Maps; 20 import com.google.common.collect.Maps;
21 +import com.google.common.collect.Sets;
21 import org.apache.felix.scr.annotations.Activate; 22 import org.apache.felix.scr.annotations.Activate;
22 import org.apache.felix.scr.annotations.Component; 23 import org.apache.felix.scr.annotations.Component;
23 import org.apache.felix.scr.annotations.Deactivate; 24 import org.apache.felix.scr.annotations.Deactivate;
...@@ -39,9 +40,11 @@ import org.slf4j.Logger; ...@@ -39,9 +40,11 @@ import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory; 40 import org.slf4j.LoggerFactory;
40 41
41 import java.util.Collections; 42 import java.util.Collections;
43 +import java.util.Iterator;
42 import java.util.Map; 44 import java.util.Map;
43 import java.util.Optional; 45 import java.util.Optional;
44 import java.util.Set; 46 import java.util.Set;
47 +import java.util.concurrent.atomic.AtomicBoolean;
45 48
46 import static java.util.stream.Collectors.collectingAndThen; 49 import static java.util.stream.Collectors.collectingAndThen;
47 import static java.util.stream.Collectors.toSet; 50 import static java.util.stream.Collectors.toSet;
...@@ -145,7 +148,7 @@ public class InterfaceManager implements InterfaceService, ...@@ -145,7 +148,7 @@ public class InterfaceManager implements InterfaceService,
145 148
146 private void updateInterfaces(InterfaceConfig intfConfig) { 149 private void updateInterfaces(InterfaceConfig intfConfig) {
147 try { 150 try {
148 - interfaces.put(intfConfig.subject(), intfConfig.getInterfaces()); 151 + interfaces.put(intfConfig.subject(), Sets.newHashSet(intfConfig.getInterfaces()));
149 } catch (ConfigException e) { 152 } catch (ConfigException e) {
150 log.error("Error in interface config", e); 153 log.error("Error in interface config", e);
151 } 154 }
...@@ -157,18 +160,7 @@ public class InterfaceManager implements InterfaceService, ...@@ -157,18 +160,7 @@ public class InterfaceManager implements InterfaceService,
157 160
158 @Override 161 @Override
159 public void add(Interface intf) { 162 public void add(Interface intf) {
160 - if (interfaces.containsKey(intf.connectPoint())) { 163 + addInternal(intf);
161 - boolean conflict = interfaces.get(intf.connectPoint()).stream()
162 - .filter(i -> i.connectPoint().equals(intf.connectPoint()))
163 - .filter(i -> i.mac().equals(intf.mac()))
164 - .filter(i -> i.vlan().equals(intf.vlan()))
165 - .findAny().isPresent();
166 -
167 - if (conflict) {
168 - log.error("Can't add interface because it conflicts with existing config");
169 - return;
170 - }
171 - }
172 164
173 InterfaceConfig config = 165 InterfaceConfig config =
174 configService.addConfig(intf.connectPoint(), CONFIG_CLASS); 166 configService.addConfig(intf.connectPoint(), CONFIG_CLASS);
...@@ -178,29 +170,72 @@ public class InterfaceManager implements InterfaceService, ...@@ -178,29 +170,72 @@ public class InterfaceManager implements InterfaceService,
178 configService.applyConfig(intf.connectPoint(), CONFIG_CLASS, config.node()); 170 configService.applyConfig(intf.connectPoint(), CONFIG_CLASS, config.node());
179 } 171 }
180 172
181 - @Override 173 + private void addInternal(Interface intf) {
182 - public void remove(ConnectPoint connectPoint, VlanId vlanId) { 174 + interfaces.compute(intf.connectPoint(), (cp, current) -> {
183 - Optional<Interface> intf = interfaces.get(connectPoint).stream() 175 + if (current == null) {
184 - .filter(i -> i.vlan().equals(vlanId)) 176 + return Sets.newHashSet(intf);
185 - .findAny(); 177 + }
186 178
187 - if (!intf.isPresent()) { 179 + Iterator<Interface> it = current.iterator();
188 - log.error("Can't find interface {}/{} to remove", connectPoint, vlanId); 180 + while (it.hasNext()) {
189 - return; 181 + Interface i = it.next();
182 + if (i.name().equals(intf.name())) {
183 + it.remove();
184 + break;
185 + }
190 } 186 }
191 187
192 - InterfaceConfig config = configService.addConfig(intf.get().connectPoint(), CONFIG_CLASS); 188 + current.add(intf);
193 - config.removeInterface(intf.get()); 189 + return current;
190 + });
191 + }
192 +
193 + @Override
194 + public boolean remove(ConnectPoint connectPoint, String name) {
195 + boolean success = removeInternal(name, connectPoint);
196 +
197 + InterfaceConfig config = configService.addConfig(connectPoint, CONFIG_CLASS);
198 + config.removeInterface(name);
194 199
195 try { 200 try {
196 if (config.getInterfaces().isEmpty()) { 201 if (config.getInterfaces().isEmpty()) {
197 configService.removeConfig(connectPoint, CONFIG_CLASS); 202 configService.removeConfig(connectPoint, CONFIG_CLASS);
198 } else { 203 } else {
199 - configService.applyConfig(intf.get().connectPoint(), CONFIG_CLASS, config.node()); 204 + configService.applyConfig(connectPoint, CONFIG_CLASS, config.node());
200 } 205 }
201 } catch (ConfigException e) { 206 } catch (ConfigException e) {
202 log.error("Error reading interfaces JSON", e); 207 log.error("Error reading interfaces JSON", e);
203 } 208 }
209 +
210 + return success;
211 + }
212 +
213 + public boolean removeInternal(String name, ConnectPoint connectPoint) {
214 + AtomicBoolean removed = new AtomicBoolean(false);
215 +
216 + interfaces.compute(connectPoint, (cp, current) -> {
217 + if (current == null) {
218 + return null;
219 + }
220 +
221 + Iterator<Interface> it = current.iterator();
222 + while (it.hasNext()) {
223 + Interface i = it.next();
224 + if (i.name().equals(name)) {
225 + it.remove();
226 + removed.set(true);
227 + break;
228 + }
229 + }
230 +
231 + if (current.isEmpty()) {
232 + return null;
233 + } else {
234 + return current;
235 + }
236 + });
237 +
238 + return removed.get();
204 } 239 }
205 240
206 /** 241 /**
......