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();
// in the adapter.
String hcpSystemAddr = "hcp-ma.example.com";
String adminUser = "rsilver";
String adminPassword = "p4ssw0rd";
adapter.setUpSystemInfo(hcpSystemAddr, adminUser, adminPassword);
// Create a tenant, using FinanceTenant.json as input.
String tenantName = "finance";
String tenantUser = "lgreen";
String tenantPassword = "start123";
File f = new File("/home/rsilver/MAPI/FinanceTenant.json");
adapter.createTenant(f, tenantUser, tenantPassword);
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);
// and add HCP tenant Finance
adapter.setUpSystemInfo(hcpSystemAddr, adminUser, adminPassword);
f = new File("/home/rsilver/MAPI/LinkMA-CA.json");
adapter.createReplicationLink(f, tenantName);
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);
}
String password) {
String addr = "admin." + hcpSystemAddr;
String path = "/mapi/tenants";
List<NameValuePair> metadata = new ArrayList<NameValuePair>();
metadata.add(new BasicNameValuePair("username", tenantInitialUserName));
metadata.add(new BasicNameValuePair("password", password));
metadata.add(new BasicNameValuePair("forcePasswordChange", "false"));
String queryString = URLEncodedUtils.format(metadata, "UTF-8");
this.executeRequest(RequestType.PUT, addr, path, queryString, jsonInputFile);
}
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);
}
String addr = "admin." + hcpSystemAddr;
String path = "/mapi/services/replication/links";
this.executeRequest(RequestType.PUT, addr, path, null, jsonInputFile);
path = "/mapi/services/replication/links/MA-CA/content/tenants/" +
tenantName;
this.executeRequest(RequestType.PUT, addr, path, null, null);
}
/**
* 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();
}
}
© 2015, 2020 Hitachi Vantara LLC. All rights reserved.