Thứ Năm, 23 tháng 11, 2017

Giới thiệu OAuth 2.0

1. Chứng thực (Authentication) và cấp quyền (Authorization)

Sự chứng thực (Authentication) là tiến trình xét xem một đối tượng có đúng là nó hay không.

Sự cấp quyền (Authorization) là tiến trình xét xem một đối tượng có một số quyền nào đó hay không.


2. OAuth2 là gì?

OAuth2 là một giao thức cấp quyền mở (open authorization protocol) nhằm cho phép các ứng dụng bên thứ ba truy cập có giới hạn các tài nguyên mà trước đó người dùng đã ủy quyền. Các ứng dụng được ủy quyền và không cần biết định danh (credentials) của người dùng để sử dụng các tài nguyên.

Ví dụ : Một ứng dụng tạo avatar có thể truy cập để thay đổi avatar của người dùng trong Snapchat. Người dùng mở ứng dụng avatar, ứng dụng này yêu cầu người dùng đăng nhập vào nó thông qua Snapchat. Người dùng đăng nhập vào Snapchat và Snapchat gửi người dùng về ứng dụng avatar sau khi đăng nhập thành công. Ứng dụng avatar bây giờ có thể truy cập dữ liệu Snapchat của người dùng và gọi hàm để thay đổi avatar trong Snapchat thay người dùng.

Tham khảo bản đặc tả tại đây


3. Các khái niệm

a. Các vai (roles)

OAuth2 định nghĩa bốn vai sau:

- Chủ sở hữu tài nguyên (Ressource Owner) : là người hay ứng dụng sở hữu dữ liệu muốn chia sẻ, và có thể cấp quyền truy cập đến chúng.

- Máy chủ tài nguyên (Ressource Server): là máy chủ lưu trữ dữ liệu và bảo vệ việc truy cập đến chúng.

- Ứng dụng khách (client) : là ứng dụng thay mặt chủ sở hữu sử dụng các tài nguyên.

- Máy chủ cấp quyền (Authorization Server) : là máy chủ, theo sự đồng ý của chủ tài nguyên, cấp quyền truy cập dữ liệu được bảo vệ cho ứng dụng khách. Nó thực hiện việc này bằng cách cung cấp các thẻ định danh (token) cho ứng dụng khách. Máy chủ cấp quyền cũng có thể đồng thời là máy chủ tài nguyên.

b. Các thẻ (tokens)

Các thẻ là các chuỗi kí tự do máy chủ cấp quyền phát sinh và gởi đi khi ứng dụng khách yêu cầu. OAuth2 dùng thẻ để cấp quyền. Thẻ là danh tính duy nhất mà ứng dụng khách dùng để truy cập tài nguyên mà không cần dùng đến định danh của người dùng. Ta phân biệt hai loại thẻ sau :

 - Thẻ truy cập (access token) : Ứng dụng khách sử dụng thẻ này để truy cập dữ liệu của chủ sở hữu trên máy chủ tài nguyên. Nó có thời gian sử dụng ngắn.

OAuth2 định nghĩa hai loại thẻ truy cập chính :
+ Loại thẻ Bearer (bearer token) : sử dụng đơn giản bằng cách thêm thẻ này vào trong câu truy vấn HTTP. Loại này được sử dụng chủ yếu.

+ Loại thẻ MAC (Message Authentication Code token) : cần phải phát sinh MAC key và thẻ truy cập (access token) dùng để ký một số thành phần của câu truy vấn HTTP

- Thẻ làm mới (refresh token) : Thẻ làm mới này không bắt buộc, dùng để lấy một thẻ truy cập mới khi thẻ truy cập hiện tại hết hiệu lực. Thẻ này có thời gian sử dụng lâu hơn thẻ truy cập.

c. Đăng kí ứng dụng khách

Trước khi một ứng dụng khách có thể yêu cầu truy cập đến dữ liệu trên máy chủ tài nguyên, nó phải đăng kí với máy chủ cấp quyền của máy chủ tài nguyên. Việc đăng kí này thực hiện một lần.

Một khi đăng kí, máy chủ cấp quyền sẽ gửi định danh khách (client id), và mật khẩu (client secret). Định danh và mật khẩu này là duy nhất cho ứng dụng khách trên máy chủ cấp quyền.


4. Cấp quyền (Authorization Grant)

Chủ sở hữu cấp quyền cho ứng dụng khách thông qua máy chủ cấp quyền của máy chủ tài nguyên.

OAuth2 đặc tả bốn loại cấp quyền khác nhau sau đây : authorization code, implicit grant, resource owner password credentials và client credentials.

a. Authorization Code (mã cấp quyền)

(1) Chủ sở hữu truy cập ứng dụng khách

(2) Thay vì yêu cầu cấp quyền trực tiếp từ chủ sở hữu, ứng dụng khách thông báo chuyển chủ sở hữu đến máy chủ cấp quyền.

(3) Để đăng nhập với máy chủ cấp quyền, chủ sở hữu được ứng dụng khách chuyển tới máy chủ cấp quyền. Đồng thời ứng dụng khách gửi kèm theo định danh và đường dẫn chuyển hướng của nó (client id, redirection URI)

(4) sau khi đăng nhập thành công, máy chủ cấp quyền hỏi chủ sở hữu có đồng ý cho ứng dụng khách truy cập tài nguyên hay không.

(5) Nếu chủ sở hữu đồng ý, đến lượt máy chủ cấp quyền chuyển chủ sở hữu về ứng dụng khách cùng với mã cấp quyền (authorization code). Vì chủ sở hữu chỉ chứng thực (authenticate) với máy chủ cấp quyền nên định danh của chủ sở hữu không cần phải chia sẻ với ứng dụng khách.

