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