/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.guvnor.ala.wildfly.access; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import com.fasterxml.jackson.annotation.JsonIgnoreType; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.ByteArrayBody; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.CloseableHttpClient; import org.jboss.dmr.ModelNode; import java.util.Date; import static java.util.logging.Level.*; import static java.util.logging.Logger.*; import static org.apache.http.entity.ContentType.APPLICATION_JSON; import static org.apache.http.entity.mime.HttpMultipartMode.*; import static org.apache.http.entity.mime.MultipartEntityBuilder.create; import static org.apache.http.impl.client.HttpClients.*; import org.apache.http.entity.StringEntity; import org.apache.http.util.EntityUtils; import org.guvnor.ala.wildfly.access.exceptions.WildflyClientException; import static org.apache.http.entity.ContentType.create; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Wildfly 10 Remote client */ @JsonIgnoreType public class WildflyClient { protected static final Logger LOG = LoggerFactory.getLogger( WildflyClient.class ); private final String providerName; private final String user; private final String password; private final String host; private final int port; private final int managementPort; public WildflyClient( String providerName, String user, String password, String host, int port, int managementPort ) { this.providerName = providerName; this.user = user; this.password = password; this.host = host; this.managementPort = managementPort; this.port = port; } /* * Deploys a new WAR file to the Wildfly Instance * @param File to be deployed, it must be a deployable file * @return the 200 on successful deployment * @throw a WildflyClientException with the status code on failure * @throw a WildflyClientException with the throwable in case of an internal exception */ public int deploy( File file ) throws WildflyClientException { // the digest auth backend CredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials( new AuthScope( host, managementPort ), new UsernamePasswordCredentials( user, password ) ); CloseableHttpClient httpclient = custom() .setDefaultCredentialsProvider( credsProvider ) .build(); HttpPost post = new HttpPost( "http://" + host + ":" + managementPort + "/management-upload" ); post.addHeader( "X-Management-Client-Name", "HAL" ); // the file to be uploaded FileBody fileBody = new FileBody( file ); // the DMR operation ModelNode operation = new ModelNode(); operation.get( "address" ).add( "deployment", file.getName() ); operation.get( "operation" ).set( "add" ); operation.get( "runtime-name" ).set( file.getName() ); operation.get( "enabled" ).set( true ); operation.get( "content" ).add().get( "input-stream-index" ).set( 0 ); // point to the multipart index used ByteArrayOutputStream bout = new ByteArrayOutputStream(); try { operation.writeBase64( bout ); } catch ( IOException ex ) { getLogger( WildflyClient.class.getName() ).log( SEVERE, null, ex ); } // the multipart MultipartEntityBuilder builder = create(); builder.setMode( BROWSER_COMPATIBLE ); builder.addPart( "uploadFormElement", fileBody ); builder.addPart( "operation", new ByteArrayBody( bout.toByteArray(), create( "application/dmr-encoded" ), "blob" ) ); HttpEntity entity = builder.build(); post.setEntity( entity ); try { HttpResponse response = httpclient.execute( post ); int statusCode = response.getStatusLine().getStatusCode(); if ( statusCode != 200 ) { throw new WildflyClientException( "Error Deploying App Status Code: " + statusCode ); } return statusCode; } catch ( IOException ex ) { LOG.error( "Error Deploying App : " + ex.getMessage(), ex ); throw new WildflyClientException( "Error Deploying App : " + ex.getMessage(), ex ); } } /* * Undeploys a new WAR file to the Wildfly Instance * @param String deploymentName * @return the 200 on successful undeployment * @throw a WildflyClientException with the status code on failure * @throw a WildflyClientException with the throwable in case of an internal exception */ public int undeploy( String deploymentName ) throws WildflyClientException { CredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials( new AuthScope( host, managementPort ), new UsernamePasswordCredentials( user, password ) ); CloseableHttpClient httpclient = custom() .setDefaultCredentialsProvider( credsProvider ) .build(); final HttpPost post = new HttpPost( "http://" + host + ":" + managementPort + "/management" ); post.addHeader( "X-Management-Client-Name", "GUVNOR-ALA" ); // the DMR operation ModelNode operation = new ModelNode(); operation.get( "operation" ).set( "remove" ); operation.get( "address" ).add( "deployment", deploymentName ); post.setEntity( new StringEntity( operation.toJSONString( true ), APPLICATION_JSON ) ); try { HttpResponse response = httpclient.execute( post ); int statusCode = response.getStatusLine().getStatusCode(); if ( statusCode != 200 ) { throw new WildflyClientException( "Error Undeploying App Status Code: " + statusCode ); } return statusCode; } catch ( IOException ex ) { LOG.error( "Error Undeploying App : " + ex.getMessage(), ex ); throw new WildflyClientException( "Error Undeploying App : " + ex.getMessage(), ex ); } } public void close() { } /* * Start the application specified by the deploymentName * @param String deploymentName * @return the 200 on successful start * @throw a WildflyClientException with the status code on failure * @throw a WildflyClientException with the throwable in case of an internal exception */ public int start( String deploymentName ) throws WildflyClientException { CredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials( new AuthScope( host, managementPort ), new UsernamePasswordCredentials( user, password ) ); CloseableHttpClient httpclient = custom() .setDefaultCredentialsProvider( credsProvider ) .build(); final HttpPost post = new HttpPost( "http://" + host + ":" + managementPort + "/management" ); post.addHeader( "X-Management-Client-Name", "GUVNOR-ALA" ); // the DMR operation ModelNode operation = new ModelNode(); operation.get( "operation" ).set( "deploy" ); operation.get( "address" ).add( "deployment", deploymentName ); post.setEntity( new StringEntity( operation.toJSONString( true ), APPLICATION_JSON ) ); try { HttpResponse response = httpclient.execute( post ); int statusCode = response.getStatusLine().getStatusCode(); if ( statusCode != 200 ) { throw new WildflyClientException( "Error Starting App Status Code: " + statusCode ); } return statusCode; } catch ( IOException ex ) { getLogger( WildflyClient.class.getName() ).log( SEVERE, null, ex ); throw new WildflyClientException( "Error Starting App : " + ex.getMessage(), ex ); } } /* * Stop the application specified by the deploymentName * @param String deploymentName * @return the 200 on successful stop * @throw a WildflyClientException with the status code on failure * @throw a WildflyClientException with the throwable in case of an internal exception */ public int stop( String deploymentName ) throws WildflyClientException { CredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials( new AuthScope( host, managementPort ), new UsernamePasswordCredentials( user, password ) ); CloseableHttpClient httpclient = custom() .setDefaultCredentialsProvider( credsProvider ) .build(); final HttpPost post = new HttpPost( "http://" + host + ":" + managementPort + "/management" ); post.addHeader( "X-Management-Client-Name", "GUVNOR-ALA" ); // the DMR operation ModelNode operation = new ModelNode(); operation.get( "operation" ).set( "undeploy" ); operation.get( "address" ).add( "deployment", deploymentName ); post.setEntity( new StringEntity( operation.toJSONString( true ), APPLICATION_JSON ) ); try { HttpResponse response = httpclient.execute( post ); int statusCode = response.getStatusLine().getStatusCode(); if ( statusCode != 200 ) { throw new WildflyClientException( "Error Stopping App Status Code: " + statusCode ); } return statusCode; } catch ( IOException ex ) { LOG.error( "Error Stopping App : " + ex.getMessage(), ex ); throw new WildflyClientException( "Error Stopping App : " + ex.getMessage(), ex ); } } public void restart( String id ) throws WildflyClientException { } /* * Returns the state of the application * @param String deploymentName * @return WildflyAppState for the given deployment name * @throw a WildflyClientException with the status code on failure * @throw a WildflyClientException with the throwable in case of an internal exception */ public WildflyAppState getAppState( String deploymentName ) throws WildflyClientException { CredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials( new AuthScope( host, managementPort ), new UsernamePasswordCredentials( user, password ) ); CloseableHttpClient httpclient = custom() .setDefaultCredentialsProvider( credsProvider ) .build(); final HttpPost post = new HttpPost( "http://" + host + ":" + managementPort + "/management" ); post.addHeader( "X-Management-Client-Name", "GUVNOR-ALA" ); // the DMR operation ModelNode operation = new ModelNode(); operation.get( "operation" ).set( "read-resource" ); operation.get( "address" ).add( "deployment", deploymentName ); operation.get( "resolve-expressions" ).set( "true" ); post.setEntity( new StringEntity( operation.toJSONString( true ), APPLICATION_JSON ) ); try { HttpResponse response = httpclient.execute( post ); String json = EntityUtils.toString( response.getEntity() ); JsonParser parser = new JsonParser(); JsonElement element = parser.parse( json ); // use the isxxx methods to find out the type of jsonelement. In our // example we know that the root object is the Albums object and // contains an array of dataset objects if ( element.isJsonObject() ) { JsonObject outcome = element.getAsJsonObject(); JsonElement resultElement = outcome.get( "result" ); String enabled = "false"; if ( resultElement != null ) { JsonObject result = resultElement.getAsJsonObject(); enabled = result.get( "enabled" ).getAsString(); } String state = ""; if ( enabled.equals( "true" ) ) { state = "Running"; } else { state = "NA"; } return new WildflyAppState( state, new Date() ); } } catch ( IOException ex ) { LOG.error( "Error Getting App State : " + ex.getMessage(), ex ); throw new WildflyClientException( "Error Getting App State : " + ex.getMessage(), ex ); } return new WildflyAppState( "NA", new Date() ); } public String getProviderName() { return providerName; } public String getUser() { return user; } public String getPassword() { return password; } public String getHost() { return host; } public int getPort() { return port; } public int getManagementPort() { return managementPort; } }