星期四, 6月 22, 2017

IBM MobileFirst 7.1 拒絕存取


延續之前 MobileFirst 7.1 的 Server Farm 機制無法正常啟用,經過好一陣子與 IBM Lab 之間的往返,還是沒有一個好的解決方案。


所以,只好考慮直接裝一套新的 Server,並且把專案移轉到新的伺服器上來。
但是,在移轉之後卻出現如上圖所示的錯誤。

因為,通常我們會在 App 啟動時,使用 WL.Client.connect 與 MobileFirst 伺服器連線,以確認 Client 與 Server 之間的版本,並檢查管理者有沒有設定任何通知訊息。

但是,在移轉後,App 端會出現「Access Denied」的錯誤,無法正常啟動 App。

伺服器端,也可以觀察到下列的錯誤訊息:
FWLSE0335E: Authorization failed: 
ClientId f5ac9a8cda443cfca33d1e7f926a71f90f8c67a1 was not found 
on the server.
這個情況,可以透過移除該 App 並且重新安裝,來解除此問題。

所以,我們大概可以推測,MobileFirst 的 Client 端在跟 Server 連結之後,會在手機端留下一些資訊。這些資訊,應該是 MobileFirst 用來確保安全的機制。

1. 可以避免,我們連接到的 Server 與之前的不同
2. 從伺服器端的角度來看,如果先前該手機已經跟伺服器註冊過。但是,現在我們卻無法在伺服器上找到該 ClientId 的話。這個裝置是不是該被視為有問題的裝置。

當然,這種安全機制,有時候還是會造成我們的困擾。

所以,為了避免要求大量使用者重新安裝 App,我們可以採取下列兩種方案,來解決此問題。

1. 在 MobileFirst 7.1 之後,與先前開始有所不同,採用 Session Independent 作為伺服器運作的預設機制。當採用 Session Independent 時,MobileFirst 的相關資訊就會被存於資料庫中。所以,必須調整 MobileFirst 處理 Session 的機制,讓資訊是存於記憶體之中。這樣,就可以解決上述遇到的問題。但是,當採用這樣的機制,勢必會影響到後續 Server 做平行的擴充。所以,除非是以單一機器提供服務,不然不建議採用這個解決方案。

2. 既然,App 移除重裝之後就可以解決此問題。那麼,就是需要在程式中加上一段清除手機上暫存的這些資訊,如此就可以使 App 恢復正常運作。經測試,先前假設沒錯,就是有一段資料被存在手機上。移除之後,就可以正常與伺服器連線。

「參考資料」
1. MobileFirst 7.1 Server Access Denied when using WL.Client.connect API

星期一, 3月 27, 2017

IBM MobileFirst 7.1 WebSphere Liberty Server Farm Unresponsive

前一陣子有客戶反應,他們公司的 MobileFirst Server 無法正常啟動。

於是,開始這段伺服器搶救的過程。

1. 因為 console.log 及 message.log 中都沒有紀錄錯誤訊息,所以為了看更多的資訊,必須打開 trace.log

需要再 server.xml 中加上下列資訊,就可以產生 trace.log 了!
<logging maxfiles="10" maxfilesize="20" 
         tracefilename="trace.log" 
         traceformat="BASIC" 
  tracespecification="com.worklight.*=all:com.worklight.*=all:*=info">
</logging>
中間經歷了很多次重開的過程,Server 就是無法順利啟動。

在沒辦法之下,我只好使用 MobileFirst 的 Configuration-Tool 試著用 update 的方式,中置一下 worklight admin 服務及 runtime environment 的三個 war 檔案。

突然,其中一部 Server 正常啟動了。

心想,應該修好了!

結果在啟動另一個 Server 時,卻卡住了!

這時候剛剛啟動的 Server 也無法正常運作。

觀察一下 tracelog,後來我發現每 30 秒會出現一次下列紀錄

com.worklight.core.clustering.ClusterSynchronizationTask
解到這邊,我一直觀察資料庫內的資料跟伺服器運作的模式。
感覺,就是同步作業失敗,然後一直重做。

上網找了一下資料,看起來跟這個問題比較像的是:
IBM MobileFirst 7.1.0 Liberty Server Farm Unresponsive

但是,內文也是說重建 Server Instance 跟重新設定 Server Farm 就好了!

目前,重建後只能讓單一伺服器恢復運作。
只要想同時啟動 Server Farm 中的兩個伺服器,就會陷入同步失敗的問題。

現在還在等 IBM 原廠回覆此問題的正確解法。

星期二, 8月 09, 2016

Kendo Grid 教學 4 - 解決 REST Service 回應 HTTP 403

在先前「RestTemplate 無法呼叫 Rest Service」的文章中有提到,有些後台被 Spring Security 保護著,並啟用 Cross-site request forgery (CSRF) 的保護機制,並免他人因為知道服務的端點,就可以直接呼叫相關的服務。

Kendo UI 可以透過 Datasource 中 transport 的屬性設定,可以完成資料的讀取及寫入工作。針對新增、修改、刪除及查詢的部分,分別提供 create、update、destory 及 read 的 function 來進行相關作業的處理。
    transport:{
        create:{...},
        update:{...},
        destroy{...},
        read{...}
    }
開發人員可透過上述設定,完成 kendo grid 上 CRUD 的相關動作。

但是,當我們碰上後端具有 CSRF 保護的服務時,可能會出現 「HTTP 403 : Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'」的錯誤訊息。

這代表,我們正常地呼叫後端的服務。以整合 Spring Security 來說,當我們完成登入後,可以從 Request Header 中觀察到,HTTP Request 都會帶著兩個 Cookies 的資訊,分別是 JSESSIONID 及 XSRF-TOKEN 資訊。

