[DMAAP-BC] Add truststore to https client requests
[dmaap/dbcapi.git] / src / main / java / org / onap / dmaap / dbcapi / client / DrProvConnection.java
index 751c5b8..dffe830 100644 (file)
@@ -3,6 +3,8 @@
  * org.onap.dmaap
  * ================================================================================
  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,20 +31,15 @@ import java.net.ConnectException;
 import java.net.ProtocolException;
 import java.net.SocketException;
 import java.net.URL;
-import java.util.ArrayList;
-
+import java.util.Arrays;
 import javax.net.ssl.HttpsURLConnection;
-
-import org.apache.log4j.Logger;
-import org.apache.log4j.PropertyConfigurator;
 import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
 import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
 import org.onap.dmaap.dbcapi.model.ApiError;
-import org.onap.dmaap.dbcapi.model.DR_Pub;
 import org.onap.dmaap.dbcapi.model.DR_Sub;
 import org.onap.dmaap.dbcapi.model.Feed;
 import org.onap.dmaap.dbcapi.service.DmaapService;
-import org.onap.dmaap.dbcapi.util.RandomInteger;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
 
 
 
@@ -50,6 +47,12 @@ public class DrProvConnection extends BaseLoggingClass {
           
    
        private String provURL;
+       private String provApi;
+       private String  behalfHeader;
+       private String  feedContentType;
+       private String  subContentType;
+       private String unit_test;
+       private String  provURI;
        
        private HttpsURLConnection uc;
 
@@ -57,8 +60,17 @@ public class DrProvConnection extends BaseLoggingClass {
        public DrProvConnection() {
                provURL = new DmaapService().getDmaap().getDrProvUrl();
                if ( provURL.length() < 1 ) {
-                       errorLogger.error( DmaapbcLogMessageEnum.PREREQ_DMAAP_OBJECT, "getDrProvUrl");
+                       errorLogger.error( DmaapbcLogMessageEnum.PREREQ_DMAAP_OBJECT, "DmaapService().getDmaap().getDrProvUrl()");
                }
+               DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+               provApi = p.getProperty( "DR.provApi", "ONAP" );
+               behalfHeader = p.getProperty( "DR.onBehalfHeader", "X-DMAAP-DR-ON-BEHALF-OF");
+               feedContentType = p.getProperty( "DR.feedContentType", "application/vnd.dmaap-dr.feed");
+               subContentType = p.getProperty( "DR.subContentType", "application/vnd.dmaap-dr.subscription");
+               provURI = p.getProperty( "DR.ProvisioningURI", "/internal/prov");
+               logger.info( "provURL=" + provURL + " provApi=" + provApi + " behalfHeader=" + behalfHeader
+                               + " feedContentType=" + feedContentType + " subContentType=" + subContentType );
+               unit_test = p.getProperty( "UnitTest", "No" );
                        
        }
        
@@ -90,6 +102,10 @@ public class DrProvConnection extends BaseLoggingClass {
                                        sub,  nodep );
                return makeConnection( provURL + uri );
        }
+       public boolean makeDumpConnection() {
+               String url = provURL + provURI;
+               return makeConnection( url );
+       }
        public boolean makeNodesConnection( String varName ) {
                
                String uri = String.format("/internal/api/%s", varName);
@@ -114,13 +130,12 @@ public class DrProvConnection extends BaseLoggingClass {
                        uc = (HttpsURLConnection) u.openConnection();
                        uc.setInstanceFollowRedirects(false);
                        logger.info( "successful connect to " + pURL );
+                       uc.setSSLSocketFactory(DmaapConfig.getSSLSocketFactory());
                        return(true);
                } catch (Exception e) {
                        errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_ERROR,  pURL, e.getMessage() );
-            e.printStackTrace();
             return(false);
         }
-
        }
        
        public String bodyToString( InputStream is ) {
@@ -143,22 +158,22 @@ public class DrProvConnection extends BaseLoggingClass {
        public  String doPostFeed( Feed postFeed, ApiError err ) {
 
                byte[] postData = postFeed.getBytes();
-               logger.info( "post fields=" + postData.toString() );
+               logger.info( "post fields=" + Arrays.toString(postData) );
                String responsemessage = null;
                String responseBody = null;
+               int rc = -1;
 
                try {
                        logger.info( "uc=" + uc );
                        uc.setRequestMethod("POST");
-                       uc.setRequestProperty("Content-Type", "application/vnd.att-dr.feed");
+                       uc.setRequestProperty("Content-Type", feedContentType);
                        uc.setRequestProperty( "charset", "utf-8");
-                       uc.setRequestProperty( "X-ATT-DR-ON-BEHALF-OF", postFeed.getOwner() );
+                       uc.setRequestProperty( behalfHeader, postFeed.getOwner() );
                        uc.setRequestProperty( "Content-Length", Integer.toString( postData.length ));
                        uc.setUseCaches(false);
                        uc.setDoOutput(true);
                        OutputStream os = null;
-                       int rc = -1;
-                       
+
                        try {
                  uc.connect();
                  os = uc.getOutputStream();
@@ -172,13 +187,14 @@ public class DrProvConnection extends BaseLoggingClass {
                      uc.setDoOutput(false);
                  } catch (Exception e) {
                  }
-            }
+            } catch (Exception e) {
+                               logger.info( "Exception: " + e.getMessage() );
+                               e.printStackTrace();
+                       }
                        rc = uc.getResponseCode();
                        logger.info( "http response code:" + rc );
-            responsemessage = uc.getResponseMessage();
-            logger.info( "responsemessage=" + responsemessage );
-
-
+                       responsemessage = uc.getResponseMessage();
+                       logger.info( "responsemessage=" + responsemessage );
             if (responsemessage == null) {
                  // work around for glitch in Java 1.7.0.21 and likely others
                  // When Expect: 100 is set and a non-100 response is received, the response message is not set but the response code is
@@ -209,20 +225,28 @@ public class DrProvConnection extends BaseLoggingClass {
                        err.setCode( 500 );
                        err.setMessage( "Unable to read response from DR");
         } catch (Exception e) {
-            logger.warn("Unable to read response  " );
-            e.printStackTrace();
-            try {
-                   err.setCode( uc.getResponseCode());
-                   err.setMessage(uc.getResponseMessage());
-            } catch (Exception e2) {
-               err.setCode( 500 );
-               err.setMessage("Unable to determine response message");
-            }
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doPostFeed because unit_test =" + unit_test );
+               } else {
+                   logger.warn("Unable to read response  " );
+                   errorLogger.error("Unable to read response  ", e.getMessage());
+                   try {
+                           err.setCode( uc.getResponseCode());
+                           err.setMessage(uc.getResponseMessage());
+                   } catch (Exception e2) {
+                       err.setCode( 500 );
+                       err.setMessage("Unable to determine response message");
+                   }
+               }
         } 
                finally {
                        try {
                                uc.disconnect();
-                       } catch ( Exception e ) {}
+                       } catch ( Exception e ) {
+                               logger.error(e.getMessage(), e);
+                       }
                }
                return responseBody;
 
@@ -238,19 +262,10 @@ public class DrProvConnection extends BaseLoggingClass {
 
                try {
                        uc.setRequestMethod("POST");
-//                     uc.setRequestProperty("Content-Type", "application/vnd.att-dr.feed");
-//                     uc.setRequestProperty( "charset", "utf-8");
-//                     uc.setRequestProperty( "X-ATT-DR-ON-BEHALF-OF", postFeed.getOwner() );
-//                     uc.setRequestProperty( "Content-Length", Integer.toString( postData.length ));
-//                     uc.setUseCaches(false);
-//                     uc.setDoOutput(true);   
-                       OutputStream os = null;
-       
-                       
+
+
                        try {
                  uc.connect();
-                 os = uc.getOutputStream();
-
 
             } catch (ProtocolException pe) {
                  // Rcvd error instead of 100-Continue
@@ -259,8 +274,12 @@ public class DrProvConnection extends BaseLoggingClass {
                      // without this, Java will connect multiple times to the server to run the same request
                      uc.setDoOutput(false);
                  } catch (Exception e) {
+                       logger.error(e.getMessage(), e);
                  }
-            }
+                       } catch (Exception e) {
+                               logger.info( "Exception: " + e.getMessage() );
+                               e.printStackTrace();
+                       }
                        rc = uc.getResponseCode();
                        logger.info( "http response code:" + rc );
             responsemessage = uc.getResponseMessage();
@@ -273,12 +292,21 @@ public class DrProvConnection extends BaseLoggingClass {
                err.setMessage(responsemessage);
             }
                } catch (Exception e) {
-            System.err.println("Unable to read response  " );
-            e.printStackTrace();
-        }              finally {
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doXgressPost because unit_test =" + unit_test );
+               } else {
+                   logger.error("Unable to read response  " );
+                   logger.error(e.getMessage(), e);
+               }
+        }              
+        finally {
                        try {
                                uc.disconnect();
-                       } catch ( Exception e ) {}
+                       } catch ( Exception e ) {
+                               logger.error(e.getMessage(), e);
+                       }
                }
        
                return rc;
