Merge "major-Extract the assignment out of this expression"
[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  * Modifications Copyright (C) 2019 IBM.
7  * ===========================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END====================================================
20  *
21  */
22
23 package org.onap.aaf.auth.batch.helpers;
24
25 import java.text.SimpleDateFormat;
26 import java.util.ArrayList;
27 import java.util.Date;
28 import java.util.GregorianCalendar;
29 import java.util.HashSet;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.Set;
33 import java.util.TreeMap;
34
35 import org.onap.aaf.auth.dao.cass.CredDAO;
36 import org.onap.aaf.auth.dao.hl.Question;
37 import org.onap.aaf.cadi.util.CSV;
38 import org.onap.aaf.misc.env.Env;
39 import org.onap.aaf.misc.env.TimeTaken;
40 import org.onap.aaf.misc.env.Trans;
41 import org.onap.aaf.misc.env.util.Chrono;
42
43 import com.datastax.driver.core.ResultSet;
44 import com.datastax.driver.core.Row;
45 import com.datastax.driver.core.Session;
46 import com.datastax.driver.core.SimpleStatement;
47 import com.datastax.driver.core.Statement;
48
49 public class Cred  {
50     public static final TreeMap<String,Cred> data = new TreeMap<>();
51     public static final TreeMap<String,List<Cred>> byNS = new TreeMap<>();
52
53     public final String id;
54     public final List<Instance> instances;
55     public final String ns;
56     
57     public Cred(String id) {
58         this.id = id;
59         instances = new ArrayList<>();
60         ns=Question.domain2ns(id);
61     }
62     
63     public static class Instance {
64         public final int type;
65         public final Date expires,written;
66         public final Integer other;
67         public final String tag;
68         public List<Note> notes;
69
70         
71         public Instance(int type, Date expires, Integer other, long written, String tag) {
72             this.type = type;
73             this.expires = expires;
74             this.other = other;
75             this.written = new Date(written);
76             this.tag = tag;
77         }
78         
79         /**
80          * Usually returns Null...
81          * @return
82          */
83         public List<Note> notes() {
84             return notes;
85         }
86         
87         public void addNote(int level, String note) {
88             if(notes==null) {
89                 notes=new ArrayList<>();
90             } 
91             notes.add(new Note(level,note));
92         }
93         
94         public String toString() {
95             return expires.toString() + ": " + type + ' ' + tag;
96         }
97     }
98     
99     public static class Note {
100         public final int level;
101         public final String note;
102         
103         public Note(int level, String note) {
104             this.level = level;
105             this.note = note;
106         }
107     }
108     public Date last(final int ... types) {
109         Date last = null;
110         for (Instance i : instances) {
111             if (types.length>0) { // filter by types, if requested
112                 boolean quit = true;
113                 for (int t : types) {
114                     if (t==i.type) {
115                         quit=false;
116                         break;
117                     }
118                 }
119                 if (quit) {
120                     continue;
121                 }
122             }
123             if (last==null || i.expires.after(last)) {
124                 last = i.expires;
125             }
126         }
127         return last;
128     }
129
130     
131     public Set<Integer> types() {
132         Set<Integer> types = new HashSet<>();
133         for (Instance i : instances) {
134             types.add(i.type);
135         }
136         return types;
137     }
138
139     public static void load(Trans trans, Session session, int ... types ) {
140         load(trans, session,"select id, type, expires, other, writetime(cred), tag from authz.cred;",types);
141     }
142
143     public static void loadOneNS(Trans trans, Session session, String ns,int ... types ) {
144         load(trans, session,"select id, type, expires, other, writetime(cred), tag from authz.cred WHERE ns='" + ns + "';", types);
145     }
146
147     private static void load(Trans trans, Session session, String query, int ...types) {
148
149         trans.info().log( "query: " + query );
150         TimeTaken tt = trans.start("Read Creds", Env.REMOTE);
151        
152         ResultSet results;
153         try {
154             Statement stmt = new SimpleStatement( query );
155             results = session.execute(stmt);
156         } finally {
157             tt.done();
158         }
159         int count = 0;
160         try {
161             Iterator<Row> iter = results.iterator();
162             Row row;
163             tt = trans.start("Load Credentials", Env.SUB);
164             try {
165                 while (iter.hasNext()) {
166                     ++count;
167                     row = iter.next();
168                     int type = row.getInt(1);
169                     if (types.length>0) { // filter by types, if requested
170                         boolean hastype = false;
171                         for (int t : types) {
172                             if (t==type) {
173                                 hastype=true;
174                                 break;
175                             }
176                         }
177                         if (!hastype) {
178                             continue;
179                         }
180                     }
181                     add(row.getString(0), row.getInt(1),row.getTimestamp(2),row.getInt(3),row.getLong(4),
182                             row.getString(5));
183                 }
184             } finally {
185                 tt.done();
186             }
187         } finally {
188             trans.info().log("Found",count,"creds");
189         }
190     }
191
192     public static void add(
193             final String id, 
194             final int type,
195             final Date timestamp,
196             final int other,
197             final long written,
198             final String tag
199             ) {
200         Cred cred = data.get(id);
201         if (cred==null) {
202             cred = new Cred(id);
203             data.put(id, cred);
204         }
205         cred.instances.add(new Instance(type, timestamp, other, written/1000,tag));
206         
207         List<Cred> lscd = byNS.get(cred.ns);    
208         if (lscd==null) {
209                 lscd=new ArrayList<>();
210             byNS.put(cred.ns,lscd);
211         }
212         boolean found = false;
213         for (Cred c : lscd) {
214             if (c.id.equals(cred.id)) {
215                 found=true;
216                 break;
217             }
218         }
219         if (!found) {
220             lscd.add(cred);
221         }
222     }
223
224
225     /** 
226      * Count entries in Cred data.
227      * Note, as opposed to other methods, need to load the whole cred table for the Types.
228      * @param numbuckets 
229      * @return
230      */
231     public static CredCount count(int numbuckets) {
232         CredCount cc = new CredCount(numbuckets);
233         for (Cred c : data.values()) {
234             for (Instance ci : c.instances) {
235                 cc.inc(ci.type,ci.written, ci.expires);
236             }
237         }
238         return cc;
239     }
240
241     public static class CredCount {
242         public int raw[];
243         public int basic_auth[];
244         public int basic_auth_256[];
245         public int cert[];
246         public int x509Added[];
247         public int x509Expired[];
248         public Date dates[];
249         
250         public CredCount(int numbuckets) {
251             raw = new int[numbuckets];
252             basic_auth = new int[numbuckets];
253             basic_auth_256 = new int[numbuckets];
254             cert = new int[numbuckets];
255             x509Added = new int[numbuckets];
256             x509Expired = new int[numbuckets];
257             dates = new Date[numbuckets];
258             GregorianCalendar gc = new GregorianCalendar();
259             dates[0]=gc.getTime(); // now
260             gc.set(GregorianCalendar.DAY_OF_MONTH, 1);
261             gc.set(GregorianCalendar.HOUR, 0);
262             gc.set(GregorianCalendar.MINUTE, 0);
263             gc.set(GregorianCalendar.SECOND,0);
264             gc.set(GregorianCalendar.MILLISECOND,0);
265             gc.add(GregorianCalendar.MILLISECOND, -1); // last milli of month
266             for (int i=1;i<numbuckets;++i) {
267                 dates[i] = gc.getTime();
268                 gc.add(GregorianCalendar.MONTH, -1);
269             }
270             
271         }
272         
273         public void inc(int type, Date start, Date expires) {
274             for (int i=0;i<dates.length-1;++i) {
275                 if (start.before(dates[i])) {
276                     if ((type==CredDAO.CERT_SHA256_RSA)&&(start.after(dates[i+1]))) {
277                             ++x509Added[i];
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     static SimpleDateFormat sdf =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss+SSSS");
320     public static void batchDelete(StringBuilder sb, List<String> row) {
321         Long l = Long.parseLong(row.get(5));
322         String date = sdf.format(new Date(l));
323         sb.append("DELETE from authz.cred WHERE id='");
324         sb.append(row.get(1));
325         sb.append("' AND type=");
326         sb.append(Integer.parseInt(row.get(3)));
327         // Note: We have to work with long, because Expires is part of Key... can't easily do date.
328         sb.append(" AND expires='");
329         sb.append(date);
330         sb.append("';\n");
331 //        sb.append(" AND expires=dateof(maxtimeuuid(");
332 //        sb.append(row.get(5));
333 //        sb.append("));\n");
334         
335     }
336
337     public String toString() {
338         StringBuilder sb = new StringBuilder(id);
339         sb.append('[');
340         for (Instance i : instances) {
341             sb.append('{');
342             sb.append(i.type);
343             sb.append(",\"");
344             sb.append(i.expires);
345             sb.append("\"}");
346         }
347         sb.append(']');
348         return sb.toString();
349     }
350
351     /* (non-Javadoc)
352      * @see java.lang.Object#hashCode()
353      */
354     @Override
355     public int hashCode() {
356         return id.hashCode();
357     }
358
359     /* (non-Javadoc)
360      * @see java.lang.Object#equals(java.lang.Object)
361      */
362     @Override
363     public boolean equals(Object obj) {
364         return id.equals(obj);
365     }
366
367
368     public static String histSubject(List<String> row) {
369         return row.get(1);
370     }
371
372
373     public static String histMemo(String fmt, String orgName, List<String> row) {
374         String reason;
375         if(row.size()>5) { // Reason included
376             reason = row.get(5);
377         } else {
378             reason = String.format(fmt, row.get(1),orgName,row.get(4));
379         }
380         return reason;
381     }
382
383
384     public static void clear() {
385         data.clear();
386         byNS.clear();
387     }
388 }