X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=auth%2Fauth-cmd%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Faaf%2Fauth%2Fcmd%2FCmd.java;h=7913b76e2533d3117a40b99be664e788c85afb65;hb=HEAD;hp=71643cd014f47600a56ac7aa467961c1f4dd2c23;hpb=6261a19e61138e861f5c7eaf37835205f19f1fe0;p=aaf%2Fauthz.git diff --git a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/Cmd.java b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/Cmd.java index 71643cd0..7913b76e 100644 --- a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/Cmd.java +++ b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/Cmd.java @@ -7,9 +7,9 @@ * 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. @@ -54,489 +54,486 @@ import aaf.v2_0.History; import aaf.v2_0.History.Item; import aaf.v2_0.Request; - public abstract class Cmd { - // Sonar claims DateFormat is not thread safe. Leave as Instance Variable. - private final DateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS"); - protected static final String BLANK = ""; - protected static final String COMMA = ","; // for use in splits - - protected static final int lineLength = 80; - - private final static String hformat = "%-23s %-5s %-20s %-35s\n"; - - public static final String STARTDATE = "startdate"; - public static final String ENDDATE = "enddate"; - - private String name; - private final Param[] params; - private int required; - protected final Cmd parent; - protected final List children; - private final static ConcurrentHashMap,RosettaDF> dfs = new ConcurrentHashMap<>(); - public final AAFcli aafcli; - protected Access access; - private AuthzEnv env; - private final String defaultRealm; - - public Cmd(AAFcli aafcli, String name, Param ... params) { - this(aafcli,null, name,params); - } - - public Cmd(Cmd parent, String name, Param ... params) { - this(parent.aafcli,parent, name,params); - } - - Cmd(AAFcli aafcli, Cmd parent, String name, Param ... params) { - this.parent = parent; - this.aafcli = aafcli; - this.env = aafcli.env; - this.access = aafcli.access; - if(parent!=null) { - parent.children.add(this); - } - children = new ArrayList<>(); - this.params = params; - this.name = name; - required=0; - for(Param p : params) { - if(p.required) { - ++required; - } - } - - String temp = access.getProperty(Config.AAF_DEFAULT_REALM,null); - if(temp!=null && !temp.startsWith("@")) { - defaultRealm = '@' + temp; - } else { - defaultRealm=""; - } - } - - public final int exec(int idx, String ... args) throws CadiException, APIException, LocatorException { - if(args.length-idx cls,boolean head) { - final String smeth = meth.name(); - if(head) { - sb.append('\n'); - detailLine(sb,indent,"APIs:"); - } - indent+=2; - multiChar(sb,indent,' ',0); - sb.append(smeth); - sb.append(' '); - sb.append(pathInfo); - String cliString = aafcli.typeString(cls,true); - if(indent+smeth.length()+pathInfo.length()+cliString.length()+2>80) { - sb.append(" ..."); - multiChar(sb,indent+3+smeth.length(),' ',0); - } else { // same line - sb.append(' '); - } - sb.append(cliString); - } - - protected void multiChar(StringBuilder sb, int length, char c, int indent) { - sb.append('\n'); - for(int i=0;i ": "] "); - } - - boolean first = true; - for(Cmd child : children) { - if(!(child instanceof DeprecatedCMD)) { - if(first) { - first = false; - } else if(detail==null) { - multiChar(sb,indent,' ',0); - } else { - // Write parents for Detailed Report - Stack stack = new Stack(); - for(Cmd c = child.parent;c!=null;c=c.parent) { - if(c.name!=null) { - stack.push(c.name); - } - } - if(!stack.isEmpty()) { - sb.append(" "); - while(!stack.isEmpty()) { - sb.append(stack.pop()); - sb.append(' '); - } - } - } - child.build(sb,detail); - if(detail!=null) { - child.detailedHelp(4, detail); - // If Child wrote something, then add, bracketing by lines - if(detail.length()>0) { - multiChar(sb,80,'-',2); - sb.append(detail); - sb.append('\n'); - multiChar(sb,80,'-',2); - sb.append('\n'); - detail.setLength(0); // reuse - } else { - sb.append('\n'); - } - } - } - } - return sb; - } - - protected void error(Future future) { - StringBuilder sb = new StringBuilder("Failed"); - String desc = future.body(); - int code = future.code(); - if(desc==null || desc.length()==0) { - withCode(sb,code); - } else if(desc.startsWith("{")) { - StringReader sr = new StringReader(desc); - try { - // Note: 11-18-2013, JonathanGathman. This rather convoluted Message Structure required by TSS Restful Specs, reflecting "Northbound" practices. - Error err = getDF(Error.class).newData().in(TYPE.JSON).load(sr).asObject(); - sb.append(" ["); - sb.append(err.getMessageId()); - sb.append("]: "); - String messageBody = err.getText(); - List vars = err.getVariables(); - int pipe; - for (int varCounter=0;varCounter= 0) { - if((pipe = var.indexOf('|'))>=0) { // In AAF, we use a PIPE for Choice - if (aafcli.isTest()) { - String expiresStr = var.substring(pipe); - var = var.replace(expiresStr, "[Placeholder]"); - } else { - StringBuilder varsb = new StringBuilder(var); - varsb.deleteCharAt(pipe); - var = varsb.toString(); - } - messageBody = messageBody.replace("%" + varCounter, varCounter-1 + ") " + var); - } else { - messageBody = messageBody.replace("%" + varCounter, var); - } - } - } - sb.append(messageBody); - } catch (Exception e) { - withCode(sb,code); - sb.append(" (Note: Details cannot be obtained from Error Structure)"); - } - } else if(desc.startsWith("")){ // Core Jetty, etc sends HTML for Browsers - withCode(sb,code); - } else { - sb.append(" with code "); - sb.append(code); - sb.append(", "); - sb.append(desc); - } - pw().println(sb); - } - - - private void withCode(StringBuilder sb, Integer code) { - sb.append(" with code "); - sb.append(code); - switch(code) { - case 401: - sb.append(" (HTTP Not Authenticated)"); - break; - case 403: - sb.append(" (HTTP Forbidden)"); - break; - case 404: - sb.append(" (HTTP Not Found)"); - break; - default: - } - } - - /** - * Consistently set start and end dates from Requests (all derived from Request) - * @param req - */ - protected void setStartEnd(Request req) { - // Set Start/End Dates, if exist - String str; - if((str = access.getProperty(Cmd.STARTDATE,null))!=null) { - req.setStart(Chrono.timeStamp(Date.valueOf(str))); - } - - if((str = access.getProperty(Cmd.ENDDATE,null))!=null) { - req.setEnd(Chrono.timeStamp(Date.valueOf(str))); - } - } - - /** - * For Derived classes, who have ENV in this parent - * - * @param cls - * @return - * @throws APIException - */ - protected RosettaDF getDF(Class cls) throws APIException { - return getDF(env,cls); - } - - /** - * This works well, making available for GUI, etc. - * @param env - * @param cls - * @return - * @throws APIException - */ - @SuppressWarnings("unchecked") - public static RosettaDF getDF(AuthzEnv env, Class cls) throws APIException { - RosettaDF rdf = (RosettaDF)dfs.get(cls); - if(rdf == null) { - rdf = env.newDataFactory(cls); - dfs.put(cls, rdf); - } - return rdf; - } - - public void activity(History history, String header) { - if (history.getItem().isEmpty()) { - int start = header.indexOf('['); - if (start >= 0) { - pw().println("No Activity Found for " + header.substring(start)); - } - } else { - pw().println(header); - for(int i=0;i items = history.getItem(); - java.util.Collections.sort(items, new Comparator() { - @Override - public int compare(Item o1, Item o2) { - return o2.getTimestamp().compare(o1.getTimestamp()); - } - }); - - for(History.Item item : items) { - GregorianCalendar gc = item.getTimestamp().toGregorianCalendar(); - pw().format(hformat, - dateFmt.format(gc.getTime()), - item.getTarget(), - item.getUser(), - item.getMemo()); - } - } - } - - /** - * Turn String Array into a | delimited String - * @param options - * @return - */ - public static String optionsToString(String[] options) { - StringBuilder sb = new StringBuilder(); - boolean first = true; - for(String s : options) { - if(first) { - first = false; - } else { - sb.append('|'); - } - sb.append(s); - } - return sb.toString(); - } - - /** - * return which index number the Option matches. - * - * throws an Exception if not part of this Option Set - * - * @param options - * @param test - * @return - * @throws Exception - */ - public int whichOption(String[] options, String test) throws CadiException { - for(int i=0;i RET same(Retryable retryable) throws APIException, CadiException, LocatorException { - // We're storing in AAFCli, because we know it's always the same, and single threaded - if(aafcli.prevCall!=null) { - retryable.item(aafcli.prevCall.item()); - retryable.lastClient=aafcli.prevCall.lastClient; - } - - RET ret = aafcli.hman.same(aafcli.ss,retryable); - - // Store last call in AAFcli, because Cmds are all different instances. - aafcli.prevCall = retryable; - return ret; - } - - public RET all(Retryable retryable) throws APIException, CadiException, LocatorException { - this.setQueryParamsOn(retryable.lastClient); - return aafcli.hman.all(aafcli.ss,retryable); - } - - public RET oneOf(Retryable retryable,String host) throws APIException, CadiException, LocatorException { - this.setQueryParamsOn(retryable.lastClient); - return aafcli.hman.oneOf(aafcli.ss,retryable,true,host); - } - - protected PrintWriter pw() { - return AAFcli.pw; - } - - public String getName() { - return name; - } - - public void reportHead(String ... str) { - pw().println(); - boolean first = true; - int i=0; - for(String s : str) { - if(first) { - if(++i>1) { - first = false; - pw().print("["); - } - } else { - pw().print("] ["); - } - pw().print(s); - } - if(!first) { - pw().print(']'); - } - pw().println(); - reportLine(); - } - - public String reportColHead(String format, String ... args) { - pw().format(format,(Object[])args); - reportLine(); - return format; - } - - public void reportLine() { - for(int i=0;i rcli) { - StringBuilder sb=null; - String force; - if((force=aafcli.forceString())!=null) { - sb = new StringBuilder("force="); - sb.append(force); - } - if(aafcli.addRequest()) { - if(sb==null) { - sb = new StringBuilder("future=true"); - } else { - sb.append("&future=true"); - } - } - if(sb!=null && rcli!=null) { - rcli.setQueryParams(sb.toString()); - } - } + // Sonar claims DateFormat is not thread safe. Leave as Instance Variable. + private final DateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS"); + protected static final String BLANK = ""; + protected static final String COMMA = ","; // for use in splits + + protected static final int lineLength = 80; + + private static final String hformat = "%-23s %-5s %-20s %-35s\n"; + + public static final String STARTDATE = "startdate"; + public static final String ENDDATE = "enddate"; + + private String name; + private final Param[] params; + private int required; + protected final Cmd parent; + protected final List children; + private static final ConcurrentHashMap,RosettaDF> dfs = new ConcurrentHashMap<>(); + public final AAFcli aafcli; + protected Access access; + private AuthzEnv env; + private final String defaultRealm; + + public Cmd(AAFcli aafcli, String name, Param ... params) { + this(aafcli,null, name,params); + } + + public Cmd(Cmd parent, String name, Param ... params) { + this(parent.aafcli,parent, name,params); + } + + Cmd(AAFcli aafcli, Cmd parent, String name, Param ... params) { + this.parent = parent; + this.aafcli = aafcli; + this.env = aafcli.env; + this.access = aafcli.access; + if (parent!=null) { + parent.children.add(this); + } + children = new ArrayList<>(); + this.params = params; + this.name = name; + required=0; + for (Param p : params) { + if (p.required) { + ++required; + } + } + + String temp = access.getProperty(Config.AAF_DEFAULT_REALM,null); + if (temp!=null && !temp.startsWith("@")) { + defaultRealm = '@' + temp; + } else { + defaultRealm=""; + } + } + + public final int exec(int idx, String ... args) throws CadiException, APIException, LocatorException { + if (args.length-idx cls,boolean head) { + final String smeth = meth.name(); + if (head) { + sb.append('\n'); + detailLine(sb,indent,"APIs:"); + } + indent+=2; + multiChar(sb,indent,' ',0); + sb.append(smeth); + sb.append(' '); + sb.append(pathInfo); + String cliString = aafcli.typeString(cls,true); + if (indent+smeth.length()+pathInfo.length()+cliString.length()+2>80) { + sb.append(" ..."); + multiChar(sb,indent+3+smeth.length(),' ',0); + } else { // same line + sb.append(' '); + } + sb.append(cliString); + } + + protected void multiChar(StringBuilder sb, int length, char c, int indent) { + sb.append('\n'); + for (int i=0;i ": "] "); + } + + boolean first = true; + for (Cmd child : children) { + if (!(child instanceof DeprecatedCMD)) { + if (first) { + first = false; + } else if (detail==null) { + multiChar(sb,indent,' ',0); + } else { + // Write parents for Detailed Report + Stack stack = new Stack<>(); + for (Cmd c = child.parent;c!=null;c=c.parent) { + if (c.name!=null) { + stack.push(c.name); + } + } + if (!stack.isEmpty()) { + sb.append(" "); + while (!stack.isEmpty()) { + sb.append(stack.pop()); + sb.append(' '); + } + } + } + child.build(sb,detail); + if (detail!=null) { + child.detailedHelp(4, detail); + // If Child wrote something, then add, bracketing by lines + if (detail.length()>0) { + multiChar(sb,80,'-',2); + sb.append(detail); + sb.append('\n'); + multiChar(sb,80,'-',2); + sb.append('\n'); + detail.setLength(0); // reuse + } else { + sb.append('\n'); + } + } + } + } + return sb; + } + + protected void error(Future future) { + StringBuilder sb = new StringBuilder("Failed"); + String desc = future.body(); + int code = future.code(); + if (desc==null || desc.length()==0) { + withCode(sb,code); + } else if (desc.startsWith("{")) { + StringReader sr = new StringReader(desc); + try { + // Note: 11-18-2013, JonathanGathman. This rather convoluted Message Structure required by TSS Restful Specs, reflecting "Northbound" practices. + Error err = getDF(Error.class).newData().in(TYPE.JSON).load(sr).asObject(); + sb.append(" ["); + sb.append(err.getMessageId()); + sb.append("]: "); + String messageBody = err.getText(); + List vars = err.getVariables(); + int pipe; + for (int varCounter=0;varCounter= 0) { + if ((pipe = var.indexOf('|'))>=0) { // In AAF, we use a PIPE for Choice + if (aafcli.isTest()) { + String expiresStr = var.substring(pipe); + var = var.replace(expiresStr, "[Placeholder]"); + } else { + StringBuilder varsb = new StringBuilder(var); + varsb.deleteCharAt(pipe); + var = varsb.toString(); + } + messageBody = messageBody.replace("%" + varCounter, varCounter-1 + ") " + var); + } else { + messageBody = messageBody.replace("%" + varCounter, var); + } + } + } + sb.append(messageBody); + } catch (Exception e) { + withCode(sb,code); + sb.append(" (Note: Details cannot be obtained from Error Structure)"); + } + } else if (desc.startsWith("")){ // Core Jetty, etc sends HTML for Browsers + withCode(sb,code); + } else { + sb.append(" with code "); + sb.append(code); + sb.append(", "); + sb.append(desc); + } + pw().println(sb.toString()); + } + + + private void withCode(StringBuilder sb, Integer code) { + sb.append(" with code "); + sb.append(code); + switch(code) { + case 401: + sb.append(" (HTTP Not Authenticated)"); + break; + case 403: + sb.append(" (HTTP Forbidden)"); + break; + case 404: + sb.append(" (HTTP Not Found)"); + break; + default: + } + } + + /** + * Consistently set start and end dates from Requests (all derived from Request) + * @param req + */ + protected void setStartEnd(Request req) { + // Set Start/End Dates, if exist + String str; + if ((str = access.getProperty(Cmd.STARTDATE,null))!=null) { + req.setStart(Chrono.timeStamp(Date.valueOf(str))); + } + + if ((str = access.getProperty(Cmd.ENDDATE,null))!=null) { + req.setEnd(Chrono.timeStamp(Date.valueOf(str))); + } + } + + /** + * For Derived classes, who have ENV in this parent + * + * @param cls + * @return + * @throws APIException + */ + protected RosettaDF getDF(Class cls) throws APIException { + return getDF(env,cls); + } + + /** + * This works well, making available for GUI, etc. + * @param env + * @param cls + * @return + * @throws APIException + */ + @SuppressWarnings("unchecked") + public static RosettaDF getDF(AuthzEnv env, Class cls) throws APIException { + RosettaDF rdf = (RosettaDF)dfs.get(cls); + if (rdf == null) { + rdf = env.newDataFactory(cls); + dfs.put(cls, rdf); + } + return rdf; + } + + public void activity(History history, String header) { + if (history.getItem().isEmpty()) { + int start = header.indexOf('['); + if (start >= 0) { + pw().println("No Activity Found for " + header.substring(start)); + } + } else { + pw().println(header); + for (int i=0;i items = history.getItem(); + java.util.Collections.sort(items, (Comparator) (o1, o2) -> o2.getTimestamp().compare(o1.getTimestamp())); + + for (History.Item item : items) { + GregorianCalendar gc = item.getTimestamp().toGregorianCalendar(); + pw().format(hformat, + dateFmt.format(gc.getTime()), + item.getTarget(), + item.getUser(), + item.getMemo()); + } + } + } + + /** + * Turn String Array into a | delimited String + * @param options + * @return + */ + public static String optionsToString(String[] options) { + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (String s : options) { + if (first) { + first = false; + } else { + sb.append('|'); + } + sb.append(s); + } + return sb.toString(); + } + + /** + * return which index number the Option matches. + * + * throws an Exception if not part of this Option Set + * + * @param options + * @param test + * @return + * @throws Exception + */ + public int whichOption(String[] options, String test) throws CadiException { + for (int i=0;i RET same(Retryable retryable) throws APIException, CadiException, LocatorException { + // We're storing in AAFCli, because we know it's always the same, and single threaded + if (aafcli.prevCall!=null) { + retryable.item(aafcli.prevCall.item()); + retryable.lastClient=aafcli.prevCall.lastClient; + } + + RET ret = aafcli.hman.same(aafcli.ss,retryable); + + // Store last call in AAFcli, because Cmds are all different instances. + aafcli.prevCall = retryable; + return ret; + } + + public RET all(Retryable retryable) throws APIException, CadiException, LocatorException { + this.setQueryParamsOn(retryable.lastClient); + return aafcli.hman.all(aafcli.ss,retryable); + } + + public RET oneOf(Retryable retryable,String host) throws APIException, CadiException, LocatorException { + this.setQueryParamsOn(retryable.lastClient); + return aafcli.hman.oneOf(aafcli.ss,retryable,true,host); + } + + protected PrintWriter pw() { + return AAFcli.pw; + } + + public String getName() { + return name; + } + + public void reportHead(String ... str) { + pw().println(); + boolean first = true; + int i=0; + for (String s : str) { + if (first) { + if (++i>1) { + first = false; + pw().print("["); + } + } else { + pw().print("] ["); + } + pw().print(s); + } + if (!first) { + pw().print(']'); + } + pw().println(); + reportLine(); + } + + public String reportColHead(String format, String ... args) { + pw().format(format,(Object[])args); + reportLine(); + return format; + } + + public void reportLine() { + for (int i=0;i rcli) { + StringBuilder sb=null; + String force; + if ((force=aafcli.forceString())!=null) { + sb = new StringBuilder("force="); + sb.append(force); + } + if (aafcli.addRequest()) { + if (sb==null) { + sb = new StringBuilder("future=true"); + } else { + sb.append("&future=true"); + } + } + if (sb!=null && rcli!=null) { + rcli.setQueryParams(sb.toString()); + } + } // -// /** -// * If Force is set, will return True once only, then revert to "FALSE". -// * -// * @return -// */ -// protected String checkForce() { -// if(TRUE.equalsIgnoreCase(env.getProperty(FORCE, FALSE))) { -// env.setProperty(FORCE, FALSE); -// return "true"; -// } -// return FALSE; -// } - - public String toString() { - StringBuilder sb = new StringBuilder(); - if(parent==null) { // ultimate parent - build(sb,null); - return sb.toString(); - } else { - return parent.toString(); - } - } - -// private String getOrgRealm() { -// return ; -// } -// - /** - * Appends shortID with Realm, but only when allowed by Organization - * @throws OrganizationException - */ - public String fullID(String id) { - if(id != null) { - if (id.indexOf('@') < 0) { - id+=defaultRealm; - } else { - return id; // is already a full ID - } - } - return id; - } +// /** +// * If Force is set, will return True once only, then revert to "FALSE". +// * +// * @return +// */ +// protected String checkForce() { +// if (TRUE.equalsIgnoreCase(env.getProperty(FORCE, FALSE))) { +// env.setProperty(FORCE, FALSE); +// return "true"; +// } +// return FALSE; +// } + + public String toString() { + StringBuilder sb = new StringBuilder(); + if (parent==null) { // ultimate parent + build(sb,null); + return sb.toString(); + } else { + return parent.toString(); + } + } + + /** + * Appends shortID with Realm, but only when allowed by Organization + * @throws OrganizationException + */ + public String fullID(String id) { + if (id != null) { + if (id.indexOf('@') < 0) { + id+=defaultRealm; + } else { + return id; // is already a full ID + } + } + return id; + } }