committed by
GitHub
30 changed files with 673 additions and 263 deletions
@ -0,0 +1,36 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2024 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.controller; |
||||
|
|
||||
|
import lombok.Getter; |
||||
|
import org.springframework.boot.test.mock.mockito.SpyBean; |
||||
|
import org.springframework.test.context.TestPropertySource; |
||||
|
import org.thingsboard.server.dao.service.DaoSqlTest; |
||||
|
import org.thingsboard.server.dao.sqlts.insert.sql.DedicatedEventsSqlPartitioningRepository; |
||||
|
|
||||
|
@DaoSqlTest |
||||
|
@TestPropertySource(properties = { |
||||
|
"spring.datasource.events.enabled=true", |
||||
|
"spring.datasource.events.url=${spring.datasource.url}", |
||||
|
"spring.datasource.events.driverClassName=${spring.datasource.driverClassName}", |
||||
|
}) |
||||
|
public class AuditLogControllerTest_DedicatedEventsDataSource extends AuditLogControllerTest { |
||||
|
|
||||
|
@Getter |
||||
|
@SpyBean |
||||
|
private DedicatedEventsSqlPartitioningRepository partitioningRepository; |
||||
|
|
||||
|
} |
||||
@ -1,37 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2024 The Thingsboard Authors |
|
||||
* |
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
* you may not use this file except in compliance with the License. |
|
||||
* You may obtain a copy of the License at |
|
||||
* |
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||
* |
|
||||
* Unless required by applicable law or agreed to in writing, software |
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
* See the License for the specific language governing permissions and |
|
||||
* limitations under the License. |
|
||||
*/ |
|
||||
package org.thingsboard.server.dao; |
|
||||
|
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan; |
|
||||
import org.springframework.context.annotation.ComponentScan; |
|
||||
import org.springframework.context.annotation.Configuration; |
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories; |
|
||||
import org.springframework.data.repository.config.BootstrapMode; |
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement; |
|
||||
import org.thingsboard.server.dao.util.TbAutoConfiguration; |
|
||||
|
|
||||
/** |
|
||||
* @author Valerii Sosliuk |
|
||||
*/ |
|
||||
@Configuration |
|
||||
@TbAutoConfiguration |
|
||||
@ComponentScan({"org.thingsboard.server.dao.sql", "org.thingsboard.server.dao.attributes", "org.thingsboard.server.dao.cache", "org.thingsboard.server.cache"}) |
|
||||
@EnableJpaRepositories(value = "org.thingsboard.server.dao.sql", bootstrapMode = BootstrapMode.LAZY) |
|
||||
@EntityScan("org.thingsboard.server.dao.model.sql") |
|
||||
@EnableTransactionManagement |
|
||||
public class JpaDaoConfig { |
|
||||
|
|
||||
} |
|
||||
@ -0,0 +1,91 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2024 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.dao.config; |
||||
|
|
||||
|
import com.zaxxer.hikari.HikariDataSource; |
||||
|
import org.springframework.beans.factory.annotation.Qualifier; |
||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; |
||||
|
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
|
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; |
||||
|
import org.springframework.context.annotation.Bean; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories; |
||||
|
import org.springframework.data.repository.config.BootstrapMode; |
||||
|
import org.springframework.jdbc.core.JdbcTemplate; |
||||
|
import org.springframework.orm.jpa.JpaTransactionManager; |
||||
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; |
||||
|
import org.springframework.transaction.support.TransactionTemplate; |
||||
|
import org.thingsboard.server.dao.model.sql.AuditLogEntity; |
||||
|
import org.thingsboard.server.dao.model.sql.ErrorEventEntity; |
||||
|
import org.thingsboard.server.dao.model.sql.LifecycleEventEntity; |
||||
|
import org.thingsboard.server.dao.model.sql.RuleChainDebugEventEntity; |
||||
|
import org.thingsboard.server.dao.model.sql.RuleNodeDebugEventEntity; |
||||
|
import org.thingsboard.server.dao.model.sql.StatisticsEventEntity; |
||||
|
|
||||
|
import javax.sql.DataSource; |
||||
|
import java.util.Objects; |
||||
|
|
||||
|
@DedicatedEventsDataSource |
||||
|
@Configuration |
||||
|
@EnableJpaRepositories(value = {"org.thingsboard.server.dao.sql.event", "org.thingsboard.server.dao.sql.audit"}, |
||||
|
bootstrapMode = BootstrapMode.LAZY, |
||||
|
entityManagerFactoryRef = "eventsEntityManagerFactory", transactionManagerRef = "eventsTransactionManager") |
||||
|
public class DedicatedEventsJpaDaoConfig { |
||||
|
|
||||
|
public static final String EVENTS_PERSISTENCE_UNIT = "events"; |
||||
|
public static final String EVENTS_DATA_SOURCE = EVENTS_PERSISTENCE_UNIT + "DataSource"; |
||||
|
public static final String EVENTS_TRANSACTION_MANAGER = EVENTS_PERSISTENCE_UNIT + "TransactionManager"; |
||||
|
public static final String EVENTS_TRANSACTION_TEMPLATE = EVENTS_PERSISTENCE_UNIT + "TransactionTemplate"; |
||||
|
public static final String EVENTS_JDBC_TEMPLATE = EVENTS_PERSISTENCE_UNIT + "JdbcTemplate"; |
||||
|
|
||||
|
@Bean |
||||
|
@ConfigurationProperties("spring.datasource.events") |
||||
|
public DataSourceProperties eventsDataSourceProperties() { |
||||
|
return new DataSourceProperties(); |
||||
|
} |
||||
|
|
||||
|
@ConfigurationProperties(prefix = "spring.datasource.events.hikari") |
||||
|
@Bean(EVENTS_DATA_SOURCE) |
||||
|
public DataSource eventsDataSource(@Qualifier("eventsDataSourceProperties") DataSourceProperties eventsDataSourceProperties) { |
||||
|
return eventsDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build(); |
||||
|
} |
||||
|
|
||||
|
@Bean |
||||
|
public LocalContainerEntityManagerFactoryBean eventsEntityManagerFactory(@Qualifier(EVENTS_DATA_SOURCE) DataSource eventsDataSource, |
||||
|
EntityManagerFactoryBuilder builder) { |
||||
|
return builder |
||||
|
.dataSource(eventsDataSource) |
||||
|
.packages(LifecycleEventEntity.class, StatisticsEventEntity.class, ErrorEventEntity.class, RuleNodeDebugEventEntity.class, RuleChainDebugEventEntity.class, AuditLogEntity.class) |
||||
|
.persistenceUnit(EVENTS_PERSISTENCE_UNIT) |
||||
|
.build(); |
||||
|
} |
||||
|
|
||||
|
@Bean(EVENTS_TRANSACTION_MANAGER) |
||||
|
public JpaTransactionManager eventsTransactionManager(@Qualifier("eventsEntityManagerFactory") LocalContainerEntityManagerFactoryBean eventsEntityManagerFactory) { |
||||
|
return new JpaTransactionManager(Objects.requireNonNull(eventsEntityManagerFactory.getObject())); |
||||
|
} |
||||
|
|
||||
|
@Bean(EVENTS_TRANSACTION_TEMPLATE) |
||||
|
public TransactionTemplate eventsTransactionTemplate(@Qualifier(EVENTS_TRANSACTION_MANAGER) JpaTransactionManager eventsTransactionManager) { |
||||
|
return new TransactionTemplate(eventsTransactionManager); |
||||
|
} |
||||
|
|
||||
|
@Bean(EVENTS_JDBC_TEMPLATE) |
||||
|
public JdbcTemplate eventsJdbcTemplate(@Qualifier(EVENTS_DATA_SOURCE) DataSource eventsDataSource) { |
||||
|
return new JdbcTemplate(eventsDataSource); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2024 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.dao.config; |
||||
|
|
||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
||||
|
|
||||
|
import java.lang.annotation.Retention; |
||||
|
import java.lang.annotation.RetentionPolicy; |
||||
|
|
||||
|
@Retention(RetentionPolicy.RUNTIME) |
||||
|
@ConditionalOnProperty(value = "spring.datasource.events.enabled", havingValue = "false", matchIfMissing = true) |
||||
|
public @interface DefaultDataSource { |
||||
|
} |
||||
@ -0,0 +1,121 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2024 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.dao.config; |
||||
|
|
||||
|
import com.zaxxer.hikari.HikariDataSource; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.beans.factory.annotation.Qualifier; |
||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; |
||||
|
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
|
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; |
||||
|
import org.springframework.context.annotation.Bean; |
||||
|
import org.springframework.context.annotation.ComponentScan; |
||||
|
import org.springframework.context.annotation.ComponentScan.Filter; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
import org.springframework.context.annotation.FilterType; |
||||
|
import org.springframework.context.annotation.Primary; |
||||
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories; |
||||
|
import org.springframework.data.repository.config.BootstrapMode; |
||||
|
import org.springframework.jdbc.core.JdbcTemplate; |
||||
|
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; |
||||
|
import org.springframework.orm.jpa.JpaTransactionManager; |
||||
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; |
||||
|
import org.springframework.transaction.support.TransactionTemplate; |
||||
|
import org.thingsboard.server.dao.sql.audit.AuditLogRepository; |
||||
|
import org.thingsboard.server.dao.sql.event.EventRepository; |
||||
|
import org.thingsboard.server.dao.util.TbAutoConfiguration; |
||||
|
|
||||
|
import javax.sql.DataSource; |
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
import java.util.Objects; |
||||
|
|
||||
|
@Configuration |
||||
|
@TbAutoConfiguration |
||||
|
@ComponentScan({"org.thingsboard.server.dao.sql", "org.thingsboard.server.dao.attributes", "org.thingsboard.server.dao.sqlts.dictionary", "org.thingsboard.server.dao.cache", "org.thingsboard.server.cache"}) |
||||
|
@EnableJpaRepositories(value = {"org.thingsboard.server.dao.sql", "org.thingsboard.server.dao.sqlts.dictionary"}, |
||||
|
excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {EventRepository.class, AuditLogRepository.class}), |
||||
|
bootstrapMode = BootstrapMode.LAZY) |
||||
|
public class JpaDaoConfig { |
||||
|
|
||||
|
@Bean |
||||
|
@ConfigurationProperties("spring.datasource") |
||||
|
public DataSourceProperties dataSourceProperties() { |
||||
|
return new DataSourceProperties(); |
||||
|
} |
||||
|
|
||||
|
@Primary |
||||
|
@ConfigurationProperties(prefix = "spring.datasource.hikari") |
||||
|
@Bean |
||||
|
public DataSource dataSource(@Qualifier("dataSourceProperties") DataSourceProperties dataSourceProperties) { |
||||
|
return dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build(); |
||||
|
} |
||||
|
|
||||
|
@Primary |
||||
|
@Bean |
||||
|
public LocalContainerEntityManagerFactoryBean entityManagerFactory(@Qualifier("dataSource") DataSource dataSource, |
||||
|
EntityManagerFactoryBuilder builder, |
||||
|
@Autowired(required = false) SqlTsLatestDaoConfig tsLatestDaoConfig, |
||||
|
@Autowired(required = false) SqlTsDaoConfig tsDaoConfig, |
||||
|
@Autowired(required = false) TimescaleDaoConfig timescaleDaoConfig, |
||||
|
@Autowired(required = false) TimescaleTsLatestDaoConfig timescaleTsLatestDaoConfig) { |
||||
|
List<String> packages = new ArrayList<>(); |
||||
|
packages.add("org.thingsboard.server.dao.model.sql"); |
||||
|
packages.add("org.thingsboard.server.dao.model.sqlts.dictionary"); |
||||
|
if (tsLatestDaoConfig != null) { |
||||
|
packages.add("org.thingsboard.server.dao.model.sqlts.latest"); |
||||
|
} |
||||
|
if (tsDaoConfig != null) { |
||||
|
packages.add("org.thingsboard.server.dao.model.sqlts.ts"); |
||||
|
} |
||||
|
if (timescaleDaoConfig != null) { |
||||
|
packages.add("org.thingsboard.server.dao.model.sqlts.timescale"); |
||||
|
} |
||||
|
if (timescaleTsLatestDaoConfig != null) { |
||||
|
packages.add("org.thingsboard.server.dao.model.sqlts.latest"); |
||||
|
} |
||||
|
return builder |
||||
|
.dataSource(dataSource) |
||||
|
.packages(packages.toArray(String[]::new)) |
||||
|
.persistenceUnit("default") |
||||
|
.build(); |
||||
|
} |
||||
|
|
||||
|
@Primary |
||||
|
@Bean |
||||
|
public JpaTransactionManager transactionManager(@Qualifier("entityManagerFactory") LocalContainerEntityManagerFactoryBean entityManagerFactory) { |
||||
|
return new JpaTransactionManager(Objects.requireNonNull(entityManagerFactory.getObject())); |
||||
|
} |
||||
|
|
||||
|
@Primary |
||||
|
@Bean |
||||
|
public TransactionTemplate transactionTemplate(@Qualifier("transactionManager") JpaTransactionManager transactionManager) { |
||||
|
return new TransactionTemplate(transactionManager); |
||||
|
} |
||||
|
|
||||
|
@Primary |
||||
|
@Bean |
||||
|
public JdbcTemplate jdbcTemplate(@Qualifier("dataSource") DataSource dataSource) { |
||||
|
return new JdbcTemplate(dataSource); |
||||
|
} |
||||
|
|
||||
|
@Primary |
||||
|
@Bean |
||||
|
public NamedParameterJdbcTemplate namedParameterJdbcTemplate(@Qualifier("dataSource") DataSource dataSource) { |
||||
|
return new NamedParameterJdbcTemplate(dataSource); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,87 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2024 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.dao.sql.audit; |
||||
|
|
||||
|
import jakarta.persistence.EntityManager; |
||||
|
import jakarta.persistence.PersistenceContext; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.beans.factory.annotation.Qualifier; |
||||
|
import org.springframework.jdbc.core.JdbcTemplate; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.springframework.transaction.annotation.Transactional; |
||||
|
import org.thingsboard.server.common.data.audit.AuditLog; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.dao.config.DedicatedEventsDataSource; |
||||
|
import org.thingsboard.server.dao.sqlts.insert.sql.DedicatedEventsSqlPartitioningRepository; |
||||
|
import org.thingsboard.server.dao.util.SqlDao; |
||||
|
|
||||
|
import java.util.Collection; |
||||
|
import java.util.UUID; |
||||
|
|
||||
|
import static org.thingsboard.server.dao.config.DedicatedEventsJpaDaoConfig.EVENTS_JDBC_TEMPLATE; |
||||
|
import static org.thingsboard.server.dao.config.DedicatedEventsJpaDaoConfig.EVENTS_PERSISTENCE_UNIT; |
||||
|
import static org.thingsboard.server.dao.config.DedicatedEventsJpaDaoConfig.EVENTS_TRANSACTION_MANAGER; |
||||
|
|
||||
|
@DedicatedEventsDataSource |
||||
|
@Component |
||||
|
@SqlDao |
||||
|
public class DedicatedJpaAuditLogDao extends JpaAuditLogDao { |
||||
|
|
||||
|
@Autowired |
||||
|
@Qualifier(EVENTS_JDBC_TEMPLATE) |
||||
|
private JdbcTemplate jdbcTemplate; |
||||
|
@PersistenceContext(unitName = EVENTS_PERSISTENCE_UNIT) |
||||
|
private EntityManager entityManager; |
||||
|
|
||||
|
public DedicatedJpaAuditLogDao(AuditLogRepository auditLogRepository, DedicatedEventsSqlPartitioningRepository partitioningRepository) { |
||||
|
super(auditLogRepository, partitioningRepository); |
||||
|
} |
||||
|
|
||||
|
@Transactional(transactionManager = EVENTS_TRANSACTION_MANAGER) |
||||
|
@Override |
||||
|
public AuditLog save(TenantId tenantId, AuditLog domain) { |
||||
|
return super.save(tenantId, domain); |
||||
|
} |
||||
|
|
||||
|
@Transactional(transactionManager = EVENTS_TRANSACTION_MANAGER) |
||||
|
@Override |
||||
|
public AuditLog saveAndFlush(TenantId tenantId, AuditLog domain) { |
||||
|
return super.saveAndFlush(tenantId, domain); |
||||
|
} |
||||
|
|
||||
|
@Transactional(transactionManager = EVENTS_TRANSACTION_MANAGER) |
||||
|
@Override |
||||
|
public void removeById(TenantId tenantId, UUID id) { |
||||
|
super.removeById(tenantId, id); |
||||
|
} |
||||
|
|
||||
|
@Transactional(transactionManager = EVENTS_TRANSACTION_MANAGER) |
||||
|
@Override |
||||
|
public void removeAllByIds(Collection<UUID> ids) { |
||||
|
super.removeAllByIds(ids); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected EntityManager getEntityManager() { |
||||
|
return entityManager; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected JdbcTemplate getJdbcTemplate() { |
||||
|
return jdbcTemplate; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,36 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2024 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.dao.sql.event; |
||||
|
|
||||
|
import org.springframework.beans.factory.annotation.Qualifier; |
||||
|
import org.springframework.jdbc.core.JdbcTemplate; |
||||
|
import org.springframework.stereotype.Repository; |
||||
|
import org.springframework.transaction.support.TransactionTemplate; |
||||
|
import org.thingsboard.server.dao.config.DedicatedEventsDataSource; |
||||
|
|
||||
|
import static org.thingsboard.server.dao.config.DedicatedEventsJpaDaoConfig.EVENTS_JDBC_TEMPLATE; |
||||
|
import static org.thingsboard.server.dao.config.DedicatedEventsJpaDaoConfig.EVENTS_TRANSACTION_TEMPLATE; |
||||
|
|
||||
|
@DedicatedEventsDataSource |
||||
|
@Repository |
||||
|
public class DedicatedEventInsertRepository extends EventInsertRepository { |
||||
|
|
||||
|
public DedicatedEventInsertRepository(@Qualifier(EVENTS_JDBC_TEMPLATE) JdbcTemplate jdbcTemplate, |
||||
|
@Qualifier(EVENTS_TRANSACTION_TEMPLATE) TransactionTemplate transactionTemplate) { |
||||
|
super(jdbcTemplate, transactionTemplate); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,45 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2024 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.dao.sql.event; |
||||
|
|
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.thingsboard.server.common.stats.StatsFactory; |
||||
|
import org.thingsboard.server.dao.config.DedicatedEventsDataSource; |
||||
|
import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent; |
||||
|
import org.thingsboard.server.dao.sqlts.insert.sql.DedicatedEventsSqlPartitioningRepository; |
||||
|
import org.thingsboard.server.dao.util.SqlDao; |
||||
|
|
||||
|
@DedicatedEventsDataSource |
||||
|
@Component |
||||
|
@SqlDao |
||||
|
public class DedicatedJpaEventDao extends JpaBaseEventDao { |
||||
|
|
||||
|
public DedicatedJpaEventDao(EventPartitionConfiguration partitionConfiguration, |
||||
|
DedicatedEventsSqlPartitioningRepository partitioningRepository, |
||||
|
LifecycleEventRepository lcEventRepository, |
||||
|
StatisticsEventRepository statsEventRepository, |
||||
|
ErrorEventRepository errorEventRepository, |
||||
|
DedicatedEventInsertRepository eventInsertRepository, |
||||
|
RuleNodeDebugEventRepository ruleNodeDebugEventRepository, |
||||
|
RuleChainDebugEventRepository ruleChainDebugEventRepository, |
||||
|
ScheduledLogExecutorComponent logExecutor, |
||||
|
StatsFactory statsFactory) { |
||||
|
super(partitionConfiguration, partitioningRepository, lcEventRepository, statsEventRepository, |
||||
|
errorEventRepository, eventInsertRepository, ruleNodeDebugEventRepository, |
||||
|
ruleChainDebugEventRepository, logExecutor, statsFactory); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -1,101 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2024 The Thingsboard Authors |
|
||||
* |
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
* you may not use this file except in compliance with the License. |
|
||||
* You may obtain a copy of the License at |
|
||||
* |
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||
* |
|
||||
* Unless required by applicable law or agreed to in writing, software |
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
* See the License for the specific language governing permissions and |
|
||||
* limitations under the License. |
|
||||
*/ |
|
||||
package org.thingsboard.server.dao.sql.event; |
|
||||
|
|
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
|
||||
import org.springframework.dao.DataAccessException; |
|
||||
import org.springframework.stereotype.Repository; |
|
||||
import org.thingsboard.server.common.data.event.EventType; |
|
||||
import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService; |
|
||||
import org.thingsboard.server.dao.sqlts.insert.sql.SqlPartitioningRepository; |
|
||||
|
|
||||
import java.util.concurrent.TimeUnit; |
|
||||
|
|
||||
|
|
||||
@Slf4j |
|
||||
@Repository |
|
||||
public class SqlEventCleanupRepository extends JpaAbstractDaoListeningExecutorService implements EventCleanupRepository { |
|
||||
|
|
||||
@Autowired |
|
||||
private EventPartitionConfiguration partitionConfiguration; |
|
||||
@Autowired |
|
||||
private SqlPartitioningRepository partitioningRepository; |
|
||||
|
|
||||
@Override |
|
||||
public void cleanupEvents(long eventExpTime, boolean debug) { |
|
||||
for (EventType eventType : EventType.values()) { |
|
||||
if (eventType.isDebug() == debug) { |
|
||||
cleanupEvents(eventType, eventExpTime); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void migrateEvents(long regularEventTs, long debugEventTs) { |
|
||||
regularEventTs = Math.max(regularEventTs, 1480982400000L); |
|
||||
debugEventTs = Math.max(debugEventTs, 1480982400000L); |
|
||||
|
|
||||
callMigrateFunctionByPartitions("regular", "migrate_regular_events", regularEventTs, partitionConfiguration.getRegularPartitionSizeInHours()); |
|
||||
callMigrateFunctionByPartitions("debug", "migrate_debug_events", debugEventTs, partitionConfiguration.getDebugPartitionSizeInHours()); |
|
||||
|
|
||||
try { |
|
||||
jdbcTemplate.execute("DROP PROCEDURE IF EXISTS migrate_regular_events(bigint, bigint, int)"); |
|
||||
jdbcTemplate.execute("DROP PROCEDURE IF EXISTS migrate_debug_events(bigint, bigint, int)"); |
|
||||
jdbcTemplate.execute("DROP TABLE IF EXISTS event"); |
|
||||
} catch (DataAccessException e) { |
|
||||
log.error("Error occurred during drop of the `events` table", e); |
|
||||
throw e; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private void callMigrateFunctionByPartitions(String logTag, String functionName, long startTs, int partitionSizeInHours) { |
|
||||
long currentTs = System.currentTimeMillis(); |
|
||||
var regularPartitionStepInMs = TimeUnit.HOURS.toMillis(partitionSizeInHours); |
|
||||
long numberOfPartitions = (currentTs - startTs) / regularPartitionStepInMs; |
|
||||
if (numberOfPartitions > 1000) { |
|
||||
log.error("Please adjust your {} events partitioning configuration. " + |
|
||||
"Configuration with partition size of {} hours and corresponding TTL will use {} (>1000) partitions which is not recommended!", |
|
||||
logTag, partitionSizeInHours, numberOfPartitions); |
|
||||
throw new RuntimeException("Please adjust your " + logTag + " events partitioning configuration. " + |
|
||||
"Configuration with partition size of " + partitionSizeInHours + " hours and corresponding TTL will use " + |
|
||||
+numberOfPartitions + " (>1000) partitions which is not recommended!"); |
|
||||
} |
|
||||
while (startTs < currentTs) { |
|
||||
var endTs = startTs + regularPartitionStepInMs; |
|
||||
log.info("Migrate {} events for time period: [{},{}]", logTag, startTs, endTs); |
|
||||
callMigrateFunction(functionName, startTs, startTs + regularPartitionStepInMs, partitionSizeInHours); |
|
||||
startTs = endTs; |
|
||||
} |
|
||||
log.info("Migrate {} events done.", logTag); |
|
||||
} |
|
||||
|
|
||||
private void callMigrateFunction(String functionName, long startTs, long endTs, int partitionSizeInHours) { |
|
||||
try { |
|
||||
jdbcTemplate.update("CALL " + functionName + "(?, ?, ?)", startTs, endTs, partitionSizeInHours); |
|
||||
} catch (DataAccessException e) { |
|
||||
if (e.getMessage() == null || !e.getMessage().contains("relation \"event\" does not exist")) { |
|
||||
log.error("[{}] SQLException occurred during execution of {} with parameters {} and {}", functionName, startTs, partitionSizeInHours, e); |
|
||||
throw new RuntimeException(e); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private void cleanupEvents(EventType eventType, long eventExpTime) { |
|
||||
partitioningRepository.dropPartitionsBefore(eventType.getTable(), eventExpTime, partitionConfiguration.getPartitionSizeInMs(eventType)); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -0,0 +1,55 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2024 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.dao.sqlts.insert.sql; |
||||
|
|
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.beans.factory.annotation.Qualifier; |
||||
|
import org.springframework.jdbc.core.JdbcTemplate; |
||||
|
import org.springframework.stereotype.Repository; |
||||
|
import org.springframework.transaction.annotation.Propagation; |
||||
|
import org.springframework.transaction.annotation.Transactional; |
||||
|
import org.thingsboard.server.dao.config.DedicatedEventsDataSource; |
||||
|
import org.thingsboard.server.dao.timeseries.SqlPartition; |
||||
|
|
||||
|
import static org.thingsboard.server.dao.config.DedicatedEventsJpaDaoConfig.EVENTS_JDBC_TEMPLATE; |
||||
|
import static org.thingsboard.server.dao.config.DedicatedEventsJpaDaoConfig.EVENTS_TRANSACTION_MANAGER; |
||||
|
|
||||
|
@DedicatedEventsDataSource |
||||
|
@Repository |
||||
|
public class DedicatedEventsSqlPartitioningRepository extends SqlPartitioningRepository { |
||||
|
|
||||
|
@Autowired |
||||
|
@Qualifier(EVENTS_JDBC_TEMPLATE) |
||||
|
private JdbcTemplate jdbcTemplate; |
||||
|
|
||||
|
@Transactional(propagation = Propagation.NOT_SUPPORTED, transactionManager = EVENTS_TRANSACTION_MANAGER) |
||||
|
@Override |
||||
|
public void save(SqlPartition partition) { |
||||
|
super.save(partition); |
||||
|
} |
||||
|
|
||||
|
@Transactional(propagation = Propagation.NOT_SUPPORTED, transactionManager = EVENTS_TRANSACTION_MANAGER) |
||||
|
@Override |
||||
|
public void createPartitionIfNotExists(String table, long entityTs, long partitionDurationMs) { |
||||
|
super.createPartitionIfNotExists(table, entityTs, partitionDurationMs); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected JdbcTemplate getJdbcTemplate() { |
||||
|
return jdbcTemplate; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,28 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2024 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.dao.service.event.sql; |
||||
|
|
||||
|
import org.springframework.test.context.TestPropertySource; |
||||
|
import org.thingsboard.server.dao.service.DaoSqlTest; |
||||
|
|
||||
|
@DaoSqlTest |
||||
|
@TestPropertySource(properties = { |
||||
|
"spring.datasource.events.enabled=true", |
||||
|
"spring.datasource.events.url=${spring.datasource.url}", |
||||
|
"spring.datasource.events.driverClassName=${spring.datasource.driverClassName}" |
||||
|
}) |
||||
|
public class EventServiceSqlTest_DedicatedEventsDataSource extends EventServiceSqlTest { |
||||
|
} |
||||
Loading…
Reference in new issue