/** * 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.service.impl; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.argThat; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Set; 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.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import com.google.common.collect.ImmutableList; import ddf.catalog.data.Attribute; import ddf.catalog.data.Metacard; import ddf.catalog.data.impl.AttributeImpl; import ddf.catalog.data.impl.MetacardImpl; @RunWith(MockitoJUnitRunner.class) public class RegistryPublicationServiceImplTest { private FederationAdminService federationAdminService; private RegistryPublicationServiceImpl registryPublicationService; private MetacardImpl metacard; @Mock private BundleContext bundleContext; @Mock private ServiceReference serviceReference; @Mock private RegistryStore registryStore; private static final String REGISTRY_STORE_REGISTRY_ID = "registryStoreRegistryId"; private static final String REGISTRY_STORE_ID = "registryStoreId"; @Before public void setup() { federationAdminService = mock(FederationAdminService.class); registryPublicationService = Mockito.spy(new RegistryPublicationServiceImpl()); registryPublicationService.setFederationAdminService(federationAdminService); metacard = new MetacardImpl(new RegistryObjectMetacardType()); metacard.setId("mcardId"); metacard.setTags(Collections.singleton(RegistryConstants.REGISTRY_TAG)); when(registryPublicationService.getBundleContext()).thenReturn(bundleContext); when(bundleContext.getService(serviceReference)).thenReturn(registryStore); doReturn(REGISTRY_STORE_REGISTRY_ID).when(registryStore) .getRegistryId(); doReturn(REGISTRY_STORE_ID).when(registryStore) .getId(); registryPublicationService.bindRegistryStore(serviceReference); } @Test(expected = FederationAdminException.class) public void testPublishInvalidRegistryId() throws Exception { when(federationAdminService.getRegistryMetacardsByRegistryIds(any(List.class))).thenReturn( Collections.emptyList()); registryPublicationService.publish(null, REGISTRY_STORE_REGISTRY_ID); } @Test public void testPublishAlreadyPublished() throws Exception { String publishThisRegistryId = "publishThisRegistryId"; Date now = new Date(); Date before = new Date(now.getTime() - 100000); Attribute publishedLocationsAttribute = new AttributeImpl(RegistryObjectMetacardType.PUBLISHED_LOCATIONS, Collections.singletonList(REGISTRY_STORE_REGISTRY_ID)); metacard.setAttribute(publishedLocationsAttribute); metacard.setAttribute(new AttributeImpl(RegistryObjectMetacardType.LAST_PUBLISHED, before)); when(federationAdminService.getRegistryMetacardsByRegistryIds(any(List.class))).thenReturn( Collections.singletonList(metacard)); registryPublicationService.publish(publishThisRegistryId, REGISTRY_STORE_REGISTRY_ID); verify(federationAdminService, never()).addRegistryEntry(metacard, Collections.singleton(REGISTRY_STORE_REGISTRY_ID)); verify(federationAdminService, never()).updateRegistryEntry(metacard); Attribute publicationsAfter = metacard.getAttribute(RegistryObjectMetacardType.PUBLISHED_LOCATIONS); assertThat(publicationsAfter, is(equalTo(publishedLocationsAttribute))); Attribute lastPublished = metacard.getAttribute(RegistryObjectMetacardType.LAST_PUBLISHED); assertThat(lastPublished, notNullValue()); Date lastPublishedDate = (Date) lastPublished.getValue(); assertThat(lastPublishedDate, is(equalTo(before))); } @Test public void testPublishAddAnotherSource() throws Exception { String someAlreadyPublishedRegistryId = "someAlreadyPublishedRegistryId"; String publishThisRegistryId = "publishThisRegistryId"; Date now = new Date(); Date before = new Date(now.getTime() - 100000); Attribute publishedLocationsAttribute = new AttributeImpl(RegistryObjectMetacardType.PUBLISHED_LOCATIONS, Collections.singletonList(someAlreadyPublishedRegistryId)); metacard.setAttribute(publishedLocationsAttribute); metacard.setAttribute(new AttributeImpl(RegistryObjectMetacardType.LAST_PUBLISHED, before)); when(federationAdminService.getRegistryMetacardsByRegistryIds(any(List.class))).thenReturn( Collections.singletonList(metacard)); registryPublicationService.publish(publishThisRegistryId, REGISTRY_STORE_REGISTRY_ID); verify(federationAdminService).addRegistryEntry(metacard, Collections.singleton(REGISTRY_STORE_ID)); verify(federationAdminService).updateRegistryEntry(metacard); Attribute lastPublished = metacard.getAttribute(RegistryObjectMetacardType.LAST_PUBLISHED); assertThat(lastPublished, notNullValue()); Date lastPublishedDate = (Date) lastPublished.getValue(); assertThat(lastPublishedDate.after(before), is(equalTo(true))); Attribute publicationsAfter = metacard.getAttribute(RegistryObjectMetacardType.PUBLISHED_LOCATIONS); List<Serializable> publications = publicationsAfter.getValues(); assertThat(publications, hasItem(REGISTRY_STORE_REGISTRY_ID)); } @Test public void testPublish() throws Exception { doReturn(Collections.singletonList(metacard)).when(federationAdminService) .getRegistryMetacardsByRegistryIds(any(List.class)); String publishThisRegistryId = "registryId"; Date now = new Date(); Date before = new Date(now.getTime() - 100000); metacard.setAttribute(new AttributeImpl(RegistryObjectMetacardType.LAST_PUBLISHED, before)); registryPublicationService.publish(publishThisRegistryId, REGISTRY_STORE_REGISTRY_ID); verify(federationAdminService).addRegistryEntry(metacard, Collections.singleton(REGISTRY_STORE_ID)); verify(federationAdminService).updateRegistryEntry(metacard); Attribute lastPublished = metacard.getAttribute(RegistryObjectMetacardType.LAST_PUBLISHED); assertThat(lastPublished, notNullValue()); Date lastPublishedDate = (Date) lastPublished.getValue(); assertThat(lastPublishedDate.after(before), is(equalTo(true))); Attribute publicationsAfter = metacard.getAttribute(RegistryObjectMetacardType.PUBLISHED_LOCATIONS); List<Serializable> publications = publicationsAfter.getValues(); assertThat(publications, hasItem(REGISTRY_STORE_REGISTRY_ID)); } @Test public void testUnpublish() throws Exception { String unPublishThisRegistryId = "unPublishThisRegistryId"; Date now = new Date(); Date before = new Date(now.getTime() - 100000); metacard.setAttribute(new AttributeImpl(RegistryObjectMetacardType.LAST_PUBLISHED, before)); metacard.setAttribute(new AttributeImpl(RegistryObjectMetacardType.PUBLISHED_LOCATIONS, Collections.singletonList(REGISTRY_STORE_REGISTRY_ID))); when(federationAdminService.getRegistryMetacardsByRegistryIds(any(List.class))).thenReturn( Collections.singletonList(metacard)); registryPublicationService.unpublish(unPublishThisRegistryId, REGISTRY_STORE_REGISTRY_ID); verify(federationAdminService).deleteRegistryEntriesByRegistryIds(Collections.singletonList( unPublishThisRegistryId), Collections.singleton(REGISTRY_STORE_ID)); verify(federationAdminService).updateRegistryEntry(metacard); Attribute lastPublished = metacard.getAttribute(RegistryObjectMetacardType.LAST_PUBLISHED); assertThat(lastPublished, notNullValue()); Date lastPublishedDate = (Date) lastPublished.getValue(); assertThat(lastPublishedDate.after(before), is(equalTo(true))); Attribute publicationsAfter = metacard.getAttribute(RegistryObjectMetacardType.PUBLISHED_LOCATIONS); assertThat(publicationsAfter.getValue(), is("No_Publications")); } @Test public void testUnpublishNoCurrentlyPublished() throws Exception { metacard.setAttribute(new AttributeImpl(RegistryObjectMetacardType.PUBLISHED_LOCATIONS, Collections.emptyList())); when(federationAdminService.getRegistryMetacardsByRegistryIds(any(List.class))).thenReturn( Collections.singletonList(metacard)); registryPublicationService.unpublish("regId", "sourceId"); verify(federationAdminService, never()).deleteRegistryEntriesByRegistryIds(Collections.singletonList("regId"), Collections.singleton("sourceId")); verify(federationAdminService, never()).updateRegistryEntry(metacard); } @Test public void testUpdateNoPublications() throws Exception { MetacardImpl metacard = new MetacardImpl(); metacard.setAttribute(RegistryObjectMetacardType.PUBLISHED_LOCATIONS, new ArrayList<>()); registryPublicationService.update(metacard); verify(federationAdminService, never()).updateRegistryEntry(metacard); } @Test public void testUpdateEmptyPublications() throws Exception { MetacardImpl metacard = new MetacardImpl(); registryPublicationService.update(metacard); verify(federationAdminService, never()).updateRegistryEntry(metacard); } @Test public void testUpdate() throws Exception { String registryId1 = "registryId1"; String registryId2 = "registryId2"; String registryId3 = "registryId3"; String storeId1 = "store1"; String storeId3 = "store3"; // Purposely leave out mock for registry store 2 // so a store id won't be found for registryId2 // Not a likely case but should be handled RegistryStore store1 = mock(RegistryStore.class); when(store1.getId()).thenReturn(storeId1); when(store1.getRegistryId()).thenReturn(registryId1); RegistryStore store3 = mock(RegistryStore.class); when(store3.getId()).thenReturn(storeId3); when(store3.getRegistryId()).thenReturn(registryId3); when(bundleContext.getService(serviceReference)).thenReturn(store1); registryPublicationService.bindRegistryStore(serviceReference); when(bundleContext.getService(serviceReference)).thenReturn(store3); registryPublicationService.bindRegistryStore(serviceReference); List<Serializable> publishedLocations = ImmutableList.of(registryId1, registryId2, registryId3); Date now = new Date(); Date before = new Date(now.getTime() - 100000); MetacardImpl metacard = new MetacardImpl(); metacard.setAttribute(new AttributeImpl(RegistryObjectMetacardType.PUBLISHED_LOCATIONS, publishedLocations)); metacard.setAttribute(new AttributeImpl(RegistryObjectMetacardType.LAST_PUBLISHED, before)); registryPublicationService.update(metacard); // update will only be callled with storeIds 1 and 3, 2 didn't have a storeId match for registryId2 verify(federationAdminService, times(1)).updateRegistryEntry(eq(metacard), (Set<String>) argThat(contains(storeId1, storeId3))); verify(federationAdminService, times(1)).updateRegistryEntry(metacard); Attribute lastPublished = metacard.getAttribute(RegistryObjectMetacardType.LAST_PUBLISHED); assertThat(lastPublished, notNullValue()); Date lastPublishedDate = (Date) lastPublished.getValue(); assertThat(lastPublishedDate.after(before), is(equalTo(true))); } @Test public void testUpdateException() throws Exception { doThrow(new FederationAdminException("Test Error")).when(federationAdminService) .updateRegistryEntry(any(Metacard.class), any(Set.class)); MetacardImpl mcard = new MetacardImpl(); mcard.setAttribute(RegistryObjectMetacardType.PUBLISHED_LOCATIONS, REGISTRY_STORE_REGISTRY_ID); registryPublicationService.update(mcard); verify(federationAdminService).addRegistryEntry(mcard, Collections.singleton(REGISTRY_STORE_ID)); } @Test(expected = FederationAdminException.class) public void testNoRegistryStores() throws Exception { doReturn(Collections.singletonList(metacard)).when(federationAdminService) .getRegistryMetacardsByRegistryIds(any(List.class)); registryPublicationService.unbindRegistryStore(serviceReference); String publishThisRegistryId = "publishThisRegistryId"; Date now = new Date(); Date before = new Date(now.getTime() - 100000); MetacardImpl metacard = new MetacardImpl(); Attribute publishedLocationsAttribute = new AttributeImpl(RegistryObjectMetacardType.PUBLISHED_LOCATIONS, Collections.singletonList(REGISTRY_STORE_REGISTRY_ID)); metacard.setAttribute(publishedLocationsAttribute); metacard.setAttribute(new AttributeImpl(RegistryObjectMetacardType.LAST_PUBLISHED, before)); registryPublicationService.publish(publishThisRegistryId, REGISTRY_STORE_REGISTRY_ID); verify(federationAdminService, never()).updateRegistryEntry(metacard); Attribute publicationsAfter = metacard.getAttribute(RegistryObjectMetacardType.PUBLISHED_LOCATIONS); assertThat(publicationsAfter, is(equalTo(publishedLocationsAttribute))); Attribute lastPublished = metacard.getAttribute(RegistryObjectMetacardType.LAST_PUBLISHED); assertThat(lastPublished, notNullValue()); Date lastPublishedDate = (Date) lastPublished.getValue(); assertThat(lastPublishedDate, is(equalTo(before))); } @Test public void testBindRegistryStore() { registryPublicationService.bindRegistryStore(serviceReference); } @Test public void testBindRegistryStoreNullServiceReference() { registryPublicationService.bindRegistryStore(null); } @Test public void testUnBindRegistryStore() { registryPublicationService.unbindRegistryStore(serviceReference); } @Test public void testUnBindRegistryStoreNullServiceReference() { registryPublicationService.unbindRegistryStore(null); } }