1 /*******************************************************************************
2 * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
3 *******************************************************************************/
4 // test for case where I'm an admin
8 import java.io.BufferedInputStream;
9 import java.io.BufferedReader;
10 import java.io.BufferedWriter;
12 import java.io.FileInputStream;
13 import java.io.FileWriter;
14 import java.io.IOException;
15 import java.io.InputStreamReader;
16 import java.io.PrintStream;
17 import java.net.MalformedURLException;
19 import java.text.SimpleDateFormat;
20 import java.util.ArrayList;
21 import java.util.Date;
22 import java.util.HashMap;
23 import java.util.Iterator;
27 import com.att.authz.env.AuthzTrans;
28 import com.att.authz.org.Organization;
29 import com.att.authz.org.OrganizationFactory;
30 import com.att.inno.env.APIException;
31 import com.datastax.driver.core.ResultSet;
32 import com.datastax.driver.core.Row;
33 import com.datastax.driver.core.SimpleStatement;
34 import com.datastax.driver.core.Statement;
36 public class JobChange extends Batch
38 private class UserRole
43 private class UserCred
49 private class NamespaceOwner
58 private AuthzTrans myTrans;
60 private Map<String, ArrayList<UserRole>> rolesMap = new HashMap<String, ArrayList<UserRole>>();
61 private Map<String, ArrayList<NamespaceOwner>> ownersMap = new HashMap<String, ArrayList<NamespaceOwner>>();
62 private Map<String, ArrayList<UserCred>> credsMap = new HashMap<String, ArrayList<UserCred>>();
65 public static void createDirectory( String dir )
67 File f = new File( dir );
71 env.info().log( "creating directory: " + dir );
72 boolean result = false;
78 } catch(SecurityException e){
82 System.out.println("DIR created");
87 public static String getJobChangeDataFile()
90 BufferedWriter writer = null;
91 BufferedReader reader = null;
93 boolean errorFlag = false;
97 createDirectory( "etc" );
99 outFile = new File("etc/jobchange." + getCurrentDate() );
100 if (!outFile.exists())
102 outFile.createNewFile();
106 return( "etc/jobchange." + getCurrentDate() );
109 env.info().log("Creating the local file with the webphone data");
113 writer = new BufferedWriter(new FileWriter(
114 outFile.getAbsoluteFile()));
116 URL u = new URL( "ftp://thprod37.sbc.com/jobchange_Delta.dat" );
117 reader = new BufferedReader(new InputStreamReader(
118 new BufferedInputStream(u.openStream())));
119 while ((line = reader.readLine()) != null) {
120 writer.write(line + "\n");
126 env.info().log("Finished fetching the data from the webphone ftp site.");
127 return( "etc/jobchange." + getCurrentDate() );
129 } catch (MalformedURLException e) {
130 env.error().log("Could not open the remote job change data file.", e);
133 } catch (IOException e) {
135 "Error while opening or writing to the local data file.", e);
138 } catch (Exception e) {
139 env.error().log("Error while fetching the data file.", e);
149 public static String getCurrentDate()
151 SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");
152 Date now = new Date();
153 String strDate = sdfDate.format(now);
157 public void loadUsersFromCred()
159 String query = "select id,ns from authz.cred" ;
161 env.info().log( "query: " + query );
163 Statement stmt = new SimpleStatement( query );
164 ResultSet results = session.execute(stmt);
166 Iterator<Row> iter = results.iterator();
167 while( iter.hasNext() )
169 Row row = iter.next();
170 String user = row.getString( "id" );
171 String ns = row.getString( "ns" );
172 String simpleUser = user.substring( 0, user.indexOf( "@" ) );
174 if ( isMechID( simpleUser ) )
178 else if ( credsMap.get( simpleUser ) == null )
180 credsMap.put( simpleUser, new ArrayList<UserCred>() );
182 UserCred newEntry = new UserCred();
183 newEntry.user = user;
186 credsMap.get( simpleUser ).add( newEntry );
190 UserCred newEntry = new UserCred();
191 newEntry.user = user;
194 credsMap.get( simpleUser ).add( newEntry );
197 env.debug().log( String.format( "\tUser: %s NS: %s", user, ns ) );
201 public void loadUsersFromRoles()
203 String query = "select user,role from authz.user_role" ;
205 env.info().log( "query: " + query );
207 Statement stmt = new SimpleStatement( query );
208 ResultSet results = session.execute(stmt);
209 int total=0, flagged=0;
211 Iterator<Row> iter = results.iterator();
212 while( iter.hasNext() )
214 Row row = iter.next();
215 String user = row.getString( "user" );
216 String role = row.getString( "role" );
217 String simpleUser = user.substring( 0, user.indexOf( "@" ) );
219 if ( isMechID( simpleUser ) )
223 else if ( rolesMap.get( simpleUser ) == null )
225 rolesMap.put( simpleUser, new ArrayList<UserRole>() );
227 UserRole newEntry = new UserRole();
228 newEntry.user = user;
229 newEntry.role = role;
231 rolesMap.get( simpleUser ).add( newEntry );
235 UserRole newEntry = new UserRole();
236 newEntry.user = user;
237 newEntry.role = role;
239 rolesMap.get( simpleUser ).add( newEntry );
242 env.debug().log( String.format( "\tUser: %s Role: %s", user, role ) );
246 env.info().log( String.format( "rows read: %d expiring: %d", total, flagged ) );
249 public void loadOwnersFromNS()
251 String query = "select name,admin,responsible from authz.ns" ;
253 env.info().log( "query: " + query );
255 Statement stmt = new SimpleStatement( query );
256 ResultSet results = session.execute(stmt);
258 Iterator<Row> iter = results.iterator();
259 while( iter.hasNext() )
261 Row row = iter.next();
262 Set<String> responsibles = row.getSet( "responsible", String.class );
264 for ( String user : responsibles )
266 env.info().log( String.format( "Found responsible %s", user ) );
267 String simpleUser = user.substring( 0, user.indexOf( "@" ) );
269 if ( isMechID( simpleUser ) )
273 else if ( ownersMap.get( simpleUser ) == null )
275 ownersMap.put( simpleUser, new ArrayList<NamespaceOwner>() );
277 NamespaceOwner newEntry = new NamespaceOwner();
278 newEntry.user = user;
279 newEntry.ns = row.getString( "name" );
280 newEntry.ownerCount = responsibles.size();
281 newEntry.responsible = true;
282 ownersMap.get( simpleUser ).add( newEntry );
286 NamespaceOwner newEntry = new NamespaceOwner();
287 newEntry.user = user;
288 newEntry.ns = row.getString( "name" );
289 newEntry.ownerCount = responsibles.size();
290 newEntry.responsible = true;
291 ownersMap.get( simpleUser ).add( newEntry );
294 Set<String> admins = row.getSet( "admin", String.class );
296 for ( String user : admins )
298 env.info().log( String.format( "Found admin %s", user ) );
299 String simpleUser = user.substring( 0, user.indexOf( "@" ) );
301 if ( isMechID( simpleUser ) )
305 else if ( ownersMap.get( simpleUser ) == null )
307 ownersMap.put( simpleUser, new ArrayList<NamespaceOwner>() );
309 NamespaceOwner newEntry = new NamespaceOwner();
310 newEntry.user = user;
311 newEntry.ns = row.getString( "name" );
312 newEntry.responsible = false;
313 newEntry.ownerCount = -1; //
314 ownersMap.get( simpleUser ).add( newEntry );
318 NamespaceOwner newEntry = new NamespaceOwner();
319 newEntry.user = user;
320 newEntry.ns = row.getString( "name" );
321 newEntry.responsible = false;
322 newEntry.ownerCount = -1; //
323 ownersMap.get( simpleUser ).add( newEntry );
331 * Processes the specified JobChange data file obtained from Webphone. Each line is
332 * read and processed and any fallout is written to the specified fallout file.
333 * If fallout file already exists it is deleted and a new one is created. A
334 * comparison of the supervisor id in the job data file is done against the one returned
335 * by the authz service and if the supervisor Id has changed then the record is updated
336 * using the authz service. An email is sent to the new supervisor to approve the roles
337 * assigned to the user.
339 * @param fileName - name of the file to process including its path
340 * @param falloutFileName - the file where the fallout entries have to be written
341 * @param validDate - the valid effective date when the user had moved to the new supervisor
344 public void processJobChangeDataFile(String fileName,
345 String falloutFileName, Date validDate) throws Exception
348 BufferedWriter writer = null;
352 env.info().log("Reading file: " + fileName );
354 FileInputStream fstream = new FileInputStream(fileName);
355 BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
359 while ((strLine = br.readLine()) != null) {
360 processLine( strLine, writer );
366 } catch (IOException e) {
367 env.error().log( "Error while reading from the input data file: " + e );
372 public void handleAdminChange( String user )
374 ArrayList<NamespaceOwner> val = ownersMap.get( user );
376 for ( NamespaceOwner r : val )
378 env.info().log( "handleAdminChange: " + user );
379 AuthzTrans trans = env.newTransNoAvg();
384 env.info().log( String.format( "delete from NS owner: %s, NS: %s, count: %s",
385 r.user, r.ns, r.ownerCount ) );
387 aspr.info( String.format( "action=DELETE_NS_OWNER, user=%s, ns=%s",
389 if ( r.ownerCount < 2 )
391 // send warning email to aaf-support, after this deletion, no owner for NS
392 ArrayList<String> toAddress = new ArrayList<String>();
393 toAddress.add( "XXX_EMAIL" );
395 env.warn().log( "removing last owner from namespace" );
397 Organization org = null;
398 org = getOrgFromID( myTrans, org, toAddress.get(0) );
400 env.info().log( "calling getOrgFromID with " + toAddress.get(0) );
406 aspr.info( String.format( "action=EMAIL_NO_OWNER_NS to=%s, user=%s, ns=%s",
407 toAddress.get(0), r.user, r.ns ) );
408 org.sendEmail( trans, toAddress,
409 new ArrayList<String>(),
410 String.format( "WARNING: no owners for AAF namespace '%s'", r.ns ), // subject:
411 String.format( "AAF recieved a jobchange notification for user %s who was the owner of the '%s' namespace. Please identify a new owner for this namespace and update AAF.", r.user, r.ns ), // body of msg
413 } catch (Exception e) {
414 env.error().log("calling sendEmail()");
421 env.error().log( "Failed getOrgFromID" );
427 env.info().log( String.format( "delete from NS admin: %s, NS: %s",
430 aspr.info( String.format( "action=DELETE_NS_ADMIN, user=%s, ns=%s",
434 String field = (r.responsible == true) ? "responsible" : "admin";
436 String query = String.format( "update authz.ns set %s = %s - {'%s'} where name = '%s'",
437 field, field, r.user, r.ns ) ;
438 env.info().log( "query: " + query );
439 Statement stmt = new SimpleStatement( query );
440 /*Row row = */session.execute(stmt).one();
442 String attribQuery = String.format( "delete from authz.ns_attrib where ns = '%s' AND type='%s' AND name='%s'",
443 r.ns, field, r.user);
444 env.info().log( "ns_attrib query: " + attribQuery);
445 Statement attribStmt = new SimpleStatement( attribQuery );
446 /*Row attribRow = */session.execute(attribStmt).one();
451 public void handleRoleChange( String user )
453 ArrayList<UserRole> val = rolesMap.get( user );
455 for ( UserRole r : val )
457 env.info().log( "handleRoleChange: " + user );
459 env.info().log( String.format( "delete from %s from user_role: %s",
462 aspr.info( String.format( "action=DELETE_FROM_ROLE, user=%s, role=%s",
466 String query = String.format( "delete from authz.user_role where user = '%s' and role = '%s'",
469 env.info().log( "query: " + query );
471 Statement stmt = new SimpleStatement( query );
472 /* Row row = */ session.execute(stmt).one();
477 public void handleCredChange( String user )
479 ArrayList<UserCred> val = credsMap.get( user );
481 for ( UserCred r : val )
483 env.info().log( "handleCredChange: " + user );
485 env.info().log( String.format( "delete user %s cred from ns: %s",
488 aspr.info( String.format( "action=DELETE_FROM_CRED, user=%s, ns=%s",
491 String query = String.format( "delete from authz.cred where id = '%s'",
494 env.info().log( "query: " + query );
496 Statement stmt = new SimpleStatement( query );
497 /*Row row = */session.execute(stmt).one();
503 public boolean processLine(String line, BufferedWriter writer) throws IOException
505 SimpleDateFormat sdfDate = new SimpleDateFormat("yyyyMMdd");
506 boolean errorFlag = false;
507 String errorMsg = "";
511 String[] phoneInfo = line.split( "\\|" );
513 if ((phoneInfo != null) && (phoneInfo.length >= 8)
514 && (!phoneInfo[0].startsWith("#")))
516 String user = phoneInfo[0];
517 String newSupervisor = phoneInfo[7];
518 Date effectiveDate = sdfDate.parse(phoneInfo[8].trim());
520 env.debug().log( String.format( "checking user: %s, newSupervisor: %s, date: %s",
521 user, newSupervisor, effectiveDate ) );
523 // Most important case, user is owner of a namespace
525 if ( ownersMap.get( user ) != null )
527 env.info().log( String.format( "Found %s as a namespace admin/owner", user ) );
528 handleAdminChange( user );
531 if ( credsMap.get( user ) != null )
533 env.info().log( String.format( "Found %s in cred table", user ) );
534 handleCredChange( user );
537 if ( rolesMap.get( user ) != null )
539 env.info().log( String.format( "Found %s in a role ", user ) );
540 handleRoleChange( user );
544 else if (phoneInfo[0].startsWith("#"))
550 env.warn().log("Can't parse. Skipping the line." + line);
553 } catch (Exception e) {
555 errorMsg = e.getMessage();
556 env.error().log( "Error while processing line:" + line + e );
560 env.info().log( "Fallout enrty being written for line:" + line );
561 writer.write(line + "|Failed to update supervisor for user:" + errorMsg + "\n");
568 public JobChange(AuthzTrans trans) throws APIException, IOException {
569 super( trans.env() );
571 session = cluster.connect();
574 public Organization getOrgFromID( AuthzTrans trans, Organization _org, String user ) {
575 Organization org = _org;
576 if ( org == null || ! user.endsWith( org.getRealm() ) ) {
577 int idx = user.lastIndexOf('.');
579 idx = user.lastIndexOf( '.', idx-1 );
584 org = OrganizationFactory.obtain( trans.env(), user.substring( idx+1 ) );
585 } catch (Exception e) {
586 trans.error().log(e,"Failure Obtaining Organization");
591 PrintStream fallout = null;
594 fallout= fallout(fallout, "Fallout");
595 fallout.print("INVALID_ID,");
596 fallout.println(user);
597 } catch (Exception e) {
598 env.error().log("Could not write to Fallout File",e);
606 public void dumpOwnersMap()
608 for ( Map.Entry<String, ArrayList<NamespaceOwner>> e : ownersMap.entrySet() )
610 String key = e.getKey();
611 ArrayList<NamespaceOwner> values = e.getValue();
613 env.info().log( "ns user: " + key );
615 for ( NamespaceOwner r : values )
617 env.info().log( String.format( "\tNS-user: %s, NS-name: %s, ownerCount: %d",
618 r.user, r.ns, r.ownerCount ) );
624 public void dumpRolesMap()
626 for ( Map.Entry<String, ArrayList<UserRole>> e : rolesMap.entrySet() )
628 String key = e.getKey();
629 ArrayList<UserRole> values = e.getValue();
631 env.info().log( "user: " + key );
633 for ( UserRole r : values )
635 env.info().log( String.format( "\trole-user: %s, role-name: %s",
640 public void dumpCredMap()
642 for ( Map.Entry<String, ArrayList<UserCred>> e : credsMap.entrySet() )
644 String key = e.getKey();
645 ArrayList<UserCred> values = e.getValue();
647 env.info().log( "user: " + key );
649 for ( UserCred r : values )
651 env.info().log( String.format( "\tcred-user: %s, ns: %s",
659 protected void run (AuthzTrans trans)
661 if ( acquireRunLock( this.getClass().getName() ) != 1 ) {
662 env.warn().log( "Cannot acquire run lock, exiting" );
667 // Map<String,EmailMsg> email = new HashMap<String,EmailMsg>();
671 String workingDir = System.getProperty("user.dir");
672 env.info().log( "Process jobchange file. PWD is " + workingDir );
674 loadUsersFromRoles();
682 String fname = getJobChangeDataFile();
686 env.warn().log("getJobChangedatafile returned null");
690 env.info().log("done with FTP");
692 processJobChangeDataFile( fname, "fallout", null );
696 // TODO Auto-generated catch block
701 } catch (IllegalArgumentException e) {
702 // TODO Auto-generated catch block
704 } catch (SecurityException e) {
705 // TODO Auto-generated catch block
711 private class EmailMsg {
712 private boolean urgent = false;
714 public Organization org;
715 public String summary;
722 public boolean getUrgent() {
723 return( this.urgent );
726 public void setUrgent( boolean val ) {
729 public void setOrg( Organization newOrg ) {
732 public Organization getOrg() {
738 protected void _close(AuthzTrans trans) {