/* * Copyright 2016 JBoss by Red Hat. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jboss.as.controller.management; import java.util.ArrayList; import java.util.List; import org.jboss.as.controller.AbstractAddStepHandler; import org.jboss.as.controller.AttributeDefinition; import org.jboss.as.controller.OperationContext; import org.jboss.as.controller.OperationFailedException; import org.jboss.as.controller.OperationStepHandler; import org.jboss.dmr.ModelNode; import org.jboss.msc.service.ServiceController; import org.jboss.msc.service.ServiceController.State; import org.jboss.msc.service.ServiceName; import org.jboss.msc.service.ServiceNotFoundException; import org.jboss.msc.service.ServiceRegistry; import org.wildfly.security.manager.WildFlySecurityManager; /** * The base add handler for management interfaces. * @author Emmanuel Hugonnet (c) 2016 Red Hat, inc. */ public abstract class ManagementInterfaceAddStepHandler extends AbstractAddStepHandler { public static final OperationContext.AttachmentKey<Boolean> MANAGEMENT_INTERFACE_KEY = OperationContext.AttachmentKey.create(Boolean.class); protected ManagementInterfaceAddStepHandler(final AttributeDefinition[] attributeDefinitions) { super(attributeDefinitions); } protected ManagementInterfaceAddStepHandler() { super(); } @Override protected boolean requiresRuntime(OperationContext context) { //TODO Gigantic HACK to disable the runtime part of this for the core model testing. //The core model testing currently uses RunningMode.ADMIN_ONLY, but in the real world //the http interface needs to be enabled even when that happens. //I don't want to wire up all the services unless I can avoid it, so for now the tests set this system property return WildFlySecurityManager.getPropertyPrivileged("jboss.as.test.disable.runtime", null) == null; } protected void addVerifyInstallationStep(OperationContext context, List<ServiceName> requiredServices) { if(context.isBooting()) { context.addStep(new LenientVerifyInstallationStep(requiredServices), OperationContext.Stage.VERIFY); } } protected String asStringIfDefined(OperationContext context, AttributeDefinition attribute, ModelNode model) throws OperationFailedException { ModelNode attributeValue = attribute.resolveModelAttribute(context, model); return attributeValue.isDefined() ? attributeValue.asString() : null; } private static class LenientVerifyInstallationStep implements OperationStepHandler { private final List<ServiceName> requiredServices; private LenientVerifyInstallationStep(List<ServiceName> requiredServices) { assert requiredServices != null; this.requiredServices = requiredServices; } @Override public void execute(OperationContext context, ModelNode operation) throws OperationFailedException { List<ServiceName> failures = new ArrayList<>(); ServiceRegistry registry = context.getServiceRegistry(false); for (ServiceName serviceName : requiredServices) { try { ServiceController<?> controller = registry.getService(serviceName); if (controller == null || State.UP != controller.getState()) { failures.add(serviceName); } } catch (ServiceNotFoundException ex) { failures.add(serviceName); } } if (!failures.isEmpty()) { Boolean attachment = context.getAttachment(MANAGEMENT_INTERFACE_KEY); if (attachment == null || !context.getAttachment(MANAGEMENT_INTERFACE_KEY)) { context.attach(MANAGEMENT_INTERFACE_KEY, false); context.addStep(new VerifyInstallationStep(), OperationContext.Stage.VERIFY); } } else { context.attach(MANAGEMENT_INTERFACE_KEY, true); } } } private static class VerifyInstallationStep implements OperationStepHandler { @Override public void execute(OperationContext context, ModelNode operation) throws OperationFailedException { Boolean attachment = context.getAttachment(MANAGEMENT_INTERFACE_KEY); if (attachment == null ||!context.getAttachment(MANAGEMENT_INTERFACE_KEY)) { context.setRollbackOnly(); } } } }