@SuppressWarnings({"unchecked", "rawtypes"}) public <T extends Enricher> T createEnricher(EnricherSpec<T> spec) { if (spec.getFlags().containsKey("parent")) { throw new IllegalArgumentException( "Spec's flags must not contain parent; use spec.parent() instead for " + spec); } try { Class<? extends T> clazz = spec.getType(); T enricher; if (isNewStyleEnricher(clazz)) { enricher = constructEnricher(clazz); } else { enricher = constructOldStyle(clazz, MutableMap.copyOf(spec.getFlags())); } if (spec.getDisplayName() != null) ((AbstractEnricher) enricher).setName(spec.getDisplayName()); if (isNewStyleEnricher(clazz)) { ((AbstractEnricher) enricher).setManagementContext(managementContext); Map<String, Object> config = ConfigBag.newInstance().putAll(spec.getFlags()).putAll(spec.getConfig()).getAllConfig(); ((AbstractEnricher) enricher) .configure( MutableMap.copyOf(config)); // TODO AbstractEnricher.configure modifies the map } // TODO Can we avoid this for "new-style policies"? Should we just trust the configure() // method, // which the user may have overridden? // Also see InternalLocationFactory for same issue, which this code is based on. for (Map.Entry<ConfigKey<?>, Object> entry : spec.getConfig().entrySet()) { ((AbstractEnricher) enricher).setConfig((ConfigKey) entry.getKey(), entry.getValue()); } ((AbstractEnricher) enricher).init(); return enricher; } catch (Exception e) { throw Exceptions.propagate(e); } }
@Test public void testServiceFailureDetectorWorksAfterRebind() throws Exception { origEntity.addEnricher(EnricherSpec.create(ServiceFailureDetector.class)); // rebind TestApplication newApp = rebind(); final TestEntity newEntity = (TestEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(TestEntity.class)); newApp .getManagementContext() .getSubscriptionManager() .subscribe(newEntity, HASensors.ENTITY_FAILED, eventListener); newEntity.setAttribute(TestEntity.SERVICE_UP, true); ServiceStateLogic.setExpectedState(newEntity, Lifecycle.RUNNING); // trigger the failure newEntity.setAttribute(TestEntity.SERVICE_UP, false); assertHasEventEventually(HASensors.ENTITY_FAILED, Predicates.<Object>equalTo(newEntity), null); assertEquals(events.size(), 1, "events=" + events); }