Differences between HTTP 1.0 vs HTTP 1.1


Host field

HTTP 1.1 requires Host field by Spec

HTTP 1.0 doesn’t officially require Host header

GET / HTTP/1.1
Host: www.blahblahblahblah.com

Persistent connection

HTTP 1.0 considers a connection is persistent unless keepalive header is included

HTTP 1.1 considers all connections are persistent

Method OPTIONS

HTTP 1.1 introduces new method named OPTIONS

HTTP 1.0 doesn’t support this method

Response code 100

HTTP 1.1 uses response code 100 to continue the body and avoid big request payload

HTTP 1.0 doesn’t support this response code

Advertisements

Spring Data JPA listen to Postgres notification


Create trigger function

-- FUNCTION: public.table_update_notify()

-- DROP FUNCTION public.table_update_notify();

CREATE FUNCTION public.table_update_notify()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF
AS $BODY$
DECLARE
  id bigint;
BEGIN
  IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
    id = NEW.id;
  ELSE
    id = OLD.id;
  END IF;
  PERFORM pg_notify('employee_channel', json_build_object('table', TG_TABLE_NAME, 'id', id, 'type', TG_OP)::text);
  RETURN NEW;
END;

$BODY$;

ALTER FUNCTION public.table_update_notify()
    OWNER TO postgres;

Create a trigger into table name employee

-- Trigger: employee_notify_update

-- DROP TRIGGER employee_notify_update ON production.employee;

CREATE TRIGGER employee_notify_update
    BEFORE INSERT OR DELETE OR UPDATE
    ON production.employee
    FOR EACH ROW
    EXECUTE PROCEDURE public.table_update_notify();

Now every time, table employee changed, it fire an event with payload is information of the change

Initialize the Spring Data JPA with spring boot starter

Spring Data JPA with multiple datasource


Requisition

  • Spring Boot 1.5.11.RELEASE
  • Spring Data JPA 1.11.11.RELEASE
  • Hibernate 5.3.5.Final
  • Postgres 9.4

When using Spring Data JPA together with Spring Boot. It’s easily to realize that Spring Boot JDBC help to initialize one primary data source.

But in reality, one application usually need more than one data source. Especially with legacy systems, this kind of system is usually a centralized of all business logic implementations from customer. For instance,  We consider following scenario:

spring-data-jpa-multiple-datasource

Management System  connects to both Office department database and  People department

The following steps are sufficient for you to connect to one additional data source:

Exclude the default initalized data source from Spring Boot JDBC

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class Application {

    public static void main(String[] args) {
        SpringApplication
            .run(Application.class, args);
    }
}

Configure data source Office

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "officeEntityManagerFactory", transactionManagerRef = "officeTransactionManager", basePackageClasses = {
    DeviceRepository.class })
public class OfficeDataSourceConfiguration {

    @Bean(name = "officeEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
        final EntityManagerFactoryBuilder builder,
        @Qualifier("officeDataSource") final DataSource dataSource) {
        return builder.dataSource(dataSource).packages(Device.class)
            .persistenceUnit("office").build();
    }

    @Bean(name = "officeDataSource")
    @ConfigurationProperties(prefix = "datasource.office")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "officeTransactionManager")
    public PlatformTransactionManager transactionManager(
        @Qualifier("officeEntityManagerFactory") final EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

Configure data source People

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "peopleEntityManagerFactory", transactionManagerRef = "peopleTransactionManager", basePackageClasses = {
    DepartmentRepository.class })
public class PeopleDataSourceConfiguration {

    @Primary
    @Bean(name = "peopleEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
        final EntityManagerFactoryBuilder builder,
        @Qualifier("peopleDataSource") final DataSource dataSource) {
        return builder.dataSource(dataSource).packages(Department.class)
            .persistenceUnit("people").build();
    }