@@ -287,7 +315,7 @@ public class DrProvConnection extends BaseLoggingClass {
        
        public String doPostDr_Sub( DR_Sub postSub, ApiError err ) {
                logger.info( "entry: doPostDr_Sub() "  );
-               byte[] postData = postSub.getBytes();
+               byte[] postData = postSub.getBytes(provApi );
                logger.info( "post fields=" + postData );
                String responsemessage = null;
                String responseBody = null;
@@ -296,9 +324,9 @@ public class DrProvConnection extends BaseLoggingClass {
        
                        uc.setRequestMethod("POST");
                
-                       uc.setRequestProperty("Content-Type", "application/vnd.att-dr.subscription");
+                       uc.setRequestProperty("Content-Type", subContentType );
                        uc.setRequestProperty( "charset", "utf-8");
-                       uc.setRequestProperty( "X-ATT-DR-ON-BEHALF-OF", "DGL" );
+                       uc.setRequestProperty( behalfHeader, "DGL" );
                        uc.setRequestProperty( "Content-Length", Integer.toString( postData.length ));
                        uc.setUseCaches(false);
                        uc.setDoOutput(true);
@@ -317,8 +345,12 @@ public class DrProvConnection extends BaseLoggingClass {
                      // without this, Java will connect multiple times to the server to run the same request
                      uc.setDoOutput(false);
                  } catch (Exception e) {
+                        logger.error(e.getMessage(), e);
                  }
-            }
+                       } catch (Exception e) {
+                               logger.info( "Exception: " + e.getMessage() );
+                               e.printStackTrace();
+                       }
                        rc = uc.getResponseCode();
                        logger.info( "http response code:" + rc );
             responsemessage = uc.getResponseMessage();
@@ -347,12 +379,20 @@ public class DrProvConnection extends BaseLoggingClass {
             }
             
                } catch (Exception e) {
-            System.err.println("Unable to read response  " );
-            e.printStackTrace();
-        }              finally {
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doPostDr_Sub because unit_test =" + unit_test );
+               } else {
+                   logger.error("Unable to read response  ", e.getMessage());
+               }
+        }              
+               finally {
                        try {
                                uc.disconnect();
-                       } catch ( Exception e ) {}
+                       } catch ( Exception e ) {
+                               logger.error(e.getMessage(), e);
+                       }
                }
                return responseBody;
 
