Using Apache HTTPClient to build, download, upload, and install a CQ 5.4 content package

I have been writing some curl scripts to build, download, upload, and install CQ content packages.  **

As an alternative I decided to write some code which builds, and downloads, uploads and installs  a CQ 5.4 content package.

I have a simple main class PackageMain  which create a Package and an Environment.  The **PackageAction **class contains the CQ build, download, upload, install functionality.

The remaining classes CQ Environment (Env), and **PackageBase **are utility classes.

I hope you find these classes useful.  The eclipse project will be available “soon”.


package com.chocksaway;

import java.io.IOException;

import org.apache.http.client.ClientProtocolException;

public class PackageMain { public static void main(String[] args) throws ClientProtocolException, IOException {

/**

  • name of content package, path for content package */ PackageBase pb = new PackageBase(“myContentPackage.zip”, “/crx/packmgr/service/.json/etc/packages/my_packages/” );

/**

  • IP address, port number, protocol, user, pass */

Env srcEnv = new Env(“127.0.0.1”, 9002, “http”, “admin”, “password” );

Env destEnv = new Env(“127.0.0.1”, 4500, “http”, “admin”, “password” );

PackageAction pa = new PackageAction(pb, srcEnv); pa.build(); pa.pull();

pa = new PackageAction(pb, destEnv);

pa.push(); pa.install();

}

}


**A PackageAction **encloses the build, pull, push, and install functionality


package com.chocksaway;

import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.StringTokenizer;

import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.AuthCache; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.protocol.ClientContext; import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.entity.mime.content.StringBody; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.client.BasicAuthCache; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.util.EntityUtils;

