bea3b5ec946aa67e329481ee2c21b8ed957d281b
[aaf/authz.git] / auth / auth-batch / src / main / java / org / onap / aaf / auth / batch / helpers / UserRole.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6  * ===========================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END====================================================
19  *
20  */
21
22 package org.onap.aaf.auth.batch.helpers;
23
24 import java.io.PrintStream;
25 import java.util.ArrayList;
26 import java.util.Date;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.SortedMap;
30 import java.util.TreeMap;
31
32 import org.onap.aaf.auth.batch.actions.URDelete;
33 import org.onap.aaf.auth.dao.cass.UserRoleDAO;
34 import org.onap.aaf.auth.dao.cass.UserRoleDAO.Data;
35 import org.onap.aaf.auth.env.AuthzTrans;
36 import org.onap.aaf.cadi.util.CSV;
37 import org.onap.aaf.misc.env.Env;
38 import org.onap.aaf.misc.env.TimeTaken;
39 import org.onap.aaf.misc.env.Trans;
40 import org.onap.aaf.misc.env.util.Chrono;
41
42 import com.datastax.driver.core.ResultSet;
43 import com.datastax.driver.core.Row;
44 import com.datastax.driver.core.Session;
45 import com.datastax.driver.core.SimpleStatement;
46 import com.datastax.driver.core.Statement;
47
48 public class UserRole implements Cloneable, CacheChange.Data  {
49
50     private static final String SEPARATOR = "\",\"";
51
52     // CACHE Calling
53     private static final String LOG_FMT = "%s UserRole - %s: %s-%s (%s, %s) expiring %s";
54     private static final String REPLAY_FMT = "%s|%s|%s|%s|%s\n";
55     private static final String DELETE_FMT = "# %s\n"+ REPLAY_FMT;
56
57     private static final List<UserRole> data = new ArrayList<>();
58     private static final SortedMap<String,List<UserRole>> byUser = new TreeMap<>();
59     private static final SortedMap<String,List<UserRole>> byRole = new TreeMap<>();
60     private static final CacheChange<UserRole> cache = new CacheChange<>();
61     private static PrintStream urDelete = System.out;
62     private static PrintStream urRecover = System.err;
63     private static int totalLoaded;
64     private int deleted;
65     private Data urdd;
66
67     public static final Creator<UserRole> v2_0_11 = new Creator<UserRole>() {
68         @Override
69         public UserRole create(Row row) {
70             return new UserRole(row.getString(0), row.getString(1), row.getString(2),row.getString(3),row.getTimestamp(4));
71         }
72
73         @Override
74         public String select() {
75             return "select user,role,ns,rname,expires from authz.user_role";
76         }
77     };
78
79     public UserRole(String user, String ns, String rname, Date expires) {    
80         urdd = new UserRoleDAO.Data();
81         urdd.user = user;
82         urdd.role = ns + '.' + rname;
83         urdd.ns = ns;
84         urdd.rname = rname;
85         urdd.expires = expires;
86     }
87
88     public UserRole(String user, String role, String ns, String rname, Date expires) {
89         urdd = new UserRoleDAO.Data();
90         urdd.user = user;
91         urdd.role = role;
92         urdd.ns = ns;
93         urdd.rname = rname;
94         urdd.expires = expires;
95     }
96
97     public static List<UserRole> getData() {
98         return data;
99     }
100
101     public static SortedMap<String, List<UserRole>> getByUser() {
102         return byUser;
103     }
104
105     public static SortedMap<String, List<UserRole>> getByRole() {
106         return byRole;
107     }
108
109     public static void load(Trans trans, Session session, Creator<UserRole> creator) {
110         load(trans,session,creator,null,new DataLoadVisitor());
111     }
112     
113     public static void load(Trans trans, Session session, Creator<UserRole> creator, Visitor<UserRole> visitor ) {
114         load(trans,session,creator,null,visitor);
115     }
116
117     public static void loadOneRole(Trans trans, Session session, Creator<UserRole> creator, String role, Visitor<UserRole> visitor) {
118         load(trans,session,creator,"role='" + role +"' ALLOW FILTERING;",visitor);
119     }
120     
121     public static void loadOneUser(Trans trans, Session session, Creator<UserRole> creator, String user, Visitor<UserRole> visitor ) {
122         load(trans,session,creator,"role='"+ user +"';",visitor);
123     }
124
125     private static void load(Trans trans, Session session, Creator<UserRole> creator, String where, Visitor<UserRole> visitor) {
126         String query = creator.query(where);
127         trans.info().log( "query: " + query );
128         TimeTaken tt = trans.start("Read UserRoles", Env.REMOTE);
129
130         ResultSet results;
131         try {
132             Statement stmt = new SimpleStatement( query );
133             results = session.execute(stmt);
134         } finally {
135             tt.done();
136         }
137         try {
138             tt = trans.start("Load UserRole", Env.SUB);
139             try {
140                 iterateResults(creator, results.iterator(), visitor);
141             } finally {
142                 tt.done();
143             }
144         } finally {
145             trans.info().log("Loaded",totalLoaded,"UserRoles");
146         }
147     }
148
149     private static void iterateResults(Creator<UserRole> creator, Iterator<Row> iter, Visitor<UserRole> visit ) {
150         Row row;
151         while (iter.hasNext()) {
152             ++totalLoaded;
153             row = iter.next();
154             UserRole ur = creator.create(row);
155             visit.visit(ur);
156         }
157     }
158
159     public static class DataLoadVisitor implements Visitor<UserRole> {
160                 @Override
161                 public void visit(UserRole ur) {
162             data.add(ur);
163
164             List<UserRole> lur = byUser.get(ur.urdd.user);
165             if (lur==null) {
166                 lur = new ArrayList<>();
167                 byUser.put(ur.urdd.user, lur);
168             }
169             lur.add(ur);
170
171             lur = byRole.get(ur.urdd.role);
172             if (lur==null) {
173                 lur = new ArrayList<>();
174                 byRole.put(ur.urdd.role, lur);
175             }
176             lur.add(ur);
177                 }
178     }
179     
180     public int totalLoaded() {
181         return totalLoaded;
182     }
183     
184     public int deleted() {
185         return deleted;
186     }
187     
188     @Override
189     public void expunge() {
190         data.remove(this);
191         
192         List<UserRole> lur = byUser.get(urdd.user);
193         if (lur!=null) {
194             lur.remove(this);
195         }
196     
197         lur = byRole.get(urdd.role);
198         if (lur!=null) {
199             lur.remove(this);
200         }
201     }
202     
203     public static void setDeleteStream(PrintStream ds) {
204         urDelete = ds;
205     }
206
207     public static void setRecoverStream(PrintStream ds) {
208         urRecover = ds;
209     }
210
211     public static long count(Trans trans, Session session) {
212         String query = "select count(*) from authz.user_role LIMIT 1000000;";
213         trans.info().log( "query: " + query );
214         TimeTaken tt = trans.start("Count Namespaces", Env.REMOTE);
215         ResultSet results;
216         try {
217             Statement stmt = new SimpleStatement(query).setReadTimeoutMillis(12000);
218             results = session.execute(stmt);
219             return results.one().getLong(0);
220         } finally {
221             tt.done();
222         }
223     }
224
225     public UserRoleDAO.Data urdd() {
226         return urdd;
227     }
228     
229     public String user() {
230         return urdd.user;
231     }
232     
233     public String role() {
234         return urdd.role;
235     }
236     
237     public String ns() {
238         return urdd.ns;
239     }
240     
241     public String rname() {
242         return urdd.rname;
243     }
244     
245     public Date expires() {
246         return urdd.expires;
247     }
248     
249     public void expires(Date time) {
250         urdd.expires = time;
251     }
252
253     public String toString() {
254         return "\"" + urdd.user + SEPARATOR + urdd.role + SEPARATOR + urdd.ns + SEPARATOR + urdd.rname + SEPARATOR
255             + Chrono.dateOnlyStamp(urdd.expires);
256     }
257
258     public static UserRole get(String u, String r) {
259         List<UserRole> lur = byUser.get(u);
260         if (lur!=null) {
261             for (UserRole ur : lur) {
262
263                 if (ur.urdd.role.equals(r)) {
264                     return ur;
265                 }
266             }
267         }
268         return null;
269     }
270
271     // SAFETY - DO NOT DELETE USER ROLES DIRECTLY FROM BATCH FILES!!!
272     // We write to a file, and validate.  If the size is iffy, we email Support
273     public void delayDelete(AuthzTrans trans, String text, boolean dryRun) {
274         String dt = Chrono.dateTime(urdd.expires);
275         if (dryRun) {
276             trans.info().printf(LOG_FMT,text,"Would Delete",urdd.user,urdd.role,urdd.ns,urdd.rname,dt);
277         } else {
278             trans.info().printf(LOG_FMT,text,"Staged Deletion",urdd.user,urdd.role,urdd.ns,urdd.rname,dt);
279         }
280         urDelete.printf(DELETE_FMT,text,urdd.user,urdd.role,dt,urdd.ns,urdd.rname);
281         urRecover.printf(REPLAY_FMT,urdd.user,urdd.role,dt,urdd.ns,urdd.rname);
282
283         cache.delayedDelete(this);
284         ++deleted;
285     }
286     
287
288     /**
289      * Calls expunge() for all deleteCached entries
290      */
291     public static void resetLocalData() {
292         cache.resetLocalData();
293     }
294     
295     public static int sizeForDeletion() {
296         return cache.cacheSize();
297     }
298
299     public static boolean pendingDelete(UserRole ur) {
300         return cache.contains(ur);
301     }
302
303     public static void actuateDeletionNow(AuthzTrans trans, URDelete directDel) {
304         for (UserRole ur : cache.getRemoved()) {
305             directDel.exec(trans, ur, "Actuating UserRole Deletion");
306         }
307         cache.getRemoved().clear();
308         cache.resetLocalData();
309     }
310
311     public void row(final CSV.Writer csvw) {
312         csvw.row("ur",user(),ns(),rname(),Chrono.dateOnlyStamp(expires()),expires().getTime());
313     }
314     
315     public static void batchDelete(StringBuilder sb, List<String> row) {
316         sb.append("DELETE from authz.user_role WHERE user='");
317         sb.append(row.get(1));
318         sb.append("' AND role='");
319         sb.append(row.get(2));
320         sb.append('.');
321         sb.append(row.get(3));
322         sb.append("';\n");
323     }
324
325     public static void batchExtend(StringBuilder sb, List<String> row, String newDate ) {
326         sb.append("UPDATE authz.user_role SET expires='");
327         sb.append(newDate);
328         sb.append("' WHERE user='");
329         sb.append(row.get(1));
330         sb.append("' AND role='");
331         sb.append(row.get(2));
332         sb.append('.');
333         sb.append(row.get(3));
334         sb.append("';\n");
335     }
336     
337         public static String histMemo(String fmt, List<String> row) {
338                 return String.format(fmt, row.get(1),row.get(2)+'.'+row.get(3), row.get(4));
339         }
340
341         public static String histSubject(List<String> row) {
342                 return row.get(1) + '|' + row.get(2)+'.'+row.get(3);    
343         }
344 }