protected URL createSnapshot(final String foreignSource) throws MalformedURLException { System.err.println("--- creating snapshot for " + foreignSource + " ---"); Requisition pending = m_pending.getRequisition(foreignSource); Requisition deployed = m_active.getRequisition(foreignSource); final Date deployedDate = deployed == null ? null : deployed.getDate(); final Date pendingDate = pending == null ? null : pending.getDate(); if (deployedDate == null) return RequisitionFileUtils.createSnapshot(m_pending, foreignSource, pending.getDate()) .toURI() .toURL(); if (pendingDate == null) return m_active.getRequisitionURL(foreignSource); final URL url; if (deployedDate.before(pendingDate)) { url = RequisitionFileUtils.createSnapshot(m_pending, foreignSource, pendingDate) .toURI() .toURL(); } else { url = m_active.getRequisitionURL(foreignSource); } System.err.println("deployedDate = " + deployedDate); System.err.println("pendingDate = " + pendingDate); System.err.println("url = " + url); return url; }
private void cleanUpSnapshots(final Requisition requisition) { final String foreignSource = requisition.getForeignSource(); final Date pendingDate = m_pendingForeignSourceRepository.getRequisitionDate(foreignSource); final List<File> pendingSnapshots = RequisitionFileUtils.findSnapshots(m_pendingForeignSourceRepository, foreignSource); if (pendingDate != null) { /* determine whether to delete the pending requisition */ boolean deletePendingRequisition = true; if (pendingSnapshots.size() > 0) { for (final File pendingSnapshotFile : pendingSnapshots) { if (isNewer(pendingSnapshotFile, pendingDate)) { // the pending file is newer than an in-process snapshot, don't delete it deletePendingRequisition = false; break; } } } if (deletePendingRequisition) { m_pendingForeignSourceRepository.delete(requisition); } } /* determine whether this requisition was imported from a snapshot, and if so, delete its snapshot file */ RequisitionFileUtils.deleteResourceIfSnapshot(requisition); final Date deployedDate = m_deployedForeignSourceRepository.getRequisitionDate(foreignSource); if (deployedDate != null) { RequisitionFileUtils.deleteSnapshotsOlderThan( getPendingForeignSourceRepository(), foreignSource, deployedDate); } }
@Test public void multipleSnapshotTest() throws URISyntaxException, InterruptedException { Requisition pendingReq = new Requisition("test"); pendingReq.putNode(createNode("1")); m_pending.save(pendingReq); m_pending.flush(); final String foreignSource = pendingReq.getForeignSource(); pendingReq = m_pending.getRequisition(foreignSource); final File pendingSnapshotA = RequisitionFileUtils.createSnapshot(m_pending, foreignSource, pendingReq.getDate()); // Now, start a new pending update after the original snapshot is "in progress" pendingReq.updateDateStamp(); m_pending.save(pendingReq); m_pending.flush(); final File pendingSnapshotB = RequisitionFileUtils.createSnapshot(m_pending, foreignSource, pendingReq.getDate()); // "import" the A snapshot m_repository.importResourceRequisition(new FileSystemResource(pendingSnapshotA)); assertFalse(pendingSnapshotA.exists()); assertTrue(pendingSnapshotB.exists()); // since there's still a newer snapshot in-progress, it is safe to delete the pending test.xml URL pendingUrl = m_pending.getRequisitionURL(foreignSource); assertNotNull(pendingUrl); assertFalse(new File(pendingUrl.toURI()).exists()); // then, "import" the B snapshot final Requisition bReq = m_repository.importResourceRequisition(new FileSystemResource(pendingSnapshotB)); assertFalse(pendingSnapshotA.exists()); assertFalse(pendingSnapshotB.exists()); // now the pending test.xml should be gone pendingUrl = m_pending.getRequisitionURL(foreignSource); assertNotNull(pendingUrl); assertFalse(new File(pendingUrl.toURI()).exists()); // the last (B) pending import should match the deployed final Requisition deployedRequisition = m_active.getRequisition(foreignSource); assertEquals(deployedRequisition.getDate().getTime(), bReq.getDate().getTime()); }
@Test public void simpleSnapshotTest() throws URISyntaxException { Requisition pendingReq = new Requisition("test"); pendingReq.putNode(createNode("1")); m_pending.save(pendingReq); m_pending.flush(); pendingReq = m_pending.getRequisition(pendingReq.getForeignSource()); final File pendingSnapshot = RequisitionFileUtils.createSnapshot( m_pending, pendingReq.getForeignSource(), pendingReq.getDate()); m_repository.importResourceRequisition(new FileSystemResource(pendingSnapshot)); assertFalse(pendingSnapshot.exists()); final URL pendingUrl = m_pending.getRequisitionURL(pendingReq.getForeignSource()); final File pendingFile = new File(pendingUrl.toURI()); assertFalse(pendingFile.exists()); }
@Test public void testSpc674RaceCondition() throws Exception { final String foreignSource = "spc674"; System.err.println( "=== create a requisition like the ReST service does, import it immediately ==="); final Requisition initial = new Requisition(foreignSource); initial.putNode(createNode("1")); initial.updateDateStamp(); m_pending.save(initial); final URL node1Snapshot = createSnapshot(foreignSource); Resource resource = new UrlResource(node1Snapshot); doImport(resource); Thread.sleep(5); List<String> files = getImports(foreignSource); assertEquals(1, files.size()); System.err.println("=== create another snapshot, but don't import it yet ==="); initial.putNode(createNode("2")); initial.updateDateStamp(); m_pending.save(initial); final URL node2Snapshot = createSnapshot(foreignSource); Thread.sleep(5); files = getImports(foreignSource); assertEquals(3, files.size()); System.err.println("=== create yet another snapshot, and don't import it yet ==="); initial.putNode(createNode("3")); initial.updateDateStamp(); m_pending.save(initial); final URL node3Snapshot = createSnapshot(foreignSource); Thread.sleep(5); files = getImports(foreignSource); assertEquals(4, files.size()); System.err.println("=== import of the second file finishes ==="); doImport(new UrlResource(node2Snapshot)); Thread.sleep(5); files = getImports(foreignSource); assertEquals(2, files.size()); System.err.println("=== fourth node is sent to the ReST interface ==="); final Requisition currentPending = RequisitionFileUtils.getLatestPendingOrSnapshotRequisition(m_pending, foreignSource); assertNotNull(currentPending); assertEquals(initial.getDate(), currentPending.getDate()); currentPending.putNode(createNode("4")); currentPending.updateDateStamp(); m_pending.save(currentPending); final URL node4Snapshot = createSnapshot(foreignSource); Thread.sleep(5); files = getImports(foreignSource); assertEquals(4, files.size()); System.err.println("=== import of the third file finishes ==="); doImport(new UrlResource(node3Snapshot)); Thread.sleep(5); files = getImports(foreignSource); assertEquals(2, files.size()); System.err.println("=== import of the fourth file finishes ==="); doImport(new UrlResource(node4Snapshot)); Thread.sleep(5); files = getImports(foreignSource); assertEquals(1, files.size()); }
private boolean isNewer(final File snap, final Date date) { return RequisitionFileUtils.isNewer(snap, date); }