View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.core.persistence.jpa.dao;
20  
21  import java.time.format.DateTimeFormatter;
22  import java.util.ArrayList;
23  import java.util.LinkedHashMap;
24  import java.util.List;
25  import java.util.Map;
26  import org.apache.openjpa.datacache.CacheStatistics;
27  import org.apache.openjpa.datacache.CacheStatisticsSPI;
28  import org.apache.openjpa.datacache.QueryKey;
29  import org.apache.openjpa.kernel.QueryStatistics;
30  import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
31  import org.apache.openjpa.persistence.OpenJPAPersistence;
32  import org.apache.openjpa.persistence.QueryResultCacheImpl;
33  import org.apache.syncope.core.persistence.api.dao.EntityCacheDAO;
34  import org.apache.syncope.core.persistence.api.entity.Entity;
35  import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
36  
37  public class JPAEntityCacheDAO extends AbstractDAO<Entity> implements EntityCacheDAO {
38  
39      protected CacheStatisticsSPI cacheStatisticsSPI() {
40          return (CacheStatisticsSPI) OpenJPAPersistence.cast(entityManagerFactory()).getStoreCache().getStatistics();
41      }
42  
43      protected QueryStatistics<QueryKey> queryStatistics() {
44          return ((QueryResultCacheImpl) OpenJPAPersistence.cast(
45                  entityManagerFactory()).getQueryResultCache()).getDelegate().getStatistics();
46      }
47  
48      @Override
49      public Map<String, Object> getStatistics() {
50          Map<String, Object> result = new LinkedHashMap<>();
51  
52          CacheStatistics cacheStats = cacheStatisticsSPI();
53  
54          Map<String, Object> storeCache = new LinkedHashMap<>();
55          result.put("storeCache", storeCache);
56  
57          storeCache.put("enabled", cacheStats.isEnabled());
58          storeCache.put("activation", DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(
59                  cacheStats.start().toInstant().atOffset(FormatUtils.DEFAULT_OFFSET)));
60          storeCache.put("last_update", DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(
61                  cacheStats.since().toInstant().atOffset(FormatUtils.DEFAULT_OFFSET)));
62          storeCache.put("hits", cacheStats.getHitCount());
63          storeCache.put("reads", cacheStats.getReadCount());
64          storeCache.put("writes", cacheStats.getWriteCount());
65          storeCache.put("total_hits", cacheStats.getTotalHitCount());
66          storeCache.put("total_reads", cacheStats.getTotalReadCount());
67          storeCache.put("total_writes", cacheStats.getTotalWriteCount());
68  
69          List<Map<String, Object>> storeCacheDetails = new ArrayList<>();
70          storeCache.put("details", storeCacheDetails);
71          cacheStats.classNames().forEach(className -> {
72              Map<String, Object> classMap = new LinkedHashMap<>();
73              classMap.put("region", className);
74              classMap.put("hits", cacheStats.getHitCount(className));
75              classMap.put("reads", cacheStats.getReadCount(className));
76              classMap.put("writes", cacheStats.getWriteCount(className));
77              storeCache.put("total_hits", cacheStats.getTotalHitCount(className));
78              storeCache.put("total_reads", cacheStats.getTotalReadCount(className));
79              storeCache.put("total_writes", cacheStats.getTotalWriteCount(className));
80              storeCacheDetails.add(classMap);
81          });
82  
83          QueryStatistics<QueryKey> queryStats = queryStatistics();
84  
85          Map<String, Object> queryCache = new LinkedHashMap<>();
86          result.put("queryCache", queryCache);
87  
88          queryCache.put("activation", DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(
89                  queryStats.start().toInstant().atOffset(FormatUtils.DEFAULT_OFFSET)));
90          queryCache.put("last_update", DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(
91                  queryStats.since().toInstant().atOffset(FormatUtils.DEFAULT_OFFSET)));
92          queryCache.put("hits", queryStats.getHitCount());
93          queryCache.put("executions", queryStats.getExecutionCount());
94          queryCache.put("evictions", queryStats.getEvictionCount());
95          queryCache.put("total_hits", queryStats.getTotalHitCount());
96          queryCache.put("total_executions", queryStats.getTotalExecutionCount());
97          queryCache.put("total_evictions", queryStats.getTotalEvictionCount());
98  
99          List<Map<String, Object>> queryCacheDetails = new ArrayList<>();
100         queryCache.put("details", queryCacheDetails);
101 
102         queryStats.keys().forEach(queryKey -> {
103             Map<String, Object> queryKeyMap = new LinkedHashMap<>();
104             queryKeyMap.put("query_key", queryKey.toString());
105             queryCache.put("hits", queryStats.getHitCount(queryKey));
106             queryCache.put("executions", queryStats.getExecutionCount(queryKey));
107             queryCache.put("total_hits", queryStats.getTotalHitCount(queryKey));
108             queryCache.put("total_executions", queryStats.getTotalExecutionCount(queryKey));
109             queryCacheDetails.add(queryKeyMap);
110         });
111 
112         return result;
113     }
114 
115     @Override
116     public void enableStatistics() {
117         cacheStatisticsSPI().enable();
118     }
119 
120     @Override
121     public void disableStatistics() {
122         cacheStatisticsSPI().disable();
123     }
124 
125     @Override
126     public void resetStatistics() {
127         cacheStatisticsSPI().reset();
128         queryStatistics().reset();
129     }
130 
131     @Override
132     public void evict(final Class<? extends Entity> entityClass, final String key) {
133         OpenJPAEntityManagerFactory emf = OpenJPAPersistence.cast(entityManagerFactory());
134 
135         emf.getStoreCache().evict(entityClass, key);
136     }
137 
138     @Override
139     public void clearCache() {
140         OpenJPAEntityManagerFactory emf = OpenJPAPersistence.cast(entityManagerFactory());
141 
142         emf.getStoreCache().evictAll();
143         emf.getQueryResultCache().evictAll();
144     }
145 }