(6) Ứng dụng khách yêu cầu máy chủ cấp quyền cấp thẻ truy cập (acces token) bằng cách gởi đi mã cấp quyền vừa nhận được, định danh khách và đường dẫn chuyển hướng trong câu truy vấn HTTP

(7) Máy chủ cấp quyền chứng thực ứng dụng khách, kiểm tra có đúng mã cấp quyền và đường dẫn chuyển hướng của ứng dụng này hay không. Nếu hợp lệ, máy chủ gửi trả lời là thẻ truy cập, và có thể cả thẻ làm mới (refresh token)

(8) Ứng dụng khách từ bây giờ có thể dùng thẻ truy cập nhận được để truy vấn tài nguyên trong máy chủ tài nguyên. Thẻ truy cập được dùng để chứng thực ứng dụng khách và chủ sở hữu đồng thời cho phép truy cập tài nguyên

+----------+           +----------+                    +---------------+         +-----------+
| Resource |           |  Client  |                    | Authorization |         | Resource  |
|   Owner  |           |          |                    |     Server    |         |   Server  |
|          |           |          |                    |               |         |           |
+----------+           +----------+                    +---------------+         +-----------+
     |                      |                                  |                       |
     |>-(1)-Access client-->|                                  |                       | 
     |                      |                                  |                       | 
     |<-(2)-Login via------<|                                  |                       | 
     |  Authorization server|                                  |                       | 
     |                      |                                  |                       | 
     |>---------------------|--(3)-Login via Authorization --->|                       | 
     |                      | server & client id + redirect URI|                       |  
     |                      |                                  |                       | 
     |<---------------------|--(4)-Demande grant access ------<|                       | 
     |                      |                                  |                       | 
     |                      |                                  |                       | 
     |>---------------------|--(5)-Grant access--------------->|                       | 
     |                      |<-(5)-Authorization code---------<|                       | 
     |                      |                                  |                       | 
     |                      |--(6)-Request access token------->|                       | 
     |                      |Auth. code,client id, redirect URI|                       | 
     |                      |                                  |                       | 
     |                      |<-(7)- Access token, optionally--<|                       | 
     |                      |     refresh token                |                       | 
     |                      |                                  |                       |
     |>-(8)-Access client-->|                                  |                       | 
     |                      |>---------------------------------|(8)-Request ressource->| 
     |                      |                                  |access token, client id| 
     |                      |                                  |                       |
     |                      |                                  |<-(8)-Verify access --<|   
     |                      |                                  |         token         | 
     |                      |                                  |                       |
     |                      |<---------------------------------|--(8)-Return ---------<| 
     |                      |                                  |      ressource        | 
     |                      |                                  |                       |
     |<-(8)show ressource--<|                                  |                       |


b. Implicit (Ngầm định)

(1) Chủ sở hữu truy cập ứng dụng khách

(2) Thay vì yêu cầu cấp quyền trực tiếp từ chủ sở hữu, ứng dụng khách thông báo chuyển chủ sở hữu đến máy chủ cấp quyền.

(3) Để đăng nhập với máy chủ cấp quyền, chủ sở hữu được ứng dụng khách chuyển tới máy chủ cấp quyền. Đồng thời ứng dụng khách gửi kèm theo định danh và đường dẫn chuyển hướng của nó (client id, redirection URI)

(4) Thay vì nhận mã cấp quyền, ứng dụng khách nhận lập tức thẻ truy cập. Sự cấp quyền được ngầm định vì không có sử dụng định danh trung gian (mã cấp quyền như ở trên, để sau đó lấy thẻ truy cập). Nó không cung cấp thẻ làm mới.

(5) Ứng dụng khách từ bây giờ có thể dùng thẻ truy cập nhận được để truy vấn tài nguyên trong máy chủ tài nguyên. Thẻ truy cập được dùng để chứng thực ứng dụng khách và chủ sở hữu đồng thời cho phép truy cập tài nguyên

Các ứng dụng khách này có đặc thù là được cài đặt trong trình duyệt và dùng ngôn ngữ thông dịch chẳng hạn như JavaScript

+----------+           +----------+                    +---------------+         +-----------+
| Resource |           |  Client  |                    | Authorization |         | Resource  |
|   Owner  |           |          |                    |     Server    |         |   Server  |
|          |           |          |                    |               |         |           |
+----------+           +----------+                    +---------------+         +-----------+
     |                      |                                  |                       |
     |>-(1)-Access client-->|                                  |                       | 
     |                      |                                  |                       | 
     |<-(2)-Login via------<|                                  |                       | 
     |  Authorization server|                                  |                       | 
     |                      |                                  |                       | 
     |>---------------------|--(3)-Login via Authorization --->|                       | 
     |                      | server & client id + redirect URI|                       |  
     |                      |                                  |                       | 
     |                      |<-(4)- Access token  ------------<|                       | 
     |                      |                                  |                       | 
     |                      |                                  |                       |
     |>-(5)-Access client-->|                                  |                       | 
     |                      |>---------------------------------|(5)-Request ressource->|    
     |                      |                                  |access token, client id| 
     |                      |                                  |                       |
     |                      |                                  |<-(5)-Verify access --<| 
     |                      |                                  |         token         | 
     |                      |                                  |                       |
     |                      |<---------------------------------|--(5)-Return ---------<| 
     |                      |                                  |      ressource        | 
     |                      |                                  |                       |
     |<-(5)show ressource--<|                                  |                       |


c. Resource Owner Password Credentials (Định danh chủ sở hữu)


(1) Chủ sở hữu cung cấp cho ứng dụng khách danh tính và mật khẩu của mình (username, password)

