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
public synchronized S register(P provider) {
checkNotNull(provider, "Provider cannot be null");
checkState(!services.containsKey(provider.id()), "Provider %s already registered", provider.id());
// If the provider is a primary one, check for a conflict.
ProviderId pid = provider.id();
checkState(pid.isAncillary() || !providersByScheme.containsKey(pid.scheme()),
"A primary provider with id %s is already registered",
providersByScheme.get(pid.scheme()));
S service = createProviderService(provider);
services.put(provider.id(), service);
providers.put(provider.id(), provider);
// FIXME populate scheme look-up
// Register the provider by URI scheme only if it is not ancillary.
if (!pid.isAncillary()) {
providersByScheme.put(pid.scheme(), provider);
}
return service;
}
......
......@@ -11,6 +11,7 @@ public class ProviderId {
private final String scheme;
private final String id;
private final boolean ancillary;
/**
* Creates a new provider identifier from the specified string.
......@@ -21,8 +22,22 @@ public class ProviderId {
* @param id string identifier
*/
public ProviderId(String scheme, String id) {
this(scheme, id, false);
}
/**
* Creates a new provider identifier from the specified string.
* The providers are expected to follow the reverse DNS convention, e.g.
* {@code org.onlab.onos.provider.of.device}
*
* @param scheme device URI scheme to which this provider is bound, e.g. "of", "snmp"
* @param id string identifier
* @param ancillary ancillary provider indicator
*/
public ProviderId(String scheme, String id, boolean ancillary) {
this.scheme = scheme;
this.id = id;
this.ancillary = ancillary;
}
/**
......@@ -35,6 +50,15 @@ public class ProviderId {
}
/**
* Indicates whether the provider id belongs to an ancillary provider.
*
* @return true for ancillary; false for primary provider
*/
public boolean isAncillary() {
return ancillary;
}
/**
* Returns the device URI scheme specific id portion.
*
* @return id
......@@ -56,14 +80,16 @@ public class ProviderId {
if (obj instanceof ProviderId) {
final ProviderId other = (ProviderId) obj;
return Objects.equals(this.scheme, other.scheme) &&
Objects.equals(this.id, other.id);
Objects.equals(this.id, other.id) &&
this.ancillary == other.ancillary;
}
return false;
}
@Override
public String toString() {
return toStringHelper(this).add("scheme", scheme).add("id", id).toString();
return toStringHelper(this).add("scheme", scheme).add("id", id)
.add("ancillary", ancillary).toString();
}
}
......
......@@ -35,7 +35,7 @@ public class AbstractProviderRegistryTest {
assertThat("provider not found", registry.getProviders().contains(fooId));
assertEquals("incorrect provider", psFoo.provider(), pFoo);
ProviderId barId = new ProviderId("of", "bar");
ProviderId barId = new ProviderId("snmp", "bar");
TestProvider pBar = new TestProvider(barId);
TestProviderService psBar = registry.register(pBar);
assertEquals("incorrect provider count", 2, registry.getProviders().size());
......@@ -49,6 +49,16 @@ public class AbstractProviderRegistryTest {
assertThat("provider not found", registry.getProviders().contains(barId));
}
@Test
public void ancillaryProviders() {
TestProviderRegistry registry = new TestProviderRegistry();
TestProvider pFoo = new TestProvider(new ProviderId("of", "foo"));
TestProvider pBar = new TestProvider(new ProviderId("of", "bar", true));
registry.register(pFoo);
registry.register(pBar);
assertEquals("incorrect provider count", 2, registry.getProviders().size());
}
@Test(expected = IllegalStateException.class)
public void duplicateRegistration() {
TestProviderRegistry registry = new TestProviderRegistry();
......@@ -57,6 +67,15 @@ public class AbstractProviderRegistryTest {
registry.register(pFoo);
}
@Test(expected = IllegalStateException.class)
public void duplicateSchemeRegistration() {
TestProviderRegistry registry = new TestProviderRegistry();
TestProvider pFoo = new TestProvider(new ProviderId("of", "foo"));
TestProvider pBar = new TestProvider(new ProviderId("of", "bar"));
registry.register(pFoo);
registry.register(pBar);
}
@Test
public void voidUnregistration() {
TestProviderRegistry registry = new TestProviderRegistry();
......