@@ -361,16 +401,16 @@ public class DrProvConnection extends BaseLoggingClass {
 
        public String doPutFeed(Feed putFeed, ApiError err) {
                byte[] postData = putFeed.getBytes();
-               logger.info( "post fields=" + postData.toString() );
+               logger.info( "post fields=" + Arrays.toString(postData) );
                String responsemessage = null;
                String responseBody = null;
 
                try {
                        logger.info( "uc=" + uc );
                        uc.setRequestMethod("PUT");
-                       uc.setRequestProperty("Content-Type", "application/vnd.att-dr.feed");
+                       uc.setRequestProperty("Content-Type", feedContentType );
                        uc.setRequestProperty( "charset", "utf-8");
-                       uc.setRequestProperty( "X-ATT-DR-ON-BEHALF-OF", putFeed.getOwner() );
+                       uc.setRequestProperty( behalfHeader, putFeed.getOwner() );
                        uc.setRequestProperty( "Content-Length", Integer.toString( postData.length ));
                        uc.setUseCaches(false);
                        uc.setDoOutput(true);
@@ -389,8 +429,12 @@ public class DrProvConnection extends BaseLoggingClass {
                      // without this, Java will connect multiple times to the server to run the same request
                      uc.setDoOutput(false);
                  } catch (Exception e) {
+                        logger.error(e.getMessage(), e);
                  }
-            }
+                       } catch (Exception e) {
+                               logger.info( "Exception: " + e.getMessage() );
+                               e.printStackTrace();
+                       }
                        rc = uc.getResponseCode();
                        logger.info( "http response code:" + rc );
             responsemessage = uc.getResponseMessage();
@@ -412,7 +456,7 @@ public class DrProvConnection extends BaseLoggingClass {
             if (rc >= 200 && rc < 300 ) {
                        responseBody = bodyToString( uc.getInputStream() );
                        logger.info( "responseBody=" + responseBody );
-
+                       err.setCode( rc );
             } else if ( rc == 404 ) {
                err.setCode( rc );
                err.setFields( "feedid");
@@ -426,33 +470,48 @@ public class DrProvConnection extends BaseLoggingClass {
             }
             
                } catch (ConnectException ce) {
-                       errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() );
-            err.setCode( 500 );
-               err.setMessage("Backend connection refused");
+                       if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doPutFeed because unit_test =" + unit_test );
+                       } else {
+                               errorLogger.error(DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage());
+                               err.setCode(500);
+                               err.setMessage("Backend connection refused");
+                       }
                } catch (SocketException se) {
                        errorLogger.error( DmaapbcLogMessageEnum.SOCKET_EXCEPTION, se.getMessage(), "response from Prov server" );
                        err.setCode( 500 );
                        err.setMessage( "Unable to read response from DR");
         } catch (Exception e) {
-            logger.warn("Unable to read response  " );
-            e.printStackTrace();
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doPutFeed because unit_test =" + unit_test );
+               } else {
+                   logger.warn("Unable to read response  " );
+                   logger.error(e.getMessage(), e);
+               }
             try {
                    err.setCode( uc.getResponseCode());
                    err.setMessage(uc.getResponseMessage());
             } catch (Exception e2) {
                err.setCode( 500 );
                err.setMessage("Unable to determine response message");
+               logger.error(e2.getMessage(), e2);
             }
         }              finally {
                        try {
                                uc.disconnect();
-                       } catch ( Exception e ) {}
+                       } catch ( Exception e ) {
+                               logger.error(e.getMessage(), e);
+                       }
                }
                return responseBody;
        }
        public String doPutDr_Sub(DR_Sub postSub, ApiError err) {
                logger.info( "entry: doPutDr_Sub() "  );
-               byte[] postData = postSub.getBytes();
+               byte[] postData = postSub.getBytes(provApi);
                logger.info( "post fields=" + postData );
                String responsemessage = null;
                String responseBody = null;
@@ -461,9 +520,9 @@ public class DrProvConnection extends BaseLoggingClass {
        
                        uc.setRequestMethod("PUT");
                
-                       uc.setRequestProperty("Content-Type", "application/vnd.att-dr.subscription");
+                       uc.setRequestProperty("Content-Type", subContentType );
                        uc.setRequestProperty( "charset", "utf-8");
-                       uc.setRequestProperty( "X-ATT-DR-ON-BEHALF-OF", "DGL" );
+                       uc.setRequestProperty( behalfHeader, "DGL" );
                        uc.setRequestProperty( "Content-Length", Integer.toString( postData.length ));
                        uc.setUseCaches(false);
                        uc.setDoOutput(true);
@@ -482,8 +541,12 @@ public class DrProvConnection extends BaseLoggingClass {
                      // without this, Java will connect multiple times to the server to run the same request
                      uc.setDoOutput(false);
                  } catch (Exception e) {
+                        logger.error(e.getMessage(), e);
                  }
-            }
+                       } catch (Exception e) {
+                               logger.info( "Exception: " + e.getMessage() );
+                               e.printStackTrace();
+                       }
                        rc = uc.getResponseCode();
                        logger.info( "http response code:" + rc );
             responsemessage = uc.getResponseMessage();