(2) Ứng dụng khách yêu cầu thẻ truy cập bằng cách gửi định danh của chủ sở hữu đến máy chủ cấp quyền. Qua đó, ứng dụng khách chứng thực với máy chủ cấp quyền

(3) Máy chủ cấp quyền chứng thực ứng dụng khách và chủ sở hữu và nếu hợp lệ gởi trả lời bằng thẻ cấp quyền

(4) Ứng dụng khách từ bây giờ có thể dùng thẻ truy cập nhận được để truy vấn tài nguyên trong máy chủ tài nguyên. Thẻ truy cập được dùng để chứng thực ứng dụng khách và chủ sở hữu đồng thời cho phép truy cập tài nguyên

Dạng này dùng trực tiếp định danh (danh tính và mật khẩu) của chủ sở hữu như một cấp quyền để lấy thẻ truy cập, chỉ nên sử dụng khi thật tin tưởng ứng dụng khách và khi không dùng được các hình thức cấp quyền khác .

Tuy dạng cấp quyền này đòi ứng dụng khách sử dụng trực tiếp định danh của chủ sở hữu, định danh này chỉ sử dụng một lần để đổi lấy thẻ truy cập. Dạng cấp quyền này có thể tránh việc lưu trữ định danh của chủ sở hữu bằng cách đổi lấy một thẻ truy cập với hiệu lực lâu hoặc một thẻ làm mới


+----------+           +----------+                    +---------------+         +-----------+
| Resource |           |  Client  |                    | Authorization |         | Resource  |
|   Owner  |           |          |                    |     Server    |         |   Server  |
|          |           |          |                    |               |         |           |
+----------+           +----------+                    +---------------+         +-----------+
     |                      |                                  |                       | 
     |>-(1)-Resource owner->|                                  |                       | 
     |  Password Credentials|                                  |                       | 
     |                      |                                  |                       | 
     |                      |>-(2)-Resource owner ------------>|                       | 
     |                      |      Password Credentials        |                       |  
     |                      |                                  |                       | 
     |                      |<-(3)- Access token  ------------<|                       | 
     |                      |  (w/ optional refresh token)     |                       | 
     |                      |                                  |                       |
     |>-(4)-Access client-->|                                  |                       | 
     |                      |>---------------------------------|(4)-Request ressource->| 
     |                      |                                  |access token, client id| 
     |                      |                                  |                       |
     |                      |                                  |<-(4)-Verify access --<| 
     |                      |                                  |         token         | 
     |                      |                                  |                       |
     |                      |<---------------------------------|--(4)-Return ---------<| 
     |                      |                                  |      ressource        | 
     |                      |                                  |                       |
     |<-(4)show ressource--<|                                  |                       |


d. Client Credentials (định danh ứng dụng khách)

(1) Ứng dụng khách chứng thực với máy chủ cấp quyền và yêu cầu thẻ truy cập

(2) Máy chủ cấp quyền chứng thực ứng dụng khách, nếu đúng nó trả lời bằng một thẻ truy cập

(3) Ứng dụng khách từ bây giờ có thể dùng thẻ truy cập nhận được để truy vấn tài nguyên trong máy chủ tài nguyên. Thẻ truy cập được dùng để chứng thực ứng dụng khách và chủ sở hữu, đồng thời cho phép truy cập tài nguyên

Dạng cấp quyển theo định danh ứng dụng khách được sử dụng khi ứng dụng khách cần truy cập dữ liệu không liên quan đến một chủ sở hữu cụ thể nào trên máy chủ tài nguyên. Trong trường hợp này ứng dụng khách đồng thời là chủ sở hữu

+----------+                    +---------------+         +-----------+
|  Client  |                    | Authorization |         | Resource  |
|          |                    |     Server    |         |   Server  |
|          |                    |               |         |           |
+----------+                    +---------------+         +-----------+
     |                                  |                       | 
     |>-(1)-Client Authentication------>|                       | 
     |                                  |                       |  
     |                                  |                       | 
     |<-(2)- Access token  ------------<|                       | 
     |                                  |                       | 
     |                                  |                       |
     |>---------------------------------|(3)-Request ressource->| 
     |                                  |access token, client id| 
     |                                  |                       |
     |                                  |<-(3)-Verify access --<| 
     |                                  |         token         | 
     |                                  |                       |
     |<---------------------------------|--(3)-Return ---------<| 
     |                                  |      ressource        | 


4. Ví dụ dùng client credentials

Trong trường hợp này grant_type=client_credentials

a. Yêu cầu một thẻ truy cập

Ví dụ câu truy vấn HTTP

POST /oauth2/token HTTP/1.1
Host: openspace.vn
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=XXX&client_secret=XXX 


Ví dụ nội dung câu trả lời HTTP

{
 "access_token":"eyJraWQiOiJ0ZXN0X2Vudl9r[...]BpHhqUgQUlRngJuLxSW_ZGFXw",
 "token_type":"Bearer",
 "expires_in":900,
} 

phần access_token là nội dung thẻ truy cập

b. Sử dụng thẻ truy cập

Ví dụ thêm một điện thoại vào danh sách

POST /services/addMobile HTTP/1.1
Host: openspace.vn
Content-Type: application/json;charset=UTF-8
Authorization: Bearer
eyJraWQiOiJ0ZXN0X2Vudl9r[...]BpHhqUgQUlRngJuLxSW_ZGFXw

{
 "name": "Samsung Galaxy II",
 "manufacturer": "Samsung",
 "os": "Android"
} 


©Copyright OpenSpaceVN

Thứ Ba, 21 tháng 11, 2017

PosgreSQL : Một số hàm

1. Phát sinh chuỗi duy nhất gồm kí tự (A..Z) và số (0..9)

