SUPPORT-9122:add reconcile data

This commit is contained in:
adel.ka 2025-04-21 09:42:23 +03:00
parent 709d957558
commit 33d9ee206e
26 changed files with 1522 additions and 1228 deletions

View file

@ -0,0 +1,19 @@
package ervu_business_metrics.config;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* @author Adel Kalimullin
*/
public class IdmReconcileEnabledCondition implements Condition {
private static final String ERVU_RECONCILE_ENABLED = "ervu.idm.reconcile.enabled";
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment env = context.getEnvironment();
return Boolean.parseBoolean(env.getProperty(ERVU_RECONCILE_ENABLED, Boolean.toString(true)));
}
}

View file

@ -0,0 +1,112 @@
package ervu_business_metrics.dao;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import ervu_business_metrics.config.IdmReconcileEnabledCondition;
import org.jooq.DSLContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Repository;
import ru.micord.webbpm.ervu.business_metrics.db_beans.idm_reconcile.tables.records.AccountRecord;
import ru.micord.webbpm.ervu.business_metrics.db_beans.idm_reconcile.tables.records.AccountRoleRecord;
import ru.micord.webbpm.ervu.business_metrics.db_beans.idm_reconcile.tables.records.DomainRecord;
import ru.micord.webbpm.ervu.business_metrics.db_beans.idm_reconcile.tables.records.RoleRecord;
import static ru.micord.webbpm.ervu.business_metrics.db_beans.idm_reconcile.Tables.ACCOUNT;
import static ru.micord.webbpm.ervu.business_metrics.db_beans.idm_reconcile.Tables.ACCOUNT_ROLE;
import static ru.micord.webbpm.ervu.business_metrics.db_beans.idm_reconcile.Tables.DOMAIN;
import static ru.micord.webbpm.ervu.business_metrics.db_beans.idm_reconcile.Tables.ROLE;
/**
* @author Adel Kalimullin
*/
@Repository
@Conditional(IdmReconcileEnabledCondition.class)
public class IdmDirectoriesDao {
private final DSLContext dsl;
public IdmDirectoriesDao(DSLContext dsl) {
this.dsl = dsl;
}
public RoleRecord getRoleRecord() {
return dsl.newRecord(ROLE);
}
public DomainRecord getDomainRecord() {
return dsl.newRecord(DOMAIN);
}
public AccountRecord getAccountRecord() {
return dsl.newRecord(ACCOUNT);
}
public AccountRoleRecord getAccountRoleRecord() {
return dsl.newRecord(ACCOUNT_ROLE);
}
public Set<String> getAccountIds() {
return new HashSet<>(dsl.select(ACCOUNT.ID)
.from(ACCOUNT)
.fetch(ACCOUNT.ID));
}
public Set<String> getRoleIds() {
return new HashSet<>(dsl.select(ROLE.ID)
.from(ROLE)
.fetch(ROLE.ID));
}
public Set<String> getDomainIds() {
return new HashSet<>(dsl.select(DOMAIN.ID)
.from(DOMAIN)
.fetch(DOMAIN.ID));
}
public void insertDomainRecords(List<DomainRecord> domainRecords) {
dsl.batchInsert(domainRecords).execute();
}
public void updateDomainRecords(List<DomainRecord> domainRecords) {
dsl.batchUpdate(domainRecords).execute();
}
public void insertRoleRecords(List<RoleRecord> newRoleRecords) {
dsl.batchInsert(newRoleRecords).execute();
}
public void updateRoleRecords(List<RoleRecord> roleRecords) {
dsl.batchUpdate(roleRecords).execute();
}
public void insertAccountRecords(List<AccountRecord> newAccountRecords) {
dsl.batchInsert(newAccountRecords).execute();
}
public void updateAccountRecords(List<AccountRecord> accountRecords) {
dsl.batchUpdate(accountRecords).execute();
}
public void insertAccountRoleRecords(List<AccountRoleRecord> newAccountRoleRecords) {
dsl.batchInsert(newAccountRoleRecords).execute();
}
public void deleteAccountRolesByAccountIds(List<String> accountIds) {
dsl.deleteFrom(ACCOUNT_ROLE)
.where(ACCOUNT_ROLE.ACCOUNT_ID.in(accountIds))
.execute();
}
public void deleteAccountByIds(List<String> accountIds) {
dsl.deleteFrom(ACCOUNT)
.where(ACCOUNT.ID.in(accountIds))
.execute();
}
public void deleteDomainsByIds(List<String> domainIds) {
dsl.deleteFrom(DOMAIN)
.where(DOMAIN.ID.in(domainIds))
.execute();
}
}

View file

@ -1,33 +0,0 @@
package ervu_business_metrics.dao;
import org.jooq.DSLContext;
import org.springframework.stereotype.Repository;
import ru.micord.webbpm.ervu.business_metrics.db_beans.idm_reconcile.tables.records.DomainRecord;
import ru.micord.webbpm.ervu.business_metrics.db_beans.idm_reconcile.tables.records.RoleRecord;
import static ru.micord.webbpm.ervu.business_metrics.db_beans.idm_reconcile.Tables.DOMAIN;
import static ru.micord.webbpm.ervu.business_metrics.db_beans.idm_reconcile.Tables.ROLE;
/**
* @author Adel Kalimullin
*/
@Repository
public class IdmDirectoriesDaoService {
private final DSLContext dsl;
public IdmDirectoriesDaoService(DSLContext dsl) {
this.dsl = dsl;
}
public RoleRecord getRoleRecord() {
return dsl.newRecord(ROLE);
}
public DomainRecord getDomainRecord() {
return dsl.newRecord(DOMAIN);
}
}

View file

