Storage. Начало. Уже скомпилируется.
This commit is contained in:
parent
29828d8f07
commit
e3e2a27a82
46 changed files with 2264 additions and 4 deletions
37
clearing-classes/pom.xml
Normal file
37
clearing-classes/pom.xml
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?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>clearing-classes</artifactId>
|
||||
<name>Clearing classes</name>
|
||||
<description>Clearing classes module</description>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<artifactId>clearing</artifactId>
|
||||
<groupId>ru.spcex.clearing</groupId>
|
||||
<version>SPCEX-1.0.0.0</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.moex.platform</groupId>-->
|
||||
<!-- <artifactId>platform-common</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.moex.platform</groupId>-->
|
||||
<!-- <artifactId>platform-errors</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}-${project.version}</finalName>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package ru.clearing.classes;
|
||||
|
||||
/**
|
||||
* В случае любых изменений модуля classes необходимо изменить serialVersionUID++
|
||||
*/
|
||||
public interface ConstSerializable {
|
||||
long serialVersionUID = 293236453420L;
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package ru.clearing.classes.StaticData.Company;
|
||||
|
||||
import ru.clearing.classes.ConstSerializable;
|
||||
import ru.clearing.classes.objects.BusinessObject;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class Company extends BusinessObject {
|
||||
private static final long serialVersionUID = ConstSerializable.serialVersionUID;
|
||||
|
||||
private String clearingCode;
|
||||
private String exchangeCode;
|
||||
private String fullName;
|
||||
// private CompanyInfo profile; // todo impl profile
|
||||
private Long statusId; // WorkflowStatusDictionary
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Company{" +
|
||||
"clearingCode='" + clearingCode + '\'' +
|
||||
", exchangeCode='" + exchangeCode + '\'' +
|
||||
", fullName='" + fullName + '\'' +
|
||||
", statusId=" + statusId +
|
||||
'}';
|
||||
}
|
||||
|
||||
public String getClearingCode() {
|
||||
return clearingCode;
|
||||
}
|
||||
|
||||
public void setClearingCode(String clearingCode) {
|
||||
this.clearingCode = clearingCode;
|
||||
}
|
||||
|
||||
public String getExchangeCode() {
|
||||
return exchangeCode;
|
||||
}
|
||||
|
||||
public void setExchangeCode(String exchangeCode) {
|
||||
this.exchangeCode = exchangeCode;
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
public void setFullName(String fullName) {
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
public Long getStatusId() {
|
||||
return statusId;
|
||||
}
|
||||
|
||||
public void setStatusId(Long statusId) {
|
||||
this.statusId = statusId;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package ru.clearing.classes.StaticData.Company;
|
||||
|
||||
import ru.clearing.classes.ConstSerializable;
|
||||
import ru.clearing.classes.objects.ObjectBase;
|
||||
|
||||
/**
|
||||
* DB: COMPANY_ROLE_SET
|
||||
*/
|
||||
public class CompanyRoleSet extends ObjectBase {
|
||||
private static final long serialVersionUID = ConstSerializable.serialVersionUID;
|
||||
|
||||
private Long roleId;
|
||||
private Long companyId;
|
||||
|
||||
public Long getRoleId() {
|
||||
return roleId;
|
||||
}
|
||||
|
||||
public void setRoleId(Long roleId) {
|
||||
this.roleId = roleId;
|
||||
}
|
||||
|
||||
public Long getCompanyId() {
|
||||
return companyId;
|
||||
}
|
||||
|
||||
public void setCompanyId(Long companyId) {
|
||||
this.companyId = companyId;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package ru.clearing.classes.StaticData.User;
|
||||
|
||||
|
||||
import ru.clearing.classes.ConstSerializable;
|
||||
import ru.clearing.classes.objects.BusinessObject;
|
||||
|
||||
/**
|
||||
* Database table: USER_CLEARING todo name for user ?
|
||||
*/
|
||||
public class ClearingUser extends BusinessObject {
|
||||
private static final long serialVersionUID = ConstSerializable.serialVersionUID;
|
||||
|
||||
// private String idpUuid;
|
||||
//
|
||||
// public ClearingUser() {
|
||||
// super();
|
||||
// }
|
||||
//
|
||||
// public String toString() {
|
||||
// return String.format("%s{id=%d, idpUuid='%s'}", getClass().getSimpleName(), getId(), getIdpUuid());
|
||||
// }
|
||||
//
|
||||
// public String getIdpUuid() {
|
||||
// return idpUuid;
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package ru.clearing.classes.objects;
|
||||
|
||||
import ru.clearing.classes.ConstSerializable;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class BusinessEvent extends ObjectBase {
|
||||
static final long serialVersionUID = ConstSerializable.serialVersionUID;
|
||||
|
||||
private Date eventTime;
|
||||
|
||||
public BusinessEvent() {
|
||||
}
|
||||
|
||||
public Date getEventTime() {
|
||||
return eventTime;
|
||||
}
|
||||
|
||||
public void setEventTime(Date eventTime) {
|
||||
this.eventTime = eventTime;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package ru.clearing.classes.objects;
|
||||
|
||||
import ru.clearing.classes.ConstSerializable;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* UUID - Long based with field object
|
||||
*/
|
||||
public abstract class BusinessObject extends ObjectBase {
|
||||
static final long serialVersionUID = ConstSerializable.serialVersionUID;
|
||||
|
||||
private Instant created;
|
||||
private Instant updated;
|
||||
|
||||
public Instant getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(Instant created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public Instant getUpdated() {
|
||||
return updated;
|
||||
}
|
||||
|
||||
public void setUpdated(Instant updated) {
|
||||
this.updated = updated;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package ru.clearing.classes.objects;
|
||||
|
||||
import ru.clearing.classes.ConstSerializable;
|
||||
import ru.clearing.common.interfaces.WithId;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Long ID - based primary key object
|
||||
*/
|
||||
public abstract class ObjectBase implements WithId, Serializable {
|
||||
static final long serialVersionUID = ConstSerializable.serialVersionUID;
|
||||
|
||||
protected Long id;
|
||||
public ObjectBase(){
|
||||
}
|
||||
|
||||
public ObjectBase(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static Long getIdOrNull(WithId o) {
|
||||
return o == null ? null : o.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s{id=%d}", getClass().getSimpleName(), getId());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
ObjectBase otcObject = (ObjectBase) o;
|
||||
|
||||
return id.equals(otcObject.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id.hashCode();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package ru.clearing.common.interfaces;
|
||||
|
||||
public interface WithId {
|
||||
Long getId();
|
||||
}
|
||||
BIN
clearing-classes/target/dfa-classes-DFA-1.0.0.0.jar
Normal file
BIN
clearing-classes/target/dfa-classes-DFA-1.0.0.0.jar
Normal file
Binary file not shown.
4
clearing-classes/target/maven-archiver/pom.properties
Normal file
4
clearing-classes/target/maven-archiver/pom.properties
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#Created by Apache Maven 3.6.3
|
||||
groupId=ru.spcex.clearing
|
||||
artifactId=clearing-classes
|
||||
version=SPCEX-1.0.0.0
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
ru\clearing\classes\objects\ObjectBase.class
|
||||
ru\clearing\classes\ConstSerializable.class
|
||||
ru\clearing\classes\StaticData\Company\CompanyRoleSet.class
|
||||
ru\clearing\classes\objects\BusinessEvent.class
|
||||
ru\clearing\classes\StaticData\Company\Company.class
|
||||
ru\clearing\classes\StaticData\User\ClearingUser.class
|
||||
ru\clearing\common\interfaces\WithId.class
|
||||
ru\clearing\classes\objects\BusinessObject.class
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
E:\MFD_GIT_REPO\clearing\clearing-classes\src\main\java\ru\clearing\classes\StaticData\User\ClearingUser.java
|
||||
E:\MFD_GIT_REPO\clearing\clearing-classes\src\main\java\ru\clearing\classes\objects\ObjectBase.java
|
||||
E:\MFD_GIT_REPO\clearing\clearing-classes\src\main\java\ru\clearing\classes\ConstSerializable.java
|
||||
E:\MFD_GIT_REPO\clearing\clearing-classes\src\main\java\ru\clearing\classes\StaticData\Company\Company.java
|
||||
E:\MFD_GIT_REPO\clearing\clearing-classes\src\main\java\ru\clearing\classes\objects\BusinessEvent.java
|
||||
E:\MFD_GIT_REPO\clearing\clearing-classes\src\main\java\ru\clearing\classes\objects\BusinessObject.java
|
||||
E:\MFD_GIT_REPO\clearing\clearing-classes\src\main\java\ru\clearing\classes\StaticData\Company\CompanyRoleSet.java
|
||||
E:\MFD_GIT_REPO\clearing\clearing-classes\src\main\java\ru\clearing\common\interfaces\WithId.java
|
||||
12
clearing-dictionary/.gitignore
vendored
Normal file
12
clearing-dictionary/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
*.iml
|
||||
target
|
||||
lib
|
||||
.idea
|
||||
*.log
|
||||
temp
|
||||
otc.logs_IS_UNDEFINED
|
||||
.gitconfig
|
||||
dependency-reduced-pom.xml
|
||||
*/otc-test/src/test/resources/dataForDb/*.sql
|
||||
**/out
|
||||
preview
|
||||
3
clearing-dictionary/CHANGELOG.md
Normal file
3
clearing-dictionary/CHANGELOG.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
1.0.0
|
||||
------------------------------
|
||||
-
|
||||
118
clearing-dictionary/pom.xml
Normal file
118
clearing-dictionary/pom.xml
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
<?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>clearing-dictionary</artifactId>
|
||||
<name>PLATFORM dictionary</name>
|
||||
<description>PLATFORM dictionary</description>
|
||||
<packaging>jar</packaging>
|
||||
<version>SPCEX-1.0.0.0</version>
|
||||
|
||||
<parent>
|
||||
<artifactId>clearing</artifactId>
|
||||
<groupId>ru.spcex.clearing</groupId>
|
||||
<version>SPCEX-1.0.0.0</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<external_libraries.junit-jupiter.version>5.4.2</external_libraries.junit-jupiter.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- TEST -->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>${external_libraries.junit-jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.7</version>
|
||||
</dependency>
|
||||
|
||||
<!-- TEST -->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<configuration>
|
||||
<source>${project.java.version}</source>
|
||||
<target>${project.java.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.0.0-M5</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
||||
</manifest>
|
||||
<manifestEntries>
|
||||
<Built-By>${built.by}</Built-By>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
||||
</manifest>
|
||||
<manifestEntries>
|
||||
<Built-By>${built.by}</Built-By>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package ru.clearing.platform.dictionary;
|
||||
|
||||
public abstract class AbstractDictionary implements Dictionary {
|
||||
static final long serialVersionUID = ConstDictionarySerializable.serialVersionUID;
|
||||
|
||||
protected Long id;
|
||||
protected String name;
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package ru.clearing.platform.dictionary;
|
||||
|
||||
public interface ConstDictionarySerializable {
|
||||
long serialVersionUID = 7020097431335696640L;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package ru.clearing.platform.dictionary;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Словарь.
|
||||
*/
|
||||
public interface Dictionary extends Serializable {
|
||||
|
||||
Long getId();
|
||||
|
||||
void setId(Long id);
|
||||
|
||||
String getName();
|
||||
|
||||
void setName(String id);
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package ru.clearing.platform.dictionary;
|
||||
|
||||
/**
|
||||
* Database table: WORKFLOW_STATUS_DICTIONARY
|
||||
*/
|
||||
public class WorkflowStatusDictionary extends AbstractDictionary {
|
||||
private static final long serialVersionUID = ConstDictionarySerializable.serialVersionUID;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package ru.clearing.platform.dictionary.special;
|
||||
|
||||
import ru.clearing.platform.dictionary.ConstDictionarySerializable;
|
||||
import ru.clearing.platform.dictionary.Dictionary;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* DB table: COUNTRY_CODE_DICTIONARY
|
||||
* Dictionary
|
||||
*/
|
||||
public class CountryCode implements Serializable, Dictionary {
|
||||
static final long serialVersionUID = ConstDictionarySerializable.serialVersionUID;
|
||||
|
||||
private Long id;
|
||||
private String name;
|
||||
private String countryCode;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("CountryCode{id=%d, countryCode='%s'}", id, countryCode);
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getCountryCode() {
|
||||
return countryCode;
|
||||
}
|
||||
|
||||
public void setCountryCode(String countryCode) {
|
||||
this.countryCode = countryCode;
|
||||
}
|
||||
}
|
||||
5
pom.xml
5
pom.xml
|
|
@ -15,6 +15,8 @@
|
|||
<module>frontendapi</module>
|
||||
<module>storage</module>
|
||||
<module>db-scripts</module>
|
||||
<module>clearing-classes</module>
|
||||
<module>clearing-dictionary</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
|
@ -27,6 +29,9 @@
|
|||
<global.project.version>SPCEX-1.0.0.0</global.project.version>
|
||||
|
||||
<spring-boot.version>2.3.12.RELEASE</spring-boot.version>
|
||||
|
||||
<!-- IMDG -->
|
||||
<external_libraries.hazelcast.version>3.12.4</external_libraries.hazelcast.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
|
|
|
|||
|
|
@ -17,10 +17,6 @@
|
|||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
|
|
@ -29,6 +25,38 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ru.spcex.clearing</groupId>
|
||||
<artifactId>clearing-classes</artifactId>
|
||||
<version>SPCEX-1.0.0.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ru.spcex.clearing</groupId>
|
||||
<artifactId>clearing-dictionary</artifactId>
|
||||
<version>SPCEX-1.0.0.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- JDBC -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mchange</groupId>
|
||||
<artifactId>c3p0</artifactId>
|
||||
<version>0.9.5.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- IMDG для MapStore -->
|
||||
<dependency>
|
||||
<groupId>com.hazelcast</groupId>
|
||||
<artifactId>hazelcast-all</artifactId>
|
||||
<version>${external_libraries.hazelcast.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<finalName>jar/${project.artifactId}</finalName>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
package ru.spcex.clearing.storage.base;
|
||||
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import ru.clearing.classes.objects.BusinessEvent;
|
||||
import ru.clearing.classes.objects.BusinessObject;
|
||||
import ru.spcex.clearing.storage.utils.TimeUtil;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class BusinessEventMapStore<T extends BusinessEvent> extends ObjectBaseMapStore<T> {
|
||||
|
||||
public BusinessEventMapStore(JdbcTemplate jdbcTemplate) {
|
||||
super(jdbcTemplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Iterable<Long> loadAllKeys() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final T load(Long id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Collection<T> load(Collection<Long> keys) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Map<Long, T> loadAll(Collection<Long> keys) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Заполняет поля:<br>
|
||||
* uuid<br>
|
||||
* eventTime<br>
|
||||
* ownerId<br>
|
||||
* eventTypeId
|
||||
*
|
||||
* @param businessEvent объект для заполнения
|
||||
* @param rs resultSet для выгрузки
|
||||
*/
|
||||
public void fillBusinessEventFields(BusinessEvent businessEvent, ResultSet rs) throws SQLException {
|
||||
businessEvent.setEventTime(TimeUtil.toUtilDate(rs.getDate("eventtime")));
|
||||
businessEvent.setId(getLong(rs, "id"));
|
||||
}
|
||||
|
||||
public void fillBusinessObjectFieds(BusinessObject businessObject, ResultSet rs) throws SQLException {
|
||||
businessObject.setId(rs.getObject("orderbondid", Long.class));
|
||||
businessObject.setUpdated(TimeUtil.fromDate(rs.getDate("updated")));
|
||||
businessObject.setCreated(TimeUtil.fromDate(rs.getDate("created")));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package ru.spcex.clearing.storage.base;
|
||||
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import ru.clearing.classes.objects.BusinessObject;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Шаблон для загрузки <code>BusinessObject</code>-ов.
|
||||
*/
|
||||
public abstract class BusinessObjectMapStore<T extends BusinessObject> extends ObjectBaseMapStore<T> {
|
||||
|
||||
public BusinessObjectMapStore(JdbcTemplate jdbcTemplate) {
|
||||
super(jdbcTemplate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Заполняет стандартные поля для BusinessObject из ResultSet
|
||||
*
|
||||
* @param businessObject дозаполнить стандартные поля этому объекту
|
||||
* @param rs из ResultSet
|
||||
* @throws SQLException - error
|
||||
*/
|
||||
protected void fillBusinessObjectFields(BusinessObject businessObject, ResultSet rs) throws SQLException {
|
||||
fillBusinessObjectFields(businessObject, rs, "id");
|
||||
}
|
||||
|
||||
protected void fillBusinessObjectFields(BusinessObject businessObject, ResultSet rs, String idName) throws SQLException {
|
||||
businessObject.setUpdated(getInstantFromTimestamp(rs, "updated"));
|
||||
businessObject.setCreated(getInstantFromTimestamp(rs, "created"));
|
||||
businessObject.setId(getLong(rs, idName));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
package ru.spcex.clearing.storage.base;
|
||||
|
||||
import com.hazelcast.core.MapLoader;
|
||||
import ru.clearing.platform.dictionary.Dictionary;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.dao.support.DataAccessUtils;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
|
||||
import static ru.spcex.clearing.storage.base.ObjectBaseMapStore.MAX_IN_CLAUSE_SIZE;
|
||||
|
||||
/**
|
||||
* Store для словарей стандартных - из ID, NAME.
|
||||
*/
|
||||
public abstract class DictionaryMapStore<T extends Dictionary> implements MapLoader<Long, T> {
|
||||
private static Logger log = LoggerFactory.getLogger(DictionaryMapStore.class);
|
||||
|
||||
protected NamedParameterJdbcTemplate namedParameterJdbcTemplate;
|
||||
|
||||
protected final JdbcTemplate jdbcTemplate;
|
||||
|
||||
protected DictionaryMapStore(JdbcTemplate jdbcTemplate) {
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
|
||||
}
|
||||
|
||||
public abstract String getTableName();
|
||||
|
||||
public abstract T getDictionaryObject();
|
||||
|
||||
protected T mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||
T dictionary = getDictionaryObject();
|
||||
dictionary.setId(rs.getLong("id"));
|
||||
dictionary.setName(rs.getString("name"));
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
private Collection<T> loadCollection(Collection<Long> keys) {
|
||||
Map<String, Collection<Long>> paramMap = Collections.singletonMap("ids", keys);
|
||||
return namedParameterJdbcTemplate.query("select * from " + getTableName() + " where id in (:ids)", paramMap, this::mapRow);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T load(Long id) {
|
||||
Collection<T> rows;
|
||||
List<Long> list = Collections.singletonList(id);
|
||||
try {
|
||||
rows = loadCollection(list);
|
||||
} catch (Throwable e) { // one retry
|
||||
log.trace("Retry load after {}", e.toString());
|
||||
rows = loadCollection(list);
|
||||
}
|
||||
return DataAccessUtils.singleResult(rows);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, T> loadAll(Collection<Long> keys) {
|
||||
log.trace("loadAll from dictionary {} {} keys", getTableName(), keys.size());
|
||||
Map<Long, T> result = new HashMap<>();
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
// загрузить данные по ключам частями, чтобы не выйти за ограничения базы по кол-ву элементов в in clause
|
||||
List<Long> keysSubList = new ArrayList<>(MAX_IN_CLAUSE_SIZE);
|
||||
for (Iterator<Long> iterator = keys.iterator(); iterator.hasNext(); ) {
|
||||
Long key = iterator.next();
|
||||
keysSubList.add(key);
|
||||
if (keysSubList.size() == MAX_IN_CLAUSE_SIZE || !iterator.hasNext()) {
|
||||
Collection<T> rows = loadCollection(keysSubList);
|
||||
for (T row : rows) {
|
||||
result.put(row.getId(), row);
|
||||
}
|
||||
keysSubList.clear();
|
||||
}
|
||||
}
|
||||
|
||||
log.trace("loadAll from dictionary {} {} keys done in {} ms", getTableName(), keys.size(), (System.currentTimeMillis() - start));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Long> loadAllKeys() {
|
||||
log.debug("loadAllKeys from " + getTableName());
|
||||
return jdbcTemplate.query("select id from " + getTableName(), (rs, rowNum) -> rs.getLong("id"));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
package ru.spcex.clearing.storage.base;
|
||||
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import com.hazelcast.core.MapLoaderLifecycleSupport;
|
||||
import com.hazelcast.core.MapStore;
|
||||
//import com.opencsv.CSVWriter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.lang.NonNull;
|
||||
import ru.clearing.classes.objects.ObjectBase;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* MapStore записывающий изменения в файл
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class LoggingMapStore<T extends ObjectBase> implements MapStore<Long, T>, MapLoaderLifecycleSupport {
|
||||
protected final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
// private CSVWriter csvWriter; todo подключить OpenCSV и настройку про логирование данных добавить
|
||||
|
||||
// private Supplier<String> recoveryPath = () -> DfaConfig.get().getRoot().getSettings().getRecoveryLogPath();
|
||||
|
||||
@Override
|
||||
public void init(HazelcastInstance hazelcastInstance, Properties properties, String mapName) {
|
||||
// try {
|
||||
// String recoveryLogPath = recoveryPath.get();
|
||||
// if (recoveryLogPath != null) {
|
||||
// SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||
// File recoveryDir = new File(recoveryLogPath + File.separator + simpleDateFormat.format(new Date()));
|
||||
// recoveryDir.mkdirs();
|
||||
// File recoveryFile = new File(recoveryDir, getTableName() + ".csv");
|
||||
// csvWriter = new CSVWriter(new BufferedWriter(new FileWriter(recoveryFile)), ';');
|
||||
// log.info("recovery log started {}", recoveryFile);
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// log.error("", e);
|
||||
// }
|
||||
}
|
||||
|
||||
// public void setRecoveryPath(Supplier<String> recoveryPath) {
|
||||
// this.recoveryPath = recoveryPath;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
// try {
|
||||
// if (csvWriter != null)
|
||||
// csvWriter.close();
|
||||
// } catch (IOException e) {
|
||||
// log.error("", e);
|
||||
// }
|
||||
}
|
||||
|
||||
public abstract String getTableName();
|
||||
|
||||
protected void logHeaders(@NonNull String[] headers) {
|
||||
try {
|
||||
// if (csvWriter != null) {
|
||||
// csvWriter.writeNext(headers);
|
||||
// csvWriter.flush();
|
||||
// }
|
||||
} catch (Exception e) {
|
||||
log.error("", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void logValues(@NonNull List<Object[]> valuesList) {
|
||||
try {
|
||||
// if (csvWriter != null) {
|
||||
// for (Object[] values : valuesList) {
|
||||
// String[] nextLine = new String[values.length];
|
||||
// for (int i = 0; i < values.length; i++) {
|
||||
// nextLine[i] = String.valueOf(values[i]);
|
||||
// }
|
||||
// csvWriter.writeNext(nextLine);
|
||||
// }
|
||||
// csvWriter.flush();
|
||||
// }
|
||||
} catch (Exception e) {
|
||||
log.error("", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
package ru.spcex.clearing.storage.base;
|
||||
import org.springframework.dao.support.DataAccessUtils;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
import ru.clearing.classes.objects.ObjectBase;
|
||||
import ru.spcex.clearing.storage.utils.DbUtilsHelper;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
|
||||
public abstract class ObjectBaseMapStore<T extends ObjectBase> extends SimpleObjectMapStore<T> {
|
||||
/**
|
||||
* См. legalEntityProfileToSQLArgs()
|
||||
*/
|
||||
protected static final String LEGAL_ENTITY_PROFILE_STATEMENT_ARGUMENT =
|
||||
"description, domicilecountrycodeid, isprofessional, organizationtypeid, ogrn, name," +
|
||||
" fullname, nameeng, fullnameeng, kpp, contactphone, contactemail, tsedallowedid, edomail," +
|
||||
" nsdallowedid, otcmonitorallowedid, otcmonitorobligedid";
|
||||
|
||||
protected static final String insertChargeDefinitionStatement = DbUtilsHelper.fillValuesBlock(
|
||||
"UPDATE OR INSERT INTO CHARGEDEFINITION (id, chargeamount, chargedirectionid, " +
|
||||
" chargesettlementamount, chargetypeid, netincluded, currencycodeid, moexexchangecommission, userid, partyid)" +
|
||||
" values %values_block% matching (id);"
|
||||
);
|
||||
public static final int MAX_IN_CLAUSE_SIZE = 1000;
|
||||
|
||||
protected NamedParameterJdbcTemplate namedParameterJdbcTemplate;
|
||||
|
||||
public ObjectBaseMapStore(JdbcTemplate jdbcTemplate) {
|
||||
super(jdbcTemplate);
|
||||
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
|
||||
// this.jdbcTemplate = jdbcTemplate;
|
||||
// this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public T load(Long id) {
|
||||
if (!isLoadable(id)) return null;
|
||||
Collection<T> rows;
|
||||
List<Long> list = Collections.singletonList(id);
|
||||
try {
|
||||
rows = load(list);
|
||||
} catch (Throwable e) { // one retry
|
||||
rows = load(list);
|
||||
}
|
||||
T obj = DataAccessUtils.singleResult(rows);
|
||||
if (obj != null && isLoadable(obj))
|
||||
return obj;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean isLoadable(Long id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean isLoadable(T obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, T> loadAll(Collection<Long> keys) {
|
||||
log.debug("loadAll from " + getTableName() + " " + keys.size() + " keys");
|
||||
Map<Long, T> result = new HashMap<>();
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
// загрузить данные по ключам частями, чтобы не выйти за ограничения базы по кол-ву элементов в in clause
|
||||
List<Long> keysSubList = new ArrayList<>(MAX_IN_CLAUSE_SIZE);
|
||||
for (Iterator<Long> iterator = keys.iterator(); iterator.hasNext(); ) {
|
||||
Long key = iterator.next();
|
||||
keysSubList.add(key);
|
||||
if (keysSubList.size() == MAX_IN_CLAUSE_SIZE || !iterator.hasNext()) {
|
||||
Collection<T> rows = load(keysSubList);
|
||||
for (T row : rows) {
|
||||
result.put(row.getId(), row);
|
||||
}
|
||||
keysSubList.clear();
|
||||
}
|
||||
}
|
||||
|
||||
log.debug("loadAll from " + getTableName() + " " + keys.size() + " keys done in " + (System.currentTimeMillis() - start) + "ms");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public abstract Collection<T> load(Collection<Long> keys);
|
||||
|
||||
protected Long getLong(ResultSet rs, String columnName) throws SQLException {
|
||||
return rs.getObject(columnName, Long.class);
|
||||
}
|
||||
|
||||
protected Instant getInstantFromTimestamp(ResultSet rs, String column) throws SQLException {
|
||||
Timestamp date = rs.getTimestamp(column);
|
||||
return date != null ? date.toInstant() : null;
|
||||
}
|
||||
|
||||
/* todo реfакторинг:
|
||||
protected LegalEntityProfile getLegalEntityProfile(Long id) {
|
||||
if (id == null)
|
||||
return null;
|
||||
List<LegalEntityProfile> results = jdbcTemplate.query(
|
||||
"SELECT * FROM legalentityprofile WHERE id = ?", new Object[]{id},
|
||||
(rs, rowNum) -> {
|
||||
LegalEntityProfile legalEntityProfile = new LegalEntityProfile();
|
||||
legalEntityProfile.setDescription(rs.getString("description"));
|
||||
legalEntityProfile.setDomicileCountryCodeId(rs.getObject("domicilecountrycodeid", Long.class));
|
||||
legalEntityProfile.setProfessional(rs.getObject("isprofessional", Boolean.class));
|
||||
legalEntityProfile.setOrganizationTypeId(rs.getObject("organizationtypeid", Long.class));
|
||||
legalEntityProfile.setOgrn(rs.getString("ogrn"));
|
||||
legalEntityProfile.setShortName(rs.getString("name"));
|
||||
legalEntityProfile.setFullName(rs.getString("fullname"));
|
||||
legalEntityProfile.setNameEng(rs.getString("nameeng"));
|
||||
legalEntityProfile.setFullNameEng(rs.getString("fullnameeng"));
|
||||
legalEntityProfile.setKpp(rs.getString("kpp"));
|
||||
legalEntityProfile.setContactPhone(rs.getString("contactphone"));
|
||||
legalEntityProfile.setContactEMail(rs.getString("contactemail"));
|
||||
legalEntityProfile.setTsedAllowedId(rs.getObject("tsedallowedid", Long.class));
|
||||
legalEntityProfile.setEdoMail(rs.getString("edomail"));
|
||||
legalEntityProfile.setNsdAllowedId(rs.getObject("nsdallowedid", Long.class));
|
||||
legalEntityProfile.setOtcMonitorAllowedId(rs.getObject("otcmonitorallowedid", Long.class));
|
||||
legalEntityProfile.setOtcMonitorObligedId(rs.getObject("otcmonitorobligedid", Long.class));
|
||||
legalEntityProfile.setId(getLong(rs, "id"));
|
||||
return legalEntityProfile;
|
||||
}
|
||||
);
|
||||
LegalEntityProfile onceObject = DataAccessUtils.singleResult(results);
|
||||
if (onceObject == null) {
|
||||
log.warn("No row in table legalentityprofile where id={}. Create empty ", id);
|
||||
onceObject = new LegalEntityProfile();
|
||||
onceObject.setId(id); // чтобы не потерять id
|
||||
}
|
||||
return onceObject;
|
||||
}
|
||||
*/
|
||||
|
||||
// /**
|
||||
// * Без ID перечисление значений полей LegalEntityProfile.
|
||||
// * См. LegalentityprofileStatementArgument
|
||||
// *
|
||||
// * @param legalEntityProfile
|
||||
// * @return
|
||||
// */
|
||||
// protected List<Object> legalEntityProfileToSQLArgs(@NonNull LegalEntityProfile legalEntityProfile) {
|
||||
// List<Object> legalEntityArgs = new ArrayList<>(Arrays.asList(
|
||||
//// legalEntityProfile.getId(),
|
||||
// legalEntityProfile.getDescription(),
|
||||
// legalEntityProfile.getDomicileCountryCodeId(),
|
||||
// legalEntityProfile.getProfessional(),
|
||||
// legalEntityProfile.getOrganizationTypeId(),
|
||||
// legalEntityProfile.getOgrn(),
|
||||
// legalEntityProfile.getShortName(),
|
||||
// legalEntityProfile.getFullName(),
|
||||
// legalEntityProfile.getNameEng(),
|
||||
// legalEntityProfile.getFullNameEng(),
|
||||
// legalEntityProfile.getKpp(),
|
||||
// legalEntityProfile.getContactPhone(),
|
||||
// legalEntityProfile.getContactEMail(),
|
||||
// legalEntityProfile.getTsedAllowedId(),
|
||||
// legalEntityProfile.getEdoMail(),
|
||||
// legalEntityProfile.getNsdAllowedId(),
|
||||
// legalEntityProfile.getOtcMonitorAllowedId(),
|
||||
// legalEntityProfile.getOtcMonitorObligedId()
|
||||
// ));
|
||||
// return legalEntityArgs;
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
package ru.spcex.clearing.storage.base;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.SqlTypeValue;
|
||||
import org.springframework.jdbc.core.StatementCreatorUtils;
|
||||
import org.springframework.lang.NonNull;
|
||||
import ru.clearing.classes.objects.ObjectBase;
|
||||
import ru.spcex.clearing.storage.utils.BigDecimalUtil;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* MapStore для выгрузки обычных объектов
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class SimpleObjectMapStore<T extends ObjectBase> extends LoggingMapStore<T>
|
||||
{
|
||||
protected final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
protected SimpleDateFormat FIREBIRD_DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd"); // не делать static.
|
||||
protected final JdbcTemplate jdbcTemplate;
|
||||
private final int bathSize = 1000;
|
||||
|
||||
protected SimpleObjectMapStore(JdbcTemplate jdbcTemplate) {
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
logHeaders(getFields());
|
||||
}
|
||||
|
||||
public abstract String getTableName();
|
||||
|
||||
public abstract String[] getFields();
|
||||
|
||||
private boolean oidIsPresentInTheFields = Arrays.stream(getFields()).anyMatch(anotherString -> {
|
||||
if (anotherString == null) return false;
|
||||
return "oid".equalsIgnoreCase(anotherString.trim());
|
||||
});
|
||||
|
||||
public boolean deleteIsSupported() {
|
||||
return !oidIsPresentInTheFields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void store(Long id, T o) {
|
||||
log.debug("store {} {} {}", getTableName(), id, o);
|
||||
Map<Long, T> map = new HashMap<>();
|
||||
map.put(id, o);
|
||||
store(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void storeAll(Map<Long, T> map) {
|
||||
log.debug("storeAll {} {}", getTableName(), map);
|
||||
store(map);
|
||||
}
|
||||
|
||||
public abstract void store(Map<Long, T> map);
|
||||
|
||||
@Override
|
||||
public void delete(Long id) {
|
||||
if (deleteIsSupported()) {
|
||||
defaultDelete(id);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("delete not supported");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAll(Collection<Long> collection) {
|
||||
if (deleteIsSupported()) {
|
||||
deleteAllShowNotDeleted(collection);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("deleteAll not supported");
|
||||
}
|
||||
}
|
||||
|
||||
protected void defaultDelete(Long id) {
|
||||
ArrayList<Long> list = new ArrayList<>();
|
||||
list.add(id);
|
||||
deleteAll(list);
|
||||
}
|
||||
|
||||
protected void deleteAllShowNotDeleted(Collection<Long> collection) {
|
||||
List<Object[]> listOfID = new ArrayList<>(collection.size());
|
||||
for (Long id : collection)
|
||||
listOfID.add(new Object[]{id});
|
||||
try {
|
||||
jdbcTemplate.batchUpdate("DELETE FROM " + getTableName() + " WHERE id=?", listOfID);
|
||||
} catch (Exception e) {
|
||||
log.error("SQL error at batch DELETE FROM {}\n{}", getTableName(), ExceptionUtils.getStackTrace(e));
|
||||
log.info("List of non deleted ID {}", collection); // показать список неудалённых UUID
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract T load(Long id);
|
||||
|
||||
@Override
|
||||
public Map<Long, T> loadAll(Collection<Long> keys) {
|
||||
Map<Long, T> result = new HashMap<>();
|
||||
for (Long key : keys) {
|
||||
result.put(key, load(key));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Long> loadAllKeys() {
|
||||
log.debug("loadAllKeys from " + getTableName());
|
||||
List<Long> keys;
|
||||
try {
|
||||
keys = jdbcTemplate.query("select id from " + getTableName(), (resultSet, i) -> resultSet.getLong("id"));
|
||||
} catch (Throwable e) {
|
||||
log.error("{}", ExceptionUtils.getStackTrace(e));
|
||||
throw e;
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Загружает ключи только за текущий день.
|
||||
* <code>where CAST(tradingday as DATE) = ?</code>
|
||||
* Осторожно со знаком: в некоторых случаях требуется за текущий и будущие дни, тогда этот метод не подходит.
|
||||
* См. так же loadAllKeys().
|
||||
*
|
||||
* @return список id
|
||||
*/
|
||||
protected List<Long> defaultLoadAllKeysOnTradingDay() {
|
||||
log.debug("loadAllKeys from " + getTableName());
|
||||
return jdbcTemplate.query("select id from " + getTableName() + " where CAST(tradingday as DATE) = ?",
|
||||
new Object[]{FIREBIRD_DATE_FORMATTER.format(new Date())},
|
||||
(resultSet, i) -> resultSet.getObject("id", Long.class));
|
||||
}
|
||||
|
||||
|
||||
protected void batchInsertUpdate(@NonNull String insertStatement, @NonNull List<Object[]> args) {
|
||||
try {
|
||||
logValues(args);
|
||||
int[][] ret = jdbcTemplate.batchUpdate(insertStatement, args, bathSize, (ps, params) -> {
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
int type = ps.getParameterMetaData().getParameterType(i + 1);
|
||||
Object value = params[i];
|
||||
if (value != null) {
|
||||
if ((type == Types.VARCHAR || type == Types.CHAR) && value instanceof String) {
|
||||
String stringValue = (String) value;
|
||||
int length = ps.getParameterMetaData().getPrecision(i + 1);
|
||||
if (stringValue.length() > length) {
|
||||
value = stringValue.substring(0, length);
|
||||
log.error("String value for insert is too large [ insertSql: {}, params: {}, incorrect value : {}, normalized value: {} ]",
|
||||
insertStatement, Arrays.toString(params), stringValue, value);
|
||||
}
|
||||
} else if ((type == Types.DECIMAL || type == Types.NUMERIC) && value instanceof BigDecimal) {
|
||||
BigDecimal bigDecimalValue = (BigDecimal) value;
|
||||
int dbScalePartLength = ps.getParameterMetaData().getScale(i + 1);
|
||||
int precision = ps.getParameterMetaData().getPrecision(i + 1);
|
||||
if (!BigDecimalUtil.checkSize(bigDecimalValue, precision, dbScalePartLength)) {
|
||||
value = BigDecimalUtil.genMaxValueForInsert(precision, dbScalePartLength);
|
||||
log.error("BigDecimal value for insert is too large [ insertSql: {}, params: {}, incorrect value : {}, normalized value: {} ]",
|
||||
insertStatement, Arrays.toString(params), bigDecimalValue, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
//в batchUpdate(String sql, List<Object[]> batchArgs), как типа поля всегда передавался SqlTypeValue.TYPE_UNKNOWN,
|
||||
//см. BatchUpdateUtils.setStatementParameters
|
||||
try {
|
||||
StatementCreatorUtils.setParameterValue(ps, i + 1, SqlTypeValue.TYPE_UNKNOWN, value);
|
||||
} catch (SQLException e) {
|
||||
throw new SQLException("batchInsertUpdate, at prepare argument " + i + " value = " + value + "; SQL=" + insertStatement, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
int batchSize = ret.length > 0 ? ret[0].length : ret.length;
|
||||
log.debug("{} {} rows stored", getTableName(), batchSize);
|
||||
} catch (Exception e) {
|
||||
log.error("SQL error at batch UPDATE OR INSERT INTO {}\n{}", getTableName(), ExceptionUtils.getStackTrace(e));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
protected Instant getInstantFromTimestamp(ResultSet rs, String column) throws SQLException {
|
||||
Timestamp date = rs.getTimestamp(column);
|
||||
return date != null ? date.toInstant() : null;
|
||||
}
|
||||
|
||||
protected Timestamp timestampFromInstant(Instant instant) {
|
||||
if (instant == null) return null;
|
||||
return Timestamp.from(instant);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package ru.spcex.clearing.storage.config;
|
||||
|
||||
|
||||
/**
|
||||
* Корневой элемент конфигурации
|
||||
*/
|
||||
|
||||
@SuppressWarnings("DefaultAnnotationParam")
|
||||
public class ConfigurationRootElement /*extends ConfigurationRootBaseElement*/ {
|
||||
|
||||
/**
|
||||
* Конфигурация БД
|
||||
*/
|
||||
// @JsonProperty(value = "Database", required = true)
|
||||
private SettingsElementDatabase database = new SettingsElementDatabase();
|
||||
|
||||
// @JsonProperty(value = "Settings", required = false)
|
||||
private SettingsElement settings = new SettingsElement();
|
||||
|
||||
/**
|
||||
* Конфигурация Hazelcast
|
||||
*/
|
||||
// @JsonProperty(value = "HazelcastServer", required = true)
|
||||
// private HazelcastServerElement hazelcast = new HazelcastServerElement();
|
||||
|
||||
/**
|
||||
* Конфигурация сервисов Core
|
||||
*/
|
||||
// @JsonProperty(value = "Services")
|
||||
private ServicesElement servicesElement = new ServicesElement();
|
||||
|
||||
public SettingsElementDatabase getDatabase() {
|
||||
return database;
|
||||
}
|
||||
|
||||
// public HazelcastServerElement getHazelcast() {
|
||||
// return hazelcast;
|
||||
// }
|
||||
|
||||
public SettingsElement getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
public ServicesElement getServicesElement() {
|
||||
return servicesElement;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package ru.spcex.clearing.storage.config;
|
||||
|
||||
import com.mchange.v2.c3p0.ComboPooledDataSource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import ru.spcex.clearing.storage.error.ModuleInitializeException;
|
||||
import ru.spcex.clearing.storage.utils.DbDefaultConfig;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
@Configuration
|
||||
public class DbConnectionConfig {
|
||||
private Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private ConfigurationRootElement configRoot = DfaConfig.get().getRoot();
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() /*fixme why: throws PropertyVetoException*/ {
|
||||
DataSource result;
|
||||
String login = configRoot.getDatabase().getLogin();
|
||||
String password = configRoot.getDatabase().getPassword();
|
||||
String logTimeoutPart = "";
|
||||
String dbPath;
|
||||
if (StringUtils.isEmpty(configRoot.getDatabase().getEmbeddedFilePath())) {
|
||||
dbPath = configRoot.getDatabase().getJdbcConnectionString();
|
||||
int timeoutSec = configRoot.getDatabase().getConnectionAcquireTimeoutSeconds();
|
||||
ComboPooledDataSource cpds = new ComboPooledDataSource();
|
||||
try {
|
||||
cpds.setDriverClass(configRoot.getDatabase().getDriver());
|
||||
} catch (Exception ue) { // fixme не компилится из-за PropertyVetoException
|
||||
throw new RuntimeException(ue);
|
||||
}
|
||||
cpds.setJdbcUrl(dbPath);
|
||||
cpds.setUser(login);
|
||||
cpds.setPassword(password);
|
||||
cpds.setInitialPoolSize(configRoot.getDatabase().getMinPoolSize());
|
||||
cpds.setMinPoolSize(configRoot.getDatabase().getMinPoolSize());
|
||||
cpds.setMaxPoolSize(configRoot.getDatabase().getMaxPoolSize());
|
||||
cpds.setNumHelperThreads(configRoot.getDatabase().getNumHelperThreads());
|
||||
cpds.setCheckoutTimeout(timeoutSec * 1000/*todo common 1000==ConstsCommon.SECOND*/);
|
||||
logTimeoutPart = String.format(" (timeout=%ds)", timeoutSec);
|
||||
result = cpds;
|
||||
} else {
|
||||
dbPath = configRoot.getDatabase().getEmbeddedFilePath();
|
||||
result = DbDefaultConfig.getEmbeddedDatabase(dbPath);
|
||||
}
|
||||
String OPERATION_DATABASE_CONNECTION_CHECK = String.format("Database [%s] connection check", dbPath);
|
||||
try {
|
||||
Connection conn = result.getConnection();
|
||||
conn.close();
|
||||
log.info("{}: success", OPERATION_DATABASE_CONNECTION_CHECK);
|
||||
return result;
|
||||
} catch (Throwable e) {
|
||||
String msg = String.format("%s%s: failed: %s -> %s",
|
||||
OPERATION_DATABASE_CONNECTION_CHECK, logTimeoutPart, e.getClass().getSimpleName(), e.getMessage());
|
||||
log.error(msg);
|
||||
throw new ModuleInitializeException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
|
||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
return jdbcTemplate;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package ru.spcex.clearing.storage.config;
|
||||
|
||||
|
||||
public class DfaConfig {
|
||||
protected static DfaConfig self;
|
||||
|
||||
|
||||
ConfigurationRootElement root = new ConfigurationRootElement();
|
||||
|
||||
protected String defaultLogFileName() {
|
||||
return "storage";
|
||||
}
|
||||
|
||||
|
||||
public String appName() {
|
||||
return "clearing-storage";
|
||||
}
|
||||
|
||||
|
||||
protected Class parsedClazz() {
|
||||
return ConfigurationRootElement.class;
|
||||
}
|
||||
|
||||
public static DfaConfig get() {
|
||||
if (self == null) {
|
||||
self = new DfaConfig();
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
public ConfigurationRootElement getRoot() {
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
package ru.spcex.clearing.storage.config;
|
||||
|
||||
import com.hazelcast.config.*;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.hazelcast.HazelcastInstanceFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class HazelcastConfiguration {
|
||||
|
||||
private ConfigurationRootElement configRoot = DfaConfig.get().getRoot();
|
||||
private final PoolMapConfigs poolMapConfigs;
|
||||
|
||||
@Autowired
|
||||
public HazelcastConfiguration(PoolMapConfigs poolMapConfigs) {
|
||||
this.poolMapConfigs = poolMapConfigs;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HazelcastInstance hazelcastServerInstance(Config config) {
|
||||
return (new HazelcastInstanceFactory(config)).getHazelcastInstance();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Config hazelCastConfig() {
|
||||
Config config = new Config();
|
||||
config.setInstanceName("instance");
|
||||
config.setGroupConfig(new GroupConfig()
|
||||
// todo config .setName(configRoot.getHazelcast().getLogin())
|
||||
// .setPassword(configRoot.getHazelcast().getPassword()
|
||||
// )
|
||||
);
|
||||
// if (StringUtils.isEmpty(configRoot.getHazelcast().getMancenterUrl())) {
|
||||
// config.setManagementCenterConfig(new ManagementCenterConfig()
|
||||
// .setEnabled(false)
|
||||
// );
|
||||
// } else {
|
||||
// config.setManagementCenterConfig(new ManagementCenterConfig()
|
||||
// .setEnabled(true)
|
||||
// .setUrl(configRoot.getHazelcast().getMancenterUrl())
|
||||
// );
|
||||
// }
|
||||
config.setProperty("hazelcast.shutdownhook.enabled", "true");
|
||||
config.setProperty("hazelcast.logging.type", "slf4j");
|
||||
config.setProperty("hazelcast.operation.call.timeout.millis", "600000");
|
||||
config.setNetworkConfig(new NetworkConfig()
|
||||
// .setPort(configRoot.getHazelcast().getListenPort())
|
||||
.setJoin(new JoinConfig()
|
||||
.setMulticastConfig(new MulticastConfig()
|
||||
.setEnabled(false))
|
||||
.setTcpIpConfig(new TcpIpConfig()
|
||||
.setEnabled(true)
|
||||
// .setMembers(
|
||||
// DfaConfig.get()
|
||||
// .getRoot().getHazelcast().getClusterMembersList()
|
||||
// )
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
config.addMapConfig(poolMapConfigs.map_WorkflowStatusDictionary());
|
||||
config.addMapConfig(poolMapConfigs.map_WorkflowStatusDictionary());
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package ru.spcex.clearing.storage.config;
|
||||
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages = "com.moex.platform.storage")
|
||||
public class PlatformStorageBeans {
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package ru.spcex.clearing.storage.config;
|
||||
|
||||
import com.hazelcast.config.*;
|
||||
import com.hazelcast.core.MapLoader;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import ru.spcex.clearing.storage.dictionary.WorkflowStatusDictionaryMapStore;
|
||||
import ru.spcex.clearing.storage.object.CompanyRoleSetMapStore;
|
||||
import ru.spcex.clearing.storage.utils.IMDGDistributedNames;
|
||||
|
||||
@Configuration
|
||||
public class PoolMapConfigs {
|
||||
|
||||
private ConfigurationRootElement configRoot = DfaConfig.get().getRoot();
|
||||
|
||||
public PoolMapConfigs() {
|
||||
}
|
||||
|
||||
private MapStoreConfig makeDefaultMapStoreConfig(MapLoader<Long, ?> mapBean) {
|
||||
return new MapStoreConfig()
|
||||
.setImplementation(mapBean)
|
||||
;//todo config: .setWriteDelaySeconds(configRoot.getHazelcast().getDbSyncSeconds());
|
||||
}
|
||||
|
||||
public ScheduledExecutorConfig makeDefaultScheduledExecutorConfig(String name) {
|
||||
return new ScheduledExecutorConfig()
|
||||
.setName(name)
|
||||
.setPoolSize(16)
|
||||
.setDurability(1)
|
||||
.setCapacity(0);
|
||||
}
|
||||
|
||||
public MapConfig makeDefaultMapConfig(String mapName, MapLoader<Long, ?> mapBean) {
|
||||
return new MapConfig()
|
||||
.setName(mapName)
|
||||
.setInMemoryFormat(InMemoryFormat.OBJECT)
|
||||
.setMapStoreConfig(makeDefaultMapStoreConfig(mapBean))
|
||||
//fixme config: .setBackupCount(configRoot.getHazelcast().getBackupCount())
|
||||
;
|
||||
}
|
||||
|
||||
private NearCacheConfig makeDefaultNearCacheConfig() {
|
||||
return new NearCacheConfig()
|
||||
.setMaxIdleSeconds(3600)
|
||||
.setInMemoryFormat(InMemoryFormat.OBJECT)
|
||||
.setSerializeKeys(true)
|
||||
;
|
||||
}
|
||||
|
||||
private MapIndexConfig makeMapIndexConfig(String attributeName, boolean ordered) {
|
||||
return new MapIndexConfig()
|
||||
.setAttribute(attributeName)
|
||||
.setOrdered(ordered);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Autowired
|
||||
private WorkflowStatusDictionaryMapStore workflowStatusDictionaryMapStore;
|
||||
|
||||
public MapConfig map_WorkflowStatusDictionary() {
|
||||
return makeDefaultMapConfig(IMDGDistributedNames.Map_WorkflowStatusDictionary, workflowStatusDictionaryMapStore)
|
||||
.setNearCacheConfig(makeDefaultNearCacheConfig());
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private CompanyRoleSetMapStore companyRoleSetMapStore;
|
||||
|
||||
public MapConfig map_CompanyRoleSet() {
|
||||
return makeDefaultMapConfig(IMDGDistributedNames.Map_CompanyRoleSet, companyRoleSetMapStore);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package ru.spcex.clearing.storage.config;
|
||||
|
||||
//import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
//import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Настройка сервисов
|
||||
*/
|
||||
public class ServicesElement implements Serializable {
|
||||
|
||||
/**
|
||||
* Время, через которое выставленная заявка будет снята, в миллисекундах.
|
||||
*/
|
||||
// @JsonProperty(value = "ExpirationDelay")
|
||||
private Integer ExpirationDelay = 5 * 60 * 1000;
|
||||
|
||||
public Integer getExpirationDelay() {
|
||||
return ExpirationDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Время окончания торговой сессии
|
||||
*/
|
||||
// @JsonProperty(value = "SessionEndTime")
|
||||
// @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "HH:mm:ss", timezone = "Europe/Moscow")
|
||||
private Date SessionEndTime = null;
|
||||
|
||||
public Date getSessionEndTime() {
|
||||
return SessionEndTime;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package ru.spcex.clearing.storage.config;
|
||||
|
||||
//import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@SuppressWarnings({"DefaultAnnotationParam", "unused", "FieldCanBeLocal"})
|
||||
public class SettingsElement implements Serializable {
|
||||
// @JsonProperty(value = "InitHazelcastThreadMultiplier", required = false)
|
||||
private int initHazelcastThreadMultiplier = 2;
|
||||
|
||||
// @JsonProperty(value = "RecoveryLogPath", required = false)
|
||||
private String recoveryLogPath;
|
||||
|
||||
// @JsonProperty(value = "ExecutionLimitationPeriod", required = false)
|
||||
private Integer executionLimitationPeriod = 10;
|
||||
|
||||
public int getInitHazelcastThreadMultiplier() {
|
||||
return initHazelcastThreadMultiplier;
|
||||
}
|
||||
|
||||
public Integer getExecutionLimitationPeriod() {
|
||||
return executionLimitationPeriod;
|
||||
}
|
||||
|
||||
public String getRecoveryLogPath() {
|
||||
return recoveryLogPath;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
package ru.spcex.clearing.storage.config;
|
||||
|
||||
//import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@SuppressWarnings({"FieldCanBeLocal", "unused", "DefaultAnnotationParam"})
|
||||
public class SettingsElementDatabase implements Serializable {
|
||||
|
||||
// @JsonProperty(value = "Driver")
|
||||
private String driver = "org.firebirdsql.jdbc.FBDriver";
|
||||
|
||||
// @JsonProperty(value = "JdbcConnectionString", required = true)
|
||||
private String jdbcConnectionString;
|
||||
|
||||
// @JsonProperty(value = "Login", required = true)
|
||||
private String login;
|
||||
|
||||
// @JsonProperty(value = "Password", required = true)
|
||||
private String password;
|
||||
|
||||
// @JsonProperty(value = "MaxPoolSize")
|
||||
private int maxPoolSize = 30;
|
||||
|
||||
// @JsonProperty(value = "MinPoolSize")
|
||||
private int minPoolSize = 10;
|
||||
|
||||
// @JsonProperty(value = "EmbeddedFilePath", required = false)
|
||||
private String embeddedFilePath;
|
||||
|
||||
// @JsonProperty(value = "NumHelperThreads", required = false)
|
||||
private int numHelperThreads = Runtime.getRuntime().availableProcessors() * 2;
|
||||
|
||||
// @JsonProperty(value = "ConnectionAcquireTimeoutSeconds", required = false)
|
||||
private int connectionAcquireTimeoutSeconds = 30;
|
||||
|
||||
public String getDriver() {
|
||||
return driver;
|
||||
}
|
||||
|
||||
public String getJdbcConnectionString() {
|
||||
return jdbcConnectionString;
|
||||
}
|
||||
|
||||
public String getLogin() {
|
||||
return login;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public int getMaxPoolSize() {
|
||||
return maxPoolSize;
|
||||
}
|
||||
|
||||
public int getMinPoolSize() {
|
||||
return minPoolSize;
|
||||
}
|
||||
|
||||
public String getEmbeddedFilePath() {
|
||||
return embeddedFilePath;
|
||||
}
|
||||
|
||||
public int getNumHelperThreads() {
|
||||
return numHelperThreads;
|
||||
}
|
||||
|
||||
public int getConnectionAcquireTimeoutSeconds() {
|
||||
return connectionAcquireTimeoutSeconds;
|
||||
}
|
||||
|
||||
// для поддержки интеграционных тестов otc-test:
|
||||
public void setJdbcConnectionString(String jdbcConnectionString) {
|
||||
this.jdbcConnectionString = jdbcConnectionString;
|
||||
}
|
||||
|
||||
public void setLogin(String login) {
|
||||
this.login = login;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public void setEmbeddedFilePath(String embeddedFilePath) {
|
||||
this.embeddedFilePath = embeddedFilePath;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package ru.spcex.clearing.storage.dictionary;
|
||||
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import ru.clearing.platform.dictionary.WorkflowStatusDictionary;
|
||||
import ru.spcex.clearing.storage.base.DictionaryMapStore;
|
||||
|
||||
@Component
|
||||
public class WorkflowStatusDictionaryMapStore extends DictionaryMapStore<WorkflowStatusDictionary> {
|
||||
|
||||
public WorkflowStatusDictionaryMapStore(JdbcTemplate jdbcTemplate) {
|
||||
super(jdbcTemplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
return "WORKFLOW_STATUS_DICTIONARY";
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorkflowStatusDictionary getDictionaryObject() {
|
||||
return new WorkflowStatusDictionary();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package ru.spcex.clearing.storage.error;
|
||||
|
||||
public class ModuleInitializeException extends RuntimeException {
|
||||
public ModuleInitializeException() {
|
||||
}
|
||||
|
||||
public ModuleInitializeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ModuleInitializeException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ModuleInitializeException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package ru.spcex.clearing.storage.object;
|
||||
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import ru.clearing.classes.StaticData.Company.Company;
|
||||
import ru.clearing.classes.StaticData.Company.CompanyRoleSet;
|
||||
import ru.spcex.clearing.storage.base.ObjectBaseMapStore;
|
||||
import ru.spcex.clearing.storage.utils.DbUtilsHelper;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Component
|
||||
public class CompanyRoleSetMapStore extends ObjectBaseMapStore<CompanyRoleSet> {
|
||||
|
||||
public CompanyRoleSetMapStore(JdbcTemplate jdbcTemplate) {
|
||||
super(jdbcTemplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
return "COMPANY_ROLE_SET";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getFields() {
|
||||
return new String[]{"id", "roleid", "companyid"};
|
||||
}
|
||||
|
||||
protected final String insertStatement = DbUtilsHelper.createUpdateOrInsert(getTableName(), getFields(), "id");
|
||||
|
||||
@Override
|
||||
public Collection<CompanyRoleSet> load(Collection<Long> keys) {
|
||||
Map<String, Collection<Long>> paramMap = Collections.singletonMap("ids", keys);
|
||||
return namedParameterJdbcTemplate.query("select * from " + getTableName() + " where id in (:ids)", paramMap,
|
||||
(resultSet, i) -> {
|
||||
CompanyRoleSet companyRoleSet = new CompanyRoleSet();
|
||||
companyRoleSet.setId(resultSet.getObject("id", Long.class));
|
||||
companyRoleSet.setRoleId(resultSet.getObject("roleid", Long.class));
|
||||
companyRoleSet.setCompanyId(resultSet.getObject("companyid", Long.class));
|
||||
return companyRoleSet;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(Map<Long, CompanyRoleSet> map) {
|
||||
List<Object[]> batchArgs = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<Long, CompanyRoleSet> entry : map.entrySet()) {
|
||||
CompanyRoleSet partnerList = entry.getValue();
|
||||
|
||||
Object[] args = new Object[]{
|
||||
partnerList.getId(),
|
||||
partnerList.getRoleId(),
|
||||
partnerList.getCompanyId(),
|
||||
};
|
||||
batchArgs.add(args);
|
||||
}
|
||||
batchInsertUpdate(insertStatement, batchArgs);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
package ru.spcex.clearing.storage.utils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
|
||||
public class BigDecimalUtil {
|
||||
|
||||
private static final DecimalFormat defaultDecimalFormat;
|
||||
|
||||
static {
|
||||
DecimalFormatSymbols decimalFormatSymbols = new DecimalFormatSymbols();
|
||||
decimalFormatSymbols.setDecimalSeparator('.');
|
||||
decimalFormatSymbols.setGroupingSeparator(' ');
|
||||
defaultDecimalFormat = new DecimalFormat("#,###.00", decimalFormatSymbols);
|
||||
}
|
||||
|
||||
public static BigDecimal sum(BigDecimal num1, BigDecimal num2) {
|
||||
BigDecimal sum = BigDecimal.ZERO;
|
||||
if (num1 != null)
|
||||
sum = sum.add(num1);
|
||||
if (num2 != null)
|
||||
sum = sum.add(num2);
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value
|
||||
* @param dbSize общее кол-во позиций
|
||||
* @param dbScale кол-во позиций под дробную часть
|
||||
* @return true, если размер целой части не превышает значения, указанные в параметрах
|
||||
*/
|
||||
public static boolean checkSize(BigDecimal value, int dbSize, int dbScale) {
|
||||
if (value == null)
|
||||
return true;
|
||||
return value.precision() - value.scale() <= dbSize - dbScale;
|
||||
}
|
||||
|
||||
public static BigDecimal genMaxValueForInsert(int dbSize, int dbScale) {
|
||||
int maxIntSizeForInsert = dbSize - dbScale;
|
||||
long newLongValue = new BigDecimal(Math.pow(10, maxIntSizeForInsert)).longValue();
|
||||
return new BigDecimal(newLongValue - 1);
|
||||
}
|
||||
|
||||
public static BigDecimal chooseHighest(BigDecimal oldPrice, BigDecimal newPrice) {
|
||||
if (newPrice != null && (oldPrice == null || isLess(oldPrice, newPrice))) {
|
||||
return newPrice;
|
||||
} else {
|
||||
return oldPrice;
|
||||
}
|
||||
}
|
||||
|
||||
public static BigDecimal chooseSmallest(BigDecimal oldPrice, BigDecimal newPrice) {
|
||||
if (newPrice != null && (oldPrice == null || isLess(newPrice, oldPrice))) {
|
||||
return newPrice;
|
||||
} else {
|
||||
return oldPrice;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Если bestPrice меньше price, то true, иначе false
|
||||
*
|
||||
* @param bestPrice
|
||||
* @param price
|
||||
* @return
|
||||
*/
|
||||
public static boolean isLess(BigDecimal bestPrice, BigDecimal price) {
|
||||
return price != null && bestPrice != null && bestPrice.compareTo(price) < 0;
|
||||
}
|
||||
|
||||
public static Integer nullSafeAdd(Integer a, Integer b) {
|
||||
if (a == null) {
|
||||
return b;
|
||||
} else if (b == null) {
|
||||
return a;
|
||||
} else {
|
||||
return a + b;
|
||||
}
|
||||
}
|
||||
|
||||
public static BigDecimal nullSafeAdd(BigDecimal a, BigDecimal b) {
|
||||
if (a == null) {
|
||||
return b;
|
||||
} else if (b == null) {
|
||||
return a;
|
||||
} else {
|
||||
return a.add(b);
|
||||
}
|
||||
}
|
||||
|
||||
public static Long nullSafeAdd(Long a, Long b) {
|
||||
if (a == null) {
|
||||
return b;
|
||||
} else if (b == null) {
|
||||
return a;
|
||||
} else {
|
||||
return a + b;
|
||||
}
|
||||
}
|
||||
|
||||
public static String defaultFormatValue(BigDecimal val) {
|
||||
DecimalFormatSymbols decimalFormatSymbols = new DecimalFormatSymbols();
|
||||
decimalFormatSymbols.setDecimalSeparator('.');
|
||||
decimalFormatSymbols.setGroupingSeparator(' ');
|
||||
if (val == null) {
|
||||
return "";
|
||||
}
|
||||
return defaultDecimalFormat.format(val);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package ru.spcex.clearing.storage.utils;
|
||||
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class DbDefaultConfig {
|
||||
public static DataSource getEmbeddedDatabase(String embeddedFilePath) {
|
||||
throw new UnsupportedOperationException("Are PostgreSQL not supported embedded DB?");//todo PsotgreSQL
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package ru.spcex.clearing.storage.utils;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DbUtilsHelper {
|
||||
|
||||
private static String generateValuesBlock(int querySignCount) {
|
||||
return StringUtils.rightPad("(?", querySignCount * 3 - 1, ", ?") + ")";
|
||||
}
|
||||
|
||||
private static Pattern pGetColumns = Pattern.compile("(?m)(?i)INTO\\s+[0-9a-z\" _$]+\\s+\\(\\s*([0-9a-z_\\- ,\"\\n+]*?)\\s*\\)");
|
||||
|
||||
public static String fillValuesBlock(String insertStatement) {
|
||||
|
||||
Matcher m = pGetColumns.matcher(insertStatement);
|
||||
if (m.find()) {
|
||||
String g = m.group(1);
|
||||
String block = generateValuesBlock(g.split(",").length);
|
||||
return insertStatement.replaceAll("%values_block%", block);
|
||||
} else {
|
||||
return insertStatement;
|
||||
}
|
||||
}
|
||||
|
||||
public static String createInsert(String tableName, String[] fields) {
|
||||
return "INSERT INTO " + tableName +
|
||||
" (" + Arrays.stream(fields).map(f -> "\"" + f.toUpperCase() + "\"").collect(Collectors.joining(", ")) + ") values (" +
|
||||
// Arrays.stream(fields).map(f -> "\"" + f.toUpperCase() + "\"").collect(Collectors.joining(", ", ":", ""));
|
||||
String.join(", ", Collections.nCopies(fields.length, "?")) +
|
||||
")";
|
||||
}
|
||||
|
||||
public static String createUpdateOrInsert(String tableName, String[] fields, String matchingKey) {
|
||||
String updateOrInsert = "INSERT INTO " + tableName +
|
||||
" (" + Arrays.stream(fields).map(f -> "\"" + f.toUpperCase() + "\"").collect(Collectors.joining(", ")) + ") values (" +
|
||||
// Arrays.stream(fields).map(f -> "\"" + f.toUpperCase() + "\"").collect(Collectors.joining(", ", ":", ""));
|
||||
String.join(", ", Collections.nCopies(fields.length, "?")) +
|
||||
") WHERE ";
|
||||
if (matchingKey != null) // PostgreSQL conflict_target fixme проверить мэтчинг
|
||||
updateOrInsert += " " + matchingKey.toUpperCase();
|
||||
updateOrInsert += " CONFLICT DO UPDATE";
|
||||
|
||||
return updateOrInsert;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package ru.spcex.clearing.storage.utils;
|
||||
|
||||
//fixme перенести в новый модуль IMDGDistributedNames
|
||||
public final class IMDGDistributedNames {
|
||||
private IMDGDistributedNames() {
|
||||
}
|
||||
|
||||
public static final String Map_WorkflowStatusDictionary = "Map_WorkflowStatusDictionary";
|
||||
public static final String Map_CompanyRoleSet = "Map_CompanyRoleSet";
|
||||
}
|
||||
|
|
@ -0,0 +1,288 @@
|
|||
package ru.spcex.clearing.storage.utils;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.time.*;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Для работы с java.util.Date
|
||||
* И конвертация в новый формат
|
||||
* todo копипаст юниттеста нужен.
|
||||
*/
|
||||
public class TimeUtil {
|
||||
private static final Logger log = LoggerFactory.getLogger(TimeUtil.class);
|
||||
public static final ZoneId zone = ZoneId.systemDefault();
|
||||
|
||||
/**
|
||||
* Получить дату без времени (начало дня)
|
||||
*
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static Date getDateOnStartOfDay(Date date) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
return calendar.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить начало следующего дня
|
||||
*
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static Date getDateNextDay(Date date) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
calendar.add(Calendar.DAY_OF_YEAR, 1);
|
||||
return calendar.getTime();
|
||||
}
|
||||
|
||||
public static LocalDateTime toDateTime(Date fromDate) {
|
||||
if (fromDate == null)
|
||||
return null;
|
||||
if (fromDate instanceof java.sql.Timestamp)
|
||||
return ((java.sql.Timestamp) fromDate).toLocalDateTime();
|
||||
if (fromDate instanceof java.sql.Date || fromDate instanceof java.sql.Time)
|
||||
log.debug("Warning at converting date/time: for class {} may not contain date or time. unixtime={}", fromDate.getClass(), fromDate.getTime());
|
||||
return toDateTime0(fromDate);
|
||||
}
|
||||
|
||||
private static LocalDateTime toDateTime0(Date fromDate) {
|
||||
try {
|
||||
if (fromDate instanceof java.sql.Date) {
|
||||
Instant instant = Instant.now(); //can be LocalDateTime
|
||||
ZoneId systemZone = ZoneId.systemDefault(); // my timezone
|
||||
ZoneOffset currentOffsetForMyZone = systemZone.getRules().getOffset(instant);
|
||||
return LocalDateTime.ofEpochSecond(fromDate.getTime() / 1000, 0, currentOffsetForMyZone);
|
||||
}
|
||||
return LocalDateTime.ofInstant(fromDate.toInstant(), ZoneId.systemDefault());
|
||||
} catch (UnsupportedOperationException ue) {
|
||||
log.warn("Error(warn) convert type of date/time: {}({}) class: {}. Retry", fromDate, fromDate.getTime(), fromDate.getClass());
|
||||
try {
|
||||
Instant instant = Instant.now(); //can be LocalDateTime
|
||||
ZoneId systemZone = ZoneId.systemDefault(); // my timezone
|
||||
ZoneOffset currentOffsetForMyZone = systemZone.getRules().getOffset(instant);
|
||||
return LocalDateTime.ofEpochSecond(fromDate.getTime() / 1000, 0, currentOffsetForMyZone);
|
||||
} catch (Exception e) {
|
||||
log.error("Error convert type2 of date/time: {} class: {}\n{}", fromDate, fromDate.getClass(), ExceptionUtils.getStackTrace(ue));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// Date out = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
|
||||
}
|
||||
|
||||
public static LocalDate toDate(Date fromDate) {
|
||||
if (fromDate == null)
|
||||
return null;
|
||||
if (fromDate instanceof java.sql.Date)
|
||||
return ((java.sql.Date) fromDate).toLocalDate();
|
||||
if (fromDate instanceof java.sql.Time)
|
||||
log.debug("Warning at converting date/time: for class {} may not contain date. unixtime={}", fromDate.getClass(), fromDate.getTime());
|
||||
return toDateTime0(fromDate).toLocalDate();
|
||||
}
|
||||
|
||||
public static LocalTime toTime(Date fromDate) {
|
||||
if (fromDate == null)
|
||||
return null;
|
||||
if (fromDate instanceof java.sql.Time)
|
||||
return ((java.sql.Time) fromDate).toLocalTime();
|
||||
if (fromDate instanceof java.sql.Date)
|
||||
log.debug("Warning at converting date/time: for class {} may not contain time. unixtime={}", fromDate.getClass(), fromDate.getTime());
|
||||
return toDateTime0(fromDate).toLocalTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Последовательный ряд дат дней между двумя датами.
|
||||
*
|
||||
* @param from с даты, включительно
|
||||
* @param to по дату, включительно.
|
||||
* @return
|
||||
*/
|
||||
public static Date[] makeDateRange(Date from, Date to) {
|
||||
ArrayList<Date> datesL = new ArrayList<Date>();
|
||||
LocalDate fromDate = toDate(from);
|
||||
LocalDate toDate = toDate(to);
|
||||
datesL.add(from);
|
||||
for (LocalDate dateI = fromDate.plusDays(1); dateI.isBefore(toDate); dateI = dateI.plusDays(1)) {
|
||||
Date date = Date.from(dateI.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
||||
datesL.add(date);
|
||||
}
|
||||
if (!fromDate.equals(toDate))
|
||||
datesL.add(to);
|
||||
Date[] dates = datesL.toArray(new Date[0]);
|
||||
return dates;
|
||||
}
|
||||
|
||||
public static Date fromInstant(Instant instant) {
|
||||
if (instant == null) return null;
|
||||
return Date.from(instant);
|
||||
}
|
||||
|
||||
public static Date from(LocalDateTime localDateTime) {
|
||||
return localDateTime != null ? Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()) : null;
|
||||
}
|
||||
|
||||
public static Date from(LocalDate localDate) {
|
||||
return localDate != null ? Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* иногда встречается java.sql.Date
|
||||
* у них toInstant() не поддерживается
|
||||
*/
|
||||
public static Instant fromDate(Date dateToConvert) {
|
||||
try {
|
||||
if (dateToConvert == null) return null;
|
||||
return dateToConvert.toInstant();
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// log.warn("java.sql.Date");
|
||||
if (dateToConvert instanceof java.sql.Date) {
|
||||
return ((java.sql.Date) dateToConvert).toLocalDate().atStartOfDay(ZoneId.systemDefault()).toInstant();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Instant fromDate(LocalDate dateToConvert) {
|
||||
return dateToConvert == null ? null : dateToConvert.atStartOfDay(ZoneId.systemDefault()).toInstant();
|
||||
}
|
||||
|
||||
public static LocalDateTime toDateTime(Instant instant) {
|
||||
if (instant == null) {
|
||||
return null;
|
||||
} else {
|
||||
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
|
||||
}
|
||||
}
|
||||
|
||||
public static Date toUtilDate(java.sql.Date sqlDate) {
|
||||
return sqlDate != null ? new Date(sqlDate.getTime()) : null;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isCurrentTradingDay(Date date) {
|
||||
Date tradingDay = getDateOnStartOfDay(date);
|
||||
Date currentDay = getDateOnStartOfDay(new Date());
|
||||
return currentDay.equals(tradingDay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Начало дня по текущей временной зоне
|
||||
*/
|
||||
public static Instant startOfDayNow() {
|
||||
ZonedDateTime zdtStart = ZonedDateTime.now();
|
||||
zdtStart = zdtStart.truncatedTo(ChronoUnit.DAYS);
|
||||
return zdtStart.toInstant();
|
||||
}
|
||||
|
||||
/**
|
||||
* Начало дня по текущей временной зоне.
|
||||
*
|
||||
* @param from
|
||||
* @return
|
||||
*/
|
||||
public static Instant startOfDay(Instant from) {
|
||||
ZonedDateTime zdtStart = from.atZone(ZoneId.systemDefault());
|
||||
zdtStart = zdtStart.truncatedTo(ChronoUnit.DAYS);
|
||||
return zdtStart.toInstant();
|
||||
}
|
||||
|
||||
public static ZonedDateTime toZoned(Instant instant) {
|
||||
if (instant == null) return null;
|
||||
return instant.atZone(zone);
|
||||
}
|
||||
|
||||
public static LocalDate toDate(Instant instant) {
|
||||
ZonedDateTime zoned = toZoned(instant);
|
||||
if (zoned == null) return null;
|
||||
return zoned.toLocalDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Сегодня (от начала дня) или позднее
|
||||
*
|
||||
* @param instant дата, может ыть null
|
||||
* @return
|
||||
*/
|
||||
public static boolean afterToday(Instant instant) {
|
||||
LocalDate localDate = toDate(instant);
|
||||
return afterToday(localDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Сегодня (от начала дня) или позднее
|
||||
*
|
||||
* @param date дата, может ыть null
|
||||
* @return
|
||||
*/
|
||||
public static boolean afterToday(Date date) {
|
||||
LocalDate localDate = toDate(date);
|
||||
return afterToday(localDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Сегодня (от начала дня) или позднее
|
||||
*
|
||||
* @param localDate дата, может ыть null
|
||||
* @return
|
||||
*/
|
||||
public static boolean afterToday(LocalDate localDate) {
|
||||
if (localDate == null) return false;
|
||||
return !localDate.isBefore(LocalDate.now());
|
||||
}
|
||||
|
||||
public static boolean isToday(Instant instant) {
|
||||
LocalDate localDate = toDate(instant);
|
||||
return isToday(localDate);
|
||||
}
|
||||
|
||||
public static boolean isToday(Date date) {
|
||||
LocalDate localDate = toDate(date);
|
||||
return isToday(localDate);
|
||||
}
|
||||
|
||||
public static boolean isToday(LocalDate localDate) {
|
||||
if (localDate == null) return false;
|
||||
return localDate.equals(LocalDate.now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Если instant без даты (1970 год), то берёт из него время и добавляет текущую дату.
|
||||
*
|
||||
* @param time может быть null
|
||||
* @return time, или если не указана дата, то текущая дата + время из <code>time</code>
|
||||
*/
|
||||
public static Instant addDateTodayToTimeIfNeeded(Instant time) {
|
||||
if (time == null)
|
||||
return null;
|
||||
LocalDateTime ldt = TimeUtil.toDateTime(time);
|
||||
if (ldt.getYear() == 1970 && ldt.getMonth() == Month.JANUARY && ldt.getDayOfMonth() == 1) {
|
||||
// time without date
|
||||
ldt = LocalDateTime.of(LocalDate.now(), ldt.toLocalTime());
|
||||
return ldt.atZone(ZoneId.systemDefault()).toInstant();
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
public static String formatInstantToString(DateTimeFormatter formatter, Instant date) {
|
||||
if (formatter == null || date == null) return "";
|
||||
return formatter.format(date);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue