tom

Enhanced ProviderId to support notion of primary vs. ancillary and modified Abst…

…ractProviderRegistry to enforce one primary provider per URI scheme.
...@@ -35,10 +35,22 @@ public abstract class AbstractProviderRegistry<P extends Provider, S extends Pro ...@@ -35,10 +35,22 @@ public abstract class AbstractProviderRegistry<P extends Provider, S extends Pro
35 public synchronized S register(P provider) { 35 public synchronized S register(P provider) {
36 checkNotNull(provider, "Provider cannot be null"); 36 checkNotNull(provider, "Provider cannot be null");
37 checkState(!services.containsKey(provider.id()), "Provider %s already registered", provider.id()); 37 checkState(!services.containsKey(provider.id()), "Provider %s already registered", provider.id());
38 +
39 + // If the provider is a primary one, check for a conflict.
40 + ProviderId pid = provider.id();
41 + checkState(pid.isAncillary() || !providersByScheme.containsKey(pid.scheme()),
42 + "A primary provider with id %s is already registered",
43 + providersByScheme.get(pid.scheme()));
44 +
38 S service = createProviderService(provider); 45 S service = createProviderService(provider);
39 services.put(provider.id(), service); 46 services.put(provider.id(), service);
40 providers.put(provider.id(), provider); 47 providers.put(provider.id(), provider);
41 - // FIXME populate scheme look-up 48 +
49 + // Register the provider by URI scheme only if it is not ancillary.
50 + if (!pid.isAncillary()) {
51 + providersByScheme.put(pid.scheme(), provider);
52 + }
53 +
42 return service; 54 return service;
43 } 55 }
44 56
......
...@@ -11,6 +11,7 @@ public class ProviderId { ...@@ -11,6 +11,7 @@ public class ProviderId {
11 11
12 private final String scheme; 12 private final String scheme;
13 private final String id; 13 private final String id;
14 + private final boolean ancillary;
14 15
15 /** 16 /**
16 * Creates a new provider identifier from the specified string. 17 * Creates a new provider identifier from the specified string.
...@@ -21,8 +22,22 @@ public class ProviderId { ...@@ -21,8 +22,22 @@ public class ProviderId {
21 * @param id string identifier 22 * @param id string identifier
22 */ 23 */
23 public ProviderId(String scheme, String id) { 24 public ProviderId(String scheme, String id) {
25 + this(scheme, id, false);
26 + }
27 +
28 + /**
29 + * Creates a new provider identifier from the specified string.
30 + * The providers are expected to follow the reverse DNS convention, e.g.
31 + * {@code org.onlab.onos.provider.of.device}
32 + *
33 + * @param scheme device URI scheme to which this provider is bound, e.g. "of", "snmp"
34 + * @param id string identifier
35 + * @param ancillary ancillary provider indicator
36 + */
37 + public ProviderId(String scheme, String id, boolean ancillary) {
24 this.scheme = scheme; 38 this.scheme = scheme;
25 this.id = id; 39 this.id = id;
40 + this.ancillary = ancillary;
26 } 41 }
27 42
28 /** 43 /**
...@@ -35,6 +50,15 @@ public class ProviderId { ...@@ -35,6 +50,15 @@ public class ProviderId {
35 } 50 }
36 51
37 /** 52 /**
53 + * Indicates whether the provider id belongs to an ancillary provider.
54 + *
55 + * @return true for ancillary; false for primary provider
56 + */
57 + public boolean isAncillary() {
58 + return ancillary;
59 + }
60 +
61 + /**
38 * Returns the device URI scheme specific id portion. 62 * Returns the device URI scheme specific id portion.
39 * 63 *
40 * @return id 64 * @return id
...@@ -56,14 +80,16 @@ public class ProviderId { ...@@ -56,14 +80,16 @@ public class ProviderId {
56 if (obj instanceof ProviderId) { 80 if (obj instanceof ProviderId) {
57 final ProviderId other = (ProviderId) obj; 81 final ProviderId other = (ProviderId) obj;
58 return Objects.equals(this.scheme, other.scheme) && 82 return Objects.equals(this.scheme, other.scheme) &&
59 - Objects.equals(this.id, other.id); 83 + Objects.equals(this.id, other.id) &&
84 + this.ancillary == other.ancillary;
60 } 85 }
61 return false; 86 return false;
62 } 87 }
63 88
64 @Override 89 @Override
65 public String toString() { 90 public String toString() {
66 - return toStringHelper(this).add("scheme", scheme).add("id", id).toString(); 91 + return toStringHelper(this).add("scheme", scheme).add("id", id)
92 + .add("ancillary", ancillary).toString();
67 } 93 }
68 94
69 } 95 }
......
...@@ -35,7 +35,7 @@ public class AbstractProviderRegistryTest { ...@@ -35,7 +35,7 @@ public class AbstractProviderRegistryTest {
35 assertThat("provider not found", registry.getProviders().contains(fooId)); 35 assertThat("provider not found", registry.getProviders().contains(fooId));
36 assertEquals("incorrect provider", psFoo.provider(), pFoo); 36 assertEquals("incorrect provider", psFoo.provider(), pFoo);
37 37
38 - ProviderId barId = new ProviderId("of", "bar"); 38 + ProviderId barId = new ProviderId("snmp", "bar");
39 TestProvider pBar = new TestProvider(barId); 39 TestProvider pBar = new TestProvider(barId);
40 TestProviderService psBar = registry.register(pBar); 40 TestProviderService psBar = registry.register(pBar);
41 assertEquals("incorrect provider count", 2, registry.getProviders().size()); 41 assertEquals("incorrect provider count", 2, registry.getProviders().size());
...@@ -49,6 +49,16 @@ public class AbstractProviderRegistryTest { ...@@ -49,6 +49,16 @@ public class AbstractProviderRegistryTest {
49 assertThat("provider not found", registry.getProviders().contains(barId)); 49 assertThat("provider not found", registry.getProviders().contains(barId));
50 } 50 }
51 51
52 + @Test
53 + public void ancillaryProviders() {
54 + TestProviderRegistry registry = new TestProviderRegistry();
55 + TestProvider pFoo = new TestProvider(new ProviderId("of", "foo"));
56 + TestProvider pBar = new TestProvider(new ProviderId("of", "bar", true));
57 + registry.register(pFoo);
58 + registry.register(pBar);
59 + assertEquals("incorrect provider count", 2, registry.getProviders().size());
60 + }
61 +
52 @Test(expected = IllegalStateException.class) 62 @Test(expected = IllegalStateException.class)
53 public void duplicateRegistration() { 63 public void duplicateRegistration() {
54 TestProviderRegistry registry = new TestProviderRegistry(); 64 TestProviderRegistry registry = new TestProviderRegistry();
...@@ -57,6 +67,15 @@ public class AbstractProviderRegistryTest { ...@@ -57,6 +67,15 @@ public class AbstractProviderRegistryTest {
57 registry.register(pFoo); 67 registry.register(pFoo);
58 } 68 }
59 69
70 + @Test(expected = IllegalStateException.class)
71 + public void duplicateSchemeRegistration() {
72 + TestProviderRegistry registry = new TestProviderRegistry();
73 + TestProvider pFoo = new TestProvider(new ProviderId("of", "foo"));
74 + TestProvider pBar = new TestProvider(new ProviderId("of", "bar"));
75 + registry.register(pFoo);
76 + registry.register(pBar);
77 + }
78 +
60 @Test 79 @Test
61 public void voidUnregistration() { 80 public void voidUnregistration() {
62 TestProviderRegistry registry = new TestProviderRegistry(); 81 TestProviderRegistry registry = new TestProviderRegistry();
......