@Test public void testLoad() throws Exception { Configuration configuration = new Configuration("", ""); Prodigy.configuration(configuration); AmazonS3 s3 = mock(AmazonS3.class); ListObjectsV2Result result = new ListObjectsV2Result(); S3ObjectSummary objectSummary = new S3ObjectSummary(); objectSummary.setKey("repository-test-1.jar"); result.getObjectSummaries().add(objectSummary); result.setTruncated(false); doReturn(result).when(s3).listObjectsV2(anyString()); Repository repository = spy(new Repository(s3)); doReturn(false).when(repository, "exists", anyString()); doNothing().when(repository, "create", anyString()); List<String> files = new ArrayList<>(); doReturn(files).when(repository, "list", anyString()); doAnswer(i -> { Collection<String> add = i.getArgument(1); assertThat(add.size(), is(1)); assertTrue(add.contains("repository-test-1.jar")); files.addAll(add); return null; }).when(repository, "create", anyString(), any(Collection.class)); doAnswer(i -> { Collection<String> remove = i.getArgument(1); assertTrue(remove.isEmpty()); files.removeAll(remove); return null; }).when(repository, "delete", anyString(), any(Collection.class)); doAnswer(i -> { List<URL> urls = i.getArgument(0); assertThat(urls.size(), is(1)); assertTrue(urls.get(0).toString().endsWith("repository-test-1.jar")); return Thread.currentThread().getContextClassLoader(); }).when(repository, "newLoader", any(List.class)); doAnswer(i -> { return new ArrayList<>(); }).when(repository, "readFaults", any(ClassLoader.class)); Map<String, Class<? extends Fault>> faults = repository.load(); assertTrue(faults.isEmpty()); verifyPrivate(repository, times(1)).invoke("create", anyString()); s3 = mock(AmazonS3.class); result = new ListObjectsV2Result(); result.setTruncated(false); doReturn(result).when(s3).listObjectsV2(anyString()); repository = spy(new Repository(s3)); doReturn(true).when(repository, "exists", anyString()); doNothing().when(repository, "create", anyString()); List<String> files2 = new ArrayList<>(); files2.add("repository-test-2.jar"); doReturn(files2).when(repository, "list", anyString()); doAnswer(i -> { Collection<String> add = i.getArgument(1); assertTrue(add.isEmpty()); files2.addAll(add); return null; }).when(repository, "create", anyString(), any(Collection.class)); doAnswer(i -> { Collection<String> remove = i.getArgument(1); assertThat(remove.size(), is(1)); assertTrue(remove.contains("repository-test-2.jar")); files2.removeAll(remove); return null; }).when(repository, "delete", anyString(), any(Collection.class)); doAnswer(i -> { List<URL> urls = i.getArgument(0); assertTrue(urls.isEmpty()); return Thread.currentThread().getContextClassLoader(); }).when(repository, "newLoader", any(List.class)); doAnswer(i -> { return new ArrayList<>(); }).when(repository, "readFaults", any(ClassLoader.class)); faults = repository.load(); assertTrue(faults.isEmpty()); verifyPrivate(repository, never()).invoke("create", anyString()); s3 = mock(AmazonS3.class); result = new ListObjectsV2Result(); objectSummary = new S3ObjectSummary(); objectSummary.setKey("repository-test-3.jar"); result.getObjectSummaries().add(objectSummary); result.setTruncated(false); doReturn(result).when(s3).listObjectsV2(anyString()); repository = spy(new Repository(s3)); doReturn(true).when(repository, "exists", anyString()); doNothing().when(repository, "create", anyString()); List<String> files3 = new ArrayList<>(); files3.add("repository-test-3.jar"); doReturn(files3).when(repository, "list", anyString()); doAnswer(i -> { Collection<String> add = i.getArgument(1); assertTrue(add.isEmpty()); files3.addAll(add); return null; }).when(repository, "create", anyString(), any(Collection.class)); doAnswer(i -> { Collection<String> remove = i.getArgument(1); assertTrue(remove.isEmpty()); files3.removeAll(remove); return null; }).when(repository, "delete", anyString(), any(Collection.class)); doAnswer(i -> { List<URL> urls = i.getArgument(0); assertThat(urls.size(), is(1)); assertTrue(urls.get(0).toString().endsWith("repository-test-3.jar")); return Thread.currentThread().getContextClassLoader(); }).when(repository, "newLoader", any(List.class)); doAnswer(i -> { return new ArrayList<>(); }).when(repository, "readFaults", any(ClassLoader.class)); faults = repository.load(); assertTrue(faults.isEmpty()); s3 = mock(AmazonS3.class); result = new ListObjectsV2Result(); objectSummary = new S3ObjectSummary(); objectSummary.setKey("repository-test-4.jar"); result.getObjectSummaries().add(objectSummary); result.setTruncated(false); doReturn(result).when(s3).listObjectsV2(anyString()); repository = spy(new Repository(s3)); doReturn(true).when(repository, "exists", anyString()); doNothing().when(repository, "create", anyString()); doReturn(new ArrayList<>()).when(repository, "list", anyString()); doNothing().when(repository, "create", anyString(), any(Collection.class)); doNothing().when(repository, "delete", anyString(), any(Collection.class)); doReturn(Thread.currentThread().getContextClassLoader()).when(repository, "newLoader", any(List.class)); List<String> classes = new ArrayList<>(); classes.add("# io.eiichiro.prodigy.Fault1"); classes.add("io.eiichiro.prodigy.FaultNotFound"); classes.add("io.eiichiro.prodigy.Fault3"); classes.add("io.eiichiro.prodigy.Fault4"); classes.add("io.eiichiro.prodigy.Fault2"); doReturn(classes).when(repository, "readFaults", any(ClassLoader.class)); faults = repository.load(); assertThat(faults.size(), is(2)); assertTrue(faults.get("fault-4").equals(Fault4.class)); assertTrue(faults.get("Fault2").equals(Fault2.class)); s3 = mock(AmazonS3.class); result = new ListObjectsV2Result(); result.setTruncated(false); doReturn(result).when(s3).listObjectsV2(anyString()); repository = spy(new Repository(s3)); doReturn(false).when(repository, "exists", anyString()); doThrow(new IOException("hello")).when(repository, "create", anyString()); doReturn(new ArrayList<>()).when(repository, "list", anyString()); doNothing().when(repository, "create", anyString(), any(Collection.class)); doNothing().when(repository, "delete", anyString(), any(Collection.class)); doReturn(Thread.currentThread().getContextClassLoader()).when(repository, "newLoader", any(List.class)); classes = new ArrayList<>(); doReturn(classes).when(repository, "readFaults", any(ClassLoader.class)); try { faults = repository.load(); fail(); } catch (UncheckedException e) { assertThat(e.getMessage(), is("hello")); } }
@SuppressWarnings("unchecked") public Map<String, Class<? extends Fault>> load() { List<String> objects = new ArrayList<>(); String repository = Prodigy.configuration().repository(); ListObjectsV2Result result = s3.listObjectsV2(repository); result.getObjectSummaries().forEach(s -> objects.add(s.getKey())); while (result.isTruncated()) { ListObjectsV2Request request = new ListObjectsV2Request(); result = s3.listObjectsV2(request.withBucketName(repository).withContinuationToken(result.getContinuationToken())); result.getObjectSummaries().forEach(s -> objects.add(s.getKey())); } String tmpdir = Environment.getProperty("java.io.tmpdir"); if (!tmpdir.endsWith(File.separator)) { tmpdir += File.separator; } tmpdir += CACHE; try { if (!exists(tmpdir)) { create(tmpdir); } List<String> files = new ArrayList<>(); list(tmpdir).forEach(f -> { files.add(Paths.get(f).getFileName().toString()); }); log.debug("Saved fault jars are [" + objects + "]"); log.debug("Cached fault jars are [" + files + "]"); Collection<String> add = CollectionUtils.subtract(objects, files); Collection<String> remove = CollectionUtils.subtract(files, objects); create(tmpdir, add); delete(tmpdir, remove); if (!add.isEmpty() || !remove.isEmpty()) { List<URL> urls = new ArrayList<>(); for (String file : list(tmpdir)) { urls.add(Paths.get(file).toUri().toURL()); } log.debug("Fault jars to be loaded are [" + urls + "]"); Map<String, Class<? extends Fault>> faults = new HashMap<>(); ClassLoader loader = newLoader(urls); readFaults(loader).forEach(l -> { if (l.startsWith("#")) { return; } try { log.debug("Fault class to be loaded is [" + l + "]"); Class<?> clazz = Class.forName(l, true, loader); if (!Fault.class.isAssignableFrom(clazz)) { log.warn("Fault class [" + clazz + "] must inherit " + Fault.class); return; } Named named = clazz.getAnnotation(Named.class); if (named != null) { String name = named.value(); if (name == null || name.isEmpty()) { log.warn("Value of @Named annotation on [" + clazz + "] must not be [" + name + "]"); return; } faults.put(name, (Class<? extends Fault>) clazz); } else { faults.put(clazz.getSimpleName(), (Class<? extends Fault>) clazz); } } catch (ClassNotFoundException e) { log.warn("Fault class [" + l + "] not found", e); } }); this.faults = faults; } return faults; } catch (IOException e) { throw new UncheckedException(e); } }
Repository { @SuppressWarnings("unchecked") public Map<String, Class<? extends Fault>> load() { List<String> objects = new ArrayList<>(); String repository = Prodigy.configuration().repository(); ListObjectsV2Result result = s3.listObjectsV2(repository); result.getObjectSummaries().forEach(s -> objects.add(s.getKey())); while (result.isTruncated()) { ListObjectsV2Request request = new ListObjectsV2Request(); result = s3.listObjectsV2(request.withBucketName(repository).withContinuationToken(result.getContinuationToken())); result.getObjectSummaries().forEach(s -> objects.add(s.getKey())); } String tmpdir = Environment.getProperty("java.io.tmpdir"); if (!tmpdir.endsWith(File.separator)) { tmpdir += File.separator; } tmpdir += CACHE; try { if (!exists(tmpdir)) { create(tmpdir); } List<String> files = new ArrayList<>(); list(tmpdir).forEach(f -> { files.add(Paths.get(f).getFileName().toString()); }); log.debug("Saved fault jars are [" + objects + "]"); log.debug("Cached fault jars are [" + files + "]"); Collection<String> add = CollectionUtils.subtract(objects, files); Collection<String> remove = CollectionUtils.subtract(files, objects); create(tmpdir, add); delete(tmpdir, remove); if (!add.isEmpty() || !remove.isEmpty()) { List<URL> urls = new ArrayList<>(); for (String file : list(tmpdir)) { urls.add(Paths.get(file).toUri().toURL()); } log.debug("Fault jars to be loaded are [" + urls + "]"); Map<String, Class<? extends Fault>> faults = new HashMap<>(); ClassLoader loader = newLoader(urls); readFaults(loader).forEach(l -> { if (l.startsWith("#")) { return; } try { log.debug("Fault class to be loaded is [" + l + "]"); Class<?> clazz = Class.forName(l, true, loader); if (!Fault.class.isAssignableFrom(clazz)) { log.warn("Fault class [" + clazz + "] must inherit " + Fault.class); return; } Named named = clazz.getAnnotation(Named.class); if (named != null) { String name = named.value(); if (name == null || name.isEmpty()) { log.warn("Value of @Named annotation on [" + clazz + "] must not be [" + name + "]"); return; } faults.put(name, (Class<? extends Fault>) clazz); } else { faults.put(clazz.getSimpleName(), (Class<? extends Fault>) clazz); } } catch (ClassNotFoundException e) { log.warn("Fault class [" + l + "] not found", e); } }); this.faults = faults; } return faults; } catch (IOException e) { throw new UncheckedException(e); } } }
Repository { @SuppressWarnings("unchecked") public Map<String, Class<? extends Fault>> load() { List<String> objects = new ArrayList<>(); String repository = Prodigy.configuration().repository(); ListObjectsV2Result result = s3.listObjectsV2(repository); result.getObjectSummaries().forEach(s -> objects.add(s.getKey())); while (result.isTruncated()) { ListObjectsV2Request request = new ListObjectsV2Request(); result = s3.listObjectsV2(request.withBucketName(repository).withContinuationToken(result.getContinuationToken())); result.getObjectSummaries().forEach(s -> objects.add(s.getKey())); } String tmpdir = Environment.getProperty("java.io.tmpdir"); if (!tmpdir.endsWith(File.separator)) { tmpdir += File.separator; } tmpdir += CACHE; try { if (!exists(tmpdir)) { create(tmpdir); } List<String> files = new ArrayList<>(); list(tmpdir).forEach(f -> { files.add(Paths.get(f).getFileName().toString()); }); log.debug("Saved fault jars are [" + objects + "]"); log.debug("Cached fault jars are [" + files + "]"); Collection<String> add = CollectionUtils.subtract(objects, files); Collection<String> remove = CollectionUtils.subtract(files, objects); create(tmpdir, add); delete(tmpdir, remove); if (!add.isEmpty() || !remove.isEmpty()) { List<URL> urls = new ArrayList<>(); for (String file : list(tmpdir)) { urls.add(Paths.get(file).toUri().toURL()); } log.debug("Fault jars to be loaded are [" + urls + "]"); Map<String, Class<? extends Fault>> faults = new HashMap<>(); ClassLoader loader = newLoader(urls); readFaults(loader).forEach(l -> { if (l.startsWith("#")) { return; } try { log.debug("Fault class to be loaded is [" + l + "]"); Class<?> clazz = Class.forName(l, true, loader); if (!Fault.class.isAssignableFrom(clazz)) { log.warn("Fault class [" + clazz + "] must inherit " + Fault.class); return; } Named named = clazz.getAnnotation(Named.class); if (named != null) { String name = named.value(); if (name == null || name.isEmpty()) { log.warn("Value of @Named annotation on [" + clazz + "] must not be [" + name + "]"); return; } faults.put(name, (Class<? extends Fault>) clazz); } else { faults.put(clazz.getSimpleName(), (Class<? extends Fault>) clazz); } } catch (ClassNotFoundException e) { log.warn("Fault class [" + l + "] not found", e); } }); this.faults = faults; } return faults; } catch (IOException e) { throw new UncheckedException(e); } } Repository();  Repository(AmazonS3 s3); }
Repository { @SuppressWarnings("unchecked") public Map<String, Class<? extends Fault>> load() { List<String> objects = new ArrayList<>(); String repository = Prodigy.configuration().repository(); ListObjectsV2Result result = s3.listObjectsV2(repository); result.getObjectSummaries().forEach(s -> objects.add(s.getKey())); while (result.isTruncated()) { ListObjectsV2Request request = new ListObjectsV2Request(); result = s3.listObjectsV2(request.withBucketName(repository).withContinuationToken(result.getContinuationToken())); result.getObjectSummaries().forEach(s -> objects.add(s.getKey())); } String tmpdir = Environment.getProperty("java.io.tmpdir"); if (!tmpdir.endsWith(File.separator)) { tmpdir += File.separator; } tmpdir += CACHE; try { if (!exists(tmpdir)) { create(tmpdir); } List<String> files = new ArrayList<>(); list(tmpdir).forEach(f -> { files.add(Paths.get(f).getFileName().toString()); }); log.debug("Saved fault jars are [" + objects + "]"); log.debug("Cached fault jars are [" + files + "]"); Collection<String> add = CollectionUtils.subtract(objects, files); Collection<String> remove = CollectionUtils.subtract(files, objects); create(tmpdir, add); delete(tmpdir, remove); if (!add.isEmpty() || !remove.isEmpty()) { List<URL> urls = new ArrayList<>(); for (String file : list(tmpdir)) { urls.add(Paths.get(file).toUri().toURL()); } log.debug("Fault jars to be loaded are [" + urls + "]"); Map<String, Class<? extends Fault>> faults = new HashMap<>(); ClassLoader loader = newLoader(urls); readFaults(loader).forEach(l -> { if (l.startsWith("#")) { return; } try { log.debug("Fault class to be loaded is [" + l + "]"); Class<?> clazz = Class.forName(l, true, loader); if (!Fault.class.isAssignableFrom(clazz)) { log.warn("Fault class [" + clazz + "] must inherit " + Fault.class); return; } Named named = clazz.getAnnotation(Named.class); if (named != null) { String name = named.value(); if (name == null || name.isEmpty()) { log.warn("Value of @Named annotation on [" + clazz + "] must not be [" + name + "]"); return; } faults.put(name, (Class<? extends Fault>) clazz); } else { faults.put(clazz.getSimpleName(), (Class<? extends Fault>) clazz); } } catch (ClassNotFoundException e) { log.warn("Fault class [" + l + "] not found", e); } }); this.faults = faults; } return faults; } catch (IOException e) { throw new UncheckedException(e); } } Repository();  Repository(AmazonS3 s3); @SuppressWarnings("unchecked") Map<String, Class<? extends Fault>> load(); void save(String name, InputStream jar); }
Repository { @SuppressWarnings("unchecked") public Map<String, Class<? extends Fault>> load() { List<String> objects = new ArrayList<>(); String repository = Prodigy.configuration().repository(); ListObjectsV2Result result = s3.listObjectsV2(repository); result.getObjectSummaries().forEach(s -> objects.add(s.getKey())); while (result.isTruncated()) { ListObjectsV2Request request = new ListObjectsV2Request(); result = s3.listObjectsV2(request.withBucketName(repository).withContinuationToken(result.getContinuationToken())); result.getObjectSummaries().forEach(s -> objects.add(s.getKey())); } String tmpdir = Environment.getProperty("java.io.tmpdir"); if (!tmpdir.endsWith(File.separator)) { tmpdir += File.separator; } tmpdir += CACHE; try { if (!exists(tmpdir)) { create(tmpdir); } List<String> files = new ArrayList<>(); list(tmpdir).forEach(f -> { files.add(Paths.get(f).getFileName().toString()); }); log.debug("Saved fault jars are [" + objects + "]"); log.debug("Cached fault jars are [" + files + "]"); Collection<String> add = CollectionUtils.subtract(objects, files); Collection<String> remove = CollectionUtils.subtract(files, objects); create(tmpdir, add); delete(tmpdir, remove); if (!add.isEmpty() || !remove.isEmpty()) { List<URL> urls = new ArrayList<>(); for (String file : list(tmpdir)) { urls.add(Paths.get(file).toUri().toURL()); } log.debug("Fault jars to be loaded are [" + urls + "]"); Map<String, Class<? extends Fault>> faults = new HashMap<>(); ClassLoader loader = newLoader(urls); readFaults(loader).forEach(l -> { if (l.startsWith("#")) { return; } try { log.debug("Fault class to be loaded is [" + l + "]"); Class<?> clazz = Class.forName(l, true, loader); if (!Fault.class.isAssignableFrom(clazz)) { log.warn("Fault class [" + clazz + "] must inherit " + Fault.class); return; } Named named = clazz.getAnnotation(Named.class); if (named != null) { String name = named.value(); if (name == null || name.isEmpty()) { log.warn("Value of @Named annotation on [" + clazz + "] must not be [" + name + "]"); return; } faults.put(name, (Class<? extends Fault>) clazz); } else { faults.put(clazz.getSimpleName(), (Class<? extends Fault>) clazz); } } catch (ClassNotFoundException e) { log.warn("Fault class [" + l + "] not found", e); } }); this.faults = faults; } return faults; } catch (IOException e) { throw new UncheckedException(e); } } Repository();  Repository(AmazonS3 s3); @SuppressWarnings("unchecked") Map<String, Class<? extends Fault>> load(); void save(String name, InputStream jar);  }