use of org.apache.nifi.controller.ConfigurationContext in project nifi by apache.
the class TestAmbariReportingTask method testOnTrigger.
@Test
public void testOnTrigger() throws InitializationException, IOException {
final String metricsUrl = "http://myambari:6188/ws/v1/timeline/metrics";
final String applicationId = "NIFI";
final String hostName = "localhost";
// create the jersey client mocks for handling the post
final Client client = Mockito.mock(Client.class);
final WebTarget target = Mockito.mock(WebTarget.class);
final Invocation.Builder builder = Mockito.mock(Invocation.Builder.class);
final Response response = Mockito.mock(Response.class);
Mockito.when(response.getStatus()).thenReturn(200);
Mockito.when(client.target(metricsUrl)).thenReturn(target);
Mockito.when(target.request()).thenReturn(builder);
Mockito.when(builder.post(Matchers.any(Entity.class))).thenReturn(response);
// mock the ReportingInitializationContext for initialize(...)
final ComponentLog logger = Mockito.mock(ComponentLog.class);
final ReportingInitializationContext initContext = Mockito.mock(ReportingInitializationContext.class);
Mockito.when(initContext.getIdentifier()).thenReturn(UUID.randomUUID().toString());
Mockito.when(initContext.getLogger()).thenReturn(logger);
// mock the ConfigurationContext for setup(...)
final ConfigurationContext configurationContext = Mockito.mock(ConfigurationContext.class);
// mock the ReportingContext for onTrigger(...)
final ReportingContext context = Mockito.mock(ReportingContext.class);
Mockito.when(context.getProperty(AmbariReportingTask.METRICS_COLLECTOR_URL)).thenReturn(new MockPropertyValue(metricsUrl));
Mockito.when(context.getProperty(AmbariReportingTask.APPLICATION_ID)).thenReturn(new MockPropertyValue(applicationId));
Mockito.when(context.getProperty(AmbariReportingTask.HOSTNAME)).thenReturn(new MockPropertyValue(hostName));
Mockito.when(context.getProperty(AmbariReportingTask.PROCESS_GROUP_ID)).thenReturn(new MockPropertyValue("1234"));
final EventAccess eventAccess = Mockito.mock(EventAccess.class);
Mockito.when(context.getEventAccess()).thenReturn(eventAccess);
Mockito.when(eventAccess.getControllerStatus()).thenReturn(status);
// create a testable instance of the reporting task
final AmbariReportingTask task = new TestableAmbariReportingTask(client);
task.initialize(initContext);
task.setup(configurationContext);
task.onTrigger(context);
}
use of org.apache.nifi.controller.ConfigurationContext in project nifi by apache.
the class TestAvroSchemaRegistry method validateStrictAndNonStrictSchemaRegistrationFromDynamicProperties.
@Test
public void validateStrictAndNonStrictSchemaRegistrationFromDynamicProperties() throws Exception {
String schemaName = "fooSchema";
ConfigurationContext configContext = mock(ConfigurationContext.class);
Map<PropertyDescriptor, String> properties = new HashMap<>();
PropertyDescriptor fooSchema = new PropertyDescriptor.Builder().name(schemaName).dynamic(true).build();
// NOTE: name of record and name of first field are not Avro-compliant, verified below
String fooSchemaText = "{\"namespace\": \"example.avro\", " + "\"type\": \"record\", " + "\"name\": \"$User\", " + "\"fields\": [ " + "{\"name\": \"@name\", \"type\": [\"string\", \"null\"]}, " + "{\"name\": \"favorite_number\", \"type\": [\"int\", \"null\"]}, " + "{\"name\": \"foo\", \"type\": [\"int\", \"null\"]}, " + "{\"name\": \"favorite_color\", \"type\": [\"string\", \"null\"]} " + "]" + "}";
PropertyDescriptor barSchema = new PropertyDescriptor.Builder().name("barSchema").dynamic(false).build();
properties.put(fooSchema, fooSchemaText);
properties.put(barSchema, "");
AvroSchemaRegistry delegate = new AvroSchemaRegistry();
delegate.getSupportedPropertyDescriptors().forEach(prop -> properties.put(prop, prop.getDisplayName()));
when(configContext.getProperties()).thenReturn(properties);
ValidationContext validationContext = mock(ValidationContext.class);
when(validationContext.getProperties()).thenReturn(properties);
PropertyValue propertyValue = mock(PropertyValue.class);
when(validationContext.getProperty(AvroSchemaRegistry.VALIDATE_FIELD_NAMES)).thenReturn(propertyValue);
// Strict parsing
when(propertyValue.asBoolean()).thenReturn(true);
Collection<ValidationResult> results = delegate.customValidate(validationContext);
assertTrue(results.stream().anyMatch(result -> !result.isValid()));
// Non-strict parsing
when(propertyValue.asBoolean()).thenReturn(false);
results = delegate.customValidate(validationContext);
results.forEach(result -> assertTrue(result.isValid()));
}
use of org.apache.nifi.controller.ConfigurationContext in project nifi by apache.
the class StandardProcessScheduler method unschedule.
@Override
public void unschedule(final ReportingTaskNode taskNode) {
final LifecycleState lifecycleState = getLifecycleState(requireNonNull(taskNode), false);
if (!lifecycleState.isScheduled()) {
return;
}
taskNode.verifyCanStop();
final SchedulingAgent agent = getSchedulingAgent(taskNode.getSchedulingStrategy());
final ReportingTask reportingTask = taskNode.getReportingTask();
taskNode.setScheduledState(ScheduledState.STOPPED);
final Runnable unscheduleReportingTaskRunnable = new Runnable() {
@Override
public void run() {
final ConfigurationContext configurationContext = taskNode.getConfigurationContext();
synchronized (lifecycleState) {
lifecycleState.setScheduled(false);
try {
try (final NarCloseable x = NarCloseable.withComponentNarLoader(reportingTask.getClass(), reportingTask.getIdentifier())) {
ReflectionUtils.invokeMethodsWithAnnotation(OnUnscheduled.class, reportingTask, configurationContext);
}
} catch (final Exception e) {
final Throwable cause = e instanceof InvocationTargetException ? e.getCause() : e;
final ComponentLog componentLog = new SimpleProcessLogger(reportingTask.getIdentifier(), reportingTask);
componentLog.error("Failed to invoke @OnUnscheduled method due to {}", cause);
LOG.error("Failed to invoke the @OnUnscheduled methods of {} due to {}; administratively yielding this ReportingTask and will attempt to schedule it again after {}", reportingTask, cause.toString(), administrativeYieldDuration);
LOG.error("", cause);
try {
Thread.sleep(administrativeYieldMillis);
} catch (final InterruptedException ie) {
}
}
agent.unschedule(taskNode, lifecycleState);
if (lifecycleState.getActiveThreadCount() == 0 && lifecycleState.mustCallOnStoppedMethods()) {
ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnStopped.class, reportingTask, configurationContext);
}
}
}
};
componentLifeCycleThreadPool.execute(unscheduleReportingTaskRunnable);
}
use of org.apache.nifi.controller.ConfigurationContext in project nifi by apache.
the class StandardProcessGroup method removeControllerService.
@Override
public void removeControllerService(final ControllerServiceNode service) {
boolean removed = false;
writeLock.lock();
try {
final ControllerServiceNode existing = controllerServices.get(requireNonNull(service).getIdentifier());
if (existing == null) {
throw new IllegalStateException("ControllerService " + service.getIdentifier() + " is not a member of this Process Group");
}
service.verifyCanDelete();
try (final NarCloseable x = NarCloseable.withComponentNarLoader(service.getControllerServiceImplementation().getClass(), service.getIdentifier())) {
final ConfigurationContext configurationContext = new StandardConfigurationContext(service, controllerServiceProvider, null, variableRegistry);
ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnRemoved.class, service.getControllerServiceImplementation(), configurationContext);
}
for (final Map.Entry<PropertyDescriptor, String> entry : service.getProperties().entrySet()) {
final PropertyDescriptor descriptor = entry.getKey();
if (descriptor.getControllerServiceDefinition() != null) {
final String value = entry.getValue() == null ? descriptor.getDefaultValue() : entry.getValue();
if (value != null) {
final ControllerServiceNode referencedNode = getControllerService(value);
if (referencedNode != null) {
referencedNode.removeReference(service);
}
}
}
}
controllerServices.remove(service.getIdentifier());
onComponentModified();
// For any component that references this Controller Service, find the component's Process Group
// and notify the Process Group that a component has been modified. This way, we know to re-calculate
// whether or not the Process Group has local modifications.
service.getReferences().getReferencingComponents().stream().map(ConfiguredComponent::getProcessGroupIdentifier).filter(id -> !id.equals(getIdentifier())).forEach(groupId -> {
final ProcessGroup descendant = findProcessGroup(groupId);
if (descendant != null) {
descendant.onComponentModified();
}
});
flowController.getStateManagerProvider().onComponentRemoved(service.getIdentifier());
removed = true;
LOG.info("{} removed from {}", service, this);
} finally {
if (removed) {
try {
ExtensionManager.removeInstanceClassLoader(service.getIdentifier());
} catch (Throwable t) {
}
}
writeLock.unlock();
}
}
use of org.apache.nifi.controller.ConfigurationContext in project nifi by apache.
the class StandardControllerServiceNode method enable.
/**
* Will atomically enable this service by invoking its @OnEnabled operation.
* It uses CAS operation on {@link #stateRef} to transition this service
* from DISABLED to ENABLING state. If such transition succeeds the service
* will be marked as 'active' (see {@link ControllerServiceNode#isActive()}).
* If such transition doesn't succeed then no enabling logic will be
* performed and the method will exit. In other words it is safe to invoke
* this operation multiple times and from multiple threads.
* <br>
* This operation will also perform re-try of service enabling in the event
* of exception being thrown by previous invocation of @OnEnabled.
* <br>
* Upon successful invocation of @OnEnabled this service will be transitioned to
* ENABLED state.
* <br>
* In the event where enabling took longer then expected by the user and such user
* initiated disable operation, this service will be automatically disabled as soon
* as it reached ENABLED state.
*/
@Override
public CompletableFuture<Void> enable(final ScheduledExecutorService scheduler, final long administrativeYieldMillis) {
final CompletableFuture<Void> future = new CompletableFuture<>();
if (this.stateTransition.transitionToEnabling(ControllerServiceState.DISABLED, future)) {
synchronized (active) {
this.active.set(true);
}
final StandardControllerServiceNode service = this;
final ConfigurationContext configContext = new StandardConfigurationContext(this, this.serviceProvider, null, getVariableRegistry());
scheduler.execute(new Runnable() {
@Override
public void run() {
try {
try (final NarCloseable nc = NarCloseable.withComponentNarLoader(getControllerServiceImplementation().getClass(), getIdentifier())) {
ReflectionUtils.invokeMethodsWithAnnotation(OnEnabled.class, getControllerServiceImplementation(), configContext);
}
boolean shouldEnable;
synchronized (active) {
shouldEnable = active.get() && stateTransition.enable();
}
if (!shouldEnable) {
LOG.debug("Disabling service {} after it has been enabled due to disable action being initiated.", service);
// Can only happen if user initiated DISABLE operation before service finished enabling. It's state will be
// set to DISABLING (see disable() operation)
invokeDisable(configContext);
stateTransition.disable();
} else {
LOG.debug("Successfully enabled {}", service);
}
} catch (Exception e) {
future.completeExceptionally(e);
final Throwable cause = e instanceof InvocationTargetException ? e.getCause() : e;
final ComponentLog componentLog = new SimpleProcessLogger(getIdentifier(), StandardControllerServiceNode.this);
componentLog.error("Failed to invoke @OnEnabled method due to {}", cause);
LOG.error("Failed to invoke @OnEnabled method of {} due to {}", getControllerServiceImplementation(), cause.toString());
invokeDisable(configContext);
if (isActive()) {
scheduler.schedule(this, administrativeYieldMillis, TimeUnit.MILLISECONDS);
} else {
try (final NarCloseable nc = NarCloseable.withComponentNarLoader(getControllerServiceImplementation().getClass(), getIdentifier())) {
ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnDisabled.class, getControllerServiceImplementation(), configContext);
}
stateTransition.disable();
}
}
}
});
} else {
future.complete(null);
}
return future;
}
Aggregations