JAVA application
Here is the sample Java application that uses the JSON files shown in the preceding sections.
import sun.misc.BASE64Encoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.KeyManagementException; import java.io.*; import java.net.URI; import java.net.URISyntaxException; import java.util.List; import java.util.ArrayList; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.params.ConnPerRouteBean; import org.apache.http.conn.params.ConnManagerParams; import org.apache.http.params.HttpParams; import org.apache.http.params.BasicHttpParams; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.AbstractHttpClient; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.HttpRequest; import org.apache.http.message.BasicNameValuePair; import org.apache.http.entity.FileEntity; import org.apache.http.client.utils.URIUtils; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpPost; import org.apache.http.util.EntityUtils; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory import javax.net.ssl.X509TrustManager import java.security.cert.X509Certificate import java.security.cert.CertificateException import java.security.cert.KeyStore import java.security.cert.KeyStoreException /** * HCP Management API - Sample Java Application */ public class MAPISample { private AbstractHttpClient httpClient = null; private String protocol; private int port; private String uname64; private String encodedPassword; private String hcpSystemAddr; private enum RequestType { PUT, POST; } public class HCPNotInitializedException extends Exception { public HCPNotInitializedException(String msg) { super("HTTP client could not be initialized in HCPAdapter for the " + "following reason: " + msg); } } public static void main(String [] args) { MAPISample adapter = null; try { adapter = new MAPISample(); // Switch the adapter to the initial user account for the new tenant. adapter.setUpSystemInfo(hcpSystemAddr, tenantUser, tenantPassword); // Modify the initial user account, using lgreen-UAroles.json as input. f = new File("/home/rsilver/MAPI/lgreen-UAroles.json"); adapter.modifylUserAccount(tenantName, tenantUser, f); // Create a user account for compliance, using mwhite-UA.json as input // and specifying start123 as the account password. f = new File("/home/rsilver/MAPI/mwhite-UA.json"); adapter.createTenantUserAccount(tenantName, "start123", f); // Configure the Tenant Management Console, using FinanceMgmtConsole.json // as input. f = new File("/home/rsilver/MAPI/FinanceMgmtConsole.json"); adapter.configureTenantSecurity(tenantName, f); // Modify the tenant, using modFinance.json as input. f = new File("/home/rsilver/MAPI/modFinance.json"); adapter.modifyTenant(tenantName, f); // Create a namespace, using AccountsRecNS.json as input. f = new File("/home/rsilver/MAPI/AccountsRecNS.json"); adapter.createNamespace(tenantName, f); // Create a namespace, using AccountsPayNS.json as input. f = new File("/home/rsilver/MAPI/AccountsPayNS.json"); adapter.createNamespace(tenantName, f); // Modify the Accounts-Receivable namespace, using // AcctsRecCompliance.json as input. String namespaceName = "Accounts-Receivable"; f = new File("/home/rsilver/MAPI/AcctsRecCompliance.json"); adapter.modifyNamespace(namespaceName, tenantName, f); // Configure HTTP for the Accounts-Receivable namespace, using http.json // as input. String namespaceName = "Accounts-Receivable"; f = new File("/home/rsilver/MAPI/http.json"); adapter.modifyNamespaceHTTP(namespaceName, tenantName, f); // Configure HTTP for the Accounts-Payable namespace, using http.json // as input. String namespaceName = "Accounts-Payable"; f = new File("/home/rsilver/MAPI/http.json"); adapter.modifyNamespaceHTTP(namespaceName, tenantName, f); // Create a user account with no roles, using pblack-UA.json as input // and specifying start123 as the account password. f = new File("/home/rsilver/MAPI/pblack-UA.json"); adapter.createTenantUserAccount(tenantName, "start123", f); // Modify the user account, using pblack-UAperms.json as input. String userAcctName = "pblack" f = new File("/home/rsilver/MAPI/pblack-UAperms.json"); adapter.changeDataUserAccountPerms(userAcctName, tenantName, f); // Create a retention class, using RC-FN-Std-42.json as input. f = new File("/home/rsilver/MAPI/RC-FN-Std-42.json"); adapter.createRetentionClass(namespaceName, tenantName, f); } catch (HCPNotInitializedException e) { e.printStackTrace(); } finally { if(adapter != null) { adapter.shutdownHttpClient(); } } } /** * Constructor - initializes the HTTP client. */ public MAPISample() throws HCPNotInitializedException{ initHttpClient(); } /** * When done with this adapter, shut it down. */ public void shutdownHttpClient() { httpClient.getConnectionManager().shutdown(); } /** * Initialize the HCP system access settings. * @param hcpSystemAddr * @param username * @param password */ public void setUpSystemInfo(String hcpSystemAddr, String username, String password) { // This is the root for management API commands. In general, these values // should be retrieved from configuration settings. this.hcpSystemAddr = hcpSystemAddr; // The management API requires HTTPS and port 9090. protocol = "https"; port = 9090; // Calculate the authentication token for management API access to HCP. BASE64Encoder base64Encoder = new BASE64Encoder(); uname64 = base64Encoder.encode(username.getBytes()); encodedPassword = toMD5Digest(password); } public void modifylUserAccount(String tenantName, String username, File jsonInputFile) { String addr = tenantName + "." + hcpSystemAddr; String path = "/mapi" + "/tenants/" + tenantName + "/userAccounts/" + username; this.executeRequest(RequestType.POST, addr, path, null, jsonInputFile); } public void createTenantUserAccount(String tenantName, String password, File jsonInputFile) { String addr = tenantName + "." + hcpSystemAddr; String path = "/mapi" + "/tenants/" + tenantName + "/userAccounts"; List<NameValuePair> metadata = new ArrayList<NameValuePair>(); metadata.add(new BasicNameValuePair("password", password)); String queryString = URLEncodedUtils.format(metadata, "UTF-8"); this.executeRequest(RequestType.PUT, addr, path, queryString, jsonInputFile); } public void configureTenantSecurity(String tenantName, File jsonInputFile) { String addr = tenantName + "." + hcpSystemAddr; String path = "/mapi" + "/tenants/" + tenantName + "/consoleSecurity"; this.executeRequest(RequestType.POST, addr, path, null, jsonInputFile); } public void modifyTenant(String tenantName, File jsonInputFile) { String addr = tenantName + "." + hcpSystemAddr; String path = "/mapi" + "/tenants/" + tenantName; this.executeRequest(RequestType.POST, addr, path, null, jsonInputFile); } public void createNamespace(String tenantName, File jsonInputFile) { String addr = tenantName + "." + hcpSystemAddr; String path = "/mapi" + "/tenants/" + tenantName + "/namespaces"; this.executeRequest(RequestType.PUT, addr, path, null, jsonInputFile); } public void modifyNamespace(String namespaceName, String tenantName, File jsonInputFile) { String addr = tenantName + "." + hcpSystemAddr; String path = "/mapi" + "/tenants/" + tenantName + "/namespaces/" + namespaceName + "/complianceSettings"; this.executeRequest(RequestType.POST, addr, path, null, jsonInputFile); } public void modifyNamespaceHTTP(String namespaceName, String tenantName, File jsonInputFile) { String addr = tenantName + "." + hcpSystemAddr; String path = "/mapi" + "/tenants/" + tenantName + "/namespaces/" + namespaceName + "/protocols/http"; this.executeRequest(RequestType.POST, addr, path, null, jsonInputFile); } public void changeDataUserAccountPerms(String dataUserAcctName, String tenantName, File jsonInputFile) { String addr = tenantName + "." + hcpSystemAddr; String path = "/mapi" + "/tenants/" + tenantName + "/userAccounts/" + dataUserAcctName + "/dataAccessPermissions"; List<NameValuePair> metadata = new ArrayList<NameValuePair>(); metadata.add(new BasicNameValuePair("debug", "true")); String queryString = URLEncodedUtils.format(metadata, "UTF-8"); this.executeRequest(RequestType.POST, addr, path, queryString, jsonInputFile); } public void createRetentionClass(String namespaceName, String tenantName, File jsonInputFile) { String addr = tenantName + "." + hcpSystemAddr; String path = "/mapi" + "/tenants/" + tenantName + "/namespaces/" + namespaceName + "/retentionClasses"; this.executeRequest(RequestType.PUT, addr, path, null, jsonInputFile); } /** * Execute the HTTP request to perform the applicable management API operation. * @param requestType * @param addr * @param path * @param queryString * @param jsonInputFile */ private void executeRequest(RequestType requestType, String addr, String path, String queryString, File jsonInputFile) { boolean success = false; try { // Set up the HTTP host. HttpHost httpHost = new HttpHost(addr, port, protocol); URI uri = URIUtils.createURI(protocol, addr, port, path, queryString, null); // JSON file. FileEntity fileEntity = new FileEntity( jsonInputFile, "application/json; charset=\"UTF-8\""); HttpRequest request; if(requestType == RequestType.PUT) { request = new HttpPut(uri); ((HttpPut)request).setEntity(fileEntity); } else { request = new HttpPost(uri); ((HttpPost)request).setEntity(fileEntity); } // Set up the authentication header. String header = "HCP " + uname64 + ":" + encodedPassword; request.setHeader("Authorization", header); // You should retry the request if the execute throws an IOException or // if HCP returns a server error. You should put the number of retry // attempts in a configuration file that can be changed depending on // network conditions. int retries = 3; while(retries > 0) { --retries; HttpResponse response = null; try { response = httpClient.execute(httpHost, request); if (response != null) { // Get back the status and log it. int statusCode = response.getStatusLine().getStatusCode(); System.out.println("Status code for PUT = " + statusCode); // PUT returns a 201 (Created) if it is successful. if(statusCode == 201) { success = true; } // Return codes below 500 are due to either a successful // PUT, an error by the client, or an authentication error. // Errors >= 500 are HCP server errors, so you should retry // on those errors. if(statusCode < 500) { retries = 0; // Notify the user about the error. For descriptions of // the management API return codes, see Appendix A. } else { if(retries == 0) { // Notify your HCP system administrator about the // error. } // Wait two minutes; then try the request again. Thread.sleep(2*60*1000); } } } catch(IOException e) { // An IOException from the client means there was a transport // error and is likely a one-off I/O issue. Try the request // again. e.printStackTrace(); if(retries == 0) { // Notify your network administrator. } } // Clean up after ourselves and release the HTTP connection to the // connection manager.EntityUtils.consume (httpResponse.getEntity()); } } catch (URISyntaxException e) { e.printStackTrace(); } catch(InterruptedException e) { e.printStackTrace(); // Wait. } } /** * Start the HTTP client. */ private void initHttpClient() throws HCPNotInitializedException { // Register the HTTPS scheme. SchemeRegistry schemeRegistry = new SchemeRegistry(); try { // The recommended protocol is TLS. SSLContext sslcontext = SSLContext.getInstance("TLS"); // The trust manager used here was created for use with this sample // application. For more information about creating trust managers, see // http://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/ // JSSERefGuide.html#TrustManager MyX509TrustManager trustMgr = new MyX509TrustManager(); sslcontext.init(null, new TrustManager[] {trustMgr}, null); SSLSocketFactory sslSocketFactory = new SSLSocketFactory(sslcontext); // The hostname verifier verifies that the hostname matches the one // stored in the X.509 certificate on the server (that is, the SSL // server certificate used by the HCP system). You can use // AllowAllHostnameVerifier, BrowserCompatHostnameVerifier, or // StrictHostnameVerifier. This sample application allows all hostnames. sslSocketFactory.setHostnameVerifier( SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); // Register the HTTPS scheme. Scheme https = new Scheme("https", sslSocketFactory, 9090); schemeRegistry.register(https); // Specify any HTTP parameters you want. HttpParams params = new BasicHttpParams(); params.setIntParameter("http.connection.timeout", 60000); // This manages a thread-safe pool of connections that are created on // first request, then persisted and leased out to subsequent requests. // By default, HCP closes a connection after ten minutes. To change // this setting, contact your authorized HCP service provider. ClientConnectionManager connMgr = new ThreadSafeClientConnManager( params, schemeRegistry); ConnPerRouteBean connPerRoute = new ConnPerRouteBean(20); // HCP recommended settings: max connections per node = 20; // total max connections = 200 ConnManagerParams.setMaxConnectionsPerRoute(params, connPerRoute); ConnManagerParams.setMaxTotalConnections(params, 200); // Ensure that the connection manager does not block indefinitely in the // connection request operation. ConnManagerParams.setTimeout(params, 2000); // milleseconds // Create the HTTP client. httpClient = new DefaultHttpClient(connMgr, params); } catch (NoSuchAlgorithmException e1) { throw new HCPNotInitializedException(e1.getMessage()); } catch (KeyManagementException e1) { throw new HCPNotInitializedException(e1.getMessage()); } } private static final String HEX_DIGITS[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}; private static String encodeBytes(byte[] bytes) { if (bytes == null || bytes.length == 0) { return ""; } StringBuffer out = new StringBuffer(bytes.length * 2); byte ch; for (int i = 0; i < bytes.length; i++) { ch = (byte) (bytes[i] & 0xF0); ch = (byte) (ch >>> 4); ch = (byte) (ch & 0x0F); out.append(HEX_DIGITS[(int) ch]); ch = (byte) (bytes[i] & 0x0F); out.append(HEX_DIGITS[(int) ch]); } return out.toString(); } protected String toMD5Digest(String sInStr) { StringBuffer mOutDigest = new StringBuffer(""); try { MessageDigest pMD = MessageDigest.getInstance("MD5"); byte pDigest[] = pMD.digest(sInStr.getBytes()); // Convert to string. for(int i=0; i < pDigest.length; i++) { mOutDigest.append(Integer.toHexString(0xFF & pDigest[i])); } } catch (Exception e) { System.err.println("Error: " + e.getMessage()); e.printStackTrace(); } return mOutDigest.toString(); } } /* Simple trust manager implementation. */ class MyX509TrustManager implements X509TrustManager { private X509TrustManager standardTrustManager = null; public MyX509TrustManager() { } public MyX509TrustManager(KeyStore keystore) throws NoSuchAlgorithmException, KeyStoreException { super(); TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); factory.init(keystore); TrustManager[] trustmanagers = factory.getTrustManagers(); if (trustmanagers.length == 0) { throw new NoSuchAlgorithmException("no trust manager found"); } this.standardTrustManager = (X509TrustManager)trustmanagers[0]; } public void checkClientTrusted(X509Certificate[] certificates,String authType) throws CertificateException { standardTrustManager.checkClientTrusted(certificates,authType); } public void checkServerTrusted(X509Certificate[] certificates,String authType) throws CertificateException { if ((certificates != null) && (certificates.length == 1)) { certificates[0].checkValidity(); } else { standardTrustManager.checkServerTrusted(certificates,authType); } } public X509Certificate[] getAcceptedIssuers() { return this.standardTrustManager.getAcceptedIssuers(); } }