Skip to content

Instantly share code, notes, and snippets.

@pavelfomin
pavelfomin / JWT-audience-validator.md
Last active November 13, 2025 22:45
Spring Boot JWT Audience Validator

A Mathematical Explanation for Why Knowledge Transfer Is Difficult

If we accept the classic equation knowledge = power, then by substitution, knowledge transfer becomes power transfer. In disciplines like physics, engineering, and especially politics, transferring power is rarely simple — it often involves resistance, inefficiency, and loss.

@pavelfomin
pavelfomin / KafkaConfig.java
Last active July 25, 2025 16:19
Create Kafka topic in a Spring Boot application
@Configuration
public class KafkaConfig {
@Bean
public NewTopic fooTopic(@Value("${app.topics.fooTopic}") String topic) {
return TopicBuilder.name(topic)
.partitions(8)
.build();
}
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import org.javers.core.ChangesByCommit;
import org.javers.core.diff.Change;
import org.javers.core.json.BasicStringTypeAdapter;
import org.javers.core.json.typeadapter.util.UtilTypeCoreAdapters;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
@pavelfomin
pavelfomin / AsyncTaskExecutorConfiguration.java
Created May 16, 2025 15:17
DelegatingSecurityContextAsyncTaskExecutor bootstrap that requires custom taskExecutor for some reason
import org.springframework.boot.task.ThreadPoolTaskExecutorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.security.task.DelegatingSecurityContextAsyncTaskExecutor;
@Configuration
public class AsyncTaskExecutorConfiguration {
/**
@pavelfomin
pavelfomin / AvroConsumer.java
Last active February 27, 2025 22:43
Use Multiple Avro Schemas in the same Kafka topic
import com.droidablebee.avro.BlueEvent;
import com.droidablebee.avro.GreenEvent;
import org.apache.avro.specific.SpecificRecord;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.messaging.MessageHeaders;
import org.springframework.stereotype.Service;
@pavelfomin
pavelfomin / _flyway-pgsql-auto-vaccum.md
Last active February 19, 2025 19:59
Flyway and Postgres auto-vacuum

Ran into an issue with flyway script executing an alter table statement while Postgres auto-vacuum for the same table was in progress. As tables grow, Postgres runs the auto-vacuum for tables periodically. The flyway script was stuck waiting for the table lock to be released. To avoid this issue, one can disable the auto-vacuum before the flyway migration and re-enable it after migration is finished using beforeMigrate.sql and afterMigrate.sql.

@pavelfomin
pavelfomin / flyway.md
Created November 26, 2024 13:31
Parameterizing flyway scripts

Occasionally it can be helpful to parameterize a migration depending on an environment. Flyway supports the concept of placeholders to help with that.

Flyway provides default placeholders, whose values are automatically populated:

  • ${flyway:defaultSchema} = The default schema for Flyway
  • ${flyway:user} = The user Flyway will use to connect to the database
  • ${flyway:database} = The name of the database from the connection url
  • ${flyway:timestamp} = The time that Flyway parsed the script, formatted as 'yyyy-MM-dd HH:mm:ss'
@pavelfomin
pavelfomin / DataSourceHealthIndicator.md
Last active November 13, 2024 15:09
Specify custom query for DataSourceHealthIndicator in Spring Boot 3

For some reason, DataSourceHealthIndicator does not support custom query configuration via a property. DataSourceHealthContributorAutoConfiguration uses poolMetadata.getValidationQuery() to pass the validation query to DataSourceHealthIndicator.

Using spring.datasource.hikari.connection-test-query will customize the Hikari datasource test query and db health check will also it. However, it will also affect the performance of the Hikari connection pool which is not ideal.

Another way of configuring a custom query for DataSourceHealthIndicator is to create this as a @Bean manually and pass a custom query to its constructor. Using the same @Bean name dbHealthIndicator disables the [autoconfiguration of the default DataSourceHealthIndicator](https://github.com/spr

@pavelfomin
pavelfomin / gcp-crash-loop.md
Last active October 28, 2024 18:51
Troubleshooting application crash looping in GCP

Troubleshooting application crash looping in GCP

  • disable auto scaling and set number of replicas manually

  • view events in GCP to get a better idea of why application is getting killed and restarted image

  • note how long it takes for app to start successfully in your current environment

    • adjust number of tries for liveness and readiness probes to accommodate slower start ups
    • enable debug logging by org.springframework.boot.availability.ApplicationAvailabilityBean
  • use GCP metrics to monitor application CPU and RAM usage