Archive for August, 2014

上手Bluemix (3)

Tuesday, August 19th, 2014

截止上篇文章,我们已经在Bluemix上构建了一个可以连接Bluemix数据库服务、基于WebSphere Liberty Server的Java Web应用了。我们提到Connections Blogs的老版本(相比新版本对WebSphere Application Server (WAS)已经是最小的了)跑起来还是会有很多错误,大致总结一下:

1) WAS专用API. 如做Basic Authentication用的是WAS Programmatic Login的API;

2) 和WAS环境相关的配置文件。代码中需要到WAS环境下特定的目录找某些配置文件;

3) 不同Web container的实现差异。在移植过程中发现对于URL的最后一个斜杠/,在WAS和Liberty中处理是不同的;

4) 文件系统。Blogs会把上传附件保存在文件系统,目前我也不清楚Bluemix上给我的空间大小(应该是1G)和位置。通过测试说明至少服务器端代码是可以在Liberty安装目录下创建目录和文件的;

5) Directory service。这是Connections自己的code,根据用户配置调用WAS VMM API从Federated Repository,或者Connections Profiles里查找用户详细信息。这两个数据源在Bluemix上都没有,所以需要更新一些代码跳过用户同步过程。

在disable了Basic Authentication、Connections navbar、Directory service和Lucene index后,Blogs最终可以跑在Bluemix上。

最后的问题是用户登录,我没打算搞个LDAP,只要创建些简单的测试用户就可以了。在Liberty里很容易做到,通过在server.xml中添加用户定义和角色定义,如下:

定义用户:

<basicRegistry id=”basic” realm=”WebRealm”>
      <user name=”ajones1″ password=”jones1″/>
      <user name=”ajones2″ password=”jones2″/>
      <user name=”ajones3″ password=”jones3″/>
      <user name=”ajones4″ password=”jones4″/>
      <user name=”ajones5″ password=”jones5″/>
      <user name=”ajones6″ password=”jones6″/>
</basicRegistry>

定义用户在应用中的role:

<application type=”war” id=”blogs” name=”blogs” location=”blogs.war”>
    <application-bnd>
        
        <security-role name=”person“>
            <special-subject type=”ALL_AUTHENTICATED_USERS” />
        </security-role>
        <security-role name=”admin“>
            <user name=”ajones1″/>
        </security-role>
        
    </application-bnd>
</application>

“ALL_AUTHENTICATED_USERS”是个特殊的保留角色,对应于WAS的相同角色,用来指定所有已登录用户。测试中我发现security-role的映射有bug,不是每次调用request.isUserInRole(role)都会返回正确的结果。

接下来的事情很关键 – 如何把一份自定义的server.xml文件上传到server端?答案:你做不到。目前找到的解决方案是按照Bluemix的buildpack去部署应用,即同时上传Liberty的Runtime和应用程序。利用Eclipse的Bluemix插件很容易实现:

1) 下载Eclipse Bluemix插件。在Eclipse Marketplace搜索‘bluemix’,找到后安装:

bluemix-plugin-install

2) 安装后右键在Server Tab里点New Server,选择IBM Bluemix,开始配置:

config-bluemix-plugin

domain

bind-db

3) 配置完成后,可以直接用Publish选项发布整个Runtime和application。

upload

<终>

上手Bluemix (2)

Friday, August 15th, 2014

上次说到在Bluemix新建一个简单的Java webapp,现在这个Java应用需要访问数据库服务来存取数据,我们来看看在Bluemix上该如何使用和管理数据库服务。首先,Bluemix上有多种数据库服务供选择,有传统的关系型数据库也有NoSQL (包含了IBM收购的Cloudant),因为Connections本身支持包括DB2, Oracle和SQL Server,所以我们选择基于IBM DB2的数据服务。

可以从Dashboard的Service tab或者直接从Catalog进入服务选择界面,选择Data Management -> SQL Database:

database

创建时需要指定服务名(注意这个名字既不是数据库名也不是schema名,仅仅是个标示符),同时如果应用已经创建好,可以在创建数据库服务的时候直接绑定应用。

create-db-instance

创建好数据库服务后回到Dashboard,可以看到名下有一个应用和一个服务 – APPS(1) & SERVICES(1) – 移植Connections Blogs需要的全部组件都齐了。

db-service

