PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/jboss-as-7.1.1.Final/host-controller/src/main/java/org/jboss/as/domain/controller/operations/deployment/DeploymentAddHandler.java

#
Java | 242 lines | 169 code | 21 blank | 52 comment | 25 complexity | 0fa79267bf8db160ad8e83aa5ced69b7 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/or its affiliates and other contributors
  4. * as indicated by the @authors tag. All rights reserved.
  5. * See the copyright.txt in the distribution for a
  6. * full listing of individual contributors.
  7. *
  8. * This copyrighted material is made available to anyone wishing to use,
  9. * modify, copy, or redistribute it subject to the terms and conditions
  10. * of the GNU Lesser General Public License, v. 2.1.
  11. * This program is distributed in the hope that it will be useful, but WITHOUT A
  12. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  13. * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
  14. * You should have received a copy of the GNU Lesser General Public License,
  15. * v.2.1 along with this distribution; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  17. * MA 02110-1301, USA.
  18. */
  19. package org.jboss.as.domain.controller.operations.deployment;
  20. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD;
  21. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ARCHIVE;
  22. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.BYTES;
  23. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.CONTENT;
  24. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.HASH;
  25. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.INPUT_STREAM_INDEX;
  26. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NAME;
  27. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
  28. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.PATH;
  29. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RELATIVE_TO;
  30. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RUNTIME_NAME;
  31. import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.URL;
  32. import static org.jboss.as.controller.operations.validation.ChainedParameterValidator.chain;
  33. import static org.jboss.as.domain.controller.DomainControllerMessages.MESSAGES;
  34. import java.io.ByteArrayInputStream;
  35. import java.io.IOException;
  36. import java.io.InputStream;
  37. import java.net.MalformedURLException;
  38. import java.net.URL;
  39. import java.util.Arrays;
  40. import java.util.List;
  41. import java.util.Locale;
  42. import org.jboss.as.controller.HashUtil;
  43. import org.jboss.as.controller.OperationContext;
  44. import org.jboss.as.controller.OperationFailedException;
  45. import org.jboss.as.controller.OperationStepHandler;
  46. import org.jboss.as.controller.PathAddress;
  47. import org.jboss.as.controller.RunningMode;
  48. import org.jboss.as.controller.descriptions.DescriptionProvider;
  49. import org.jboss.as.controller.descriptions.common.DeploymentDescription;
  50. import org.jboss.as.controller.operations.validation.AbstractParameterValidator;
  51. import org.jboss.as.controller.operations.validation.ListValidator;
  52. import org.jboss.as.controller.operations.validation.ModelTypeValidator;
  53. import org.jboss.as.controller.operations.validation.ParametersOfValidator;
  54. import org.jboss.as.controller.operations.validation.ParametersValidator;
  55. import org.jboss.as.controller.operations.validation.StringLengthValidator;
  56. import org.jboss.as.controller.registry.Resource;
  57. import org.jboss.as.domain.controller.DomainControllerLogger;
  58. import org.jboss.as.protocol.StreamUtils;
  59. import org.jboss.as.repository.ContentRepository;
  60. import org.jboss.dmr.ModelNode;
  61. import org.jboss.dmr.ModelType;
  62. /**
  63. * Handles addition of a deployment to the model.
  64. *
  65. * @author Brian Stansberry (c) 2011 Red Hat Inc.
  66. */
  67. public class DeploymentAddHandler implements OperationStepHandler, DescriptionProvider {
  68. public static final String OPERATION_NAME = ADD;
  69. private static final List<String> CONTENT_ADDITION_PARAMETERS = Arrays.asList(INPUT_STREAM_INDEX, BYTES, URL);
  70. private final ContentRepository contentRepository;
  71. private final ParametersValidator validator = new ParametersValidator();
  72. private final ParametersValidator unmanagedContentValidator = new ParametersValidator();
  73. private final ParametersValidator managedContentValidator = new ParametersValidator();
  74. /** Constructor for a slave Host Controller */
  75. public DeploymentAddHandler() {
  76. this(null);
  77. }
  78. /**
  79. * Constructor for a master Host Controller
  80. *
  81. * @param contentRepository the master content repository. If {@code null} this handler will function as a slave handler would.
  82. */
  83. public DeploymentAddHandler(final ContentRepository contentRepository) {
  84. this.contentRepository = contentRepository;
  85. this.validator.registerValidator(RUNTIME_NAME, new StringLengthValidator(1, Integer.MAX_VALUE, true, false));
  86. final ParametersValidator contentValidator = new ParametersValidator();
  87. // existing managed content
  88. contentValidator.registerValidator(HASH, new ModelTypeValidator(ModelType.BYTES, true));
  89. // existing unmanaged content
  90. contentValidator.registerValidator(ARCHIVE, new ModelTypeValidator(ModelType.BOOLEAN, true));
  91. contentValidator.registerValidator(PATH, new StringLengthValidator(1, true));
  92. contentValidator.registerValidator(RELATIVE_TO, new ModelTypeValidator(ModelType.STRING, true));
  93. // content additions
  94. contentValidator.registerValidator(INPUT_STREAM_INDEX, new ModelTypeValidator(ModelType.INT, true));
  95. contentValidator.registerValidator(BYTES, new ModelTypeValidator(ModelType.BYTES, true));
  96. contentValidator.registerValidator(URL, new StringLengthValidator(1, true));
  97. this.validator.registerValidator(CONTENT, chain(new ListValidator(new ParametersOfValidator(contentValidator)),
  98. new AbstractParameterValidator() {
  99. @Override
  100. public void validateParameter(String parameterName, ModelNode value) throws OperationFailedException {
  101. validateOnePieceOfContent(value);
  102. }
  103. }));
  104. this.managedContentValidator.registerValidator(HASH, new ModelTypeValidator(ModelType.BYTES));
  105. this.unmanagedContentValidator.registerValidator(ARCHIVE, new ModelTypeValidator(ModelType.BOOLEAN));
  106. this.unmanagedContentValidator.registerValidator(PATH, new StringLengthValidator(1));
  107. }
  108. @Override
  109. public ModelNode getModelDescription(Locale locale) {
  110. return DeploymentDescription.getAddDeploymentOperation(locale, false);
  111. }
  112. /**
  113. * {@inheritDoc}
  114. */
  115. public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
  116. validator.validate(operation);
  117. PathAddress address = PathAddress.pathAddress(operation.get(OP_ADDR));
  118. String name = address.getLastElement().getValue();
  119. String runtimeName = operation.hasDefined(RUNTIME_NAME) ? operation.get(RUNTIME_NAME).asString() : name;
  120. byte[] hash = null;
  121. // clone it, so we can modify it to our own content
  122. final ModelNode content = operation.require(CONTENT).clone();
  123. // TODO: JBAS-9020: for the moment overlays are not supported, so there is a single content item
  124. final ModelNode contentItemNode = content.require(0);
  125. if (contentItemNode.hasDefined(HASH)) {
  126. managedContentValidator.validate(contentItemNode);
  127. hash = contentItemNode.require(HASH).asBytes();
  128. // If we are the master, validate that we actually have this content. If we're not the master
  129. // we do not need the content until it's added to a server group we care about, so we defer
  130. // pulling it until then
  131. if (contentRepository != null && !contentRepository.hasContent(hash)) {
  132. if (context.isBooting()) {
  133. if (context.getRunningMode() == RunningMode.ADMIN_ONLY) {
  134. // The deployment content is missing, which would be a fatal boot error if we were going to actually
  135. // install services. In ADMIN-ONLY mode we allow it to give the admin a chance to correct the problem
  136. DomainControllerLogger.HOST_CONTROLLER_LOGGER.reportAdminOnlyMissingDeploymentContent(HashUtil.bytesToHexString(hash), name);
  137. } else {
  138. throw createFailureException(MESSAGES.noDeploymentContentWithHashAtBoot(HashUtil.bytesToHexString(hash), name));
  139. }
  140. } else {
  141. throw createFailureException(MESSAGES.noDeploymentContentWithHash(HashUtil.bytesToHexString(hash)));
  142. }
  143. }
  144. } else if (hasValidContentAdditionParameterDefined(contentItemNode)) {
  145. if (contentRepository == null) {
  146. // This is a slave DC. We can't handle this operation; it should have been fixed up on the master DC
  147. throw createFailureException(MESSAGES.slaveCannotAcceptUploads());
  148. }
  149. InputStream in = getInputStream(context, contentItemNode);
  150. try {
  151. try {
  152. hash = contentRepository.addContent(in);
  153. } catch (IOException e) {
  154. throw createFailureException(e.toString());
  155. }
  156. } finally {
  157. StreamUtils.safeClose(in);
  158. }
  159. contentItemNode.clear(); // AS7-1029
  160. contentItemNode.get(HASH).set(hash);
  161. } else {
  162. // Unmanaged content, the user is responsible for replication
  163. // Just validate the required attributes are present
  164. unmanagedContentValidator.validate(contentItemNode);
  165. }
  166. final Resource resource = context.createResource(PathAddress.EMPTY_ADDRESS);
  167. final ModelNode subModel = resource.getModel();
  168. subModel.get(NAME).set(name);
  169. subModel.get(RUNTIME_NAME).set(runtimeName);
  170. subModel.get(CONTENT).set(content);
  171. context.completeStep(OperationContext.RollbackHandler.NOOP_ROLLBACK_HANDLER);
  172. }
  173. private static InputStream getInputStream(OperationContext context, ModelNode operation) throws OperationFailedException {
  174. InputStream in = null;
  175. String message = "";
  176. if (operation.hasDefined(INPUT_STREAM_INDEX)) {
  177. int streamIndex = operation.get(INPUT_STREAM_INDEX).asInt();
  178. message = MESSAGES.nullStream(streamIndex);
  179. in = context.getAttachmentStream(streamIndex);
  180. } else if (operation.hasDefined(BYTES)) {
  181. message = MESSAGES.invalidByteStream();
  182. in = new ByteArrayInputStream(operation.get(BYTES).asBytes());
  183. } else if (operation.hasDefined(URL)) {
  184. final String urlSpec = operation.get(URL).asString();
  185. try {
  186. message = MESSAGES.invalidUrlStream();
  187. in = new URL(urlSpec).openStream();
  188. } catch (MalformedURLException e) {
  189. throw createFailureException(message);
  190. } catch (IOException e) {
  191. throw createFailureException(message);
  192. }
  193. }
  194. if (in == null) {
  195. throw createFailureException(message);
  196. }
  197. return in;
  198. }
  199. /**
  200. * Checks to see if a valid deployment parameter has been defined.
  201. *
  202. * @param operation the operation to check.
  203. * @return {@code true} of the parameter is valid, otherwise {@code false}.
  204. */
  205. private static boolean hasValidContentAdditionParameterDefined(ModelNode operation) {
  206. for (String s : CONTENT_ADDITION_PARAMETERS) {
  207. if (operation.hasDefined(s)) {
  208. return true;
  209. }
  210. }
  211. return false;
  212. }
  213. private static OperationFailedException createFailureException(String msg) {
  214. return new OperationFailedException(msg);
  215. }
  216. private static void validateOnePieceOfContent(final ModelNode content) throws OperationFailedException {
  217. // TODO: implement overlays
  218. if (content.asList().size() != 1)
  219. throw createFailureException(MESSAGES.as7431());
  220. }
  221. }