2 * ============LICENSE_START====================================================
4 * ===========================================================================
5 * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6 * ===========================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END====================================================
22 package org.onap.aaf.auth.dao;
24 import java.util.ArrayList;
25 import java.util.List;
27 import org.onap.aaf.auth.dao.cass.Status;
28 import org.onap.aaf.auth.layer.Result;
29 import org.onap.aaf.misc.env.Trans;
34 * Cache the response of "get" of any DAO.
36 * For simplicity's sake, at this time, we only do this for single Object keys
42 public class CachedDAO<TRANS extends Trans,D extends DAO<TRANS,DATA>,DATA extends Cacheable>
43 extends Cached<TRANS,DATA> implements DAO_RO<TRANS,DATA>{
44 // private final String dirty_str;
48 public CachedDAO(D dao, CIDAO<TRANS> info, int segsize, long expireIn) {
49 super(info, dao.table(), segsize, expireIn);
51 // Instantiate a new Cache per DAO name (so separate instances use the same cache)
53 //read_str = "Cached READ for " + dao.table();
54 // dirty_str = "Cache DIRTY on " + dao.table();
55 if (dao instanceof CassDAOImpl) {
56 ((CassDAOImpl<?,?>)dao).cache = this;
60 public static<T extends Trans, DA extends DAO<T,DT>, DT extends Cacheable>
61 CachedDAO<T,DA,DT> create(DA dao, CIDAO<T> info, int segsize, long expireIn) {
62 return new CachedDAO<T,DA,DT>(dao,info, segsize, expireIn);
65 public void add(DATA data) {
66 String key = keyFromObjs(dao.keyFrom(data));
67 List<DATA> list = new ArrayList<>();
72 // public void invalidate(TRANS trans, Object ... objs) {
73 // TimeTaken tt = trans.start(dirty_str, Env.SUB);
75 // super.invalidate(keyFromObjs(objs));
81 public static String keyFromObjs(Object ... objs) {
83 if (objs.length==1 && objs[0] instanceof String) {
84 key = (String)objs[0];
86 StringBuilder sb = new StringBuilder();
88 for (Object o : objs) {
95 sb.append(o.toString());
103 public Result<DATA> create(TRANS trans, DATA data) {
104 Result<DATA> d = dao.create(trans,data);
105 if (d.status==Status.OK) {
108 trans.error().log(d.errorString());
110 // dao.create already modifies cache. Do not invalidate again. invalidate(trans,data);
114 protected class DAOGetter implements Getter<DATA> {
115 protected TRANS trans;
116 protected Object objs[];
118 public Result<List<DATA>> result;
120 public DAOGetter(TRANS trans, D dao, Object ... objs) {
127 * Separated into single call for easy overloading
130 public Result<List<DATA>> call() {
131 return dao.read(trans, objs);
135 public final Result<List<DATA>> get() {
137 // if (result.isOKhasData()) { // Note, given above logic, could exist, but stale
138 // return result.value;
146 public Result<List<DATA>> read(final TRANS trans, final Object ... objs) {
147 DAOGetter getter = new DAOGetter(trans,dao,objs);
148 return get(trans, keyFromObjs(objs),getter);
150 // return Result.ok(ld);//.emptyList(ld.isEmpty());
152 // // Result Result if exists
153 // if (getter.result==null) {
154 // return Result.err(Status.ERR_NotFound, "No Cache or Lookup found on [%s]",dao.table());
156 // return getter.result;
159 // Slight Improved performance available when String and Obj versions are known.
160 public Result<List<DATA>> read(final String key, final TRANS trans, final Object[] objs) {
161 DAOGetter getter = new DAOGetter(trans,dao,objs);
162 return get(trans, key, getter);
164 // return Result.ok(ld);//.emptyList(ld.isEmpty());
166 // // Result Result if exists
167 // if (getter.result==null) {
168 // return Result.err(Status.ERR_NotFound, "No Cache or Lookup found on [%s]",dao.table());
170 // return getter.result;
174 public Result<List<DATA>> read(TRANS trans, DATA data) {
175 return read(trans,dao.keyFrom(data));
177 public Result<Void> update(TRANS trans, DATA data) {
178 Result<Void> d = dao.update(trans, data);
179 if (d.status==Status.OK) {
182 trans.error().log(d.errorString());
187 public Result<Void> delete(TRANS trans, DATA data, boolean reread) {
188 if (reread) { // If reread, get from Cache, if possible, not DB exclusively
189 Result<List<DATA>> rd = read(trans,data);
191 return Result.err(rd);
193 // trans.error().log(rd.errorString());
196 data.invalidate(this);
197 return Result.err(Status.ERR_NotFound,"Not Found");
199 data = rd.value.get(0);
201 Result<Void> rv=dao.delete(trans, data, false);
202 data.invalidate(this);
207 public void close(TRANS trans) {
215 public String table() {
223 public void invalidate(TRANS trans, DATA data) {
224 if (info.touch(trans, dao.table(),data.invalidate(this)).notOK()) {
225 trans.error().log("Cannot touch CacheInfo for Role");