然後,我們再看一下錯誤的訊息「HTTP 403 : Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'」。看起來,後端要的服務需要我們的 Header 送一個 X-CSRF-TOKEN 的資訊過去。上網找一下參考資料「Invalid CSRF Token 'null' 解決方案」看起來也是這樣說明沒錯。而且,X-CSRF-TOKEN 的內容跟 XSRF-TOKEN 一樣 (一樣的東西,底層竟然沒有自己處理掉 .... 看來還要找時間看看到底為什麼有這樣的限制)。 

所以,接著要思考的是如何在 Kendo Grid 呼叫後端服務時,將  X-CSRF-TOKEN 動態的塞入。後來,我在 「Transport and basic authentication」找到了解答。我們可以在 create、update、destroy 跟 read 等方法上加上 「beforeSend」的方法來加入 X-CSRF-TOKEN。

beforeSend: function(req){
    req.setRequestHeader('X-XSRF-TOKEN', $cookies.get('XSRF-TOKEN'));
}
如此一來,就可以正常使用後端服務了!

[參考資料]
1. 跨網站請求偽造
2. Invalid CSRF Token 'null' 解決方案
3. Transport and basic authentication

星期一, 8月 08, 2016

RestTemplate 無法呼叫 Rest Service

最近有人問我一個問題,現象是他的應用程式呼叫被 Spring Security 保護的服務時,如果未將 csrf disable,系統就無法正常運作。

Spring Security 啟用 CSRF 後可保護 Server Side 的 Resource,避免跨網域攻擊 (從別的機器發出 Request 以取得後端的資訊)。所以,當 Spring Security 啟用 CSRF 後,我們會在前端的頁面加上

   <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>

以便,證明我們是從同一個網域發送的請求。

然而,這個問題卻不是上述原因造成!第一時間的猜想錯誤,所以我就開始檢視程式碼內容,來看看到底那邊出了問題。

後來,發現在後端的程式中有一段使用 RestTemplate 去呼叫 REST 服務。基本上,如果在內部應該可以直接呼叫相關的物件,而不需要透過 RestTemplate 來進行呼叫 (多繞了一圈)。不過,依照範例來看是個教學程式,所以就先不討論合理性的問題。

RestTemplate 其實是一個增強化的 HTTP Client ,所以在使用 RestTemplate 時我們可以想像自己開了一個新的瀏覽器,然後存取該服務。此時,RestTemplate 中根本就沒有儲存相關的 Session。因為他的 Request 中沒有帶任何經過驗證的資訊。所以,會被 Spring Security 視為不合法的存取。

我們必須在 RestTemplate 中加入一些資訊,才可讓這個呼叫合法。相關資訊,可參考下列參考資訊的網址。

HttpHeaders headers = new HttpHeaders();
headers.add("cookie", req.getHeader("cookie"));
HttpEntity requestEntity = new HttpEntity(null, headers);
ResponseEntity rssResponse =
restTemplate.exchange( your_service_url,
HttpMethod.GET,
requestEntity, List.class);
1. 建立 HttpHeader 物件,並將 request header 中的 cookie 值取出,設定到自己建立的 HttpHeader 中。(因為 Session 就存在這裡)

2. 建立 HttpEntity 物件,並利用先前建立的 HttpHeader 進行初始化。

3. 使用 restTemplate 呼叫後端服務,取得 ResponseEntity 以進行後續邏輯運算


[參考資料]

星期三, 8月 03, 2016

Kendo Grid 教學 3 - 建立新增功能

在 「Kendo Grid 教學 2 - Inline Edit」的文章中提到怎麼樣進行 inline edit 的工作。但是,以先前提供的範例來看,並未交代如何進行新增的作業。

但是,如果有依據參考資料進入 「Kendo Grid Grid Inline Edit Demo」檢視範官方的範例程式的話,應該已經發現如何把「Add New Record」的按鈕加上去。

$scope.mainGridOptions = {
    dataSource: $scope.datasource,
    pageable: true,
         height: 300,
toolbar: ["create"],
    columns: [
     { field: "id",  title: "商品編號", width: "120px"},
     { field: "name", title: "商品名稱", width: "120px" },
      { field: "price", title: "商品價格", width: "120px"},
{ command: ["edit", "destroy"], title: "&nbsp;", width: "250px" }
          ],
editable: 'inline'
};
};
在原本 mainGridOptions 中,加入 toolbar 的元素,並指定要使用 create 功能,就可以像官方的範例,有一個 「Add New Record」的按鈕。

當這個按鈕按下去之後,以 inline 編輯模式來看,Kendo Grid 的第一行會進入編輯模式,讓我們輸入資料後進行新增作業。

[參考資料]
1. Kendo Grid Grid Inline Edit Demo

星期三, 7月 27, 2016

Kendo Grid 教學 2 - Inline Edit

在 「Kendo Grid 教學 1 - 建立列表」的文章中,有兩個主要的變數要設定,以便讓 Kendo Grid 可以運作起來,並透過 Rest Service 拿到列表資訊。分別是 datasource 與 mainGridOptions。

Datasource

其中,datasource 可以看作是 kendo grid 的資料來源。在先前的文章中,設定了 transport 與 schema  兩個主要屬性。

transport


透過 transport 的屬性設定,可以完成資料的讀取及寫入工作。針對新增、修改、刪除及查詢的部分,分別提供 create、update、destory 及 read 的 function 來進行相關作業的處理。
    transport:{
        create:{...},
        update:{...},
        destroy{...},
        read{...}
    }
開發人員可透過上述設定,完成 kendo grid 上 CRUD 的相關動作。

