1 /*******************************************************************************
\r
2 * ============LICENSE_START====================================================
\r
4 * * ===========================================================================
\r
5 * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
\r
6 * * ===========================================================================
\r
7 * * Licensed under the Apache License, Version 2.0 (the "License");
\r
8 * * you may not use this file except in compliance with the License.
\r
9 * * You may obtain a copy of the License at
\r
11 * * http://www.apache.org/licenses/LICENSE-2.0
\r
13 * * Unless required by applicable law or agreed to in writing, software
\r
14 * * distributed under the License is distributed on an "AS IS" BASIS,
\r
15 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
16 * * See the License for the specific language governing permissions and
\r
17 * * limitations under the License.
\r
18 * * ============LICENSE_END====================================================
\r
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
\r
22 ******************************************************************************/
\r
23 package org.onap.aaf.dao.aaf.cass;
\r
25 import java.io.ByteArrayOutputStream;
\r
26 import java.io.DataInputStream;
\r
27 import java.io.DataOutputStream;
\r
28 import java.io.IOException;
\r
29 import java.nio.ByteBuffer;
\r
30 import java.util.Date;
\r
31 import java.util.HashSet;
\r
32 import java.util.List;
\r
33 import java.util.Set;
\r
35 import org.onap.aaf.authz.env.AuthzTrans;
\r
36 import org.onap.aaf.authz.layer.Result;
\r
37 import org.onap.aaf.dao.Bytification;
\r
38 import org.onap.aaf.dao.CassDAOImpl;
\r
39 import org.onap.aaf.dao.Loader;
\r
40 import org.onap.aaf.dao.Streamer;
\r
42 import org.onap.aaf.inno.env.util.Chrono;
\r
43 import com.datastax.driver.core.Cluster;
\r
44 import com.datastax.driver.core.Row;
\r
47 * CredDAO manages credentials.
\r
50 public class ArtiDAO extends CassDAOImpl<AuthzTrans,ArtiDAO.Data> {
\r
51 public static final String TABLE = "artifact";
\r
53 private HistoryDAO historyDAO;
\r
54 private PSInfo psByMechID,psByMachine;
\r
56 public ArtiDAO(AuthzTrans trans, Cluster cluster, String keyspace) {
\r
57 super(trans, ArtiDAO.class.getSimpleName(),cluster, keyspace, Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));
\r
61 public ArtiDAO(AuthzTrans trans, HistoryDAO hDao, CacheInfoDAO ciDao) {
\r
62 super(trans, ArtiDAO.class.getSimpleName(),hDao, Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));
\r
67 public static final int KEYLIMIT = 2;
\r
68 public static class Data implements Bytification {
\r
69 public String mechid;
\r
70 public String machine;
\r
71 private Set<String> type;
\r
72 public String sponsor;
\r
75 public String appName;
\r
76 public String os_user;
\r
77 public String notify;
\r
78 public Date expires;
\r
79 public int renewDays;
\r
82 public Set<String> type(boolean mutable) {
\r
84 type = new HashSet<String>();
\r
85 } else if (mutable && !(type instanceof HashSet)) {
\r
86 type = new HashSet<String>(type);
\r
93 public ByteBuffer bytify() throws IOException {
\r
94 ByteArrayOutputStream baos = new ByteArrayOutputStream();
\r
95 ArtifactLoader.deflt.marshal(this,new DataOutputStream(baos));
\r
96 return ByteBuffer.wrap(baos.toByteArray());
\r
100 public void reconstitute(ByteBuffer bb) throws IOException {
\r
101 ArtifactLoader.deflt.unmarshal(this, toDIS(bb));
\r
104 public String toString() {
\r
105 return mechid + ' ' + machine + ' ' + Chrono.dateTime(expires);
\r
109 private static class ArtifactLoader extends Loader<Data> implements Streamer<Data>{
\r
110 public static final int MAGIC=95829343;
\r
111 public static final int VERSION=1;
\r
112 public static final int BUFF_SIZE=48; // Note:
\r
114 public static final ArtifactLoader deflt = new ArtifactLoader(KEYLIMIT);
\r
115 public ArtifactLoader(int keylimit) {
\r
120 public Data load(Data data, Row row) {
\r
121 data.mechid = row.getString(0);
\r
122 data.machine = row.getString(1);
\r
123 data.type = row.getSet(2, String.class);
\r
124 data.sponsor = row.getString(3);
\r
125 data.ca = row.getString(4);
\r
126 data.dir = row.getString(5);
\r
127 data.appName = row.getString(6);
\r
128 data.os_user = row.getString(7);
\r
129 data.notify = row.getString(8);
\r
130 data.expires = row.getDate(9);
\r
131 data.renewDays = row.getInt(10);
\r
136 protected void key(final Data data, final int idx, Object[] obj) {
\r
138 obj[i=idx] = data.mechid;
\r
139 obj[++i] = data.machine;
\r
143 protected void body(final Data data, final int idx, Object[] obj) {
\r
145 obj[i=idx] = data.type;
\r
146 obj[++i] = data.sponsor;
\r
147 obj[++i] = data.ca;
\r
148 obj[++i] = data.dir;
\r
149 obj[++i] = data.appName;
\r
150 obj[++i] = data.os_user;
\r
151 obj[++i] = data.notify;
\r
152 obj[++i] = data.expires;
\r
153 obj[++i] = data.renewDays;
\r
157 public void marshal(Data data, DataOutputStream os) throws IOException {
\r
158 writeHeader(os,MAGIC,VERSION);
\r
159 writeString(os, data.mechid);
\r
160 writeString(os, data.machine);
\r
161 os.writeInt(data.type.size());
\r
162 for(String s : data.type) {
\r
163 writeString(os, s);
\r
165 writeString(os, data.sponsor);
\r
166 writeString(os, data.ca);
\r
167 writeString(os, data.dir);
\r
168 writeString(os, data.appName);
\r
169 writeString(os, data.os_user);
\r
170 writeString(os, data.notify);
\r
171 os.writeLong(data.expires==null?-1:data.expires.getTime());
\r
172 os.writeInt(data.renewDays);
\r
176 public void unmarshal(Data data, DataInputStream is) throws IOException {
\r
177 /*int version = */readHeader(is,MAGIC,VERSION);
\r
178 // If Version Changes between Production runs, you'll need to do a switch Statement, and adequately read in fields
\r
179 byte[] buff = new byte[BUFF_SIZE];
\r
180 data.mechid = readString(is,buff);
\r
181 data.machine = readString(is,buff);
\r
182 int size = is.readInt();
\r
183 data.type = new HashSet<String>(size);
\r
184 for(int i=0;i<size;++i) {
\r
185 data.type.add(readString(is,buff));
\r
187 data.sponsor = readString(is,buff);
\r
188 data.ca = readString(is,buff);
\r
189 data.dir = readString(is,buff);
\r
190 data.appName = readString(is,buff);
\r
191 data.os_user = readString(is,buff);
\r
192 data.notify = readString(is,buff);
\r
193 long l = is.readLong();
\r
194 data.expires = l<0?null:new Date(l);
\r
195 data.renewDays = is.readInt();
\r
199 private void init(AuthzTrans trans) {
\r
201 if(historyDAO==null) {
\r
202 historyDAO = new HistoryDAO(trans,this);
\r
205 String[] helpers = setCRUD(trans, TABLE, Data.class, ArtifactLoader.deflt);
\r
207 psByMechID = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + " FROM " + TABLE +
\r
208 " WHERE mechid = ?", new ArtifactLoader(1) {
\r
210 protected void key(Data data, int idx, Object[] obj) {
\r
211 obj[idx]=data.type;
\r
213 },readConsistency);
\r
215 psByMachine = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + " FROM " + TABLE +
\r
216 " WHERE machine = ?", new ArtifactLoader(1) {
\r
218 protected void key(Data data, int idx, Object[] obj) {
\r
219 obj[idx]=data.type;
\r
221 },readConsistency);
\r
226 public Result<List<Data>> readByMechID(AuthzTrans trans, String mechid) {
\r
227 return psByMechID.read(trans, R_TEXT, new Object[]{mechid});
\r
230 public Result<List<ArtiDAO.Data>> readByMachine(AuthzTrans trans, String machine) {
\r
231 return psByMachine.read(trans, R_TEXT, new Object[]{machine});
\r
235 * Log Modification statements to History
\r
237 * @param modified which CRUD action was done
\r
238 * @param data entity data that needs a log entry
\r
239 * @param overrideMessage if this is specified, we use it rather than crafting a history message based on data
\r
242 protected void wasModified(AuthzTrans trans, CRUD modified, Data data, String ... override) {
\r
243 boolean memo = override.length>0 && override[0]!=null;
\r
244 boolean subject = override.length>1 && override[1]!=null;
\r
246 HistoryDAO.Data hd = HistoryDAO.newInitedData();
\r
247 hd.user = trans.user();
\r
248 hd.action = modified.name();
\r
250 hd.subject = subject?override[1]: data.mechid;
\r
252 ? String.format("%s by %s", override[0], hd.user)
\r
253 : String.format("%sd %s for %s",modified.name(),data.mechid,data.machine);
\r
255 if(modified==CRUD.delete) {
\r
257 hd.reconstruct = data.bytify();
\r
258 } catch (IOException e) {
\r
259 trans.error().log(e,"Could not serialize CredDAO.Data");
\r
263 if(historyDAO.create(trans, hd).status!=Status.OK) {
\r
264 trans.error().log("Cannot log to History");
\r