minor 2.1.20 changes
[aaf/authz.git] / auth / auth-batch / src / main / java / org / onap / aaf / auth / batch / Batch.java
index 7920e48..983ef81 100644 (file)
@@ -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.
@@ -34,22 +34,20 @@ import java.net.UnknownHostException;
 import java.nio.ByteBuffer;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.GregorianCalendar;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.TimeZone;
 
+import org.apache.log4j.Logger;
 import org.onap.aaf.auth.common.Define;
 import org.onap.aaf.auth.dao.CassAccess;
-import org.onap.aaf.auth.dao.cass.RoleDAO;
-import org.onap.aaf.auth.dao.cass.UserRoleDAO;
-import org.onap.aaf.auth.dao.hl.Question;
 import org.onap.aaf.auth.env.AuthzEnv;
 import org.onap.aaf.auth.env.AuthzTrans;
-import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.auth.log4j.Log4JAccessAppender;
 import org.onap.aaf.auth.org.Organization;
-import org.onap.aaf.auth.org.Organization.Identity;
 import org.onap.aaf.auth.org.OrganizationException;
 import org.onap.aaf.auth.org.OrganizationFactory;
 import org.onap.aaf.cadi.Access.Level;
@@ -57,8 +55,10 @@ import org.onap.aaf.cadi.PropAccess;
 import org.onap.aaf.cadi.config.Config;
 import org.onap.aaf.misc.env.APIException;
 import org.onap.aaf.misc.env.Env;
-import org.onap.aaf.misc.env.StaticSlot;
 import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.util.Chrono;
+import org.onap.aaf.misc.env.util.Split;
+import org.onap.aaf.misc.env.util.StringBuilderOutputStream;
 
 import com.datastax.driver.core.Cluster;
 import com.datastax.driver.core.ResultSet;
