CacheController.java
/*
* Copyright 2021 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.genesys.server.mvc.admin;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.genesys.server.service.MappingService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.hazelcast.core.DistributedObject;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import com.hazelcast.map.LocalMapStats;
/**
* Manage caches
*
* @author mobreza
*/
@Controller
@RequestMapping("/admin/cache")
@PreAuthorize("hasRole('ADMINISTRATOR')")
public class CacheController {
public static final Logger LOG = LoggerFactory.getLogger(AdminController.class);
@Autowired
private MappingService mappingService;
@Autowired
private CacheManager cacheManager;
@RequestMapping(method = RequestMethod.POST, value = "/clearCache", params = { "clearTiles" })
public String clearCacheTiles() {
return clearTilesCache();
}
@RequestMapping(method = RequestMethod.POST, value = "/clearCache", params = { "clearAll" })
public String clearCacheAll() {
return clearCaches();
}
@RequestMapping(method = RequestMethod.POST, value = "/clearTilesCache")
public String clearTilesCache() {
final Cache tileServerCache = cacheManager.getCache("tileserver");
if (LOG.isDebugEnabled()) {
LOG.debug("tileServerCache={}", tileServerCache.getNativeCache());
}
@SuppressWarnings("rawtypes")
final IMap hazelCache = (IMap) tileServerCache.getNativeCache();
LOG.info("Tiles cache size={}", hazelCache.size());
int count = 0;
for (final Object key : hazelCache.keySet()) {
LOG.info("\tkey={}", key);
if (++count > 20) {
break;
}
}
mappingService.clearCache();
LOG.info("Tiles cache size={}", hazelCache.size());
return "redirect:/admin/cache/";
}
@RequestMapping(method = RequestMethod.POST, value = "/clearCaches")
public String clearCaches() {
for (String cacheName : cacheManager.getCacheNames()) {
clearCache(cacheName);
}
return "redirect:/admin/cache/";
}
@RequestMapping(method = RequestMethod.POST, value = "/clearCache")
public String clearCache(@RequestParam(required = true, value = "name") String cacheName) {
final Cache cache = cacheManager.getCache(cacheName);
if (cache != null) {
LOG.info("Clearing cache {}", cacheName);
cache.clear();
} else {
LOG.info("No such cache: {}", cacheName);
}
return "redirect:/admin/cache/";
}
@RequestMapping("/")
public String cacheStats(Model model) {
List<CacheStats> cacheMaps = new ArrayList<CacheStats>();
List<Object> cacheOther = new ArrayList<Object>();
Set<HazelcastInstance> instances = Hazelcast.getAllHazelcastInstances();
for (HazelcastInstance hz : instances) {
if (LOG.isDebugEnabled())
LOG.debug("\n\nCache stats Instance: {}", hz.getName());
for (DistributedObject o : hz.getDistributedObjects()) {
if (o instanceof IMap) {
IMap<?, ?> imap = (IMap<?, ?>) o;
cacheMaps.add(new CacheStats(imap));
if (LOG.isDebugEnabled()) {
LOG.debug("{}: {} {}", imap.getServiceName(), imap.getName(), imap.getPartitionKey());
LocalMapStats localMapStats = imap.getLocalMapStats();
LOG.debug("created: {}", localMapStats.getCreationTime());
LOG.debug("owned entries: {}", localMapStats.getOwnedEntryCount());
LOG.debug("backup entries: {}", localMapStats.getBackupEntryCount());
LOG.debug("locked entries: {}", localMapStats.getLockedEntryCount());
LOG.debug("dirty entries: {}", localMapStats.getDirtyEntryCount());
LOG.debug("hits: {}", localMapStats.getHits());
LOG.debug("puts: {}", localMapStats.getPutOperationCount());
LOG.debug("last update: {}", localMapStats.getLastUpdateTime());
LOG.debug("last access: {}", localMapStats.getLastAccessTime());
}
} else {
if (LOG.isDebugEnabled())
LOG.debug("{} {}", o.getClass(), o);
cacheOther.add(o);
}
}
}
cacheMaps.sort((a, b) -> a.name.compareTo(b.name));
model.addAttribute("cacheMaps", cacheMaps);
model.addAttribute("cacheOther", cacheOther);
return "/admin/cache";
}
public static final class CacheStats {
private String serviceName;
private String name;
private LocalMapStats mapStats;
public CacheStats(IMap<?, ?> imap) {
this.serviceName = imap.getServiceName();
this.name = imap.getName();
this.mapStats = imap.getLocalMapStats();
}
public String getServiceName() {
return serviceName;
}
public String getName() {
return name;
}
public LocalMapStats getMapStats() {
return mapStats;
}
}
}