DROP FUNCTION IF EXISTS unique_string(int);
CREATE OR REPLACE FUNCTION unique_string(quantity int)
RETURNS TEXT AS
$BODY$
SELECT result FROM (SELECT array_to_string(
    ARRAY (
        SELECT substring(
            '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
            FROM (ceil(random()*36))::int FOR 1
        )
        FROM generate_series(1, $1)
    ),
    ''
) as result) r  WHERE NOT EXISTS (SELECT 1 FROM mobile WHERE mobile.name = r.result)
$BODY$
LANGUAGE sql VOLATILE;

SELECT unique_string(16); 

2. Phát sinh chuỗi duy nhất gồm số (0..9)

CREATE OR REPLACE FUNCTION unique_number(int)
RETURNS TEXT AS
$BODY$
SELECT result FROM (
    SELECT array_to_string(
    ARRAY(
        SELECT chr((48 + round(random() * 9)) :: integer) 
        FROM generate_series(1,$1)
    ), ''
) as result) r  WHERE NOT EXISTS (SELECT 1 FROM mobile WHERE mobile.serial_number = r.result);
$BODY$
LANGUAGE sql VOLATILE;

SELECT unique_number(16);
 
 
Doi type cua mot column
ALTER TABLE mobile ALTER COLUMN numero SET DATA TYPE character varying(16) using numero::varchar(16); 





Ubuntu : Eclipse - Cấu hình/Cá nhân hoá và một số phím tắt

1. Cài đặt

Tải eclipse về, chép vào thư mục muốn cài rồi giải nén như sau (ở đây là gói eclipse kepler):
$ tar xzvf eclipse-standard-kepler-SR1-linux-gtk-x86_64.tar.gz

2. Cá nhân hoá (customize) Eclipse

Để cấu hình Eclipse, ta mở hộp thoại Preference trong trình đơn Window :

* Kiểm tra/điều chỉnh việc Eclipse dùng bộ ký tự (charset) khi ghi tập tin trong mục General/Workspace, chẳng hạn :
Text file encoding = UTF-8

* Cấu hình cho Eclipse kết nối Network trong General/Network Connections :
Active Provider gán là Manual
Kích chọn dòng HTTP trong mục proxy entries và điều chỉnh thông tin để kết nối, chẳng hạn
Host = địa chỉ kết nối (VD : toan.openspace.vn)
Port = cổng kết nối (VD: 9090)
Kích chọn requires authentication
User = LDAP login chẳng hạn (VD : toan)
Password = LDAP password chẳng hạn

Thêm trường hợp vượt trong mục proxy bypass, chẳng hạn để vượt qua địa chỉ có dạng "*.openspace.vn"

* Trong mục Java/Installed JREs/<current JRE>/Edit, có thể tăng thêm dung lượng bộ nhớ bằng cách thêm -XX:MaxPermSize=256m vào 'Default VM Arguments'

* Điều chỉnh việc Eclipse hiển thị lỗi (error) hay cảnh báo trong mục Java/Compiler/Errors&Warnings

3. Một số phím tắt

* Chuyển thành hoa/thường : Chọn chuỗi (string) rồi
Ctrl + Shift + Y --> lower case
Ctrl + Shift + X --> upper case

* Sửa nhanh (Quick fix) : Ctrl + 1
- Chuyển thành hằng (constant) : Chọn chuỗi rồi Ctrl + 1
- Chuyển một biến thành inline : chọn biến rồi Ctrl + 1

* Vào trong lớp/hàm : F3

* Mở nhanh hộp thoại Open Type : Ctrl + Shift + T
* Mở nhanh hộp thoại Open Resource : Ctrl + Shift + R
* Mở hộp thoại Open Type in Hierarchy : Ctrl + Shift + H
* Mở nhanh hộp thoại tìm kiếm (Search) : Ctrl + H

* Đi đến dòng (go to line) : Ctrl + L

4. Một số plugin hữu dụng

MoreUnit :
Ctrl + J để chuyển qua lại giữa một lớp và lớp kiểm thử của nó

Maven 3 : Giới thiệu

 1. Giới thiệu

Apache Maven là công cụ quản lý dự án (project management tool) chủ yếu là các dự án Java dựa trên khái niệm mô hình đối tượng dự án (project object model : POM). Nó cho phép thực hiện các chức năng của một công cụ xây dựng dự án (build tool) như tiền xử lý, biên dịch, chạy kiểm thử, cài đặt, đóng gói, triển khai... (preprocess, compile, test, install, deploy, ...). Ngoài ra nó còn cho phép phát sinh báo cáo kiểm thử (report) và tài liệu (document), quản lý các phụ thuộc (dependency), các plugin, các dự án con...

Lược qua vài nét về Maven, đầu tiên nó nằm trong dự án Jakarta Alexandria, được tách ra thành một dự án riêng mang tên Maven vào năm 2002, đây là Maven 1. Maven 2 ra đời năm 2005 được cải tiến về nhiều mặt như về hiệu năng, tính ổn định và có thêm những tính năng mới, tuy nhiên nó hoàn toàn không tương thích với Maven 1. Năm 2010, Maven 3 chính thức xuất xưởng với phiên bản 3.0, lần này thì nó tương thích với Maven 2.

Muốn hiểu và sử dụng Maven ta cần biết về  : tập tin cấu hình pom.xml; việc sử dụng một số quy ước về cấu trúc dự án và các tên thư mục quy ước của Maven, các tên thư mục này có thể cá nhân hóa (customize) được; vòng đời xây dựng (build lifecycle)

2. Quy ước thay cho cấu hình (Convention Over Configuration)

