/* * 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; } } }