Commit e27bcce2 authored by Andrey Lugovskiy's avatar Andrey Lugovskiy
Browse files

- added hazelcast config

parent 32071373
......@@ -19,6 +19,7 @@
<tomcat-jdbc-juli>8.5.13</tomcat-jdbc-juli>
<liquibase.version>3.5.3</liquibase.version>
<spring-security-jwt>1.0.8.RELEASE</spring-security-jwt>
<hazelcast.version>3.8.2-SNAPSHOT</hazelcast.version>
</properties>
<build>
......@@ -214,6 +215,26 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>${hazelcast.version}</version>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-spring</artifactId>
<version>${hazelcast.version}</version>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-hibernate4</artifactId>
<version>${hazelcast.version}</version>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-wm</artifactId>
<version>${hazelcast.version}</version>
</dependency>
<dependency>
<groupId>com.google.api-client</groupId>
......
......@@ -23,8 +23,6 @@ import org.genesys.filerepository.service.impl.ClamAVScanner;
import org.genesys.filerepository.service.impl.FilesystemStorageServiceImpl;
import org.genesys.filerepository.service.impl.S3StorageServiceImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
......@@ -47,15 +45,6 @@ public class ApplicationConfig {
@Value("${CLAMD_PORT}")
private String clamdPortStr;
@Bean
public CacheManager cacheManager() {
// // FIXME ehcache
// SimpleCacheManager cacheManager = new SimpleCacheManager();
// cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("default")));
// return cacheManager;
return new CaffeineCacheManager();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
......
/*
* Copyright 2017 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.catalog.server.config;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IExecutorService;
import com.hazelcast.core.IMap;
import com.hazelcast.core.IQueue;
import com.hazelcast.spring.cache.HazelcastCacheManager;
import com.hazelcast.web.WebFilter;
import com.hazelcast.web.spring.SpringAwareWebFilter;
import org.genesys.blocks.security.lockout.AccountLockoutManager.AttemptStatistics;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import java.util.Properties;
@Configuration
@EnableCaching
@Import({ HazelcastConfig.class })
public class CacheConfig {
@Value("${hazelcast.instanceName}")
protected String instanceName = "genesys";
@Value("${base.cookie-domain}")
private String cookieDomain;
@Value("${base.cookie-secure}")
private String cookieSecure;
@Value("${base.cookie-http-only}")
private String cookieHttpOnly;
@Bean
public HazelcastCacheManager cacheManager(final HazelcastInstance hazelcastInstance) {
final HazelcastCacheManager cm = new HazelcastCacheManager(hazelcastInstance);
return cm;
}
@Bean
public IMap<Object, Object> tileserverMap(final HazelcastInstance hazelcast) {
final IMap<Object, Object> x = hazelcast.getMap("tileserver");
return x;
}
@Bean
public IQueue<Object> elasticRemoveQueue(final HazelcastInstance hazelcast) {
return hazelcast.getQueue("es-remove");
}
@Bean
public IQueue<Object> elasticUpdateQueue(final HazelcastInstance hazelcast) {
return hazelcast.getQueue("es-update");
}
@Bean
public IExecutorService distributedExecutor(final HazelcastInstance hazelcast) {
final IExecutorService executorService = hazelcast.getExecutorService("hazel-exec");
return executorService;
}
@Bean
public IMap<String, AttemptStatistics> accountLockoutMap(final HazelcastInstance hazelcast) {
final IMap<String, AttemptStatistics> x = hazelcast.getMap("accountLocks");
return x;
}
@Bean
public WebFilter hazelcastWebFilter() {
return new SpringAwareWebFilter(filterProps());
}
@Bean
public SessionRegistry SessionRegistry() {
return new SessionRegistryImpl();
}
private Properties filterProps() {
final Properties properties = new Properties();
properties.setProperty("use-client", "false");
properties.setProperty("map-name", "jetty-sessions");
// Not allowed in HZ-3.8.1
// properties.setProperty("session-ttl-seconds", "21600");
properties.setProperty("sticky-session", "false");
properties.setProperty("cookie-name", "hz-session-id");
properties.setProperty("cookie-domain", cookieDomain);
properties.setProperty("cookie-secure", cookieSecure);
properties.setProperty("cookie-http-only", cookieHttpOnly);
// properties.setProperty("debug", "true");
properties.setProperty("instance-name", instanceName);
properties.setProperty("shutdown-on-destroy", "true");
return properties;
}
}
/*
* Copyright 2017 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.catalog.server.config;
import com.hazelcast.config.Config;
import com.hazelcast.config.EvictionPolicy;
import com.hazelcast.config.ExecutorConfig;
import com.hazelcast.config.GroupConfig;
import com.hazelcast.config.JoinConfig;
import com.hazelcast.config.MapConfig;
import com.hazelcast.config.MaxSizeConfig;
import com.hazelcast.config.MaxSizeConfig.MaxSizePolicy;
import com.hazelcast.config.NetworkConfig;
import com.hazelcast.config.QueueConfig;
import com.hazelcast.config.TcpIpConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.ILock;
import com.hazelcast.core.ManagedContext;
import com.hazelcast.hibernate.HazelcastCacheRegionFactory;
import com.hazelcast.spring.context.SpringManagedContext;
import org.apache.commons.lang3.StringUtils;
import org.genesys.catalog.server.config.hazelcast.HazelcastCacheRegionFactoryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author Matija Obreza
*/
@Configuration
@EnableCaching
public abstract class HazelcastConfig {
protected final Logger LOG = LoggerFactory.getLogger(HazelcastConfig.class);
/// Interfaces on which HZ should bind
@Value("${hazelcast.interfaces}")
protected String hazelInterfaces;
/// TCP port to listen on
@Value("${hazelcast.port}")
protected int hazelPort;
/// The public address (in case of NAT)
@Value("${hazelcast.publicAddress}")
protected String hazelPublicAddress;
@Value("${hazelcast.instanceName}")
protected String instanceName;
@Value("${hazelcast.password}")
protected String password;
@Value("${hazelcast.name}")
protected String name;
@Value("${cache.defaultCacheSize}")
protected int defaultCacheSize;
@Value("${cache.time-to-live-seconds}")
private int cacheTimeToLiveSeconds;
@Value("${cache.max-idle-seconds}")
private int cacheMaxIdleSeconds;
@Value("${cache.eviction-policy}")
protected EvictionPolicy cacheEvictionPolicy;
@Bean
public ManagedContext managedContext() {
return new SpringManagedContext();
}
@Value("${hazelcast.members}")
private String[] hazelcastMembers;
@Bean
public HazelcastInstance hazelcast(final ManagedContext managedContext) {
final Config cfg = new Config();
cfg.setManagedContext(managedContext);
cfg.setInstanceName(instanceName);
final GroupConfig groupConfig = cfg.getGroupConfig();
groupConfig.setName(name);
groupConfig.setPassword(password);
cfg.setProperty("hazelcast.merge.first.run.delay.seconds", "5");
cfg.setProperty("hazelcast.merge.next.run.delay.seconds", "5");
cfg.setProperty("hazelcast.logging.type", "log4j");
cfg.setProperty("hazelcast.icmp.enabled", "true");
final NetworkConfig network = cfg.getNetworkConfig();
network.setPort(hazelPort);
network.setPortAutoIncrement(true);
if (StringUtils.isNotBlank(hazelInterfaces)) {
network.getInterfaces().setEnabled(true);
for (final String hazelInterface : hazelInterfaces.split(",")) {
final String trimmed = hazelInterface.trim();
if (StringUtils.isNotBlank(trimmed)) {
System.out.println("Hazelcast: Adding single interface " + trimmed);
try {
final InetAddress ipAddress = InetAddress.getByName(trimmed);
LOG.warn("Interface ip={} ={}", ipAddress.getHostAddress(), ipAddress.isSiteLocalAddress());
network.getInterfaces().addInterface(ipAddress.getHostAddress());
} catch (final UnknownHostException e) {
LOG.warn("Could not resolve {}, error {}", trimmed, e.getMessage());
network.getInterfaces().addInterface(trimmed);
}
}
}
}
if (StringUtils.isNotBlank(hazelPublicAddress)) {
System.out.println("Hazelcast: Using public address " + hazelPublicAddress);
try {
final InetAddress ipAddress = InetAddress.getByName(hazelPublicAddress);
LOG.warn("Public ip={} siteLocal={}", ipAddress, ipAddress.isSiteLocalAddress());
network.setPublicAddress(ipAddress.getHostAddress());
} catch (final UnknownHostException e) {
LOG.warn("Could not resolve {}, error {}", hazelPublicAddress, e.getMessage());
network.setPublicAddress(hazelPublicAddress);
}
} else {
try {
hazelPublicAddress = InetAddress.getLocalHost().getHostName();
System.out.println("Hazelcast: Using public address " + hazelPublicAddress);
final InetAddress ipAddress = InetAddress.getByName(InetAddress.getLocalHost().getHostName());
LOG.warn("Public ip={} siteLocal={}", ipAddress, ipAddress.isSiteLocalAddress());
network.setPublicAddress(ipAddress.getHostAddress());
} catch (final UnknownHostException e) {
LOG.warn("Could not resolve {}, error {}", hazelPublicAddress, e.getMessage());
network.setPublicAddress(hazelPublicAddress);
}
}
final JoinConfig join = network.getJoin();
if (!hasConfiguredMembers()) {
LOG.warn("Enabling Hazelcast multicast, members={}", Arrays.toString(hazelcastMembers));
join.getMulticastConfig().setEnabled(true);
final TcpIpConfig tcpIpConfig = join.getTcpIpConfig();
tcpIpConfig.setEnabled(false);
} else {
join.getMulticastConfig().setEnabled(false);
LOG.warn("Enabling TCP/IP discovery for members={}", Arrays.toString(hazelcastMembers));
final TcpIpConfig tcpIpConfig = join.getTcpIpConfig();
tcpIpConfig.setEnabled(true);
tcpIpConfig.setConnectionTimeoutSeconds(20);
final List<String> hzMembers = new ArrayList<>();
for (final String hazelcastMember : hazelcastMembers) {
final String trimmed = hazelcastMember.trim();
if (StringUtils.isNotBlank(trimmed)) {
System.out.println("Hazelcast: Adding member " + trimmed);
try {
final InetAddress ipAddress = InetAddress.getByName(trimmed);
LOG.warn("Interface ip={} ={}", ipAddress, ipAddress.isSiteLocalAddress());
hzMembers.add(ipAddress.getHostAddress());
} catch (final UnknownHostException e) {
LOG.warn("Could not resolve {}, error {}", trimmed, e.getMessage());
hzMembers.add(trimmed);
}
}
}
tcpIpConfig.setMembers(hzMembers);
}
configureHazelcast(cfg);
final HazelcastInstance instance = Hazelcast.newHazelcastInstance(cfg);
return instance;
}
private boolean hasConfiguredMembers() {
LOG.debug("HZ members={}", Arrays.toString(hazelcastMembers));
return (this.hazelcastMembers != null) && (this.hazelcastMembers.length != 0) && (this.hazelcastMembers[0].length() > 0);
}
@Bean
public ILock taxonomyUpdateLock(final HazelcastInstance hazelcast) {
final ILock lock = hazelcast.getLock("taxonomyUpdateLock");
return lock;
}
@Bean
public ILock elasticsearchAdminLock(final HazelcastInstance hazelcast) {
final ILock lock = hazelcast.getLock("elasticsearchAdminLock");
return lock;
}
/**
* Loads an instance and sets the static field
*
* @param hazelcastCacheRegionFactory
*
* @return
*/
@Bean
public HazelcastCacheRegionFactoryWrapper hazelcastCacheRegionFactoryWrapper(final HazelcastCacheRegionFactory hazelcastCacheRegionFactory) {
System.err.println("Hazelcast Cache");
final HazelcastCacheRegionFactoryWrapper x = new HazelcastCacheRegionFactoryWrapper();
x.setHazelcastCacheRegionFactory(hazelcastCacheRegionFactory);
return x;
}
/**
* Injected into wrapper above
*
* @param instance
* @return
*/
@Bean
public HazelcastCacheRegionFactory hazelcastCacheRegionFactory(final HazelcastInstance instance) {
System.err.println("HazelcastCacheRegionFactory");
return new HazelcastCacheRegionFactory(instance);
}
protected void configureHazelcast(final Config cfg) {
final MapConfig defaultMapConfig = new MapConfig();
defaultMapConfig.setName("default");
defaultMapConfig.setTimeToLiveSeconds(cacheTimeToLiveSeconds);
defaultMapConfig.setMaxIdleSeconds(cacheMaxIdleSeconds);
defaultMapConfig.setEvictionPolicy(EvictionPolicy.LFU);
{
final MaxSizeConfig maxSizeConfig = new MaxSizeConfig();
maxSizeConfig.setSize(defaultCacheSize);
maxSizeConfig.setMaxSizePolicy(MaxSizePolicy.PER_NODE);
defaultMapConfig.setMaxSizeConfig(maxSizeConfig);
}
cfg.addMapConfig(defaultMapConfig);
final MapConfig tileserverMapConfig = new MapConfig();
tileserverMapConfig.setName("tileserver");
tileserverMapConfig.setMaxIdleSeconds(60 * 60 * 3); // 3 hours
cfg.addMapConfig(tileserverMapConfig);
final MapConfig jettySessionsMapConfig = new MapConfig();
jettySessionsMapConfig.setName("jetty-sessions");
jettySessionsMapConfig.setTimeToLiveSeconds(60 * 60 * 24); // 1 day
cfg.addMapConfig(jettySessionsMapConfig);
final ExecutorConfig execConfig = new ExecutorConfig();
execConfig.setName("hazel-exec");
execConfig.setPoolSize(4);
execConfig.setQueueCapacity(2);
execConfig.setStatisticsEnabled(true);
cfg.addExecutorConfig(execConfig);
final QueueConfig queueConfig = new QueueConfig();
queueConfig.setName("elasticsearchQueue");
queueConfig.setMaxSize(100);
cfg.addQueueConfig(queueConfig);
}
}
/*
* Copyright (c) 2008-2013, 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 org.genesys.catalog.server.config.hazelcast;
import com.hazelcast.hibernate.HazelcastCacheRegionFactory;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.QueryResultsRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TimestampsRegion;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cfg.Settings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Properties;
/**
* @author Matija Obreza
*/
@Component
public class HazelcastCacheRegionFactoryWrapper implements RegionFactory {
/**
*
*/
private static final long serialVersionUID = -7713402428018035618L;
private static HazelcastCacheRegionFactory hazelcastCacheRegionFactory;
public HazelcastCacheRegionFactoryWrapper() {
}
public HazelcastCacheRegionFactoryWrapper(final Properties properties) {
this();
}
@Autowired(required = true)
public void setHazelcastCacheRegionFactory(HazelcastCacheRegionFactory hazelcastCacheRegionFactory) {
HazelcastCacheRegionFactoryWrapper.hazelcastCacheRegionFactory = hazelcastCacheRegionFactory;
}
@Override
public CollectionRegion buildCollectionRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException {
return hazelcastCacheRegionFactory.buildCollectionRegion(regionName, properties, metadata);
}
@Override
public void start(Settings settings, Properties properties) throws CacheException {
hazelcastCacheRegionFactory.start(settings, properties);
}
@Override
public void stop() {
hazelcastCacheRegionFactory.stop();
}
@Override
public boolean isMinimalPutsEnabledByDefault() {
return hazelcastCacheRegionFactory.isMinimalPutsEnabledByDefault();
}
@Override
public AccessType getDefaultAccessType() {
return hazelcastCacheRegionFactory.getDefaultAccessType();
}
@Override
public long nextTimestamp() {
return hazelcastCacheRegionFactory.nextTimestamp();
}
@Override
public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException {
return hazelcastCacheRegionFactory.buildEntityRegion(regionName, properties, metadata);
}
@Override
public NaturalIdRegion buildNaturalIdRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException {
return hazelcastCacheRegionFactory.buildNaturalIdRegion(regionName, properties, metadata);
}
@Override
public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException {
return hazelcastCacheRegionFactory.buildQueryResultsRegion(regionName, properties);
}
@Override
public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException {
return hazelcastCacheRegionFactory.buildTimestampsRegion(regionName, properties);
}
}
......@@ -28,6 +28,7 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;