Maven áp dụng nguyên tắc Quy ước thay cho cấu hình để đơn giản hóa việc cấu hình và đồng nhất cấu trúc của các dự án dùng maven xây dựng. Maven định nghĩa bố cục các thư mục trong dự án mà người dùng phải tuân thủ, tuy nhiên ta cũng có thể cá nhân hóa và thay đổi tên gọi hay vị trí thư mục này theo ý mình. Ngoài định nghĩa các thư mục dự án, nguyên tắc này còn được maven áp dụng trong nhiều tiến trình khác như việc biên dịch, đóng gói dự án, phát sinh web sites, ...

Cụ thể Maven định nghĩa bố cục các thư mục chuẩn trong một thư mục dự án phát triển bằng java trong super POM như sau :
pom.xml                Tập tin cấu hình 
src/main/java          Thư mục chứa mã java
src/main/resources     Thư mục chứa các tập tin tài nguyên khác (.properties, .xml ...)
src/main/filters       Thư mục chứa các tập tin filter ( .properties cho resources)
src/main/assembly      Thư mục chứa miêu tả assembly
src/main/config        Thư mục chứa các tập tin cấu hình
src/main/scripts       Thư mục chứa các tập tin script (.js chẳng hạn)
src/main/webapp        Thư mục chứa mã của ứng dụng web (thư mục WEB-INF, .html, .jsp, ...)
src/test/java          Thư mục chứa mã nguồn phần kiểm thử
src/test/resources     Thư mục chứa các tập tin tài nguyên khác của kiểm thử (.properties...)
src/test/filters       Thư mục chứa các tập tin filter của phần kiểm thử (.properties)
src/site               Site
target                 Thư mục maven phát sinh để chứa các tập tin xuất
target/classes         Thư mục maven phát sinh khi biên dịch dự án
LICENSE.txt            Thông tin bản quyền
NOTICE.txt             Ghi chú về các thông tin cần thiết khác của đề án
README.txt             Thông tin về đề án

3. Vòng đời xây dựng (build lifecycle)

Một vòng đời maven bao gồm một chuỗi có thứ tự các giai đoạn (phase), mỗi giai đoạn định nghĩa một đích (goal). Trong maven có ba vòng đời dựng sẵn (built-in) là clean, default (còn gọi là build) và site. Các vòng đời của Maven được định nghĩa trong tập tin components.xml : Maven 2.xMaven 3.x

Một số giai đoạn được maven mặc định gắn với một đích. Đối với các vòng đời dựng sẵn nói trên, sự gắn kết này phụ thuộc vào việc đóng gói (packaging) artifact (tức project hay dự án). Và nó được định nghĩa trong tập tin components.xml đối với Maven 2.x, còn Maven 3.x thì chúng được định nghĩa trong tập tin  default-bindings.xml. Ta gọi các gắn kết này là các gắn kết vòng đời dựng sẵn (built-in lifecycle bindings).

a. Vòng đời clean
Vòng đời clean xử lý việc làm sạch dự án, tức xóa những thư mục do maven phát sinh trong việc xây dựng dự án, gồm ba giai đoạn theo thứ tự : pre-clean, clean, post-clean

Trong vòng đời clean, giai đoạn clean được định nghĩa trỏ tới đích mặc định là clean:clean , đích này có tác dụng xóa toàn bộ các thư mục phát sinh khi build đề án, cụ thể là thư mục  ${basedir}/target được định nghĩa trong super POM.

Vòng đời clean có định nghĩa một gắn kết vòng đời sau:
clean       -->    clean:clean

Tức khi gõ lệnh mvn clean sẽ tương đương với việc gõ lệnh gọi trực tiếp giai đoạn clean để thực thi đích clean (clean:clean) như sau mvn clean:clean. Lệnh này thực hiện giai đoạn clean và tất cả các giai đoạn trước nó tức là cả pre-clean.

b. Vòng đời default
Vòng đời default nắm việc xây dựng (build) và triển khai (deploy) một dự án, bao gồm một chuỗi các giai đoạn theo thứ tự sau :
validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy

Khi ta thực thi một trong các giai đoạn này, maven không chỉ thực thi giai đoạn đó mà còn thực thi tất cả các giai đoạn đứng trước nó. Chẳng hạn, khi ta thực hiện mvn deploy thì maven sẽ thực thi tất cả các giai đoạn liệt kê ở trên vì deploy là giai đoạn cuối cùng của vòng đời này.

Các gắn kết vòng đời default :
Các gắn kết vòng đời dựng sẵn cho đóng gói ejb / ejb3 / jar / par / rar / war
process-resources        resources:resources
compile                  compiler:compile
process-test-resources   resources:testResources
test-compile             compiler:testCompile
test                     surefire:test
package                  ejb:ejb hay ejb3:ejb3 hay jar:jar hay par:par hay rar:rar hay war:war
install                  install:install
deploy                   deploy:deploy

Các gắn kết vòng đời dựng sẵn cho đóng gói ear
generate-resources     ear:generate-application-xml
process-resources      resources:resources
package                ear:ear
install                install:install
deploy                 deploy:deploy

Các gắn kết vòng đời dựng sẵn cho đóng gói maven-plugin
generate-resources         plugin:descriptor
process-resources          resources:resources
compile                    compiler:compile
process-test-resources     resources:testResources
test-compile               compiler:testCompile
test                       surefire:test
package                    jar:jar và plugin:addPluginArtifactMetadata
install                    install:install
deploy                     deploy:deploy

Các gắn kết vòng đời dựng sẵn cho đóng gói pom
package     site:attach-descriptor
install     install:install
deploy      deploy:deploy

c. Vòng đời site
Vòng đời site nhằm tạo trang tài liệu cho dự án

d. Một số lệnh maven

