blob: 7633f362c730fd3363587a13243a06a6faa2fdca [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You 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.apache.geode.modules.session.internal.common;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.InterestResultPolicy;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionShortcut;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.client.ClientRegionFactory;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.apache.geode.cache.execute.Execution;
import org.apache.geode.cache.execute.FunctionService;
import org.apache.geode.cache.execute.ResultCollector;
import org.apache.geode.modules.util.BootstrappingFunction;
import org.apache.geode.modules.util.CreateRegionFunction;
import org.apache.geode.modules.util.RegionConfiguration;
import org.apache.geode.modules.util.RegionStatus;
import org.apache.geode.modules.util.SessionCustomExpiry;
/**
* Class which defines a client/server cache.
*/
public class ClientServerSessionCache extends AbstractSessionCache {
private static final Logger LOG = LoggerFactory.getLogger(PeerToPeerSessionCache.class.getName());
private ClientCache cache;
protected static final String DEFAULT_REGION_ATTRIBUTES_ID =
RegionShortcut.PARTITION_REDUNDANT.toString();
protected static final Boolean DEFAULT_ENABLE_LOCAL_CACHE = true;
/**
* Constructor
*
*/
public ClientServerSessionCache(ClientCache cache, Map<CacheProperty, Object> properties) {
super();
this.cache = cache;
/**
* Set some default properties for this cache if they haven't already been set
*/
this.properties.put(CacheProperty.REGION_ATTRIBUTES_ID, DEFAULT_REGION_ATTRIBUTES_ID);
this.properties.put(CacheProperty.ENABLE_LOCAL_CACHE, DEFAULT_ENABLE_LOCAL_CACHE);
this.properties.putAll(properties);
}
@Override
public void initialize() {
// Bootstrap the servers
bootstrapServers();
// Create or retrieve the region
createOrRetrieveRegion();
// Set the session region directly as the operating region since there is no difference
// between the local cache region and the session region.
operatingRegion = sessionRegion;
// Create or retrieve the statistics
createStatistics();
}
@Override
public GemFireCache getCache() {
return cache;
}
@Override
public boolean isClientServer() {
return true;
}
////////////////////////////////////////////////////////////////////////
// Private methods
private void bootstrapServers() {
Execution execution = FunctionService.onServers(this.cache);
ResultCollector collector = execution.execute(new BootstrappingFunction());
// Get the result. Nothing is being done with it.
try {
collector.getResult();
} catch (Exception e) {
// If an exception occurs in the function, log it.
LOG.warn("Caught unexpected exception:", e);
}
}
private void createOrRetrieveRegion() {
// Retrieve the local session region
this.sessionRegion = this.cache.getRegion((String) properties.get(CacheProperty.REGION_NAME));
// If necessary, create the regions on the server and client
if (this.sessionRegion == null) {
// Create the PR on the servers
createSessionRegionOnServers();
// Create the region on the client
this.sessionRegion = createLocalSessionRegion();
LOG.debug("Created session region: " + this.sessionRegion);
} else {
LOG.debug("Retrieved session region: " + this.sessionRegion);
// Register interest in case users provide their own client cache region
if (sessionRegion.getAttributes().getDataPolicy() != DataPolicy.EMPTY) {
sessionRegion.registerInterestForAllKeys(InterestResultPolicy.KEYS);
}
}
}
private void createSessionRegionOnServers() {
// Create the RegionConfiguration
RegionConfiguration configuration = createRegionConfiguration();
// Send it to the server tier
Execution execution = FunctionService.onServer(this.cache).setArguments(configuration);
ResultCollector collector = execution.execute(CreateRegionFunction.ID);
// Verify the region was successfully created on the servers
List<RegionStatus> results = (List<RegionStatus>) collector.getResult();
for (RegionStatus status : results) {
if (status == RegionStatus.INVALID) {
StringBuilder builder = new StringBuilder();
builder.append(
"An exception occurred on the server while attempting to create or validate region named ");
builder.append(properties.get(CacheProperty.REGION_NAME));
builder.append(". See the server log for additional details.");
throw new IllegalStateException(builder.toString());
}
}
}
private Region<String, HttpSession> createLocalSessionRegion() {
ClientRegionFactory<String, HttpSession> factory = null;
boolean enableLocalCache = (Boolean) properties.get(CacheProperty.ENABLE_LOCAL_CACHE);
String regionName = (String) properties.get(CacheProperty.REGION_NAME);
if (enableLocalCache) {
// Create the region factory with caching and heap LRU enabled
factory = this.cache
.<String, HttpSession>createClientRegionFactory(
ClientRegionShortcut.CACHING_PROXY_HEAP_LRU)
.setCustomEntryIdleTimeout(new SessionCustomExpiry());
LOG.info("Created new local client session region: {}", regionName);
} else {
// Create the region factory without caching enabled
factory = this.cache.createClientRegionFactory(ClientRegionShortcut.PROXY);
LOG.info("Created new local client (uncached) session region: {} without any session expiry",
regionName);
}
// Create the region
Region region = factory.create(regionName);
if (enableLocalCache) {
region.registerInterestForAllKeys(InterestResultPolicy.KEYS);
}
return region;
}
}