Jelly的思想看上去很简单。预定义了一些tag,关键是你可以自定义tag,然后用自己的xml引擎回调自己的tag processor。恩。就是这样的原理吧。
Jelly的这种能力正好与我现在的问题域相匹配:
1)我需要自动的通过telnet去执行很多的DSLAM命令;
2)对命令的结果进行处理,最终获得命令成果或是失败的结果;
3)结果的true/false会控制后续的命令是否执行
4)需要能够让用户自定义变量给DSLAM命令使用;
5)用户执行dslam命令时需要while和if 的能力。
浏览了一下Jelly的预定义tag,已经包含了很丰富的用于逻辑判断的tag。太棒了!只要很好总结、抽象出对命令的处理,我一定是可以写出功能强大的CLTF的。:)
感谢zero.liu的一篇摘读,让我看到了Jelly。曾经的一个想法是去使用groovy这样的脚本语言的。
2009年2月10日星期二
多态与适配器模式
背景:N2X和TestCenter的很多功能都很类似。以前同样的功能都是针对不同的设备写的独立代码。
提出一个需求:测试人员希望一个测试step的代码对于设备是透明的,既能在n2x上跑,也能在TC上跑。
问题:虽然这两个设备的多数功能都有重叠,但是每个功能API的接口参数、格式还是有差别的,而且具体的功能能力也是有些差别的。
解决:
抽象出一个参数类。
抽象出一个设备接口,定义出设备能力。
直接用OO的多态特性对调用进行设备匹配。
有的同事说用适配器模式。适配器模式是针对接口不一致时进行中间层的适配。这里其实体现的是一种动态地对某种实现的选择。似乎没有必要立刻就考虑使用哪种模式。
【UI层通过使用tab等组件根据设备的不同接受参数输入。】
困难:
功能的差异还是很难解决。
提出一个需求:测试人员希望一个测试step的代码对于设备是透明的,既能在n2x上跑,也能在TC上跑。
问题:虽然这两个设备的多数功能都有重叠,但是每个功能API的接口参数、格式还是有差别的,而且具体的功能能力也是有些差别的。
解决:
抽象出一个参数类。
抽象出一个设备接口,定义出设备能力。
直接用OO的多态特性对调用进行设备匹配。
有的同事说用适配器模式。适配器模式是针对接口不一致时进行中间层的适配。这里其实体现的是一种动态地对某种实现的选择。似乎没有必要立刻就考虑使用哪种模式。
【UI层通过使用tab等组件根据设备的不同接受参数输入。】
困难:
功能的差异还是很难解决。
2009年2月9日星期一
对敏捷的一点思考 ---- 敏捷是强调结果的
现在软件工程项目管理流行使用“敏捷”。经历了一些敏捷项目,有了些感想。
现在的项目组强制执行结对编程。我喜欢敏捷因为敏捷是山寨版的CMMI。而山寨代表着先进生产力、代表着具体问题具体分析的思想与实践。
先看看Agile 宣言与原则。你就发现敏捷其实是强调结果的。它用结果督促、指导项目的进行。
但是我觉得敏捷开发忽略了对总体架构或者系统设计的要求与指导。
在最近的几个项目中,都号称用敏捷的模式进行项目管理:每天早上的15分钟会议、结对编程、与用户的直接沟通。但这些手段都不能很好的解决在软件框架的设计问题。因为大多数程序员的经验与水平还不能够为项目建立框架(spring, struts这些现有框架确实解决了很多问题。但是一但项目需要定制自己的框架时,问题就凸显出来。)
如何根据具体的项目特点搭建适合自己业务需求的框架能够敏捷出来么?我个人觉得是不大可能的。因为这要求开发人员在对业务、技术比较了解的情况下进行更深一个层次的抽象。如何抽象?哪些可以抽象?抽象后如何向外提供服务(提供调用接口或IoC)?都是需要有比较专业的思考,同时很多也是经验。
想说的是,敏捷并不能替代全部的传统的软件工程流程,尤其是系统设计这一块。
敏捷是方法论,并不是保证。就如,设计也需要敏捷一样。
虽然我自己对敏捷有了以上负面的感觉,但我依旧喜欢敏捷,因为它思想包括:个体和交互、客户合作。
Manifesto for Agile Software Development
个体和交互 胜过 工具和过程
可以运行的软件 胜过 面面俱到的文档
客户合作 胜过 合同谈判
响应变化 胜过 遵循计划
敏捷原则
1. 优先级最高的是,通过早期和持续交付有价值的软件来满足客户。
2. 欢迎变更需求,即使在开发的后期提出。敏捷过程为客户的竞争优势而控制变更。
3. 以两周到两月为周期,频繁地交付可运行的软件,首推较短的时间定量。
4. 在整个项目过程中,每一天开发人员都要和业务人员合作。
5. 由个体推动项目的建设,为个体提供所需的环境,支持和信任。
6. 在开发团队中或开发团队间传递信息的最为有效和高效的方法是面对面的交谈。
7. 衡量进展的重要尺度是可运行的软件。
8. 敏捷过程提倡可持续的开发。
9. 发起人,开发者和用户应该步调一致。
10.不断地关注技术上优越的设计会提高敏捷性。
11.简洁是最重要的,简洁就是尽量减少工作量的艺术。
12.最佳的架构,需求和设计来自于自组织的团队。
13.团队要定期反省如何使工作更有效,然后相应地调整行为。
现在的项目组强制执行结对编程。我喜欢敏捷因为敏捷是山寨版的CMMI。而山寨代表着先进生产力、代表着具体问题具体分析的思想与实践。
先看看Agile 宣言与原则。你就发现敏捷其实是强调结果的。它用结果督促、指导项目的进行。
但是我觉得敏捷开发忽略了对总体架构或者系统设计的要求与指导。
在最近的几个项目中,都号称用敏捷的模式进行项目管理:每天早上的15分钟会议、结对编程、与用户的直接沟通。但这些手段都不能很好的解决在软件框架的设计问题。因为大多数程序员的经验与水平还不能够为项目建立框架(spring, struts这些现有框架确实解决了很多问题。但是一但项目需要定制自己的框架时,问题就凸显出来。)
如何根据具体的项目特点搭建适合自己业务需求的框架能够敏捷出来么?我个人觉得是不大可能的。因为这要求开发人员在对业务、技术比较了解的情况下进行更深一个层次的抽象。如何抽象?哪些可以抽象?抽象后如何向外提供服务(提供调用接口或IoC)?都是需要有比较专业的思考,同时很多也是经验。
想说的是,敏捷并不能替代全部的传统的软件工程流程,尤其是系统设计这一块。
敏捷是方法论,并不是保证。就如,设计也需要敏捷一样。
虽然我自己对敏捷有了以上负面的感觉,但我依旧喜欢敏捷,因为它思想包括:个体和交互、客户合作。
Manifesto for Agile Software Development
个体和交互 胜过 工具和过程
可以运行的软件 胜过 面面俱到的文档
客户合作 胜过 合同谈判
响应变化 胜过 遵循计划
敏捷原则
1. 优先级最高的是,通过早期和持续交付有价值的软件来满足客户。
2. 欢迎变更需求,即使在开发的后期提出。敏捷过程为客户的竞争优势而控制变更。
3. 以两周到两月为周期,频繁地交付可运行的软件,首推较短的时间定量。
4. 在整个项目过程中,每一天开发人员都要和业务人员合作。
5. 由个体推动项目的建设,为个体提供所需的环境,支持和信任。
6. 在开发团队中或开发团队间传递信息的最为有效和高效的方法是面对面的交谈。
7. 衡量进展的重要尺度是可运行的软件。
8. 敏捷过程提倡可持续的开发。
9. 发起人,开发者和用户应该步调一致。
10.不断地关注技术上优越的设计会提高敏捷性。
11.简洁是最重要的,简洁就是尽量减少工作量的艺术。
12.最佳的架构,需求和设计来自于自组织的团队。
13.团队要定期反省如何使工作更有效,然后相应地调整行为。
2009年2月6日星期五
Telnet命令执行器--BlockingQueue
.
昨天完成了DslamTelnetProtocol类,这个类实现了IResponseListener接口,用于对接收到的输入流进行实时的解析、处理。DslamTelnetProtocol这个类的名称也许改成...ProtocolFilter比较合适。
目前启动了一个线程处理telnet的输出。对telnet的输入还是在主线程中调用telnetConnection.send()实现的。下一步应该把输入也用另一个线程来处理。
TODO: 对设备发送的命令放到一个BlockingQueue commandQueue中。DslamTelnetProtocol解析获得的命令结果放BlockingQueue resultQueue中。BlockingQueue确实为生产者-消费者模式简化了很多代码。否则你自己必须封装一个合适的queue,对这个queue进行适当的同步保证并发性。而且需要很好的设计wait() notify()来进行线程之间的协调。
昨天完成了DslamTelnetProtocol类,这个类实现了IResponseListener接口,用于对接收到的输入流进行实时的解析、处理。DslamTelnetProtocol这个类的名称也许改成...ProtocolFilter比较合适。
目前启动了一个线程处理telnet的输出。对telnet的输入还是在主线程中调用telnetConnection.send()实现的。下一步应该把输入也用另一个线程来处理。
TODO: 对设备发送的命令放到一个BlockingQueue commandQueue中。DslamTelnetProtocol解析获得的命令结果放BlockingQueue resultQueue中。BlockingQueue确实为生产者-消费者模式简化了很多代码。否则你自己必须封装一个合适的queue,对这个queue进行适当的同步保证并发性。而且需要很好的设计wait() notify()来进行线程之间的协调。
2009年2月4日星期三
Telnet命令执行器----对the end of a stream的理解
现在工作中的软件框架中有一个比较严重的问题是网络命令的执行request-reponse之间没有进行很好的协调而是使用sleep, check这种糟糕的方式。
很自然联想起给Neustar做的IM软件。但telnet协议又不同于IM系统所使用的协议。前者是基于长连接,而后者是短连接。对于短链接,请求与回应很容易进行匹对。而长连接,则需要依靠同一个网络连接顺序地、依次地进行请求-回应的处理。
对于利用像telnet协议基于长连接来执行的命令,同步是其天然特性。所以对于命令的执行是没有必要进行异步处理的。(当然也可以进行异步处理,但是意义基本不大,这里异步/同步的选择应该是基于应用的不同而变化。)
先不考虑接口、抽象。直接用两个类封装逻辑。TelnetConnection利用common-net项目中的TelnetClient建立连接,获得input, output。TelnetCommond封装通过telnet协议发出的命令。
public String receiveText() {
StringBuilder sb = null;
try {
sb = new StringBuilder();
byte ch = (byte) in.read();
while (ch > 0) {
sb.append((char) ch);
ch = (byte) in.read(); // 当读到-1之后再用out发送指令之后再也不能读出response了。
// 而且读取这个-1的值时程序被阻塞!
}
} catch (IOException e) {
Log.warn(e);
}
Log.debug(sb.toString());
return sb.toString();
}
改为使用结束字符串做检查标志后就正常了。
byte ch = (byte) in.read();
while (ch > 0) {
sb.append((char) ch);
if (sb.indexOf(endFlagStr) >=0) {
break;
}
ch = (byte) in.read();
}
很奇怪,难道是apache common-net里的类TelnetInputStream实现得有问题?当inputstream读到末尾后,有新的数据进入后没有进行适当的处理?
呵呵,是我的错误!inputStream.read()返回-1说明已经读到了the end of the stream。对于有限容量的stream(比如来自文件的流)来说就是读尽了,对于未知容量的stream比如网络流,如果 read()返回-1,说明这个流可能已经被对端关闭了。总之就应该对这种情况进行处理。再读下去,也是-1。这篇文章对此有些所描述:http://publib.boulder.ibm.com/infocenter/zos/v1r9/index.jsp?topic=/com.ibm.zos.r9.rexa100/h1981605209.htm
Telnet概述及RFC: http://en.wikipedia.org/wiki/Telnet
common-net 的使用:http://www.informit.com/guides/content.aspx?g=java&seqNum=40
很自然联想起给Neustar做的IM软件。但telnet协议又不同于IM系统所使用的协议。前者是基于长连接,而后者是短连接。对于短链接,请求与回应很容易进行匹对。而长连接,则需要依靠同一个网络连接顺序地、依次地进行请求-回应的处理。
对于利用像telnet协议基于长连接来执行的命令,同步是其天然特性。所以对于命令的执行是没有必要进行异步处理的。(当然也可以进行异步处理,但是意义基本不大,这里异步/同步的选择应该是基于应用的不同而变化。)
先不考虑接口、抽象。直接用两个类封装逻辑。TelnetConnection利用common-net项目中的TelnetClient建立连接,获得input, output。TelnetCommond封装通过telnet协议发出的命令。
public String receiveText() {
StringBuilder sb = null;
try {
sb = new StringBuilder();
byte ch = (byte) in.read();
while (ch > 0) {
sb.append((char) ch);
ch = (byte) in.read(); // 当读到-1之后再用out发送指令之后再也不能读出response了。
// 而且读取这个-1的值时程序被阻塞!
}
} catch (IOException e) {
Log.warn(e);
}
Log.debug(sb.toString());
return sb.toString();
}
改为使用结束字符串做检查标志后就正常了。
byte ch = (byte) in.read();
while (ch > 0) {
sb.append((char) ch);
if (sb.indexOf(endFlagStr) >=0) {
break;
}
ch = (byte) in.read();
}
很奇怪,难道是apache common-net里的类TelnetInputStream实现得有问题?当inputstream读到末尾后,有新的数据进入后没有进行适当的处理?
呵呵,是我的错误!inputStream.read()返回-1说明已经读到了the end of the stream。对于有限容量的stream(比如来自文件的流)来说就是读尽了,对于未知容量的stream比如网络流,如果 read()返回-1,说明这个流可能已经被对端关闭了。总之就应该对这种情况进行处理。再读下去,也是-1。这篇文章对此有些所描述:http://publib.boulder.ibm.com/infocenter/zos/v1r9/index.jsp?topic=/com.ibm.zos.r9.rexa100/h1981605209.htm
Telnet概述及RFC: http://en.wikipedia.org/wiki/Telnet
common-net 的使用:http://www.informit.com/guides/content.aspx?g=java&seqNum=40
2009年2月3日星期二
对synchronized 的又一点理解
java里的synchronized给我的一个强烈印象是“同步资源”,或者说是利用对象的monitor进行序列化访问的手段。
当使用object.wait()而没有事先synchronized object时,问题出现了:IllegalMonitorStateException。
wait() 之前必须先过的这个对象上的锁。这就要依靠synchronized。因为
synchronized的基本作用是“获取对象上的monitor”。所谓的同步、序列化访问都是建立在monitor的作用之上的。也许把synchronized理解成获得锁的语句可能更接近事实。
sleep() yield()并没有释放锁,这是和wait()的巨大区别。
当使用object.wait()而没有事先synchronized object时,问题出现了:IllegalMonitorStateException。
wait() 之前必须先过的这个对象上的锁。这就要依靠synchronized。因为
synchronized的基本作用是“获取对象上的monitor”。所谓的同步、序列化访问都是建立在monitor的作用之上的。也许把synchronized理解成获得锁的语句可能更接近事实。
sleep() yield()并没有释放锁,这是和wait()的巨大区别。
2008年11月21日星期五
IMS SDS4.1 training
19,20号参加了Ericsson的IMS SDS4.1的培训。虽然目前还找不到那个公司需要用到这些技术,但是当听着黎巴嫩帅哥老师讲这以前看过的IMS术语心里还是有些开心。
==== 用一句话总结我还记得的术语吧。=======
UA: user agent。
UAC, UAS,C,S分别代表client, server。UAC UAS是相对的。
IMS Core network: 内部使用SIP协议。RTP...这些视频流走的不是ISM网络通道。
SIP 建立会话时使用SDP。SDP放在SIP的body中。
SIP 很像HTTP,有header, 有body。做练习时把SIP的request类型(message reqeust)小写了,结果发出的消息没有收到。
SIP 很像HTTP,有header, 有body。做练习时把SIP的request类型(message reqeust)小写了,结果发出的消息没有收到。
HSS 存放registered User信息,以及用户可以使用的服务(IP/port ...)。Service profile. 其中ifc决定了用户使用特定服务的特定条件。
ifc: Initial Filter Criteria
C-CSCF 从HSS中获得用户的service profile,然后去寻找service application server,比如PoC, WE-Share, IMS-MSG...
ifc: Initial Filter Criteria
C-CSCF 从HSS中获得用户的service profile,然后去寻找service application server,比如PoC, WE-Share, IMS-MSG...
P-CSCF 用户终端(UA)不是直接与C-CSCF talking的。每个UA都固化了P-CSCF 的地址。P-CSCF是与域相关的。
每个电信运营商有自己的domain。比如,chinamobile, vodafone...
Application Server通过SIP servlet处理SIP请求,进行response。SIP servlet像及了HttpServlet。
很遗憾,其它的IMS节点老师就没有再讲了。(Ericsson内部五天的课程,现在压缩成2天。)
==== SDS =====
SDS非常好用。熟悉eclipse的,学习曲线很平坦。SDS menu item提供了几个perspective。DNS, HSS, CSCF的设置很直观。比较炫的一个功能是可以把来来回回的SIP 请求以sequence图的形式画出来。非常直观,见图。
安装glassfish后,一直不能很好的启动glassfish。后来发现是防火墙的原因。同时,启动glassfish之前最好要把DNS, CSCF Server也启动了。
==== 一些规范 =====
- ICP java API: 用于windows/symbian UIQ3
- ICP C++ API: 用于S-60
- IJCU API: 用于J2me
- JSR 281 : 用于java phone。 IJCU是JSR281的subset. 针对的是IMS core。
- JSR 325: 还没有finalise。定义了OMA规范了的service, 针对的是IMS service那层。 比如IMPS,PoC...
- JSR116, SIP Servlet 1.0 JSR289,SIP Servlet 1.1
有个术语“IMS Client Framework”。这个framwork是手机的功能集。以上的API规范是IMS Client Framework之上的一层。
针 对android, iPhone, windows mobile平台的API现在还没有。移动终端太混乱了。虽然moto不自己玩自己了、Nokia买了Symbian和Qt、索爱不玩UIQ了,但是还是 有micrisoft, google, apple。以后不知道谁会被整合到谁的手里。
订阅:
博文 (Atom)