Trong trường hợp các lệnh sau được gọi tại  thư mục dự án cha, thì các lệnh này sẽ thực thi trên toàn thể các dự án con của dự án này.

Thích ứng hoá thư mục dự án cho eclipse bằng cách phát sinh các tập tin .project .classpath với lệnh sau :
$ mvn eclipse:eclipse

Biên dịch thư mục dự án
$ mvn install

Xoá các tập tin biên dịch trong thư mục target:
$ mvn clean

Có thể kết hợp các lệnh này cùng lúc theo thứ tự (xoá, biên dịch, bỏ qua không thực thi các kiểm thử (test))
$ mvn clean install -DskipTests

Có thể kết hợp các lệnh này cùng lúc theo thứ tự (xoá, biên dịch, thực thi các kiểm thử (test) có tên tận cùng bằng)
$ mvn clean test -Dtest=*<name>

Đóng gói (jar, ear, war) tuỳ theo cấu hình trong tập tin pom.xml
$ mvn package

Đóng gói và không thực thi các kiểm thử (test)
$ mvn clean package -DskipTests

Phân tích sự phụ thuộc giữa các thư viện (jar), có thể dùng để tìm các jar trùng lập:
$ mvn dependency:analyze-report

Giúp giải quyết vấn đề thiếu các thư viện phụ thuộc (bằng cách tải chúng về):
$ mvn dependency:resolve

Hiển thị cây các thư viện phụ thuộc:
$ mvn dependency:tree

4. Tập tin pom.xml

Tập tin pom.xml định nghĩa một dự án (project) : định danh của nó là gì, bao gồm những gì, được đóng gói như thế nào (jar, war, ear ...), có dự án cha hay không, có những phụ thuộc nào ...
Tập tin pom.xml của thư mục gốc parent
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>vn.openspace</groupId>
    <artifactId>parent</artifactId>
    <version>0.1.0</version>
    <packaging>pom</packaging>
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-archetype-plugin</artifactId>
                    <version>2.1</version>
                </plugin>
            </plugins>
        </pluginManagement>
        
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-archetype-plugin</artifactId>
                <version>2.1</version>
            </plugin>
        </plugins>
    </build>
</project>

5. Cài đặt Maven

a. Cài Maven trong Ubuntu
Trước khi cài đặt bằng apt-get, ta cần cập nhật nguồn trước với lệnh sau
$ sudo apt-get update

Sau đó ta có thể kiểm xem gói cần cài đặt (maven2 để tải về maven2; maven3 để tải về maven3) có trong nguồn hay không với lệnh sau:
$ apt-cache search maven3

Cài đặt maven3
$ sudo apt-get install maven3

Gõ lệnh sau để tạo thư mục .m2 tại thư mục gốc
$ mvn

b. Cài Maven 3 trong Windows
Maven cần có Java đã được cài đặt và biến môi trường JAVA_HOME (=C:\Program Files\Java\jdk1.7.0_51 chẳng hạn) đã được định nghĩa để có thể hoạt động.

Tải maven về tại đây http://maven.apache.org/download.cgi

Ở đây tôi tải phiên bản apache-maven-3.1.1-bin.zip , sau đó giải nén gói này tại thư mục D:\maven chẳng hạn.

Rồi thêm vào cuối biến môi trường Path đường dẫn đến ";D:\maven\apache-maven-3.1.1\bin". Sau đó để kiểm tra maven đã hoạt động hay chưa ta mở một màn hình lệnh command line (cmd) và gõ lệnh sau :
$ mvn -version
Lệnh này cho biết phiên bản của maven, đường dẫn đến Maven home và Java home mà ta đã định nghĩa trong biến môi trường.

6. Dùng archetype để tạo các dự án

Một số archetype :

org.apache.maven.archetypes:maven-archetype-archetype (An archetype which contains a sample archetype.)
org.apache.maven.archetypes:maven-archetype-j2ee-simple (An archetype which contains a simplifed sample J2EE application.)
org.apache.maven.archetypes:maven-archetype-marmalade-mojo (-)
org.apache.maven.archetypes:maven-archetype-mojo (An archetype which contains a sample a sample Maven plugin.)
org.apache.maven.archetypes:maven-archetype-plugin (An archetype which contains a sample Maven plugin.)
org.apache.maven.archetypes:maven-archetype-plugin-site (An archetype which contains a sample Maven plugin site. This archetype can be layered upon an    existing Maven plugin project.)
org.apache.maven.archetypes:maven-archetype-portlet (An archetype which contains a sample JSR-268 Portlet.)
org.apache.maven.archetypes:maven-archetype-profiles (-)
org.apache.maven.archetypes:maven-archetype-quickstart (An archetype which contains a sample Maven project.)
org.apache.maven.archetypes:maven-archetype-site (An archetype which contains a sample Maven site which demonstrates some of the supported document types like APT, XDoc, and FML and demonstrates how to i18n your site. This archetype can be layered upon an existing Maven project.)
org.apache.maven.archetypes:maven-archetype-site-simple (An archetype which contains a sample Maven site.)
org.apache.maven.archetypes:maven-archetype-webapp (An archetype which contains a sample Maven Webapp project.)


