Refine Agent for cadi utils 99/55899/1
authorInstrumental <jonathan.gathman@att.com>
Thu, 5 Jul 2018 20:00:18 +0000 (15:00 -0500)
committerInstrumental <jonathan.gathman@att.com>
Thu, 5 Jul 2018 20:00:23 +0000 (15:00 -0500)
Issue-ID: AAF-361
Change-Id: Id07b60181b906e65aefb24cbe0d192e362c2c3f4
Signed-off-by: Instrumental <jonathan.gathman@att.com>
cadi/aaf/src/main/java/org/onap/aaf/cadi/configure/Agent.java
cadi/aaf/src/main/java/org/onap/aaf/cadi/configure/ArtifactDir.java
cadi/aaf/src/test/java/org/onap/aaf/cadi/cm/test/JU_ArtifactDir.java
cadi/client/src/main/java/org/onap/aaf/cadi/client/Rcli.java
cadi/core/src/main/java/org/onap/aaf/cadi/CmdLine.java
cadi/core/src/test/java/org/onap/aaf/cadi/test/JU_CmdLine.java
cadi/oauth-enduser/src/main/java/org/onap/aaf/cadi/enduser/RESTException.java [new file with mode: 0644]
cadi/oauth-enduser/src/main/java/org/onap/aaf/cadi/enduser/SimpleRESTClient.java
cadi/oauth-enduser/src/test/java/org/onap/aaf/cadi/enduser/test/SimpleRestClientExample.java

index 18f6e7b..09f5ed7 100644 (file)
@@ -24,12 +24,14 @@ package org.onap.aaf.cadi.configure;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.PrintStream;
 import java.net.ConnectException;
 import java.net.HttpURLConnection;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.nio.file.Files;
+import java.security.KeyPair;
 import java.security.KeyStore;
 import java.security.cert.X509Certificate;
 import java.util.ArrayDeque;
@@ -58,6 +60,7 @@ import org.onap.aaf.cadi.config.SecurityInfoC;
 import org.onap.aaf.cadi.http.HBasicAuthSS;
 import org.onap.aaf.cadi.locator.SingleEndpointLocator;
 import org.onap.aaf.cadi.sso.AAFSSO;
+import org.onap.aaf.cadi.util.Chmod;
 import org.onap.aaf.cadi.util.FQI;
 import org.onap.aaf.misc.env.APIException;
 import org.onap.aaf.misc.env.Data.TYPE;
