PageRenderTime 58ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/jboss-as-7.1.1.Final/controller/src/main/java/org/jboss/as/controller/RestartParentResourceHandlerBase.java

#
Java | 205 lines | 100 code | 24 blank | 81 comment | 20 complexity | 8ba39cae1babf3d3dc249ff61d93c411 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1. /*
  2. * JBoss, Home of Professional Open Source.
  3. * Copyright 2011, Red Hat, Inc., and individual contributors
  4. * as indicated by the @author tags. See the copyright.txt file in the
  5. * distribution for a full listing of individual contributors.
  6. *
  7. * This is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This software is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this software; if not, write to the Free
  19. * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20. * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21. */
  22. package org.jboss.as.controller;
  23. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
  24. import java.util.NoSuchElementException;
  25. import org.jboss.as.controller.operations.common.Util;
  26. import org.jboss.as.controller.registry.Resource;
  27. import org.jboss.dmr.ModelNode;
  28. import org.jboss.msc.service.ServiceController;
  29. import org.jboss.msc.service.ServiceName;
  30. /**
  31. * Simple remove handler that, if allowed, restarts a parent resource when a child is removed.
  32. * Otherwise the server is put into a forced reload.
  33. *
  34. * @author Jason T. Greene
  35. */
  36. public abstract class RestartParentResourceHandlerBase implements OperationStepHandler {
  37. private final String parentKeyName;
  38. protected RestartParentResourceHandlerBase(String parentKeyName) {
  39. this.parentKeyName = parentKeyName;
  40. }
  41. @Override
  42. public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
  43. // Do the simple model part
  44. updateModel(context, operation);
  45. if (!context.isBooting() && requiresRuntime(context)) {
  46. context.addStep(new OperationStepHandler() {
  47. @Override
  48. public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
  49. PathAddress address = getParentAddress(PathAddress.pathAddress(operation.require(OP_ADDR)));
  50. ServiceName serviceName = getParentServiceName(address);
  51. final ServiceController<?> service = serviceName != null ?
  52. context.getServiceRegistry(false).getService(serviceName) : null;
  53. ModelNode parentModel = null;
  54. boolean servicesRestarted = false;
  55. final boolean reloadRequired = service != null && !isResourceServiceRestartAllowed(context, service);
  56. if (reloadRequired) {
  57. context.reloadRequired();
  58. } else if (service != null ) {
  59. parentModel = getModel(context, address);
  60. if (parentModel != null && context.markResourceRestarted(address, this)) {
  61. removeServices(context, serviceName, parentModel);
  62. final ServiceVerificationHandler verificationHandler = new ServiceVerificationHandler();
  63. recreateParentService(context, address, parentModel, verificationHandler);
  64. context.addStep(verificationHandler, OperationContext.Stage.VERIFY);
  65. servicesRestarted = true;
  66. }
  67. } // else No parent service, nothing to do
  68. // If we restarted services, keep the model that drove the new services so we can
  69. // revert the change on rollback
  70. final ModelNode invalidatedParentModel = servicesRestarted ? parentModel : null;
  71. context.completeStep(new OperationContext.RollbackHandler() {
  72. @Override
  73. public void handleRollback(OperationContext context, ModelNode operation) {
  74. if (reloadRequired) {
  75. context.revertReloadRequired();
  76. } else if (invalidatedParentModel != null) {
  77. recoverServices(context, operation, invalidatedParentModel);
  78. }
  79. }
  80. });
  81. }
  82. }, OperationContext.Stage.RUNTIME);
  83. }
  84. context.completeStep(OperationContext.RollbackHandler.NOOP_ROLLBACK_HANDLER);
  85. }
  86. /**
  87. * Gets whether this operation needs to update the runtime. The default implementation returns {@code true}
  88. * if {@link OperationContext#getProcessType() the process type} is not {@link ProcessType#HOST_CONTROLLER}.
  89. *
  90. * @param context the operation context
  91. * @return {@code true} if the operation should update the runtime; {@code false} if it only updates the configuration
  92. * model
  93. */
  94. protected boolean requiresRuntime(OperationContext context) {
  95. return context.getProcessType() != ProcessType.HOST_CONTROLLER;
  96. }
  97. /**
  98. * Gets whether a restart of the parent resource's services is allowed. This default implementation
  99. * checks whether {@link OperationContext#isResourceServiceRestartAllowed() the context allows resource service restarts};
  100. * subclasses could also check the state of the {@code service}.
  101. *
  102. * @param context the operation context
  103. * @param service the parent service
  104. * @return {@code true} if a restart is allowed; {@code false}
  105. */
  106. protected boolean isResourceServiceRestartAllowed(final OperationContext context, final ServiceController<?> service) {
  107. return context.isResourceServiceRestartAllowed();
  108. }
  109. /**
  110. * Removes services. This default implementation simply
  111. * {@link OperationContext#removeService(ServiceController) instructs the context to remove the parentService}.
  112. * Subclasses could use the provided {@code parentModel} to identify and remove other services.
  113. *
  114. * @param context the operation context
  115. * @param parentService the name of the parent service
  116. * @param parentModel the model associated with the parent resource, including nodes for any child resources
  117. *
  118. * @throws OperationFailedException if there is a problem removing the services
  119. */
  120. protected void removeServices(final OperationContext context, final ServiceName parentService, final ModelNode parentModel) throws OperationFailedException {
  121. context.removeService(parentService);
  122. }
  123. /**
  124. * Performs the update to the persistent configuration model.
  125. *
  126. * @param context the operation context
  127. * @param operation the operation
  128. * @throws OperationFailedException if there is a problem updating the model
  129. */
  130. protected abstract void updateModel(final OperationContext context, final ModelNode operation) throws OperationFailedException;
  131. /**
  132. * Recreate the parent service(s) using the given model.
  133. *
  134. * @param context the operation context
  135. * @param parentAddress the address of the parent resource
  136. * @param parentModel the current configuration model for the parent resource and its children
  137. * @param verificationHandler handler for verifying newly installed services
  138. *
  139. * @throws OperationFailedException if there is a problem installing the services
  140. */
  141. protected abstract void recreateParentService(OperationContext context, PathAddress parentAddress, ModelNode parentModel, ServiceVerificationHandler verificationHandler) throws OperationFailedException;
  142. /**
  143. * Gets the name of the parent service.
  144. *
  145. * @param parentAddress the address of the parent resource
  146. * @return the service name
  147. */
  148. protected abstract ServiceName getParentServiceName(PathAddress parentAddress);
  149. protected PathAddress getParentAddress(PathAddress address) {
  150. return Util.getParentAddressByKey(address, parentKeyName);
  151. }
  152. private void recoverServices(final OperationContext context, final ModelNode operation, final ModelNode invalidatedParentModel) {
  153. PathAddress address = getParentAddress(PathAddress.pathAddress(operation.require(OP_ADDR)));
  154. ServiceName serviceName = getParentServiceName(address);
  155. ModelNode parentModel = getOriginalModel(context, address);
  156. if (parentModel != null && context.revertResourceRestarted(address, this)) {
  157. try {
  158. removeServices(context, serviceName, invalidatedParentModel);
  159. recreateParentService(context, address, parentModel, null);
  160. } catch (OperationFailedException e) {
  161. throw ControllerMessages.MESSAGES.failedToRecoverServices(e);
  162. }
  163. }
  164. }
  165. private ModelNode getModel(OperationContext ctx, PathAddress address) {
  166. try {
  167. Resource resource = ctx.readResourceFromRoot(address);
  168. return Resource.Tools.readModel(resource);
  169. } catch (NoSuchElementException e) {
  170. return null;
  171. }
  172. }
  173. private ModelNode getOriginalModel(OperationContext ctx, PathAddress address) {
  174. try {
  175. Resource resource = ctx.getOriginalRootResource().navigate(address);
  176. return Resource.Tools.readModel(resource);
  177. } catch (NoSuchElementException e) {
  178. return null;
  179. }
  180. }
  181. }