Skip to content

Commit

Permalink
DDF-6169 fixes support for multiple wfs 1.1.0 sources (#6170)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason Smith authored Jul 16, 2020
1 parent 5b366da commit b3b4f9b
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ public void init() {
"unused"
})
public void destroy(int code) {
wfsMetacardTypeRegistry.clear();
wfsMetacardTypeRegistry.clear(getId());
availabilityPollFuture.cancel(true);
scheduler.shutdownNow();
}
Expand Down Expand Up @@ -608,7 +608,7 @@ private void registerFeatureMetacardTypes(Map<String, FeatureMetacardType> mcTyp
// registering the MetacardTypes - the concern is that if this registration is too lengthy
// a query could come in that is handled while the MetacardType registrations are
// in a state of flux.
wfsMetacardTypeRegistry.clear();
wfsMetacardTypeRegistry.clear(getId());

List<String> featureNames = new ArrayList<>();
if (!mcTypeRegs.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ public interface WfsMetacardTypeRegistry {
*/
void registerMetacardType(MetacardType metacardType, String sourceId, String featureSimpleName);

/** Used to clear all entries of the registry for a specific source */
void clear(String sourceId);

/** Used to clear all entries of the registry */
void clear();
void clearAll();
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@
import ddf.catalog.data.MetacardType;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.codice.ddf.configuration.DictionaryMap;
import org.codice.ddf.spatial.ogc.wfs.catalog.metacardtype.registry.WfsMetacardTypeRegistry;
import org.osgi.framework.BundleContext;
Expand All @@ -34,6 +37,8 @@ public final class WfsMetacardTypeRegistryImpl implements WfsMetacardTypeRegistr

private List<ServiceRegistration<MetacardType>> serviceRegistrations;

private final Lock registryLock = new ReentrantLock();

public WfsMetacardTypeRegistryImpl(BundleContext bundleContext) {
this.bundleContext = bundleContext;
this.serviceRegistrations = new ArrayList<>();
Expand All @@ -46,19 +51,25 @@ public Optional<MetacardType> lookupMetacardTypeBySimpleName(String sourceId, St
return Optional.empty();
}

Optional<ServiceRegistration<MetacardType>> serviceRegistrationOptional =
serviceRegistrations
.stream()
.filter(s -> s.getReference().getProperty(SOURCE_ID) != null)
.filter(s -> s.getReference().getProperty(SOURCE_ID).equals(sourceId))
.filter(s -> s.getReference().getProperty(FEATURE_NAME) != null)
.filter(s -> s.getReference().getProperty(FEATURE_NAME).equals(simpleName))
.findFirst();

if (serviceRegistrationOptional.isPresent()) {
MetacardType featureMetacardType =
bundleContext.getService(serviceRegistrationOptional.get().getReference());
return Optional.of(featureMetacardType);
try {
// acquire a lock to protect read access on serviceRegistrations
registryLock.lock();
Optional<ServiceRegistration<MetacardType>> serviceRegistrationOptional =
serviceRegistrations
.stream()
.filter(s -> s.getReference().getProperty(SOURCE_ID) != null)
.filter(s -> s.getReference().getProperty(SOURCE_ID).equals(sourceId))
.filter(s -> s.getReference().getProperty(FEATURE_NAME) != null)
.filter(s -> s.getReference().getProperty(FEATURE_NAME).equals(simpleName))
.findFirst();

if (serviceRegistrationOptional.isPresent()) {
MetacardType featureMetacardType =
bundleContext.getService(serviceRegistrationOptional.get().getReference());
return Optional.of(featureMetacardType);
}
} finally {
registryLock.unlock();
}

return Optional.empty();
Expand All @@ -77,12 +88,43 @@ public void registerMetacardType(
properties.put(FEATURE_NAME, featureSimpleName);
ServiceRegistration<MetacardType> serviceRegistration =
bundleContext.registerService(MetacardType.class, metacardType, properties);
serviceRegistrations.add(serviceRegistration);
try {
registryLock.lock();
serviceRegistrations.add(serviceRegistration);
} finally {
registryLock.unlock();
}
}

/** {@inheritDoc} */
@Override
public void clear(String sourceId) {
Verify.verifyNotNull(sourceId, "argument 'sourceId' may not be null.");
try {
registryLock.lock();
for (Iterator<ServiceRegistration<MetacardType>> iter = serviceRegistrations.iterator();
iter.hasNext(); ) {
ServiceRegistration registration = iter.next();
if (registration.getReference() != null
&& registration.getReference().getProperty(SOURCE_ID).equals(sourceId)) {
registration.unregister();
iter.remove();
}
}
} finally {
registryLock.unlock();
}
}

/** {@inheritDoc} */
public void clear() {
serviceRegistrations.stream().forEach(ServiceRegistration::unregister);
serviceRegistrations.clear();
@Override
public void clearAll() {
try {
registryLock.lock();
serviceRegistrations.stream().forEach(ServiceRegistration::unregister);
serviceRegistrations.clear();
} finally {
registryLock.unlock();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public class WfsMetacardTypeRegistryTest {

public static final String TEST_SOURCE_ID = "test-source";

public static final String TEST_SOURCE_ID_2 = "test-source2";

public static final String TEST_FEATURE_SIMPLE_NAME = "amazon-waters";

private BundleContext mockBundleContext;
Expand Down Expand Up @@ -94,13 +96,42 @@ public void testLookupMetacardTypeBySimpleName() {
}

@Test
public void testClear() {
public void testClearAll() {
wfsMetacardTypeRegistry.registerMetacardType(
mockMetacardType, TEST_SOURCE_ID, TEST_FEATURE_SIMPLE_NAME);
wfsMetacardTypeRegistry.clear();
wfsMetacardTypeRegistry.clearAll();
verify(mockServiceRegistration, times(1)).unregister();
}

@Test
public void testClear() {
ServiceRegistration mockServiceRegistration1 = mock(ServiceRegistration.class);
ServiceRegistration mockServiceRegistration2 = mock(ServiceRegistration.class);
ServiceReference mockServiceReference1 = mock(ServiceReference.class);
ServiceReference mockServiceReference2 = mock(ServiceReference.class);
String featureA = "featureA";
String featureB = "featureB";

when(mockServiceRegistration1.getReference()).thenReturn(mockServiceReference1);
when(mockServiceRegistration2.getReference()).thenReturn(mockServiceReference2);
when(mockServiceReference1.getProperty(WfsMetacardTypeRegistryImpl.SOURCE_ID))
.thenReturn(TEST_SOURCE_ID);
when(mockServiceReference2.getProperty(WfsMetacardTypeRegistryImpl.SOURCE_ID))
.thenReturn(TEST_SOURCE_ID_2);
when(mockBundleContext.registerService(
same(MetacardType.class), any(MetacardType.class), any(Dictionary.class)))
.thenReturn(mockServiceRegistration1)
.thenReturn(mockServiceRegistration2);
wfsMetacardTypeRegistry = new WfsMetacardTypeRegistryImpl(mockBundleContext);

wfsMetacardTypeRegistry.registerMetacardType(mockMetacardType, TEST_SOURCE_ID, featureA);
wfsMetacardTypeRegistry.registerMetacardType(mockMetacardType, TEST_SOURCE_ID_2, featureB);
wfsMetacardTypeRegistry.clear(TEST_SOURCE_ID);
verify(mockBundleContext, times(2))
.registerService(same(MetacardType.class), same(mockMetacardType), any(Dictionary.class));
verify(mockServiceRegistration1, times(1)).unregister();
}

@Test(expected = VerifyException.class)
public void testNullMetacardType() {
wfsMetacardTypeRegistry.registerMetacardType(null, TEST_SOURCE_ID, TEST_FEATURE_SIMPLE_NAME);
Expand Down

0 comments on commit b3b4f9b

Please sign in to comment.