org.codehaus.mojo:gwt-maven-plugin (Maven plugin for the Google Web Toolkit.)
org.codehaus.mojo:javascript-ria-archetype (A JavaScript Rich Internet Application template using jQuery and jQuery UI.)
org.codehaus.mojo.archetypes:appclient-javaee6 (-)
org.codehaus.mojo.archetypes:appclient-javaee7 (Archetype for an Application Client package using Java EE 7.)
org.codehaus.mojo.archetypes:appclient-jee5 (-)
org.codehaus.mojo.archetypes:appframework (Archetype for creating application based on JSR 296)
org.codehaus.mojo.archetypes:ear-j2ee14 (-)
org.codehaus.mojo.archetypes:ear-javaee6 (-)
org.codehaus.mojo.archetypes:ear-javaee7 (Archetype for EAR package using Java EE 7)
org.codehaus.mojo.archetypes:ear-jee5 (-)
org.codehaus.mojo.archetypes:ejb-j2ee13 (-)
org.codehaus.mojo.archetypes:ejb-j2ee14 (-)
org.codehaus.mojo.archetypes:ejb-javaee6 (-)
org.codehaus.mojo.archetypes:ejb-javaee7 (Archetype for an EJB package using Java EE 7.)
org.codehaus.mojo.archetypes:ejb-jee5 (-)
org.codehaus.mojo.archetypes:javafx (Archetype for creating a JavaFX application)
org.codehaus.mojo.archetypes:nbm-archetype (Archetype for development of NetBeans modules in Maven.)
org.codehaus.mojo.archetypes:nbm-osgi-archetype (Archetype for development of NetBeans modules that can depend on OSGi bundles.)
org.codehaus.mojo.archetypes:nbm-suite-root (Root project archetype for creating multi module projects developing NetBeans IDE modules. Approximately similar in functionality to module suites in NetBeans Ant projects.)
org.codehaus.mojo.archetypes:netbeans-platform-app-archetype (Archetype for sample application based on NetBeans Platform. Creates parent POM with branding and empty NBM project.)
org.codehaus.mojo.archetypes:osgi-archetype (Archetype for development of OSGi bundles using Apache Felix Maven plugin)
org.codehaus.mojo.archetypes:pom-root (Root project archetype for creating multi module projects)
org.codehaus.mojo.archetypes:sample-javafx (Sample archetype for creating a JavaFX application)
org.codehaus.mojo.archetypes:webapp-j2ee13 (-)
org.codehaus.mojo.archetypes:webapp-j2ee14 (-)
org.codehaus.mojo.archetypes:webapp-javaee6 (-)
org.codehaus.mojo.archetypes:webapp-javaee7 (Archetype for a web application using Java EE 7.)
org.codehaus.mojo.archetypes:webapp-jee5 (-)


Chú ý lần đầu tiên dùng maven, trong trường hợp này là ta gọi lệnh mvn  archetype:generate, ta sẽ thấy hơi lâu vì Maven sẽ tải về các thư viện jar và các plugin nó sử dụng. Những lần sau sẽ nhanh hơn nhiều vì những thư viện này đã được lưu lại trong local repository tức thư mục .m2

7. Cấu hình Maven

Mặc định maven sẽ tải các thư viện từ central repository. Nếu muốn cấu hình repository, ta tạo tập tin settings.xml (trong đó định nghĩa repository) tại vị trí ~/.m2/settings.xml (~ là vị trí thư mục gốc của người dùng, trong Windows là C:\Users\<thư mục người dùng> chẳng hạn)

Một ví dụ về tập tin settings.xml
<?xml version="1.0" encoding="UTF-8"?>
<settings>
  <mirrors>
    <mirror>
      <id>internal</id>
      <mirrorOf>*</mirrorOf>
      <url>http://path-to-repository</url>
    </mirror>
  </mirrors> 
  <servers>
      <server>
          <id>remote-repository</id>
          <username>toan</username>
          <password>toan</password>
      </server>
  </servers>
</settings> 

9. Thuộc tính của maven (Maven properties)
Thuộc tính trong maven bao giờ cũng được bao giữa ${}. Ta có thể dùng các thuộc tính định nghĩa trước của Maven hoặc tự định nghĩa các thuộc tính trong tập tin pom.xml hoặc các tài nguyên khác mà maven sử dụng, chẳng hạn maven settings, maven profiles ....

a. Thuộc tính project (maven project properties)
 Ta có thể dùng tiền tố project.* để tham chiếu đến các giá trị định nghĩa trong tập tin pom (kể cả parent pom).

Đồng thời tiền tố này có thể dùng để tham chiếu đến các thuộc tính của org.apache.maven.model.Model, chẳng hạn khi ta dùng ${project.build.directory} là tương đương với việc gọi hàm model.getBuild().getDirectory()

Sau đây là danh sách một số thuộc tính thường dùng theo cách vừa kể :
${project.groupId}
${project.version}
${project.artifactId}
${project.name}
${project.description}
${project.build.sourceDirectory} 
${project.build.scriptSourceDirectory}    
${project.build.testSourceDirectory}     
${project.build.outputDirectory}     
${project.build.testOutputDirectory} 
${project.build.directory}
${project.build.finalName}
${project.baseUri}
${project.parent} : giá trị trỏ đến đề án cha

b. Thuộc tính settings (maven settings properties)
Dùng tiền tố settings.* để tham chiếu đến các giá trị định nghĩa trong  ~\.m2\settings.xml. Chẳng hạn:
${settings.localRepository}

c. Thuộc tính biến môi trường (environnement variables properties)
Dùng tiền tố env.* để tham chiếu đến các giá trị của biến môi trường.Chẳng hạn
${env.PATH} : giá trị biến môi trường Path
${env.HOME} : trỏ đến thư mục gốc của người dùng
${env.JAVA_HOME} : trỏ đến thư mục cài đặt java định nghĩa trong biến môi trường
${env.M2_HOME} : trỏ đến thư mục cài đặt maven định nghĩa trong biến môi trường

d. Thuộc tính hệ thống của Java (Java system properties)
Maven cho phép truy xuất các thuộc tính của java.lang.System. Các thuộc tính có thể dùng dưới dạng gọi phương thức System.getProperty(), thì ta có thể tham chiếu đến nó bằng thuộc tính maven. Danh sách các thuộc tính hệ thống Java :