    @Primary
    @Bean(name = "peopleDataSource")
    @ConfigurationProperties(prefix = "datasource.people")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name = "peopleTransactionManager")
    public PlatformTransactionManager peopleTransactionManager(
        @Qualifier("peopleEntityManagerFactory") final EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

Update configuration in application.yml

spring:
    application:
        name: spring-data-jpa-multiple-datasource
    profiles:
        active: default
    data.jpa.repositories.enabled: true
    jpa:
        database-platform: POSTGRESQL
        generate-ddl: true
        open-in-view: true
        show-sql: false
        hibernate.ddl-auto: update
        properties:
            hibernate:
                dialect: org.hibernate.dialect.PostgreSQL94Dialect
                default_schema: production

datasource:
    people:
        driverClassName: org.postgresql.Driver
        url: jdbc:postgresql://10.10.15.171:5432/people?currentSchema=production
        username: postgres
        password: postgres
        type: org.apache.tomcat.jdbc.pool.DataSource
        jmx-enabled: true
        initialSize: 2
        maxActive: 100
        maxIdle: 5
        minIdle: 2
        maxWait: 600000
        testOnBorrow: true
        validationQuery: select 1
        minEvictableIdleTimeMillis: 60000
        removeAbandoned: true
        removeAbandonedTimeout: 60000
        testWhileIdle: true
        timeBetweenEvictionRunsMillis: 60000

    office:
        driverClassName: org.postgresql.Driver
        url: jdbc:postgresql://10.10.15.171:5432/office?currentSchema=production
        username: postgres
        password: postgres
        type: org.apache.tomcat.jdbc.pool.DataSource
        jmx-enabled: true
        initialSize: 2
        maxActive: 100
        maxIdle: 5
        minIdle: 2
        maxWait: 600000
        testOnBorrow: true
        validationQuery: select 1
        minEvictableIdleTimeMillis: 60000
        removeAbandoned: true
        removeAbandonedTimeout: 60000
        testWhileIdle: true
        timeBetweenEvictionRunsMillis: 60000

Source code sample

Configuration ngoài cho ứng dụng với Spring Boot


1. Sử dụng properties file SpringApplication sẽ load các property từ tất cả các file application.properties trong các vị trí sau, và thêm chúng vào application environment: + Folder /config bên trong folder hiện tại. + Folder hiện tại. + Class path /config + Root class path Mặc định, SpringApplication sẽ load theo thứ tự từ dưới lên trên. Và các property nào load sau sẽ override property load trước. Vì lý do này, bạn cứ đặt property vào class path bình thường, khi muốn config ngoài file jar, thì sẽ đặt file application.properties vào folder /config là được. Như vậy cần phải build dự án với maven sao cho có kết quả trong folder target như sau:

+-target
    +---myapp.jar
    +---config
            +--application.properties

Continue reading “Configuration ngoài cho ứng dụng với Spring Boot”

Sử dụng configuration class trong Spring Boot


1. Sử dụng class Configuration
Spring Boot ưu ái việc sử dụng các class Configuration. Mặc dù bạn có thể hoàn toàn sử dụng việc gọi hàm SpringApplication.run() ngay bên trong file XML, nhưng nhìn chung Spring khuyên điểm xuất phát của ứng dụng là một class với annotation @Configuration. Thông thường thì class với hàm main() thì nên là cũng là lớp chứa @Configuration.

import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Application
{
    public static void main(final String[] args)
    {
        SpringApplication.run(Application.class, args);
    }
}

Continue reading “Sử dụng configuration class trong Spring Boot”

What is Hypervisor ?


What is Hypervisor?
Hypervisor (visor: còn gọi là tấm bảo vệ) là một software, firmware hay hardware giúp tạo và điều hành các máy ảo. PC mà trên đó hypervisor đang kiểm soát hoạt động của một hoặc nhiều máy ảo gọi là host machine. Mỗi máy ảo gọi là guest machine. Hypervisor kiểm soát các guest OS trên một nền tảng điều hành ảo (Virtual Operating Platform) và quản lý hoạt động của các hệ điều hành này. Các guest machine chia sẽ các hardware resource ảo.

Continue reading “What is Hypervisor ?”

What you should do when the arrow keys is locked in eclipse on Linux platform


When I use Eclipse IDE on a Linux machine, I usually encounter some problems when the arrow keys suddenly loose their effect. The enter and backspace key also is stuck by this way. It makes me angry and I often press these key many times to try to get out of this obstacle.
After many attempts, I can reproduce the case when this problem occur by these steps: Hover your mouse on a function to make eclipse show up its java doc popup window. Then you move your mouse and click inside that window to focus on that one. After that, you move the mouse out the java doc window and click on anywhere in the editor. By this way, the problem happens.

As my opinion, this is simply caused by the loosing of focus on your editor. The focus is still on the popup window.

With that cause, I find out the way to make the focus back on the editor. You can do something like: show up any more popup window (by right click on editor and select Quick Outline for instance) and then press Esc, the focus will back immediately and you can use your arrow keys as usual.

For conclusion: Right Click (on editor) -> Quick Outline -> press Esc key.