@@ -515,11 +578,20 @@ public class DrProvConnection extends BaseLoggingClass {
             errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() );
             err.setCode( 500 );
                err.setMessage("Backend connection refused");
+               logger.error(ce.getMessage(), ce);
                } catch (Exception e) {
-            System.err.println("Unable to read response  " );
-            e.printStackTrace();
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doPutDr_Sub because unit_test =" + unit_test );
+               } else {
+                   logger.error("Unable to read response  " );
+                   logger.error(e.getMessage(), e);
+               }
         } finally {
-               uc.disconnect();
+               if(null != uc){
+                   uc.disconnect();
+               }
         }
                return responseBody;
 
@@ -531,49 +603,39 @@ public class DrProvConnection extends BaseLoggingClass {
                //logger.info( "get fields=" + postData );
                String responsemessage = null;
                String responseBody = null;
-               logger.info( "templog:doGetNodes at 12.10.14.10"  );
 
                try {
-               logger.info( "templog:doGetNodes at 12.10.14.11"  );
        
                        uc.setRequestMethod("GET");
-               
-                       //uc.setRequestProperty("Content-Type", "application/vnd.att-dr.subscription");
-                       //uc.setRequestProperty( "charset", "utf-8");
-                       //uc.setRequestProperty( "X-ATT-DR-ON-BEHALF-OF", "DGL" );
-                       //uc.setRequestProperty( "Content-Length", Integer.toString( postData.length ));
-                       //uc.setUseCaches(false);
-                       //uc.setDoOutput(true);
-                       OutputStream os = null;
                        int rc = -1;
                        
-               logger.info( "templog:doGetNodes at 12.10.14.12"  );
+
                        try {
-                 uc.connect();
-               logger.info( "templog:doGetNodes at 12.10.14.13"  );
-                 //os = uc.getOutputStream();
-                 //os.write( postData );
+                uc.connect();
+       
 
             } catch (ProtocolException pe) {
-               logger.info( "templog:doGetNodes at 12.10.14.14"  );
+
                  // Rcvd error instead of 100-Continue
                  try {
                      // work around glitch in Java 1.7.0.21 and likely others
                      // without this, Java will connect multiple times to the server to run the same request
                      uc.setDoOutput(false);
                  } catch (Exception e) {
+                        logger.error(e.getMessage(), e);
                  }
-            } 
-               logger.info( "templog:doGetNodes at 12.10.14.15"  );
+                       } catch (Exception e) {
+                               logger.info( "Exception: " + e.getMessage() );
+                               e.printStackTrace();
+                       }
+       
                        rc = uc.getResponseCode();
                        logger.info( "http response code:" + rc );
             responsemessage = uc.getResponseMessage();
             logger.info( "responsemessage=" + responsemessage );
-               logger.info( "templog:doGetNodes at 12.10.14.16"  );
-
 
             if (responsemessage == null) {
-               logger.info( "templog:doGetNodes at 12.10.14.17"  );
+
                  // work around for glitch in Java 1.7.0.21 and likely others
                  // When Expect: 100 is set and a non-100 response is received, the response message is not set but the response code is
                  String h0 = uc.getHeaderField(0);
@@ -585,7 +647,7 @@ public class DrProvConnection extends BaseLoggingClass {
                      }
                  }
             }