@@ -67,39 +67,33 @@ import com.datastax.driver.core.Session;
 import com.datastax.driver.core.Statement;
 
 public abstract class Batch {
-
-    private static String rootNs;
-
-    private static StaticSlot ssargs;
-
     protected static final String STARS = "*****";
 
-    protected final Cluster cluster; 
+    protected static Cluster cluster;
     protected static AuthzEnv env;
     protected static Session session;
     protected static Set<String> specialNames;
     protected static List<String> specialDomains;
-    protected static boolean dryRun; 
+    protected static boolean dryRun;
     protected static String batchEnv;
 
+    private static File logdir;
+
+       private static String[] batchArgs;
+
     public static final String CASS_ENV = "CASS_ENV";
     public static final String LOG_DIR = "LOG_DIR";
-    protected static final String PUNT="punt";
     protected static final String MAX_EMAILS="MAX_EMAILS";
     protected static final String VERSION="VERSION";
     public static final String GUI_URL="GUI_URL";
-    
-    protected final Organization org;
 
+    protected final Organization org;
+    protected String version;
+    protected static final Date now = new Date();
+    protected static final Date never = new Date(0);
 
-    
     protected Batch(AuthzEnv env) throws APIException, IOException, OrganizationException {
-        // Be able to change Environments
-        // load extra properties, i.e.
-        // PERF.cassandra.clusters=....
-        batchEnv = env.getProperty(CASS_ENV);
         if (batchEnv != null) {
-            batchEnv = batchEnv.trim();
             env.info().log("Redirecting to ",batchEnv,"environment");
             String str;
             for (String key : new String[]{
@@ -107,9 +101,10 @@ public abstract class Batch {
                     CassAccess.CASSANDRA_CLUSTERS_PORT,
                     CassAccess.CASSANDRA_CLUSTERS_USER_NAME,
                     CassAccess.CASSANDRA_CLUSTERS_PASSWORD,
-                    VERSION,GUI_URL,PUNT,MAX_EMAILS,
+                    VERSION,GUI_URL,MAX_EMAILS,
                     LOG_DIR,
-                    "SPECIAL_NAMES"
+                    "SPECIAL_NAMES",
+                    "MAIL_TEST_TO"
                     }) {
                 if ((str = env.getProperty(batchEnv+'.'+key))!=null) {
                     env.setProperty(key, str);
@@ -118,7 +113,9 @@ public abstract class Batch {
         }
 
         // Setup for Dry Run
-        cluster = CassAccess.cluster(env,batchEnv);
+        if(cluster==null) {
+            cluster = CassAccess.cluster(env,batchEnv);
+        }
         env.info().log("cluster name - ",cluster.getClusterName());
         String dryRunStr = env.getProperty( "DRY_RUN" );
         if ( dryRunStr == null || "false".equals(dryRunStr.trim()) ) {
@@ -129,6 +126,9 @@ public abstract class Batch {
         }
 
         org = OrganizationFactory.init(env);
+        if(org==null) {
+            throw new OrganizationException("Organization MUST be defined for Batch");
+        }
         org.setTestMode(dryRun);
 
         // Special names to allow behaviors beyond normal rules
@@ -141,42 +141,44 @@ public abstract class Batch {
             for (String s :names.split(",") ) {
                 env.info().log("\tspecial: " + s );
                 if(s.indexOf('@')>0) {
-                       specialNames.add( s.trim() );
+                    specialNames.add( s.trim() );
                 } else {
-                       specialDomains.add(s.trim());
+                    specialDomains.add(s.trim());
                 }
             }
         }
+
+        version = env.getProperty(VERSION,Config.AAF_DEFAULT_API_VERSION);
     }
 
     protected abstract void run(AuthzTrans trans);
-    protected abstract void _close(AuthzTrans trans);
-    
+    protected void _close(AuthzTrans trans) {}
+
     public String[] args() {
-        return env.get(ssargs);
+        return batchArgs;
     }
-    
+
     public boolean isDryRun()
     {
         return dryRun;
     }
-    
+
     public boolean isSpecial(String user) {
-       if(user==null) {
-               return false;
-       }
+        if(user==null) {
+            return false;
+        }
         if (specialNames != null && specialNames.contains(user)) {
             env.info().log("specialName: " + user);
             return (true);
         } else {
-               if(specialDomains!=null) {
-                       for(String sd : specialDomains) {
-                               if(user.endsWith(sd)) {
-                                       env.info().log("specialDomain: " + user + " matches " + sd);
-                                       return (true);
-                               }
-                       }
-               }
+            if(specialDomains!=null) {
+                for(String sd : specialDomains) {
+                    if(user.endsWith(sd)) {
+                        env.info().log("specialDomain: " + user + " matches " + sd);
+                        return (true);
+                    }
+                }
+            }
         }
         return (false);
     }
@@ -226,7 +228,7 @@ public abstract class Batch {
 
         return (organization);
     }
-    
+
     public static Row executeDeleteQuery(Statement stmt) {
         Row row = null;
         if (!dryRun) {
@@ -236,7 +238,7 @@ public abstract class Batch {
         return (row);
 
     }
-        
+
     public static int acquireRunLock(String className) {
         Boolean testEnv = true;
         String envStr = env.getProperty("AFT_ENVIRONMENT");
@@ -260,8 +262,7 @@ public abstract class Batch {
         try {
             hostname = InetAddress.getLocalHost().getHostName();
         } catch (UnknownHostException e) {
-            e.printStackTrace();
-            env.warn().log("Unable to get hostname");
+            env.warn().log("Unable to get hostname : "+e.getMessage());
             return (0);
         }
 
@@ -316,7 +317,7 @@ public abstract class Batch {
         }
         return (1);
     }
-    
+
     private static void deleteLock( String className) {
         Row row = session.execute( String.format( "DELETE FROM authz.run_lock WHERE class = '%s' IF EXISTS", className ) ).one();
         if (! row.getBool("[applied]")) {
@@ -332,46 +333,23 @@ public abstract class Batch {
             }
         }
     }
-    
-    // IMPORTANT! VALIDATE Organization isUser method
-    protected void checkOrganizationAcccess(AuthzTrans trans, Question q) throws APIException, OrganizationException {
-            Set<String> testUsers = new HashSet<>();
-            Result<List<RoleDAO.Data>> rrd = q.roleDAO.readNS(trans, rootNs);
-            if (rrd.isOK()) {
-                for (RoleDAO.Data r : rrd.value) {
-                    Result<List<UserRoleDAO.Data>> rur = q.userRoleDAO.readByRole(trans, r.fullName());
-                    if (!rur.isOK()) {
-                        continue;
-                    }
-                    for (UserRoleDAO.Data udd : rur.value) {
-                        testUsers.add(udd.user);
-                    }
-                }
-                if (testUsers.size() < 2) {
-                    throw new APIException("Not enough Users in Roles for " + rootNs + " to Validate");
-                }
 
-                Identity iden;
-                for (String user : testUsers) {
-                    if ((iden = org.getIdentity(trans, user)) == null) {
-                        throw new APIException("Failed Organization Entity Validation Check: " + user);
-                    } else {
-                        trans.info().log("Organization Validation Check: " + iden.id());
-                    }
+    protected static File logDir() {
+        if(logdir == null) {
+            String ld = env.getProperty(LOG_DIR);
+            if (ld==null) {
+                if (batchEnv==null) { // Deployed Batch doesn't use different ENVs, and a common logdir
+                    ld = "logs/";
+                } else {
+                    ld = "logs/"+batchEnv;
                 }
             }
-        }
-    
-    protected static String logDir() {
-        String ld = env.getProperty(LOG_DIR);
-        if (ld==null) {
-            if (batchEnv==null) { // Deployed Batch doesn't use different ENVs, and a common logdir
-                ld = "logs/";
-            } else {
-                ld = "logs/"+batchEnv;
+            logdir = new File(ld);
+            if(!logdir.exists()) {
+                logdir.mkdirs();
             }
         }
-        return ld;
+        return logdir;
     }
     protected int count(String str, char c) {
         if (str==null || str.isEmpty()) {
@@ -387,141 +365,185 @@ public abstract class Batch {
 
     public final void close(AuthzTrans trans) {
         _close(trans);
-        cluster.close();
+        if(session!=null) {
+            session.close();
+            session = null;
+        }
+        if(cluster!=null && !cluster.isClosed()) {
+            cluster.close();
+        }
     }
 
     public static void main(String[] args) {
-        PropAccess access = new PropAccess(args);
+        // Use a StringBuilder to save off logs until a File can be setup
+        StringBuilderOutputStream sbos = new StringBuilderOutputStream();
+        PropAccess access = new PropAccess(new PrintStream(sbos),args);
+        access.log(Level.INFO, "------- Starting Batch ------\n  Args: ");
+        for(String s: args) {
+            sbos.getBuffer().append(s);
+            sbos.getBuffer().append(' ');
+        }
+        sbos.getBuffer().append('\n');
+
         InputStream is = null;
         String filename;
         String propLoc;
         try {
             Define.set(access);
-            rootNs =Define.ROOT_NS();
+
             if(access.getProperty(Config.CADI_PROP_FILES)==null) {
-                   File f = new File("authBatch.props");
-                   try {
-                       if (f.exists()) {
-                           filename = f.getAbsolutePath();
-                           is = new FileInputStream(f);
-                           propLoc = f.getPath();
-                       } else {
-                           URL rsrc = ClassLoader.getSystemResource("authBatch.props");
-                           filename = rsrc.toString();
-                           is = rsrc.openStream();
-                           propLoc = rsrc.getPath();
-                       }
-                       access.load(is);
-                   } finally {
-                       if (is == null) {
-                           System.err.println("authBatch.props must exist in current dir, or in Classpath");
-                           System.exit(1);
-                       }
-                       is.close();
-                   }
-                   if (filename != null) {
-                       access.log(Level.INFO,"Instantiated properties from", filename);
-                   }
-
-                   // Log where Config found
-                   access.log(Level.INFO,"Configuring from", propLoc);
+                File f = new File("authBatch.props");
+                try {
+                    if (f.exists()) {
+                        filename = f.getAbsolutePath();
+                        is = new FileInputStream(f);
+                        propLoc = f.getPath();
+                    } else {
+                        URL rsrc = ClassLoader.getSystemResource("authBatch.props");
+                        filename = rsrc.toString();
+                        is = rsrc.openStream();
+                        propLoc = rsrc.getPath();
+                    }
+                    access.load(is);
+                } finally {
+                    if (is == null) {
+                        System.err.println("authBatch.props must exist in current dir, or in Classpath");
+                        System.exit(1);
+                    }
+                    is.close();
+                }
+                if (filename != null) {
+                    access.log(Level.INFO,"Instantiated properties from", filename);
+                }
+
+                // Log where Config found
+                access.log(Level.INFO,"Configuring from", propLoc);
 
             }
+
             env = new AuthzEnv(access);
 
             transferVMProps(env, CASS_ENV, "DRY_RUN", "NS", "Organization");
 
-            // Flow all Env Logs to Log4j, with ENV
-
-//            LogFileNamer lfn;
-//            lfn = new LogFileNamer(logDir(),"").noPID();
-//            lfn.setAppender("authz-batch");
-//            lfn.setAppender("aspr|ASPR");
-//            lfn.setAppender("sync");
-//            lfn.setAppender("jobchange");
-//            lfn.setAppender("validateuser");
-//            aspr = Logger.getLogger("aspr");
-//            Log4JLogTarget.setLog4JEnv("authz-batch", env);
-//            propLoc = null;
-
-            Batch batch = null;
-            // setup ATTUser and Organization Slots before starting this:
-            // TODO redo this
-            // env.slot(ATT.ATT_USERSLOT);
-            //
-            // OrganizationFactory.setDefaultOrg(env, ATT.class.getName());
-            AuthzTrans trans = env.newTrans();
-
-            TimeTaken tt = trans.start("Total Run", Env.SUB);
+            // Be able to change Environments
+            // load extra properties, i.e.
+            // PERF.cassandra.clusters=....
+            batchEnv = env.getProperty(CASS_ENV);
+            if(batchEnv!=null) {
+                batchEnv = batchEnv.trim();
+            }
+
+            File logFile = new File(logDir() + "/batch" + Chrono.dateOnlyStamp(new Date()) + ".log" );
+            PrintStream batchLog = new PrintStream(new FileOutputStream(logFile,true));
             try {
-                int len = args.length;
-                if (len > 0) {
-                    String toolName = args[0];
-                    len -= 1;
-                    if (len < 0)
-                        len = 0;
-                    String nargs[] = new String[len];
+                access.setStreamLogIt(batchLog);
+                sbos.flush();
+                batchLog.print(sbos.getBuffer());
+                sbos = null;
+                Logger.getRootLogger().addAppender(new Log4JAccessAppender(access));
+
+                Batch batch = null;
+                AuthzTrans trans = env.newTrans();
+
+                TimeTaken tt = trans.start("Total Run", Env.SUB);
+                try {
+                    int len = args.length;
                     if (len > 0) {
-                        System.arraycopy(args, 1, nargs, 0, len);
-                    }
-
-                    env.put(ssargs = env.staticSlot("ARGS"), nargs);
-
-                    /*
-                     * Add New Batch Programs (inherit from Batch) here
-                     */
+                        String toolName = args[0];
+                        len -= 1;
+                        if (len < 0)
+                            len = 0;
+                        batchArgs = new String[len];
+                        if (len > 0) {
+                            System.arraycopy(args, 1, batchArgs, 0, len);
+                        }
+                        /*
+                         * Add New Batch Programs (inherit from Batch) here
+                         */
+
+                        // Might be a Report, Update or Temp Batch
+                        Class<?> cls = null;
+                        String classifier = "";
+
+                        String[] pkgs = new String[] {
+                                "org.onap.aaf.auth.batch.update",
+                                "org.onap.aaf.auth.batch.reports",
+                                "org.onap.aaf.auth.batch.temp"
+                                };
+
+                        String ebp = env.getProperty("EXTRA_BATCH_PKGS");
+                        if(ebp!=null) {
+                            String[] ebps = Split.splitTrim(':', ebp);
+                            String[] temp = new String[ebps.length + pkgs.length];
+                            System.arraycopy(pkgs,0, temp, 0, pkgs.length);
+                            System.arraycopy(ebps,0,temp,pkgs.length,ebps.length);
+                            pkgs = temp;
+                        }
 
-                    // Might be a Report, Update or Temp Batch
-                    Class<?> cls;
-                    String classifier = "";
-                    try {
-                        cls = ClassLoader.getSystemClassLoader().loadClass("org.onap.aaf.auth.batch.update." + toolName);
-                        classifier = "Update:";
-                    } catch (ClassNotFoundException e) {
-                        try {
-                            cls = ClassLoader.getSystemClassLoader().loadClass("org.onap.aaf.auth.batch.reports." + toolName);
-                            classifier = "Report:";
-                        } catch (ClassNotFoundException e2) {
+                        for(String p : pkgs) {
                             try {
-                                cls = ClassLoader.getSystemClassLoader()
-                                        .loadClass("org.onap.aaf.auth.batch.temp." + toolName);
-                                classifier = "Temp Utility:";
-                            } catch (ClassNotFoundException e3) {
+                                cls = ClassLoader.getSystemClassLoader().loadClass(p + '.' + toolName);
+                                int lastDot = p.lastIndexOf('.');
+                                if(p.length()>0 || p.length()!=lastDot) {
+                                    StringBuilder sb = new StringBuilder();
+                                    sb.append(Character.toUpperCase(p.charAt(++lastDot)));
+                                    while(++lastDot<p.length()) {
+                                        sb.append(p.charAt(lastDot));
+                                    }
+                                    sb.append(':');
+                                    classifier = sb.toString();
+                                    break;
+                                }
+                            } catch (ClassNotFoundException e) {
                                 cls = null;
                             }
                         }
+                        if (cls != null) {
+                            Constructor<?> cnst = cls.getConstructor(AuthzTrans.class);
+                            batch = (Batch) cnst.newInstance(trans);
+                            env.info().log("Begin", classifier, toolName);
+                        }
+
+
+                        if (batch == null) {
+                            trans.error().log("No Batch named", toolName, "found");
+                        }
+                        /*
+                         * End New Batch Programs (inherit from Batch) here
+                         */
+
                     }
-                    if (cls != null) {
-                        Constructor<?> cnst = cls.getConstructor(AuthzTrans.class);
-                        batch = (Batch) cnst.newInstance(trans);
-                        env.info().log("Begin", classifier, toolName);
+                    if (batch != null) {
+                        try {
+                            batch.run(trans);
+                        } catch (Exception e) {
+                               trans.error().log(e);
+                            if(cluster!=null && !cluster.isClosed()) {
+                                cluster.close();
+                            }
+                            trans.error().log(e);
+                        }
                     }
-                
-
-                    if (batch == null) {
-                        trans.error().log("No Batch named", toolName, "found");
+                } finally {
+                    tt.done();
+                    if (batch != null) {
+                        batch.close(trans);
                     }
-                    /*
-                     * End New Batch Programs (inherit from Batch) here
-                     */
-
-                }
-                if (batch != null) {
-                    batch.run(trans);
+                    StringBuilder sb = new StringBuilder("Task Times\n");
+                    trans.auditTrail(4, sb, AuthzTrans.SUB, AuthzTrans.REMOTE);
+                    trans.info().log(sb);
                 }
+            } catch (Exception e) {
+               env.warn().log(e);
             } finally {
-                tt.done();
-                if (batch != null) {
-                    batch.close(trans);
-                }
-                StringBuilder sb = new StringBuilder("Task Times\n");
-                trans.auditTrail(4, sb, AuthzTrans.SUB, AuthzTrans.REMOTE);
-                trans.info().log(sb);
+                batchLog.close();
             }
+
         } catch (Exception e) {
-            e.printStackTrace(System.err);
-            // Exceptions thrown by DB aren't stopping the whole process.
-            System.exit(1);
+            if(cluster!=null && !cluster.isClosed()) {
+                cluster.close();
+            }
+            env.warn().log(System.err);
         }
     }