e6942f09bbc43f7f363d2f1795cca26c99553f7a
[aaf/authz.git] / auth / auth-batch / src / main / java / org / onap / aaf / auth / batch / helpers / LastNotified.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6  * ===========================================================================
7  * Modifications Copyright (C) 2019 IBM.
8  * ===========================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END====================================================
21  *
22  */
23 package org.onap.aaf.auth.batch.helpers;
24
25 import java.security.cert.X509Certificate;
26 import java.util.Date;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.TreeMap;
32
33 import org.onap.aaf.auth.batch.helpers.Cred.Instance;
34 import org.onap.aaf.auth.batch.helpers.ExpireRange.Range;
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.Split;
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 LastNotified {
48         private Map<String,Date> lastNotified = new TreeMap<>();
49         private Session session;
50         public static final Date NEVER = new Date(0);
51         private static final String SELECT = "SELECT user,target,key,last FROM authz.notified";
52         
53         public LastNotified(Session session) {
54                 this.session = session;
55         }
56         
57         public void add(Set<String> users) {
58                 StringBuilder query = new StringBuilder();
59                 startQuery(query);
60                 int cnt = 0;
61         for(String user : users) {
62                 if(++cnt>1) {
63                         query.append(',');
64                 }
65                 query.append('\'');
66                 query.append(user);
67                 query.append('\'');
68                 if(cnt>=30) {
69                         endQuery(query);
70                         add(session.execute(query.toString()),lastNotified, (x,y) -> false);
71                         query.setLength(0);
72                         startQuery(query);
73                         cnt=0;
74                 }
75         }
76         if(cnt>0) {
77                 endQuery(query);
78                         add(session.execute(query.toString()),lastNotified, (x,y) -> false);
79         }
80         }
81
82         /**
83          * Note: target_key CAN also contain a Pipe.
84          * 
85          * @param user
86          * @param target
87          * @param targetkey
88          * @return
89          */
90         public Date lastNotified(String user, String target, String targetkey) {
91                 String key = user + '|' + target + '|' + (targetkey==null?"":targetkey);
92                 return lastNotified(key);
93         }
94         
95         public Date lastNotified(String key) {
96                 Date d = lastNotified.get(key);
97                 return d==null?NEVER:d;
98         }
99         
100         private Date add(ResultSet result, Map<String, Date> lastNotified, MarkDelete md) {
101                 Date last = null;
102                 Row r;
103         for(Iterator<Row> iter = result.iterator(); iter.hasNext();) {
104                 r = iter.next();
105                 String ttKey = r.getString(1) + '|' +
106                                            r.getString(2);
107  
108                 String fullKey = r.getString(0) + '|' +
109                                          ttKey;
110                 last=r.getTimestamp(3);
111                 if(!md.process(fullKey, last)) {
112                         lastNotified.put(fullKey, last);
113                         Date d = lastNotified.get(ttKey);
114                         if(d==null || d.after(last)) { // put most recent, if different
115                                 lastNotified.put(ttKey, last);
116                         }
117                 }
118         }
119         return last;
120         }
121         
122         private interface MarkDelete {
123                 boolean process(String fullKey, Date last);
124         }
125
126         private void startQuery(StringBuilder query) {
127                 query.append(SELECT + " WHERE user in (");
128         }
129
130         private void endQuery(StringBuilder query) {
131                 query.append(");");
132         }
133
134         public void update(StringBuilder query,String user, String target, String key) {
135                 query.append("UPDATE authz.notified SET last=dateof(now()) WHERE user='");
136                 query.append(user);
137                 query.append("' AND target='");
138                 query.append(target);
139                 query.append("' AND key='");
140                 query.append(key);
141                 query.append("';\n");
142         }
143
144     public LastNotified loadAll(Trans trans, final Range delRange, final CSV.Writer cw) {
145         trans.debug().log( "query: ",SELECT );
146         TimeTaken tt = trans.start("Read all LastNotified", Env.REMOTE);
147
148         ResultSet results;
149         try {
150             Statement stmt = new SimpleStatement( SELECT );
151             results = session.execute(stmt);
152             add(results,lastNotified, (fullKey, last) ->  {
153                 if(delRange.inRange(last)) {
154                         String[] params = Split.splitTrim('|', fullKey,3);
155                         if(params.length==3) {
156                                 cw.row("notified",params[0],params[1],params[2]);
157                                 return true;
158                         }
159                 }
160                 return false;
161             });
162         } finally {
163             tt.done();
164         }
165         return this;
166     }
167
168         public static String newKey(UserRole ur) {
169                 return "ur|" + ur.user() + '|'+ur.role();
170         }
171
172         public static String newKey(Cred cred, Instance inst) {
173                 return "cred|" + cred.id + '|' + inst.type + '|' + inst.tag;
174         }
175
176         public static String newKey(X509 x509, X509Certificate x509Cert) {
177                 return "x509|" + x509.id + '|' + x509Cert.getSerialNumber().toString();
178         }
179
180         public static void delete(StringBuilder query, List<String> row) {
181                 query.append("DELETE FROM authz.notified WHERE user='");
182                 query.append(row.get(1));
183                 query.append("' AND target='");
184                 query.append(row.get(2));
185                 query.append("' AND key='");
186                 query.append(row.get(3));
187                 query.append("';\n");
188         }
189
190 }