-               logger.info( "templog:doGetNodes at 12.10.14.18"  );
+       
                err.setCode(rc);  // may not really be an error, but we save rc
             if (rc == 200 ) {
                        responseBody = bodyToString( uc.getInputStream() );
@@ -594,49 +656,46 @@ public class DrProvConnection extends BaseLoggingClass {
                err.setMessage(responsemessage);
             }
             
-               logger.info( "templog:doGetNodes at 12.10.14.19"  );
+
                } catch (ConnectException ce) {
-               logger.info( "templog:doGetNodes at 12.10.14.20"  );
-            errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() );
-            err.setCode( 500 );
-               err.setMessage("Backend connection refused");
+                       if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doGetNodes because unit_test =" + unit_test );
+                       } else {
+                               errorLogger.error(DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage());
+                               err.setCode(500);
+                               err.setMessage("Backend connection refused");
+                               logger.error(ce.getMessage(), ce);
+                       }
                } catch (Exception e) {
-               logger.info( "templog:doGetNodes at 12.10.14.21"  );
-            System.err.println("Unable to read response  " );
-            e.printStackTrace();
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doGetNodes because unit_test =" + unit_test );
+               } else {
+                   logger.error("Unable to read response  ", e.getMessage());
+               }
         } finally {
-               logger.info( "templog:doGetNodes at 12.10.14.22"  );
+
                        if ( uc != null ) uc.disconnect();
         }
