@Override
  public void enableControllerService(final ControllerService service) {
    final ControllerServiceConfiguration configuration =
        context.getConfiguration(service.getIdentifier());
    if (configuration == null) {
      throw new IllegalArgumentException("Controller Service " + service + " is not known");
    }

    if (configuration.isEnabled()) {
      throw new IllegalStateException(
          "Cannot enable Controller Service " + service + " because it is not disabled");
    }

    try {
      final ConfigurationContext configContext =
          new MockConfigurationContext(service, configuration.getProperties(), context);
      ReflectionUtils.invokeMethodsWithAnnotation(OnEnabled.class, service, configContext);
    } catch (final InvocationTargetException ite) {
      ite.getCause().printStackTrace();
      Assert.fail("Failed to enable Controller Service " + service + " due to " + ite.getCause());
    } catch (final Exception e) {
      e.printStackTrace();
      Assert.fail("Failed to enable Controller Service " + service + " due to " + e);
    }

    configuration.setEnabled(true);
  }
  @Override
  public ValidationResult setProperty(
      final ControllerService service, final PropertyDescriptor property, final String value) {
    final MockStateManager serviceStateManager =
        controllerServiceStateManagers.get(service.getIdentifier());
    if (serviceStateManager == null) {
      throw new IllegalStateException(
          "Controller service "
              + service
              + " has not been added to this TestRunner via the #addControllerService method");
    }

    final ControllerServiceConfiguration configuration = getConfigToUpdate(service);
    final Map<PropertyDescriptor, String> curProps = configuration.getProperties();
    final Map<PropertyDescriptor, String> updatedProps = new HashMap<>(curProps);

    final ValidationContext validationContext =
        new MockValidationContext(context, serviceStateManager)
            .getControllerServiceValidationContext(service);
    final ValidationResult validationResult = property.validate(value, validationContext);

    updatedProps.put(property, value);
    configuration.setProperties(updatedProps);

    return validationResult;
  }
  @Override
  public boolean isControllerServiceEnabled(final ControllerService service) {
    final ControllerServiceConfiguration configuration =
        context.getConfiguration(service.getIdentifier());
    if (configuration == null) {
      throw new IllegalArgumentException("Controller Service " + service + " is not known");
    }

    return configuration.isEnabled();
  }
  @Override
  public void addControllerService(
      final String identifier,
      final ControllerService service,
      final Map<String, String> properties)
      throws InitializationException {
    // hold off on failing due to deprecated annotation for now... will introduce later.
    // for ( final Method method : service.getClass().getMethods() ) {
    // if ( method.isAnnotationPresent(org.apache.nifi.controller.annotation.OnConfigured.class) ) {
    // Assert.fail("Controller Service " + service + " is using deprecated Annotation " +
    // org.apache.nifi.controller.annotation.OnConfigured.class + " for method " + method);
    // }
    // }

    final MockComponentLog logger = new MockComponentLog(identifier, service);
    controllerServiceLoggers.put(identifier, logger);
    final MockStateManager serviceStateManager = new MockStateManager(service);
    final MockControllerServiceInitializationContext initContext =
        new MockControllerServiceInitializationContext(
            requireNonNull(service), requireNonNull(identifier), logger, serviceStateManager);
    controllerServiceStateManagers.put(identifier, serviceStateManager);
    initContext.addControllerServices(context);
    service.initialize(initContext);

    final Map<PropertyDescriptor, String> resolvedProps = new HashMap<>();
    for (final Map.Entry<String, String> entry : properties.entrySet()) {
      resolvedProps.put(service.getPropertyDescriptor(entry.getKey()), entry.getValue());
    }

    try {
      ReflectionUtils.invokeMethodsWithAnnotation(OnAdded.class, service);
    } catch (final InvocationTargetException
        | IllegalAccessException
        | IllegalArgumentException e) {
      throw new InitializationException(e);
    }

    context.addControllerService(identifier, service, resolvedProps, null);
  }
 @Override
 public ValidationResult setProperty(
     final ControllerService service, final String propertyName, final String value) {
   final PropertyDescriptor descriptor = service.getPropertyDescriptor(propertyName);
   if (descriptor == null) {
     return new ValidationResult.Builder()
         .input(propertyName)
         .explanation(propertyName + " is not a known Property for Controller Service " + service)
         .subject("Invalid property")
         .valid(false)
         .build();
   }
   return setProperty(service, descriptor, value);
 }
  private ControllerServiceConfiguration getConfigToUpdate(final ControllerService service) {
    final ControllerServiceConfiguration configuration =
        context.getConfiguration(service.getIdentifier());
    if (configuration == null) {
      throw new IllegalArgumentException("Controller Service " + service + " is not known");
    }

    if (configuration.isEnabled()) {
      throw new IllegalStateException(
          "Controller service " + service + " cannot be modified because it is not disabled");
    }

    return configuration;
  }
  @Override
  public void assertValid(final ControllerService service) {
    final StateManager serviceStateManager =
        controllerServiceStateManagers.get(service.getIdentifier());
    if (serviceStateManager == null) {
      throw new IllegalStateException(
          "Controller Service has not been added to this TestRunner via the #addControllerService method");
    }

    final ValidationContext validationContext =
        new MockValidationContext(context, serviceStateManager)
            .getControllerServiceValidationContext(service);
    final Collection<ValidationResult> results =
        context.getControllerService(service.getIdentifier()).validate(validationContext);

    for (final ValidationResult result : results) {
      if (!result.isValid()) {
        Assert.fail(
            "Expected Controller Service to be valid but it is invalid due to: "
                + result.toString());
      }
    }
  }
  @Override
  public void disableControllerService(final ControllerService service) {
    final ControllerServiceConfiguration configuration =
        context.getConfiguration(service.getIdentifier());
    if (configuration == null) {
      throw new IllegalArgumentException("Controller Service " + service + " is not known");
    }

    if (!configuration.isEnabled()) {
      throw new IllegalStateException(
          "Controller service " + service + " cannot be disabled because it is not enabled");
    }

    try {
      ReflectionUtils.invokeMethodsWithAnnotation(OnDisabled.class, service);
    } catch (final Exception e) {
      e.printStackTrace();
      Assert.fail("Failed to disable Controller Service " + service + " due to " + e);
    }

    configuration.setEnabled(false);
  }
 /**
  * Returns the State Manager for the given Controller Service.
  *
  * @param controllerService the Controller Service whose State Manager should be returned
  * @return the State Manager for the given Controller Service
  */
 @Override
 public MockStateManager getStateManager(final ControllerService controllerService) {
   return controllerServiceStateManagers.get(controllerService.getIdentifier());
 }