PageRenderTime 36ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

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

#
Java | 197 lines | 133 code | 31 blank | 33 comment | 22 complexity | 0903ea4f1663decf482009673c533e47 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.FAILURE_DESCRIPTION;
  24. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP;
  25. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
  26. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RESULT;
  27. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SERVER_GROUPS;
  28. import java.io.IOException;
  29. import java.io.InputStream;
  30. import java.util.ArrayList;
  31. import java.util.List;
  32. import java.util.concurrent.atomic.AtomicReference;
  33. import org.jboss.as.controller.client.MessageSeverity;
  34. import org.jboss.as.controller.client.OperationAttachments;
  35. import org.jboss.as.controller.client.OperationMessageHandler;
  36. import org.jboss.dmr.ModelNode;
  37. /**
  38. * Step handler that uses a proxied {@link ModelController} to execute the step.
  39. *
  40. * @author Brian Stansberry (c) 2011 Red Hat Inc.
  41. */
  42. public class ProxyStepHandler implements OperationStepHandler {
  43. private final ProxyController proxyController;
  44. public ProxyStepHandler(final ProxyController proxyController) {
  45. this.proxyController = proxyController;
  46. }
  47. @Override
  48. public void execute(OperationContext context, ModelNode operation) {
  49. OperationMessageHandler messageHandler = new DelegatingMessageHandler(context);
  50. final AtomicReference<ModelController.OperationTransaction> txRef = new AtomicReference<ModelController.OperationTransaction>();
  51. final AtomicReference<ModelNode> preparedResultRef = new AtomicReference<ModelNode>();
  52. final AtomicReference<ModelNode> finalResultRef = new AtomicReference<ModelNode>();
  53. final ProxyController.ProxyOperationControl proxyControl = new ProxyController.ProxyOperationControl() {
  54. @Override
  55. public void operationPrepared(ModelController.OperationTransaction transaction, ModelNode result) {
  56. txRef.set(transaction);
  57. preparedResultRef.set(result);
  58. }
  59. @Override
  60. public void operationFailed(ModelNode response) {
  61. finalResultRef.set(response);
  62. }
  63. @Override
  64. public void operationCompleted(ModelNode response) {
  65. finalResultRef.set(response);
  66. }
  67. };
  68. proxyController.execute(operation, messageHandler, proxyControl, new DelegatingOperationAttachments(context));
  69. ModelNode finalResult = finalResultRef.get();
  70. if (finalResult != null) {
  71. // operation failed before it could commit
  72. context.getResult().set(finalResult.get(RESULT));
  73. context.getFailureDescription().set(finalResult.get(FAILURE_DESCRIPTION));
  74. context.completeStep();
  75. } else {
  76. completeRemoteTransaction(context, operation, txRef, preparedResultRef, finalResultRef);
  77. }
  78. }
  79. private void completeRemoteTransaction(OperationContext context, ModelNode operation, AtomicReference<ModelController.OperationTransaction> txRef, AtomicReference<ModelNode> preparedResultRef, AtomicReference<ModelNode> finalResultRef) {
  80. boolean txCompleted = false;
  81. try {
  82. ModelNode preparedResponse = preparedResultRef.get();
  83. ModelNode preparedResult = preparedResponse.get(RESULT);
  84. if (preparedResponse.hasDefined(FAILURE_DESCRIPTION)) {
  85. context.getFailureDescription().set(preparedResponse.get(FAILURE_DESCRIPTION));
  86. if (preparedResult.isDefined()) {
  87. context.getResult().set(preparedResult);
  88. }
  89. }
  90. else {
  91. context.getResult().set(preparedResult);
  92. }
  93. OperationContext.ResultAction resultAction = context.completeStep();
  94. ModelController.OperationTransaction tx = txRef.get();
  95. try {
  96. if (resultAction == OperationContext.ResultAction.KEEP) {
  97. tx.commit();
  98. } else {
  99. tx.rollback();
  100. }
  101. } finally {
  102. txCompleted = true;
  103. }
  104. // Get the final result from the proxy and use it to update our response.
  105. // Per the ProxyOperationControl contract, this will have been provided via operationCompleted
  106. // by the time the call to OperationTransaction.commit/rollback returns
  107. ModelNode finalResponse = finalResultRef.get();
  108. if (finalResponse != null) {
  109. ModelNode finalResult = finalResponse.get(RESULT);
  110. if (finalResponse.hasDefined(FAILURE_DESCRIPTION)) {
  111. context.getFailureDescription().set(finalResponse.get(FAILURE_DESCRIPTION));
  112. if (finalResult.isDefined()) {
  113. context.getResult().set(finalResult);
  114. }
  115. } else {
  116. context.getResult().set(finalResult);
  117. }
  118. if (context.getProcessType() == ProcessType.HOST_CONTROLLER && finalResponse.has(SERVER_GROUPS)) {
  119. context.getServerResults().set(finalResponse.get(SERVER_GROUPS));
  120. }
  121. } else {
  122. // This is an error condition
  123. ControllerLogger.SERVER_MANAGEMENT_LOGGER.noFinalProxyOutcomeReceived(operation.get(OP),
  124. operation.get(OP_ADDR), proxyController.getProxyNodeAddress().toModelNode());
  125. }
  126. } finally {
  127. // Ensure the remote side gets a transaction outcome if we can't commit/rollback above
  128. if (!txCompleted && txRef.get() != null) {
  129. txRef.get().rollback();
  130. }
  131. }
  132. }
  133. private static class DelegatingMessageHandler implements OperationMessageHandler {
  134. private final OperationContext context;
  135. DelegatingMessageHandler(final OperationContext context) {
  136. this.context = context;
  137. }
  138. @Override
  139. public void handleReport(MessageSeverity severity, String message) {
  140. context.report(severity, message);
  141. }
  142. }
  143. private static class DelegatingOperationAttachments implements OperationAttachments {
  144. private final OperationContext context;
  145. private DelegatingOperationAttachments(final OperationContext context) {
  146. this.context = context;
  147. }
  148. @Override
  149. public boolean isAutoCloseStreams() {
  150. return false;
  151. }
  152. @Override
  153. public List<InputStream> getInputStreams() {
  154. int count = context.getAttachmentStreamCount();
  155. List<InputStream> result = new ArrayList<InputStream>(count);
  156. for (int i = 0; i < count; i++) {
  157. result.add(context.getAttachmentStream(i));
  158. }
  159. return result;
  160. }
  161. @Override
  162. public void close() throws IOException {
  163. //
  164. }
  165. }
  166. }