-               logger.info( "templog:doGetNodes at 12.10.14.23"  );
+
                return responseBody;
 
        }
        public String doPutNodes( ApiError err ) {
                logger.info( "entry: doPutNodes() "  );
-               //byte[] postData = nodeList.getBytes();
-               //logger.info( "get fields=" + postData );
                String responsemessage = null;
                String responseBody = null;
 
                try {
-       
                        uc.setRequestMethod("PUT");
-               
-                       //uc.setRequestProperty("Content-Type", "application/vnd.att-dr.subscription");
-                       //uc.setRequestProperty( "charset", "utf-8");
-                       //uc.setRequestProperty( "X-ATT-DR-ON-BEHALF-OF", "DGL" );
-                       //uc.setRequestProperty( "Content-Length", Integer.toString( postData.length ));
                        uc.setUseCaches(false);
-                       //uc.setDoOutput(true);
-                       OutputStream os = null;
                        int rc = -1;
                        
                        try {
                  uc.connect();
-                 //os = uc.getOutputStream();
-                 //os.write( postData );
-
             } catch (ProtocolException pe) {
                  // Rcvd error instead of 100-Continue
                  try {
@@ -645,7 +704,10 @@ public class DrProvConnection extends BaseLoggingClass {
                      uc.setDoOutput(false);
                  } catch (Exception e) {
                  }
-            }
+                       } catch (Exception e) {
+                               logger.info( "Exception: " + e.getMessage() );
+                               e.printStackTrace();
+                       }
                        rc = uc.getResponseCode();
                        logger.info( "http response code:" + rc );
             responsemessage = uc.getResponseMessage();
@@ -675,8 +737,13 @@ public class DrProvConnection extends BaseLoggingClass {
             }
             
                } catch (Exception e) {
-            System.err.println("Unable to read response  " + e.getMessage() );
-            e.printStackTrace();
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doPutNodes because unit_test =" + unit_test );
+               } else {
+                   logger.error("Unable to read response  ", e.getMessage());
+               }
         } finally {
                        if ( uc != null ) {
                        uc.disconnect();
@@ -687,18 +754,15 @@ public class DrProvConnection extends BaseLoggingClass {
        }
        
        public String doDeleteFeed(Feed putFeed, ApiError err) {
-               //byte[] postData = putFeed.getBytes();
-               //logger.info( "post fields=" + postData.toString() );
                String responsemessage = null;
                String responseBody = null;
 
                try {
                        logger.info( "uc=" + uc );
                        uc.setRequestMethod("DELETE");
-                       uc.setRequestProperty("Content-Type", "application/vnd.att-dr.feed");
+                       uc.setRequestProperty("Content-Type", feedContentType );
                        uc.setRequestProperty( "charset", "utf-8");
-                       uc.setRequestProperty( "X-ATT-DR-ON-BEHALF-OF", putFeed.getOwner() );
-                       //uc.setRequestProperty( "Content-Length", Integer.toString( postData.length ));
+                       uc.setRequestProperty( behalfHeader, putFeed.getOwner() );
                        uc.setUseCaches(false);
                        uc.setDoOutput(true);
                        OutputStream os = null;
@@ -716,8 +780,12 @@ public class DrProvConnection extends BaseLoggingClass {
                      // without this, Java will connect multiple times to the server to run the same request
                      uc.setDoOutput(false);
                  } catch (Exception e) {
+                        logger.error(e.getMessage(), e);
                  }
-            }
+                       } catch (Exception e) {
+                               logger.info( "Exception: " + e.getMessage() );
+                               e.printStackTrace();
+                       }
                        rc = uc.getResponseCode();
                        logger.info( "http response code:" + rc );
             responsemessage = uc.getResponseMessage();
@@ -756,32 +824,45 @@ public class DrProvConnection extends BaseLoggingClass {
                        errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() );
             err.setCode( 500 );
                err.setMessage("Backend connection refused");
+               logger.error(ce.getMessage(), ce);
                } catch (SocketException se) {
                        errorLogger.error( DmaapbcLogMessageEnum.SOCKET_EXCEPTION, se.getMessage(), "response from Prov server" );
                        err.setCode( 500 );
                        err.setMessage( "Unable to read response from DR");
+                       logger.error(se.getMessage(), se);
         } catch (Exception e) {
-            logger.warn("Unable to read response  " );
-            e.printStackTrace();
-            try {
-                   err.setCode( uc.getResponseCode());
-                   err.setMessage(uc.getResponseMessage());
-            } catch (Exception e2) {
-               err.setCode( 500 );
-               err.setMessage("Unable to determine response message");
-            }
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doDeleteFeed because unit_test =" + unit_test );
+               } else {
+                   logger.warn("Unable to read response  " );
+                   logger.error(e.getMessage(), e);
+                   try {
+                           err.setCode( uc.getResponseCode());
+                           err.setMessage(uc.getResponseMessage());
+                   } catch (Exception e2) {
+                       err.setCode( 500 );
+                       err.setMessage("Unable to determine response message");
+                       logger.error(e2.getMessage(), e2);
+                   }
+               }
         }              finally {
                        try {
-                               uc.disconnect();
-                       } catch ( Exception e ) {}
+                               if(uc != null) {
+                                   uc.disconnect();
+                               }
+                       } catch ( Exception e ) {
+                               logger.error(e.getMessage(), e);
+                       }
                }
                return responseBody;
        }
        
        public String doDeleteDr_Sub(DR_Sub delSub, ApiError err) {
                logger.info( "entry: doDeleteDr_Sub() "  );
-               byte[] postData = delSub.getBytes();
-               logger.info( "post fields=" + postData );
+               byte[] postData = delSub.getBytes(provApi);
+               logger.info( "post fields=" + Arrays.toString(postData));
                String responsemessage = null;
                String responseBody = null;
 
@@ -789,10 +870,9 @@ public class DrProvConnection extends BaseLoggingClass {
        
                        uc.setRequestMethod("DELETE");
                
-                       uc.setRequestProperty("Content-Type", "application/vnd.att-dr.subscription");
+                       uc.setRequestProperty("Content-Type", subContentType);
                        uc.setRequestProperty( "charset", "utf-8");
-                       uc.setRequestProperty( "X-ATT-DR-ON-BEHALF-OF", "DGL" );
-                       //uc.setRequestProperty( "Content-Length", Integer.toString( postData.length ));
+                       uc.setRequestProperty( behalfHeader, "DGL" );
                        uc.setUseCaches(false);
                        uc.setDoOutput(true);
                        OutputStream os = null;
@@ -810,8 +890,12 @@ public class DrProvConnection extends BaseLoggingClass {
                      // without this, Java will connect multiple times to the server to run the same request
                      uc.setDoOutput(false);
                  } catch (Exception e) {
+                        logger.error(e.getMessage(), e);
                  }
-            }
+                       } catch (Exception e) {
+                               logger.info( "Exception: " + e.getMessage() );
+                               e.printStackTrace();
+                       }
                        rc = uc.getResponseCode();
                        logger.info( "http response code:" + rc );
             responsemessage = uc.getResponseMessage();