@@ -100,169 +103,197 @@ public class Agent {
        private static RosettaEnv env;
        
        private static boolean doExit;
+       private static AAFCon<?> aafcon;
 
        public static void main(String[] args) {
                int exitCode = 0;
                doExit = true;
-               try {
-                       AAFSSO aafsso=null;
-                       PropAccess access;
-                       
-                       if(args.length>0 && args[0].equals("validate")) {
-                               int idx = args[1].indexOf('=');
-                               aafsso = null;
-                               access = new PropAccess(
-                                                       (idx<0?Config.CADI_PROP_FILES:args[1].substring(0, idx))+
-                                                       '='+
-                                                   (idx<0?args[1]:args[1].substring(idx+1)));
-                       } else {
-                               aafsso= new AAFSSO(args, new AAFSSO.ProcessArgs() {
-                                       @Override
-                                       public Properties process(String[] args, Properties props) {
-                                               if(args.length>1) {
-                                                       if (!args[0].equals("genkeypair")) {
-                                                               props.put("aaf_id", args[1]);
-                                                       }       
-                                               }
-                                               return props;
-                                       }
-                               });
-                               access = aafsso.access();
+               if(args.length>0 && "cadi".equals(args[0])) {
+                       String[] newArgs = new String[args.length-1];
+                       System.arraycopy(args, 1, newArgs, 0, newArgs.length);
+                       if(newArgs.length==0) {
+                               System.out.println(HASHES);
+                               System.out.println("Note: Cadi CmdLine is a separate component.  When running with\n\t"
+                                               + "Agent, always preface with \"cadi\",\n\tex: cadi keygen [<keyfile>]");
+                               System.out.println(HASHES);
                        }
+                       CmdLine.main(newArgs);
+               } else {
+                       try {
+                               AAFSSO aafsso=null;
+                               PropAccess access;
                                
-                       if(aafsso!=null && aafsso.loginOnly()) {
-                               aafsso.setLogDefault();
-                               aafsso.writeFiles();
-                               System.out.println("AAF SSO information created in ~/.aaf");
-                       } else {
-                               env = new RosettaEnv(access.getProperties());
-                               Deque<String> cmds = new ArrayDeque<String>();
-                               for(String p : args) {
-                                       if("-noexit".equalsIgnoreCase(p)) {
-                                               doExit = false;
-                                       } else if(p.indexOf('=') < 0) {
-                                               cmds.add(p);
-                                       }
+                               if(args.length>0 && args[0].equals("validate")) {
+                                       int idx = args[1].indexOf('=');
+                                       aafsso = null;
+                                       access = new PropAccess(
+                                                               (idx<0?Config.CADI_PROP_FILES:args[1].substring(0, idx))+
+                                                               '='+
+                                                           (idx<0?args[1]:args[1].substring(idx+1)));
+                               } else {
+                                       aafsso= new AAFSSO(args, new AAFSSO.ProcessArgs() {
+                                               @Override
+                                               public Properties process(String[] args, Properties props) {
+                                                       if(args.length>1) {
+                                                               if (!args[0].equals("keypairgen")) {
+                                                                       props.put("aaf_id", args[1]);
+                                                               }       
+                                                       }
+                                                       return props;
+                                               }
+                                       });
+                                       access = aafsso.access();
                                }
-                               
-                               if(cmds.size()==0) {
-                                       if(aafsso!=null) {
-                                               aafsso.setLogDefault();
+                                       
+                               if(aafsso!=null && aafsso.loginOnly()) {
+                                       aafsso.setLogDefault();
+                                       aafsso.writeFiles();
+                                       System.out.println("AAF SSO information created in ~/.aaf");
+                               } else {
+                                       env = new RosettaEnv(access.getProperties());
+                                       Deque<String> cmds = new ArrayDeque<String>();
+                                       for(String p : args) {
+                                               if("-noexit".equalsIgnoreCase(p)) {
+                                                       doExit = false;
+                                               } else if(p.indexOf('=') < 0) {
+                                                       cmds.add(p);
+                                               }
                                        }
-                                       // NOTE: CHANGE IN CMDS should be reflected in AAFSSO constructor, to get FQI->aaf-id or not
-                                       System.out.println("Usage: java -jar <cadi-aaf-*-full.jar> cmd [<tag=value>]*");
-                                       System.out.println("   create   <FQI> [<machine>]");
-                                       System.out.println("   read     <FQI> [<machine>]");
-                                       System.out.println("   update   <FQI> [<machine>]");
-                                       System.out.println("   delete   <FQI> [<machine>]");
-                                       System.out.println("   copy     <FQI> <machine> <newmachine>[,<newmachine>]*");
-                                       System.out.println("   place    <FQI> [<machine>]");
-                                       System.out.println("   showpass <FQI> [<machine>]");
-                                       System.out.println("   check    <FQI> [<machine>]");
-                                       System.out.println("   config   <FQI>");
-                                       System.out.println("   validate <FQI>.props>");
-                                       System.out.println("   genkeypair");
-                                       if (doExit) {
-                                               System.exit(1);
+                                       
+                                       if(cmds.size()==0) {
+                                               if(aafsso!=null) {
+                                                       aafsso.setLogDefault();
+                                               }
+                                               // NOTE: CHANGE IN CMDS should be reflected in AAFSSO constructor, to get FQI->aaf-id or not
+                                               System.out.println("Usage: java -jar <cadi-aaf-*-full.jar> cmd [<tag=value>]*");
+                                               System.out.println("   create     <FQI> [<machine>]");
+                                               System.out.println("   read       <FQI> [<machine>]");
+                                               System.out.println("   update     <FQI> [<machine>]");
+                                               System.out.println("   delete     <FQI> [<machine>]");
+                                               System.out.println("   copy       <FQI> <machine> <newmachine>[,<newmachine>]*");
+                                               System.out.println("   place      <FQI> [<machine>]");
+                                               System.out.println("   showpass   <FQI> [<machine>]");
+                                               System.out.println("   check      <FQI> [<machine>]");
+                                               System.out.println("   keypairgen <FQI>");
+                                               System.out.println("   config     <FQI>");
+                                               System.out.println("   validate   <FQI>.props>");
+                                               System.out.println("   --- Additional Tool Access ---");
+                                               System.out.println("     ** Type with no params for Tool Help");
+                                               System.out.println("     ** If using with Agent, preface with \"cadi\"");
+                                               System.out.println("   cadi <cadi tool params, see -?>");
+                                               
+                                               if (doExit) {
+                                                       System.exit(1);
+                                               }
                                        }
-                               }
+                                       
+                                       TIMEOUT = Integer.parseInt(env.getProperty(Config.AAF_CONN_TIMEOUT, "5000"));
                                
-                               TIMEOUT = Integer.parseInt(env.getProperty(Config.AAF_CONN_TIMEOUT, "5000"));
-                       
-                               reqDF = env.newDataFactory(CertificateRequest.class);
-                               artifactsDF = env.newDataFactory(Artifacts.class);
-                               certDF = env.newDataFactory(CertInfo.class);
-                               configDF = env.newDataFactory(Configuration.class);
-                               permDF = env.newDataFactory(Perms.class);
-                               errMsg = new ErrMessage(env);
+                                       reqDF = env.newDataFactory(CertificateRequest.class);
+                                       artifactsDF = env.newDataFactory(Artifacts.class);
+                                       certDF = env.newDataFactory(CertInfo.class);
+                                       configDF = env.newDataFactory(Configuration.class);
+                                       permDF = env.newDataFactory(Perms.class);
+                                       errMsg = new ErrMessage(env);
+               
+                                       placeArtifact = new HashMap<>();
+                                       placeArtifact.put(JKS, new PlaceArtifactInKeystore(JKS));
+                                       placeArtifact.put(PKCS12, new PlaceArtifactInKeystore(PKCS12));
+                                       placeArtifact.put(FILE, new PlaceArtifactInFiles());
+                                       placeArtifact.put(PRINT, new PlaceArtifactOnStream(System.out));
+                                       placeArtifact.put(SCRIPT, new PlaceArtifactScripts());
+                                       
+                                       Trans trans = env.newTrans();
+                                       String token;
+                                       if((token=access.getProperty("oauth_token"))!=null) {
+                                               trans.setProperty("oauth_token", token);
+                                       }
+                                       try {
+                                               if(aafsso!=null) {
+                                               // show Std out again
+                                                       aafsso.setLogDefault();
+                                                       aafsso.setStdErrDefault();
+                                                       
+                                                       // if CM_URL can be obtained, add to sso.props, if written
+                                                       String cm_url = getProperty(access,env,false, Config.CM_URL,Config.CM_URL+": ");
+                                                       if(cm_url!=null) {
+                                                               aafsso.addProp(Config.CM_URL, cm_url);
+                                                       }
+                                                       aafsso.writeFiles();
+                                               }
        
-                               placeArtifact = new HashMap<>();
-                               placeArtifact.put(JKS, new PlaceArtifactInKeystore(JKS));
-                               placeArtifact.put(PKCS12, new PlaceArtifactInKeystore(PKCS12));
-                               placeArtifact.put(FILE, new PlaceArtifactInFiles());
-                               placeArtifact.put(PRINT, new PlaceArtifactOnStream(System.out));
-                               placeArtifact.put(SCRIPT, new PlaceArtifactScripts());
-                               
-                               Trans trans = env.newTrans();
-                               String token;
-                               if((token=access.getProperty("oauth_token"))!=null) {
-                                       trans.setProperty("oauth_token", token);
-                               }
-                               try {
-                                       if(aafsso!=null) {
-                                       // show Std out again
-                                               aafsso.setLogDefault();
-                                               aafsso.setStdErrDefault();
                                                
-                                               // if CM_URL can be obtained, add to sso.props, if written
-                                               String cm_url = getProperty(access,env,false, Config.CM_URL,Config.CM_URL+": ");
-                                               if(cm_url!=null) {
-                                                       aafsso.addProp(Config.CM_URL, cm_url);
+       
+                                               String cmd = cmds.removeFirst();
+                                               switch(cmd) {
+                                                       case "place":
+                                                               placeCerts(trans,aafcon(access),cmds);
+                                                               break;
+                                                       case "create":
+                                                               createArtifact(trans, aafcon(access),cmds);
+                                                               break;
+                                                       case "read":
+                                                               readArtifact(trans, aafcon(access), cmds);
+                                                               break;
+                                                       case "copy":
+                                                               copyArtifact(trans, aafcon(access), cmds);
+                                                               break;
+                                                       case "update":
+                                                               updateArtifact(trans, aafcon(access), cmds);
+                                                               break;
+                                                       case "delete":
+                                                               deleteArtifact(trans, aafcon(access), cmds);
+                                                               break;
+                                                       case "showpass":
+                                                               showPass(trans, aafcon(access), cmds);
+                                                               break;
+                                                       case "keypairgen":
+                                                               keypairGen(trans, access, cmds);
+                                                               break;
+                                                       case "config":
+                                                               config(trans,access,aafcon(access),cmds);
+                                                               break;
+                                                       case "validate":
+                                                               validate(access);
+                                                               break;
+                                                       case "check":
+                                                               try {
+                                                                       exitCode = check(trans,aafcon(access),cmds);
+                                                               } catch (Exception e) {
+                                                                       exitCode = 1;
+                                                                       throw e;
+                                                               }
+                                                               break;
+                                                       default:
+                                                               AAFSSO.cons.printf("Unknown command \"%s\"\n", cmd);
                                                }
-                                               aafsso.writeFiles();
+                                       } finally {
+                                               StringBuilder sb = new StringBuilder();
+                               trans.auditTrail(4, sb, Trans.REMOTE);
+                               if(sb.length()>0) {
+                                       trans.info().log("Trans Info\n",sb);
+                               }
                                        }
-
-                                       AAFCon<?> aafcon = new AAFConHttp(access,Config.CM_URL);
-
-                                       String cmd = cmds.removeFirst();
-                                       switch(cmd) {
-                                               case "place":
-                                                       placeCerts(trans,aafcon,cmds);
-                                                       break;
-                                               case "create":
-                                                       createArtifact(trans, aafcon,cmds);
-                                                       break;
-                                               case "read":
-                                                       readArtifact(trans, aafcon, cmds);
-                                                       break;
-                                               case "copy":
-                                                       copyArtifact(trans, aafcon, cmds);
-                                                       break;
-                                               case "update":
-                                                       updateArtifact(trans, aafcon, cmds);
-                                                       break;
-                                               case "delete":
-                                                       deleteArtifact(trans, aafcon, cmds);
-                                                       break;
-                                               case "showpass":
-                                                       showPass(trans, aafcon, cmds);
-                                                       break;
-                                               case "config":
-                                                       initConfig(trans,access,aafcon,cmds);
-                                                       break;
-                                               case "validate":
-                                                       validate(access);
-                                                       break;
-                                               case "check":
-                                                       try {
-                                                               exitCode = check(trans,aafcon,cmds);
-                                                       } catch (Exception e) {
-                                                               exitCode = 1;
-                                                               throw e;
-                                                       }
-                                                       break;
-                                               default:
-                                                       AAFSSO.cons.printf("Unknown command \"%s\"\n", cmd);
+                                       if(aafsso!=null) {
+                                               aafsso.close();
                                        }
-                               } finally {
-                                       StringBuilder sb = new StringBuilder();
-                       trans.auditTrail(4, sb, Trans.REMOTE);
-                       if(sb.length()>0) {
-                               trans.info().log("Trans Info\n",sb);
-                       }
-                               }
-                               if(aafsso!=null) {
-                                       aafsso.close();
                                }
+                       } catch (Exception e) {
+                               e.printStackTrace();
                        }
-               } catch (Exception e) {
-                       e.printStackTrace();
                }
                if(exitCode != 0 && doExit) {
                        System.exit(exitCode);
                }
        }
 
+       private static synchronized AAFCon<?> aafcon(PropAccess access) throws APIException, CadiException, LocatorException {
+               if(aafcon==null) {
+                       aafcon = new AAFConHttp(access,Config.CM_URL);
+               }
+               return aafcon;
+       }
+
        private static String getProperty(PropAccess pa, Env env, boolean secure, String tag, String prompt, Object ... def) {
                String value;
                if((value=pa.getProperty(tag))==null) {
@@ -665,8 +696,30 @@ public class Agent {
 
        }
        
+       private static void keypairGen(final Trans trans, final PropAccess access, final Deque<String> cmds) throws IOException {
+               final String fqi = fqi(cmds);
+               final String ns = FQI.reverseDomain(fqi);
+               File dir = new File(access.getProperty(Config.CADI_ETCDIR,".")); // default to current Directory
+               File f = new File(dir,ns+".key");
+               
+               if(f.exists()) {
+                       String line = AAFSSO.cons.readLine("%s exists. Overwrite? (y/n): ", f.getCanonicalPath());
+                       if(!"Y".equalsIgnoreCase(line)) {
+                               System.out.println("Canceling...");
+                               return;
+                       }
+               }
+               
+               KeyPair kp = Factory.generateKeyPair(trans);
+               ArtifactDir.write(f, Chmod.to400, Factory.toString(trans, kp.getPrivate()));
+               System.out.printf("Wrote %s\n", f.getCanonicalFile());
 
-       private static void initConfig(Trans trans, PropAccess pa, AAFCon<?> aafcon, Deque<String> cmds) throws Exception {
+               f=new File(dir,ns+".pubkey");
+               ArtifactDir.write(f, Chmod.to644, Factory.toString(trans, kp.getPublic()));
+               System.out.printf("Wrote %s\n", f.getCanonicalFile());
+       }
+       
+       private static void config(Trans trans, PropAccess pa, AAFCon<?> aafcon, Deque<String> cmds) throws Exception {
                final String fqi = fqi(cmds);
                final String locator = getProperty(pa,aafcon.env,false,Config.AAF_LOCATE_URL,"AAF Locator URL: ");
                final String rootFile = FQI.reverseDomain(fqi);
index 266ace8..d553ceb 100644 (file)
@@ -29,7 +29,6 @@ import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.security.KeyStore;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -143,7 +142,7 @@ public abstract class ArtifactDir implements PlaceArtifact {
                encodeds.add(sb.toString());
        }
 
-       protected void write(File f, Chmod c, String ... data) throws IOException {
+       public static void write(File f, Chmod c, String ... data) throws IOException {
                f.setWritable(true,true);
                
                FileOutputStream fos = new FileOutputStream(f);
@@ -158,7 +157,7 @@ public abstract class ArtifactDir implements PlaceArtifact {
                }
        }
 
-       protected void write(File f, Chmod c, byte[] bytes) throws IOException {
+       public static void write(File f, Chmod c, byte[] bytes) throws IOException {
                f.setWritable(true,true);
                
                FileOutputStream fos = new FileOutputStream(f);
@@ -170,7 +169,7 @@ public abstract class ArtifactDir implements PlaceArtifact {
                }
        }
        
-       protected void write(File f, Chmod c, KeyStore ks, char[] pass ) throws IOException, CadiException {
+       public static void write(File f, Chmod c, KeyStore ks, char[] pass ) throws IOException, CadiException {
                f.setWritable(true,true);
                
                FileOutputStream fos = new FileOutputStream(f);
index ed23179..ecadb6e 100644 (file)
@@ -105,22 +105,22 @@ public class JU_ArtifactDir {
                artiDir.place(transMock, certInfoMock, artiMock, "machine");
                
                File writableFile = new File(dirName + '/' + nsName + "writable.txt");
-               artiDir.write(writableFile, Chmod.to755, "first data point", "second data point");
+               ArtifactDir.write(writableFile, Chmod.to755, "first data point", "second data point");
                try {
-                       artiDir.write(writableFile, Chmod.to755, (String[])null);
+                       ArtifactDir.write(writableFile, Chmod.to755, (String[])null);
                        fail("Should've thrown an exception");
                } catch(NullPointerException e) {
                }
                
                KeyStore ks = KeyStore.getInstance("pkcs12");
                try {
-                       artiDir.write(writableFile, Chmod.to755, ks, luggagePassword.toCharArray());
+                       ArtifactDir.write(writableFile, Chmod.to755, ks, luggagePassword.toCharArray());
                        fail("Should've thrown an exception");
                } catch(CadiException e) {
                }
                
                ks.load(null, null);
-               artiDir.write(writableFile, Chmod.to755, ks, luggagePassword.toCharArray());
+               ArtifactDir.write(writableFile, Chmod.to755, ks, luggagePassword.toCharArray());
                
                ArtifactDirStud artiDir2 = new ArtifactDirStud();
                artiDir2.place(transMock, certInfoMock, artiMock, "machine");
@@ -147,15 +147,6 @@ public class JU_ArtifactDir {
                        // This is only here so that we have a concrete class to test
                        return false;
                }
-               
-               // Expose the protected methods
-
-               public  void write(File f, Chmod c, String ... data) throws IOException {
-                       super.write(f, c, data);
-               }
-               public void write(File f, Chmod c, KeyStore ks, char[] pass ) throws IOException, CadiException {
-                       super.write(f, c, ks, pass);
-               }
        }
 
        private static void cleanup() {
index a98feb2..058bbd3 100644 (file)
@@ -455,6 +455,7 @@ public abstract class Rcli<CT> {
                client.setPayload(new EClient.Transfer() {
                        @Override
                        public void transfer(OutputStream os) throws IOException, APIException {
+                               //String s = df.newData().out(type).load(t).asString();
                                df.newData().out(type).direct(t,os);
                        }
                });
index ea126f5..9444cfa 100644 (file)
@@ -37,11 +37,7 @@ import org.onap.aaf.cadi.util.JsonOutputStream;
 
 /**
  * A Class to run on command line to determine suitability of environment for certain TAFs.
- * 
- * For instance, CSP supports services only in certain domains, and while dynamic host
- * lookups on the machine work in most cases, sometimes, names and IPs are unexpected (and
- * invalid) for CSP because of multiple NetworkInterfaces, etc
- * 
+ *  * 
  * @author Jonathan
  *
  */
@@ -336,11 +332,10 @@ public class CmdLine {
                        System.out.println("Usage: java -jar <this jar> ...");
                        System.out.println("  keygen [<keyfile>]                     (Generates Key on file, or Std Out)");
                        System.out.println("  digest [<passwd>|-i|] <keyfile>        (Encrypts Password with \"keyfile\"");
-                       System.out.println("                                          if passwd = -i, will read StdIin");
+                       System.out.println("                                          if passwd = -i, will read StdIn");
                        System.out.println("                                          if passwd is blank, will ask securely)");
                        System.out.println("  passgen <digits>                       (Generate Password of given size)");
                        System.out.println("  urlgen <digits>                        (Generate URL field of given size)");
-                       System.out.println("  csptest                                (Tests for CSP compatibility)");
                        System.out.println("  encode64 <your text>                   (Encodes to Base64)");
                        System.out.println("  decode64 <base64 encoded text>         (Decodes from Base64)");
                        System.out.println("  encode64url <your text>                (Encodes to Base64 URL charset)");
index efcc1b2..76cd225 100644 (file)
@@ -228,20 +228,20 @@ public class JU_CmdLine {
        @Test
        public void showHelpTest() {
                String expected = 
-                       "Usage: java -jar <this jar> ...\n" +
-                       "  keygen [<keyfile>]                     (Generates Key on file, or Std Out)\n" +
-                       "  digest [<passwd>|-i|] <keyfile>        (Encrypts Password with \"keyfile\"\n" +
-                       "                                          if passwd = -i, will read StdIin\n" +
-                       "                                          if passwd is blank, will ask securely)\n" +
-                       "  passgen <digits>                       (Generate Password of given size)\n" +
-                       "  urlgen <digits>                        (Generate URL field of given size)\n" +
-                       "  csptest                                (Tests for CSP compatibility)\n" +
-                       "  encode64 <your text>                   (Encodes to Base64)\n" +
-                       "  decode64 <base64 encoded text>         (Decodes from Base64)\n" +
-                       "  encode64url <your text>                (Encodes to Base64 URL charset)\n" +
-                       "  decode64url <base64url encoded text>   (Decodes from Base64 URL charset)\n" +
-                       "  sha256 <text> <salts(s)>               (Digest String into SHA256 Hash)\n" +
-                       "  md5 <text>                             (Digest String into MD5 Hash)\n";
+                       "Usage: java -jar <this jar> ...\n" + 
+                       "  keygen [<keyfile>]                     (Generates Key on file, or Std Out)\n" + 
+                       "  digest [<passwd>|-i|] <keyfile>        (Encrypts Password with \"keyfile\"\n" + 
+                       "                                          if passwd = -i, will read StdIn\n" + 
+                       "                                          if passwd is blank, will ask securely)\n" + 
+                       "  passgen <digits>                       (Generate Password of given size)\n" + 
+                       "  urlgen <digits>                        (Generate URL field of given size)\n" + 
+                       "  encode64 <your text>                   (Encodes to Base64)\n" + 
+                       "  decode64 <base64 encoded text>         (Decodes from Base64)\n" + 
+                       "  encode64url <your text>                (Encodes to Base64 URL charset)\n" + 
+                       "  decode64url <base64url encoded text>   (Decodes from Base64 URL charset)\n" + 
+                       "  sha256 <text> <salts(s)>               (Digest String into SHA256 Hash)\n" + 
+                       "  md5 <text>                             (Digest String into MD5 Hash)\n"
+                       ;
 
                CmdLine.main(new String[]{});
 
diff --git a/cadi/oauth-enduser/src/main/java/org/onap/aaf/cadi/enduser/RESTException.java b/cadi/oauth-enduser/src/main/java/org/onap/aaf/cadi/enduser/RESTException.java
new file mode 100644 (file)
index 0000000..95c9fe8
--- /dev/null
@@ -0,0 +1,66 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+package org.onap.aaf.cadi.enduser;
+
+import org.onap.aaf.cadi.client.Future;
+
+public class RESTException extends Exception {
+       /**
+        * 
+        */
+       private static final long serialVersionUID = -5232371598208651058L;
+       private Future<?> future;
+
+       public RESTException(Future<?> future) {
+               this.future = future;
+       }
+       
+       public int getCode() {
+               return future.code();
+       }
+       
+       public String getMsg() {
+               return future.body();
+       }
+
+       public String errorString() {
+               String body = future.body();
+               return "RESTClient Error: "  + future.code() + ": " + (body.isEmpty()?"<no message in call>":body);
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.Throwable#getMessage()
+        */
+       @Override
+       public String getMessage() {
+               return errorString();
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.Throwable#getLocalizedMessage()
+        */
+       @Override
+       public String getLocalizedMessage() {
+               return errorString();
+       }
+       
+
+}
index 9535ad6..386d938 100644 (file)
@@ -80,7 +80,7 @@ public class SimpleRESTClient {
        }
 
        //Format:<ID>:<APP>:<protocol>[:AS][,<ID>:<APP>:<protocol>]*
-       public SimpleRESTClient as(Principal principal) {
+       public SimpleRESTClient endUser(Principal principal) {
                if(principal==null) {
                        chain = null;
                } else {
@@ -93,23 +93,27 @@ public class SimpleRESTClient {
                }
                return this;
        }
-       
-       public String get(final String path) throws CadiException, LocatorException, APIException  {
+
+       public String read(final String path) throws RESTException, CadiException, LocatorException, APIException  {
+               return get(path,"application/json");
+       }
+
+       public String get(final String path) throws RESTException, CadiException, LocatorException, APIException  {
                return get(path,"application/json");
        }
 
-       public String get(final String path, final String accepts) throws CadiException, LocatorException, APIException  {
-               return restClient.best(new Retryable<String>() {
+       public String get(final String path, final String accepts) throws RESTException, CadiException, LocatorException, APIException  {
+               Future<String> future = restClient.best(new Retryable<Future<String>>() {
                        @Override
-                       public String code(Rcli<?> client) throws CadiException, ConnectException, APIException {
-                               Future<String> future = client.read(path,accepts, headers());
-                               if(future.get(callTimeout)) {
-                                       return future.value;
-                               } else {
-                                       throw new APIException(future.code()  + future.body());
-                               }                                       
+                       public Future<String> code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+                               return client.read(path,accepts, headers());
                        }
                });
+               if(future.get(callTimeout)) {
+                       return future.value;
+               } else {
+                       throw new RESTException(future);
+               }                                       
        }
        
        public interface Headers {
index 7340618..7d251ba 100644 (file)
@@ -27,6 +27,7 @@ import java.security.Principal;
 import org.onap.aaf.cadi.CadiException;
 import org.onap.aaf.cadi.LocatorException;
 import org.onap.aaf.cadi.enduser.ClientFactory;
+import org.onap.aaf.cadi.enduser.RESTException;
 import org.onap.aaf.cadi.enduser.SimpleRESTClient;
 import org.onap.aaf.misc.env.APIException;
 
@@ -53,6 +54,11 @@ public class SimpleRestClientExample {
                                String rv = restClient.get("resthello");
                                System.out.println(rv);
                                
+                               // Same call with "read" style
+                               rv = restClient.read("resthello");
+                               System.out.println(rv);
+                               
+                               
                                // Call with Queries
                                rv = restClient.get("resthello?perm=org.osaaf.people|*|read");
                                System.out.println(rv);
@@ -61,10 +67,22 @@ public class SimpleRestClientExample {
                                // Pretend Transaction
                                HRequest req = new HRequest("demo@people.osaaf.org"); // Pretend Trans has Jonathan as Identity
                                
-                               rv = restClient.as(req.userPrincipal()).get("resthello?perm=org.osaaf.people|*|read");
+                               // Call with RESTException, which allows obtaining HTTPCode and any Error message sent
+                               rv = restClient.endUser(req.userPrincipal()).get("resthello?perm=org.osaaf.people|*|read");
                                System.out.println(rv);
+
+                               try {
+                                       restClient.get("notAnAPI");
+                               } catch(RESTException e) {
+                                       System.out.println(e.getCode());
+                                       System.out.println(e.getMsg());
+                                       System.out.println(e.getMessage());
+                                       System.out.println(e.getLocalizedMessage());
+                                       System.out.println(e);
+                               }
+
                        }                       
-               } catch (CadiException | APIException e) {
+               } catch (CadiException | APIException | RESTException e) {
                        e.printStackTrace();
                }
        }