Merge "Fixed some poorly spelled phrases in doc and some typos"
[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         private 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;
92                 return lastNotified(key);
93         }
94         
95         public Date lastNotified(String key) {
96                 return lastNotified.computeIfAbsent(key, k -> never);
97         }
98         
99         private Date add(ResultSet result, Map<String, Date> lastNotified, MarkDelete md) {
100                 Date last = null;
101                 Row r;
102         for(Iterator<Row> iter = result.iterator(); iter.hasNext();) {
103                 r = iter.next();
104                 String ttKey = r.getString(1) + '|' +
105                                            r.getString(2);
106  
107                 String fullKey = r.getString(0) + '|' +
108                                          ttKey;
109                 last=r.getTimestamp(3);
110                 if(!md.process(fullKey, last)) {
111                         lastNotified.put(fullKey, last);
112                         Date d = lastNotified.get(ttKey);
113                         if(d==null || d.after(last)) { // put most recent, if different
114                                 lastNotified.put(ttKey, last);
115                         }
116                 }
117         }
118         return last;
119         }
120         
121         private interface MarkDelete {
122                 boolean process(String fullKey, Date last);
123         }
124
125         private void startQuery(StringBuilder query) {
126                 query.append(SELECT + " WHERE user in (");
127         }
128
129         private void endQuery(StringBuilder query) {
130                 query.append(");");
131         }
132
133         public void update(StringBuilder query,String user, String target, String key) {
134                 query.append("UPDATE authz.notified SET last=dateof(now()) WHERE user='");
135                 query.append(user);
136                 query.append("' AND target='");
137                 query.append(target);
138                 query.append("' AND key='");
139                 query.append(key);
140                 query.append("';\n");
141         }
142
143     public LastNotified loadAll(Trans trans, final Range delRange, final CSV.Writer cw) {
144         trans.debug().log( "query: ",SELECT );
145         TimeTaken tt = trans.start("Read all LastNotified", Env.REMOTE);
146
147         ResultSet results;
148         try {
149             Statement stmt = new SimpleStatement( SELECT );
150             results = session.execute(stmt);
151             add(results,lastNotified, (fullKey, last) ->  {
152                 if(delRange.inRange(last)) {
153                         String[] params = Split.splitTrim('|', fullKey,3);
154                         if(params.length==3) {
155                                 cw.row("notified",params[0],params[1],params[2]);
156                                 return true;
157                         }
158                 }
159                 return false;
160             });
161         } finally {
162             tt.done();
163         }
164         return this;
165     }
166
167         public static String newKey(UserRole ur) {
168                 return "ur|" + ur.user() + '|'+ur.role();
169         }
170
171         public static String newKey(Cred cred, Instance inst) {
172                 return "cred|" + cred.id + '|' + inst.type + '|' + inst.tag;
173         }
174
175         public static String newKey(X509 x509, X509Certificate x509Cert) {
176                 return "x509|" + x509.id + '|' + x509Cert.getSerialNumber().toString();
177         }
178
179         public static void delete(StringBuilder query, List<String> row) {
180                 query.append("DELETE FROM authz.notified WHERE user='");
181                 query.append(row.get(1));
182                 query.append("' AND target='");
183                 query.append(row.get(2));
184                 query.append("' AND key='");
185                 query.append(row.get(3));
186                 query.append("';\n");
187         }
188
189 }