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