/*
   * In order to test this specific scenario, we use Byteman to insert a monitor in the specific moment
   *  where the transition from STOP_REQUESTED to the next state is going to occur.
   *  This monitor will force the thread to wait until upperCount is incremented to 1.
   */
  @Test
  public void test() throws Exception {
    ServiceName serviceName = ServiceName.of("service");
    TestServiceListener serviceListener = new TestServiceListener();

    // install service as usual
    Future<ServiceController<?>> serviceStart = serviceListener.expectServiceStart(serviceName);
    serviceContainer.addService(serviceName, Service.NULL).addListener(serviceListener).install();
    ServiceController<?> serviceController = assertController(serviceName, serviceStart);

    Future<ServiceController<?>> serviceStopping =
        serviceListener.expectNoServiceStopping(serviceName);
    Future<ServiceController<?>> serviceStop = serviceListener.expectNoServiceStop(serviceName);
    serviceStart = serviceListener.expectNoServiceStart(serviceName);
    // set the mode to NEVER, so that serviceController enters STOP_REQUESTED state
    serviceController.setMode(ServiceController.Mode.NEVER);
    // set the mode to ACTIVE, so that serviceController transitions to UP state
    serviceController.setMode(ServiceController.Mode.ACTIVE);
    // no notifications are expected
    assertNull(serviceStop.get());
    assertNull(serviceStopping.get());
    assertNull(serviceStart.get());
    // service should still be in the up state
    assertSame(ServiceController.State.UP, serviceController.getState());
  }
 private void handleStateChange(ServiceController controller) {
   state = controller.getState();
   if (state == State.UP) {
     value = controller.getValue();
   }
   if (state == State.UP || state == State.START_FAILED || state == State.REMOVED) {
     controller.removeListener(this);
     finished = true;
     notifyAll();
   }
 }
 @Override
 protected void revertUpdateToRuntime(
     final OperationContext context,
     final ModelNode operation,
     final String attributeName,
     final ModelNode valueToRestore,
     final ModelNode valueToRevert,
     final Boolean handback)
     throws OperationFailedException {
   if (handback != null
       && handback.booleanValue()
       && runtimeAttributes.containsKey(attributeName)) {
     final ServiceController<?> service = getService(context, operation);
     if (service != null && service.getState() == ServiceController.State.UP) {
       // Create and execute a write-attribute operation that uses the valueToRestore
       ModelNode revertModel = context.readResource(PathAddress.EMPTY_ADDRESS).getModel().clone();
       revertModel.get(attributeName).set(valueToRestore);
       applyOperation(context, revertModel, attributeName, service);
     }
   }
 }
 @Override
 protected boolean applyUpdateToRuntime(
     final OperationContext context,
     final ModelNode operation,
     final String attributeName,
     final ModelNode newValue,
     final ModelNode currentValue,
     final HandbackHolder<Boolean> handbackHolder)
     throws OperationFailedException {
   AttributeDefinition attr = runtimeAttributes.get(attributeName);
   if (attr == null) {
     // Not a runtime attribute; restart required
     return true;
   } else {
     final ServiceController<?> service = getService(context, operation);
     if (service == null) {
       // The service isn't installed, so the work done in the Stage.MODEL part is all there is to
       // it
       return false;
     } else if (service.getState() != ServiceController.State.UP) {
       // Service is installed but not up?
       // throw new IllegalStateException(String.format("Cannot apply attribue %s to runtime;
       // service %s is not in state %s, it is in state %s",
       //            attributeName, MessagingServices.JBOSS_MESSAGING, ServiceController.State.UP,
       // hqService.getState()));
       // No, don't barf; just let the update apply to the model and put the server in a
       // reload-required state
       return true;
     } else {
       // Actually apply the update
       final ModelNode model = context.readResource(PathAddress.EMPTY_ADDRESS).getModel();
       applyOperation(context, model, attributeName, service);
       handbackHolder.setHandback(Boolean.TRUE);
       return false;
     }
   }
 }