${java.version} : Java Runtime Environment version
${java.vendor} : Java Runtime Environment vendor
${java.vendor.url} : Java vendor URL
${java.home} : Java installation directory
${java.vm.specification.version} : Java Virtual Machine specification version
${java.vm.specification.vendor} : Java Virtual Machine specification vendor
${java.vm.specification.name} : Java Virtual Machine specification name
${java.vm.version} : Java Virtual Machine implementation version
${java.vm.vendor} : Java Virtual Machine implementation vendor
${java.vm.name} : Java Virtual Machine implementation name
${java.specification.version} : Java Runtime Environment specification version
${java.specification.vendor} : Java Runtime Environment specification vendor
${java.specification.name} : Java Runtime Environment specification name
${java.class.version} : Java class format version number
${java.class.path} : Java class path
${java.ext.dirs} : Path of extension directory or directories
${os.name} : Operating system name
${os.arch} : Operating system architecture
${os.version} : Operating system version
${file.separator} : File separator ("/" on UNIX, "\" on Windows)
${path.separator} : Path separator (":" on UNIX, ";" on Windows)
${line.separator} : Line separator ("\n" on UNIX and Windows)
${user.name} : User’s account name
${user.home} : User’s home directory
${user.dir} : User’s current working

e. Một số thuộc tính tiền định nghĩa khác
${basedir} : trỏ đến thư mục đang chứa tập tin pom.xml
${version} : tương đương với ${project.version}

f. Thuộc tính người dùng định nghĩa

Người dùng có thể định nghĩa các thuộc tính trong thẻ properties trong tập tin pom.xml, chẳng hạn như sau :
<project>
...
  <properties>
     <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
  </properties>
...
</project>

Khi đó ${endorsed.dir} có giá trị là "./target/endorsed"; thư mục  này nằm trong thư mục gốc của dự án.



Ubuntu : Một số lệnh

1. Cài đặt một chương trình

$ wget package.tar.gz
$ tar xvzf package.tar.gz
hay $ tar xvjf package.tar.bz2
$ cd package
$ ./configure
$ make
$ make install
$ make clean

2.Liên quan đến tập tin
So sánh hai tập tin
$ meld file1 file2

Tìm tập tin từ thư mục gốc theo tên
$ find . -name filename.xml
hay
$ locate slapd.conf

Tìm tập tin của một lệnh
$ whereis ldapsearch

Tìm chuỗi trong toàn bộ các tập tin trong thư mục và thư mục con
$ grep -r "searched string" *


3. Liên quan đến process và cổng (port)
Tìm process của prostgresql
$ ps -ef | grep postgresql

Kiếm một process tương ứng với một service :
$ ps aux | grep l[d]ap

Kiểm tra một chương trình có đang chạy hay không (ở đây là varnish):
$ ps aux | grep varnish

Tìm cổng của một dịch vụ được cài :
$ lsof -i | grep l[d]ap
hay
$ netstat -autp | grep l[d]ap

Tìm cổng đăng ký của một service :
$ grep ldap /etc/services

Kiểm tra chương trình có đang xài một cổng nào đó hay không (ex: 8080):
$ lsof -i:8080

4. Kết nối từ xa
Lấy tập tin từ máy từ xa :
$ scp root@openspacevn.local:/root/ldap_update /platform/home/user/

Gởi tập tin đến máy từ xa:
$ scp jdk-6u29-linux-x64.bin root@openspacevn.local:/root

Hoặc xài sftp:
$ sftp root@10.1.15.125
$ sftp> get export.ldif

Kết nối ssh đến máy từ xa :
$ ssh root@10.1.15.125
$ logout

5. Chương trình và bộ nhớ
Kiểm tra xem chương trình đã được cài trên máy hay chưa :
$ rpm -qa | grep ldap

$ rpm -q --whatprovides /usr/bin/ldapsearch
$ rpm -v openldap_clients

Xem thông tin bộ nhớ:
$grep MemTotal /proc/meminfo
$grep SwapTotal /proc/meminfo

test available memory:
Bộ nhớ chia sẻ chưa dùng (available):
$ df -k /dev/shm/

Dung lượng bộ nhớ còn trống trong tmp directory
$ df -h /tmp

Xem  thông tin toàn bộ không gian ổ đĩa còn trống:
$ df -h

Xem thông tin phiên bản của ubuntu:
$ more /etc/*-release
$ lsb_release -id
$ lsb_release -a

Xem thông tin phiên bản của lõi linux:
$ uname -rms
$ uname -a

6. Liên quan đến mạng và kết nối
Kiểm tra có thể kết nối tới một địa chỉ hay không, thay <ip adress> bằng địa chỉ muốn kiểm tra:
$ ping <ip addresse>

Kiểm tra server DNS đã được cấu hình (đúng) chưa (ở đây bằng cách hỏi tên miền của google) :
$ nslookup google.com

Thêm server DNS bằng cách sửa tập tin resolv.conf:
$ sudo gedit /etc/resolv.conf
Sau đó thêm địa chỉ server bằng cách thêm dòng sau vào cuối tập tin, thay <ip dns server> bằng địa chỉ ip của server DNS:
nameserver <ip dns server>

7. Tập tin .profile
Sửa tập tin .profile:
$ gedit .profile

Cập nhật thông tin vừa thay đổi trong tập tin .profile:
$ source .profile

8. Java
Mở Java Control Panel:
$ ControlPanel

9. Dùng cURL
Ví dụ thực hiện truy vấn POST:
curl -X POST \
  http://openspacevn.com/oauth2/token \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/x-www-form-urlencoded' \
  -d 'grant_type=client_credentials&client_id=XXX&client_secret=XXX'