schema

Schema 在 Datasource 中扮演兩個重要的角色:

  1. 透過 schema.model.fields 定義 kendo grid 的資料模型,設定排序 (sorting)、篩選 (filtering),並確保使用對應的編輯元件,例如: 數字輸入框對應到數字型別的資料。
  2. 透過 schema.model.id 定義 kendo grid 中的 id 欄位,以確保新增、修改、刪除等工作可以正確執行。

schema: {
      model: {
           id: "id", 
           fields: {
                 id: { editable: false, nullable: true, defaultValue: null},
                 name: {validation: { required: true }},
                 price: { type: 'number', defaultValue: 0, validation: { required: true, min: 0}}
           }
       }
}



parameterMap

在 Kendo Grid 與後端服務整合的部分,透過設定可以採用 json, jsonp, odata 等不同資料模式。所以,在請求資料 (request) 真的往後送之前,我們需要透過 parameterMap function 幫我們處理資料的轉置問題。

下列為,parameterMap 中的範例程式。因為 read 方法不需要傳參數即可拿到資料,所以在範例程式中,我們把 read 方法過濾掉。然而,在 create, update 及 destory 的部分,我們將前端 Form 內的第一個元素取出 (因為 options.models 預設是 array),並將其當作參數往後面的服務拋送。

parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
        return JSON.stringify(options.models[0]);
     }
 }


mainGridOptions


在前一篇文章中,我們有看到下列 mainGridOptions 之設定。設定的內容可以進一步分成幾個區塊。


  1. 設定 datasource,作為 kendo grid 的資料來源
  2. 利用 pageable 設定是否分頁
  3. 透過 height 設定 kendo grid 的高度
  4. 透過 columns 設定 kendo grid 的表頭應該呈現什麼
    4.1. filed 的設定會與 datasource 底下 schema 內的 fields 做呼應,相同名稱的會對在一起,是一種透過設定抓相對應資料的概念。
  5. columns 中還有一個設定為 command,在每一列上會顯示編輯 (edit) 與刪除 (destory) 的按鈕
  6. editable 設定為 inline 代表該 grid 會使用 inline 的方式進行編輯作業
      其中,標紅色字樣的部分是本次要做 inline edit 新加的部分


$scope.mainGridOptions = {
    dataSource: $scope.datasource,
    pageable: true,
         height: 300,
    columns: [
     { field: "id",  title: "商品編號", width: "120px"},
     { field: "name", title: "商品名稱", width: "120px" },
      { field: "price", title: "商品價格", width: "120px"},
{ command: ["edit", "destroy"], title: "&nbsp;", width: "250px" }
          ],
editable: 'inline'
};
};

建立對應新增、修改、刪除、查詢的方法

在本文前面有提到 datasource 中的 transport 就是讓我們進行 create、update、destory 及 read 的 function 撰寫。

在本文中,以 update 為例:

1. url : 記錄遠端服務的端點
2. type:  使用 HTTP  通訊協定的方法 (例如:GET, PUT, POST, DELETE 等)
3. contentType 傳輸內容的類型
4. complete function: 服務呼叫成功後,要做的相關動作可以寫在此處
5. error function: 服務呼叫失敗後,要做的相關動作可以寫在此處

update: {
     url: "your service endpoint",
     type: "PUT",
     dataType: "json",
     contentType: 'application/json',
     complete: function (data) {
// 呼叫服務成功後,要做什麼事
     },
     error: function (xhr, error) {
         // 呼叫服務失敗後,要做什麼事
     }
}

其他,關於 destory 及 create 也是採用相同的方式進行撰寫。雖然,在這裡並沒有說明如何建立一筆新的資料。但,後面還會有其他文章提到。

備註:
我們做 Rest Service 的時候,可能經常將 create、update 及 delete 的 method 預設為不回傳值。以 Java 來說,就是宣告回傳的是 void。

但是,這樣可能會導致 kendo grid 不 work。所以,我們必須回傳一個 JSON 字串回來。針對,create 及 update 的方法,需要回傳新增或是更新的那個物件回來。避免 kendo grid 呈現一個空白列在那邊。

有關 inline edit 的實際 demo,可以進一步參考官網上 Inline Edit 的範例。

「參考資料」
1. Kendo Grid CRUD Data Operation
2. Kendo Grid Grid Inline Edit Demo

Kendo Grid 教學 1 - 建立列表

近年來,前端 javascript 的技術突飛猛進,有許多的 framework 出現,學都學不完。而在,公司的專案需求上,我們需要開始研究 Kendo UI 這套框架。

Grid View 是我們建置 Web 應用程式中相當常用的 UI 元件。記得十多年前,同時接觸 .NET 與 Java 時,總覺得為什麼 .NET 上做一個 Grid View 相當容易,而在 Java 上卻需要自己寫那麼多程式。一個 Page 一個 Page  一直寫著重覆類似的程式碼。

雖然知道,這裡應該要被元件化,但始終沒有下手去做這類整理的事。那時候,還是以 Server Page 為主的時代。AJAX 的興起是在那之後兩三年的事情。

