June 29, 2014

AWS EC2 Load Balancer上設定SSL憑證

前一篇文章中提到了在AWS EC2上建立load balancer (以下簡稱LB)的方法,當時是以HTTP做分流為範例。我的開發環境中,SSL憑證是直接安裝在web server (IIS)上的,而EC2提供的LB具有SSL offloading的機制,可以直接把SSL憑證安裝在LB上,減輕web server加解密資料的負擔。

接續前面的設定,新增一筆listener。


Load Balancer Protocol選取HTTPS (Secure HTTP),點選SSL Certificate欄位裡的Change


可以看到頁面要求輸入憑證的相關資訊,如Private Key和Public Key Certificate,而且是*.pem格式。由於目前已經有SSL憑證安裝在IIS上,所以我必須先把憑證匯出成*.pfx再轉換成*.pem,並取出Private Key和Public Key Certificate。


將*.pfx轉換成*.pem需要借助OpenSSL,可至http://slproweb.com/products/Win32OpenSSL.html下載Windows專用的OpenSSL工具,在此下載Win64 OpenSSL v1.0.1h Light安裝。安裝完後在C:\OpenSSL-Win64\bin下會看到openssl.exe檔案。


準備好匯出的憑證,如G:\test.pfx。以管理者身份開啟Command Prompt,輸入C:\OpenSSL-Win64\bin\openssl.exe pkcs12 -in G:\test.pfx -out G:\test.pem -nodes及憑證匯出時所設定的密碼將*.pfx轉換成*.pem格式。


接下來輸入C:\OpenSSL-Win64\bin\openssl.exe x509 -in G:\test.pem -out G:\test_public.txt產生Public Key Certificate


接下來輸入C:\OpenSSL-Win64\bin\openssl.exe rsa -in G:\test.pem -out G:\test_private.txt產生Private Key


最後將G:\test_private.txt內容複製到Private Key欄位中,而G:\test_public.txt內容複製到Public Key Certificate欄位中。這裡要特別注意的是,檔案內容中如-----BEGIN RSA PRIVATE KEY-----和-----END RSA PRIVATE KEY-----皆需放至欄位中,否則無法設定成功。


輸入完後按下Save完成所有設定




參考
  1. Converting a .pfx/.p12 ("PKCS #12") file to certificate and key
  2. Install Wildcard Certificate onto AWS EC2 Load Balancer

June 15, 2014

AWS EC2上設定Load Balancer

目前團隊的開發和測試環境是放在AWS (Amazon Web Services) EC2上,最近因為專案需要在load balance的環境下運行,所以直接在EC2上設定環境,設定的過程相當簡單且快速。

先到EC2 Dash board,點選左邊選單的Load Balancers


點選Create Load Balancer


輸入Load Balancer name,預設會有HTTP加入設定,也可新增其它設定如HTTPS (Secure HTTP、TCP和SSL (Secure TCP)。點選Continue


預設load balancer透過監聽HTTP port 80下的某支檔案來判斷instance是否還有效。


不過我改以TCP監聽port 80,主要是之前使用過Rackspace的load balancer (Broadcade)經驗,當時以檔案來監聽,load balancer會以HTTP status code是否為200來判別檔案是否存在,所以load balancer在第一次存取檔案時會取得200。但因為cache的關係,load balancer第二次存取檔案時會取得304而判定instance失效。設定完成後點選Continue


選擇要加入要使用load balance的instance,點選Continue


點選Create開始建立load balancer




建立完成後會顯示成功訊息,點選Close


完成設定後AWS會分配3組domain name給load balancer,接下來只要到你的domain name provider或是Route 53內將原先的domain name設定CName對應到load balancer提供的domain name即可。



June 14, 2014

使用Fluent Assertions提昇測試程式可讀性

目前團隊所使用的unit testing framework為NUnit。在NUnit裡如果要做assertion的話可以這樣寫
[Test]
public void Can_Add_Integer()
{
    int total = Calculator.Add(1, 2);
    Assert.AreEqual(3, total);
}

上面的Assertion閱讀起來不難懂,可以理解是在測試total與3是否相等。然而對開發人員在撰寫程式碼時卻有個小問題,Assert.AreEqual(3, total)Assert.AreEqual(total, 3)意義相同嗎?看一下NUnit提供的說明可以知道第一個參數要代入的是預期該得到的數值,而第二個參數是實際運算完後的數值。


當assertion永遠成功時,Assert.AreEqual(3, total)Assert.AreEqual(total, 3)看起來沒什麼差別。但在assertion失敗時,意義上就不一樣了,因為NUnit提供的失敗訊息會有很大差別。如

Assert.AreEqual(3, total)


Assert.AreEqual(total, 3)


以上是NUnit提供的Classic Assert Model。事實上NUnit還有提供另一種assertion方式稱為Constraint Model,如
[Test]
public void Can_Add_Integer_Using_Constraints()
{
    int total = Calculator.Add(1, 2);
    Assert.That(total, Is.EqualTo(3));
}

用以上方式撰寫assertion程式碼在閱讀上易讀許多。

雖然Constraint Model已提供可讀性不錯的撰寫方式,但每次要使用時還是得先Assert.That,而且有時NUnit提供的除錯訊息不是那麼清楚。基於以上因素,便出現Fluent Assertions這套函式庫來強化NUnit(或其它framework)在assertion上的不足。

將上述的assertion改以Fluent Assertions重新撰寫可以得到更簡潔的assertion
[Test]
public void Can_Add_Integer_Using_FluentAssertions()
{
    int total = Calculator.Add(1, 2);
    total.Should().Be(3);
}

寫成一行閱讀起來也很清楚,就如同說話一般
[Test]
public void Can_Add_Integer_Using_FluentAssertions()
{
    Calculator.Add(1, 2).Should().Be(3);
}
有時我們需要驗證功能是否有正確拋出例外,也可以Fluent Assertions來撰寫如
[Test]
public void Cannot_Subtract_And_Throw_NotSupportedException()
{
    Action action = () => Calculator.Subtract(5, 3);
    action.ShouldThrow<NotSupportedException>().WithMessage("Not yet implemented");
}

Fluent Assertions提供的assertion很豐富也簡潔易懂,目前我所在團隊已將原本NUnit的assertion全部換成使用Fluent Assertions,效果還不錯,在撰寫assertion程式碼時速度快了許多也沒遇到太大的問題。