@@ -830,58 +914,188 @@ public class DrProvConnection extends BaseLoggingClass {
                      }
                  }
             }
+               err.setCode(rc);
             if (rc == 204 ) {
                        responseBody = bodyToString( uc.getInputStream() );
                        logger.info( "responseBody=" + responseBody );
-
             } else {
-               err.setCode(rc);
                err.setMessage(responsemessage);
             }
             
                } catch (ConnectException ce) {
-            errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() );
-            err.setCode( 500 );
-               err.setMessage("Backend connection refused");
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doDeleteDr_Sub because unit_test =" + unit_test );
+               } else {
+                   errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() );
+                   err.setCode( 500 );
+                       err.setMessage("Backend connection refused");
+               }
                } catch (Exception e) {
-            System.err.println("Unable to read response  " );
-            e.printStackTrace();
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doDeleteDr_Sub because unit_test =" + unit_test );
+               } else {
+                   logger.error("Unable to read response  ", e.getMessage());
+               }
         } finally {
-               uc.disconnect();
+               if(uc != null){
+                   uc.disconnect();
+               }
         }
                return responseBody;
 
        }
-       /*
-        public static void main( String[] args ) throws Exception {
-               PropertyConfigurator.configure("log4j.properties");
-               logger.info("Started.");
-               
-               RandomInteger ri = new RandomInteger(10000);
-                       //String postJSON = String.format("{\"name\": \"dgl feed %d\", \"version\": \"v1.0\", \"description\": \"dgl feed N for testing\", \"authorization\": { \"classification\": \"unclassified\", \"endpoint_addrs\": [],\"endpoint_ids\": [{\"password\": \"test\",\"id\": \"test\"}]}}", ri.next()) ;
-                       int i = ri.next();
-                       Feed tst = new Feed( "dgl feed " + i,
-                                                               "v1.0",
-                                                               "dgl feed " + i + "for testing",
-                                                               "TEST",
-                                                               "unclassified"
-                                       );
-                       ArrayList<DR_Pub> pubs = new ArrayList<DR_Pub>();
-                       pubs.add( new DR_Pub( "centralLocation" ) ); 
-                       tst.setPubs(pubs);
-
-               boolean rc;
-               DrProvConnection context = new DrProvConnection();
-               rc = context.makeFeedConnection();
-               logger.info( "makeFeedConnection returns " + rc);
-               ApiError err = new ApiError();
-               if ( rc ) {
-                       String tmp  = context.doPostFeed( tst, err );
-                       logger.info( "doPostFeed returns " + tmp);
-               }
-    
-        }
- */
        