而到了現在,檯面上已經有非常多這種前端的元件,而且透過 javascript 技術的發展。現在,前端的頁面已經鮮少使用 Server Page 相關的 Tag 。而改由 HTML5 + javascript + css 來進行所有的事情。至於後端採用什麼語言 (C#, Java or PHP) 似乎已經沒那麼重要,也徹底實現 Web 端的 MVC 概念。

底下,我們就建立一系列的文章,來探討使用 Kendo UI 的心路歷程:

1. 下載 kendo ui 的相關套件 Kendo UI Download Free Trial
 
解壓縮後,將套件內的 js 與  styles 資料夾放到專案目錄中。以我自己的範例來看,這兩個資料夾放在 [your project]/webapp/resources/lib/ui/ 底下。

2. 下載 kendo.all.min.js

我是認為 kendo.all.min.js 應該涵蓋在第一步驟中所下載的內容裡。但是,不知道為什麼沒有。可能這樣可以收一點顧問費,畢竟它是需要付費的!所以,只好從官網的範例偷偷把 js 檔載回來。一樣放在 [your project]/webapp/resources/lib/ui/ 底下。

此使,該目錄下有 js 及 styles 兩個資料夾再加上 kendo.all.min.js 這個檔案。

3. 建立後端 RESTFUL Services,讓 Service 回傳下列這串 JSON 訊息回來

[
  {"id":4,"name":"Starbucks","price":300},
  {"id":5,"name":"BrownCafe","price":200},
  {"id":6,"name":"CityCafe","price":100}
]
4. 撰寫前端頁面

4.1. CSS 與 JS 引用之宣告

<link rel="stylesheet" href="./resources/scripts/lib/ui/styles/kendo.common.min.css" />
<link rel="stylesheet" href="./resources/scripts/lib/ui/styles/kendo.default.min.css" />
<link rel="stylesheet" href="./resources/scripts/lib/ui/styles/kendo.default.mobile.min.css" />
<script src="./resources/scripts/lib/ui/js/jquery.min.js"></script>
<script src="./resources/scripts/lib/ui/js/angular.min.js"></script>
<script src="./resources/scripts/lib/ui/kendo.all.min.js"></script>
4.2. 在 HTML 頁面上,宣告要使用 Kendo Grid (以 AngularJS 為範例,官網上還有許多 JQuery 的範例)

<div id="example" >
    <div ng-controller="MyCtrl">
        <kendo-grid options="mainGridOptions">
        </kendo-grid>
    </div>
</div>
4.3. AngularJS

4.3.1. kendo UI 元件在 AngularJS 中被實作成 directives 所以當我們要使用 kendo ui 時需要注入 kendo.directives
var app = angular.module('myApp', ['kendo.directives']);
4.3.2. Controller

app.controller('MyCtrl', function($scope){
$scope.datasource = {
transport: {
read: {
url: [your service address]
dataType: "json"
}
},
schema: {  
model: {
                 fields: {
                    id: { editable: false},
                    name: {validation: { required: true }},
                        price: { type: 'number', defaultValue: 0, validation: { required: true, min: 0}}
                    }
                }
            }
};
$scope.mainGridOptions = {
    dataSource: $scope.datasource,
    pageable: true,
         height: 300,
    columns: [
     { field: "id",  title: "商品編號", width: "120px"},
     { field: "name", title: "商品名稱", width: "120px" },
      { field: "price", title: "商品價格", width: "120px"},
          ]
};
};
依據此方式,即可完成下列表格之設計。雖然,做了很多事才弄出這張表。但是,使用這個元件可以讓後續新增、修改跟刪除的 UI 操作快很多,只需要再加上一些設定。




[參考資料]
1. Kendo UI - Grid Example

星期一, 7月 25, 2016

IBM MobileFirst 7.1 DirectUpdate 失效


最近,有客戶反應他們的 MobileFirst Server 升級到 7.1 後,Direct Update 僅能更新一次,之後就無法再進行更新。

因為客戶說,他們當天要準備上線作業,這個功能必須能正常運作。所以,我跟同事就開始研究問題可能發生的原因。

根據客戶描述,一開始的時候是部署 wlapp 到 MobileFirst Console 時會出現警告訊息如下:


FWLSE3210W: Environment: android of application [YOUR Application] 
version 1.1 has been deployed with a different version of the native 
MobileFirst SDK. 

Direct updates will no longer be available for existing clients with 
other versions of the MobileFirst SDK. 

To Continue to use direct updates, increment the app version, publish it 
to the public app store, deploy to the server, and (optionally) block/notify 
older versions of the app to enforce customers to upgrade to the new version 
from the app store.

針對上述部分,需要修改 wlapp 的版本。因為 version 1.1 的時候是使用 MobileFirst 先前的版本進行打包。依據 IBM 對於 Direct Update 的定義來看,如果有 Native SDK 更新的話,是必須整個 App 重新下載安裝,而非僅更新 Web Content 就可以。

而升級的時候,IBM MobileFirst 底層的 SDK 有可能被更換掉,所以會出現上述訊息。故,我們將 version 1.1 換成 1.2。如此,在部署 wlapp 時,就不會有 FWLSE3210W 的警告訊息。

但是,上述問題解決後。客戶驗證 Direct Update 的系統發現還是只能更新一次。所以,問題實際上還沒有被解決。

後來,我們又發現 worklight.properties 檔案中,有一個參數是 wl.realm.expiration.directUpdate 的值預設為 3600 (一小時內,Direct Update 不會再生效)。在舊版的值似乎是 -1。但是,目前設定 -1  MobileFirst Server 又無法正常啟動。所以,只好設定個 60 秒 (反正改程式應該都會超過一分鐘吧!)。

修改後,重新更新 MobileFirst Server 的 Runtime WAR 檔之後,Direct Update 的更新頻率就換成1分鐘後可重覆更新的模式。

[參考資料]
1. The direct update doesn't work in MobileFirst Studio v7.1


星期四, 8月 13, 2015

Certificate Scrum Developer 認證課程心得




最近剛上完 Certificate Scrum Developer 課程,授課老師是 Jacky Shen。在這門課程當中討論「持續整合」,「TDD」,「重構」,「Simple Design」,「Git version control」,「Pair Programming」等相關議題。

在最近一年的時間裡,我陸續取得 PMI-ACP,CSPO 及CSM等證照。有了這些知識,卻感覺還少那麼一點東西。Scrum 團隊有 Product Owner,Scrum  Master 及 Development Team 這三個角色。其中,Team 的人數最多,卻很少有人坐下來好好地把什麼是一個好的 Development Team,以及我們該如何成為這樣的團隊。

所以,有 Product Owner 的認證,有 Scrum Master 的認證,當然我們也需要知道如何培養自己或是團隊成為一個敏捷開發團隊成員之一。所以,基於一個這樣的念頭,讓我在颱風隔天連續上了兩天 12 小時的馬拉松課程。


從整個課程的內容來看,初步可以將課程內容分成兩個主要觀念。

          (1) 專注品質

1.1. 在課程中有提到許多好的程式概念,例如:程式碼要讓其他人一目了然,快速地了解。程式碼要可被信賴。程式碼必須是可維護的。

1.2. Test Driven Development: 確保每一段程式碼都有其對應可執行的測試案例。

1.3. 頻繁且持續地測試,保持程式碼永遠是可動的,並且合於需求。

1.4. 透過重構,不斷地改善程式碼的品質,降低程式的壞味道。

          (2) 減少浪費

2.1. 不做過度的設計,減少浪費。

2.2. 花時間進行重構,可以降低日後一次性大規模的調整。(這讓我想起「不要惹公司的程式設計師啊」。)

2.3. 建立自動化的測試案例,可以降低人為測試不斷重工的浪費。


但是,我認為上述的內容還不是最重要的。在 Scrum Alliance 的網站上,說明怎樣是一個成功的 CSD?

A successful Scrum Developer is committed to continuous improvement.

課程最重要的內容是

讀書、練習、分享

努力不懈地提升自己,透過練習不斷地提升自己實務的能力,並且將這些知識分享出去,發揮影響力,讓團隊可以更精進。

最後,感謝長宏的團隊促成以及一起上完這兩天馬拉松式課程的同學們,讓這次Certificate Scrum Developer 課程能在百般的艱難下開課成功。感謝 Jacky  老師充實的課程使大家獲益良多。

星期日, 5月 03, 2015

Deploy IBM Worklight Server to WebSphere Liberty Profile Manually


最近,有一個客戶要將 IBM Mobile First 7 安裝在 AIX 6.1 上。但是,在裝好後,我卻發現 MobileFirst Platform 的目錄中沒有 Worklight Configuration Tool。

心裡面的OS是,這不是IBM的產品嗎?為什麼沒有自家 OS 的工具。

所以,只好開始研究看看,怎麼手動將 Worklight Server 手動佈到伺服器上。

首先,第一步就是檢視 MobileFirst 的安裝目錄,看看裡面有什麼設定檔,反正根據過去經驗應該可以找到一些東西。

終於,在 WorklightServer 的資料夾底下,找到 configuration-samples 的資料夾。在這裡面發現了許多的 xml 檔案 (例如:configure-liberty-db2.xml)。從這些檔案的命名規則,大概可以推敲出可能的解決方案。

於是,我將該檔案打開來進行編輯。依據 xml 檔案內容的提示,置換相關的資料進去。

隨後,執行下列幾個指令:

ant -f configure-liberty-db2.xml admdatabases
ant -f configure-liberty-db2.xml databases

ant -f configure-liberty-db2.xml adminstall

ant -f configure-liberty-db2.xml install

記得每個指令執行後都必須要看到 BUILD SUCCESSFUL 關鍵字,才可以執行下一個指令。


[參考資料]
1. IBM Mobile First 7 Knowledge Center

星期一, 3月 30, 2015

Windows 磁碟壓縮後 Microsoft SQL Server 無法正常使用

使用 Apple Mac Book Pro 最大的問題應該就是硬碟空間太小。

前幾天,我電腦中 windows 的 VM 空間滿了。讓我無法執行寫程式與測試的工作 (因為只要想寫檔案,系統就會出現,磁碟空間不足的錯誤訊息)。

所以,在這種清況下,為了清出空間來使用,只好使用 Windows 的磁碟壓縮功能。

服用後,多出了 20%左右的空間,使得手邊的工作得以繼續。

就在這兩天,我準備打開 Microsoft SQL Server 進行一些相關技術驗證時,就出現資料庫檔案是壓縮檔,無法正常使用的錯誤。

於是,我開始在網路上找尋 solution,花了十幾分鐘,也沒看到一個好的建議方案。


只好自己想辦法處理。如果跟據先前的分析來看,我應該要設法解除磁碟壓縮的狀態。

但是,如果解決磁碟壓縮,就會面臨空間不足的另外一個問題。所以,只好探索是否能部份解除。

後來,我在相關的資料夾的進階設定選單中發現了設定選項。解除該資料夾底下的磁碟壓縮狀態。

設定方法如下:
1. 選定該資料夾,按右鍵選擇「內容」,並且點選「進階」按鈕
2. 系統跳出右邊視窗,取消勾選「壓縮內容,節省磁碟空間(C)」

弄完後,Microsoft SQL Server 就恢復正常了!

星期二, 1月 20, 2015

修改 WebSphere Application Server 上的 JESSIONID cookie name

       Java Servlet API 2.5 之前規定,session identification coolie 必須叫做 JESSIONID。但是,這個規定在 Servlet API 3.0 後已經解除,而 WebSphere Application Server 第八版之後就已經支援 Java Servlet API 3.0 的規格,所以我們可以修改 WebSphere Application Server 上的 JESSIONID cookie name。

        基於,以上的原因。最近突然有人說有改這個東西。當然,先前完全沒改過這個項目!所以,到 IBM 的 Knowledge Center 翻出了下列修改方式:


1. 開啓 WebSphere Application Server 管理主控台
2. 選擇 Servers > Application Servers > Server_Name > Web Container Settings > Session management > Enable Cookies
3. 修改 Session Cookie 的值,預設為“JSESSIONID”
4. 點選確認,然後儲存相關修改設定
5. 重新啟動 WebSphere Application Server
6. 重新啟動 plugin 檔案

待確認問題:
1. 假設在 Cluster 的環境上,我們只修改某一台 Server 的 JESSION Cookie Name 會發生什麼事?

2. 如果 WebSphere Application Server 上裝著以前的舊程式 (Java Servlet API 2.5 以前),會不會被影響?

3. 修改後的 plugin-cfg.xml 會有什麼變化?

4. 這個跟 IBM HTTP Server 以及 WebSphere Application Server Plugin 的版本有沒有關係 (例如:IBM HTTP Server v7.0 是否支援)?


未完,待續 .....


參考資料:
1. 修改 HTTP Cookie Name

星期四, 10月 02, 2014

IBM Installation Manager 啟動錯誤

今天到客戶端進行 IBM HTTP Server 的升級,想說這是一個秒殺的工作,含把檔案放到伺服器上的時間,應該一個上午就可以搞定!

不過,通常事情沒有這麼順。

近年來,IBM 很多軟體大概都透過 Installation Manager 來進行安裝與更新,一切圖形化操作介面,相當地方便。

所以,對於一個軟體升級的工作來說,沒其他狀況的話就是勾一勾,然後下一步,下一步就可以結束。

如果這麼簡單,客戶為什麼一花一筆錢來請我們進行維護?當然,不是要應付這種狀況!而是,我接下來要講的突發狀況。

一開始是客戶跟我反應他們進行弱點掃描時,有掃出 DoS 的弱點,要求補強。於是,我到 IBM 的修正中心看看有沒有修補程式。剛好看到最新的修補程式中,有他們提到的特性,所以我就把修補程式下載下來,並且與客戶約時間,準備進行更新作業。

當客戶幫設定好工作環境後,我打開 Installation Manager 時卻發生了一個錯誤:

Unexpected error in startup resynchronization.

java.lang.illegalStateException: No metadata found for installed package com.ibm.websphere.WCT.v85 8.5.0.20120501_1108.
這下就麻煩了,沒有 installation manager 幾乎什麼事都不能做,所以只能想辦法修復了!

從剛剛的訊息中,我整理出來的相關情報如下:
1. 目前的軟體環境是用 Flush Copy 過來的,會不會少了什麼檔案?
2. 系統呈現的錯誤訊息表示 WCT 這個元件有問題
3. IBM Installation Manager 的檔案結構可分成兩個部分,其中之一是 eclipse 相關的資料,另外一個部分是我們安裝進去的相關資料檔 (在 UNIX 的環境該資料目錄就是 /var/ibm/InstallationManager/ 中)

後來,我到 /var/ibm/InstallationManager/installRegistry/metadata/Offerings 這個目錄中,看到裡面有下列資訊:

com.ibm.websphere.WCT.v85_8.5.0.20120501_1108.jar
com.ibm.websphere.WCT.v85_8.5.0.20120501_1108.jar0
其中,com.ibm.websphere.WCT.v85_8.5.0.20120501_1108.jar 的檔案大小是 0,另外應該還少一個 com.ibm.websphere.WCT.v85_8.5.0.20120501_1108_SE.jar 的檔案。

於是,在請 User 將這兩個檔案補上後,Installation Manager 就可以正常啟動了!
然後就迅速地完成 IBM HTTP Server 的更新,完成這次的任務。

【參考文章】
1. A "No metadata found for installed package" message is seen by Installation Manager with WebSphere Enterprise Service Bus (WESB)

星期四, 9月 25, 2014

在 MAC 中開啓 Linux 裡的 X 視窗

在 Windows 中,我們可以透過 Xming 來叫起 Linux 或 Unix 上的 X 視窗。但是,最近換了 MAC Book Pro 後,突然想到那 MAC 該怎麼處理?

於是,我就上網找找看解決方案。後來找到 XQuartz 這個工具,他是蘋果電腦在 MAC OS 上對於 X Window 的實作。

當我們在 MAC OS 上安裝了 XQuartz 後,可以透過下列指令,來啟動 Linux 上的 X 視窗應用程式:

ssh -X user@servername
xeyes

執行完上面的指令,應該可以看到下列這個眼睛!這就代表設定完成了。





參考資料

1. XQuartz 維基百科, http://zh.wikipedia.org/wiki/XQuartz



JBoss 4.2.3 JSP page cache


這兩天遇到一個棘手的問題。因為,某些因素我需要去修改某個產品的登入程式,讓他支援二次驗證。理論上,我修改 JSP 的程式後,不需要重啟 Server,該 Server 可以自動生效。

不過,神奇的事情就發生在我完成整合後,要丟給客戶看時,確一直看到舊的 JSP (就算我把那個檔案刪掉了,也是一樣)。

然後,我就重開 JBoss Server,看到的還是舊的 JSP!(這真是見鬼了)

一直重開,我還是看到舊的 JSP!

後來,我才想到,JBoss 的 Redeploy 的驅動點好像是檔案的時間。

所以,我就把檔案動一下再存檔,以更新檔案的最後存取時間。

結果,這招果然奏效了。不然,在那邊換檔案換半天就是沒有效。

讓客戶在旁邊看笑話了。

星期二, 9月 23, 2014

CentOS command line install Tomcat

最近突然有一個需求,就是在 Linux 上安裝 Tomcat。但是,因為使用 VM 的關係,GUI 的操作不是很靈敏,又沒有弄 Xming,所以只好用指令來完成安裝啦!也順被把這樣的程序整理起來。


安裝 JDK 7 Update 67

wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/7u67-b01/jdk-7u67-linux-x64.tar.gz"
下載回來後,檔名為:
jdk-7u67-linux-x64.tar.gz?AuthParam=1411398968_5826ae3ee1898fbb3d1e25e9de936e9d

此時,將該檔案檔名修改為「jdk-7u67-linux-x64.tar.gz」。再執行下列指令,進行解壓縮的工作。
tar xzf jdk-7u67-linux-x64.tar.gz
接著,使用 alternatives 指令進行 java 安裝,指令如下:

cd /opt/jdk1.7.0_67/
alternatives --install /usr/bin/java java /opt/jdk1.7.0_67/bin/java 2
# alternatives --config java (如果該機器中有多個 java 環境,可利用此指令進行篩選)
設定 JAVA_HOME 及 PATH 等環境變數,將 .bash_profile 設定修改如下 (紅字部分為增加之設定)

# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi
# User specific environment and startup programs
export JAVA_HOME=/opt/jdk1.7.0_67
PATH=$PATH:$HOME/bin:/opt/jdk1.7.0_67/bin
export PATH
unset USERNAME



安裝 Apache Tomcat

執行下列指令,進行 tomcat 下載 (本範例下載到 /usr/Apache 目錄底下)
wget http://apache.stu.edu.tw/tomcat/tomcat-7/v7.0.55/bin/apache-tomcat-7.0.55.zip
執行下列指令,將下載回來的 Tomcat Server 檔案解壓縮

unzip apache-tomcat-7.0.55.zip
至 apache-tomcat-7.0.55 目錄底下的 bin,執行下列指令,啟動 Tomcat Server

./startup.sh
接著可以使用 http://serverip:8080/ 測試 Tomcat 伺服器是否正常運作。



星期五, 9月 12, 2014

Sencha Touch 入門 - 環境建置 for MAC (1)


隨著行動應用的發展,App 開發的專案越來越多。最近,IBM Worklight 的詢問度似乎有提高的趨勢。面對 Hybrid App 的開發,大家通常提出來的第一個問題就是「效能會不會很差」。為了,能夠推廣 Hybrid App 的開發,我們當然要很努力地扭轉這樣的局面。

所謂,Hybrid App 指的就是利用 HTML5 + JavaScript + CSS3 來開發行動應用 App。當然,利用這樣的技術來製作 App 效能是比寫 Objective-C 或 Java 來得差。但是,使用者真的需要那麼快的 UI 響應嗎?

開發 Hybrid App 時,處理程式邏輯最重要的部分非 JavaScript 莫屬。在現今許多Framework並起的時代,以 Sencha Touch 的平台效能響應最快。因此,我們就開始 Sencha Touch 的 Survey 了!

這篇文章,算是個起頭!先交代如何建立 Sencha Touch 的環境。後面,再寫幾篇文章來說明我們實驗的過程。

安裝 Sencha Cmd

首先,把下載回來的檔案「SenchaCmd-5.0.1.231-osx.app.zip」解壓縮。解壓縮後可以看到「SenchaCmd-5.0.1.231-osx」檔案。點選該檔案後,開始進行 Sencha Cmd 的安裝。


在上述畫面,點選「打開」後,開始進行 Sencha Cmd 的安裝工作。在下列畫面中,點選下一步,進行 Sencha Cmd 的安裝工作。


在 License Agreement 的畫面上,選擇「I accept the agreement」後,點選「Next」繼續進行安裝工作。


選擇 installation Directory (可以採用預設的建議目錄),點選「Next」


在 Ready to Install 畫面上,點選「Next」 開始進行安裝程序


等待安裝程序完成!


點選 Finish 完成安裝!


開啓「終端機」,輸入「sencha」可以看到下列畫面,代表 Sencha Cmd 已經安裝完成了!


Sencha Touch 2.4 


  1. 將下載回來的「touch-2.4.0-commercial.zip」檔案解壓縮
  2. 將終端機中的路徑,切換到「touch-2.4.0-commercial.zip」 解壓縮的位址
  3. 輸入下列畫面中的指令,來建立 Sencha Touch 專案

成功建立 Sencha Touch 專案後,可以看到上列畫面。接著,執行下列指令打開 Chrome 瀏覽器「open /Applications/Google\ Chrome.app/ --args --disable-web-security」。然後再從檔案中選到 index.html 後即可看到預設的範例程式。
到了這一步,表示基本環境已經建置完成。


參考資料:

下載 Sencha Touch : http://www.sencha.com/products/touch/
下載 Sencha Cmd: http://www.sencha.com/products/sencha-cmd/download



星期四, 9月 11, 2014

修改 CentOS 的 MAC Address

有很多地方是透過電腦的 MAC Address 來管理一個設備是否可以上網。然而,有時候要跟系統或網管人員申請 MAC 的轉換又很麻煩。所以,如果我們可以自己修改 MAC Address 的話,就不用透過這道手續。

會去找 CentOS 如何修改 MAC Address 的方法,主要是我本來用一台 Windows Server 在做一些測試。然後,因為某些專案的因素,我又需要有一部 Linux 的測試環境。但是,網管人員只給我一組 IP,而且是綁定 Windows Server 的 MAC Address。

此時,如果懶得驚動網管人員,最佳的解決方案就是替這部 Linux 修改 MAC Address,並且設定相對應的 IP。於是,我先從 Linux 的 GUI 界面探索是否有可以設定的地方。

首先,我從「Administration」/「Network」中找到下列設定畫面:

選擇 eth0 的 Device 後,按下「Edit」按鈕,就可以出現該網卡的設定畫面。

選擇「Hardware Device」的 Tab 就可以看到有一個「Bind to MAC address」的地方可以進行設定。


設定後,按下確認鈕,並且重啟該網卡。突然遇到了「Device eth0 has different MAC Address than expected, ignoring」的錯誤訊息。於是找好再打開 Google 檢查一下還有哪邊需要設定,但是看來看去都是指向 「/etc/sysconfig/network-scripts/ifcfg-eth0」的檔案要修改。

這個檔案中,有一個屬性「HWADDR」看起來就是我設定的哪個 MAC Address。不過怎麼改好像都沒用!後來,我又找到一篇文章「How to change MAC address on CentOS Linux」。這篇文章中寫的屬性是「MACADDR」,於是我將 HWADDR 修改成 MACADDR 後,網卡就可以正常運作了!







星期二, 9月 09, 2014

特權帳號管理

大概是在三四年前,因為和 CA 的配合,我開始接觸到「特權帳號管理」這一塊領域。

一般來說,我們的系統大致上可以把使用者的帳號切割成兩個部分:
1. 一般使用者帳號
2. 系統管理者帳號

通常,我們在公司裡面談的資訊安全,有80%是針對「一般使用者」來進行管理,但是對於特權帳號這部分卻疏於管控。

為什麼會說疏於管控?我經常到客戶那邊協助處理 IT 的問題 (不管是系統類的或是應用程式開發類的錯誤),我總是需要一組擁有「足夠權限」的帳號,讓我進行問題的診斷。

這時候該如何取得該帳號與密碼來登入系統?通常就是直接問承辦人,然後他就會跟你講帳號密碼(還好我是個善良的人,不然這些系統啟不落入我的掌控之中!)。接著,我就可以使用這組帳號密碼登入系統,胡作非為。

近年來,這些安全的意識高漲,所以到客戶那邊要取得這些帳號密碼的資料也變的比較麻煩了。以我們公司最大的客戶來講,現在你去維護他們家的系統,帳號密碼由他們敲,你在操作的同時他們的員工必須陪同在旁邊,跟你 pair programming (就是監視你是不是有真的胡作非為)。

如果他們是以學習的角度,來觀察我做了什麼,那對於他們可能是有價值的。如果,只是來監視我,那這樣就顯得很浪費資源。

談到這裡,有一些IT的需求就逐漸浮現:
1. 企業不希望外部的維護工程師知道我系統管理者的帳號密碼,所以要有人幫我管理密碼或者是幫我敲密碼
2. 當他人登入我的系統時,我們可以監控其一舉一動,了解登入者進入系統中做了哪些操作

在這上面,CA 使用 ControlMinder 的 Shared Account Management 模組,就是針對上述需求而設計的產品。

該產品讓使用者透過入口網站,來控管共用使用者(系統管理者)的管理權限,也提供使用者自動登入 (資料庫,作業系統,網路設備等)機制,防止密碼外洩。針對臨時的存取者,該產品也提供申請,審核的機制。

針對應用程式中常見的 Shared Account Management 問題,例如:程式碼中將資料庫的密碼寫死在設定檔或應用程式伺服器上。導致開發人員知道資料庫系統的帳號密碼,使資料庫內的資料暴露在可能被取走的風險中。因此,CA ControlMinder 模組也提供各種與既有程式整合的方式,包括 .NET, Java 等 (我也處理過 C++, PHP, ASP, VB, CScript 等程式語言的整合案例)。藉由上述方式,可以解決第 1 項需求。

而第 2 項需求的部分,則由 ControlMinder 產品整合 ObserveIT 來解決。透過整合 ObserveIT 的套件,當使用者使用 ControlMinder 上的自動登入功能時,就可以啟動錄影功能,將使用者登入系統後所做的事情錄製下來。

很多人看完這個功能後的問題就是那不是會耗費很大量的磁碟空間?ObserveIT 使採用差異化錄影的技術來節省錄製檔案的空間。所謂的差異化錄影,就是說當我們有進行動作時,畫面才會被存下來。如果登入後,讓畫面停在那邊不動,則 ObserveIT 僅會儲存一個畫面,藉此降低影像儲存的資料量。

透過上述軟體系統的協助,可以解決特權帳號管理的問題,並能確實留下他人進入系統的操作記錄,作為後續稽核及問題追蹤的重要證據。

星期二, 9月 02, 2014

CentOS 上設定 FTP


因為工作上的需求,有時後得用 Linux 模擬客戶端的環境。通常是模擬 Linux or Unix,使得自己到現場的時候能拿出更專業的表現。

這時候,我通常會在機器上建立起 Linux 的 VM。會安裝這個 VM 主要是為了進行一些軟體的安裝驗證。所以,通常需要從自己的 Windows host copy 檔案到 Linux 中。

這時,我通常會使用 FTP。

在 CentOS 底下,可以使用【yum install vsftpd】進行 FTP 軟體的安裝。

安裝完成後,可以透過【service vsftpd start】來啟動 FTP 的服務。

另外,我們可能希望檔案可以上傳到 Home Directory。
此時,因為 Linux 上一些預設的限制,要達成此條件的話,要執行下列指令:

/usr/sbin/setsebool -P ftp_home_dir 1

如此應該就可以正常運作。當然,如果你要使用的是 root 帳號,還要設定下列檔案:

/etc/vsftpd/ftpusers

/etc/vsftpd/user_list

必須將 root 帳號從排除清單中移除,才可以用 root 登入。