Batch work and client
[aaf/authz.git] / auth / auth-batch / src / main / java / org / onap / aaf / auth / batch / helpers / Cred.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.util.ArrayList;
25 import java.util.Date;
26 import java.util.GregorianCalendar;
27 import java.util.HashSet;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Set;
31 import java.util.TreeMap;
32
33 import org.onap.aaf.auth.dao.cass.CredDAO;
34 import org.onap.aaf.auth.dao.hl.Question;
35 import org.onap.aaf.cadi.util.CSV;
36 import org.onap.aaf.misc.env.Env;
37 import org.onap.aaf.misc.env.TimeTaken;
38 import org.onap.aaf.misc.env.Trans;
39 import org.onap.aaf.misc.env.util.Chrono;
40
41 import com.datastax.driver.core.ResultSet;
42 import com.datastax.driver.core.Row;
43 import com.datastax.driver.core.Session;
44 import com.datastax.driver.core.SimpleStatement;
45 import com.datastax.driver.core.Statement;
46
47 public class Cred  {
48     public static final TreeMap<String,Cred> data = new TreeMap<>();
49     public static final TreeMap<String,List<Cred>> byNS = new TreeMap<>();
50
51     public final String id;
52     public final List<Instance> instances;
53     public final String ns;
54     
55     public Cred(String id) {
56         this.id = id;
57         instances = new ArrayList<>();
58         ns=Question.domain2ns(id);
59     }
60     
61     public static class Instance {
62         public final int type;
63         public final Date expires,written;
64         public final Integer other;
65         public final String tag;
66         public List<Note> notes;
67
68         
69         public Instance(int type, Date expires, Integer other, long written, String tag) {
70             this.type = type;
71             this.expires = expires;
72             this.other = other;
73             this.written = new Date(written);
74             this.tag = tag;
75         }
76         
77         /**
78          * Usually returns Null...
79          * @return
80          */
81         public List<Note> notes() {
82                 return notes;
83         }
84         
85         public void addNote(int level, String note) {
86                 if(notes==null) {
87                         notes=new ArrayList<>();
88                 } 
89                 notes.add(new Note(level,note));
90         }
91         
92         public String toString() {
93                 return expires.toString() + ": " + type + ' ' + tag;
94         }
95     }
96     
97     public static class Note {
98         public final int level;
99         public final String note;
100         
101         public Note(int level, String note) {
102                 this.level = level;
103                 this.note = note;
104         }
105     }
106     public Date last(final int ... types) {
107         Date last = null;
108         for (Instance i : instances) {
109             if (types.length>0) { // filter by types, if requested
110                 boolean quit = true;
111                 for (int t : types) {
112                     if (t==i.type) {
113                         quit=false;
114                         break;
115                     }
116                 }
117                 if (quit) {
118                     continue;
119                 }
120             }
121             if (last==null || i.expires.after(last)) {
122                 last = i.expires;
123             }
124         }
125         return last;
126     }
127
128     
129     public Set<Integer> types() {
130         Set<Integer> types = new HashSet<>();
131         for (Instance i : instances) {
132             types.add(i.type);
133         }
134         return types;
135     }
136
137     public static void load(Trans trans, Session session, int ... types ) {
138         load(trans, session,"select id, type, expires, other, writetime(cred), tag from authz.cred;",types);
139         
140     }
141
142     public static void loadOneNS(Trans trans, Session session, String ns,int ... types ) {
143         load(trans, session,"select id, type, expires, other, writetime(cred), tag from authz.cred WHERE ns='" + ns + "';");
144     }
145
146     private static void load(Trans trans, Session session, String query, int ...types) {
147
148         trans.info().log( "query: " + query );
149         TimeTaken tt = trans.start("Read Creds", Env.REMOTE);
150        
151         ResultSet results;
152         try {
153             Statement stmt = new SimpleStatement( query );
154             results = session.execute(stmt);
155         } finally {
156             tt.done();
157         }
158         int count = 0;
159         try {
160             Iterator<Row> iter = results.iterator();
161             Row row;
162             tt = trans.start("Load Credentials", Env.SUB);
163             try {
164                 while (iter.hasNext()) {
165                     ++count;
166                     row = iter.next();
167                     int type = row.getInt(1);
168                     if (types.length>0) { // filter by types, if requested
169                         boolean hastype = false;
170                         for (int t : types) {
171                             if (t==type) {
172                                 hastype=true;
173                                 break;
174                             }
175                         }
176                         if (!hastype) {
177                             continue;
178                         }
179                     }
180                     add(row.getString(0), row.getInt(1),row.getTimestamp(2),row.getInt(3),row.getLong(4),
181                                 row.getString(5));
182                 }
183             } finally {
184                 tt.done();
185             }
186         } finally {
187             trans.info().log("Found",count,"creds");
188         }
189     }
190
191     public static void add(
192                 final String id, 
193                 final int type,
194                 final Date timestamp,
195                 final int other,
196                 final long written,
197                 final String tag
198                 ) {
199         Cred cred = data.get(id);
200         if (cred==null) {
201             cred = new Cred(id);
202             data.put(id, cred);
203         }
204         cred.instances.add(new Instance(type, timestamp, other, written/1000,tag));
205         
206         List<Cred> lscd = byNS.get(cred.ns);
207         if (lscd==null) {
208             byNS.put(cred.ns, (lscd=new ArrayList<>()));
209         }
210         boolean found = false;
211         for (Cred c : lscd) {
212             if (c.id.equals(cred.id)) {
213                 found=true;
214                 break;
215             }
216         }
217         if (!found) {
218             lscd.add(cred);
219         }
220         }
221
222
223         /** 
224      * Count entries in Cred data.
225      * Note, as opposed to other methods, need to load the whole cred table for the Types.
226      * @param numbuckets 
227      * @return
228      */
229     public static CredCount count(int numbuckets) {
230         CredCount cc = new CredCount(numbuckets);
231         for (Cred c : data.values()) {
232             for (Instance ci : c.instances) {
233                 cc.inc(ci.type,ci.written, ci.expires);
234             }
235         }
236         return cc;
237     }
238
239     public static class CredCount {
240         public int raw[];
241         public int basic_auth[];
242         public int basic_auth_256[];
243         public int cert[];
244         public int x509Added[];
245         public int x509Expired[];
246         public Date dates[];
247         
248         public CredCount(int numbuckets) {
249             raw = new int[numbuckets];
250             basic_auth = new int[numbuckets];
251             basic_auth_256 = new int[numbuckets];
252             cert = new int[numbuckets];
253             x509Added = new int[numbuckets];
254             x509Expired = new int[numbuckets];
255             dates = new Date[numbuckets];
256             GregorianCalendar gc = new GregorianCalendar();
257             dates[0]=gc.getTime(); // now
258             gc.set(GregorianCalendar.DAY_OF_MONTH, 1);
259             gc.set(GregorianCalendar.HOUR, 0);
260             gc.set(GregorianCalendar.MINUTE, 0);
261             gc.set(GregorianCalendar.SECOND,0);
262             gc.set(GregorianCalendar.MILLISECOND,0);
263             gc.add(GregorianCalendar.MILLISECOND, -1); // last milli of month
264             for (int i=1;i<numbuckets;++i) {
265                 dates[i] = gc.getTime();
266                 gc.add(GregorianCalendar.MONTH, -1);
267             }
268             
269         }
270         
271         public void inc(int type, Date start, Date expires) {
272             for (int i=0;i<dates.length-1;++i) {
273                 if (start.before(dates[i])) {
274                     if (type==CredDAO.CERT_SHA256_RSA) {
275                         if (start.after(dates[i+1])) {
276                             ++x509Added[i];
277                         }
278                     }
279                     if (expires.after(dates[i])) {
280                         switch(type) {
281                             case CredDAO.RAW:
282                                 ++raw[i];
283                                 break;
284                             case CredDAO.BASIC_AUTH:
285                                 ++basic_auth[i];
286                                 break;
287                             case CredDAO.BASIC_AUTH_SHA256:
288                                 ++basic_auth_256[i];
289                                 break;
290                             case CredDAO.CERT_SHA256_RSA:
291                                 ++cert[i];
292                                 break;
293                         }
294                     }
295                 }
296             }
297         }
298
299         public long authCount(int idx) {
300             return (long)basic_auth[idx]+basic_auth_256[idx];
301         }
302         
303         public long x509Count(int idx) {
304             return cert[idx];
305         }
306
307     }
308     
309     public void row(final CSV.Writer csvw, final Instance inst) {
310         csvw.row("cred",id,ns,Integer.toString(inst.type),Chrono.dateOnlyStamp(inst.expires),
311                         inst.expires.getTime(),inst.tag);
312     }
313
314     public void row(final CSV.Writer csvw, final Instance inst, final String reason) {
315         csvw.row("cred",id,ns,Integer.toString(inst.type),Chrono.dateOnlyStamp(inst.expires),
316                         inst.expires.getTime(),inst.tag,reason);
317     }
318
319
320     public static void batchDelete(StringBuilder sb, List<String> row) {
321         sb.append("DELETE from authz.cred WHERE id='");
322         sb.append(row.get(1));
323         sb.append("' AND type=");
324         sb.append(Integer.parseInt(row.get(3)));
325         // Note: We have to work with long, because Expires is part of Key... can't easily do date.
326         sb.append(" AND expires=dateof(maxtimeuuid(");
327         sb.append(row.get(5));
328         sb.append("));\n");
329         }
330
331         public String toString() {
332         StringBuilder sb = new StringBuilder(id);
333         sb.append('[');
334         for (Instance i : instances) {
335             sb.append('{');
336             sb.append(i.type);
337             sb.append(",\"");
338             sb.append(i.expires);
339             sb.append("\"}");
340         }
341         sb.append(']');
342         return sb.toString();
343     }
344
345     /* (non-Javadoc)
346      * @see java.lang.Object#hashCode()
347      */
348     @Override
349     public int hashCode() {
350         return id.hashCode();
351     }
352
353     /* (non-Javadoc)
354      * @see java.lang.Object#equals(java.lang.Object)
355      */
356     @Override
357     public boolean equals(Object obj) {
358         return id.equals(obj);
359     }
360
361
362         public static String histSubject(List<String> row) {
363                 return row.get(1);
364         }
365
366
367         public static String histMemo(String fmt, String orgName, List<String> row) {
368                 String reason;
369                 if(row.size()>5) { // Reason included
370                         reason = row.get(5);
371                 } else {
372                         reason = String.format(fmt, row.get(1),orgName,row.get(4));
373                 }
374                 return reason;
375         }
376 }