public class PackageAction {

private static final String CMD = “?cmd=”; private static final String BUILD = CMD + “build”; private static final String INSTALL = CMD + “install”; private static final String UPLOAD = CMD + “upload”;

private PackageBase pack; private Env env; BasicHttpContext localcontext;

/**

  • A package needs to be associated with an environment *
  • @param pack
  • @param env */ PackageAction(PackageBase pack, Env env) { this.pack = pack; this.env = env; }

private DefaultHttpClient getHTTPClient() { HttpHost targetHost = new HttpHost(env.getIp(), env.getPort(), env .getProtocol());

DefaultHttpClient httpclient = new DefaultHttpClient();

httpclient.getCredentialsProvider().setCredentials( new AuthScope(targetHost.getHostName(), targetHost.getPort()), new UsernamePasswordCredentials(env.getUser(), env.getPass()));

// Create AuthCache instance AuthCache authCache = new BasicAuthCache(); // Generate BASIC scheme object and add it to the local // auth cache BasicScheme basicAuth = new BasicScheme(); authCache.put(targetHost, basicAuth);

// Add AuthCache to the execution context localcontext = new BasicHttpContext(); localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);

return httpclient;

}

/**

  • Clean up and disconnect Ensures that the entity content is fully consumed
  • and the content stream, if exists, is closed *
  • @param entity
  • @param httpclient
  • @throws IOException */ private void cleanUp(HttpEntity entity, DefaultHttpClient httpClient) throws IOException { EntityUtils.consume(entity); httpClient.getConnectionManager().shutdown(); }

/**

  • Parse the HTTP response and check for “success”:true”
  • This cannot be used for HTTP download of a package
  • @param response
  • @return
  • @throws IllegalStateException
  • @throws IOException */ private boolean validateHTTPResponseForCQAction(HttpResponse response) throws IllegalStateException, IOException { BufferedReader rd = new BufferedReader(new InputStreamReader(response .getEntity().getContent())); String line; StringBuffer buff;

if (response != null) { buff = new StringBuffer(); while ((line = rd.readLine()) != null) { buff.append(line); }

System.out.println(buff.toString()); if (buff.toString().contains(““success”:true”)) { return true; } }

return false; }

/**

  • Build content package *
  • @throws ClientProtocolException
  • @throws IOException */ void build() throws ClientProtocolException, IOException { HttpHost targetHost = new HttpHost(env.getIp(), env.getPort(), env .getProtocol()); DefaultHttpClient httpclient = getHTTPClient();

HttpPost httpPost = new HttpPost(pack.getPath() + pack.getName()

  • BUILD);

HttpResponse response = httpclient.execute(targetHost, httpPost, localcontext);

validateHTTPResponseForCQAction(response); HttpEntity entity = response.getEntity();

cleanUp(entity, httpclient); }

/**

  • Split a package name. For example:
  • “/crx/packmgr/service/.json/etc/packages/my_packages/” Needs to return
  • /etc/packages/my_packages/ *
  • @return */ private String getPackageDownloadLocation() { // “/crx/packmgr/service/.json/etc/packages/my_packages/” ); StringBuffer buff; boolean found=false;

if (pack.getPath() != null) { StringTokenizer st = new StringTokenizer(pack.getPath(), “/”); buff = new StringBuffer();

while (st.hasMoreTokens()) { String eachTok = st.nextToken(); if (found) { buff.append(eachTok + “/”); } else if (eachTok.equals(“.json”)) { buff.append(“/”); found = true; } }

return buff.toString();

}

return null;

}

/**

  • Download content package to local file system *
  • @throws ClientProtocolException
  • @throws IOException */ void pull() throws ClientProtocolException, IOException { HttpHost targetHost = new HttpHost(env.getIp(), env.getPort(), env .getProtocol()); DefaultHttpClient httpclient = getHTTPClient();

// HttpPost httpPost = new HttpPost(pack.getPath() + pack.getName());

// http://vm002/etc/packages/export/bgasExportTesting.zip

HttpGet httpGet = new HttpGet(getPackageDownloadLocation()

  • pack.getName());

//HttpGet httpGet = new HttpGet(“/etc/packages/my_packages/” //+ pack.getName());

HttpResponse response = httpclient.execute(targetHost, httpGet, localcontext);

// validateHTTPResponseForCQAction(response); HttpEntity entity = response.getEntity();

if (entity != null) { FileOutputStream fos = new java.io.FileOutputStream(pack.getName()); entity.writeTo(fos); fos.close(); }

cleanUp(entity, httpclient); }

/**

  • Upload a CQ content package The force=true parameter is used (forces an
  • upload even if package already exists *
  • @throws ClientProtocolException
  • @throws IOException */ void push() throws ClientProtocolException, IOException {

HttpHost targetHost = new HttpHost(env.getIp(), env.getPort(), env .getProtocol()); DefaultHttpClient httpclient = getHTTPClient();

HttpPost httpPost = new HttpPost(pack.getPath() + pack.getName()

  • UPLOAD);

// HttpPost httppost = new HttpPost( // “http://localhost:4500/crx/packmgr/service/.json/?cmd=upload”); File file = new File(pack.getName());

if (file.exists()) { System.out.println(“file exists”); }

MultipartEntity mpEntity = new MultipartEntity(); ContentBody cbFile = new FileBody(file, “zip”); mpEntity.addPart(“package”, cbFile); mpEntity.addPart(“force”, new StringBody(“true”));

httpPost.setEntity(mpEntity);

HttpResponse response = httpclient.execute(targetHost, httpPost, localcontext); validateHTTPResponseForCQAction(response);

HttpEntity entity = response.getEntity();

cleanUp(entity, httpclient); }

/**

  • Install a CQ content package *
  • @throws ClientProtocolException
  • @throws IOException */ void install() throws ClientProtocolException, IOException { HttpHost targetHost = new HttpHost(env.getIp(), env.getPort(), env .getProtocol()); DefaultHttpClient httpclient = getHTTPClient();

HttpPost httpPost = new HttpPost(pack.getPath() + pack.getName()

  • INSTALL);

HttpResponse response = httpclient.execute(targetHost, httpPost, localcontext); validateHTTPResponseForCQAction(response); HttpEntity entity = response.getEntity(); cleanUp(entity, httpclient);

}

}


**PackageBase **which

package com.chocksaway;

/**

  • Java content package * */ public class PackageBase { private String name; private String path;

PackageBase(String name, String path) { this.name = name; this.path = path; }

private enum STATE { build, download, upload, install }

/**

  • A package has a name and state */ public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public String getState(String state) { // TODO Auto-generated method stub return state; } }

CQ Environment


package com.chocksaway;

/**

  • CQ environment definition * */ public class Env { Env(String ip, int port, String protocol, String user, String pass) { this.ip = ip; this.port = port; this.protocol = protocol; this.user = user; this.pass = pass; }

private String ip; private int port; private String protocol; private String user; private String pass;

public String getIp() { return ip; }

public void setIp(String ip) { this.ip = ip; }

public int getPort() { return port; }

public void setPort(int port) { this.port = port; }

public String getProtocol() { return protocol; }

public void setProtocol(String protocol) { this.protocol = protocol; }

public String getUser() { return user; }

public void setUser(String user) { this.user = user; }

public String getPass() { return pass; }

public void setPass(String pass) { this.pass = pass; }

}

Author | Miles Davenport

Career programmer, who designs, assembles, fixes, and supports customers, software and systems.