+       // add double-quotes around a value
+       // hope his is easier to read than in-line escaping...
+       private String dq( String v ) {
+               return ( "\"" + v + "\"");
+       }
+       private String dq( String k, String v) {
+               return( dq(k) + ":" + dq(v));
+       }
+       private String dqc( String k, String v) {
+               return( dq(k) + ":" + dq(v) + ",");
+       }
+       
+       private String dumpSimulation() {
+               logger.info( "enter dumpSimulation()");
+               String                                  responseBody = 
+                               "{"
+                               + dq("feeds") + ":["
+                               + "{" + dq( "suspend") + ":false,"
+                                         + dq( "groupid") + ":0,"
+                                         + dqc( "description", "Some description" )
+                                         + dqc( "version", "m1.1") 
+                                         + dq( "authorization") + ":"
+                                         + "{" + dq( "endpoint_addrs" ) + ":[],"
+                                                       + dq( "classification", "unclassified")
+                                                       + dq( "endpoint_ids") + ":[{"
+                                                               + dqc( "password", "dradmin" )
+                                                               + dq( "id", "dradmin")
+                                                               + "}]}"
+                                               + dq( "last_mod") + ":1553738110000,"
+                                               + dq( "deleted") + ":false,"
+                                               + dq( "feedid") + ":1,"
+                                               + dqc( "name", "Default PM Feed")
+                                               + dq( "business_description") + ":\"\","
+                                               + dqc( "publisher", "onap")
+                                               + dq( "links") + ":{"
+                                                       + dqc( "subscribe", "https://dmaap-dr-prov/subscribe/1")
+                                                       + dqc( "log", "https://dmaap-dr-prov/feedlog/1")
+                                                       + dqc( "publish", "https://dmaap-dr-prov/publish/1")
+                                                       + dq( "self", "https:/dmaap-dr-prov/feed/1")
+                                                       + "}"
+                                               + dq( "created_date") + ":1553738110000 }"
+                               + "],"
+                               + dq( "groups") + ":["
+                               + "],"
+                               + dq( "subscriptions") + ":["
+                               + "],"
+                               + dq( "ingress") + ":["
+                               + "],"
+                               + dq( "egress") + ":{"
+                               + "},"
+                               + dq( "routing") + ":["
+                               + "],"
+                         + "}";
+               return responseBody;
+       }
+       
+       public String doGetDump( ApiError err ) {
+               logger.info( "entry: doGetDump() "  );
+
+               String responsemessage = null;
+               String responseBody = null;
+
+               try {
+       
+                       uc.setRequestMethod("GET");
+                       int rc = -1;
+                       
+
+                       try {
+                uc.connect();
+       
+
+            } catch (ProtocolException pe) {
+
+                 // Rcvd error instead of 100-Continue
+                 try {
+                     // work around glitch in Java 1.7.0.21 and likely others
+                     // without this, Java will connect multiple times to the server to run the same request
+                     uc.setDoOutput(false);
+                 } catch (Exception e) {
+                        logger.error(e.getMessage(), e);
+                 }
+                       } catch (Exception e) {
+                               logger.info( "Exception: " + e.getMessage() );
+                               e.printStackTrace();
+                       }
+       
+                       rc = uc.getResponseCode();
+                       logger.info( "http response code:" + rc );
+            responsemessage = uc.getResponseMessage();
+            logger.info( "responsemessage=" + responsemessage );
+       
+
+
+            if (responsemessage == null) {
+
+                 // work around for glitch in Java 1.7.0.21 and likely others
+                 // When Expect: 100 is set and a non-100 response is received, the response message is not set but the response code is
+                 String h0 = uc.getHeaderField(0);
+                 if (h0 != null) {
+                     int i = h0.indexOf(' ');
+                     int j = h0.indexOf(' ', i + 1);
+                     if (i != -1 && j != -1) {
+                         responsemessage = h0.substring(j + 1);
+                     }
+                 }
+            }
+       
+               err.setCode(rc);  // may not really be an error, but we save rc
+            if (rc == 200 ) {
+                       responseBody = bodyToString( uc.getInputStream() );
+                       logger.info( "responseBody=" + responseBody );
+            } else {
+               err.setMessage(responsemessage);
+            }
+            
+
+               } catch (ConnectException ce) {
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doGetNodes because unit_test =" + unit_test );
+                               responseBody = dumpSimulation();
+                                                         
+               } else {
+                   errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() );
+                   err.setCode( 500 );
+                       err.setMessage("Backend connection refused");
+                       logger.error(ce.getMessage(), ce);
+               }
+               } catch (Exception e) {
+               if ( unit_test.equals( "Yes" ) ) {
+                               err.setCode(200);
+                               err.setMessage( "simulated response");
+                               logger.info( "artificial 200 response from doGetNodes because unit_test =" + unit_test );
+                               responseBody = dumpSimulation();
+                                                         
+               } else {
+                   logger.error("Unable to read response  ", e.getMessage());
+               }
+        } finally {
+
+                       if ( uc != null ) uc.disconnect();
+        }
+
+               return responseBody;
+
+       }
                
 }