在创建并绑定数据库服务后,点击应用的Runtime选项,可以看到新生成的环境变量。这里包含了有关数据库连接的全部信息 – 注意所有的配置信息都无法更改,一旦重新创建数据库服务,数据库名、用户名、密码等都会随之改变。这些所谓’环境变量‘实际上是保存在Liberty的server.xml中,这样app在启动的时候可以正确的找到JNDI data source。

env_variable

接下来,我们需要创建数据库schema,tables,indexes…点击进入添加好的数据库服务,点’Launch’按钮会打开一个数据库管理界面,点击‘Work with Database Objects’就可以开始创建数据对象了。Bluemix的数据库服务不支持用本地的数据库客户端直接连接,所有的数据管理操作都必须在Web界面上完成。

schema

大家注意到上图有个名叫‘REUNOBRW’的schema,它和上上图里的环境变量中的数据库用户名是一致的。之所以要手工创建‘REUNOBRW’ schema的原因在于我们要移植的Blogs早期版本(1.0.2)里,所有的数据库访问代码是仅有table名,不带schema名的,如下:

<select id=”getWebsiteById” parameterClass=”string” resultMap=”Website” >
      SELECT * FROM website WHERE id = #value#
</select>

在Bluemix环境中,这样的调用会自动在前面以用户名作为schema名。除非我们修改全部的SQL把它们都带上schema名,否则只能创建一个和用户名同名的schema。这个做法虽然可以工作,但一旦数据库服务重建schema也必须要重建,作为测试可以但作为生产环境的开发这样是不可取的。创建好schema后,可以创建table等对象了,点击Run DDL来指行数据库命令(注意不是所有的SQL都支持,比如我们无法创建table space)。下面是在创建好tables、运行应用后查询用户表的例子 –

run-sql现在可以把Connections Blogs build成一个.war文件,通过cf push到Bluemix上,它可以正确的连接数据库,但界面上有很多错误,绝大部分是因为已有代码是在WebSphere Application Server下测试运行的,在Liberty环境下存在问题。另外也没有办法登录,因为我们还没有定义用户库。下篇文章我们将继续讨论应用的迁移。

上手Bluemix (1)

Thursday, August 14th, 2014

之前写了个短文,说把IBM Connections Blogs移植到了Bluemix上。今天花点时间,写写具体的过程。对于不熟悉Bluemix的人,我一句话解释一下:Bluemix是IBM的PaaS平台,供开发者构建在云上跑的应用,而Bluemix本身是架在SoftLayer (IBM IaaS)之上的。

先来看看Bluemix长啥样。对于首次访问的用户,基本上唯一有用的界面就是Catalog了,里面列举了Bluemix提供的runtime、service和各种组件,大家的第一个应用就从这里开始。

catalog

IBM Connections是基于Java的Web应用,所以我们选择的Runtime是Liberty for Java(一个约20MB左右的Java Web容器)。输入基本参数,一个缺省的Webapp和一个WebSphere Liberty Profile的instance就产生了。这个webapp的首页是显示当前应用的一些运行时参数。

liberty当创建好第一个应用后,Dashboard就成了常用的视图了,应用的启/停、监控、服务的创建和绑定都要在这个界面上完成。

quickstart

对于新手来说,’View Quick Start’按钮很有帮助,它指导开发者之后需要做的事情,包括安装cf工具来做应用上载,以及如何登陆和访问。我一开始就是按照这个步骤在写了Hello World之后把应用打包后用cf push到Bluemix上的。

有了第一个可以运行的demo webapp后,可以从Dashboard中把这个应用打包下载到本地,展开后用Eclipse在本地继续开发,完成后重新打包上传。多尝试几次后,就可以熟练的更新、上传应用了。需要注意的是,应用更新的最小粒度是.war(至少今天我都没有找到文件级别的更新),也就是说即使要改一个JSP文件也需要完整打包后上传。我试图找到类似SSH的方式允许远程文件上传,但最终没有找到。开发者能够在文件级别范围的访问仅限于在’Files and Logs’菜单下浏览文件目录并下载里面的文件,如log等。

filesystem

最后谈谈本地开发和测试。开发者可以使用Eclipse加上WebSphere Liberty Profile runtime集成到Eclipse中,具体下载地址 – https://developer.ibm.com/wasdev/downloads/liberty-profile-using-eclipse/。搞定后的开发环境大概是这样的(截图里面的Bluemix插件,下次再介绍)。

eclipse

