private synchronized void computeImportedByMap(Optional<Config> runtimeConfig) { if (this.fullImportedByMap != null) { return; } ImmutableMultimap.Builder<ConfigKeyPath, ConfigKeyPath> importedByBuilder = ImmutableMultimap.builder(); // breath first search the whole topology to build ownImports map and ownImportedByMap // calls to retrieve cache / set cache if not present Collection<ConfigKeyPath> currentLevel = this.getChildren(SingleLinkedListConfigKeyPath.ROOT); List<ConfigKeyPath> rootImports = this.getOwnImports(SingleLinkedListConfigKeyPath.ROOT, runtimeConfig); Preconditions.checkArgument(rootImports == null || rootImports.size() == 0, "Root can not import other nodes, otherwise circular dependency will happen"); while (!currentLevel.isEmpty()) { Collection<ConfigKeyPath> nextLevel = new ArrayList<>(); for (ConfigKeyPath configKeyPath : currentLevel) { // calls to retrieve cache / set cache if not present List<ConfigKeyPath> ownImports = this.getOwnImports(configKeyPath, runtimeConfig); this.ownImportMap.put(configKeyPath, ownImports); for (ConfigKeyPath importedPath : ownImports) { importedByBuilder.put(importedPath, configKeyPath); } // calls to retrieve cache / set cache if not present Collection<ConfigKeyPath> tmp = this.getChildren(configKeyPath); nextLevel.addAll(tmp); } currentLevel = nextLevel; } this.fullImportedByMap = importedByBuilder.build(); }
public Collection<ConfigKeyPath> getImportedBy(ConfigKeyPath configKey, Optional<Config> runtimeConfig) { if (this.fullImportedByMap != null) { return this.fullImportedByMap.get(configKey); } try { return this.ownImportedByMap.get(configKey, () -> this.fallback.getImportedBy(configKey, runtimeConfig)); } catch (UncheckedExecutionException exc) { if (exc.getCause() instanceof UnsupportedOperationException) { computeImportedByMap(runtimeConfig); return getImportedBy(configKey, runtimeConfig); } else { throw new RuntimeException(exc); } } catch (ExecutionException ee) { throw new RuntimeException(ee); } }
/** * {@inheritDoc}. * * <p> * If the result is already in cache, return the result. * Otherwise, delegate the functionality to the fallback object. * * If the fallback did not support this operation, will build the entire topology of the {@link org.apache.gobblin.config.store.api.ConfigStore} * using default breath first search. * </p> */ @Override public Collection<ConfigKeyPath> getImportedByRecursively(ConfigKeyPath configKey) { return getImportedByRecursively(configKey, Optional.<Config>absent()); }
Assert.assertEquals(mockConfigStore.getCurrentVersion(), version); ConfigStoreBackedTopology csTopology = new ConfigStoreBackedTopology(this.mockConfigStore, this.version); InMemoryTopology inMemory = new InMemoryTopology(csTopology); Collection<ConfigKeyPath> result = inMemory.getChildren(data); Assert.assertTrue(result.size()==1); Assert.assertEquals(result.iterator().next(), databases); result = inMemory.getOwnImports(identity); Assert.assertTrue(result.size()==2); Iterator<ConfigKeyPath> it = result.iterator(); result = inMemory.getImportsRecursively(identity); Assert.assertEquals(result.size(), 8); Assert.assertEquals(result, Lists.newArrayList(highPriorityTag, tag, SingleLinkedListConfigKeyPath.ROOT, result = inMemory.getImportedBy(nertzTag2); Assert.assertTrue(result.size()==1); Assert.assertEquals(result.iterator().next(), espressoTag); result = inMemory.getImportedByRecursively(nertzTag2); Set<ConfigKeyPath> expected = new HashSet<ConfigKeyPath>(); expected.add(espressoTag);
@Test public void testSelfImportSelf() { ConfigKeyPath tag = SingleLinkedListConfigKeyPath.ROOT.createChild("tag"); ConfigStore mockConfigStore = mock(ConfigStore.class, Mockito.RETURNS_SMART_NULLS); when(mockConfigStore.getCurrentVersion()).thenReturn(version); addConfigStoreChildren(mockConfigStore, version, SingleLinkedListConfigKeyPath.ROOT, tag); // self import self addConfigStoreImports(mockConfigStore, version, tag, tag); ConfigStoreBackedTopology csTopology = new ConfigStoreBackedTopology(mockConfigStore, this.version); InMemoryTopology inMemory = new InMemoryTopology(csTopology); try { inMemory.getImportsRecursively(tag); Assert.fail("Did not catch expected CircularDependencyException"); } catch (CircularDependencyException e) { Assert.assertTrue(e.getMessage().indexOf("/tag") > 0); } }
/** * {@inheritDoc}. * * <p> * If the result is already in cache, return the result. * Otherwise, delegate the functionality to the fallback object * </p> */ @Override public List<ConfigKeyPath> getOwnImports(ConfigKeyPath configKey) { return getOwnImports(configKey, Optional.<Config>absent()); }
/** * {@inheritDoc}. * * <p> * If the result is already in cache, return the result. * Otherwise, delegate the functionality to the fallback object. * * If the fallback did not support this operation, will build the entire topology of the {@link org.apache.gobblin.config.store.api.ConfigStore} * using default breath first search. * </p> */ @Override public Collection<ConfigKeyPath> getImportedBy(ConfigKeyPath configKey) { return getImportedBy(configKey, Optional.<Config>absent()); }
InMemoryTopology inMemoryTopology = new InMemoryTopology(csTopology);
/** * {@inheritDoc}. * * <p> * If the result is already in cache, return the result. * Otherwise, delegate the functionality to the fallback object. * * If the fallback did not support this operation, will build the entire topology of the {@link org.apache.gobblin.config.store.api.ConfigStore} * using default breath first search. * </p> */ @Override public List<ConfigKeyPath> getImportsRecursively(ConfigKeyPath configKey) { return getImportsRecursively(configKey, Optional.<Config>absent()); }
@Test public void testSelfImportChild() { ConfigKeyPath tag = SingleLinkedListConfigKeyPath.ROOT.createChild("tag"); ConfigKeyPath highPriorityTag = tag.createChild("highPriorityTag"); ConfigStore mockConfigStore = mock(ConfigStore.class, Mockito.RETURNS_SMART_NULLS); when(mockConfigStore.getCurrentVersion()).thenReturn(version); addConfigStoreChildren(mockConfigStore, version, SingleLinkedListConfigKeyPath.ROOT, tag); addConfigStoreChildren(mockConfigStore, version, tag, highPriorityTag); // parent import direct child addConfigStoreImports(mockConfigStore, version, tag, highPriorityTag); ConfigStoreBackedTopology csTopology = new ConfigStoreBackedTopology(mockConfigStore, this.version); InMemoryTopology inMemory = new InMemoryTopology(csTopology); try { inMemory.getImportsRecursively(tag); Assert.fail("Did not catch expected CircularDependencyException"); } catch (CircularDependencyException e) { Assert.assertTrue(e.getMessage().indexOf("/tag/highPriorityTag") > 0 && e.getMessage().indexOf("/tag ") > 0); } }
public List<ConfigKeyPath> getImportsRecursively(ConfigKeyPath configKey, Optional<Config> runtimeConfig) { return new ImportTraverser<>(key -> { if (key.isRootPath()) { return new LinkedList<>(); } List<ConfigKeyPath> imports = Lists.newArrayList(); imports.addAll(Lists.reverse(getOwnImports(key, runtimeConfig))); imports.add(key.getParent()); return imports; }, this.recursiveImportMap).traverseGraphRecursively(configKey); }
public Collection<ConfigKeyPath> getImportedByRecursively(ConfigKeyPath configKey, Optional<Config> runtimeConfig) { return new ImportTraverser<>(key -> Lists.newLinkedList(getImportedBy(key, runtimeConfig)), this.recursiveImportedByMap).traverseGraphRecursively(configKey); } }
@Test public void testNonRootValues() { ConfigStoreBackedTopology csTopology = new ConfigStoreBackedTopology(this.mockConfigStore, this.version); InMemoryTopology inMemory = new InMemoryTopology(csTopology); ConfigStoreBackedValueInspector rawValueInspector = new ConfigStoreBackedValueInspector(this.mockConfigStore, this.version, inMemory); InMemoryValueInspector inMemoryStrongRef = new InMemoryValueInspector(rawValueInspector, true); InMemoryValueInspector inMemoryWeakRef = new InMemoryValueInspector(rawValueInspector, false); // test values for Identity testValuesForIdentity(rawValueInspector); testValuesForIdentity(inMemoryStrongRef); testValuesForIdentity(inMemoryWeakRef); // test values for Espresso Tag testValuesForEspressoTag(rawValueInspector); testValuesForEspressoTag(inMemoryStrongRef); testValuesForEspressoTag(inMemoryWeakRef); // test for batch Collection<ConfigKeyPath> inputs = new ArrayList<ConfigKeyPath>(); inputs.add(espressoTag); inputs.add(identity); Map<ConfigKeyPath, Config> resultMap = rawValueInspector.getOwnConfigs(inputs); Assert.assertEquals(resultMap.size(), 2); testValuesForEspressoTagOwnConfig(resultMap.get(espressoTag)); checkValuesForIdentityOwnConfig(resultMap.get(identity)); resultMap = rawValueInspector.getResolvedConfigs(inputs); Assert.assertEquals(resultMap.size(), 2); testValuesForEspressoTagResolvedConfig(resultMap.get(espressoTag)); checkValuesForIdentityResolvedConfig(resultMap.get(identity)); }
/** * {@inheritDoc}. * * <p> * If the result is already in cache, return the result. * Otherwise, delegate the functionality to the fallback object. * * If the fallback did not support this operation, will build the entire topology of the {@link org.apache.gobblin.config.store.api.ConfigStore} * using default breath first search. * </p> */ @Override public List<ConfigKeyPath> getImportsRecursively(ConfigKeyPath configKey) { return getImportsRecursively(configKey, Optional.<Config>absent()); }
InMemoryTopology inMemory = new InMemoryTopology(csTopology); List<ConfigKeyPath> result = inMemory.getImportsRecursively(nertzHighPriorityTag); Assert.assertEquals(result.size(), 4); Iterator<ConfigKeyPath> it = result.iterator();
private synchronized void computeImportedByMap(Optional<Config> runtimeConfig) { if (this.fullImportedByMap != null) { return; } ImmutableMultimap.Builder<ConfigKeyPath, ConfigKeyPath> importedByBuilder = ImmutableMultimap.builder(); // breath first search the whole topology to build ownImports map and ownImportedByMap // calls to retrieve cache / set cache if not present Collection<ConfigKeyPath> currentLevel = this.getChildren(SingleLinkedListConfigKeyPath.ROOT); List<ConfigKeyPath> rootImports = this.getOwnImports(SingleLinkedListConfigKeyPath.ROOT, runtimeConfig); Preconditions.checkArgument(rootImports == null || rootImports.size() == 0, "Root can not import other nodes, otherwise circular dependency will happen"); while (!currentLevel.isEmpty()) { Collection<ConfigKeyPath> nextLevel = new ArrayList<>(); for (ConfigKeyPath configKeyPath : currentLevel) { // calls to retrieve cache / set cache if not present List<ConfigKeyPath> ownImports = this.getOwnImports(configKeyPath, runtimeConfig); this.ownImportMap.put(configKeyPath, ownImports); for (ConfigKeyPath importedPath : ownImports) { importedByBuilder.put(importedPath, configKeyPath); } // calls to retrieve cache / set cache if not present Collection<ConfigKeyPath> tmp = this.getChildren(configKeyPath); nextLevel.addAll(tmp); } currentLevel = nextLevel; } this.fullImportedByMap = importedByBuilder.build(); }
public Collection<ConfigKeyPath> getImportedBy(ConfigKeyPath configKey, Optional<Config> runtimeConfig) { if (this.fullImportedByMap != null) { return this.fullImportedByMap.get(configKey); } try { return this.ownImportedByMap.get(configKey, () -> this.fallback.getImportedBy(configKey, runtimeConfig)); } catch (UncheckedExecutionException exc) { if (exc.getCause() instanceof UnsupportedOperationException) { computeImportedByMap(runtimeConfig); return getImportedBy(configKey, runtimeConfig); } else { throw new RuntimeException(exc); } } catch (ExecutionException ee) { throw new RuntimeException(ee); } }
/** * {@inheritDoc}. * * <p> * If the result is already in cache, return the result. * Otherwise, delegate the functionality to the fallback object * </p> */ @Override public List<ConfigKeyPath> getOwnImports(ConfigKeyPath configKey) { return getOwnImports(configKey, Optional.<Config>absent()); }
/** * {@inheritDoc}. * * <p> * If the result is already in cache, return the result. * Otherwise, delegate the functionality to the fallback object. * * If the fallback did not support this operation, will build the entire topology of the {@link org.apache.gobblin.config.store.api.ConfigStore} * using default breath first search. * </p> */ @Override public Collection<ConfigKeyPath> getImportedBy(ConfigKeyPath configKey) { return getImportedBy(configKey, Optional.<Config>absent()); }
InMemoryTopology inMemoryTopology = new InMemoryTopology(csTopology);