@ -3,15 +3,18 @@ package ervu_business_metrics.kafka;
import java.util.HashMap;
import java.util.Map;
import ervu_business_metrics.config.IdmReconcileEnabledCondition;
import org.apache.kafka.clients.CommonClientConfigs;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.common.config.SaslConfigs;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.annotation.EnableKafka;
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
import org.springframework.kafka.config.KafkaListenerEndpointRegistry;
import org.springframework.kafka.core.ConsumerFactory;
import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
@ -20,6 +23,7 @@ import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
*/
@Configuration
@EnableKafka
@Conditional(IdmReconcileEnabledCondition.class)
public class KafkaConfig {
@Value("${kafka.hosts}")
private String bootstrapServers;
@ -34,6 +38,11 @@ public class KafkaConfig {
@Value("${kafka.auth_sasl_mech}")
private String saslMechanism;
@Bean
public KafkaListenerEndpointRegistry kafkaListenerEndpointRegistry() {
return new KafkaListenerEndpointRegistry();
}
@Bean
public ConsumerFactory<String, String> consumerFactory() {
return new DefaultKafkaConsumerFactory<>(consumerConfigs());

View file

@ -0,0 +1,54 @@
package ervu_business_metrics.kafka;
import javax.annotation.PostConstruct;
import ervu_business_metrics.config.IdmReconcileEnabledCondition;
import ervu_business_metrics.service.IdmDirectoriesService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.DependsOn;
import org.springframework.kafka.config.KafkaListenerEndpointRegistry;
import org.springframework.kafka.listener.MessageListenerContainer;
import org.springframework.stereotype.Component;
/**
* @author Adel Kalimullin
*/
@Component
@DependsOn("idmDirectoriesListener")
@Conditional(IdmReconcileEnabledCondition.class)
public class KafkaConsumerInitializer {
private final KafkaListenerEndpointRegistry kafkaListenerEndpointRegistry;
private final IdmDirectoriesService idmDirectoriesService;
@Value("${kafka.domain.group.id}")
private String domainGroupId;
@Value("${kafka.role.group.id}")
private String roleGroupId;
@Value("${kafka.account.group.id}")
private String accountGroupId;
public KafkaConsumerInitializer(KafkaListenerEndpointRegistry kafkaListenerEndpointRegistry,
IdmDirectoriesService idmDirectoriesService) {
this.kafkaListenerEndpointRegistry = kafkaListenerEndpointRegistry;
this.idmDirectoriesService = idmDirectoriesService;
}
@PostConstruct
public void initialize() {
startKafkaListener(domainGroupId);
startKafkaListener(roleGroupId);
startKafkaListener(accountGroupId);
new Thread(idmDirectoriesService::updateDirectories).start();
}
private void startKafkaListener(String listenerId) {
MessageListenerContainer container = kafkaListenerEndpointRegistry.getListenerContainer(listenerId);
if (container != null) {
container.start();
}
else {
throw new IllegalStateException("Kafka Listener not found: " + listenerId);
}
}
}

View file

@ -1,6 +1,11 @@
package ervu_business_metrics.kafka.listener;
import ervu_business_metrics.config.IdmReconcileEnabledCondition;
import ervu_business_metrics.model.AccountData;
import ervu_business_metrics.model.DomainData;
import ervu_business_metrics.model.RoleData;
import ervu_business_metrics.service.IdmDirectoriesService;
import org.springframework.context.annotation.Conditional;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
@ -8,26 +13,56 @@ import org.springframework.stereotype.Component;
* @author Adel Kalimullin
*/
@Component
@Conditional(IdmReconcileEnabledCondition.class)
public class IdmDirectoriesListener {
private IdmDirectoriesService idmDirectoriesService;
private final IdmDirectoriesService idmDirectoriesService;
public IdmDirectoriesListener(IdmDirectoriesService idmDirectoriesService) {
this.idmDirectoriesService = idmDirectoriesService;
}
@KafkaListener(id = "${kafka.domain.group.id}", topics = "${kafka.domain.reconciliation}")
public void listenKafkaDomain(String kafkaMessage) {
idmDirectoriesService.upsertKafkaDomainMessage(kafkaMessage);
idmDirectoriesService.processUpsertMessage(kafkaMessage, DomainData.class);
}
@KafkaListener(id = "${kafka.role.group.id}", topics = "${kafka.role.reconciliation}")
public void listenKafkaRole(String kafkaMessage) {
idmDirectoriesService.upsertKafkaRoleMessage(kafkaMessage);
idmDirectoriesService.processUpsertMessage(kafkaMessage, RoleData.class);
}
@KafkaListener(id = "${kafka.account.group.id}", topics = "${kafka.account.reconciliation}")
public void listenKafkaAccount(String kafkaMessage) {
idmDirectoriesService.upsertKafkaAccountMessage(kafkaMessage);
idmDirectoriesService.processUpsertMessage(kafkaMessage, AccountData.class);
}
@KafkaListener(id = "${kafka.person.group.id}", topics = "${kafka.person.reconciliation}")
public void listenKafkaPerson(String kafkaMessage) {
idmDirectoriesService.upsertKafkaPersonMessage(kafkaMessage);
@KafkaListener(id = "${kafka.domain.updated.group.id}", topics = "${kafka.domain.updated}")
public void listenKafkaDomainUpdated(String kafkaMessage) {
idmDirectoriesService.processUpsertMessage(kafkaMessage, DomainData.class);
}
@KafkaListener(id = "${kafka.domain.created.group.id}", topics = "${kafka.domain.created}")
public void listenKafkaDomainCreated(String kafkaMessage) {
idmDirectoriesService.processUpsertMessage(kafkaMessage, DomainData.class);
}
@KafkaListener(id = "${kafka.account.updated.group.id}", topics = "${kafka.account.updated}")
public void listenKafkaAccountUpdated(String kafkaMessage) {
idmDirectoriesService.processUpsertMessage(kafkaMessage, AccountData.class);
}
@KafkaListener(id = "${kafka.account.created.group.id}", topics = "${kafka.account.created}")
public void listenKafkaAccountCreated(String kafkaMessage) {
idmDirectoriesService.processUpsertMessage(kafkaMessage, AccountData.class);
}
@KafkaListener(id = "${kafka.domain.deleted.group.id}", topics = "${kafka.domain.deleted}")
public void listenKafkaDomainDeleted(String kafkaMessage) {
idmDirectoriesService.processDeleteMessage(kafkaMessage, DomainData.class);
}
@KafkaListener(id = "${kafka.account.deleted.group.id}", topics = "${kafka.account.deleted}")
public void listenKafkaAccountDeleted(String kafkaMessage) {
idmDirectoriesService.processDeleteMessage(kafkaMessage, AccountData.class);
}
}

View file

@ -0,0 +1,47 @@
package ervu_business_metrics.kafka.model;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* @author Adel Kalimullin
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class DeleteKafkaMessage {
private boolean success;
private String message;
private List<String> data;
private String origin;
public List<String> getData() {
return data;
}
public void setData(List<String> data) {
this.data = data;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getOrigin() {
return origin;
}
public void setOrigin(String origin) {
this.origin = origin;
}
}

View file

@ -0,0 +1,21 @@
package ervu_business_metrics.kafka.model;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* @author Adel Kalimullin
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class UpsertMessage<T>{
private List<T> data;
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
}

View file

@ -0,0 +1,132 @@
package ervu_business_metrics.model;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* @author Adel Kalimullin
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class AccountData {
private String id;
private int version;
private long modified;
private String schema;
private String start;
private String finish;
private boolean enabled;
private String position;
private String fio;
private String workMail;
private boolean esiaAccount;
@JsonProperty("user-domain")
private ReferenceEntity userDomain;
private List<String> roles;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public long getModified() {
return modified;
}
public void setModified(long modified) {
this.modified = modified;
}
public String getSchema() {
return schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public String getStart() {
return start;
}
public void setStart(String start) {
this.start = start;
}
public String getFinish() {
return finish;
}
public void setFinish(String finish) {
this.finish = finish;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public String getFio() {
return fio;
}
public void setFio(String fio) {
this.fio = fio;
}
public String getWorkMail() {
return workMail;
}
public void setWorkMail(String workMail) {
this.workMail = workMail;
}
public boolean isEsiaAccount() {
return esiaAccount;
}
public void setEsiaAccount(boolean esiaAccount) {
this.esiaAccount = esiaAccount;
}
public ReferenceEntity getUserDomain() {
return userDomain;
}
public void setUserDomain(ReferenceEntity userDomain) {
this.userDomain = userDomain;
}
public List<String> getRoles() {
return roles;
}
public void setRoles(List<String> roles) {
this.roles = roles;
}
}

View file

@ -0,0 +1,460 @@
package ervu_business_metrics.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* @author Adel Kalimullin
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class DomainData {
private String id;
private int version;
private long modified;
private String schema;
private String name;
private String shortname;
private String fullname;
private String dns;
private String email;
private String phone;
private String address;
private String postalAddress;
private String addressId;
private String postalAddressId;
private String militaryCode;
private String timezone;
private boolean reportsEnabled;
private String inn;
private String leg;
private String ogrn;
private String region;
private String epguId;
private String type;
private boolean esiaEmployeeAuthorization;
private String defaultS3Bucket;
private String opf;
private String kpp;
private String checkingAccount;
private String bik;
private String bankName;
private String bankCorrespondentAccount;
private String oktmo;
private String okato;
private String govRegistrationDate;
private String govOrganizationType;
private String aliasKey;
private String passKey;
private String certificate;
private String accountNumberTOFK;
private String bikTOFK;
private String correspondentBankAccountTOFK;
private String nameTOFK;
private String nsiOrganizationId;
private String docHandle;
private String divisionType;
private String tnsDepartmentId;
private boolean enabled;
private String parent;
private String regionId;
private String managed;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public long getModified() {
return modified;
}
public void setModified(long modified) {
this.modified = modified;
}
public String getSchema() {
return schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getShortname() {
return shortname;
}
public void setShortname(String shortname) {
this.shortname = shortname;
}
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getDns() {
return dns;
}
public void setDns(String dns) {
this.dns = dns;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPostalAddress() {
return postalAddress;
}
public void setPostalAddress(String postalAddress) {
this.postalAddress = postalAddress;
}
public String getAddressId() {
return addressId;
}
public void setAddressId(String addressId) {
this.addressId = addressId;
}
public String getPostalAddressId() {
return postalAddressId;
}
public void setPostalAddressId(String postalAddressId) {
this.postalAddressId = postalAddressId;
}
public String getMilitaryCode() {
return militaryCode;
}
public void setMilitaryCode(String militaryCode) {
this.militaryCode = militaryCode;
}
public String getTimezone() {
return timezone;
}
public void setTimezone(String timezone) {
this.timezone = timezone;
}
public boolean isReportsEnabled() {
return reportsEnabled;
}
public void setReportsEnabled(boolean reportsEnabled) {
this.reportsEnabled = reportsEnabled;
}
public String getInn() {
return inn;
}
public void setInn(String inn) {
this.inn = inn;
}
public String getLeg() {
return leg;
}
public void setLeg(String leg) {
this.leg = leg;
}
public String getOgrn() {
return ogrn;
}
public void setOgrn(String ogrn) {
this.ogrn = ogrn;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public String getEpguId() {
return epguId;
}
public void setEpguId(String epguId) {
this.epguId = epguId;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isEsiaEmployeeAuthorization() {
return esiaEmployeeAuthorization;
}
public void setEsiaEmployeeAuthorization(boolean esiaEmployeeAuthorization) {
this.esiaEmployeeAuthorization = esiaEmployeeAuthorization;
}
public String getDefaultS3Bucket() {
return defaultS3Bucket;
}
public void setDefaultS3Bucket(String defaultS3Bucket) {
this.defaultS3Bucket = defaultS3Bucket;
}
public String getOpf() {
return opf;
}
public void setOpf(String opf) {
this.opf = opf;
}
public String getKpp() {
return kpp;
}
public void setKpp(String kpp) {
this.kpp = kpp;
}
public String getCheckingAccount() {
return checkingAccount;
}
public void setCheckingAccount(String checkingAccount) {
this.checkingAccount = checkingAccount;
}
public String getBik() {
return bik;
}
public void setBik(String bik) {
this.bik = bik;
}
public String getBankName() {
return bankName;
}
public void setBankName(String bankName) {
this.bankName = bankName;
}
public String getBankCorrespondentAccount() {
return bankCorrespondentAccount;
}
public void setBankCorrespondentAccount(String bankCorrespondentAccount) {
this.bankCorrespondentAccount = bankCorrespondentAccount;
}
public String getOktmo() {
return oktmo;
}
public void setOktmo(String oktmo) {
this.oktmo = oktmo;
}
public String getOkato() {
return okato;
}
public void setOkato(String okato) {
this.okato = okato;
}
public String getGovRegistrationDate() {
return govRegistrationDate;
}
public void setGovRegistrationDate(String govRegistrationDate) {
this.govRegistrationDate = govRegistrationDate;
}
public String getGovOrganizationType() {
return govOrganizationType;
}
public void setGovOrganizationType(String govOrganizationType) {
this.govOrganizationType = govOrganizationType;
}
public String getAliasKey() {
return aliasKey;
}
public void setAliasKey(String aliasKey) {
this.aliasKey = aliasKey;
}
public String getPassKey() {
return passKey;
}
public void setPassKey(String passKey) {
this.passKey = passKey;
}
public String getCertificate() {
return certificate;
}
public void setCertificate(String certificate) {
this.certificate = certificate;
}
public String getAccountNumberTOFK() {
return accountNumberTOFK;
}
public void setAccountNumberTOFK(String accountNumberTOFK) {
this.accountNumberTOFK = accountNumberTOFK;
}
public String getBikTOFK() {
return bikTOFK;
}
public void setBikTOFK(String bikTOFK) {
this.bikTOFK = bikTOFK;
}
public String getCorrespondentBankAccountTOFK() {
return correspondentBankAccountTOFK;
}
public void setCorrespondentBankAccountTOFK(String correspondentBankAccountTOFK) {
this.correspondentBankAccountTOFK = correspondentBankAccountTOFK;
}
public String getNameTOFK() {
return nameTOFK;
}
public void setNameTOFK(String nameTOFK) {
this.nameTOFK = nameTOFK;
}
public String getNsiOrganizationId() {
return nsiOrganizationId;
}
public void setNsiOrganizationId(String nsiOrganizationId) {
this.nsiOrganizationId = nsiOrganizationId;
}
public String getDocHandle() {
return docHandle;
}
public void setDocHandle(String docHandle) {
this.docHandle = docHandle;
}
public String getDivisionType() {
return divisionType;
}
public void setDivisionType(String divisionType) {
this.divisionType = divisionType;
}
public String getTnsDepartmentId() {
return tnsDepartmentId;
}
public void setTnsDepartmentId(String tnsDepartmentId) {
this.tnsDepartmentId = tnsDepartmentId;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getParent() {
return parent;
}
public void setParent(String parent) {
this.parent = parent;
}
public String getRegionId() {
return regionId;
}
public void setRegionId(String regionId) {
this.regionId = regionId;
}
public String getManaged() {
return managed;
}
public void setManaged(String managed) {
this.managed = managed;
}
}

View file

@ -0,0 +1,19 @@
package ervu_business_metrics.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* @author Adel Kalimullin
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class ReferenceEntity {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}

View file

@ -0,0 +1,109 @@
package ervu_business_metrics.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* @author Adel Kalimullin
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class RoleData {
private String id;
private int version;
private long modified;
private String schema;
private String name;
private String shortname;
private String displayName;
private int sessionsLimit;
private boolean ervuRole;
private int imported;
private String description;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public long getModified() {
return modified;
}
public void setModified(long modified) {
this.modified = modified;
}
public String getSchema() {
return schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getShortname() {
return shortname;
}
public void setShortname(String shortname) {
this.shortname = shortname;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public int getSessionsLimit() {
return sessionsLimit;
}
public void setSessionsLimit(int sessionsLimit) {
this.sessionsLimit = sessionsLimit;
}
public boolean isErvuRole() {
return ervuRole;
}
public void setErvuRole(boolean ervuRole) {
this.ervuRole = ervuRole;
}
public int getImported() {
return imported;
}
public void setImported(int imported) {
this.imported = imported;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

View file

@ -1,184 +0,0 @@
package ervu_business_metrics.model.dto;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* @author Adel Kalimullin
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class AccountResponse {
private List<Data> data;
public List<Data> getData() {
return data;
}
public void setData(List<Data> data) {
this.data = data;
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Data {
private String id;
private int version;
private long modified;
private String schema;
private String start;
private String finish;
private boolean enabled;
private String position;
private String fio;
private String workMail;
private boolean esiaAccount;
private String userDomainId;
private String personId;
@JsonProperty("user-domain")
private ReferenceEntity userDomain;
private ReferenceEntity person;
private List<String> roles;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public long getModified() {
return modified;
}
public void setModified(long modified) {
this.modified = modified;
}
public String getSchema() {
return schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public String getStart() {
return start;
}
public void setStart(String start) {
this.start = start;
}
public String getFinish() {
return finish;
}
public void setFinish(String finish) {
this.finish = finish;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public String getFio() {
return fio;
}
public void setFio(String fio) {
this.fio = fio;
}
public String getWorkMail() {
return workMail;
}
public void setWorkMail(String workMail) {
this.workMail = workMail;
}
public boolean isEsiaAccount() {
return esiaAccount;
}
public void setEsiaAccount(boolean esiaAccount) {
this.esiaAccount = esiaAccount;
}
public String getUserDomainId() {
return userDomainId;
}
public void setUserDomainId(String userDomainId) {
this.userDomainId = userDomainId;
}
public String getPersonId() {
return personId;
}
public void setPersonId(String personId) {
this.personId = personId;
}
public ReferenceEntity getUserDomain() {
return userDomain;
}
public void setUserDomain(ReferenceEntity userDomain) {
this.userDomain = userDomain;
}
public ReferenceEntity getPerson() {
return person;
}
public void setPerson(ReferenceEntity person) {
this.person = person;
}
public List<String> getRoles() {
return roles;
}
public void setRoles(List<String> roles) {
this.roles = roles;
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class ReferenceEntity {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
}

View file

@ -1,474 +0,0 @@
package ervu_business_metrics.model.dto;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* @author Eduard Tihomirov
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class DomainResponse{
private List<Data> data;
public List<Data> getData() {
return data;
}
public void setData(List<Data> data) {
this.data = data;
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Data {
private String id;
private int version;
private long modified;
private String schema;
private String name;
private String shortname;
private String fullname;
private String dns;
private String email;
private String phone;
private String address;
private String postalAddress;
private String addressId;
private String postalAddressId;
private String militaryCode;
private String timezone;
private boolean reportsEnabled;
private String inn;
private String leg;
private String ogrn;
private String region;
private String epguId;
private String type;
private boolean esiaEmployeeAuthorization;
private String defaultS3Bucket;
private String opf;
private String kpp;
private String checkingAccount;
private String bik;
private String bankName;
private String bankCorrespondentAccount;
private String oktmo;
private String okato;
private String govRegistrationDate;
private String govOrganizationType;
private String aliasKey;
private String passKey;
private String certificate;
private String accountNumberTOFK;
private String bikTOFK;
private String correspondentBankAccountTOFK;
private String nameTOFK;
private String nsiOrganizationId;
private String docHandle;
private String divisionType;
private String tnsDepartmentId;
private boolean enabled;
private String parent;
private String regionId;
private String managed;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public long getModified() {
return modified;
}
public void setModified(long modified) {
this.modified = modified;
}
public String getSchema() {
return schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getShortname() {
return shortname;
}
public void setShortname(String shortname) {
this.shortname = shortname;
}
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getDns() {
return dns;
}
public void setDns(String dns) {
this.dns = dns;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPostalAddress() {
return postalAddress;
}
public void setPostalAddress(String postalAddress) {
this.postalAddress = postalAddress;
}
public String getAddressId() {
return addressId;
}
public void setAddressId(String addressId) {
this.addressId = addressId;
}
public String getPostalAddressId() {
return postalAddressId;
}
public void setPostalAddressId(String postalAddressId) {
this.postalAddressId = postalAddressId;
}
public String getMilitaryCode() {
return militaryCode;
}
public void setMilitaryCode(String militaryCode) {
this.militaryCode = militaryCode;
}
public String getTimezone() {
return timezone;
}
public void setTimezone(String timezone) {
this.timezone = timezone;
}
public boolean isReportsEnabled() {
return reportsEnabled;
}
public void setReportsEnabled(boolean reportsEnabled) {
this.reportsEnabled = reportsEnabled;
}
public String getInn() {
return inn;
}
public void setInn(String inn) {
this.inn = inn;
}
public String getLeg() {
return leg;
}
public void setLeg(String leg) {
this.leg = leg;
}
public String getOgrn() {
return ogrn;
}
public void setOgrn(String ogrn) {
this.ogrn = ogrn;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public String getEpguId() {
return epguId;
}
public void setEpguId(String epguId) {
this.epguId = epguId;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isEsiaEmployeeAuthorization() {
return esiaEmployeeAuthorization;
}
public void setEsiaEmployeeAuthorization(boolean esiaEmployeeAuthorization) {
this.esiaEmployeeAuthorization = esiaEmployeeAuthorization;
}
public String getDefaultS3Bucket() {
return defaultS3Bucket;
}
public void setDefaultS3Bucket(String defaultS3Bucket) {
this.defaultS3Bucket = defaultS3Bucket;
}
public String getOpf() {
return opf;
}
public void setOpf(String opf) {
this.opf = opf;
}
public String getKpp() {
return kpp;
}
public void setKpp(String kpp) {
this.kpp = kpp;
}
public String getCheckingAccount() {
return checkingAccount;
}
public void setCheckingAccount(String checkingAccount) {
this.checkingAccount = checkingAccount;
}
public String getBik() {
return bik;
}
public void setBik(String bik) {
this.bik = bik;
}
public String getBankName() {
return bankName;
}
public void setBankName(String bankName) {
this.bankName = bankName;
}
public String getBankCorrespondentAccount() {
return bankCorrespondentAccount;
}
public void setBankCorrespondentAccount(String bankCorrespondentAccount) {
this.bankCorrespondentAccount = bankCorrespondentAccount;
}
public String getOktmo() {
return oktmo;
}
public void setOktmo(String oktmo) {
this.oktmo = oktmo;
}
public String getOkato() {
return okato;
}
public void setOkato(String okato) {
this.okato = okato;
}
public String getGovRegistrationDate() {
return govRegistrationDate;
}
public void setGovRegistrationDate(String govRegistrationDate) {
this.govRegistrationDate = govRegistrationDate;
}
public String getGovOrganizationType() {
return govOrganizationType;
}
public void setGovOrganizationType(String govOrganizationType) {
this.govOrganizationType = govOrganizationType;
}
public String getAliasKey() {
return aliasKey;
}
public void setAliasKey(String aliasKey) {
this.aliasKey = aliasKey;
}
public String getPassKey() {
return passKey;
}
public void setPassKey(String passKey) {
this.passKey = passKey;
}
public String getCertificate() {
return certificate;
}
public void setCertificate(String certificate) {
this.certificate = certificate;
}
public String getAccountNumberTOFK() {
return accountNumberTOFK;
}
public void setAccountNumberTOFK(String accountNumberTOFK) {
this.accountNumberTOFK = accountNumberTOFK;
}
public String getBikTOFK() {
return bikTOFK;
}
public void setBikTOFK(String bikTOFK) {
this.bikTOFK = bikTOFK;
}
public String getCorrespondentBankAccountTOFK() {
return correspondentBankAccountTOFK;
}
public void setCorrespondentBankAccountTOFK(String correspondentBankAccountTOFK) {
this.correspondentBankAccountTOFK = correspondentBankAccountTOFK;
}
public String getNameTOFK() {
return nameTOFK;
}
public void setNameTOFK(String nameTOFK) {
this.nameTOFK = nameTOFK;
}
public String getNsiOrganizationId() {
return nsiOrganizationId;
}
public void setNsiOrganizationId(String nsiOrganizationId) {
this.nsiOrganizationId = nsiOrganizationId;
}
public String getDocHandle() {
return docHandle;
}
public void setDocHandle(String docHandle) {
this.docHandle = docHandle;
}
public String getDivisionType() {
return divisionType;
}
public void setDivisionType(String divisionType) {
this.divisionType = divisionType;
}
public String getTnsDepartmentId() {
return tnsDepartmentId;
}
public void setTnsDepartmentId(String tnsDepartmentId) {
this.tnsDepartmentId = tnsDepartmentId;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getParent() {
return parent;
}
public void setParent(String parent) {
this.parent = parent;
}
public String getRegionId() {
return regionId;
}
public void setRegionId(String regionId) {
this.regionId = regionId;
}
public String getManaged() {
return managed;
}
public void setManaged(String managed) {
this.managed = managed;
}
}
}

View file

@ -1,169 +0,0 @@
package ervu_business_metrics.model.dto;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* @author Adel Kalimullin
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class PersonResponse {
private List<Data> data;
public List<Data> getData() {
return data;
}
public void setData(List<Data> data) {
this.data = data;
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Data {
private String id;
private int version;
private long modified;
private String schema;
private String birthdate;
private String firstname;
private String middlename;
private String surname;
private String sex;
private String email;
private String photo;
private String phone;
private String snils;
private boolean secondFactorEnabled;
private List<String> ipAddresses;
private String fio;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public long getModified() {
return modified;
}
public void setModified(long modified) {
this.modified = modified;
}
public String getSchema() {
return schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public String getBirthdate() {
return birthdate;
}
public void setBirthdate(String birthdate) {
this.birthdate = birthdate;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getMiddlename() {
return middlename;
}
public void setMiddlename(String middlename) {
this.middlename = middlename;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getSnils() {
return snils;
}
public void setSnils(String snils) {
this.snils = snils;
}
public boolean isSecondFactorEnabled() {
return secondFactorEnabled;
}
public void setSecondFactorEnabled(boolean secondFactorEnabled) {
this.secondFactorEnabled = secondFactorEnabled;
}
public List<String> getIpAddresses() {
return ipAddresses;
}
public void setIpAddresses(List<String> ipAddresses) {
this.ipAddresses = ipAddresses;
}
public String getFio() {
return fio;
}
public void setFio(String fio) {
this.fio = fio;
}
}
}

View file

@ -1,124 +0,0 @@
package ervu_business_metrics.model.dto;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* @author Eduard Tihomirov
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class RoleResponse {
private List<Data> data;
public List<Data> getData() {
return data;
}
public void setData(List<Data> data) {
this.data = data;
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Data {
private String id;
private int version;
private long modified;
private String schema;
private String name;
private String shortname;
private String displayName;
private int sessionsLimit;
private boolean ervuRole;
private int imported;
private String description;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public long getModified() {
return modified;
}
public void setModified(long modified) {
this.modified = modified;
}
public String getSchema() {
return schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getShortname() {
return shortname;
}
public void setShortname(String shortname) {
this.shortname = shortname;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public int getSessionsLimit() {
return sessionsLimit;
}
public void setSessionsLimit(int sessionsLimit) {
this.sessionsLimit = sessionsLimit;
}
public boolean isErvuRole() {
return ervuRole;
}
public void setErvuRole(boolean ervuRole) {
this.ervuRole = ervuRole;
}
public int getImported() {
return imported;
}
public void setImported(int imported) {
this.imported = imported;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
}

View file

@ -0,0 +1,100 @@
package ervu_business_metrics.service;
import java.util.List;
import java.util.Set;
import ervu_business_metrics.dao.IdmDirectoriesDao;
import ervu_business_metrics.config.IdmReconcileEnabledCondition;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Repository;
import ru.micord.webbpm.ervu.business_metrics.db_beans.idm_reconcile.tables.records.*;
/**
* @author Adel Kalimullin
*/
@Repository
@Conditional(IdmReconcileEnabledCondition.class)
public class IdmDirectoriesDaoService {
private final IdmDirectoriesDao idmDirectoriesDao;
public IdmDirectoriesDaoService(IdmDirectoriesDao idmDirectoriesDao) {
this.idmDirectoriesDao = idmDirectoriesDao;
}
public RoleRecord getRoleRecord() {
return idmDirectoriesDao.getRoleRecord();
}
public DomainRecord getDomainRecord() {
return idmDirectoriesDao.getDomainRecord();
}
public AccountRecord getAccountRecord() {
return idmDirectoriesDao.getAccountRecord();
}
public AccountRoleRecord getAccountRoleRecord() {
return idmDirectoriesDao.getAccountRoleRecord();
}
@Cacheable(value = "account-ids", unless = "#result == null")
public Set<String> getAccountIds() {
return idmDirectoriesDao.getAccountIds();
}
@Cacheable(value = "role-ids", unless = "#result == null")
public Set<String> getRoleIds() {
return idmDirectoriesDao.getRoleIds();
}
@Cacheable(value = "domain-ids", unless = "#result == null")
public Set<String> getDomainIds() {
return idmDirectoriesDao.getDomainIds();
}
public void insertDomainRecords(List<DomainRecord> newDomainRecords) {
idmDirectoriesDao.insertDomainRecords(newDomainRecords);
}
public void updateDomainRecords(List<DomainRecord> domainRecords) {
idmDirectoriesDao.updateDomainRecords(domainRecords);
}
public void insertRoleRecords(List<RoleRecord> newRoleRecords) {
idmDirectoriesDao.insertRoleRecords(newRoleRecords);
}
public void updateRoleRecords(List<RoleRecord> roleRecords) {
idmDirectoriesDao.updateRoleRecords(roleRecords);
}
public void insertAccountRecords(List<AccountRecord> accountRecords) {
idmDirectoriesDao.insertAccountRecords(accountRecords);
}
public void updateAccountRecords(List<AccountRecord> accountRecords) {
idmDirectoriesDao.updateAccountRecords(accountRecords);
}
public void insertAccountRoleRecords(List<AccountRoleRecord> newAccountRoleRecords) {
idmDirectoriesDao.insertAccountRoleRecords(newAccountRoleRecords);
}
public void deleteAccountRolesByAccountIds(List<String> accountIds) {
idmDirectoriesDao.deleteAccountRolesByAccountIds(accountIds);
}
@CacheEvict(value = "domain-ids", allEntries = true)
public void deleteDomainsByIds(List<String> domainIds) {
idmDirectoriesDao.deleteDomainsByIds(domainIds);
}
@CacheEvict(value = "account-ids", allEntries = true)
public void deleteAccountsByIds(List<String> accountIds) {
idmDirectoriesDao.deleteAccountByIds(accountIds);
}
}

View file

@ -1,22 +1,30 @@
package ervu_business_metrics.service;
import java.lang.invoke.MethodHandles;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import ervu_business_metrics.dao.IdmDirectoriesDaoService;
import ervu_business_metrics.model.dto.AccountResponse;
import ervu_business_metrics.model.dto.DomainResponse;
import ervu_business_metrics.model.dto.PersonResponse;
import ervu_business_metrics.model.dto.RoleResponse;
import ervu_business_metrics.config.IdmReconcileEnabledCondition;
import ervu_business_metrics.kafka.model.DeleteKafkaMessage;
import ervu_business_metrics.kafka.model.UpsertMessage;
import ervu_business_metrics.model.AccountData;
import ervu_business_metrics.model.DomainData;
import ervu_business_metrics.model.RoleData;
import ervu_business_metrics.service.processor.impl.AccountDataProcessor;
import ervu_business_metrics.service.processor.DataProcessor;
import ervu_business_metrics.service.processor.impl.DomainDataProcessor;
import ervu_business_metrics.service.processor.impl.RoleDataProcessor;
import exception.IdmDirectoriesException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Caching;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.DependsOn;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
@ -24,227 +32,111 @@ import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import ru.micord.webbpm.ervu.business_metrics.db_beans.idm_reconcile.tables.records.DomainRecord;
/**
* @author Adel Kalimullin
*/
@Component
@DependsOn("liquibase")
@Conditional(IdmReconcileEnabledCondition.class)
public class IdmDirectoriesService {
private static final Logger LOGGER = LoggerFactory.getLogger(
MethodHandles.lookup().lookupClass());
@Value("${idm.url}")
private String idmUrl;
@Value("${ervu.collection:domain, role , account , person}")
private String ervuCollection;
private final RestTemplate restTemplate;
private final IdmDirectoriesDaoService idmDirectoriesDaoService;
private final ObjectMapper objectMapper;
private final Map<Class<?>, DataProcessor<?>> dataProcessors = new HashMap<>();
@Value("${ervu.idm.url}")
private String idmUrl;
@Value("${ervu.directories:domain, role , account }")
private String ervuDirectories;
public IdmDirectoriesService(RestTemplate restTemplate,
IdmDirectoriesDaoService idmDirectoriesDaoService, ObjectMapper objectMapper) {
public IdmDirectoriesService(
RestTemplate restTemplate,
AccountDataProcessor accountDataProcessor,
DomainDataProcessor domainDataProcessor,
RoleDataProcessor roleDataProcessor, ObjectMapper objectMapper) {
this.restTemplate = restTemplate;
this.idmDirectoriesDaoService = idmDirectoriesDaoService;
this.objectMapper = objectMapper;
dataProcessors.put(AccountData.class, accountDataProcessor);
dataProcessors.put(DomainData.class, domainDataProcessor);
dataProcessors.put(RoleData.class, roleDataProcessor);
}
@Caching(evict = {
@CacheEvict(value = "domain-ids", allEntries = true),
@CacheEvict(value = "role-ids", allEntries = true)
@CacheEvict(value = "role-ids", allEntries = true),
@CacheEvict(value = "account-ids", allEntries = true)
})
public void updateDirectories() {
try {
String[] ervuCollectionArray = ervuCollection.split(",");
Arrays.stream(ervuCollectionArray).forEach(ervuCollection -> {
String targetUrl = idmUrl + "/reconcile/"+ ervuCollection.trim() + "/to/kafka/v1";
String[] ervuDirectoriesArray = ervuDirectories.split(",");
Arrays.stream(ervuDirectoriesArray).forEach(ervuDirectory -> {
String targetUrl = idmUrl + "/reconcile/" + ervuDirectory.trim() + "/to/kafka/v1";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
String emptyJson = "{}";
HttpEntity<String> requestEntity = new HttpEntity<>(emptyJson, headers);
ResponseEntity<String> response = restTemplate.postForEntity(targetUrl, requestEntity, String.class);
ResponseEntity<String> response = restTemplate.postForEntity(targetUrl, requestEntity,
String.class
);
if (!response.getStatusCode().is2xxSuccessful()) {
LOGGER.error(
"Error in " + ervuCollection + " request. Status code: " + response.getStatusCode()
+ "; Body: " + response.getBody());
LOGGER.error("Error in {} request. Status code: {}; Body: {}",
ervuDirectory, response.getStatusCode(), response.getBody()
);
}
});
}
catch (Exception e) {
LOGGER.error(e.getMessage());
throw new RuntimeException(e);
}
}
@Transactional
public void upsertKafkaPersonMessage(String kafkaMessage) {
PersonResponse[] personResponses;
try {
personResponses = objectMapper.readValue(kafkaMessage, PersonResponse[].class);
}
catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
if (personResponses.length > 0 && personResponses[0].getData() != null && !personResponses[0].getData().isEmpty()) {
upsertRecruitmentData(personResponses[0].getData());
throw new IdmDirectoriesException(e);
}
}
@Transactional
public void upsertKafkaAccountMessage(String kafkaMessage) {
AccountResponse[] accountResponses;
public <T> void processUpsertMessage(String kafkaMessage, Class<T> entityClass) {
try {
accountResponses = objectMapper.readValue(kafkaMessage, AccountResponse[].class);
}
catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
if (accountResponses.length > 0 && accountResponses[0].getData() != null && !accountResponses[0].getData().isEmpty()) {
upsertRecruitmentData(accountResponses[0].getData());
}
}
JavaType messageType = objectMapper.getTypeFactory()
.constructParametricType(UpsertMessage.class, entityClass);
JavaType arrayType = objectMapper.getTypeFactory()
.constructArrayType(messageType);
@Transactional
public void upsertKafkaDomainMessage(String kafkaMessage) {
DomainResponse[] domainResponses;
try {
domainResponses = objectMapper.readValue(kafkaMessage, DomainResponse[].class);
}
catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
if (domainResponses.length > 0 && domainResponses[0].getData() != null && !domainResponses[0].getData().isEmpty()) {
upsertDomainData(domainResponses[0].getData());
}
}
@Transactional
public void upsertKafkaRoleMessage(String kafkaMessage) {
RoleResponse[] roleResponses;
try {
roleResponses = objectMapper.readValue(kafkaMessage, RoleResponse[].class);
}
catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
if (roleResponses.length > 0 && roleResponses[0].getData() != null && !roleResponses[0].getData().isEmpty()) {
upsertRoleData(roleResponses[0].getData());
}
}
private void upsertDomainData(List<DomainResponse.Data> dataList) {
List<DomainRecord> newRecruitmentRecords = new ArrayList<>();
List<DomainRecord> recruitmentRecords = new ArrayList<>();
List<String> existingIds = idmDirectoriesDaoService.getDomainIds();
for (DomainResponse.Data data : dataList) {
DomainRecord domainRecord = idmDirectoriesDaoService.getDomainRecord();
Timestamp createdAt = Timestamp.from(Instant.now());
Timestamp modifiedAt = Timestamp.from(Instant.ofEpochMilli(data.getModified()));
domainRecord.setId(data.getId());
domainRecord.setVersion(data.getVersion());
domainRecord.setModified(modifiedAt);
domainRecord.setSchema(data.getSchema());
domainRecord.setName(data.getName());
domainRecord.setShortname(data.getShortname());
domainRecord.setFullname(data.getFullname());
domainRecord.setDns(data.getDns());
domainRecord.setEmail(data.getEmail());
domainRecord.setPhone(data.getPhone());
domainRecord.setAddress(data.getAddress());
domainRecord.setPostalAddress(data.getPostalAddress());
domainRecord.setAddressId(data.getAddressId());
domainRecord.setPostalAddressId(data.getPostalAddressId());
domainRecord.setMilitaryCode(data.getMilitaryCode());
domainRecord.setTimezone(data.getTimezone());
domainRecord.setReportsEnabled(data.isReportsEnabled());
domainRecord.setInn(data.getInn());
domainRecord.setLeg(data.getLeg());
domainRecord.setOgrn(data.getOgrn());
domainRecord.setRegion(data.getRegion());
domainRecord.setEpguId(data.getEpguId());
domainRecord.setType(data.getType());
domainRecord.setEsiaEmployeeAuthorization(data.isEsiaEmployeeAuthorization());
domainRecord.setDefaultS3Bucket(data.getDefaultS3Bucket());
domainRecord.setOpf(data.getOpf());
domainRecord.setKpp(data.getKpp());
domainRecord.setCheckingAccount(data.getCheckingAccount());
domainRecord.setBik(data.getBik());
domainRecord.setBankName(data.getBankName());
domainRecord.setBankCorrespondentAccount(data.getBankCorrespondentAccount());
domainRecord.setOktmo(data.getOktmo());
domainRecord.setOkato(data.getOkato());
domainRecord.setGovRegistrationDate(data.getGovRegistrationDate());
domainRecord.setGovOrganizationType(data.getGovOrganizationType());
domainRecord.setAliasKey(data.getAliasKey());
domainRecord.setPassKey(data.getPassKey());
domainRecord.setCertificate(data.getCertificate());
domainRecord.setAccountNumberTofk(data.getAccountNumberTOFK());
domainRecord.setBikTofk(data.getBikTOFK());
domainRecord.setCorrespondentBankAccountTofk(data.getCorrespondentBankAccountTOFK());
domainRecord.setNameTofk(data.getNameTOFK());
domainRecord.setNsiOrganizationId(data.getNsiOrganizationId());
domainRecord.setDocHandle(data.getDocHandle());
domainRecord.setDivisionType(data.getDivisionType());
domainRecord.setTnsDepartmentId(data.getTnsDepartmentId());
domainRecord.setEnabled(data.isEnabled() != null ? data.isEnabled() : true);
domainRecord.setParent(data.getParent());
domainRecord.setRegionId(data.getRegionId());
domainRecord.setManaged(data.getManaged());
domainRecord.setCreatedAt(createdAt);
if (existingIds.contains(data.getId())) {
recruitmentRecords.add(domainRecord);
} else {
newRecruitmentRecords.add(domainRecord);
}
}
ervuDirectoriesDaoService.insertRecruitmentRecords(newRecruitmentRecords);
ervuDirectoriesDaoService.updateRecruitmentRecords(recruitmentRecords);
}
private void upsertRoleData(List<RoleResponse.Data> dataList) {
String[] adminRoles = ervuAdminRole.split(",");
List<UserApplicationRoleRecord> newRoleRecords = new ArrayList<>();
List<UserApplicationRoleRecord> roleRecords = new ArrayList<>();
List<String> ids = ervuDirectoriesDaoService.getRoleIds();
dataList.forEach(data -> {
if (data.getErvuRole() == null || !data.getErvuRole()) {
return;
}
Timestamp updatedAt = Timestamp.from(Instant.ofEpochSecond(data.getModified()));
Timestamp createdAt = Timestamp.from(Instant.ofEpochSecond(data.getCreateDate()));
Timestamp finishAt = null;
if (data.getFinish() != null) {
finishAt = Timestamp.from(Instant.ofEpochSecond(data.getFinish()));
}
UserApplicationRoleRecord roleRecord = ervuDirectoriesDaoService.getRoleRecord();
roleRecord.setUserRoleId(data.getId());
roleRecord.setRoleCode(data.getName());
roleRecord.setRoleName(data.getDisplayName());
roleRecord.setCreated(createdAt);
roleRecord.setUpdated(updatedAt);
roleRecord.setFinished(finishAt);
Arrays.stream(adminRoles).forEach(role -> {
if (role.trim().equals(data.getName())) {
roleRecord.setAdminRole(true);
UpsertMessage<T>[] messages = objectMapper.readValue(kafkaMessage, arrayType);
if (messages.length > 0 && messages[0].getData() != null && !messages[0].getData()
.isEmpty()) {
DataProcessor<T> processor = (DataProcessor<T>) dataProcessors.get(entityClass);
if (processor == null) {
throw new IllegalStateException("No processor found for " + entityClass.getSimpleName());
}
});
if (ids.contains(data.getId())) {
roleRecords.add(roleRecord);
processor.upsertData(messages[0].getData());
}
else {
newRoleRecords.add(roleRecord);
}
catch (Exception e) {
throw new IdmDirectoriesException(e);
}
}
@Transactional
public <T> void processDeleteMessage(String kafkaMessage, Class<T> entityClass) {
try {
DeleteKafkaMessage[] deleteKafkaMessages = objectMapper.readValue(kafkaMessage,
DeleteKafkaMessage[].class
);
if (Boolean.TRUE.equals(deleteKafkaMessages[0].isSuccess())
&& deleteKafkaMessages[0].getData() != null && !deleteKafkaMessages[0].getData()
.isEmpty()) {
DataProcessor<T> processor = (DataProcessor<T>) dataProcessors.get(entityClass);
if (processor == null) {
throw new IllegalStateException("No processor found for " + entityClass.getSimpleName());
}
processor.deleteData(deleteKafkaMessages[0].getData());
}
});
ervuDirectoriesDaoService.insertRoleRecords(newRoleRecords);
ervuDirectoriesDaoService.updateRoleRecords(roleRecords);
}
catch (Exception e) {
throw new IdmDirectoriesException(e);
}
}
}

View file

@ -0,0 +1,11 @@
package ervu_business_metrics.service.processor;
import java.util.List;
/**
* @author Adel Kalimullin
*/
public interface DataProcessor<T> {
void upsertData(List<T> dataList);
void deleteData(List<String> ids);
}

View file

@ -0,0 +1,93 @@
package ervu_business_metrics.service.processor.impl;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import ervu_business_metrics.config.IdmReconcileEnabledCondition;
import ervu_business_metrics.model.AccountData;
import ervu_business_metrics.service.IdmDirectoriesDaoService;
import ervu_business_metrics.service.processor.DataProcessor;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Component;
import ru.micord.webbpm.ervu.business_metrics.db_beans.idm_reconcile.tables.records.AccountRecord;
import ru.micord.webbpm.ervu.business_metrics.db_beans.idm_reconcile.tables.records.AccountRoleRecord;
/**
* @author Adel Kalimullin
*/
@Component
@Conditional(IdmReconcileEnabledCondition.class)
public class AccountDataProcessor implements DataProcessor<AccountData> {
private final IdmDirectoriesDaoService idmDirectoriesDaoService;
public AccountDataProcessor(IdmDirectoriesDaoService idmDirectoriesDaoService) {
this.idmDirectoriesDaoService = idmDirectoriesDaoService;
}
@Override
public void upsertData(List<AccountData> dataList) {
List<AccountRecord> newAccountRecords = new ArrayList<>();
List<AccountRecord> accountRecordsToUpdate = new ArrayList<>();
List<AccountRoleRecord> newAccountRoleRecords = new ArrayList<>();
List<String> accountsToDeleteRoles = new ArrayList<>();
Set<String> existingIds = idmDirectoriesDaoService.getAccountIds();
for (AccountData data : dataList) {
AccountRecord record = idmDirectoriesDaoService.getAccountRecord();
Timestamp modifiedAt = Timestamp.from(Instant.ofEpochMilli(data.getModified()));
record.setId(data.getId());
record.setVersion(data.getVersion());
record.setSchema(data.getSchema());
record.setModified(modifiedAt);
record.setStart(data.getStart());
record.setFinish(data.getFinish());
record.setEnabled(data.isEnabled());
record.setPosition(data.getPosition());
record.setFio(data.getFio());
record.setWorkMail(data.getWorkMail());
record.setEsiaAccount(data.isEsiaAccount());
record.setDomainId(data.getUserDomain().getId());
if (existingIds.contains(data.getId())) {
accountRecordsToUpdate.add(record);
accountsToDeleteRoles.add(data.getId());
}
else {
newAccountRecords.add(record);
}
if (data.getRoles() != null && !data.getRoles().isEmpty()) {
addRolesForAccount(data, newAccountRoleRecords);
}
}
idmDirectoriesDaoService.insertAccountRecords(newAccountRecords);
idmDirectoriesDaoService.updateAccountRecords(accountRecordsToUpdate);
if (!accountsToDeleteRoles.isEmpty()) {
idmDirectoriesDaoService.deleteAccountRolesByAccountIds(accountsToDeleteRoles);
}
if (!newAccountRoleRecords.isEmpty()) {
idmDirectoriesDaoService.insertAccountRoleRecords(newAccountRoleRecords);
}
}
@Override
public void deleteData(List<String> ids) {
idmDirectoriesDaoService.deleteAccountsByIds(ids);
}
private void addRolesForAccount(AccountData data, List<AccountRoleRecord> accountRoleRecords) {
for (String roleId : data.getRoles()) {
AccountRoleRecord accountRoleRecord = idmDirectoriesDaoService.getAccountRoleRecord();
accountRoleRecord.setAccountId(data.getId());
accountRoleRecord.setRoleId(roleId);
accountRoleRecords.add(accountRoleRecord);
}
}
}

View file

@ -0,0 +1,106 @@
package ervu_business_metrics.service.processor.impl;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import ervu_business_metrics.config.IdmReconcileEnabledCondition;
import ervu_business_metrics.model.DomainData;
import ervu_business_metrics.service.IdmDirectoriesDaoService;
import ervu_business_metrics.service.processor.DataProcessor;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Component;
import ru.micord.webbpm.ervu.business_metrics.db_beans.idm_reconcile.tables.records.DomainRecord;
/**
* @author Adel Kalimullin
*/
@Component
@Conditional(IdmReconcileEnabledCondition.class)
public class DomainDataProcessor implements DataProcessor<DomainData> {
private final IdmDirectoriesDaoService idmDirectoriesDaoService;
public DomainDataProcessor(IdmDirectoriesDaoService idmDirectoriesDaoService) {
this.idmDirectoriesDaoService = idmDirectoriesDaoService;
}
@Override
public void upsertData(List<DomainData> dataList) {
List<DomainRecord> newRecruitmentRecords = new ArrayList<>();
List<DomainRecord> recruitmentRecords = new ArrayList<>();
Set<String> existingIds = idmDirectoriesDaoService.getDomainIds();
for (DomainData data : dataList) {
DomainRecord domainRecord = idmDirectoriesDaoService.getDomainRecord();
Timestamp modifiedAt = Timestamp.from(Instant.ofEpochMilli(data.getModified()));
domainRecord.setId(data.getId());
domainRecord.setVersion(data.getVersion());
domainRecord.setModified(modifiedAt);
domainRecord.setSchema(data.getSchema());
domainRecord.setName(data.getName());
domainRecord.setShortname(data.getShortname());
domainRecord.setFullname(data.getFullname());
domainRecord.setDns(data.getDns());
domainRecord.setEmail(data.getEmail());
domainRecord.setPhone(data.getPhone());
domainRecord.setAddress(data.getAddress());
domainRecord.setPostalAddress(data.getPostalAddress());
domainRecord.setAddressId(data.getAddressId());
domainRecord.setPostalAddressId(data.getPostalAddressId());
domainRecord.setMilitaryCode(data.getMilitaryCode());
domainRecord.setTimezone(data.getTimezone());
domainRecord.setReportsEnabled(data.isReportsEnabled());
domainRecord.setInn(data.getInn());
domainRecord.setLeg(data.getLeg());
domainRecord.setOgrn(data.getOgrn());
domainRecord.setRegion(data.getRegion());
domainRecord.setEpguId(data.getEpguId());
domainRecord.setType(data.getType());
domainRecord.setEsiaEmployeeAuthorization(data.isEsiaEmployeeAuthorization());
domainRecord.setDefaultS3Bucket(data.getDefaultS3Bucket());
domainRecord.setOpf(data.getOpf());
domainRecord.setKpp(data.getKpp());
domainRecord.setCheckingAccount(data.getCheckingAccount());
domainRecord.setBik(data.getBik());
domainRecord.setBankName(data.getBankName());
domainRecord.setBankCorrespondentAccount(data.getBankCorrespondentAccount());
domainRecord.setOktmo(data.getOktmo());
domainRecord.setOkato(data.getOkato());
domainRecord.setGovRegistrationDate(data.getGovRegistrationDate());
domainRecord.setGovOrganizationType(data.getGovOrganizationType());
domainRecord.setAliasKey(data.getAliasKey());
domainRecord.setPassKey(data.getPassKey());
domainRecord.setCertificate(data.getCertificate());
domainRecord.setAccountNumberTofk(data.getAccountNumberTOFK());
domainRecord.setBikTofk(data.getBikTOFK());
domainRecord.setCorrespondentBankAccountTofk(data.getCorrespondentBankAccountTOFK());
domainRecord.setNameTofk(data.getNameTOFK());
domainRecord.setNsiOrganizationId(data.getNsiOrganizationId());
domainRecord.setDocHandle(data.getDocHandle());
domainRecord.setDivisionType(data.getDivisionType());
domainRecord.setTnsDepartmentId(data.getTnsDepartmentId());
domainRecord.setEnabled(data.isEnabled());
domainRecord.setParent(data.getParent());
domainRecord.setRegionId(data.getRegionId());
domainRecord.setManaged(data.getManaged());
if (existingIds.contains(data.getId())) {
recruitmentRecords.add(domainRecord);
}
else {
newRecruitmentRecords.add(domainRecord);
}
}
idmDirectoriesDaoService.insertDomainRecords(newRecruitmentRecords);
idmDirectoriesDaoService.updateDomainRecords(recruitmentRecords);
}
@Override
public void deleteData(List<String> ids) {
idmDirectoriesDaoService.deleteDomainsByIds(ids);
}
}

View file

@ -0,0 +1,70 @@
package ervu_business_metrics.service.processor.impl;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import ervu_business_metrics.config.IdmReconcileEnabledCondition;
import ervu_business_metrics.model.RoleData;
import ervu_business_metrics.service.IdmDirectoriesDaoService;
import ervu_business_metrics.service.processor.DataProcessor;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Component;
import ru.micord.webbpm.ervu.business_metrics.db_beans.idm_reconcile.tables.records.RoleRecord;
/**
* @author Adel Kalimullin
*/
@Component
@Conditional(IdmReconcileEnabledCondition.class)
public class RoleDataProcessor implements DataProcessor<RoleData> {
private final IdmDirectoriesDaoService idmDirectoriesDaoService;
public RoleDataProcessor(IdmDirectoriesDaoService idmDirectoriesDaoService) {
this.idmDirectoriesDaoService = idmDirectoriesDaoService;
}
@Override
public void upsertData(List<RoleData> dataList) {
List<RoleRecord> newRoleRecords = new ArrayList<>();
List<RoleRecord> roleRecords = new ArrayList<>();
Set<String> existingIds = idmDirectoriesDaoService.getRoleIds();
for (RoleData data : dataList) {
if (!data.isErvuRole()) {
continue;
}
RoleRecord record = idmDirectoriesDaoService.getRoleRecord();
Timestamp modifiedAt = Timestamp.from(Instant.ofEpochMilli(data.getModified()));
record.setId(data.getId());
record.setName(data.getName());
record.setDisplayName(data.getDisplayName());
record.setShortname(data.getShortname());
record.setSchema(data.getSchema());
record.setVersion(data.getVersion());
record.setSessionsLimit(data.getSessionsLimit());
record.setImported(data.getImported());
record.setDescription(data.getDescription());
record.setErvuRole(data.isErvuRole());
record.setModified(modifiedAt);
if (existingIds.contains(data.getId())) {
roleRecords.add(record);
}
else {
newRoleRecords.add(record);
}
}
idmDirectoriesDaoService.insertRoleRecords(newRoleRecords);
idmDirectoriesDaoService.updateRoleRecords(roleRecords);
}
@Override
public void deleteData(List<String> ids) {
// TODO удаление пока не реализовано
}
}

View file

@ -0,0 +1,18 @@
package exception;
/**
* @author Adel Kalimullin
*/
public class IdmDirectoriesException extends RuntimeException{
public IdmDirectoriesException(String message) {
super(message);
}
public IdmDirectoriesException(Throwable cause) {
super(cause);
}
public IdmDirectoriesException(String message, Throwable cause) {
super(message, cause);
}
}

View file

@ -94,43 +94,7 @@
</sql>
</changeSet>
<changeSet id="0004" author="a.kalimullin">
<comment>create table person and person_ip_address</comment>
<sql>
CREATE TABLE IF NOT EXISTS idm_reconcile.person (
id varchar(36) PRIMARY KEY,
version int NOT NULL,
modified timestamp without time zone,
schema varchar(100) NOT NULL,
birthdate DATE,
firstname varchar(255),
middlename varchar(255),
surname varchar(255),
sex varchar(10),
email varchar(255),
photo TEXT,
phone varchar(50),
snils varchar(20),
second_factor_enabled boolean NOT NULL DEFAULT FALSE,
fio varchar(255)
);
ALTER TABLE idm_reconcile.person OWNER TO ervu_business_metrics;
CREATE TABLE IF NOT EXISTS idm_reconcile.person_ip_address (
person_id varchar(36) NOT NULL,
ip_address varchar(45) NOT NULL,
CONSTRAINT pk_person_ip PRIMARY KEY (person_id, ip_address),
CONSTRAINT fk_person_ip_person FOREIGN KEY (person_id)
REFERENCES idm_reconcile.person (id)
ON DELETE CASCADE
);
ALTER TABLE idm_reconcile.person_ip_address OWNER TO ervu_business_metrics;
</sql>
</changeSet>
<changeSet id="0005" author="a.kalimulin">
<changeSet id="0004" author="a.kalimulin">
<comment>create table account and account_role</comment>
<sql>
CREATE TABLE IF NOT EXISTS idm_reconcile.account (
@ -146,14 +110,9 @@
work_mail varchar(255),
esia_account boolean NOT NULL DEFAULT FALSE,
domain_id varchar(36),
person_id varchar(36),
CONSTRAINT fk_domain FOREIGN KEY (domain_id)
REFERENCES idm_reconcile.domain (id)
ON DELETE SET NULL,
CONSTRAINT fk_person FOREIGN KEY (person_id)
REFERENCES idm_reconcile.person (id)
ON DELETE SET NULL
);