Creating a React App using npx
npx create-react-app my-app
Creating a TypeScript app
npx create-react-app my-app --template typescript
References
https://create-react-app.dev/docs/getting-started/
npx create-react-app my-app
Creating a TypeScript app
npx create-react-app my-app --template typescript
References
https://create-react-app.dev/docs/getting-started/
@Component public class Bean1 { @PreDestroy public void destroy() { System.out.println( "Callback triggered - @PreDestroy."); } }
References
https://www.baeldung.com/spring-shutdown-callbacks
@Component public class EventListenerExampleBean { private static final Logger LOG = Logger.getLogger(EventListenerExampleBean.class); public static int counter; @EventListener public void onApplicationEvent(ContextRefreshedEvent event) { LOG.info("Increment counter"); counter++; } }
We can use this approach for running logic after the Spring context has been initialized. So, we aren’t focusing on any particular bean. We’re instead waiting for all of them to initialize.
We want to make sure to pick an appropriate event for our needs. In this example, we chose the ContextRefreshedEvent
.
References
https://www.baeldung.com/running-setup-logic-on-startup-in-spring
Configuration
@Configuration public class RedisConfiguration { @Bean public LettuceConnectionFactory redisConnectionFactory() { ConfigFile configFile = new ConfigFile(); RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(configFile.getRedisHost()); configuration.setPassword(configFile.getRedisPassword()); return new LettuceConnectionFactory(configuration); } @Bean public StringRedisTemplate redisTemplate() { return new StringRedisTemplate(redisConnectionFactory()); } }
You can use RedisTemplate
instead of StringRedisTemplate
.
Redis Repository
@RedisHash("Student") public class Student implements Serializable { public enum Gender { MALE, FEMALE } @Id private String id; private String name; private Gender gender; private int grade; // ... }
The Spring Data Repository
@Repository public interface StudentRepository extends CrudRepository<Student, String> {}
Data Access Using StudentRepository
Saving a New Student Object
Student student = new Student( "Eng2015001", "John Doe", Student.Gender.MALE, 1); studentRepository.save(student);
Retrieving an Existing Student Object
Student retrievedStudent = studentRepository.findById("Eng2015001").get();
Updating an Existing Student Object
retrievedStudent.setName("Richard Watson"); studentRepository.save(student);
Deleting Existing Student Data
studentRepository.deleteById(student.getId());
Find All Student Data
Student engStudent = new Student( "Eng2015001", "John Doe", Student.Gender.MALE, 1); Student medStudent = new Student( "Med2015001", "Gareth Houston", Student.Gender.MALE, 2); studentRepository.save(engStudent); studentRepository.save(medStudent);
References
https://docs.spring.io/spring-data/redis/docs/current/reference/html/
https://www.baeldung.com/spring-data-redis-tutorial
@SpringBootApplication public class CustomApplication { public static void main(String[] args) { SpringApplication app = new SpringApplication(CustomApplication.class); app.setDefaultProperties(Collections .singletonMap("server.port", "8083")); app.run(args); } }
or
@Configuration public class ServerPortCustomizer implements WebServerFactoryCustomizer<ConfigurableWebServerFactory> { @Override public void customize(ConfigurableWebServerFactory factory) { factory.setPort(8086); } }
@SpringBootApplication(exclude = RabbitAutoConfiguration.class) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean CachingConnectionFactory cf1() { return new CachingConnectionFactory("localhost"); } @Bean CachingConnectionFactory cf2() { return new CachingConnectionFactory("otherHost"); } @Bean CachingConnectionFactory cf3() { return new CachingConnectionFactory("thirdHost"); } @Bean SimpleRoutingConnectionFactory rcf(CachingConnectionFactory cf1, CachingConnectionFactory cf2, CachingConnectionFactory cf3) { SimpleRoutingConnectionFactory rcf = new SimpleRoutingConnectionFactory(); rcf.setDefaultTargetConnectionFactory(cf1); rcf.setTargetConnectionFactories(Map.of("one", cf1, "two", cf2, "three", cf3)); return rcf; } @Bean("factory1-admin") RabbitAdmin admin1(CachingConnectionFactory cf1) { return new RabbitAdmin(cf1); } @Bean("factory2-admin") RabbitAdmin admin2(CachingConnectionFactory cf2) { return new RabbitAdmin(cf2); } @Bean("factory3-admin") RabbitAdmin admin3(CachingConnectionFactory cf3) { return new RabbitAdmin(cf3); } @Bean public RabbitListenerEndpointRegistry rabbitListenerEndpointRegistry() { return new RabbitListenerEndpointRegistry(); } @Bean public RabbitListenerAnnotationBeanPostProcessor postProcessor(RabbitListenerEndpointRegistry registry) { MultiRabbitListenerAnnotationBeanPostProcessor postProcessor = new MultiRabbitListenerAnnotationBeanPostProcessor(); postProcessor.setEndpointRegistry(registry); postProcessor.setContainerFactoryBeanName("defaultContainerFactory"); return postProcessor; } @Bean public SimpleRabbitListenerContainerFactory factory1(CachingConnectionFactory cf1) { SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); factory.setConnectionFactory(cf1); return factory; } @Bean public SimpleRabbitListenerContainerFactory factory2(CachingConnectionFactory cf2) { SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); factory.setConnectionFactory(cf2); return factory; } @Bean public SimpleRabbitListenerContainerFactory factory3(CachingConnectionFactory cf3) { SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); factory.setConnectionFactory(cf3); return factory; } @Bean RabbitTemplate template(SimpleRoutingConnectionFactory rcf) { return new RabbitTemplate(rcf); } @Bean ConnectionFactoryContextWrapper wrapper(SimpleRoutingConnectionFactory rcf) { return new ConnectionFactoryContextWrapper(rcf); } } @Component class Listeners { @RabbitListener(queuesToDeclare = @Queue("q1"), containerFactory = "factory1") public void listen1(String in) { } @RabbitListener(queuesToDeclare = @Queue("q2"), containerFactory = "factory2") public void listen2(String in) { } @RabbitListener(queuesToDeclare = @Queue("q3"), containerFactory = "factory3") public void listen3(String in) { } }
References
https://docs.spring.io/spring-amqp/docs/current/reference/html/#multi-rabbit
RabbitConfiguration.java
@Bean public SimpleMessageListenerContainer messageListenerContainer() { // configure listener to receive messages from queues SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(); container.setConnectionFactory(connectionFactory()); container.setConcurrentConsumers(8); container.setMaxConcurrentConsumers(32); // listen to queues container.setQueueNames("MonitoringV5_Queue1", "MonitoringV5_Queue2"); container.setMessageListener(new RabbitMessageListener()); return container; }
public class RabbitMessageListener implements MessageListener { @Override public void onMessage(Message message) { switch (message.getMessageProperties().getConsumerQueue()) { case "MonitoringV5_Queue1" -> Queue1(message); case "MonitoringV5_Queue2" -> Queue2(message); } } private void Queue1(Message message) { String str=new String(message.getBody()); System.out.println(str); Gson gson = new Gson(); ReadValueDto value= gson.fromJson(str,ReadValueDto.class); } private void Queue2(Message message) { String str=new String(message.getBody()); System.out.println(str); Gson gson = new Gson(); ReadValueDto value= gson.fromJson(str,ReadValueDto.class); } }
If your callback logic depends on the AMQP Channel
instance for any reason, you may instead use the ChannelAwareMessageListener
. It looks similar but has an extra parameter.
References
https://docs.spring.io/spring-amqp/docs/current/reference/html/#message-listener
@Bean public RabbitTemplate rabbitTemplate() { RabbitTemplate template = new RabbitTemplate(connectionFactory()); // configure template to use retry policy RetryTemplate retryTemplate = new RetryTemplate(); ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy(); backOffPolicy.setInitialInterval(500); backOffPolicy.setMultiplier(10.0); backOffPolicy.setMaxInterval(10000); retryTemplate.setBackOffPolicy(backOffPolicy); template.setRetryTemplate(retryTemplate); return template; }
References
https://docs.spring.io/spring-amqp/docs/current/reference/html/#template-retry
https://www.baeldung.com/spring-retry
@Configuration public class RabbitConfiguration { @Bean public CachingConnectionFactory connectionFactory() { // configure to connect with credential ConfigFile configFile = new ConfigFile(); CachingConnectionFactory connectionFactory = new CachingConnectionFactory(configFile.getRabbitmqHost()); connectionFactory.setUsername(configFile.getRabbitmqUserName()); connectionFactory.setPassword(configFile.getRabbitmqPassword()); return connectionFactory; } @Bean public RabbitAdmin amqpAdmin() { return new RabbitAdmin(connectionFactory()); } @Bean public RabbitTemplate rabbitTemplate() { RabbitTemplate template = new RabbitTemplate(connectionFactory()); return template; } @Bean public Queue MonitoringV5_Queue1() { // declare queue1 return new Queue("MonitoringV5_Queue1"); } @Bean public Queue MonitoringV5_Queue2() { // declare queue2 return new Queue("MonitoringV5_Queue2"); } }
References
https://docs.spring.io/spring-amqp/docs/current/reference/html/#cachingconnectionfactory
Generating a GPG key
gpg --full-generate-key
gpg --list-secret-keys --keyid-format=long
From the list of GPG keys, copy the long form of the GPG key ID you’d like to use. In this example, the GPG key ID is 3AA5C34371567BD2
:
$ gpg --list-secret-keys --keyid-format=long /Users/hubot/.gnupg/secring.gpg ------------------------------------ sec 4096R/3AA5C34371567BD2 2016-03-10 [expires: 2017-03-10] uid Hubot ssb 4096R/42B317FD4BA89E7A 2016-03-10
gpg --armor --export 3AA5C34371567BD2 # Prints the GPG key ID, in ASCII armor format
Copy your GPG key, beginning with -----BEGIN PGP PUBLIC KEY BLOCK-----
and ending with -----END PGP PUBLIC KEY BLOCK-----
.