1 /*******************************************************************************
2 * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
3 *******************************************************************************/
7 import java.io.FileInputStream;
8 import java.io.FileOutputStream;
9 import java.io.IOException;
10 import java.io.InputStream;
11 import java.io.PrintStream;
12 import java.lang.reflect.Constructor;
13 import java.net.InetAddress;
15 import java.net.UnknownHostException;
16 import java.nio.ByteBuffer;
17 import java.text.SimpleDateFormat;
18 import java.util.GregorianCalendar;
19 import java.util.HashSet;
20 import java.util.Properties;
22 import java.util.TimeZone;
24 import org.apache.log4j.Logger;
26 import com.att.authz.env.AuthzEnv;
27 import com.att.authz.env.AuthzTrans;
28 import com.att.authz.org.Organization;
29 import com.att.authz.org.OrganizationException;
30 import com.att.authz.org.OrganizationFactory;
31 import com.att.dao.CassAccess;
32 import com.att.inno.env.APIException;
33 import com.att.inno.env.Env;
34 import com.att.inno.env.StaticSlot;
35 import com.att.inno.env.TimeTaken;
36 import com.att.inno.env.impl.Log4JLogTarget;
37 import com.att.inno.env.log4j.LogFileNamer;
38 import com.datastax.driver.core.Cluster;
39 import com.datastax.driver.core.ResultSet;
40 import com.datastax.driver.core.Row;
41 import com.datastax.driver.core.Session;
42 import com.datastax.driver.core.Statement;
44 public abstract class Batch {
45 private static StaticSlot ssargs;
47 protected static final String STARS = "*****";
49 protected final Cluster cluster;
50 protected static AuthzEnv env;
51 protected static Session session;
52 protected static Logger aspr;
53 private static Set<String> specialNames = null;
54 protected static boolean dryRun;
55 protected static String batchEnv;
57 public static final String CASS_ENV = "CASS_ENV";
58 protected final static String PUNT="punt";
59 protected final static String VERSION="VERSION";
60 public final static String GUI_URL="GUI_URL";
62 protected final static String ORA_URL="ora_url";
63 protected final static String ORA_PASSWORD="ora_password";
67 protected Batch(AuthzEnv env) throws APIException, IOException {
68 // TODO - Property Driven Organization
70 // // att = new ATT(env);
71 // } catch (OrganizationException e) {
72 // throw new APIException(e);
75 // Be able to change Environments
76 // load extra properties, i.e.
77 // PERF.cassandra.clusters=....
78 batchEnv = env.getProperty(CASS_ENV);
79 if(batchEnv != null) {
80 batchEnv = batchEnv.trim();
81 env.info().log("Redirecting to ",batchEnv,"environment");
83 for(String key : new String[]{
84 CassAccess.CASSANDRA_CLUSTERS,
85 CassAccess.CASSANDRA_CLUSTERS_PORT,
86 CassAccess.CASSANDRA_CLUSTERS_USER_NAME,
87 CassAccess.CASSANDRA_CLUSTERS_PASSWORD,
92 if((str = env.getProperty(batchEnv+'.'+key))!=null) {
93 env.setProperty(key, str);
99 cluster = CassAccess.cluster(env,batchEnv);
100 env.info().log("cluster name - ",cluster.getClusterName());
101 String dryRunStr = env.getProperty( "DRY_RUN" );
102 if ( dryRunStr == null || dryRunStr.equals("false") ) {
106 env.info().log("dryRun set to TRUE");
109 // Special names to allow behaviors beyond normal rules
110 String names = env.getProperty( "SPECIAL_NAMES" );
113 env.info().log("Loading SPECIAL_NAMES");
114 specialNames = new HashSet<String>();
115 for (String s :names.split(",") )
117 env.info().log("\tspecial: " + s );
118 specialNames.add( s.trim() );
123 protected abstract void run(AuthzTrans trans);
124 protected abstract void _close(AuthzTrans trans);
126 public String[] args() {
127 return (String[])env.get(ssargs);
130 public boolean isDryRun()
135 public boolean isSpecial(String user) {
136 if (specialNames != null && specialNames.contains(user)) {
137 env.info().log("specialName: " + user);
145 public boolean isMechID(String user) {
146 if (user.matches("m[0-9][0-9][0-9][0-9][0-9]")) {
153 protected PrintStream fallout(PrintStream _fallout, String logType)
155 PrintStream fallout = _fallout;
156 if (fallout == null) {
157 File dir = new File("logs");
163 // String os = System.getProperty("os.name").toLowerCase();
164 long uniq = System.currentTimeMillis();
166 f = new File(dir, getClass().getSimpleName() + "_" + logType + "_"
169 fallout = new PrintStream(new FileOutputStream(f, true));
174 public Organization getOrgFromID(AuthzTrans trans, String user) {
177 org = OrganizationFactory.obtain(trans.env(),user.toLowerCase());
178 } catch (OrganizationException e1) {
179 trans.error().log(e1);
184 PrintStream fallout = null;
187 fallout = fallout(fallout, "Fallout");
188 fallout.print("INVALID_ID,");
189 fallout.println(user);
190 } catch (Exception e) {
191 env.error().log("Could not write to Fallout File", e);
199 public static Row executeDeleteQuery(Statement stmt) {
202 row = session.execute(stmt).one();
209 public static int acquireRunLock(String className) {
210 Boolean testEnv = true;
211 String envStr = env.getProperty("AFT_ENVIRONMENT");
213 if (envStr != null) {
214 if (envStr.equals("AFTPRD")) {
219 .log("AFT_ENVIRONMENT property is required and was not found. Exiting.");
224 env.info().log("TESTMODE: skipping RunLock");
228 String hostname = null;
230 hostname = InetAddress.getLocalHost().getHostName();
231 } catch (UnknownHostException e) {
233 env.warn().log("Unable to get hostname");
237 ResultSet existing = session.execute(String.format(
238 "select * from authz.run_lock where class = '%s'", className));
240 for (Row row : existing) {
241 long curr = System.currentTimeMillis();
242 ByteBuffer lastRun = row.getBytesUnsafe(2); // Can I get this field
245 long interval = (1 * 60 * 1000); // @@ Create a value in props file
247 long prev = lastRun.getLong();
249 if ((curr - prev) <= interval) {
251 String.format("Too soon! Last run was %d minutes ago.",
252 ((curr - prev) / 1000) / 60));
254 String.format("Min time between runs is %d minutes ",
255 (interval / 1000) / 60));
257 String.format("Last ran on machine: %s at %s",
258 row.getString("host"), row.getDate("start")));
261 env.info().log("Delete old lock");
262 deleteLock(className);
266 GregorianCalendar current = new GregorianCalendar();
268 // We want our time in UTC, hence "+0000"
269 SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss+0000");
270 fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
273 .format("INSERT INTO authz.run_lock (class,host,start) VALUES ('%s','%s','%s') IF NOT EXISTS",
274 className, hostname, fmt.format(current.getTime()));
278 Row row = session.execute(cql).one();
279 if (!row.getBool("[applied]")) {
280 env.warn().log("Lightweight Transaction failed to write lock.");
282 String.format("host with lock: %s, running at %s",
283 row.getString("host"), row.getDate("start")));
289 private static void deleteLock( String className) {
290 Row row = session.execute( String.format( "DELETE FROM authz.run_lock WHERE class = '%s' IF EXISTS", className ) ).one();
291 if (! row.getBool("[applied]")) {
292 env.info().log( "delete failed" );
296 private static void transferVMProps(AuthzEnv env, String ... props) {
298 for(String key : props) {
299 if((value = System.getProperty(key))!=null) {
300 env.setProperty(key, value);
306 protected int count(String str, char c) {
307 int count=str==null||str.isEmpty()?0:1;
308 for(int i=str.indexOf(c);i>=0;i=str.indexOf(c,i+1)) {
314 public final void close(AuthzTrans trans) {
319 public static void main(String[] args) {
320 Properties props = new Properties();
325 File f = new File("etc/authBatch.props");
328 filename = f.getCanonicalPath();
329 is = new FileInputStream(f);
332 URL rsrc = ClassLoader.getSystemResource("authBatch.props");
333 filename = rsrc.toString();
334 is = rsrc.openStream();
335 propLoc=rsrc.getPath();
340 System.err.println("authBatch.props must exist in etc dir, or in Classpath");
346 env = new AuthzEnv(props);
348 transferVMProps(env,CASS_ENV,"DRY_RUN","NS","Organization");
350 // Flow all Env Logs to Log4j, with ENV
353 if((batchEnv=env.getProperty(CASS_ENV))==null) {
354 lfn = new LogFileNamer("logs/").noPID();
356 lfn = new LogFileNamer("logs/" + batchEnv+'/').noPID();
359 lfn.setAppender("authz-batch");
360 lfn.setAppender("aspr|ASPR");
361 lfn.setAppender("sync");
362 lfn.setAppender("jobchange");
363 lfn.setAppender("validateuser");
364 aspr = Logger.getLogger("aspr");
365 Log4JLogTarget.setLog4JEnv("authz-batch", env);
367 env.init().log("Instantiated properties from",filename);
371 // Log where Config found
372 env.info().log("Configuring from",propLoc);
376 // setup ATTUser and Organization Slots before starting this:
377 //TODO Property Driven Organization
378 // env.slot(ATT.ATT_USERSLOT);
379 // OrganizationFactory.setDefaultOrg(env, ATT.class.getName());
380 AuthzTrans trans = env.newTrans();
382 TimeTaken tt = trans.start("Total Run", Env.SUB);
384 int len = args.length;
386 String toolName = args[0];
389 String nargs[] = new String[len];
391 System.arraycopy(args, 1, nargs, 0, len);
394 env.put(ssargs=env.staticSlot("ARGS"), nargs);
397 * Add New Batch Programs (inherit from Batch) here
400 if( JobChange.class.getSimpleName().equals(toolName)) {
401 aspr.info( "Begin jobchange processing" );
402 batch = new JobChange(trans);
404 //// else if( ValidateUsers.class.getSimpleName().equals(toolName)) {
405 //// aspr.info( "Begin ValidateUsers processing" );
406 //// batch = new ValidateUsers(trans);
408 else if( UserRoleDataGeneration.class.getSimpleName().equals(toolName)) {
409 // This job duplicates User Role add/delete History items
410 // so that we can search them by Role. Intended as a one-time
411 // script! but written as batch job because Java has better
412 // UUID support. Multiple runs will generate multiple copies of
413 // these history elements!
414 aspr.info( "Begin User Role Data Generation Processing ");
415 batch = new UserRoleDataGeneration(trans);
416 } else { // Might be a Report, Update or Temp Batch
418 String classifier = "";
420 cls = ClassLoader.getSystemClassLoader().loadClass("com.att.authz.update."+toolName);
421 classifier = "Update:";
422 } catch(ClassNotFoundException e) {
424 cls = ClassLoader.getSystemClassLoader().loadClass("com.att.authz.reports."+toolName);
425 classifier = "Report:";
426 } catch (ClassNotFoundException e2) {
428 cls = ClassLoader.getSystemClassLoader().loadClass("com.att.authz.temp."+toolName);
429 classifier = "Temp Utility:";
430 } catch (ClassNotFoundException e3) {
436 Constructor<?> cnst = cls.getConstructor(new Class[]{AuthzTrans.class});
437 batch = (Batch)cnst.newInstance(trans);
438 env.info().log("Begin",classifier,toolName);
443 trans.error().log("No Batch named",toolName,"found");
446 * End New Batch Programs (inherit from Batch) here
458 StringBuilder sb = new StringBuilder("Task Times\n");
459 trans.auditTrail(4, sb, AuthzTrans.REMOTE);
460 trans.info().log(sb);
462 } catch (Exception e) {
463 e.printStackTrace(System.err);
464 // Exceptions thrown by DB aren't stopping the whole process.