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) {
277                         if (start.after(dates[i+1])) {
278                             ++x509Added[i];
279                         }
280                     }
281                     if (expires.after(dates[i])) {
282                         switch(type) {
283                             case CredDAO.RAW:
284                                 ++raw[i];
285                                 break;
286                             case CredDAO.BASIC_AUTH:
287                                 ++basic_auth[i];
288                                 break;
289                             case CredDAO.BASIC_AUTH_SHA256:
290                                 ++basic_auth_256[i];
291                                 break;
292                             case CredDAO.CERT_SHA256_RSA:
293                                 ++cert[i];
294                                 break;
295                         }
296                     }
297                 }
298             }
299         }
300
301         public long authCount(int idx) {
302             return (long)basic_auth[idx]+basic_auth_256[idx];
303         }
304         
305         public long x509Count(int idx) {
306             return cert[idx];
307         }
308
309     }
310     
311     public void row(final CSV.Writer csvw, final Instance inst) {
312         csvw.row("cred",id,ns,Integer.toString(inst.type),Chrono.dateOnlyStamp(inst.expires),
313                 inst.expires.getTime(),inst.tag);
314     }
315
316     public void row(final CSV.Writer csvw, final Instance inst, final String reason) {
317         csvw.row("cred",id,ns,Integer.toString(inst.type),Chrono.dateOnlyStamp(inst.expires),
318                 inst.expires.getTime(),inst.tag,reason);
319     }
320
321     static SimpleDateFormat sdf =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss+SSSS");
322     public static void batchDelete(StringBuilder sb, List<String> row) {
323         Long l = Long.parseLong(row.get(5));
324         String date = sdf.format(new Date(l));
325         sb.append("DELETE from authz.cred WHERE id='");
326         sb.append(row.get(1));
327         sb.append("' AND type=");
328         sb.append(Integer.parseInt(row.get(3)));
329         // Note: We have to work with long, because Expires is part of Key... can't easily do date.
330         sb.append(" AND expires='");
331         sb.append(date);
332         sb.append("';\n");
333 //        sb.append(" AND expires=dateof(maxtimeuuid(");
334 //        sb.append(row.get(5));
335 //        sb.append("));\n");
336         
337     }
338
339     public String toString() {
340         StringBuilder sb = new StringBuilder(id);
341         sb.append('[');
342         for (Instance i : instances) {
343             sb.append('{');
344             sb.append(i.type);
345             sb.append(",\"");
346             sb.append(i.expires);
347             sb.append("\"}");
348         }
349         sb.append(']');
350         return sb.toString();
351     }
352
353     /* (non-Javadoc)
354      * @see java.lang.Object#hashCode()
355      */
356     @Override
357     public int hashCode() {
358         return id.hashCode();
359     }
360
361     /* (non-Javadoc)
362      * @see java.lang.Object#equals(java.lang.Object)
363      */
364     @Override
365     public boolean equals(Object obj) {
366         return id.equals(obj);
367     }
368
369
370     public static String histSubject(List<String> row) {
371         return row.get(1);
372     }
373
374
375     public static String histMemo(String fmt, String orgName, List<String> row) {
376         String reason;
377         if(row.size()>5) { // Reason included
378             reason = row.get(5);
379         } else {
380             reason = String.format(fmt, row.get(1),orgName,row.get(4));
381         }
382         return reason;
383     }
384
385
386     public static void clear() {
387         data.clear();
388         byNS.clear();
389     }
390 }