This commit is contained in:
parent
4f199c3d37
commit
1d33e0cd3b
25 changed files with 870 additions and 30 deletions
|
|
@ -33,6 +33,10 @@
|
||||||
<artifactId>keycloak-spring-boot-starter</artifactId>
|
<artifactId>keycloak-spring-boot-starter</artifactId>
|
||||||
<version>${keycloak-spring-boot-starter.version}</version>
|
<version>${keycloak-spring-boot-starter.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ru.spcex.platform</groupId>
|
||||||
|
<artifactId>platform-imdg-api-hazelcast-impl</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
package ru.spcex.clearing.backendapi.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
|
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||||
|
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class BackEndApiImdgConfig {
|
||||||
|
@Bean(name = "taskExecutorHazelcastClientInitializer")
|
||||||
|
public ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer() {
|
||||||
|
return createThreadPoolTaskExecutor(1, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name = "taskExecutorIdGeneratorAwaiter")
|
||||||
|
public ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter() {
|
||||||
|
return createThreadPoolTaskExecutor(1, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Bean
|
||||||
|
public ImdgProvider imdgProvider(
|
||||||
|
@Qualifier("taskExecutorHazelcastClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer,
|
||||||
|
@Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
|
||||||
|
HazelcastSettings clientSetting
|
||||||
|
) {
|
||||||
|
return new HazelcastService(taskExecutorHazelcastClientInitializer,
|
||||||
|
taskExecutorIdGeneratorAwaiter,
|
||||||
|
clientSetting);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static ThreadPoolTaskExecutor createThreadPoolTaskExecutor(int maxPoolSz, boolean waitForCompletion) {
|
||||||
|
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
|
||||||
|
if (maxPoolSz > 2) {
|
||||||
|
pool.setKeepAliveSeconds(60);
|
||||||
|
pool.setAllowCoreThreadTimeOut(true);
|
||||||
|
}
|
||||||
|
pool.setCorePoolSize(maxPoolSz);
|
||||||
|
pool.setWaitForTasksToCompleteOnShutdown(waitForCompletion);
|
||||||
|
return pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package ru.spcex.clearing.backendapi.config;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.PropertySource;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@PropertySource("file:${spring.config.location}/application.properties")
|
||||||
|
@ConfigurationProperties("backend-api.hazelcast")
|
||||||
|
public class HazelcastSettings extends HazelcastClientParams {
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,9 @@ server.servlet.context-path=/backend-api
|
||||||
spring.main.web-application-type=servlet
|
spring.main.web-application-type=servlet
|
||||||
|
|
||||||
backend-api.example-setting=test
|
backend-api.example-setting=test
|
||||||
|
backend-api.hazelcast.cluster-members=127.0.0.1
|
||||||
|
backend-api.hazelcast.login=dev
|
||||||
|
backend-api.hazelcast.password=dev-pass
|
||||||
|
|
||||||
|
|
||||||
##keycloak
|
##keycloak
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,24 @@
|
||||||
<artifactId>hazelcast-all</artifactId>
|
<artifactId>hazelcast-all</artifactId>
|
||||||
<version>${external_libraries.hazelcast.version}</version>
|
<version>${external_libraries.hazelcast.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ru.spcex.platform</groupId>
|
||||||
|
<artifactId>platform-imdg-api-hazelcast-impl</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<finalName>jar/${project.artifactId}</finalName>
|
<finalName>jar/${project.artifactId}</finalName>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<excludes>
|
||||||
|
<exclude>application.properties</exclude>
|
||||||
|
</excludes>
|
||||||
|
<filtering>false</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,12 @@ public class HazelcastConfiguration {
|
||||||
|
|
||||||
private ConfigurationRootElement configRoot = DfaConfig.get().getRoot();
|
private ConfigurationRootElement configRoot = DfaConfig.get().getRoot();
|
||||||
private final PoolMapConfigs poolMapConfigs;
|
private final PoolMapConfigs poolMapConfigs;
|
||||||
|
private final HazelcastServerElement hzSettings;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public HazelcastConfiguration(PoolMapConfigs poolMapConfigs) {
|
public HazelcastConfiguration(PoolMapConfigs poolMapConfigs, ImdgSettings imdgSettings) {
|
||||||
this.poolMapConfigs = poolMapConfigs;
|
this.poolMapConfigs = poolMapConfigs;
|
||||||
|
this.hzSettings = imdgSettings.getHazelcast();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|
@ -37,7 +39,7 @@ public class HazelcastConfiguration {
|
||||||
.setMulticastConfig(new MulticastConfig()
|
.setMulticastConfig(new MulticastConfig()
|
||||||
.setEnabled(false))
|
.setEnabled(false))
|
||||||
.setTcpIpConfig(new TcpIpConfig()
|
.setTcpIpConfig(new TcpIpConfig()
|
||||||
.setEnabled(true)
|
.setEnabled(true).setMembers(hzSettings.getClusterMembers())
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
package ru.spcex.clearing.imdg.config;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class HazelcastServerElement {
|
||||||
|
|
||||||
|
private int listenPort = 5071;
|
||||||
|
private String login = "dev";
|
||||||
|
private String password = "dev-pass";
|
||||||
|
private List<String> clusterMembers;
|
||||||
|
|
||||||
|
public int getListenPort() {
|
||||||
|
return listenPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setListenPort(int listenPort) {
|
||||||
|
this.listenPort = listenPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLogin() {
|
||||||
|
return login;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLogin(String login) {
|
||||||
|
this.login = login;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getClusterMembers() {
|
||||||
|
return clusterMembers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClusterMembers(List<String> clusterMembers) {
|
||||||
|
this.clusterMembers = clusterMembers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package ru.spcex.clearing.imdg.config;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.PropertySource;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@PropertySource("file:${spring.config.location}/application.properties")
|
||||||
|
@ConfigurationProperties("imdg")
|
||||||
|
public class ImdgSettings {
|
||||||
|
|
||||||
|
private HazelcastServerElement hazelcast;
|
||||||
|
|
||||||
|
public HazelcastServerElement getHazelcast() {
|
||||||
|
return hazelcast;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHazelcast(HazelcastServerElement hazelcast) {
|
||||||
|
this.hazelcast = hazelcast;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,6 +15,7 @@ import ru.clearing.classes.objects.BusinessObject;
|
||||||
import ru.spcex.clearing.imdg.base.DictionaryMapStore;
|
import ru.spcex.clearing.imdg.base.DictionaryMapStore;
|
||||||
import ru.spcex.clearing.imdg.base.SimpleObjectMapStore;
|
import ru.spcex.clearing.imdg.base.SimpleObjectMapStore;
|
||||||
import ru.spcex.clearing.imdg.utils.IMDGDistributedNames;
|
import ru.spcex.clearing.imdg.utils.IMDGDistributedNames;
|
||||||
|
import ru.spcex.platform.imdg.iml.hazelcast.util.HazelcastHelper;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -125,7 +126,7 @@ public abstract class AbstractHazelcastLifecycleSupport implements InitializingB
|
||||||
throw new RuntimeException("MapStore multithreaded not complete.", e);
|
throw new RuntimeException("MapStore multithreaded not complete.", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// HazelcastCommon.otcSystem_setStorageState(true, hazelcastServerInstance); todo в других модулях может быть проверка на это, и должна быть.
|
HazelcastHelper.otcSystem_setStorageState(true, hazelcastServerInstance);
|
||||||
// hazelcastServerInstance.getClientService().addClientListener(clientListener);
|
// hazelcastServerInstance.getClientService().addClientListener(clientListener);
|
||||||
loadTime = System.currentTimeMillis() - loadTime;
|
loadTime = System.currentTimeMillis() - loadTime;
|
||||||
log.info("All map load time {} ms", loadTime);
|
log.info("All map load time {} ms", loadTime);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
imdg.hazelcast.cluster-members[0]=127.0.0.1
|
||||||
65
platform-parent/platform-imdg-api-hazelcast-impl/pom.xml
Normal file
65
platform-parent/platform-imdg-api-hazelcast-impl/pom.xml
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>platform-parent</artifactId>
|
||||||
|
<groupId>ru.spcex.platform</groupId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>platform-imdg-api-hazelcast-impl</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ru.spcex.platform</groupId>
|
||||||
|
<artifactId>platform-imdg-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ru.spcex.platform</groupId>
|
||||||
|
<artifactId>platform-utils</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.hazelcast</groupId>
|
||||||
|
<artifactId>hazelcast-all</artifactId>
|
||||||
|
<version>${external_libraries.hazelcast.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>${external_libraries.logback.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-core</artifactId>
|
||||||
|
<version>${external_libraries.logback.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<version>${external_libraries.slf4j.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-core</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package ru.spcex.platform.imdg.iml.hazelcast.adapter;
|
||||||
|
|
||||||
|
import com.hazelcast.core.IMap;
|
||||||
|
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||||
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
|
|
||||||
|
public class ImdgHazelcast<T extends SpcexObjectBase> implements Imdg<T> {
|
||||||
|
|
||||||
|
private IMap<Long, T> map;
|
||||||
|
|
||||||
|
public IMap<Long, T> getMap() {
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMap(IMap<Long, T> map) {
|
||||||
|
this.map = map;
|
||||||
|
}
|
||||||
|
//todo implement methods
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
package ru.spcex.platform.imdg.iml.hazelcast.config;
|
||||||
|
|
||||||
|
import com.hazelcast.config.NearCacheConfig;
|
||||||
|
|
||||||
|
@SuppressWarnings({"FieldCanBeLocal", "unused"})
|
||||||
|
public class HazelcastClientParams {
|
||||||
|
|
||||||
|
public HazelcastClientParams() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private String clusterMembers;
|
||||||
|
|
||||||
|
private String login;
|
||||||
|
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private String instanceName;
|
||||||
|
|
||||||
|
private NearCacheConfig nearCacheConfig;
|
||||||
|
|
||||||
|
public String getClusterMembers() {
|
||||||
|
return clusterMembers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClusterMembers(String clusterMembers) {
|
||||||
|
this.clusterMembers = clusterMembers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLogin() {
|
||||||
|
return login;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLogin(String login) {
|
||||||
|
this.login = login;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInstanceName() {
|
||||||
|
return instanceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInstanceName(String instanceName) {
|
||||||
|
this.instanceName = instanceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NearCacheConfig getNearCacheConfig() {
|
||||||
|
return nearCacheConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNearCacheConfig(NearCacheConfig nearCacheConfig) {
|
||||||
|
this.nearCacheConfig = nearCacheConfig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package ru.spcex.platform.imdg.iml.hazelcast.service;
|
||||||
|
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
|
import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams;
|
||||||
|
|
||||||
|
public final class HazelcastService extends HazelcastServiceBase implements InitializingBean, DisposableBean {
|
||||||
|
|
||||||
|
public HazelcastService(ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer,
|
||||||
|
ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
|
||||||
|
HazelcastClientParams hazelcastClientParams) {
|
||||||
|
super(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, hazelcastClientParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init() {
|
||||||
|
taskExecutorHazelcastClientInitializer.submit(this::reinitializeHazelcastClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scheduled(cron = "* 0 0 * * *")
|
||||||
|
@Override
|
||||||
|
protected void reloadClient() {
|
||||||
|
super.reloadClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,259 @@
|
||||||
|
package ru.spcex.platform.imdg.iml.hazelcast.service;
|
||||||
|
|
||||||
|
import com.hazelcast.client.HazelcastClient;
|
||||||
|
import com.hazelcast.client.config.ClientConfig;
|
||||||
|
import com.hazelcast.core.HazelcastInstance;
|
||||||
|
import com.hazelcast.core.LifecycleEvent;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
|
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||||
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
|
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||||
|
import ru.spcex.platform.imdg.iml.hazelcast.adapter.ImdgHazelcast;
|
||||||
|
import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams;
|
||||||
|
import ru.spcex.platform.imdg.iml.hazelcast.util.HazelcastHelper;
|
||||||
|
import ru.spcex.platform.utils.log.ExceptionUtils;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public abstract class HazelcastServiceBase
|
||||||
|
// implements IHazelcastService
|
||||||
|
implements ImdgProvider
|
||||||
|
{
|
||||||
|
protected final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
public final int SLEEP_AFTER_RELOAD_MS = 5000;
|
||||||
|
protected String mapNameForCache;
|
||||||
|
protected final ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer;
|
||||||
|
protected final ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter;
|
||||||
|
protected final HazelcastClientParams settingsElementHazelcastClient;
|
||||||
|
|
||||||
|
protected final Collection<IHazelcastClusterStatus> hazelcastStatusSubscribers = new ArrayList<>();
|
||||||
|
protected HazelcastInstance hazelcastInstance;
|
||||||
|
protected volatile boolean isAvailableNow;
|
||||||
|
private Environment environment;
|
||||||
|
|
||||||
|
public HazelcastServiceBase(
|
||||||
|
ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer,
|
||||||
|
ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
|
||||||
|
HazelcastClientParams settingsElementHazelcastClient,
|
||||||
|
Environment environment) {
|
||||||
|
this.taskExecutorIdGeneratorAwaiter = taskExecutorIdGeneratorAwaiter;
|
||||||
|
this.taskExecutorHazelcastClientInitializer = taskExecutorHazelcastClientInitializer;
|
||||||
|
this.settingsElementHazelcastClient = settingsElementHazelcastClient;
|
||||||
|
this.environment = environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HazelcastServiceBase(
|
||||||
|
ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer,
|
||||||
|
ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
|
||||||
|
HazelcastClientParams settingsElementHazelcastClient) {
|
||||||
|
this.taskExecutorIdGeneratorAwaiter = taskExecutorIdGeneratorAwaiter;
|
||||||
|
this.taskExecutorHazelcastClientInitializer = taskExecutorHazelcastClientInitializer;
|
||||||
|
this.settingsElementHazelcastClient = settingsElementHazelcastClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createHazelcastClient() {
|
||||||
|
if (hazelcastInstance != null) {
|
||||||
|
try {
|
||||||
|
hazelcastInstance.shutdown();
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.info("Hazelcast: client init");
|
||||||
|
ClientConfig clientConfig = HazelcastHelper.getClientConfig(
|
||||||
|
settingsElementHazelcastClient.getClusterMembers(),
|
||||||
|
settingsElementHazelcastClient.getLogin(),
|
||||||
|
settingsElementHazelcastClient.getPassword(),
|
||||||
|
settingsElementHazelcastClient.getInstanceName(),
|
||||||
|
settingsElementHazelcastClient.getNearCacheConfig()
|
||||||
|
);
|
||||||
|
if (environment != null && Arrays.asList(environment.getActiveProfiles()).contains("tests")) {
|
||||||
|
clientConfig.getNetworkConfig().setConnectionAttemptLimit(HazelcastHelper.TEST_CONNECTION_ATTEMPT_LIMIT);
|
||||||
|
}
|
||||||
|
log.info("Hazelcast: client created, trying connect to server ({}) ...", settingsElementHazelcastClient.getClusterMembers());
|
||||||
|
hazelcastInstance = HazelcastClient.newHazelcastClient(clientConfig);
|
||||||
|
log.info("Hazelcast: client created and connected");
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
public void reinitializeHazelcastClient() {
|
||||||
|
try {
|
||||||
|
createHazelcastClient();
|
||||||
|
Thread.sleep(100); // await for skip CLIENT_CONNECTED event. See warn "Hazelcast already available, but has call onAvailable() again."
|
||||||
|
awaitGeneratorId();
|
||||||
|
hazelcastInstance.getLifecycleService().addLifecycleListener((LifecycleEvent event) -> {
|
||||||
|
switch (event.getState()) {
|
||||||
|
case CLIENT_CONNECTED:
|
||||||
|
log.info("Hazelcast: event connected");
|
||||||
|
awaitGeneratorId();
|
||||||
|
break;
|
||||||
|
case CLIENT_DISCONNECTED:
|
||||||
|
log.info("Hazelcast: event disconnected");
|
||||||
|
onUnavailable();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable e) {
|
||||||
|
log.error("reinitializeHazelcastClient() has error: {}", ExceptionUtils.getStackTrace(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onAvailable() {
|
||||||
|
if (isAvailableNow) {
|
||||||
|
log.warn("Hazelcast already available, but has call onAvailable() again. Ignore.");
|
||||||
|
return; // пропустить
|
||||||
|
}
|
||||||
|
isAvailableNow = false;
|
||||||
|
synchronized (hazelcastStatusSubscribers) {
|
||||||
|
hazelcastStatusSubscribers.forEach(hazelcastStatusSubscriber -> {
|
||||||
|
log.trace("hazelcastStatusSubscribers call> {}", hazelcastStatusSubscriber);
|
||||||
|
try {
|
||||||
|
hazelcastStatusSubscriber.getAvailable(hazelcastInstance);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
log.warn(ExceptionUtils.getStackTrace(e));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
isAvailableNow = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onUnavailable() {
|
||||||
|
if (!isAvailableNow)
|
||||||
|
log.warn("Hazelcast already unavailable, but has call onUnavailable() again.");
|
||||||
|
isAvailableNow = false;
|
||||||
|
synchronized (hazelcastStatusSubscribers) {
|
||||||
|
hazelcastStatusSubscribers.forEach(hazelcastStatusSubscriber -> {
|
||||||
|
log.trace("hazelcastStatusSubscribers call unavailable> {}", hazelcastStatusSubscriber);
|
||||||
|
try {
|
||||||
|
hazelcastStatusSubscriber.getUnavailable(hazelcastInstance);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
log.warn(ExceptionUtils.getStackTrace(e));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (isAvailableNow) { // never: если успел проскочить между isAvailableNow = false и synchronized
|
||||||
|
log.warn("Concurrent call onAvailable() and onUnavailable(). Stacktrace: {}", ExceptionUtils.getStackTrace(new ConcurrentModificationException("Warning")));
|
||||||
|
isAvailableNow = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void reloadClient() {
|
||||||
|
String logMsg = "Reloading Hazelcast client:";
|
||||||
|
Date dtStart = new Date();
|
||||||
|
try {
|
||||||
|
onUnavailable();
|
||||||
|
Thread.sleep(SLEEP_AFTER_RELOAD_MS);
|
||||||
|
reinitializeHazelcastClient();
|
||||||
|
logMsg = String.format("%s done OK! (duration=%dms)",
|
||||||
|
logMsg, (new Date()).getTime() - dtStart.getTime());
|
||||||
|
} catch (Throwable e) {
|
||||||
|
logMsg = String.format("%s error (duration=%dms):\n%s",
|
||||||
|
logMsg, (new Date()).getTime() - dtStart.getTime(), ExceptionUtils.getStackTrace(e));
|
||||||
|
} finally {
|
||||||
|
log.info(logMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void awaitGeneratorId() {
|
||||||
|
taskExecutorIdGeneratorAwaiter.execute(() -> {
|
||||||
|
try {
|
||||||
|
// ожидание инициализации Storage (только после инициализации IDGenerator начинать работу).
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
log.debug("Execute awaitGeneratorId()");
|
||||||
|
try {
|
||||||
|
HazelcastHelper.otcSystem_waitTillReadyState(getHazelcast());
|
||||||
|
onAvailable();
|
||||||
|
done = true;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
log.info(String.format("Waiting Hazelcast: %s -> %s", e.getClass().getSimpleName(), e.getMessage()));
|
||||||
|
createHazelcastClient();
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
log.warn("awaitGeneratorId thread interrupted!");
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// проверка версии классов
|
||||||
|
// HazelcastCommon.verifyVersionClientsClasses(hazelcastInstance);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
log.error("Error at awaitGeneratorId(): {}", ExceptionUtils.getStackTrace(e));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
public void statusSubscribe(IHazelcastClusterStatus clusterStatus) {
|
||||||
|
log.trace("hazelcastStatusSubscribers add> {}", clusterStatus);
|
||||||
|
synchronized (hazelcastStatusSubscribers) {
|
||||||
|
if (hazelcastStatusSubscribers.contains(clusterStatus)) // never
|
||||||
|
throw new IllegalStateException("ClusterStatus listener " + clusterStatus + " already added!");
|
||||||
|
hazelcastStatusSubscribers.add(clusterStatus);
|
||||||
|
if (isAvailableNow) { // register now
|
||||||
|
log.trace("hazelcastStatusSubscribers added and call now> {}", clusterStatus);
|
||||||
|
try {
|
||||||
|
clusterStatus.getAvailable(hazelcastInstance);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
log.warn(ExceptionUtils.getStackTrace(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
public HazelcastInstance getHazelcast() {
|
||||||
|
return hazelcastInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends SpcexObjectBase> Imdg<T> getImdg(String key, Class<T> clazz) {
|
||||||
|
ImdgHazelcast<T> imdg = new ImdgHazelcast<>();
|
||||||
|
imdg.setMap(getHazelcast().getMap(key));
|
||||||
|
return imdg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
public void waitTillReadyState() throws InterruptedException {
|
||||||
|
boolean done = false;
|
||||||
|
int sleepCount = 0;
|
||||||
|
while (!done) {
|
||||||
|
try {
|
||||||
|
HazelcastInstance instance = getHazelcast();
|
||||||
|
if (instance != null) {
|
||||||
|
HazelcastHelper.otcSystem_waitTillReadyState(instance);
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if (sleepCount++ % 30 == 0)
|
||||||
|
log.debug("Hazelcast not connected. Wait till STORAGE be ready...");
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.warn(String.format("Waiting Hazelcast interrupted: %s -> %s", e.getClass().getSimpleName(), e.getMessage()));
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
Thread.sleep(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
public void shutdown() {
|
||||||
|
isAvailableNow = false;
|
||||||
|
if (hazelcastInstance != null)
|
||||||
|
hazelcastInstance.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMapNameForCache() {
|
||||||
|
return mapNameForCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMapNameForCache(String mapNameForCache) {
|
||||||
|
this.mapNameForCache = mapNameForCache;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package ru.spcex.platform.imdg.iml.hazelcast.service;
|
||||||
|
|
||||||
|
import com.hazelcast.core.HazelcastInstance;
|
||||||
|
|
||||||
|
public interface IHazelcastClusterStatus {
|
||||||
|
void getAvailable(HazelcastInstance hazelcastNotInited);
|
||||||
|
|
||||||
|
void getUnavailable(HazelcastInstance hazelcastNotInited);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,130 @@
|
||||||
|
package ru.spcex.platform.imdg.iml.hazelcast.util;
|
||||||
|
|
||||||
|
import com.hazelcast.client.HazelcastClient;
|
||||||
|
import com.hazelcast.client.config.ClientConfig;
|
||||||
|
import com.hazelcast.client.config.ClientNetworkConfig;
|
||||||
|
import com.hazelcast.config.NearCacheConfig;
|
||||||
|
import com.hazelcast.core.HazelcastException;
|
||||||
|
import com.hazelcast.core.HazelcastInstance;
|
||||||
|
import com.hazelcast.core.IMap;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public final class HazelcastHelper {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(HazelcastHelper.class);
|
||||||
|
|
||||||
|
public static final int DEFAULT_CONNECTION_TIMEOUT_SEC = 30;
|
||||||
|
public static final int DEFAULT_CONNECTION_ATTEMPT_PERIOD_SEC = 10;
|
||||||
|
public static final int DEFAULT_CONNECTION_ATTEMPT_LIMIT = Integer.MAX_VALUE;
|
||||||
|
public static final int TEST_CONNECTION_ATTEMPT_LIMIT = 1;
|
||||||
|
public static final String OTC_SYSTEM_MAP = "OTC_SYSTEM";
|
||||||
|
|
||||||
|
public static ClientConfig getClientConfig(String members, String login, String password, String instanceName) {
|
||||||
|
return getClientConfig(members, login, password, instanceName, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClientConfig getClientConfig(String members, String login, String password, String instanceName, NearCacheConfig nearCacheConfig) {
|
||||||
|
if (members == null) {
|
||||||
|
throw new IllegalArgumentException("members must not be null!");
|
||||||
|
}
|
||||||
|
String[] mm = members.split(",");
|
||||||
|
if (mm.length == 0) {
|
||||||
|
throw new IllegalArgumentException("members must not be empty!");
|
||||||
|
}
|
||||||
|
ClientNetworkConfig clientNetworkConfig = new ClientNetworkConfig();
|
||||||
|
for (String m : mm) {
|
||||||
|
if (m != null && !m.isEmpty()) {
|
||||||
|
clientNetworkConfig.addAddress(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ClientConfig config = new ClientConfig();
|
||||||
|
config.setInstanceName(instanceName);
|
||||||
|
config.setNetworkConfig(clientNetworkConfig);
|
||||||
|
|
||||||
|
config.setProperty("hazelcast.logging.type", "slf4j");
|
||||||
|
|
||||||
|
config.getGroupConfig().setName(login);
|
||||||
|
config.getGroupConfig().setPassword(password);
|
||||||
|
|
||||||
|
config.getNetworkConfig().setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT_SEC * 1000);
|
||||||
|
config.getNetworkConfig().setConnectionAttemptPeriod(DEFAULT_CONNECTION_ATTEMPT_PERIOD_SEC * 1000);
|
||||||
|
config.getNetworkConfig().setConnectionAttemptLimit(DEFAULT_CONNECTION_ATTEMPT_LIMIT);
|
||||||
|
|
||||||
|
if (nearCacheConfig != null) config.addNearCacheConfig(nearCacheConfig);
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Создаёт клиента HazelcastInstance, подключённого по настрйокам ClientConfig.
|
||||||
|
* Ожидает готовности Storage, инициализирует TextErrorService.
|
||||||
|
* В случае ошибок делает повторение попыток создания клиента.
|
||||||
|
* <p>
|
||||||
|
* Пример получения ClientConfig:
|
||||||
|
* <code>
|
||||||
|
* HazelcastHelper.getClientConfig(
|
||||||
|
* Config.get().getHazelcastSettings().getClusterMembers(),
|
||||||
|
* Config.get().getHazelcastSettings().getLogin(),
|
||||||
|
* Config.get().getHazelcastSettings().getPassword()
|
||||||
|
* )
|
||||||
|
* </code>
|
||||||
|
*
|
||||||
|
* @param hzClientConfig
|
||||||
|
* @return HazelcastClient
|
||||||
|
*/
|
||||||
|
public HazelcastInstance makeHazelcastClientAndWaitTillReady(ClientConfig hzClientConfig) {
|
||||||
|
HazelcastInstance instance = null;
|
||||||
|
// ожидание инициализации Storage (только после инициализации IDGenerator начинать работу).
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
try {
|
||||||
|
instance = HazelcastClient.newHazelcastClient(hzClientConfig);// createHzClient();
|
||||||
|
otcSystem_waitTillReadyState(instance);
|
||||||
|
// TextErrorService.setHazelcast(instance);
|
||||||
|
log.info("Hazelcast: TextErrorService done");
|
||||||
|
done = true;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException("Thread interrupted when waiting storage ready.", e);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info(String.format("Waiting Hazelcast: %s -> %s", e.getClass().getSimpleName(), e.getMessage()));
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
throw new RuntimeException("Thread interrupted.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// проверка версии классов
|
||||||
|
// HazelcastCommon.verifyVersionClientsClasses(instance);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void otcSystem_waitTillReadyState(HazelcastInstance hazelcast) throws InterruptedException {
|
||||||
|
int sleepCount = 0;
|
||||||
|
try {
|
||||||
|
while (!otcSystem_getStorageState(hazelcast)) {
|
||||||
|
if (sleepCount++ % 30 == 0)
|
||||||
|
log.info("Wait till STORAGE be ready...");
|
||||||
|
Thread.sleep(100);
|
||||||
|
}
|
||||||
|
} catch (HazelcastException hcEx) {
|
||||||
|
// проброс InterruptException из Hazelcast
|
||||||
|
if (hcEx instanceof HazelcastException && hcEx.getCause() instanceof InterruptedException)
|
||||||
|
throw new InterruptedException("Can not obtain storage for check state, cause has interrupted. " + hcEx);
|
||||||
|
throw hcEx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean otcSystem_getStorageState(HazelcastInstance hazelcast) {
|
||||||
|
IMap<String, String> systemMap = hazelcast.getMap(OTC_SYSTEM_MAP);
|
||||||
|
return Boolean.valueOf(systemMap.get("STORAGE.STATE"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void otcSystem_setStorageState(boolean val, HazelcastInstance hazelcast) {
|
||||||
|
IMap<String, String> systemMap = hazelcast.getMap(OTC_SYSTEM_MAP);
|
||||||
|
systemMap.set("STORAGE.STATE", Boolean.toString(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
package ru.spcex.platform.imdg.api;
|
||||||
|
|
||||||
|
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public interface Imdg<T extends SpcexObjectBase> {
|
||||||
|
default void insert(T paramT) {
|
||||||
|
throw new UnsupportedOperationException("not implemented insert");
|
||||||
|
}
|
||||||
|
|
||||||
|
default void update(T paramT) {
|
||||||
|
throw new UnsupportedOperationException("not implemented update");
|
||||||
|
}
|
||||||
|
|
||||||
|
default void delete(T paramT) {
|
||||||
|
throw new UnsupportedOperationException("not implemented delete");
|
||||||
|
}
|
||||||
|
|
||||||
|
default Long nextIDSequenceFor() {
|
||||||
|
throw new UnsupportedOperationException("not implemented nextIDSequenceFor");
|
||||||
|
}
|
||||||
|
|
||||||
|
default Collection<T> getCollectionObjectsBySQL(String paramString) {
|
||||||
|
throw new UnsupportedOperationException("not implemented getCollectionObjectsBySQL");
|
||||||
|
}
|
||||||
|
|
||||||
|
default T getSingleObjectBySQL(String paramString) {
|
||||||
|
throw new UnsupportedOperationException("not implemented getSingleObjectBySQL");
|
||||||
|
}
|
||||||
|
|
||||||
|
default T getSingleObjectByID(Long paramLong) {
|
||||||
|
throw new UnsupportedOperationException("not implemented getSingleObjectByID");
|
||||||
|
}
|
||||||
|
|
||||||
|
default Collection<Long> getCollectionIdsBySQL(String paramString) {
|
||||||
|
throw new UnsupportedOperationException("not implemented getCollectionIdsBySQL");
|
||||||
|
}
|
||||||
|
|
||||||
|
default Collection<T> getAllValues() {
|
||||||
|
throw new UnsupportedOperationException("not implemented getAllValues");
|
||||||
|
}
|
||||||
|
|
||||||
|
default <A> Collection<A> projectionsAttributeBySql(String paramString, String... paramVarArgs) {
|
||||||
|
throw new UnsupportedOperationException("not implemented projectionsAttributeBySql");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package ru.spcex.platform.imdg.api;
|
||||||
|
|
||||||
|
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||||
|
|
||||||
|
public interface ImdgProvider {
|
||||||
|
/**
|
||||||
|
* пока простой интерфейс для получения доступа к мапам
|
||||||
|
*/
|
||||||
|
public <T extends SpcexObjectBase> Imdg<T> getImdg(String key, Class<T> clazz);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
package ru.spcex.platform.imdg.api;
|
|
||||||
|
|
||||||
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public interface Storage {
|
|
||||||
<T extends SpcexObjectBase> void insert(Class<T> paramClass, T paramT);
|
|
||||||
|
|
||||||
<T extends SpcexObjectBase> void update(Class<T> paramClass, T paramT);
|
|
||||||
|
|
||||||
<T extends SpcexObjectBase> void delete(Class<T> paramClass, T paramT);
|
|
||||||
|
|
||||||
Long nextIDSequenceFor();
|
|
||||||
|
|
||||||
<T> Collection<T> getCollectionObjectsBySQL(Class<T> paramClass, String paramString);
|
|
||||||
|
|
||||||
<T> T getSingleObjectBySQL(Class<T> paramClass, String paramString);
|
|
||||||
|
|
||||||
<T> T getSingleObjectByID(Class<T> paramClass, Long paramLong);
|
|
||||||
|
|
||||||
<T> Collection<Long> getCollectionIdsBySQL(Class<T> paramClass, String paramString);
|
|
||||||
|
|
||||||
<T> Collection<T> getAllValues(Class<T> paramClass);
|
|
||||||
|
|
||||||
<T, A> Collection<A> projectionsAttributeBySql(Class<T> paramClass, String paramString, String... paramVarArgs);
|
|
||||||
}
|
|
||||||
22
platform-parent/platform-utils/pom.xml
Normal file
22
platform-parent/platform-utils/pom.xml
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>platform-utils</artifactId>
|
||||||
|
<name>Platform utilities</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<artifactId>platform-parent</artifactId>
|
||||||
|
<groupId>ru.spcex.platform</groupId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package ru.spcex.platform.utils.log;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
public class ExceptionUtils {
|
||||||
|
public static String getStackTrace(Throwable throwable) {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
PrintWriter pw = new PrintWriter(sw, true);
|
||||||
|
throwable.printStackTrace(pw);
|
||||||
|
return sw.getBuffer().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,5 +20,7 @@
|
||||||
<modules>
|
<modules>
|
||||||
<module>platform-imdg-api</module>
|
<module>platform-imdg-api</module>
|
||||||
<module>platform-classes-base</module>
|
<module>platform-classes-base</module>
|
||||||
|
<module>platform-imdg-api-hazelcast-impl</module>
|
||||||
|
<module>platform-utils</module>
|
||||||
</modules>
|
</modules>
|
||||||
</project>
|
</project>
|
||||||
21
pom.xml
21
pom.xml
|
|
@ -31,10 +31,13 @@
|
||||||
<!--suppress UnresolvedMavenProperty -->
|
<!--suppress UnresolvedMavenProperty -->
|
||||||
<folder_root_clearing>${folder_root_clearing_temp}</folder_root_clearing>
|
<folder_root_clearing>${folder_root_clearing_temp}</folder_root_clearing>
|
||||||
<folder_root_clearing_backend-api>${folder_root_clearing}/clearing-parent/backend-api</folder_root_clearing_backend-api>
|
<folder_root_clearing_backend-api>${folder_root_clearing}/clearing-parent/backend-api</folder_root_clearing_backend-api>
|
||||||
|
<folder_root_clearing_imdg>${folder_root_clearing}/clearing-parent/imdg</folder_root_clearing_imdg>
|
||||||
<folder_root_dbf-exporter>${folder_root_clearing}/clearing-parent/dbf-exporter</folder_root_dbf-exporter>
|
<folder_root_dbf-exporter>${folder_root_clearing}/clearing-parent/dbf-exporter</folder_root_dbf-exporter>
|
||||||
<folder_root_dbf-importer>${folder_root_clearing}/clearing-parent/dbf-importer</folder_root_dbf-importer>
|
<folder_root_dbf-importer>${folder_root_clearing}/clearing-parent/dbf-importer</folder_root_dbf-importer>
|
||||||
<!-- IMDG -->
|
<!-- IMDG -->
|
||||||
<external_libraries.hazelcast.version>3.12.4</external_libraries.hazelcast.version>
|
<external_libraries.hazelcast.version>3.12.4</external_libraries.hazelcast.version>
|
||||||
|
<external_libraries.slf4j.version>1.7.33</external_libraries.slf4j.version>
|
||||||
|
<external_libraries.logback.version>1.2.10</external_libraries.logback.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
|
|
@ -52,6 +55,11 @@
|
||||||
<artifactId>backend-api</artifactId>
|
<artifactId>backend-api</artifactId>
|
||||||
<version>${global.project.version}</version>
|
<version>${global.project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ru.spcex.clearing</groupId>
|
||||||
|
<artifactId>imdg</artifactId>
|
||||||
|
<version>${global.project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ru.spcex.clearing</groupId>
|
<groupId>ru.spcex.clearing</groupId>
|
||||||
<artifactId>classes</artifactId>
|
<artifactId>classes</artifactId>
|
||||||
|
|
@ -73,6 +81,19 @@
|
||||||
<artifactId>platform-classes-base</artifactId>
|
<artifactId>platform-classes-base</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>ru.spcex.platform</groupId>
|
||||||
|
<artifactId>platform-imdg-api-hazelcast-impl</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>ru.spcex.platform</groupId>
|
||||||
|
<artifactId>platform-utils</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ru.spcex.platform</groupId>
|
<groupId>ru.spcex.platform</groupId>
|
||||||
<artifactId>platform-imdg-api</artifactId>
|
<artifactId>platform-imdg-api</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,10 @@
|
||||||
<groupId>ru.spcex.clearing</groupId>
|
<groupId>ru.spcex.clearing</groupId>
|
||||||
<artifactId>backend-api</artifactId>
|
<artifactId>backend-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ru.spcex.clearing</groupId>
|
||||||
|
<artifactId>imdg</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
|
|
@ -106,6 +110,25 @@
|
||||||
</fileSets>
|
</fileSets>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>copy-imdg-bin</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<fileSets>
|
||||||
|
<fileSet>
|
||||||
|
<sourceFile>${folder_root_clearing_imdg}/target/jar/imdg-exec.jar</sourceFile>
|
||||||
|
<destinationFile>${folder.clearing.distr.modules}/imdg/imdg-exec.jar</destinationFile>
|
||||||
|
</fileSet>
|
||||||
|
<fileSet>
|
||||||
|
<sourceFile>${folder_root_clearing_imdg}/src/main/resources/application.properties</sourceFile>
|
||||||
|
<destinationFile>${folder.clearing.distr.modules}/imdg/application.properties</destinationFile>
|
||||||
|
</fileSet>
|
||||||
|
</fileSets>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
|
||||||
<execution>
|
<execution>
|
||||||
<id>copy-dbf-exporter-bin</id>
|
<id>copy-dbf-exporter-bin</id>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue