/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.coverage;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.geoserver.config.ConfigurationListenerAdapter;
import org.geoserver.config.CoverageAccessInfo;
import org.geoserver.config.CoverageAccessInfo.QueueType;
import org.geoserver.config.GeoServer;
import org.geoserver.config.GeoServerInfo;
import org.geoserver.config.GeoServerInitializer;
import org.geoserver.config.impl.CoverageAccessInfoImpl;
import org.geoserver.platform.ExtensionPriority;
import org.geotools.factory.GeoTools;
import org.geotools.factory.Hints;
import org.geotools.image.io.ImageIOExt;
/**
* Initializes Coverage Access settings from configuration.
*
* @author Daniele Romagnoli, GeoSolutions
*
*/
public class CoverageAccessInitializer implements GeoServerInitializer, ExtensionPriority {
GeoServer gs;
public void initialize(GeoServer geoServer) throws Exception {
this.gs = geoServer;
final GeoServerInfo geoserverInfo = geoServer.getGlobal();
CoverageAccessInfo coverageAccess = geoserverInfo.getCoverageAccess();
if (coverageAccess == null){
coverageAccess = new CoverageAccessInfoImpl();
geoserverInfo.setCoverageAccess(coverageAccess);
}
initCoverage(coverageAccess);
geoServer.addListener( new ConfigurationListenerAdapter() {
public void handleGlobalChange(GeoServerInfo global,
List<String> propertyNames, List<Object> oldValues,
List<Object> newValues) {
if (propertyNames.contains("coverageAccess")) {
// Make sure to proceed with coverageAccess init
// only in case the global change involved that section
initCoverage(global.getCoverageAccess());
}
}
@Override
public void handlePostGlobalChange(GeoServerInfo global) {
// No need to handle that change too
}
});
}
void initCoverage(CoverageAccessInfo coverageAccess) {
if (coverageAccess != null) {
ThreadPoolExecutor executor = coverageAccess.getThreadPoolExecutor();
//First initialization
if (executor == null){
final Hints defHints = GeoTools.getDefaultHints();
//Looking for executor from default Hints
if (defHints != null && defHints.containsKey(Hints.EXECUTOR_SERVICE)){
executor = (ThreadPoolExecutor) defHints.get(Hints.EXECUTOR_SERVICE);
}
}
if (executor == null){
// No Executor found: Create a new one
executor = new ThreadPoolExecutor(coverageAccess.getCorePoolSize(),
coverageAccess.getMaxPoolSize(), coverageAccess.getKeepAliveTime(), TimeUnit.MILLISECONDS,
coverageAccess.getQueueType() == QueueType.UNBOUNDED ? new LinkedBlockingQueue<Runnable>() : new SynchronousQueue<Runnable>());
coverageAccess.setThreadPoolExecutor(executor);
} else {
// //
//
// Overriding values
//
// //
final BlockingQueue<Runnable> queue = executor.getQueue();
final QueueType queueType = coverageAccess.getQueueType();
// If the queue type is the same, I can simply override the parameter settings.
if ((queue instanceof LinkedBlockingQueue && queueType == QueueType.UNBOUNDED) ||
(queue instanceof SynchronousQueue && queueType == QueueType.DIRECT) ){
executor.setCorePoolSize(coverageAccess.getCorePoolSize());
executor.setMaximumPoolSize(coverageAccess.getMaxPoolSize());
executor.setKeepAliveTime(coverageAccess.getKeepAliveTime(), TimeUnit.MILLISECONDS);
coverageAccess.setThreadPoolExecutor(executor);
} else {
// The queue type has been changed. Initializing a new ThreadPoolExecutor by
// previously shutting down the current one
executor.shutdown();
if (!executor.isTerminated()) {
executor.shutdownNow();
}
executor = new ThreadPoolExecutor(coverageAccess.getCorePoolSize(),
coverageAccess.getMaxPoolSize(), coverageAccess.getKeepAliveTime(), TimeUnit.MILLISECONDS,
coverageAccess.getQueueType() == QueueType.DIRECT ? new SynchronousQueue<Runnable>() : new LinkedBlockingQueue<Runnable>() );
coverageAccess.setThreadPoolExecutor(executor);
}
}
// set the executor in the resource pool
gs.getCatalog().getResourcePool().setCoverageExecutor(executor);
// setup the memory/file system cache usage threshold
ImageIOExt.setFilesystemThreshold(coverageAccess.getImageIOCacheThreshold() * 1024);
}
}
public int getPriority() {
return 0;
}
}