com.hazelcast.cache.HazelcastCachingProvider Maven / Gradle / Ivy
/*
* Copyright (c) 2008-2021, Hazelcast, Inc. All Rights Reserved.
*
* 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 com.hazelcast.cache;
import com.hazelcast.cache.impl.HazelcastServerCachingProvider;
import com.hazelcast.client.cache.impl.HazelcastClientCachingProvider;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.spi.properties.ClusterProperty;
import javax.cache.CacheException;
import javax.cache.CacheManager;
import javax.cache.Caching;
import javax.cache.configuration.OptionalFeature;
import javax.cache.spi.CachingProvider;
import java.net.URI;
import java.util.Properties;
/**
* Hazelcast implementation of JCache {@link javax.cache.spi.CachingProvider}.
*
* This provider class is registered as a {@link CachingProvider} implementation.
* When Hazelcast is the only {@link CachingProvider} on the classpath,
* using {@link Caching#getCachingProvider()} will instantiate and return
* an instance of this class.
*
* This provider implementation delegates to a {@code CachingProvider} backed
* by either a member- or a client-side {@link HazelcastInstance}:
*
* - {@link com.hazelcast.cache.HazelcastMemberCachingProvider} is the
* member-side {@link CachingProvider} implementation
* - {@link com.hazelcast.client.cache.HazelcastClientCachingProvider} is the
* client-side {@link CachingProvider} implementation
*
* Provider Type Selection
* When using {@link Caching#getCachingProvider()} without a class name argument,
* this provider is instantiated. The choice between member- or client-side provider
* is made by inspecting the value of system property
* {@code hazelcast.jcache.provider.type}:
*
* - If no value was set, then the client-side caching provider is selected
* - If a value was set, then value {@code member} selects the member-side caching
* provider, while value {@code client} selects the client-side provider. Legacy value
* {@code server} is also accepted as an alias for {@code member} for backwards compatibility,
* however its usage is discouraged and will be removed in a future version.
* Other values result in a {@link CacheException} being thrown.
*
* When using one of {@code Caching#getCachingProvider} variants with an explicit
* class name argument, then:
*
* - using {@code com.hazelcast.cache.HazelcastCachingProvider} as class name
* is identical to using {@link Caching#getCachingProvider()}; choice between
* member- or client-side caching provider is performed via system property
* {@code hazelcast.jcache.provider.type} as described above.
* - using {@link #MEMBER_CACHING_PROVIDER} as
* class name will return a member-side caching provider
* - using {@link #CLIENT_CACHING_PROVIDER} as
* class name will return a client-side caching provider
*
* Creating or reusing HazelcastInstances with CacheManagers
* Arguments used with {@link CachingProvider#getCacheManager(URI, ClassLoader, Properties)}
* and its variants control whether a {@code HazelcastInstance} will be created or reused
* to back the {@link CacheManager} being created:
*
* - Property {@code hazelcast.config.location} specifies a URI to locate a Hazelcast
* member or client configuration file. Supports {@code classpath:}, {@code file:},
* {@code http:} and {@code https:} URI schemes.
* Examples: {@code classpath:com/acme/hazelcast.xml}
* will locate {@code hazelcast.xml} in package {@code com.acme},
* {@code http://internal.acme.com/hazelcast.xml} will locate the configuration from
* the given HTTP URL.
* - Property {@code hazelcast.instance.name} specifies the instance name of a running
* {@code HazelcastInstance}. If no instance is found running by that name, then a new
* {@code HazelcastInstance} is started with a default configuration and the given
* instance name.
* - In any {@code CachingProvider#getCacheManager} variant that accepts a
* {@link URI} as argument, and if no properties were provided or properties did not result
* in resolving a specific {@code HazelcastInstance}, then the {@code URI} argument is
* interpreted as a Hazelcast config location as follows:
*
* - if {@code URI} starts with one of supported schemes ({@code classpath:}, {@code http:},
* {@code https:}, {@code file:}), then a Hazelcast XML configuration is loaded from that location.
* - otherwise, {@code URI} is interpreted as a system property. If {@link System#getProperty(String)
* System.getProperty(URI)} returns a value that starts with one of supported schemes above, then
* a Hazelcast XML configuration is loaded from that location.
* - if {@code URI} or its resolved value as a system property does not start with a supported
* URI scheme, a default {@code HazelcastInstance} named {@value #SHARED_JCACHE_INSTANCE_NAME} is
* created or used, if it already exists.
*
*
*
* Convenience methods {@link #propertiesByLocation(String)} and {@link #propertiesByInstanceName(String)}
* will create an appropriate {@link Properties} instance for use with
* {@link #getCacheManager(URI, ClassLoader, Properties)}.
* Examples
* Obtain a member-side caching provider backed by an existing HazelcastInstance.
* In this example the member-side caching provider is selected by setting the value of
* system property {@code hazelcast.jcache.provider.type} to value "{@code member}". An existing
* {@code HazelcastInstance} is referenced by instance name in the {@code Properties} provided as
* argument to {@link CachingProvider#getCacheManager(URI, ClassLoader, Properties)}.
*
* Config config = new Config();
* config.setInstanceName("hz-jcache");
* HazelcastInstance member = Hazelcast.newHazelcastInstance(config);
*
* System.setProperty("hazelcast.jcache.provider.type", "member");
* CachingProvider provider = Caching.getCachingProvider();
* CacheManager manager = provider.getCacheManager(null, null, HazelcastCachingProvider.propertiesByInstanceName("hz-jcache"));
* Cache cache = manager.createCache("sessions", new MutableConfiguration());
* cache.put("a", "b");
*
*
* Obtain a client-side caching provider, starting a default client {@code HazelcastInstance}
* In this example the client-side caching provider is selected as default option. A new
* client-side {@code HazelcastInstance} is created with default configuration once
* {@link CachingProvider#getCacheManager()} is called.
*
* // start a Hazelcast member for the client to connect to
* HazelcastInstance member = Hazelcast.newHazelcastInstance();
*
* // obtain a client-side (default) CachingProvider
* CachingProvider provider = Caching.getCachingProvider();
* // obtain the default CacheManager; since there is no JCache-backing client-side
* // HazelcastInstance started, this will start a new instance
* CacheManager manager = provider.getCacheManager();
* Cache cache = manager.createCache("sessions", new MutableConfiguration());
* cache.put("a", "b");
*
*
*
* @since 3.4
*/
public final class HazelcastCachingProvider implements CachingProvider {
/**
* Hazelcast config location property
*/
public static final String HAZELCAST_CONFIG_LOCATION = "hazelcast.config.location";
/**
* Hazelcast instance name property
*/
public static final String HAZELCAST_INSTANCE_NAME = "hazelcast.instance.name";
/**
* Hazelcast instance itself property
*/
public static final String HAZELCAST_INSTANCE_ITSELF = "hazelcast.instance.itself";
/**
* Class name of the member-side Caching Provider
*/
public static final String MEMBER_CACHING_PROVIDER = HazelcastMemberCachingProvider.class.getName();
/**
* Same value as {@link #MEMBER_CACHING_PROVIDER}. This field is maintained for backwards compatibility.
* Its use is discouraged and will be removed in a future version.
*/
@Deprecated
public static final String SERVER_CACHING_PROVIDER = HazelcastMemberCachingProvider.class.getName();
/**
* Class name of the client-side Caching Provider
*/
public static final String CLIENT_CACHING_PROVIDER =
com.hazelcast.client.cache.HazelcastClientCachingProvider.class.getName();
/**
* Name of default {@link HazelcastInstance} which may be started when
* obtaining the default {@link CachingProvider}.
*/
public static final String SHARED_JCACHE_INSTANCE_NAME = "_hzinstance_jcache_shared";
private static final String PROVIDER_TYPE_CLIENT = "client";
private static final String PROVIDER_TYPE_MEMBER = "member";
private static final String LEGACY_PROVIDER_TYPE_MEMBER = "server";
private final CachingProvider delegate;
public HazelcastCachingProvider() {
CachingProvider cp = null;
String providerType = ClusterProperty.JCACHE_PROVIDER_TYPE.getSystemProperty();
if (providerType != null) {
if (PROVIDER_TYPE_CLIENT.equals(providerType)) {
cp = new HazelcastClientCachingProvider();
} else if (PROVIDER_TYPE_MEMBER.equals(providerType)
|| LEGACY_PROVIDER_TYPE_MEMBER.equals(providerType)) {
cp = new HazelcastServerCachingProvider();
} else {
throw new CacheException("Unknown CachingProvider type \"" + providerType + "\". Use "
+ "\"client\" or \"member\" as provider type.");
}
} else {
cp = new HazelcastClientCachingProvider();
}
delegate = cp;
}
/**
* Create the {@link java.util.Properties} with the provided config file location.
*
* @param configFileLocation the location of the config file to configure
* @return properties instance pre-configured with the configuration location
*/
public static Properties propertiesByLocation(String configFileLocation) {
Properties properties = new Properties();
properties.setProperty(HAZELCAST_CONFIG_LOCATION, configFileLocation);
return properties;
}
/**
* Create the {@link java.util.Properties} with the provided instance name.
*
* @param instanceName the instance name to configure
* @return the properties instance pre-configured with the instance name
*/
public static Properties propertiesByInstanceName(String instanceName) {
Properties properties = new Properties();
properties.setProperty(HAZELCAST_INSTANCE_NAME, instanceName);
return properties;
}
/**
* Create the {@link java.util.Properties} with the provided instance itself.
*
* @param instance the instance itself to be used
* @return the properties instance pre-configured with the instance itself
*/
public static Properties propertiesByInstanceItself(HazelcastInstance instance) {
Properties properties = new Properties();
properties.put(HAZELCAST_INSTANCE_ITSELF, instance);
return properties;
}
@Override
public CacheManager getCacheManager(URI uri, ClassLoader classLoader, Properties properties) {
return delegate.getCacheManager(uri, classLoader, properties);
}
@Override
public ClassLoader getDefaultClassLoader() {
return delegate.getDefaultClassLoader();
}
@Override
public URI getDefaultURI() {
return delegate.getDefaultURI();
}
@Override
public Properties getDefaultProperties() {
return delegate.getDefaultProperties();
}
@Override
public CacheManager getCacheManager(URI uri, ClassLoader classLoader) {
return delegate.getCacheManager(uri, classLoader);
}
@Override
public CacheManager getCacheManager() {
return delegate.getCacheManager();
}
@Override
public void close() {
delegate.close();
}
@Override
public void close(ClassLoader classLoader) {
delegate.close(classLoader);
}
@Override
public void close(URI uri, ClassLoader classLoader) {
delegate.close(uri, classLoader);
}
@Override
public boolean isSupported(OptionalFeature optionalFeature) {
return delegate.isSupported(optionalFeature);
}
@Override
public String toString() {
return "HazelcastCachingProvider{delegate=" + delegate + '}';
}
}