好了,到此为止一个简单的Java webapp已经可以欢快的跑在Bluemix之上,我们也初步了解了开发者该如何更新和部署这个应用了。接下来,谈谈如何创建一个数据库服务并绑定应用,待续。

WordPress测试

Thursday, August 14th, 2014

新浪微博自动发布测试。

配置方法:http://www.weibo.com/tool/bloglink

IBM Connections Mobile二维码测试

Tuesday, August 12th, 2014

IBM Connections mobile App下载 (iOS):

https://itunes.apple.com/us/app/ibm-connections/id450533489?mt=8

ios_ibm_connections

自动预填服务器地址和用户名:

ibmscp://com.ibm.connections/launch?accountname=ChinaOpen&accountserver=https%3A%2F%2Fmycompany%2Ecom&accountuser=tom

connections-app-login

评论添加图片验证码

Tuesday, August 12th, 2014

装了SI CAPTCHA – http://wordpress.org/plugins/si-captcha-for-wordpress/, 现在评论需要图片验证码,观察一下效果。

Lotus Connections Blogs 1.0 on Bluemix

Friday, August 1st, 2014

上周花了些时间把IBM Connections Blogs的一个早期版本(那时候叫Lotus Connections)移植到了IBM Bluemix上。这是一个学习的过程,帮我了解IBM PaaS平台的开发,掌握第一手经验。

为了把基于WebSphere Application Server实现的应用能跑到WebSphere Liberty Profile上,修改了一些代码,然后通过Bluemix Eclipse插件push到服务器上。等有时间写写详细的过程。

  • Lotus Connections Blogs 1.0 on Bluemix: http://ling.stage1.mybluemix.net/blogs/ 这个地址外网应该是访问不了的,我自己试了几次都不行,虽然ping server的地址不是9.x网段。

留了截屏:

blogs_bluemix

Bluemix上的部署界面:

bluemix

把Fiddler配置成reverse proxy

Friday, August 1st, 2014

Fiddler是用作Web调试的工具,因为一个需求想自己搭一个简单的reverse proxy,试了几个工具都不太好用。做了些功课发现可以把Fiddler配置成reverse proxy。大致步骤如下:

1) 配置成Fiddler的侦听端口

这个很容易,在平时用作调试的时候就已经有了。需要注意的是要允许其他电脑访问Fiddler服务;

fiddler1

2) 侦听HTTPS端口

侦听HTTS端口在界面上没有办法配置,需要在Fiddler QuickEexc命令行里输入:!listen 443 proxy.mycompany.com

fiddler2

 

3) 定制HTTP  response处理脚本

Reverse proxy最重要的一个功能是对返回的HTTP response进行预处理,之后再返回给浏览器。比如把嵌入在HTML中的所有绝对URL的hostname变成reverse proxy自己的hostname,这样才能保证用户后续的访问可以指向正确的服务器地址。Fiddler提供了脚本支持来完成对HTTP response的修改。

你可以使用Fiddler的菜单调出脚本用文本编辑器进行编辑,或者安装FiddlerScript插件进行开发(有代码提示功能)。

fiddler3

你可能需要定制的地方包括:

3.1)对所有HTTP 302进行截获,把重定向地址改成reverse proxy自己的地址,代码大致如下:

static function OnBeforeResponse(oSession: Session) {

..

if (oSession.HostnameIs(“server.mycompany.com”)){
            var redirect = oSession.oResponse.headers.AllValues(“Location”);
            if (redirect != “”) {
                redirect = redirect.replace(“server.mycompany.com”, “proxy.mycompany.com”);
                oSession.oResponse.headers.Remove(“Location”);
                oSession.oResponse.headers.Add(“Location”, redirect);
            }

3.2) 对所有HTTP response 200的正文进行扫描,替换掉里面嵌入的绝对URL:

 if (oSession.oResponse.headers.ExistsAndContains(“Content-Type”,”text/html”)){
                oSession.utilDecodeResponse();
                oSession.utilReplaceInResponse(“server.mycompany.com”,”proxy.mycompnay.com”);
            }
            
        }

 

现在可以启动你的本地浏览器来访问用Fiddler搭成的reverse proxy了: http://proxy.mycompany.com/

:Fiddler配置为reverse proxy的官方文档(不详细,要结合本文内容)- http://docs.telerik.com/fiddler/configure-fiddler/Tasks/UseFiddlerAsReverseProxy