package org.gbif.ipt.action.admin;
import org.gbif.dwc.terms.DwcTerm;
import org.gbif.ipt.config.AppConfig;
import org.gbif.ipt.config.Constants;
import org.gbif.ipt.model.Extension;
import org.gbif.ipt.model.ExtensionMapping;
import org.gbif.ipt.model.Organisation;
import org.gbif.ipt.model.PropertyMapping;
import org.gbif.ipt.model.Resource;
import org.gbif.ipt.service.AlreadyExistingException;
import org.gbif.ipt.service.ImportException;
import org.gbif.ipt.service.InvalidFilenameException;
import org.gbif.ipt.service.PublicationException;
import org.gbif.ipt.service.admin.RegistrationManager;
import org.gbif.ipt.service.manage.impl.ResourceManagerImpl;
import org.gbif.ipt.service.manage.impl.ResourceManagerImplTest;
import org.gbif.ipt.service.registry.RegistryManager;
import org.gbif.ipt.struts2.SimpleTextProvider;
import org.gbif.ipt.task.GenerateDwcaFactory;
import org.gbif.ipt.task.ReportHandler;
import org.gbif.metadata.eml.Eml;
import org.gbif.metadata.eml.EmlFactory;
import org.gbif.utils.file.FileUtils;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.UUID;
import javax.xml.parsers.ParserConfigurationException;
import com.google.common.collect.Sets;
import org.junit.Before;
import org.junit.Test;
import org.xml.sax.SAXException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class PublishAllResourcesActionTest {
private PublishAllResourcesAction action;
@Before
public void setup()
throws IOException, ParserConfigurationException, SAXException, AlreadyExistingException, ImportException,
InvalidFilenameException {
ResourceManagerImplTest test = new ResourceManagerImplTest();
ResourceManagerImpl mockResourceManager = test.getResourceManagerImpl();
// prepare and add resource
Resource resource = test.getNonRegisteredMetadataOnlyResource();
// ensure resource has mandatory metadata filled in, meaning its EML validates and it has a valid publishing org
Eml eml = EmlFactory.build(FileUtils.classpathStream("data/eml.xml"));
eml.setEmlVersion(BigDecimal.valueOf(3.0));
eml.setPreviousEmlVersion(BigDecimal.valueOf(1.0));
resource.setEml(eml);
// assign publishing organisation to resource
Organisation o = new Organisation();
o.setName("TestOrg");
o.setKey(UUID.randomUUID().toString());
resource.setOrganisation(o);
// mock successful lookup for organization by key (done by RegistrationManager in EmlValidator)
RegistrationManager mockRegistrationManager = mock(RegistrationManager.class);
when(mockRegistrationManager.get(any(UUID.class))).thenReturn(o);
mockResourceManager.save(resource);
// mock generateDwca() throwing PublicationException, not actually possible, but used to test failed publications
GenerateDwcaFactory mockDwcaFactory = mockResourceManager.getDwcaFactory();
when(mockDwcaFactory.create(any(Resource.class), any(ReportHandler.class)))
.thenThrow(new PublicationException(PublicationException.TYPE.DWCA, "Mock exception"));
// mock finding versioned EML file - not important which one
File emlXML = File.createTempFile("eml-1.1", ".xml");
when(test.getMockedDataDir().resourceEmlFile(anyString(), any(BigDecimal.class))).thenReturn(emlXML);
// mock finding versioned RTF file - not important which one
File rtf = File.createTempFile("short-1.1", ".rtf");
when(test.getMockedDataDir().resourceRtfFile(anyString(), any(BigDecimal.class))).thenReturn(rtf);
// mock action
action = new PublishAllResourcesAction(mock(SimpleTextProvider.class), mock(AppConfig.class),
mockRegistrationManager, mockResourceManager, mock(RegistryManager.class));
}
@Test
public void testExecuteFailsOnPublish() throws Exception {
Resource resource = action.resourceManager.get("res2");
// make a few pre-publication assertions
assertEquals(BigDecimal.valueOf(1.0), resource.getReplacedEmlVersion());
assertEquals(BigDecimal.valueOf(3.0), resource.getEmlVersion());
assertEquals(BigDecimal.valueOf(3.0), resource.getEml().getEmlVersion());
// populate a source mapping, and assign it to resource
ExtensionMapping em = new ExtensionMapping();
PropertyMapping pm = new PropertyMapping();
pm.setTerm(DwcTerm.occurrenceID);
pm.setIndex(1);
em.setFields(Sets.newHashSet(pm));
Extension extension = new Extension();
extension.setRowType(Constants.DWC_ROWTYPE_OCCURRENCE);
em.setExtension(extension);
resource.addMapping(em);
// trigger publish all
String result = action.execute();
// make some post-failed-publication assertions
assertEquals("success", result);
// PublicationException logged in ActionError
assertEquals(2, action.getActionErrors().size());
// # of publish event failures for resource captured
assertEquals(1, action.resourceManager.getProcessFailures().size());
assertFalse(action.resourceManager.hasMaxProcessFailures(resource));
assertEquals(BigDecimal.valueOf(3.0), resource.getEml().getEmlVersion());
assertNull(resource.getNextPublished());
assertNull(resource.getLastPublished());
// trigger publish all again
action.execute();
assertFalse(action.resourceManager.hasMaxProcessFailures(resource));
// # of publish event failures for resource captured, should have incremented by 1
assertEquals(2, action.resourceManager.getProcessFailures().size());
// trigger publish all again
action.execute();
assertTrue(action.resourceManager.hasMaxProcessFailures(resource));
// # of publish event failures for resource captured, should have incremented by 1
assertEquals(3, action.resourceManager.getProcessFailures().size());
// trigger publish all again
action.execute();
assertTrue(action.resourceManager.hasMaxProcessFailures(resource));
// since max failures was reached, publication not scheduled, and number of publication failures stays the same
assertEquals(3, action.resourceManager.getProcessFailures().size());
}
}