/** * Copyright (c) Codice Foundation * <p> * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation, either version 3 of the * License, or any later version. * <p> * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. A copy of the GNU Lesser General Public License * is distributed along with this program and can be found at * <http://www.gnu.org/licenses/lgpl.html>. */ package org.codice.ddf.registry.federationadmin.impl; import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo; import static org.custommonkey.xmlunit.XMLAssert.assertXpathExists; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyList; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Dictionary; import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import javax.xml.bind.JAXBElement; import org.apache.commons.io.IOUtils; import org.codice.ddf.configuration.SystemBaseUrl; import org.codice.ddf.parser.Parser; import org.codice.ddf.parser.ParserConfigurator; import org.codice.ddf.parser.ParserException; import org.codice.ddf.parser.xml.XmlParser; import org.codice.ddf.registry.api.internal.RegistryStore; import org.codice.ddf.registry.common.RegistryConstants; import org.codice.ddf.registry.common.metacard.RegistryObjectMetacardType; import org.codice.ddf.registry.federationadmin.service.internal.FederationAdminException; import org.codice.ddf.registry.federationadmin.service.internal.FederationAdminService; import org.codice.ddf.registry.federationadmin.service.internal.RegistrySourceConfiguration; import org.codice.ddf.registry.schemabindings.EbrimConstants; import org.codice.ddf.registry.schemabindings.converter.type.RegistryPackageTypeConverter; import org.codice.ddf.registry.schemabindings.converter.web.RegistryPackageWebConverter; import org.codice.ddf.registry.schemabindings.helper.MetacardMarshaller; import org.codice.ddf.registry.schemabindings.helper.SlotTypeHelper; import org.codice.ddf.registry.transformer.RegistryTransformer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.service.cm.Configuration; import org.osgi.service.event.Event; import ddf.action.Action; import ddf.action.MultiActionProvider; import ddf.catalog.CatalogFramework; import ddf.catalog.data.Metacard; import ddf.catalog.data.impl.AttributeImpl; import ddf.catalog.data.impl.MetacardImpl; import ddf.catalog.data.impl.ResultImpl; import ddf.catalog.endpoint.CatalogEndpoint; import ddf.catalog.operation.QueryRequest; import ddf.catalog.operation.QueryResponse; import ddf.catalog.service.ConfiguredService; import ddf.catalog.source.CatalogStore; import ddf.catalog.source.Source; import ddf.catalog.transform.CatalogTransformerException; import oasis.names.tc.ebxml_regrep.xsd.rim._3.RegistryObjectType; import oasis.names.tc.ebxml_regrep.xsd.rim._3.RegistryPackageType; @RunWith(MockitoJUnitRunner.class) public class FederationAdminTest { @Rule public TemporaryFolder folder = new TemporaryFolder(); @Mock private FederationAdminService federationAdminService; @Mock private RegistryTransformer registryTransformer; @Mock private AdminHelper helper; @Mock private CatalogFramework catalogFramework; @Mock private BundleContext context; @Mock private QueryResponse queryResponse; @Mock private CatalogStore store; @Mock private RegistrySourceConfiguration sourceConfiguration; @Mock private MultiActionProvider multiActionProvider; private Parser parser; private ParserConfigurator configurator; private FederationAdmin federationAdmin; private Map<String, CatalogStore> catalogStoreMap = new HashMap<>(); private MetacardImpl mcard; private RegistryPackageTypeConverter typeConverter = new RegistryPackageTypeConverter(); private RegistryPackageWebConverter mapConverter = new RegistryPackageWebConverter(); private static final String LOCAL_NODE_KEY = "nodes"; @Before public void setup() throws Exception { parser = new XmlParser(); configurator = parser.configureParser(Arrays.asList(RegistryObjectType.class.getPackage() .getName(), EbrimConstants.OGC_FACTORY.getClass() .getPackage() .getName(), EbrimConstants.GML_FACTORY.getClass() .getPackage() .getName()), this.getClass() .getClassLoader()); federationAdmin = new FederationAdmin(helper) { @Override public BundleContext getContext() { return context; } }; federationAdmin.setFederationAdminService(federationAdminService); federationAdmin.setRegistryTransformer(registryTransformer); federationAdmin.setMetacardMarshaller(new MetacardMarshaller(parser)); federationAdmin.setSlotHelper(new SlotTypeHelper()); federationAdmin.setRegistryMapConverter(new RegistryPackageWebConverter()); federationAdmin.setRegistryTypeConverter(new RegistryPackageTypeConverter()); federationAdmin.setSourceConfigRefresh(sourceConfiguration); mcard = new MetacardImpl(new RegistryObjectMetacardType()); mcard.setAttribute(RegistryObjectMetacardType.REGISTRY_ID, "myId"); mcard.setAttribute(RegistryObjectMetacardType.PUBLISHED_LOCATIONS, new ArrayList<>()); mcard.setId("someUUID"); when(queryResponse.getResults()).thenReturn(Collections.singletonList(new ResultImpl(mcard))); when(catalogFramework.query(any(QueryRequest.class))).thenReturn(queryResponse); catalogStoreMap.put("myDest", store); } @Test public void testCreateLocalEntry() throws Exception { String metacardId = "metacardId"; RegistryPackageType registryObject = getRegistryObjectFromResource( "/csw-full-registry-package.xml"); Map<String, Object> registryMap = getMapFromRegistryObject(registryObject); Metacard metacard = getTestMetacard(); when(registryTransformer.transform(any(InputStream.class))).thenReturn(metacard); when(federationAdminService.addRegistryEntry(any(Metacard.class))).thenReturn(metacardId); String createdMetacardId = federationAdmin.createLocalEntry(registryMap); assertThat(createdMetacardId, is(equalTo(metacardId))); verify(federationAdminService).addRegistryEntry(metacard); } @Test public void testCreateLocalEntryMissingAttributes() throws Exception { String metacardId = "metacardId"; RegistryPackageType registryObject = getRegistryObjectFromResource( "/csw-full-registry-package.xml"); Map<String, Object> registryMap = getMapFromRegistryObject(registryObject); registryMap.remove("id"); registryMap.remove("home"); registryMap.remove("objectType"); Metacard metacard = getTestMetacard(); when(registryTransformer.transform(any(InputStream.class))).thenReturn(metacard); when(federationAdminService.addRegistryEntry(any(Metacard.class))).thenReturn(metacardId); federationAdmin.createLocalEntry(registryMap); ArgumentCaptor<InputStream> captor = ArgumentCaptor.forClass(InputStream.class); verify(registryTransformer).transform(captor.capture()); String ebrim = IOUtils.toString(captor.getValue()); IOUtils.closeQuietly(captor.getValue()); assertXpathEvaluatesTo(SystemBaseUrl.getBaseUrl(), "/*[local-name() = 'RegistryPackage']/@home", ebrim); assertXpathEvaluatesTo(RegistryConstants.REGISTRY_NODE_OBJECT_TYPE, "/*[local-name() = 'RegistryPackage']/@objectType", ebrim); assertXpathExists("/*[local-name() = 'RegistryPackage']/@id", ebrim); } @Test(expected = FederationAdminException.class) public void testCreateLocalEntryWithEmptyMap() throws Exception { Map<String, Object> registryMap = new HashMap<>(); federationAdmin.createLocalEntry(registryMap); verify(federationAdminService, never()).addRegistryEntry(any(Metacard.class)); } @Test(expected = FederationAdminException.class) public void testCreateLocalEntryWithBadMap() throws Exception { Map<String, Object> registryMap = new HashMap<>(); registryMap.put("BadKey", "BadValue"); federationAdmin.createLocalEntry(registryMap); verify(federationAdminService, never()).addRegistryEntry(any(Metacard.class)); } @Test(expected = FederationAdminException.class) public void testCreateLocalEntryWithFederationAdminException() throws Exception { RegistryPackageType registryObject = getRegistryObjectFromResource( "/csw-full-registry-package.xml"); Map<String, Object> registryMap = getMapFromRegistryObject(registryObject); Metacard metacard = getTestMetacard(); when(registryTransformer.transform(any(InputStream.class))).thenReturn(metacard); when(federationAdminService.addRegistryEntry(any(Metacard.class))).thenThrow( FederationAdminException.class); federationAdmin.createLocalEntry(registryMap); verify(federationAdminService).addRegistryEntry(metacard); } @Test public void testCreateLocalEntryString() throws Exception { String encodeThisString = "aPretendXmlRegistryPackage"; String metacardId = "createdMetacardId"; String base64EncodedString = Base64.getEncoder() .encodeToString(encodeThisString.getBytes()); Metacard metacard = getTestMetacard(); when(registryTransformer.transform(any(InputStream.class))).thenReturn(metacard); when(federationAdminService.addRegistryEntry(metacard)).thenReturn(metacardId); String createdMetacardId = federationAdmin.createLocalEntry(base64EncodedString); assertThat(createdMetacardId, is(equalTo(metacardId))); verify(registryTransformer).transform(any(InputStream.class)); verify(federationAdminService).addRegistryEntry(metacard); } @Test(expected = FederationAdminException.class) public void testCreateLocalEntryStringWithBlankString() throws Exception { String base64EncodedString = ""; federationAdmin.createLocalEntry(base64EncodedString); verify(registryTransformer, never()).transform(any(InputStream.class)); verify(federationAdminService, never()).addRegistryEntry(any(Metacard.class)); } @Test(expected = FederationAdminException.class) public void testCreateLocalEntryStringWithTransformerException() throws Exception { String encodeThisString = "aPretendXmlRegistryPackage"; String base64EncodedString = Base64.getEncoder() .encodeToString(encodeThisString.getBytes()); when(registryTransformer.transform(any(InputStream.class))).thenThrow( CatalogTransformerException.class); federationAdmin.createLocalEntry(base64EncodedString); verify(registryTransformer).transform(any(InputStream.class)); verify(federationAdminService, never()).addRegistryEntry(any(Metacard.class)); } @Test(expected = FederationAdminException.class) public void testCreateLocalEntryStringWithDecodeError() throws Exception { // This is has an illegal base64 character String base64EncodedString = "[B@6499375d"; federationAdmin.createLocalEntry(base64EncodedString); verify(registryTransformer, never()).transform(any(InputStream.class)); verify(federationAdminService, never()).addRegistryEntry(any(Metacard.class)); } @Test public void testUpdateLocalEntry() throws Exception { RegistryPackageType registryObject = getRegistryObjectFromResource( "/csw-registry-package-smaller.xml"); Map<String, Object> registryMap = getMapFromRegistryObject(registryObject); String existingMetacardId = "someUpdateMetacardId"; Metacard existingMetacard = getTestMetacard(); existingMetacard.setAttribute(new AttributeImpl(Metacard.ID, existingMetacardId)); List<Metacard> existingMetacards = new ArrayList<>(); existingMetacards.add(existingMetacard); Metacard updateMetacard = getTestMetacard(); when(federationAdminService.getLocalRegistryMetacardsByRegistryIds(Collections.singletonList( registryObject.getId()))).thenReturn(existingMetacards); when(registryTransformer.transform(any(InputStream.class))).thenReturn(updateMetacard); federationAdmin.updateLocalEntry(registryMap); verify(federationAdminService).getLocalRegistryMetacardsByRegistryIds(Collections.singletonList( registryObject.getId())); verify(registryTransformer).transform(any(InputStream.class)); verify(federationAdminService).updateRegistryEntry(updateMetacard); } @Test(expected = FederationAdminException.class) public void testUpdateLocalEntryWithEmptyMap() throws Exception { Map<String, Object> registryMap = new HashMap<>(); federationAdmin.updateLocalEntry(registryMap); verify(federationAdminService, never()).getLocalRegistryMetacardsByRegistryIds(Collections.singletonList(any(String.class))); verify(registryTransformer, never()).transform(any(InputStream.class)); verify(federationAdminService, never()).updateRegistryEntry(any(Metacard.class)); } @Test(expected = FederationAdminException.class) public void testUpdateLocalEntryWithBadMap() throws Exception { Map<String, Object> registryMap = new HashMap<>(); registryMap.put("BadKey", "BadValue"); federationAdmin.updateLocalEntry(registryMap); verify(federationAdminService, never()).getLocalRegistryMetacardsByRegistryIds(Collections.singletonList(any(String.class))); verify(registryTransformer, never()).transform(any(InputStream.class)); verify(federationAdminService, never()).updateRegistryEntry(any(Metacard.class)); } @Test(expected = FederationAdminException.class) public void testUpdateLocalEntryWithEmptyExistingList() throws Exception { RegistryPackageType registryObject = getRegistryObjectFromResource( "/csw-full-registry-package.xml"); Map<String, Object> registryMap = getMapFromRegistryObject(registryObject); List<Metacard> existingMetacards = new ArrayList<>(); when(federationAdminService.getLocalRegistryMetacardsByRegistryIds(Collections.singletonList( registryObject.getId()))).thenReturn(existingMetacards); federationAdmin.updateLocalEntry(registryMap); verify(federationAdminService, never()).getLocalRegistryMetacardsByRegistryIds(Collections.singletonList( registryObject.getId())); verify(registryTransformer, never()).transform(any(InputStream.class)); verify(federationAdminService, never()).updateRegistryEntry(any(Metacard.class)); } @Test(expected = FederationAdminException.class) public void testUpdateLocalEntryWithMultipleExistingMetacards() throws Exception { RegistryPackageType registryObject = getRegistryObjectFromResource( "/csw-full-registry-package.xml"); Map<String, Object> registryMap = getMapFromRegistryObject(registryObject); List<Metacard> existingMetacards = new ArrayList<>(); existingMetacards.add(getTestMetacard()); existingMetacards.add(getTestMetacard()); when(federationAdminService.getLocalRegistryMetacardsByRegistryIds(Collections.singletonList( registryObject.getId()))).thenReturn(existingMetacards); federationAdmin.updateLocalEntry(registryMap); verify(federationAdminService, never()).getLocalRegistryMetacardsByRegistryIds(Collections.singletonList( registryObject.getId())); verify(registryTransformer, never()).transform(any(InputStream.class)); verify(federationAdminService, never()).updateRegistryEntry(any(Metacard.class)); } @Test(expected = FederationAdminException.class) public void testUpdateLocalEntryWithFederationAdminServiceException() throws Exception { RegistryPackageType registryObject = getRegistryObjectFromResource( "/csw-full-registry-package.xml"); Map<String, Object> registryMap = getMapFromRegistryObject(registryObject); String existingMetacardId = "someUpdateMetacardId"; Metacard existingMetacard = getTestMetacard(); existingMetacard.setAttribute(new AttributeImpl(Metacard.ID, existingMetacardId)); List<Metacard> existingMetacards = new ArrayList<>(); existingMetacards.add(existingMetacard); Metacard updateMetacard = getTestMetacard(); when(federationAdminService.getLocalRegistryMetacardsByRegistryIds(Collections.singletonList( registryObject.getId()))).thenReturn(existingMetacards); when(registryTransformer.transform(any(InputStream.class))).thenReturn(updateMetacard); doThrow(FederationAdminException.class).when(federationAdminService) .updateRegistryEntry(updateMetacard); federationAdmin.updateLocalEntry(registryMap); verify(federationAdminService).getLocalRegistryMetacardsByRegistryIds(Collections.singletonList( registryObject.getId())); verify(registryTransformer).transform(any(InputStream.class)); verify(federationAdminService).updateRegistryEntry(updateMetacard); } @Test public void testDeleteLocalEntry() throws Exception { String firstRegistryId = "firstRegistryId"; String secondRegistryId = "secondRegistryId"; List<String> ids = new ArrayList<>(); ids.add(firstRegistryId); ids.add(secondRegistryId); String firstMetacardId = "firstMetacardId"; String secondMetacardId = "secondMetacardId"; Metacard firstMetacard = getTestMetacard(); firstMetacard.setAttribute(new AttributeImpl(Metacard.ID, firstMetacardId)); Metacard secondMetacard = getTestMetacard(); secondMetacard.setAttribute(new AttributeImpl(Metacard.ID, secondMetacardId)); List<Metacard> matchingMetacards = new ArrayList<>(); matchingMetacards.add(firstMetacard); matchingMetacards.add(secondMetacard); List<String> metacardIds = new ArrayList<>(); metacardIds.addAll(matchingMetacards.stream() .map(Metacard::getId) .collect(Collectors.toList())); when(federationAdminService.getRegistryMetacardsByRegistryIds(ids, true)).thenReturn( matchingMetacards); federationAdmin.deleteLocalEntry(ids); verify(federationAdminService).getRegistryMetacardsByRegistryIds(ids, true); verify(federationAdminService).deleteRegistryEntriesByMetacardIds(metacardIds); } @Test(expected = FederationAdminException.class) public void testDeleteLocalEntryWithEmptyList() throws Exception { List<String> ids = new ArrayList<>(); federationAdmin.deleteLocalEntry(ids); verify(federationAdminService, never()).getLocalRegistryMetacardsByRegistryIds(anyList()); verify(federationAdminService, never()).deleteRegistryEntriesByMetacardIds(anyList()); } @Test(expected = FederationAdminException.class) public void testDeleteLocalEntryWithExceptionGettingLocalMetacards() throws Exception { List<String> ids = new ArrayList<>(); ids.add("whatever"); when(federationAdminService.getLocalRegistryMetacardsByRegistryIds(ids)).thenThrow( FederationAdminException.class); federationAdmin.deleteLocalEntry(ids); verify(federationAdminService).getLocalRegistryMetacardsByRegistryIds(ids); verify(federationAdminService, never()).deleteRegistryEntriesByMetacardIds(anyList()); } @Test(expected = FederationAdminException.class) public void testDeleteLocalEntryWithNonMatchingLists() throws Exception { String firstRegistryId = "firstRegistryId"; String secondRegistryId = "secondRegistryId"; List<String> ids = new ArrayList<>(); ids.add(firstRegistryId); ids.add(secondRegistryId); String firstMetacardId = "firstMetacardId"; Metacard firstMetacard = getTestMetacard(); firstMetacard.setAttribute(new AttributeImpl(Metacard.ID, firstMetacardId)); List<Metacard> matchingMetacards = new ArrayList<>(); matchingMetacards.add(firstMetacard); List<String> metacardIds = new ArrayList<>(); metacardIds.addAll(matchingMetacards.stream() .map(Metacard::getId) .collect(Collectors.toList())); when(federationAdminService.getLocalRegistryMetacardsByRegistryIds(ids)).thenReturn( matchingMetacards); federationAdmin.deleteLocalEntry(ids); verify(federationAdminService).getLocalRegistryMetacardsByRegistryIds(ids); verify(federationAdminService, never()).deleteRegistryEntriesByMetacardIds(metacardIds); } @Test(expected = FederationAdminException.class) public void testDeleteLocalEntryWithExceptionDeletingEntries() throws Exception { List<String> ids = new ArrayList<>(); ids.add("firstId"); doThrow(FederationAdminException.class).when(federationAdminService) .deleteRegistryEntriesByRegistryIds(ids); federationAdmin.deleteLocalEntry(ids); verify(federationAdminService).deleteRegistryEntriesByRegistryIds(ids); } @Test public void testGetLocalNodes() throws Exception { RegistryPackageType registryObject = getRegistryObjectFromResource( "/csw-registry-package-smaller.xml"); Map<String, Object> registryObjectMap = new RegistryPackageWebConverter().convert( registryObject); List<RegistryPackageType> registryPackages = new ArrayList<>(); registryPackages.add((RegistryPackageType) registryObject); when(federationAdminService.getLocalRegistryObjects()).thenReturn(registryPackages); Map<String, Object> localNodes = federationAdmin.getLocalNodes(); Map<String, Object> localNode = ((List<Map<String, Object>>) localNodes.get(LOCAL_NODE_KEY)).get(0); verify(federationAdminService).getLocalRegistryObjects(); assertThat(localNode, is(equalTo(registryObjectMap))); } @Test(expected = FederationAdminException.class) public void testGetLocalNodesWithFederationAdminException() throws Exception { when(federationAdminService.getLocalRegistryObjects()).thenThrow(FederationAdminException.class); federationAdmin.getLocalNodes(); verify(federationAdminService).getLocalRegistryObjects(); } @Test public void testAllRegistryInfoNoMetatypes() throws Exception { List<Map<String, Object>> metatypes = new ArrayList<>(); when(helper.getMetatypes()).thenReturn(metatypes); assertThat(federationAdmin.allRegistryInfo() .size(), is(0)); } @Test public void testAllRegistryInfo() throws Exception { List<Map<String, Object>> metatypes = new ArrayList<>(); List<Configuration> configurations = new ArrayList<>(); Dictionary<String, Object> props = new Hashtable<>(); Dictionary<String, Object> propsDisabled = new Hashtable<>(); metatypes.add(new HashMap<>()); props.put("key1", "value1"); propsDisabled.put("key2", "value2"); Configuration config = mock(Configuration.class); configurations.add(config); when(config.getPid()).thenReturn("myPid"); when(config.getFactoryPid()).thenReturn("myFpid"); when(config.getProperties()).thenReturn(props); Configuration configDisabled = mock(Configuration.class); configurations.add(configDisabled); when(configDisabled.getPid()).thenReturn("myPid_disabled"); when(configDisabled.getFactoryPid()).thenReturn("myFpid_disabled"); when(configDisabled.getProperties()).thenReturn(propsDisabled); when(helper.getMetatypes()).thenReturn(metatypes); when(helper.getConfigurations(any(Map.class))).thenReturn(configurations); when(helper.getName(any(Configuration.class))).thenReturn("name"); when(helper.getBundleName(any(Configuration.class))).thenReturn("bundleName"); when(helper.getBundleId(any(Configuration.class))).thenReturn(1234L); List<Map<String, Object>> updatedMetatypes = federationAdmin.allRegistryInfo(); assertThat(updatedMetatypes.size(), is(1)); ArrayList<Map<String, Object>> configs = (ArrayList<Map<String, Object>>) updatedMetatypes.get(0) .get("configurations"); assertThat(configs.size(), is(2)); Map<String, Object> activeConfig = configs.get(0); Map<String, Object> disabledConfig = configs.get(1); assertThat(activeConfig.get("name"), equalTo("name")); assertThat(activeConfig.get("id"), equalTo("myPid")); assertThat(activeConfig.get("fpid"), equalTo("myFpid")); assertThat(activeConfig.get("enabled"), equalTo(true)); assertThat(((Map<String, Object>) activeConfig.get("properties")).get("key1"), equalTo("value1")); assertThat(disabledConfig.get("name"), equalTo("myPid_disabled")); assertThat(disabledConfig.get("id"), equalTo("myPid_disabled")); assertThat(disabledConfig.get("fpid"), equalTo("myFpid_disabled")); assertThat(disabledConfig.get("enabled"), equalTo(false)); assertThat(((Map<String, Object>) disabledConfig.get("properties")).get("key2"), equalTo("value2")); } @Test public void testAllRegistryMetacards() throws Exception { List<RegistryPackageType> regObjects = Collections.singletonList((RegistryPackageType) getRegistryObjectFromResource( "/csw-full-registry-package.xml")); when(federationAdminService.getRegistryObjects()).thenReturn(regObjects); ArrayList<String> tags = new ArrayList<>(); tags.add(RegistryConstants.REGISTRY_TAG); mcard.setAttribute(Metacard.TAGS, tags); mcard.setAttribute(RegistryObjectMetacardType.REGISTRY_ID, "urn:uuid:2014ca7f59ac46f495e32b4a67a51276"); mcard.setAttribute(RegistryObjectMetacardType.PUBLISHED_LOCATIONS, "location1"); when(federationAdminService.getRegistryMetacards()).thenReturn(Collections.singletonList( mcard)); List<Map<String, Object>> result = (List<Map<String, Object>>) federationAdmin.allRegistryMetacards() .get("nodes"); assertThat(result.size(), is(1)); Map<String, Object> mcardMap = result.get(0); assertThat(mcardMap.get("TransientValues"), notNullValue()); Map<String, Object> transValues = (Map<String, Object>) mcardMap.get("TransientValues"); assertThat(((List) transValues.get(RegistryObjectMetacardType.PUBLISHED_LOCATIONS)).get(0), equalTo("location1")); } @Test public void testRegistryStatusNotConfiguredService() throws Exception { Source source = mock(Source.class); when(helper.getRegistrySources()).thenReturn(Collections.singletonList(source)); assertThat(federationAdmin.registryStatus("servicePid"), is(false)); } @Test public void testRegistryStatusNoMatchingConfig() throws Exception { RegistryStore source = mock(RegistryStore.class); Configuration config = mock(Configuration.class); Dictionary<String, Object> props = new Hashtable<>(); props.put("service.pid", "servicePid2"); when(config.getProperties()).thenReturn(props); when(source.isAvailable()).thenReturn(true); when(helper.getRegistrySources()).thenReturn(Collections.singletonList(source)); when(helper.getConfiguration(any(ConfiguredService.class))).thenReturn(config); assertThat(federationAdmin.registryStatus("servicePid"), is(false)); } @Test public void testRegistryStatusNoConfig() throws Exception { RegistryStore source = mock(RegistryStore.class); when(source.isAvailable()).thenReturn(true); when(helper.getRegistrySources()).thenReturn(Collections.singletonList(source)); when(helper.getConfiguration(any(ConfiguredService.class))).thenReturn(null); assertThat(federationAdmin.registryStatus("servicePid"), is(false)); } @Test public void testRegistryStatus() throws Exception { RegistryStore source = mock(RegistryStore.class); Configuration config = mock(Configuration.class); Dictionary<String, Object> props = new Hashtable<>(); props.put("service.pid", "servicePid"); when(config.getProperties()).thenReturn(props); when(source.isAvailable()).thenReturn(true); when(helper.getRegistrySources()).thenReturn(Collections.singletonList(source)); when(helper.getConfiguration(any(ConfiguredService.class))).thenReturn(config); assertThat(federationAdmin.registryStatus("servicePid"), is(true)); } @Test public void testInit() throws Exception { copyJsonFileToKarafDir(); List<RegistryPackageType> regObjects = Collections.singletonList((RegistryPackageType) getRegistryObjectFromResource( "/csw-full-registry-package.xml")); when(federationAdminService.getRegistryObjects()).thenReturn(regObjects); mcard.setAttribute(RegistryObjectMetacardType.REGISTRY_ID, "urn:uuid:2014ca7f59ac46f495e32b4a67a51276"); mcard.setAttribute(RegistryObjectMetacardType.PUBLISHED_LOCATIONS, "location1"); when(federationAdminService.getRegistryMetacards()).thenReturn(Collections.singletonList( mcard)); federationAdmin.init(); Map<String, Object> nodes = federationAdmin.getLocalNodes(); Map<String, Object> customSlots = (Map<String, Object>) nodes.get("customSlots"); assertThat(customSlots.size(), is(6)); } @Test public void testInitNoFile() throws Exception { List<RegistryPackageType> regObjects = Collections.singletonList((RegistryPackageType) getRegistryObjectFromResource( "/csw-full-registry-package.xml")); when(federationAdminService.getRegistryObjects()).thenReturn(regObjects); mcard.setAttribute(RegistryObjectMetacardType.REGISTRY_ID, "urn:uuid:2014ca7f59ac46f495e32b4a67a51276"); mcard.setAttribute(RegistryObjectMetacardType.PUBLISHED_LOCATIONS, "location1"); when(federationAdminService.getRegistryMetacards()).thenReturn(Collections.singletonList( mcard)); federationAdmin.init(); Map<String, Object> nodes = federationAdmin.getLocalNodes(); Map<String, Object> customSlots = (Map<String, Object>) nodes.get("customSlots"); assertThat(customSlots, nullValue()); } @Test public void testBindEndpointNullReference() throws Exception { List<RegistryPackageType> regObjects = Collections.singletonList((RegistryPackageType) getRegistryObjectFromResource( "/csw-full-registry-package.xml")); when(federationAdminService.getRegistryObjects()).thenReturn(regObjects); mcard.setAttribute(RegistryObjectMetacardType.REGISTRY_ID, "urn:uuid:2014ca7f59ac46f495e32b4a67a51276"); when(federationAdminService.getRegistryMetacards()).thenReturn(Collections.singletonList( mcard)); federationAdmin.bindEndpoint(null); Map<String, Object> autoValues = (Map<String, Object>) federationAdmin.getLocalNodes() .get("autoPopulateValues"); assertThat(autoValues.size(), is(1)); Collection bindingValues = (Collection) autoValues.get("ServiceBinding"); assertThat(bindingValues.size(), is(0)); } @Test public void testBindEndpoint() throws Exception { List<RegistryPackageType> regObjects = Collections.singletonList((RegistryPackageType) getRegistryObjectFromResource( "/csw-full-registry-package.xml")); when(federationAdminService.getRegistryObjects()).thenReturn(regObjects); mcard.setAttribute(RegistryObjectMetacardType.REGISTRY_ID, "urn:uuid:2014ca7f59ac46f495e32b4a67a51276"); when(federationAdminService.getRegistryMetacards()).thenReturn(Collections.singletonList( mcard)); ServiceReference reference = mock(ServiceReference.class); CatalogEndpoint endpoint = mock(CatalogEndpoint.class); Map<String, String> props = new HashMap<>(); props.put(CatalogEndpoint.ID_KEY, "myId"); when(endpoint.getEndpointProperties()).thenReturn(props); when(context.getService(reference)).thenReturn(endpoint); federationAdmin.bindEndpoint(reference); Map<String, Object> autoValues = (Map<String, Object>) federationAdmin.getLocalNodes() .get("autoPopulateValues"); assertThat(autoValues.size(), is(1)); Collection bindingValues = (Collection) autoValues.get("ServiceBinding"); assertThat(bindingValues.size(), is(1)); Map<String, String> bindings = (Map<String, String>) bindingValues.iterator() .next(); assertThat(bindings.get(CatalogEndpoint.ID_KEY), equalTo("myId")); } @Test public void testUnbindEndpoint() throws Exception { List<RegistryPackageType> regObjects = Collections.singletonList((RegistryPackageType) getRegistryObjectFromResource( "/csw-full-registry-package.xml")); when(federationAdminService.getRegistryObjects()).thenReturn(regObjects); mcard.setAttribute(RegistryObjectMetacardType.REGISTRY_ID, "urn:uuid:2014ca7f59ac46f495e32b4a67a51276"); when(federationAdminService.getRegistryMetacards()).thenReturn(Collections.singletonList( mcard)); ServiceReference reference = mock(ServiceReference.class); CatalogEndpoint endpoint = mock(CatalogEndpoint.class); Map<String, String> props = new HashMap<>(); props.put(CatalogEndpoint.ID_KEY, "myId"); when(endpoint.getEndpointProperties()).thenReturn(props); when(context.getService(reference)).thenReturn(endpoint); federationAdmin.bindEndpoint(reference); federationAdmin.unbindEndpoint(reference); Map<String, Object> autoValues = (Map<String, Object>) federationAdmin.getLocalNodes() .get("autoPopulateValues"); assertThat(autoValues.size(), is(1)); Collection bindingValues = (Collection) autoValues.get("ServiceBinding"); assertThat(bindingValues.size(), is(0)); } @Test public void testRegenerateSources() throws Exception { federationAdmin.regenerateRegistrySources(Collections.singletonList("regId")); verify(sourceConfiguration).regenerateOneSource("regId"); } @Test public void testHandleEventCreate() throws Exception { performCreateEvent(); } @Test public void testHandleEventUpdate() throws Exception { performCreateEvent(); Dictionary<String, Object> eventProperties = new Hashtable<>(); mcard.setTitle("UpdatedTitle"); eventProperties.put("ddf.catalog.event.metacard", mcard); Event event = new Event("ddf/catalog/event/UPDATED", eventProperties); federationAdmin.handleEvent(event); List<Map<String, Object>> result = (List<Map<String, Object>>) federationAdmin.allRegistryMetacardsSummary() .get("nodes"); assertThat(result.size(), is(1)); Map<String, Object> mcardMap = result.get(0); assertThat(mcardMap.get(FederationAdmin.SUMMARY_NAME), is("UpdatedTitle")); } @Test public void testHandleEventDelete() throws Exception { performCreateEvent(); Dictionary<String, Object> eventProperties = new Hashtable<>(); eventProperties.put("ddf.catalog.event.metacard", mcard); Event event = new Event("ddf/catalog/event/DELETED", eventProperties); federationAdmin.handleEvent(event); List<Map<String, Object>> result = (List<Map<String, Object>>) federationAdmin.allRegistryMetacardsSummary() .get("nodes"); assertThat(result.size(), is(0)); } @Test public void testAllRegistryMetacardsSummary() throws Exception { Date timestamp = setupSummary(); List<Map<String, Object>> result = (List<Map<String, Object>>) federationAdmin.allRegistryMetacardsSummary() .get("nodes"); assertThat(result.size(), is(1)); Map<String, Object> mcardMap = result.get(0); assertSummary(mcardMap, timestamp); } @Test public void testAllRegistryMetacardsSummaryWithActionProvider() throws Exception { Action action = mock(Action.class); when(action.getId()).thenReturn("catalog.data.metacard.registry"); when(action.getUrl()).thenReturn(new URL("https://host/path")); when(multiActionProvider.canHandle(any())).thenReturn(true); when(multiActionProvider.getActions(any())).thenReturn(Collections.singletonList(action)); federationAdmin.setRegistryActionProvider(multiActionProvider); Date timestamp = setupSummary(); List<Map<String, Object>> result = (List<Map<String, Object>>) federationAdmin.allRegistryMetacardsSummary() .get("nodes"); assertThat(result.size(), is(1)); Map<String, Object> mcardMap = result.get(0); assertSummary(mcardMap, timestamp); assertThat(mcardMap.get("reportAction"), is("https://host/path")); } @Test public void testAllRegistryMetacardsSummaryWithActionProviderNoAction() throws Exception { when(multiActionProvider.canHandle(any())).thenReturn(true); when(multiActionProvider.getActions(any())).thenReturn(Collections.emptyList()); federationAdmin.setRegistryActionProvider(multiActionProvider); Date timestamp = setupSummary(); List<Map<String, Object>> result = (List<Map<String, Object>>) federationAdmin.allRegistryMetacardsSummary() .get("nodes"); assertThat(result.size(), is(1)); Map<String, Object> mcardMap = result.get(0); assertSummary(mcardMap, timestamp); } @Test public void testRegistryMetacard() throws Exception { when(federationAdminService.getRegistryObjectByRegistryId(any())).thenReturn( getRegistryObjectFromResource("/csw-full-registry-package.xml")); ArrayList<String> tags = new ArrayList<>(); tags.add(RegistryConstants.REGISTRY_TAG); mcard.setAttribute(Metacard.TAGS, tags); mcard.setAttribute(RegistryObjectMetacardType.REGISTRY_ID, "urn:uuid:2014ca7f59ac46f495e32b4a67a51276"); when(federationAdminService.getRegistryMetacardsByRegistryIds(any())).thenReturn(Collections.singletonList( mcard)); List<Map<String, Object>> result = (List<Map<String, Object>>) federationAdmin.registryMetacard( "urn:uuid:2014ca7f59ac46f495e32b4a67a51276") .get("nodes"); assertThat(result.size(), is(1)); Map<String, Object> mcardMap = result.get(0); assertThat(mcardMap.get("id"), is("urn:uuid:2014ca7f59ac46f495e32b4a67a51276")); } @Test(expected = IllegalArgumentException.class) public void testRegistryMetacardInvalidRegistryId() throws Exception { federationAdmin.registryMetacard("invalidRegId"); } @Test public void testRegistryMetacardRegistryIdNotFound() throws Exception { when(federationAdminService.getRegistryObjectByRegistryId(any())).thenThrow(new FederationAdminException( "Not found")); when(federationAdminService.getRegistryMetacardsByRegistryIds(any())).thenReturn(Collections.emptyList()); List<Map<String, Object>> result = (List<Map<String, Object>>) federationAdmin.registryMetacard( "urn:uuid:2014ca7f59ac46f495e32b4a67a51276") .get("nodes"); assertThat(result.size(), is(0)); } private void performCreateEvent() throws Exception { List<Map<String, Object>> result = (List<Map<String, Object>>) federationAdmin.allRegistryMetacardsSummary() .get("nodes"); assertThat(result.size(), is(0)); Date timestamp = setupSummary(false); Dictionary<String, Object> eventProperties = new Hashtable<>(); eventProperties.put("ddf.catalog.event.metacard", mcard); Event event = new Event("ddf/catalog/event/CREATED", eventProperties); federationAdmin.handleEvent(event); result = (List<Map<String, Object>>) federationAdmin.allRegistryMetacardsSummary() .get("nodes"); assertThat(result.size(), is(1)); Map<String, Object> mcardMap = result.get(0); assertSummary(mcardMap, timestamp); } private Date setupSummary() throws Exception { return setupSummary(true); } private Date setupSummary(boolean setupAdminService) throws Exception { Date now = new Date(); ArrayList<String> tags = new ArrayList<>(); tags.add(RegistryConstants.REGISTRY_TAG); mcard.setAttribute(Metacard.TAGS, tags); mcard.setTitle("TestTitle"); mcard.setCreatedDate(now); mcard.setModifiedDate(now); mcard.setAttribute(RegistryObjectMetacardType.REGISTRY_LOCAL_NODE, true); mcard.setAttribute(RegistryObjectMetacardType.REGISTRY_IDENTITY_NODE, true); if (setupAdminService) { when(federationAdminService.getRegistryMetacards()).thenReturn(Collections.singletonList( mcard)); } return now; } private void assertSummary(Map<String, Object> mcardMap, Date timestamp) { assertThat(mcardMap.get(FederationAdmin.SUMMARY_METACARD_ID), is("someUUID")); assertThat(mcardMap.get(FederationAdmin.SUMMARY_REGISTRY_ID), is("myId")); assertThat(mcardMap.get(FederationAdmin.SUMMARY_NAME), is("TestTitle")); assertThat(mcardMap.get(Metacard.CREATED), is(timestamp)); assertThat(mcardMap.get(Metacard.MODIFIED), is(timestamp)); assertThat(mcardMap.get(FederationAdmin.SUMMARY_IDENTITY_NODE), is(true)); assertThat(mcardMap.get(FederationAdmin.SUMMARY_LOCAL_NODE), is(true)); } private void copyJsonFileToKarafDir() throws Exception { File etc = folder.getRoot(); File registry = folder.newFolder("registry"); File jsonFile = new File(registry, "registry-custom-slots.json"); FileOutputStream outputStream = new FileOutputStream(jsonFile); InputStream inputStream = this.getClass() .getResourceAsStream("/etc/registry/registry-custom-slots.json"); IOUtils.copy(inputStream, outputStream); inputStream.close(); outputStream.close(); System.setProperty("karaf.etc", etc.getCanonicalPath()); } private RegistryPackageType getRegistryObjectFromResource(String path) throws ParserException { RegistryObjectType registryObject = null; JAXBElement<RegistryObjectType> jaxbRegistryObject = parser.unmarshal(configurator, JAXBElement.class, getClass().getResourceAsStream(path)); if (jaxbRegistryObject != null) { registryObject = jaxbRegistryObject.getValue(); } return (RegistryPackageType) registryObject; } private Map<String, Object> getMapFromRegistryObject(RegistryPackageType registryObject) { return mapConverter.convert(registryObject); } private RegistryPackageType getRegistryObjectFromMap(Map<String, Object> registryMap) { return typeConverter.convert(registryMap) .get(); } private Metacard getTestMetacard() { return new MetacardImpl(new RegistryObjectMetacardType()); } }