/** * Handle a form POST deployment upload request. * * @param http The HttpExchange object that allows access to the request and response. * @throws IOException if an error occurs while attempting to extract the deployment from the * multipart/form data. */ private void processUploadRequest(final HttpExchange http) throws IOException { ModelNode response = null; try { SeekResult result = seekToDeployment(http); final ModelNode dmr = new ModelNode(); dmr.get("operation").set("upload-deployment-stream"); dmr.get("address").setEmptyList(); dmr.get("input-stream-index").set(0); OperationBuilder operation = new OperationBuilder(dmr); operation.addInputStream(result.stream); response = modelController.execute(operation.build()); drain(http.getRequestBody()); } catch (Throwable t) { // TODO Consider draining input stream ROOT_LOGGER.uploadError(t); http.sendResponseHeaders(INTERNAL_SERVER_ERROR, -1); return; } // TODO Determine what format the response should be in for a deployment upload request. writeResponse(http, false, false, response, OK, false, TEXT_HTML); }
@Test public void testDeploymentViaStream() throws Exception { ModelNode content = new ModelNode(); content.get(INPUT_STREAM_INDEX).set(0); ModelNode composite = createDeploymentOperation( content, OTHER_SERVER_GROUP_DEPLOYMENT_ADDRESS, MAIN_SERVER_GROUP_DEPLOYMENT_ADDRESS); OperationBuilder builder = new OperationBuilder(composite, true); builder.addInputStream(webArchive.as(ZipExporter.class).exportAsInputStream()); executeOnMaster(builder.build()); performHttpCall(DomainTestSupport.slaveAddress, 8080); }
@Test public void testJsfWorks() throws Exception { ModelNode content = new ModelNode(); content.get(INPUT_STREAM_INDEX).set(0); // Just be lazy here and deploy the jsf-test.war with the same name as the other deployments we // tried ModelNode composite = createDeploymentOperation( content, OTHER_SERVER_GROUP_DEPLOYMENT_ADDRESS, MAIN_SERVER_GROUP_DEPLOYMENT_ADDRESS); OperationBuilder builder = new OperationBuilder(composite, true); builder.addInputStream(jsfTestArchive.as(ZipExporter.class).exportAsInputStream()); executeOnMaster(builder.build()); performHttpCall(DomainTestSupport.slaveAddress, 8080, "test/home.jsf", "Bean Works"); }
private static void addContent( final OperationBuilder builder, final ModelNode op, final InputStream content) { final ModelNode contentNode = op.get(CONTENT); final ModelNode contentItem = contentNode.get(0); contentItem.get(ClientConstants.INPUT_STREAM_INDEX).set(0); builder.addInputStream(content); }
private void readLogFile(ModelNode opNode) throws IOException { Operation op = OperationBuilder.create(opNode).build(); OperationResponse response = null; try { response = getModelControllerClient().executeOperation(op, OperationMessageHandler.DISCARD); ModelNode respNode = response.getResponseNode(); Assert.assertEquals(respNode.toString(), "success", respNode.get("outcome").asString()); Assert.assertEquals(respNode.toString(), ModelType.STRING, respNode.get("result").getType()); String uuid = respNode.get("result").asString(); List<? extends OperationResponse.StreamEntry> streams = response.getInputStreams(); Assert.assertEquals(1, streams.size()); OperationResponse.StreamEntry se = streams.get(0); Assert.assertEquals(uuid, se.getUUID()); readLogStream(se.getStream()); } finally { StreamUtils.safeClose(response); } }
private OperationResponse execute(ModelNode request, boolean useWaitCursor) throws IOException { if (request.get(Util.OPERATION).asString().equals(Util.COMPOSITE) && (!request.get(Util.STEPS).isDefined() || request.get(Util.STEPS).asList().isEmpty())) { return OperationResponse.Factory.createSimple( new ModelNode( "WARN: no request was sent as there were no server-side operations to execute")); } try { if (useWaitCursor) { cliGuiCtx.getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); } return client.executeOperation( OperationBuilder.create(request).build(), OperationMessageHandler.DISCARD); } finally { if (useWaitCursor) { cliGuiCtx.getMainWindow().setCursor(Cursor.getDefaultCursor()); } } }
@Override protected void doHandle(CommandContext ctx) { ModelControllerClient client = ctx.getModelControllerClient(); if (!ctx.hasArguments()) { printList(ctx, Util.getDeployments(client)); return; } String filePath = null; String name = null; String runtimeName = null; for (String arg : ctx.getArguments()) { if (filePath == null) { filePath = arg; } else if (name == null) { name = arg; } else { runtimeName = arg; } } if (filePath == null) { printList(ctx, Util.getDeployments(client)); return; } File f = new File(filePath); if (!f.exists()) { ctx.printLine("The path doesn't exist: " + f.getAbsolutePath()); return; } if (name == null) { name = f.getName(); } if (Util.isDeployed(name, client)) { if (ctx.hasSwitch("f")) { DefaultOperationRequestBuilder builder = new DefaultOperationRequestBuilder(); ModelNode result; // replace builder = new DefaultOperationRequestBuilder(); builder.setOperationName("full-replace-deployment"); builder.addProperty("name", name); if (runtimeName != null) { builder.addProperty("runtime-name", runtimeName); } FileInputStream is = null; try { is = new FileInputStream(f); ModelNode request = builder.buildRequest(); OperationBuilder op = OperationBuilder.Factory.create(request); op.addInputStream(is); request.get("input-stream-index").set(0); result = client.execute(op.build()); } catch (Exception e) { ctx.printLine("Failed to replace the deployment: " + e.getLocalizedMessage()); return; } finally { StreamUtils.safeClose(is); } if (!Util.isSuccess(result)) { ctx.printLine(Util.getFailureDescription(result)); return; } ctx.printLine("'" + name + "' re-deployed successfully."); } else { ctx.printLine("'" + name + "' is already deployed (use -f to force re-deploy)."); } return; } else { DefaultOperationRequestBuilder builder; ModelNode result; // add builder = new DefaultOperationRequestBuilder(); builder.setOperationName("add"); builder.addNode("deployment", name); if (runtimeName != null) { builder.addProperty("runtime-name", runtimeName); } FileInputStream is = null; try { is = new FileInputStream(f); ModelNode request = builder.buildRequest(); OperationBuilder op = OperationBuilder.Factory.create(request); op.addInputStream(is); request.get("input-stream-index").set(0); result = client.execute(op.build()); } catch (Exception e) { ctx.printLine( "Failed to add the deployment content to the repository: " + e.getLocalizedMessage()); return; } finally { StreamUtils.safeClose(is); } if (!Util.isSuccess(result)) { ctx.printLine(Util.getFailureDescription(result)); return; } // deploy builder = new DefaultOperationRequestBuilder(); builder.setOperationName("deploy"); builder.addNode("deployment", name); try { ModelNode request = builder.buildRequest(); result = client.execute(request); } catch (Exception e) { ctx.printLine("Failed to deploy: " + e.getLocalizedMessage()); return; } if (!Util.isSuccess(result)) { ctx.printLine(Util.getFailureDescription(result)); return; } ctx.printLine("'" + name + "' deployed successfully."); } }
@Override public void handleRequest(final HttpServerExchange exchange) throws Exception { final FormDataParser parser = formParserFactory.createParser(exchange); if (parser == null) { Common.UNSUPPORTED_MEDIA_TYPE.handleRequest(exchange); } // Prevent CSRF which can occur from standard a multipart/form-data submission from a standard // HTML form. // If the browser sends an Origin header (Chrome / Webkit) then the earlier origin check will // have passed // to reach this point. If the browser doesn't (FireFox), then only requests which came from // Javascript, // which enforces same-origin policy when no Origin header is present, should be allowed. The // presence of // a custom header indicates usage of XHR since simple forms can not set them. HeaderMap headers = exchange.getRequestHeaders(); if (!headers.contains(Headers.ORIGIN) && !headers.contains(CLIENT_NAME)) { ROOT_LOGGER.debug( "HTTP Origin or X-Management-Client-Name header is required for all multipart form data posts."); Common.UNAUTHORIZED.handleRequest(exchange); return; } // Parse the form data final FormData data = parser.parseBlocking(); final OperationParameter.Builder operationParameterBuilder = new OperationParameter.Builder(false); // Process the operation final FormData.FormValue op = data.getFirst(OPERATION); final ModelNode operation; try { String type = op.getHeaders().getFirst(Headers.CONTENT_TYPE); if (Common.APPLICATION_DMR_ENCODED.equals(type)) { try (InputStream stream = convertToStream(op)) { operation = ModelNode.fromBase64(stream); } operationParameterBuilder.encode(true); } else if (Common.APPLICATION_JSON.equals(stripSuffix(type))) { try (InputStream stream = convertToStream(op)) { operation = ModelNode.fromJSONStream(stream); } } else { ROOT_LOGGER.debug("Content-type must be application/dmr-encoded or application/json"); Common.UNAUTHORIZED.handleRequest(exchange); return; } } catch (Exception e) { ROOT_LOGGER.errorf("Unable to construct ModelNode '%s'", e.getMessage()); Common.sendError(exchange, false, e.getLocalizedMessage()); return; } // Process the input streams final OperationBuilder builder = OperationBuilder.create(operation, true); final Iterator<String> i = data.iterator(); while (i.hasNext()) { final String name = i.next(); final Deque<FormData.FormValue> contents = data.get(name); if (contents != null && !contents.isEmpty()) { for (final FormData.FormValue value : contents) { if (value.isFile()) { builder.addFileAsAttachment(value.getPath().toFile()); } } } } operationParameterBuilder.pretty( operation.hasDefined("json.pretty") && operation.get("json.pretty").asBoolean()); // Response callback to handle the :reload operation final OperationParameter opParam = operationParameterBuilder.build(); final ResponseCallback callback = new ResponseCallback() { @Override void doSendResponse(final ModelNode response) { if (response.hasDefined(OUTCOME) && FAILED.equals(response.get(OUTCOME).asString())) { Common.sendError(exchange, opParam.isEncode(), response); return; } writeResponse(exchange, 200, response, opParam); } }; final boolean sendPreparedResponse = sendPreparedResponse(operation); final ModelController.OperationTransactionControl control = sendPreparedResponse ? new ModelController.OperationTransactionControl() { @Override public void operationPrepared( final ModelController.OperationTransaction transaction, final ModelNode result) { transaction.commit(); // Fix prepared result result.get(OUTCOME).set(SUCCESS); result.get(RESULT); callback.sendResponse(result); } } : ModelController.OperationTransactionControl.COMMIT; ModelNode response; final Operation builtOp = builder.build(); try { ModelNode opheaders = operation.get(OPERATION_HEADERS); opheaders.get(ACCESS_MECHANISM).set(AccessMechanism.HTTP.toString()); opheaders.get(CALLER_TYPE).set(USER); // Don't allow a domain-uuid operation header from a user call if (opheaders.hasDefined(DOMAIN_UUID)) { opheaders.remove(DOMAIN_UUID); } response = modelController.execute(operation, OperationMessageHandler.DISCARD, control, builtOp); } catch (Throwable t) { ROOT_LOGGER.modelRequestError(t); Common.sendError(exchange, opParam.isEncode(), t.getLocalizedMessage()); return; } finally { // Close any input streams that were open if (builtOp.isAutoCloseStreams()) { for (InputStream in : builtOp.getInputStreams()) { IoUtils.safeClose(in); } } } callback.sendResponse(response); }