|
| 1 | +--- |
| 2 | +sidebar_position: 4 |
| 3 | +--- |
| 4 | + |
| 5 | +# Migration |
| 6 | + |
| 7 | +## From 5.x.x to 6.x.x |
| 8 | + |
| 9 | +### New Features |
| 10 | + |
| 11 | +- **Connection customization:** You can now customize the RabbitMQ connection by defining a |
| 12 | + `ConnectionFactoryCustomizer` bean. For more details, |
| 13 | + see [Customizing the connection](/reactive-commons-java/docs/reactive-commons/configuration_properties/rabbitmq#customizing-the-connection). |
| 14 | + |
| 15 | +```java title="Programmatic configuration" |
| 16 | + |
| 17 | +@Bean |
| 18 | +public ConnectionFactoryCustomizer connectionFactoryCustomizer() { |
| 19 | + return (ConnectionFactoryCustomizer) (asyncProps, connectionFactory) -> { |
| 20 | + connectionFactory.setExceptionHandler(new MyCustomExceptionHandler()); // Optional custom exception handler |
| 21 | + connectionFactory.setCredentialsProvider(new MyCustomCredentialsProvider()); // Optional custom credentials provider |
| 22 | + return connectionFactory; |
| 23 | + }; |
| 24 | +} |
| 25 | +``` |
| 26 | + |
| 27 | +### Change notes |
| 28 | + |
| 29 | +- The configuration property `listenReplies` for RabbitMQ now defaults to `null`. Previously, it was `true`, causing all |
| 30 | + applications to subscribe to a reply queue even when not needed. |
| 31 | +- The domain `app` is now **required**. If not defined, the application will fail to start. |
| 32 | + |
| 33 | +### Actions |
| 34 | + |
| 35 | +- If your application uses the ReqReply pattern, you must explicitly set `app.async.app.listenReplies` to `true`. |
| 36 | + Otherwise, it should be `false` to avoid unnecessary resource usage: |
| 37 | + |
| 38 | +```yaml title="application.yaml" |
| 39 | +app: |
| 40 | + async: |
| 41 | + app: |
| 42 | + listenReplies: true # set to true if ReqReply is required, false if not |
| 43 | +``` |
| 44 | +
|
| 45 | +```java title="Programmatic configuration" |
| 46 | +@Configuration |
| 47 | +public class MyDomainConfig { |
| 48 | + |
| 49 | + @Bean |
| 50 | + @Primary |
| 51 | + public AsyncRabbitPropsDomainProperties customDomainProperties() { |
| 52 | + RabbitProperties propertiesApp = new RabbitProperties(); |
| 53 | + // Additional connection configuration goes here... |
| 54 | + return AsyncRabbitPropsDomainProperties.builder() |
| 55 | + .withDomain("app", AsyncProps.builder() |
| 56 | + .connectionProperties(propertiesApp) |
| 57 | + .listenReplies(Boolean.TRUE) // set to true if ReqReply is required, false if not |
| 58 | + .build()) |
| 59 | + .build(); |
| 60 | + } |
| 61 | +} |
| 62 | +``` |
| 63 | + |
| 64 | +--- |
| 65 | + |
| 66 | +- The domain `app` must be defined in your configuration. Otherwise, the application will throw an exception at startup: |
| 67 | + |
| 68 | +```yaml title="application.yaml" |
| 69 | +app: |
| 70 | + async: |
| 71 | + app: # Configure the 'app' domain |
| 72 | + # domain configuration goes here |
| 73 | +``` |
| 74 | + |
| 75 | +```java title="Programmatic configuration" |
| 76 | +@Configuration |
| 77 | +public class MyDomainConfig { |
| 78 | + |
| 79 | + @Bean |
| 80 | + @Primary |
| 81 | + public AsyncRabbitPropsDomainProperties customDomainProperties() { |
| 82 | + RabbitProperties propertiesApp = new RabbitProperties(); |
| 83 | + // Additional connection configuration goes here... |
| 84 | + return AsyncRabbitPropsDomainProperties.builder() |
| 85 | + .withDomain("app", AsyncProps.builder() // Configure the 'app' domain |
| 86 | + .connectionProperties(propertiesApp) |
| 87 | + .build()) |
| 88 | + .build(); |
| 89 | + } |
| 90 | +} |
| 91 | +``` |
| 92 | + |
| 93 | +## From 4.x.x to 5.x.x |
| 94 | + |
| 95 | +### New Features |
| 96 | + |
| 97 | +- **Support for multiple brokers:** It is now possible to configure and connect to up to two brokers simultaneously, |
| 98 | + using |
| 99 | + independent domains in the configuration. |
| 100 | + |
| 101 | +### Change notes |
| 102 | + |
| 103 | +- Configuration properties are now defined per domain, allowing each to have its own properties and connection |
| 104 | + settings. |
| 105 | +- The broker connection is no longer manually defined in the code. It is now automatically managed based on the |
| 106 | + configuration declared in the `application.yaml` file or through programmatic configuration. |
| 107 | + |
| 108 | +### Actions |
| 109 | + |
| 110 | +- The `app` domain needs to be defined to specify the configuration properties. |
| 111 | + |
| 112 | +Before: |
| 113 | + |
| 114 | +```yaml title="application.yaml" |
| 115 | +app: |
| 116 | + async: |
| 117 | + withDLQRetry: true |
| 118 | + maxRetries: 1 |
| 119 | + retryDelay: 1000 |
| 120 | +``` |
| 121 | +
|
| 122 | +Now: |
| 123 | +
|
| 124 | +```yaml title="application.yaml" |
| 125 | +app: |
| 126 | + async: |
| 127 | + app: # this is the name of the default domain |
| 128 | + withDLQRetry: true |
| 129 | + maxRetries: 1 |
| 130 | + retryDelay: 1000 |
| 131 | +``` |
| 132 | +
|
| 133 | +- Migrate the connection configuration: |
| 134 | +
|
| 135 | +Before: the connection was defined manually in a Java class, as shown below: |
| 136 | +
|
| 137 | +```java |
| 138 | +@Log4j2 |
| 139 | +@Configuration |
| 140 | +@RequiredArgsConstructor |
| 141 | +public class MyDomainConfig { |
| 142 | + |
| 143 | + private final RabbitMQConnectionProperties properties; |
| 144 | + private static final String TLS = "TLSv1.2"; |
| 145 | + private static final String FAIL_MSG = "Error creating ConnectionFactoryProvider in enroll"; |
| 146 | + |
| 147 | + @Primary |
| 148 | + @Bean |
| 149 | + public ConnectionFactoryProvider getConnectionFactoryProvider() { |
| 150 | + final var factory = new ConnectionFactory(); |
| 151 | + var map = PropertyMapper.get(); |
| 152 | + map.from(properties::hostname).whenNonNull().to(factory::setHost); |
| 153 | + map.from(properties::port).to(factory::setPort); |
| 154 | + map.from(properties::username).whenNonNull().to(factory::setUsername); |
| 155 | + map.from(properties::password).whenNonNull().to(factory::setPassword); |
| 156 | + map.from(properties::ssl).whenTrue().as(isSsl -> factory).to(this::configureSsl); |
| 157 | + return () -> factory; |
| 158 | + } |
| 159 | + |
| 160 | + private void configureSsl(ConnectionFactory factory) { |
| 161 | + try { |
| 162 | + var sslContext = SSLContext.getInstance(TLS); |
| 163 | + var trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); |
| 164 | + trustManagerFactory.init((KeyStore) null); |
| 165 | + sslContext.init(null, trustManagerFactory.getTrustManagers(), null); |
| 166 | + factory.useSslProtocol(sslContext); |
| 167 | + } catch (KeyManagementException | KeyStoreException | NoSuchAlgorithmException e) { |
| 168 | + log.error("{}: {}", FAIL_MSG, e); |
| 169 | + } |
| 170 | + } |
| 171 | +} |
| 172 | +``` |
| 173 | + |
| 174 | +Now: the connection is configured directly in the `application.yaml` file per domain: |
| 175 | + |
| 176 | +```yaml title="application.yaml" |
| 177 | +app: |
| 178 | + async: |
| 179 | + app: # this is the name of the default domain |
| 180 | + connectionProperties: # you can override the connection properties of each domain |
| 181 | + host: localhost |
| 182 | + port: 5672 |
| 183 | + username: guest |
| 184 | + password: guest |
| 185 | + virtual-host: / |
| 186 | + # Another domain can be configured with same properties structure that app |
| 187 | + accounts: # this is a second domain name and can have another independent setup |
| 188 | + connectionProperties: # you can override the connection properties of each domain |
| 189 | + host: localhost |
| 190 | + port: 5672 |
| 191 | + username: guest |
| 192 | + password: guest |
| 193 | + virtual-host: /accounts |
| 194 | +``` |
| 195 | +
|
| 196 | +Domains can also be configured programmatically: |
| 197 | +
|
| 198 | +```java title="Programmatic configuration" |
| 199 | +@Configuration |
| 200 | +public class MyDomainConfig { |
| 201 | + |
| 202 | + @Bean |
| 203 | + @Primary |
| 204 | + public AsyncRabbitPropsDomainProperties customDomainProperties() { |
| 205 | + RabbitProperties propertiesApp = new RabbitProperties(); |
| 206 | + propertiesApp.setHost("localhost"); |
| 207 | + propertiesApp.setPort(5672); |
| 208 | + propertiesApp.setVirtualHost("/"); |
| 209 | + propertiesApp.setUsername("guest"); |
| 210 | + propertiesApp.setPassword("guest"); |
| 211 | + |
| 212 | + RabbitProperties propertiesAccounts = new RabbitProperties(); |
| 213 | + propertiesAccounts.setHost("localhost"); |
| 214 | + propertiesAccounts.setPort(5672); |
| 215 | + propertiesAccounts.setVirtualHost("/accounts"); |
| 216 | + propertiesAccounts.setUsername("guest"); |
| 217 | + propertiesAccounts.setPassword("guest"); |
| 218 | + |
| 219 | + return AsyncRabbitPropsDomainProperties.builder() |
| 220 | + .withDomain("app", AsyncProps.builder() |
| 221 | + .connectionProperties(propertiesApp) |
| 222 | + .build()) |
| 223 | + .withDomain("accounts", AsyncProps.builder() |
| 224 | + .connectionProperties(propertiesAccounts) |
| 225 | + .build()) |
| 226 | + .build(); |
| 227 | + } |
| 228 | +} |
| 229 | +``` |
0 commit comments