diff --git a/src/main/java/it/inaf/ia2/transfer/service/ArchiveService.java b/src/main/java/it/inaf/ia2/transfer/service/ArchiveService.java index 4e8fc81d3814e7d5752214e3879f20f812797a5d..c659b02a16cc091463a0d6b9454defe6e41302a5 100644 --- a/src/main/java/it/inaf/ia2/transfer/service/ArchiveService.java +++ b/src/main/java/it/inaf/ia2/transfer/service/ArchiveService.java @@ -11,6 +11,7 @@ import it.inaf.ia2.transfer.auth.TokenPrincipal; import it.inaf.ia2.transfer.persistence.FileDAO; import it.inaf.ia2.transfer.persistence.JobDAO; import it.inaf.ia2.transfer.persistence.model.FileInfo; +import it.inaf.oats.vospace.datamodel.NodeUtils; import it.inaf.oats.vospace.exception.InternalFaultException; import it.inaf.oats.vospace.exception.PermissionDeniedException; import it.inaf.oats.vospace.exception.QuotaExceededException; @@ -26,8 +27,8 @@ import java.io.OutputStream; import java.io.UncheckedIOException; import java.nio.file.Files; import java.security.Principal; +import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -235,29 +236,46 @@ public class ArchiveService { } private String getCommonParent(List<ArchiveEntryDescriptor> entryDescriptors) { - - List<String> vosPaths = entryDescriptors.stream().map(ed -> ed.getVosPath()) + + if(entryDescriptors.isEmpty()) { + throw new IllegalArgumentException("Empty descriptors list"); + } else if(entryDescriptors.size() == 1) { + return NodeUtils.getParentPath(entryDescriptors.get(0).getVosPath()); + } + + // Get list of parent paths + List<String[]> vosParentPaths = entryDescriptors.stream().map( + ed -> NodeUtils.getParentPath(ed.getVosPath()).split("/")) .collect(Collectors.toList()); - - String commonParent = null; - for (String vosPath : vosPaths) { - if (commonParent == null) { - commonParent = vosPath.substring(0, vosPath.lastIndexOf("/")); - } else { - StringBuilder newCommonParent = new StringBuilder(); - boolean same = true; - int lastSlashPos = vosPath.lastIndexOf("/"); - for (int i = 0; same && i < Math.min(commonParent.length(), vosPath.length()) && i <= lastSlashPos; i++) { - if (commonParent.charAt(i) == vosPath.charAt(i)) { - newCommonParent.append(commonParent.charAt(i)); - } else { - same = false; - } - } - commonParent = newCommonParent.toString(); + + // Get minimum size of split vosParentPaths arrays + + int minSize = vosParentPaths.stream() + .mapToInt(v->v.length).min().orElseThrow(); + + switch(minSize) { + case 0: + return "/"; + + case 1: + // this should never happen + throw new IllegalArgumentException("Invalid vosPath"); + } + + StringBuilder sb = new StringBuilder(); + + for(int i = 1; i < minSize; i++) { + List<String> elements = new ArrayList<>(); + for(String[] s : vosParentPaths) { + elements.add(s[i]); } + String sample = elements.get(0); + if(elements.stream().allMatch(e->e.equals(sample))) + sb.append("/").append(sample); } - return commonParent.substring(0, commonParent.lastIndexOf("/")); + + return sb.toString(); + } private abstract class ArchiveHandler<O extends OutputStream, E> implements AutoCloseable { diff --git a/src/test/java/it/inaf/ia2/transfer/service/ArchiveServiceTest.java b/src/test/java/it/inaf/ia2/transfer/service/ArchiveServiceTest.java index 356fcfeb66e14526a8aeb1d5fbc7c37247a6a495..59b226323d062134d39c7ea2c431763bceabef11 100644 --- a/src/test/java/it/inaf/ia2/transfer/service/ArchiveServiceTest.java +++ b/src/test/java/it/inaf/ia2/transfer/service/ArchiveServiceTest.java @@ -11,7 +11,6 @@ import it.inaf.ia2.transfer.persistence.JobDAO; import it.inaf.ia2.transfer.persistence.model.FileInfo; import it.inaf.oats.vospace.exception.QuotaExceededException; import it.inaf.oats.vospace.parent.exchange.ArchiveEntryDescriptor; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -22,7 +21,6 @@ import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Map; import java.util.function.Function; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -37,10 +35,7 @@ import org.junit.jupiter.api.Test; import org.kamranzafar.jtar.TarEntry; import org.kamranzafar.jtar.TarInputStream; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import org.mockito.Mockito; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -48,12 +43,8 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.http.HttpMethod; -import org.springframework.http.client.ClientHttpResponse; import org.springframework.test.context.ContextConfiguration; import org.springframework.util.FileSystemUtils; -import org.springframework.web.client.RequestCallback; -import org.springframework.web.client.ResponseExtractor; import org.springframework.web.client.RestTemplate; @SpringBootTest @@ -87,7 +78,6 @@ public class ArchiveServiceTest { FileSystemUtils.deleteRecursively(tmpDir); } - // TODO: refactor tests @Test public void testTarGeneration() throws Exception { @@ -241,8 +231,10 @@ public class ArchiveServiceTest { try (InputStream is = testArchiveHandler.getInputStream()) { E entry; while ((entry = testArchiveHandler.getNextEntry()) != null) { - assertFalse(i >= expectedSequence.size(), "Found more entries than in expected sequence"); - assertEquals(expectedSequence.get(i), testArchiveHandler.getName(entry)); + assertFalse(i >= expectedSequence.size(), "Found more entries than in expected sequence"); + assertEquals(type.equals(ArchiveJob.Type.ZIP) ? + "/" + expectedSequence.get(i) : expectedSequence.get(i), + testArchiveHandler.getName(entry)); if (!testArchiveHandler.isDirectory(entry)) { assertEquals("some data", new String(is.readAllBytes())); }