JAVA application

Content Platform Tenant Management Help

Version
9.7.x
File Size
4269 KB
Audience
anonymous
Part Number
MK-95HCPH002-19

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 the REST API 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 the REST API 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;
                        }

                        // Status 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 status 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();
    }

}