tag:blogger.com,1999:blog-32254992685563478052024-02-06T19:43:12.431-08:00technology for allpipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.comBlogger38125tag:blogger.com,1999:blog-3225499268556347805.post-87409849474252686952008-12-10T04:21:00.000-08:002008-12-11T16:35:45.462-08:00Benchmarking Oracle 10g XE<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHERYf8FvyeAa8oBUl8arSPDmvH38Xz_5MM-4hIy51UN3K4-sWsUE6UhBIrMEFDDGW5QYB7uElm1Mf9QZGognqYnLml0AfgH5OjrLd0tJBXMTm-O4xbiR6AVEP1D2i52JSoZTiyJzFLSs/s1600-h/OracleXE.PNG"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 158px; height: 97px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHERYf8FvyeAa8oBUl8arSPDmvH38Xz_5MM-4hIy51UN3K4-sWsUE6UhBIrMEFDDGW5QYB7uElm1Mf9QZGognqYnLml0AfgH5OjrLd0tJBXMTm-O4xbiR6AVEP1D2i52JSoZTiyJzFLSs/s400/OracleXE.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5278690106874901986" /></a>Free to develop, deploy, and distribute...<br /><br />Yes, that's the tagline for Oracle Database 10g <a href="http://www.oracle.com/technology/products/database/xe/index.html">Express Edition</a> (XE), an entry-level database based on the 10g R2 code base. Certain handicaps are imposed: only one database can be installed per machine, user data is limited to 4GB, only one CPU shall be used, and only up to 1GB of memory.<br /><br />Although there are several <a href="http://wiki.oracle.com/page/Database+Benchmarking?t=anon">database benchmarking</a> tools available, I've decided to try <a href="http://www.quest.com/benchmark-factory/">Benchmark Factory</a>. The licensed version allows you to simulate 100 users whereas the freeware version is limited to only 20 virtual users. <br /><br />My target database is an Oracle XE installed on a 32-bit Windows XP Pro system. I ran Benchmark Factory on another unit connected via a 100Mbps Ethernet LAN. Here are the workload benchmark results for 5, 10, 15, and 20 virtual users.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSzUuIpLyC3K1wS7xTKX0qJb-BxdjUW-VFdoNABEKyLnKbY0a_XEvGjh9PIzIFpfT1TybUrc_r70aOR6DBvc7x8FZZBzbNdkUaheIv2F2o1VKjJ0WQPu7ffRdN-KnB9Ms9juSrSR-WTHg/s1600-h/BF-TxnTime-20Users.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 214px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSzUuIpLyC3K1wS7xTKX0qJb-BxdjUW-VFdoNABEKyLnKbY0a_XEvGjh9PIzIFpfT1TybUrc_r70aOR6DBvc7x8FZZBzbNdkUaheIv2F2o1VKjJ0WQPu7ffRdN-KnB9Ms9juSrSR-WTHg/s400/BF-TxnTime-20Users.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5278198427961170082" /></a><br />I encountered ORA-12519 errors (TNS:no appropriate service handler found) before the number of virtual clients reached 20. This was resolved by increasing the number of processes specified in the server parameter file (spfile). This is done via the following SQL commands:<br /><br /><blockquote>SQL> <span style="font-style:italic;">alter system set processes=300 scope=spfile;</span><br />SQL> <span style="font-style:italic;">alter system set sessions=300 scope=spfile;</span></blockquote><br />Restart the database and verify that the new parameter values have taken effect. Execute the following SQL command to display the current values:<br /><br /><blockquote>SQL> <span style="font-style:italic;">select name, value from v$parameter where name in ('processes','sessions');</span></blockquote><br />XE's response times did not falter even up to 100 users. Here is the transaction-time vs user-load comparison graph for 20 to 100 virtual users. <br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZ3pBBPItGHaPZM94rSdG60dFBRcMnFgPk0yXQ0L-451kXqPob7-QrPmMM4g2qAaefqaKNv0E1FrQn76dC22oVThDoGXliWBaVeG3iUK6xyaLNbr-yTF3xc5hjW-Ldwm_2Rg3onZi6Mrc/s1600-h/BF-TxnTime-20-100Users.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 209px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZ3pBBPItGHaPZM94rSdG60dFBRcMnFgPk0yXQ0L-451kXqPob7-QrPmMM4g2qAaefqaKNv0E1FrQn76dC22oVThDoGXliWBaVeG3iUK6xyaLNbr-yTF3xc5hjW-Ldwm_2Rg3onZi6Mrc/s400/BF-TxnTime-20-100Users.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5278536656110747378" /></a><br />The 1GB memory restriction may have been breached at around 350 virtual users when I encountered ORA-12518 errors (TNS:listener could not hand off client connection). At 325 virtual users, the maximum qualified throughput (MQTH) is computed at 469.221 tpmC. The highest published TPC-C result can be found at <a href="http://tpc.org/tpcc/results/tpcc_results.asp?print=false&orderby=tpm&sortby=desc">TPC.org</a>. <br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizhLFPF6G8d47JvuK6BIMCM5LsFmZHWL5WTuuiGlWmoSB9aZtsWIbBNryAhzRKl5WAx1FVBUE39ag9XMybvSrsMTQy8OkuIe2RhMFGQcoZEJLXNxhuSg9IX0dZc8omHL955-hKsyfcqxc/s1600-h/BF-MQTH.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 123px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizhLFPF6G8d47JvuK6BIMCM5LsFmZHWL5WTuuiGlWmoSB9aZtsWIbBNryAhzRKl5WAx1FVBUE39ag9XMybvSrsMTQy8OkuIe2RhMFGQcoZEJLXNxhuSg9IX0dZc8omHL955-hKsyfcqxc/s400/BF-MQTH.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5278558811739950018" /></a>pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com0tag:blogger.com,1999:blog-3225499268556347805.post-544803584212407612008-11-17T06:32:00.000-08:002008-11-21T17:26:42.287-08:00ERP on a Flash.. in a Flash<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvZilgSlerfTM7vaAY8wceiMWgzloNtUyTqIlMuW5AfMPMjFyiUNg2hDlCMGq49FAXmhfmkzy_Tnmn8EMPpnXz7tURK9M6SVX4gc6ts1thxn37L2tnlDzwbTY84JHf5KbNHwl43q_XaJc/s1600-h/nanodrive.png"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px; height: 200px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvZilgSlerfTM7vaAY8wceiMWgzloNtUyTqIlMuW5AfMPMjFyiUNg2hDlCMGq49FAXmhfmkzy_Tnmn8EMPpnXz7tURK9M6SVX4gc6ts1thxn37L2tnlDzwbTY84JHf5KbNHwl43q_XaJc/s200/nanodrive.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5270151924870303298" /></a>My sister is wishing for a software to help her manage the raw materials inventory of her new bakery franchise. I think I'm going to end up as her Santa this year...<br /><br />Lots of ERP heavyweights abound the opensource community.. but I want something lighter. Something that can fit in a USB flash drive and delivered in a pouch -- an ERP on a Flash!<br /><br />And here's my magic combo: TinyERP 4.2.2 + Ubuntu Intrepid Ibex + 2GB Imation NanoDrive. <br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1p0c-btanE4CAGN7gg0T_MZpUxK041JUc3KbDc1w4cqaCFtylI3rCHatBUnUZti3VrtGf-6-HwCsiYvzsDFhSYTjzLWBSrvXaz4EX3vLByWHIFJUlXuB4OqqMj556uWnwfS7DErrE_Bs/s1600-h/openlogo.png"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 202px; height: 61px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1p0c-btanE4CAGN7gg0T_MZpUxK041JUc3KbDc1w4cqaCFtylI3rCHatBUnUZti3VrtGf-6-HwCsiYvzsDFhSYTjzLWBSrvXaz4EX3vLByWHIFJUlXuB4OqqMj556uWnwfS7DErrE_Bs/s320/openlogo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5270154559156573426" /></a>TinyERP is included in the Ubuntu repositories -- a promise of painless installation via a series of apt-gets. <a href="http://www.pendrivelinux.com/">PendriveLinux.com</a> has lots of guides on how to install Linux on a USB flash drive. I favored the <a href="http://www.pendrivelinux.com/2008/11/01/ubuntu-810-install-using-the-built-in-usb-installer/">Ubuntu 8.10 install using the built-in USB installer</a>. This method provides a persistence feature allowing you to save the changes on subsequent boots. <br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMyEMoVNo9IKm76oZh_ah6JBOmerrT_bVS64JeiTKMOEmpQF6HaOv4RLzTYrvlEiCbUcAOIB-gzcdReYS_Dgc7jeMzoL0JBoyqsE3Pm03v6XUjtpIe_EL35i21GA3CmjMPLhNADJ7BGfc/s1600-h/ubuntulogo.png"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 202px; height: 55px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMyEMoVNo9IKm76oZh_ah6JBOmerrT_bVS64JeiTKMOEmpQF6HaOv4RLzTYrvlEiCbUcAOIB-gzcdReYS_Dgc7jeMzoL0JBoyqsE3Pm03v6XUjtpIe_EL35i21GA3CmjMPLhNADJ7BGfc/s320/ubuntulogo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5270154727424539650" /></a>Once Ubuntu is installed and booted up, we need to issue a <span style="font-weight:bold;">sudo apt-get update</span> command in order to synchronize the package index files from their sources. But before doing that, let's edit the list of apt sources via the command <span style="font-weight:bold;">sudo vi /etc/apt/sources.list</span>. Uncomment the deb entry for the <span style="font-weight:bold;">intrepid universe</span> repository --- the TinyERP packages are contained here. Save the changes and issue the following commands to download the desired packages:<br /><br /><blockquote>sudo apt-get update<br />sudo apt-get install tinyerp-server<br />sudo apt-get install tinyerp-client<br /></blockquote><br /><br />At this point, the Postgres database server and client should be installed and two new accounts (postgres and terp) created. We still need to create the <span style="font-weight:bold;">terp</span> database and user... <br /><br /><blockquote>sudo /etc/init.d/postgresql* restart<br />sudo su - postgres -c "createdb -q --encoding=UNICODE terp"<br />sudo su - postgres -c "createuser -q --createdb --adduser terp"<br /></blockquote><br />..and restart the TinyERP server.<br /><br /><blockquote>sudo /etc/init.d/tinyerp-server restart<br /></blockquote><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhun2SnaAY2_l6c2CvRgp_0HePHxtGz1MHhVZCM7z1ulf5G0Qzs_uHSQ-4ZvyPMfljUOKbUrwYfx_TuVTRmuvaPSXGq0HXO-53IEkxL16Uqqpir8I2R_kwhfXcFumcxCkIgvua6QvtP6XA/s1600-h/terp-login"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 179px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhun2SnaAY2_l6c2CvRgp_0HePHxtGz1MHhVZCM7z1ulf5G0Qzs_uHSQ-4ZvyPMfljUOKbUrwYfx_TuVTRmuvaPSXGq0HXO-53IEkxL16Uqqpir8I2R_kwhfXcFumcxCkIgvua6QvtP6XA/s320/terp-login" border="0" alt=""id="BLOGGER_PHOTO_ID_5270016013833939890" /></a><br />Press Alt-F2 and select Tiny ERP Client from the list of known applications. You can view the User Manual <a href="http://openerp.com/wiki/index.php/Documentation:UserManual">here</a> .<br /><br />TinyERP is re-branding itself and is now known as <a href="http://openerp.com/">OpenERP</a>.pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com2tag:blogger.com,1999:blog-3225499268556347805.post-71075735023175634362008-10-20T07:07:00.000-07:002008-10-21T06:18:29.640-07:00KnowledgeTree integration using Apache Camel<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj05XlkcjJ-rKjDupxhRf8ODPpBp7eLvQMiXlrKFu2v59ORv73XNExN3QvCblqau3c_HVdOq0AtT3uhv_FOVD-NSBteIyc5IIwHMJdYFwPWpkGhNF3jVu96yauYVTM8qQzossd8OBIk5Rk/s1600-h/ApacheCamel.PNG"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj05XlkcjJ-rKjDupxhRf8ODPpBp7eLvQMiXlrKFu2v59ORv73XNExN3QvCblqau3c_HVdOq0AtT3uhv_FOVD-NSBteIyc5IIwHMJdYFwPWpkGhNF3jVu96yauYVTM8qQzossd8OBIk5Rk/s200/ApacheCamel.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5259594248457077506" /></a>What the hump is Apache Camel?<br /><br /><a href="http://activemq.apache.org/camel/">Camel</a> is a Spring-based Integration Framework that implements routing and mediation rules using a Java-based Domain Specific Language (DSL or Fluent API), via a Spring-based XML configuration files or via Scala DSL.<br /><br />The upcoming version 1.5 release includes a <a href="http://activemq.apache.org/camel/tutorial-axis-camel.html">tutorial</a> using Axis 1.4 with Camel. I used this example as a springboard to craft a document publisher to <a href="http://www.knowledgetree.com/">KnowledgeTree</a> document management system via it's Axis-based web services.<br /><br />The basic document publisher picks up an XML file, uploads it to KnowledgeTree using Apache HttpClient, and invokes KnowledgeTree's add_document webservice to include the file into the document repository. Here is the associated routing rule:<br /><br /><blockquote><code><small>from("file:src/data?delete=true").process(ktDocUploader).to("file://target/test?noop=true");</small></code></blockquote><br />Once the document-uploader function is implemented, the power and versatility of Camel as a routing and mediation framework comes into play. Camel supports a wide array of <a href="http://activemq.apache.org/camel/components.html">components</a> allowing for more points of integration. In the above example, the File endpoint can easily be changed to FTP, SMTP, or JMS messaging without affecting the Processor code.<br /><br />Route interceptors can be used to insert simple tasks like logging or complex ones like payload inspection for conditional application of logic.<br /><br /><blockquote><code><small>intercept(xpath("/person[@user='rexjun']")).to("log:VIP").proceed();<br /></small></code></blockquote><br />A delivery failure is handled automatically by the <a href="http://activemq.apache.org/camel/dead-letter-channel.html">Dead Letter Channel</a> processor. I wanted failed deliveries to be deposited to another folder and this rule was implemented by a single line of code:<br /><br /><blockquote><code><small>errorHandler(deadLetterChannel("file://target/errors"));</small></code></blockquote><br />Aside from the Dead Letter Channel processor, Camel supports most of the <a href="http://activemq.apache.org/camel/enterprise-integration-patterns.html">Enterprise Integration Patterns</a> and lends itself as a component of the Apache <a href="http://servicemix.apache.org/home.html">ServiceMix</a> ESB project.<br /><br /><a href="http://activemq.apache.org/camel/architecture.html"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://activemq.apache.org/camel/architecture.data/camel-components.png" alt="" border="0"></a>pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com2tag:blogger.com,1999:blog-3225499268556347805.post-29142130786461513402008-08-05T19:30:00.000-07:002008-08-05T21:24:01.593-07:00ZK / Tomcat Hosting at EATJLast night, I attempted to upload my ZK app at GoDaddys's shared hosting servers. I've planned to do this for a long time already but I just kept on postponing a possibly dreadful experience. I don't like the idea of waiting 24 hours between <a href="http://help.godaddy.com/article/67">restarts</a> of its Tomcat service.<br /><br />So, how long is 24 hours? It's long enough to compel me to look for another webhosting service. In an hour or so, I was already up and running at <a href="http://s43.eatj.com/index.jsp">EATJ</a> web hosting solutions.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://tomcat.apache.org/"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6QFoC7yNRAEnX6CB23c59BO4NKioeEk1b-aTUAFZAW1uyleN9ijczfWLXU99t6ZWUGRBwsd5jX3IgDbq5_UGtxvoqh0uPvzz75orV76-hOEXgXivnvk0xjL5-ZaMU8LOElm7F2ncjbOY/s400/tomcat.gif" alt="" id="BLOGGER_PHOTO_ID_5231250189106823186" border="0" /></a>EATJ offers a free account for first-time users. For free accounts, the Tomcat JVM is shut down 4 times daily in order to save on server resources. Your Tomcat server, however, can be restarted easily within 30 secs via your control panel. The paid <a href="http://s41.eatj.com/plans.jsp">plans</a> enjoy 24x7 monitoring for continuous server uptime.<br /><br />I registered for a free account and got my control panel in just a couple of minutes. This <a href="http://s41.eatj.com/index.jsp?url=getting_started.html">guide</a> will help you get started and ready to deploy your own app. I created my own zk307.war file containing the ZK 3.0.7 jars as well as my ZK app and dependencies by executing the command <span style="font-style:italic;">jar cvf ..\zk307.war *</span> in the zk307 directory. <br /><br />The war file is rather chunky at 21mb (the free account allows for 50mb) and uploading it seemed to be the most challenging chore of all. I had to retry once for the two uploads I did. Here's the listing of the <span style="font-weight: bold;">webapps</span> directory contents in the remote server.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvQrkH_ZhUc33S8DnUsPzoa8XqYXxKVMmkQ8jKmC7JrH7TLRnXegtWHuTX1hTHXnHA_7Y_RFI1bMycqqwfbmw3NLzWjNuixbM3PlsTBVGG3PmY5Npi97xY3frN1U1nmpw2ViG2tYBXa_U/s1600-h/eatj-dir-contents.PNG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvQrkH_ZhUc33S8DnUsPzoa8XqYXxKVMmkQ8jKmC7JrH7TLRnXegtWHuTX1hTHXnHA_7Y_RFI1bMycqqwfbmw3NLzWjNuixbM3PlsTBVGG3PmY5Npi97xY3frN1U1nmpw2ViG2tYBXa_U/s400/eatj-dir-contents.PNG" alt="" id="BLOGGER_PHOTO_ID_5231247844220346306" border="0" /></a><br />Restart the Tomcat server and taadaaaa... my ZK app remotely-hosted at <a href="http://rexjun.s43.eatj.com/zk307/k3soap.zul">http://rexjun.s43.eatj.com/zk307/k3soap.zul</a>!<br /><br />If you happen to catch my Tomcat service down, don't wait for me to restart it.. instead, create your own in under an hour!pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com2tag:blogger.com,1999:blog-3225499268556347805.post-53439070998035295912008-08-03T16:44:00.000-07:002008-12-10T05:27:11.275-08:00ZK Version 3.0.7 released<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://zkoss.org/"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiN1PAVCIXwa4gx2m0enukPkDWjc-6e1Iuq7GJ7Jv-EI-PvUxNVb3w4pz-fqDwrpKVIIn4eOtcOP5i1mZ7CwDQEWSY6B8Z_mUc4MW_2fqjpJ9hDwPGtowrw8WEvB0ORGs_uGUgRjQLMREM/s400/ZK-Logo.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5230453645159039842" /></a>The ZK front-end app to KnowledgeTree was developed using version 3.0.6. The newer version 3.0.7 was released on August 1 and I had the chance to install ZK from scratch and run the ZK front-end app successfully.<br /><br />Here are the steps:<ul><li>download zk-bin-3.0.7.zip from <a href="http://sourceforge.net/project/showfiles.php?group_id=152762&package_id=169309&release_id=617052">sourceforge.net</a></li><li>copy the MyApp directory (from the demo package) under the webapps directory of Apache Tomcat. Rename it to accordingly (I used zk307 in this example).</li><li>Create the WEB-INF/lib sub-directory. Place here all the jars found under the dist/lib directory of the zk-bin-3.0.7 package. Copy the jars under the ext and zkforge directories also but omit the directories - place all jars under WEB-INF/lib</li><li>Add the ktws.jar and the jars required by Apache Axis (see previous blog <a href="http://pipoltek.blogspot.com/2008/07/using-knowledgetree-soap-services-from.html">entry</a>)</li></ul><br />Fire up Tomcat and point your browser to http://localhost:8080/zk307/ktlogin.zul<br /><br />There are over 9 new features and 22 bug fixes under this new release. Read more about the new ZK release <a href="http://zkoss.org/release/rn-3.0.7.dsp">here</a>.pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com1tag:blogger.com,1999:blog-3225499268556347805.post-8901121636962153952008-08-02T09:52:00.000-07:002008-08-02T11:38:32.687-07:00ZK + SOAP + KnowledgeTreeHere's a working <a href="http://www.zkoss.org/">ZK</a> app that performs a SOAP login to KnowledgeTree's web services.<br /><br /><img src="http://i245.photobucket.com/albums/gg58/pipoltek/blogs/zkApp.png" width="100%" /><br /><br />I've uploaded the source code to a KnowledgeTree repository and can be downloaded using the <a href="http://pipoltek.blogspot.com/2008/06/knowledgetree-document-download-via.html">KT-Gadget</a>.<br /><br /><table width="190" align="right" background="http://i245.photobucket.com/albums/gg58/pipoltek/blogs/ktloginbg.png" height="208"><tbody><tr><td align="center"><img src="http://i245.photobucket.com/albums/gg58/pipoltek/blogs/a-load.gif" /></td></tr></tbody></table> You need to download the following files:<ul><li>ZK front-end app (ktlogin.zul)</li><li>ZK include script (ktlogin.zk)</li></ul>You can download the Ajax spinner <a href="http://i245.photobucket.com/albums/gg58/pipoltek/blogs/a-load.gif">here</a> or create your <a href="http://www.ajaxload.info/">own</a>.<br /><br />My testbed:<br /><ul><li>Apache Tomcat Version 5.5.26</li><li>ZK 3.0.6</li><li>Windows XP Prof Service Pack 2<br /></li><li>Mozilla Firefox 3.0</li></ul>pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com0tag:blogger.com,1999:blog-3225499268556347805.post-65367843572252056522008-07-20T03:13:00.000-07:002008-12-10T05:27:11.545-08:00Using KnowledgeTree SOAP Services from Java apps<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMneZsUR1C1OM9QSySmNT4w3b7xhOFAaZn9QpvHCROrfN7mnwejsyedu_7sXFLLmcGgfjC8etsoiW95PYT7Et8dy9YSuaDpDJbhziB7Dg7TEEZ3FES-qjhSiKd3Np-U7d5OPvathJ1r0E/s1600-h/zklogin.PNG"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMneZsUR1C1OM9QSySmNT4w3b7xhOFAaZn9QpvHCROrfN7mnwejsyedu_7sXFLLmcGgfjC8etsoiW95PYT7Et8dy9YSuaDpDJbhziB7Dg7TEEZ3FES-qjhSiKd3Np-U7d5OPvathJ1r0E/s320/zklogin.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5225094053474868226" /></a>I'm making a front-end to <a href="http://www.knowledgetree.com/">KnowledgeTree</a> using the <a href="http://zkoss.org/">ZK</a> Ajax framework so I eventually dipped my fingers into KT's web service integration from a Java app. My previous SOAP projects involved a <a href="http://pipoltek.blogspot.com/2008/01/tcl-webservices-client-for.html">Tcl client</a> and a <a href="http://pipoltek.blogspot.com/2008/06/accessing-soap-services-from-google.html">Google gadget</a> using the javascript/php combo.<br /><br />KnowledgeTree's wiki article on <a href="http://wiki.knowledgetree.com/Web_service_integration_using_Java">Web Service integration using Java</a> has been most helpful. Since I'm doing my development work on Windows, I've adapted the procedures slightly. And since ZK uses the <a href="http://www.beanshell.org/">Beanshell</a> interpreter to execute the Java code, I also modified the tester client application accordingly.<br /><br />What's needed:<br /><ul><li> <a href="http://www.apache.org/dyn/closer.cgi/ws/axis/1_4">Apache Axis 1.4</a></li><li><a href="http://www.beanshell.org/download.html">Beanshell interpreter</a></li><li>Java SE Runtime Environment (JRE)</li><li>proxy classes in a jar file (<a href="http://pipoltek.com/WEB-INF/lib/ktws.jar">ktws.jar</a>)<br /></li></ul>The proxy classes were generated using the <a href="http://ws.apache.org/axis/java/user-guide.html#WSDL2JavaBuildingStubsSkeletonsAndDataTypesFromWSDL">WSDL2Java</a> utility provided by the Apache Axis. I'm providing the packaged ktws.jar available for download <a href="http://pipoltek.com/WEB-INF/lib/ktws.jar">here</a>. To generate the proxy classes yourself, you would need the Java Compiler and not just the JRE. Here's the batch file to generate the jar package.<br /><small><pre><br />set CP=axis-1_4/lib/axis.jar;axis-1_4/lib/commons-discovery-0.2.jar<br />set CP=%CP%;axis-1_4/lib/commons-logging-1.0.4.jar;axis-1_4/lib/jaxrpc.jar<br />set CP=%CP%;axis-1_4/lib/log4j-1.2.8.jar;axis-1_4/lib/saaj.jar<br />set CP=%CP%;axis-1_4/lib/wsdl4j-1.5.1.jar<br />java -cp %CP% org.apache.axis.wsdl.WSDL2Java -c T1 -p com.pipoltek.ktws http://docs.pipoltek.com/ktwebservice/webservice.php?wsdl<br />"%JAVA_HOME%\bin\javac" -d . -classpath %CP% com/pipoltek/ktws/*.java<br />"%JAVA_HOME%\bin\jar" cvf ktws.jar .\com\pipoltek\ktws\*.class<br /></pre></small><br />Here's the Beanshell script to execute a login via SOAP. <br /><small><pre><br />/*<br />filename: ktsoaptest.bsh<br />to run, type from the command-line:<br /> java -cp bsh-2.0b4.jar bsh.Interpreter ktsoaptest.bsh<br />*/<br /><br />// add axis classes<br />addClassPath ("./axis-1_4/lib/axis.jar");<br />addClassPath ("./axis-1_4/lib/axis-ant.jar");<br />addClassPath ("./axis-1_4/lib/jaxrpc.jar");<br />addClassPath ("./axis-1_4/lib/commons-logging-1.0.4.jar");<br />addClassPath ("./axis-1_4/lib/commons-discovery-0.2.jar");<br />addClassPath ("./axis-1_4/lib/log4j-1.2.8.jar");<br />addClassPath ("./axis-1_4/lib/wsdl4j-1.5.1.jar");<br />addClassPath ("./axis-1_4/lib/saaj.jar");<br /><br />// knowledgetree proxy classes<br />addClassPath ("./ktws.jar");<br /><br />// others<br />addClassPath ("./lib/activation.jar");<br />addClassPath ("./lib/mail.jar");<br /><br />import com.pipoltek.ktws.KnowledgeTreeBindingStub;<br />import com.pipoltek.ktws.Kt_response;<br />import com.pipoltek.ktws.Kt_folder_contents;<br />import com.pipoltek.ktws.Kt_workflow_transitions_response;<br />import org.apache.axis.client.Service;<br />import java.net.URL;<br />import com.pipoltek.ktws.Kt_folder_item;<br /> <br />URL url = new URL("http://kt352c.pipoltek.com/ktwebservice/webservice.php"); <br /> <br />KnowledgeTreeBindingStub stub = new KnowledgeTreeBindingStub(url, new Service());<br /> <br />System.out.println("Logging into KnowledgeTree");<br />Kt_response response = stub.login("rexjun","cabanilla","127.0.0.1");<br /> <br />int status_code=response.getStatus_code();<br />String session;<br />if (status_code == 0) {<br /> session = response.getMessage();<br /> System.out.println("Session: " + session);<br />} else {<br /> System.out.println("Status Code: " + status_code);<br /> System.out.println("Session: " + response.getMessage());<br /> return;<br />}</pre></small><br />I'll be using this piece of code to invoke SOAP services from my ZK app. More on this later..pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com1tag:blogger.com,1999:blog-3225499268556347805.post-48735856565621110052008-06-20T09:15:00.000-07:002008-12-10T05:27:11.622-08:00KnowledgeTree document download via Google Gadget<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXUz4Ee0qkZdlET-eYhAnOOBYFLWxwNdnQGxPfi5h8-HYW3aQdz851v4tOw6i_4g2Vp-ezae4gRTdlGj0CtFOnIvolOgL_SmJ6nmi5ytqeF-EDZbO5eU3BknkbHjY6CmUwod4qkm6zZaw/s1600-h/ktg-docdetails.PNG"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXUz4Ee0qkZdlET-eYhAnOOBYFLWxwNdnQGxPfi5h8-HYW3aQdz851v4tOw6i_4g2Vp-ezae4gRTdlGj0CtFOnIvolOgL_SmJ6nmi5ytqeF-EDZbO5eU3BknkbHjY6CmUwod4qkm6zZaw/s320/ktg-docdetails.PNG" alt="" id="BLOGGER_PHOTO_ID_5214504894002549682" border="0" /></a>This is an installment feature for the <a href="http://www.google.com/ig/directory?url=hosting.gmodules.com/ig/gadgets/file/109975195701238751540/kt-gadget.xml">KT-Gadget</a>, a widget for KnowledgeTree, an open-source document management system.<br /><br />As mentioned in the previous post, I employed an application proxy to act as a bridge between a Google Gadget and KnowledgeTree's SOAP services. Originally, the application proxy responses were formatted in XML. Moving forward, I decided to adopt the JSON format instead of XML owing to simpler methods in handling JSON feeds from both PHP and (of course) Javascript worlds.<br /><br />The application proxy's SOAP client is based on PHP and converting an associative array of response items to JSON format is implemented simply by using PHP's <a href="http://us.php.net/manual/en/function.json-encode.php">json_encode</a> function. At the gadget side, the requests for remote data are invoked using Google's <a href="http://code.google.com/apis/gadgets/docs/legacy/remote-content.html#Fetch_text">_IG_FetchContent</a> function. Using Javascript's eval() function, the returned JSON text response is converted to an object whose members can be easily accessed using dot or subscript operators.<br /><br />Here are the details.. To download a document, KT-Gadget sends a request to the helper application by invoking the url:<br /><blockquote>http://kt-gadget.pipoltek.com/pipoltek.com/json/?oid=download_document&sid=rsop4e364ptf4slkp2a2vtvb96&did=4</blockquote><br />The JSON response by the application proxy is of the form:<br /><blockquote>{"response":{"status_code":0,"message":"http:\/\/docs.pipoltek.com\/ktwebservice\/download.php?code=d2db2c0868ab0c9cd053fe2e43ab9926d1bcf94c&d=4&u=6a0j9qqpqc11de6nju6o0ej5o7"}}</blockquote><br />The relevant block of KT-Gadget code is reproduced hereunder:<pre><br /> var url = "http://kt-gadget.pipoltek.com/pipoltek.com/json/?oid=get_folder_contents&sid=" + sessionID__MODULE_ID__ + "&fid=6"; <br /> _IG_FetchContent(url, function (jsonFeed) {<br /> var jsonData = eval('(' + jsonFeed + ')');<br /> if (jsonData.response.status_code != 0) {<br /> alert ('Error in retrieving document!');<br /> } else{<br /> dd_link = jsonData.response.message;<br /> _gel("ktg-lnk").innerHTML = '<a href="' + dd_link + '">@';<br /> }<br /> })<br /></pre><br />Once the application proxy has responded, the JSON text response (jsonFeed) is converted to an object (jsonData) using the eval() function. The response contains the download URL the value of which can be referenced as jsonData.response.message.<br /><br />Where did the Session-ID (sid) and Document-ID (did) used as URL parameters come from? The Session-ID is assigned during login and the Document-ID, together with the rest of the document details, is returned by a call to get_folder_contents.<br /><br />Here's the login invocation:<br /><blockquote><a href="http://kt-gadget.pipoltek.com/pipoltek.com/json/?oid=login&uid=rexjun&pwd=cabanilla" target="_blank">http://kt-gadget.pipoltek.com/pipoltek.com/json/?oid=login&uid=rexjun&pwd=cabanilla</a></blockquote><br />The invocation to get_folder_contents:<br /><blockquote><a href="http://kt-gadget.pipoltek.com/pipoltek.com/json/?oid=get_folder_contents&sid=0j8jkhjn55t7r3b0rshbcchpn1&fid=6" target="_blank">http://kt-gadget.pipoltek.com/pipoltek.com/json/?oid=get_folder_contents&sid=0j8jkhjn55t7r3b0rshbcchpn1&fid=6 </a></blockquote><br />If you get a "Session is invalid" error, it's because the link is using an ID of an expired session. Change the URL parameter (sid) to a fresh Session-ID returned by the login call to get better results.<br /><br />You may try out KT-Gadget by adding it to your iGoogle page or view the gadget source code <a href="http://www.google.com/ig/directory?url=hosting.gmodules.com/ig/gadgets/file/109975195701238751540/kt-gadget.xml">here</a>.pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com3tag:blogger.com,1999:blog-3225499268556347805.post-58509360837249334942008-06-12T16:16:00.000-07:002008-12-10T05:27:11.798-08:00Accessing Soap Services from Google GadgetsThe earlier gadget projects I developed have utilized third-party web services from a variety of sources:<br /><ul><li>Google Maps for geographic data</li><li>Google Docs spreadsheet as XML datasource<br /></li><li>IP-Geolocation (IP address->Country) service from HostIP.Info</li><li>User profile and gaming statistics as XML feeds from Xfire.</li></ul>Given the constraints of a space-restricted, remotely-hosted, javascript-only application, gadgets primarily rely on web services to provide richer data content without the attendant complexity. However, javascript is beset by <a href="http://www.mozilla.org/projects/security/components/same-origin.html">cross-domain</a> restrictions that even impact <a href="http://www.xml.com/pub/a/2005/11/09/fixing-ajax-xmlhttprequest-considered-harmful.html">xmlHttpRequest</a>, the very underpinnings of Ajax. Since Google gadgets are javascript apps, the same-origin security policy prevents it from making requests outside the domain it is running on.<br /><br />Although Google addressed this problem by providing the <a href="http://code.google.com/apis/gadgets/docs/legacy/remote-content.html#Fetch_XML">_IG_FetchXMLContent</a> function, it lacks support for https, SOAP and POST. It looks like the newer <a href="http://code.google.com/apis/opensocial/articles/makerequest.html">gadget.io.makeRequest</a> function is intended to address these deficiencies. However, the availability of the gadget.io.* functions in Google's production servers is yet forthcoming.<br /><br />I decided not to hold my breath..<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifZBMl3jOC6-ymNy4tZ1X-sN5PbgXzW0ba4ahyzNP0wgykEh6GAMyzAadmof0w2jFSz2ywkoBtKVCyXSYVevMAu7kerOrjW20U5htNA2t_lTzVODJ4LwwWIZxQQGhM-aRwznNsQOlb9_8/s1600-h/document-list.PNG"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifZBMl3jOC6-ymNy4tZ1X-sN5PbgXzW0ba4ahyzNP0wgykEh6GAMyzAadmof0w2jFSz2ywkoBtKVCyXSYVevMAu7kerOrjW20U5htNA2t_lTzVODJ4LwwWIZxQQGhM-aRwznNsQOlb9_8/s320/document-list.PNG" alt="" id="BLOGGER_PHOTO_ID_5211943848872257426" border="0" /></a><br /><br /><a href="http://www.google.com/ig/directory?url=hosting.gmodules.com/ig/gadgets/file/109975195701238751540/kt-gadget.xml">KT-Gadget</a> is a widget front-end to <a href="http://www.knowledgetree.com/">KnowledgeTree</a> - an open-source document management system. To access KnowledgeTree's <a href="http://en.wikipedia.org/wiki/SOAP">SOAP</a> services, I had to deploy another application to receive the requests from Google's _IG_FetchXMLContent calls, make the corresponding SOAP requests, and generate the appropriate XML output. Two basic functions are implemented: login and get_folder_contents. The functions are based on <a href="http://www.php.net/manual/en/ref.soap.php">PHP</a>, the same language that was used to develop KnowlegeTree.<br /><br />After pushing the login button, the gadget will indicate the progress of the subsequent operations:<br /><ul><li>Logging in</li><li>Fetching Documents</li><li>Sorting Documents</li></ul>In its current state, the gadget is useful as a watcher of some sort of inbox for workflow-enabled documents like incoming faxes needing disposition or requisitions requiring approval. Sit around and watch your work pile up...<br /><br />I plan to implement two more functions: download_document and perform_document_workflow_transition. We don't want work to pile up, do we? Other nice-to-have features: watch all accessible folders and sub-folders; show number of documents per folder; folder and document colors based on certain thresholds like document count, age, metadata contents (priority, etc); automatic refresh. <br /><br />But don't hold your breath...pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com0tag:blogger.com,1999:blog-3225499268556347805.post-75530993974497790542008-05-22T08:24:00.000-07:002008-06-01T06:54:47.915-07:00Xfire GadgetHave XML feed, will gadgetize.. <a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://hosting.gmodules.com/ig/gadgets/file/109975195701238751540/MyXfire-full.PNG"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px;" src="http://hosting.gmodules.com/ig/gadgets/file/109975195701238751540/MyXfire-full.PNG" border="0" alt="" /></a><br /><br /><a href="http://xfire.com">Xfire</a> provides xml feeds on gamer profiles, gameplays, friends, screenshots -- a whole lot of goodies. An Xfire gadget would be a good addition to one's blog, website or iGoogle. <br /><br />One of the goals was to determine how close the gadget can resemble the real thing so it was initially developed using the default Xfire skin. Making a cross-browser scrollable table was not a trivial task and once the problem was solved, I started to hate the over-sized scroll bars. More coding lies ahead..<br /><br />Employing the Ajax paradigm of single-page experience, remote services, rich visual controls and other design patterns, any web app can now come real close to the regular desktop UI. <br /><br />A live gadget using a COD4 skin is displayed in another <a href="http://gog-xfire.blogspot.com/">blog</a>.pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com0tag:blogger.com,1999:blog-3225499268556347805.post-13440198397604718922008-04-22T07:28:00.000-07:002008-12-10T05:27:12.266-08:00OpenID login for Knowledgetree<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNIytTCILJcM8tttFbRiiL1HnqDBYGaglEMX7eeZTDaO29lX0iE4AzyifKWOHh7BgoFlbXNgd9R3IUkoPIATwVQ7G5HQtL0Lncd1fZ5OPSiZ5hHJS4GqclGjYeXJ2CsIxeG1i9_TRgKio/s1600-h/ktree-opid-login.PNG"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNIytTCILJcM8tttFbRiiL1HnqDBYGaglEMX7eeZTDaO29lX0iE4AzyifKWOHh7BgoFlbXNgd9R3IUkoPIATwVQ7G5HQtL0Lncd1fZ5OPSiZ5hHJS4GqclGjYeXJ2CsIxeG1i9_TRgKio/s320/ktree-opid-login.PNG" alt="" id="BLOGGER_PHOTO_ID_5193953805253742466" border="0" /></a>I have replaced (not integrated) KnowledgeTree authentication with OpenID. Supporting both default and OpenID authentication requires more work and that can come later.<br /><br />This is by no means final since only limited testing has been performed so far. I've decided to post this in its raw form so I can solicit comments and suggestions from the community. And besides, my blog has not been updated for awhile now..<br /><br />I'll detail the procedures here. I took notes but I may have missed something. Diligence is not one of my virtues..<br /><ul><li> Copy login.php to login-orig.php (save original, let's modify login.php)</li><li> Change template ktcore/login -> ktcore/openid </li><li> Copy ./templates/ktcore/login.smarty to openid.smarty<br /><small>- change invocation of stylesheet kt-login.css -> kt-openid.css<br />- change the Username prompt label to OpenID<br />- add class="openid" to input tag for username<br />- change name="username" to name="openid_url"<br />- remove the password input field</small></li><br /><li>Download the OpenID logo <img src="http://openid.net/wp-content/uploads/2007/10/openid_small_logo.png" /><br /></li><li>Upload logo as openid-bg.png to ./resources/graphics</li><li>Copy ./resources/css/kt-login.css to kt-openid.css</li><li>Add input.openid to kt-openid.css, as follows:<br /><small><pre>input.openid {<br /> border: 1px solid #666;<br /> width: 232px;<br /> background: url(../graphics/openid-bg.png) no-repeat;<br /> padding-left: 18px;<br />}</pre></small></li></ul>Note the OpenID logo <img src="http://openid.net/wp-content/uploads/2007/10/openid_small_logo.png" /> in the input field. This is implemented by the input.openid section of the stylesheet. I also changed the input field name to <span style="font-weight: bold;">openid_url</span> in conformance to OpenID <a href="http://wiki.openid.net/OpenID_Login_Box">specifications</a>. I'm using <a href="http://pipoltek.blogspot.com/2008/04/verisign-labs-pip-my-favorite-openid.html">Verisign PIP</a> as OpenID Identity Provider and the Seatbelt browser plug-in kicks in only when <span style="font-weight: bold;">openid_url</span> is used as identifier.<br /><br />I installed version 2.x.x of the <a href="http://openidenabled.com/php-openid/">PHP OpenID Library</a>, as follows:<br /><ul><li> Create the directory ./thirdparty/OpenID</li><li> Copy the file common.php found in the examples directory. Also copy the Auth directory from the library. </li><li> Add the following functions to common.php<br /><small><pre>function fixslashes($s) {<br /> return get_magic_quotes_gpc() ? stripslashes($s) : $s;<br />}<br /><br />function normOpenIDUrl($oid_url) {<br /> $claimed_id = strtolower (fixslashes($oid_url));<br /> $has_scheme = preg_match ('#^https\://#', $claimed_id) === 1;<br /> $has_scheme = $has_scheme || preg_match ('#^http\://#', $claimed_id) === 1;<br /> $has_tslash = preg_match ('#/$#', $claimed_id) === 1;<br /> return (($has_scheme?'':'http://') . $claimed_id . ($has_tslash?'':'/'));<br />}</pre></small></li><li> Overwrite the original functions in common.php with these<small><pre>function getReturnTo() {<br />return sprintf("%s://%s:%s/login.php",<br /> getScheme(), $_SERVER['SERVER_NAME'],<br /> $_SERVER['SERVER_PORT']);<br />}<br /><br />function getTrustRoot() {<br />return sprintf("%s://%s:%s/",<br /> getScheme(), $_SERVER['SERVER_NAME'],<br /> $_SERVER['SERVER_PORT']);<br />}</pre></small></li><li> Change config/dmsDefaults.php to include the library in the path.. <small><pre>$KTInit->prependPath(KT_DIR . '/thirdparty/OpenID');</pre></small></li></ul>The rest of the changes are in login.php, the source of which can be found <a href="http://pipoltek.com/openid/ktree/login.phps">here</a>.<br /><br />I've disabled automatic sign-up so make sure to create an OpenID account with Administrator privileges before you apply the changes. To prevent duplicate accounts, the usernames are OpenID URLs in normalized form (with leading http:// and trailing /). Thus, the username http://pipoltek.blogspot.com/ applies to any of the following acceptable OpenID identity URLs:<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXbLtmAQHLc5lB3jPu7Di1bxizL5L6xLJp2JqFnUjTpjRkFAXh9NMtemqbRJ4GhlID0XQDBANMWnY2r1Hh7BQ9Hr85rSpBGAu1xt3S4A5f_j9N3GwMs4v_o90kG9hm9Xd_6BjED3Wwldw/s1600-h/300px-OpenID_logo.svg.png"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXbLtmAQHLc5lB3jPu7Di1bxizL5L6xLJp2JqFnUjTpjRkFAXh9NMtemqbRJ4GhlID0XQDBANMWnY2r1Hh7BQ9Hr85rSpBGAu1xt3S4A5f_j9N3GwMs4v_o90kG9hm9Xd_6BjED3Wwldw/s200/300px-OpenID_logo.svg.png" alt="" id="BLOGGER_PHOTO_ID_5193989814259552146" border="0" /></a><ul><li>pipoltek.blogspot.com</li><li>http://pipoltek.blogspot.com</li><li>http://pipoltek.blogspot.com/ </li></ul>I've successfully authenticated using my OpenID accounts from Blogspot, Technorati and Verisign PIP. However, I had login failures using my Yahoo OpenID and a delegate identity URL.<br /><br />My testbed:<ul><li><a href="http://vmware.com/">VMWare</a> Server version 1.0.4.56528</li><li>KnowledgeTree OSS 3.4.2 VM Appliance from <a href="http://wiki.rpath.com/wiki/Appliance:KnowledgeTree_Appliance">rPath</a></li><li>Microsoft Windows XP Home Service Pack 2</li><li>Mozilla Firefox 2.0.0.14</li></ul>pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com1tag:blogger.com,1999:blog-3225499268556347805.post-24807333064156322962008-04-06T20:39:00.000-07:002008-12-10T05:27:13.270-08:00Verisign Labs PIP, my favorite OpenID Provider<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://openid.net/" target="_blank"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8tgagRc0BzgSsiSOtKBxfVM26Xw8lo4wQoYaxTuERWe210ogmhIOruA_xiHcVMJb1IZkDm94_3WkX5JOBxZMzC-TV0XDzO-cSjan1gRzIIBw_OtYodKrtIaIdGXeqtAk9w6NpuISb9l8/s320/logo.jpg.png" alt="" id="BLOGGER_PHOTO_ID_5186439932741737474" border="0" /></a>As a long-time user of Yahoo, Blogger, and <a href="http://technorati.com/weblog/2006/12/228.html">Technorati</a>, I inherited the following OpenIDs:<br /><ul><li>pipoltek.blogspot.com</li><li>me.yahoo.com/rexjunjose</li><li>technorati.com/people/technorati/rexjun</li></ul>In due time, I may have another one courtesy of <a href="http://www.readwriteweb.com/archives/flickr_to_authenticate_openid.php">Flickr</a>. I enrolled at myopenid.com and that added rexjun.myopenid.com to my arsenal of OpenIDs.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://pip.verisignlabs.com/" target="_blank"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjX-lhIQCWIdhbbu7hD5Wr8qiuRjsarlCwBJdm86dYqNj5rfeaa7SUfubUx2svttwvAkwvNh5KpoDcR_OK9LJtEbVvahpN4Ff29eg24B_PcWCMCPMlVNiDX0uHVTv3oRD0hIBwHCnyyF9M/s320/viplogo.gif" alt="" id="BLOGGER_PHOTO_ID_5186430488108653522" border="0" /></a><br />My last OpenID provider might as well be the PIP, or <a href="https://pip.verisignlabs.com/">Personal Identity Provider</a>, from Verisign Labs. And this is primarily due to their <a href="https://pip.verisignlabs.com/seatbelt.do">Seatbelt</a> Firefox plugin which adds ease and security when using your OpenID.<br /><br /><blockquote>SeatBelt detects that you have clicked on an OpenID sign in field while not signed into your PIP account and prompts you to sign in. Once you have signed in, SeatBelt automatically returns you to the OpenID sign in page with your PIP URL filled in. The sign in session continues as normal.</blockquote><br />Since redirection to the login page of your OpenID provider is done by the Seatbelt browser plugin, you can be assured that you are sending your credentials to Verisign and not a probable fake one generated by a phishing site.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiB7Yz0PFy4vdfhorylS8vLvxpKBnyNESBOpHH3qiu-pg95Okr8VrEqdD6WNnHsr3ubRSRW8ZeSxNRcufYZujMxaQqRGBKU2RyKp7HuVRgaf35vWwtB2tZ_AajWIXYMoX-sGgChW6JrvG0/s1600-h/verisign-login-helper.PNG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiB7Yz0PFy4vdfhorylS8vLvxpKBnyNESBOpHH3qiu-pg95Okr8VrEqdD6WNnHsr3ubRSRW8ZeSxNRcufYZujMxaQqRGBKU2RyKp7HuVRgaf35vWwtB2tZ_AajWIXYMoX-sGgChW6JrvG0/s320/verisign-login-helper.PNG" alt="" id="BLOGGER_PHOTO_ID_5186437355761359842" border="0" /></a><br />One other neat feature is support for OpenID delegation allowing me to use pipoltek.com as my OpenID URI in place of the lengthy rexjun.pip.verisignlabs.com. This is made possible by adding two link tags inside the head section of my home page.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuX3t4F41T_9BhTuSEJ0yXdr9Mior_KQUWverWWtMBsvh4ZnUhSLo9xhx2vEYVbqkVZWwDsIA5ZND7ED6ffzj6pMZhxC5Ozb5k1hWkNUc7Zi57zuBvhH1y6Jg5pXurMjAgsjUB4xb4CWY/s1600-h/oid-del-link.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuX3t4F41T_9BhTuSEJ0yXdr9Mior_KQUWverWWtMBsvh4ZnUhSLo9xhx2vEYVbqkVZWwDsIA5ZND7ED6ffzj6pMZhxC5Ozb5k1hWkNUc7Zi57zuBvhH1y6Jg5pXurMjAgsjUB4xb4CWY/s400/oid-del-link.png" alt="" id="BLOGGER_PHOTO_ID_5186412449246010274" border="0" /></a><br />Wait.. there's more! You can protect your Verisign PIP account with <a href="https://idprotect.verisign.com/orderstart.v">two-factor</a> authentication by the use of a security card, token, or a Sandisk U3 flash drive. Verisign PIP even supports the US$5 <a href="https://www.paypal.com/securitykey">Paypal security key</a> aside from its own.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4x40FhxpXecZuF7rIuXvUieMHZ-guCVM0KeTBfN7G3jSc3jCr7Gb91nV0I4utL9XfkjxRd-qRaUYsbmjua8l51iLjAQ_HwaO9jVt8hQs20rKzSUKpJA5N7BvhF2MNA6B75S1R7Af41_8/s1600-h/pip-sec-tok.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4x40FhxpXecZuF7rIuXvUieMHZ-guCVM0KeTBfN7G3jSc3jCr7Gb91nV0I4utL9XfkjxRd-qRaUYsbmjua8l51iLjAQ_HwaO9jVt8hQs20rKzSUKpJA5N7BvhF2MNA6B75S1R7Af41_8/s320/pip-sec-tok.png" alt="" id="BLOGGER_PHOTO_ID_5186533674697940034" border="0" /></a><br />As a lead player in identity protection services and a recent member of the OpenID Foundation, one can expect Verisign to continue providing innovative solutions supportive of the OpenID framework. So far, I'm not disappointed.pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com0tag:blogger.com,1999:blog-3225499268556347805.post-5775441575735810982008-04-05T09:42:00.000-07:002008-12-10T05:27:14.883-08:00Getting and Using your OpenID<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://openid.net/"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTSx2C7pIRF3JuKLguvrW6_Jb3BqjWJmODrpt07EW2k8zSCZqtXWN67gBMR0QKx9GBu33rv100MKBcYpRJq1yKjHmV_-_QbJX3WexdHm18D5GemFyy32F7JAryyytyC9XJ8T0fzVgc5JM/s400/logo.jpg.png" alt="" id="BLOGGER_PHOTO_ID_5186039006134590338" border="0" /></a>I stumbled upon OpenID last year when I was foraging for single sign-on resources in the Internet. It is interesting to note that OpenID has grown by leaps and bounds in just over a couple of years since its inception in 2005. At the start of the year, OpenID's popularity ballooned when Yahoo! launched the <a href="http://developer.yahoo.net/blog/archives/2008/01/yahoo-openid-beta.html">public beta</a> of its own OpenID identity service. The following month, the <a href="http://openid.net/foundation/">OpenID Foundation</a> announced that heavyweights Google, IBM, Microsoft, VeriSign, and Yahoo! have joined its board. This recent development gives promise of significant things yet to come.<br /><br /><a href="http://openid.net/">OpenID</a> aims to simplify one's online experience by providing an account that can be used across multiple websites. Blogger already supports <a href="http://bloggerindraft.blogspot.com/2007/11/new-feature-openid-commenting.html">OpenID commenting</a> and a Wordpress <a href="http://wordpress.org/extend/plugins/openid/screenshots/">plug-in</a> is also available to achieve the same purpose. An OpenID is a passport to hundreds of sites listed <a href="http://openiddirectory.com/">here</a>.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_IZidtqky3gjdVyGaX9F0VcAqgzbSX8RWqtyNIPPmDOcpa39nAHKIO0z1LWvcS0f4EeMCQsjIqWZiWBB1kKN3CbsxfTjE-DsEAtH60Bd0jJ-2-ySU53_5oXik80VrNsqId7oP_f9r_BU/s1600-h/login-prompt.PNG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_IZidtqky3gjdVyGaX9F0VcAqgzbSX8RWqtyNIPPmDOcpa39nAHKIO0z1LWvcS0f4EeMCQsjIqWZiWBB1kKN3CbsxfTjE-DsEAtH60Bd0jJ-2-ySU53_5oXik80VrNsqId7oP_f9r_BU/s320/login-prompt.PNG" alt="" id="BLOGGER_PHOTO_ID_5186031532891495266" border="0" /></a><br />Some people strongly feel that using OpenID is akin to putting all eggs in one basket since a hacked account becomes a master-key to several sites all at once. The specter of <a href="http://marcoslot.net/apps/openid/">phishing</a> super-accounts is disturbing, and real. Privacy concerns are also associated with identity providers amassing too much personal data. One practical answer would be to have several OpenID accounts (there goes OpenID's mission) --- having five OpenIDs instead of juggling fifty accounts is still nirvana to me... Ok, make that thirty - I can't recall the twenty already! And anti-phishing <a href="http://benlog.com/articles/2007/02/06/beamauth-two-factor-web-authentication-with-a-bookmark/">counter-measures</a> need to be present, either built-in or as a supplement, OpenID or not. Identity-theft is not limited to phishing --- a significant chunk of the world's netizens can easily lose their online identity due to weak passwords, key-loggers or plain <a href="http://www.securityfocus.com/infocus/1527">social engineering</a> tactics.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://i25.tinypic.com/2pr8jsm.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 120px;" src="http://i25.tinypic.com/2pr8jsm.png" alt="" border="0" /></a>Ready to take on OpenID and its challenges? To enable a Yahoo! account for OpenID, start <a href="http://openid.yahoo.com/">here</a>. Most may not know it but <a href="http://dev.aol.com/aol-and-63-million-openids">AOL</a>, <a href="http://technorati.com/weblog/2006/12/228.html">Technorati</a>, and <a href="http://www.livejournal.com/openid/">Livejournal</a> users already have an OpenID associated with their accounts. A blog owner at Blogger or Wordpress can use their blog url (e.g. pipoltek.blogspot.com) as OpenID account. If you're not one of the millions of Yahoo (248M) or AOL (63M) users, or just want to experiment with OpenID, a host of public OpenID identity providers can be availed of <a href="http://wiki.openid.net/OpenIDServers">here</a>.<br /><br />Give it a spin by posting a <span style="font-style: italic;">hello</span> on this blog using your OpenID account.pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com2tag:blogger.com,1999:blog-3225499268556347805.post-92222591344677605332008-03-28T09:39:00.000-07:002008-12-10T05:27:15.252-08:00Circumventing IP GeolocationAlthough IP geolocation can be fairly accurate, it can also be easily thwarted with the use of global gateways or proxy servers that are geographically distant from the actual location of the user.<br /><br />Using <a href="http://api.hostip.info/" target="_blank">HostIP.info</a>'s IP geolocation service with an online PocketPC via <a href="http://smart.com.ph/Gold/Services/MmsGprs.htm" target="_blank">Smart GPRS</a> puts my location at Makati, Philippines. The country is correct but the city is a good 570 kilometers from mine, or an hour's ride by plane. <br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU3IV5vCejECjroUUkndklwiuvlXVLcEGGum7g0uLaoMObjqeCRLJcbqo080FQdgxt60QBGTBxcgB42OTkO6Kw-FhVkFGmV0rZU2hUAsDicPjv2hRxQIae_MsCtKPGrKPjgTW7QXiTXCY/s1600-h/gprs-ip-geo.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU3IV5vCejECjroUUkndklwiuvlXVLcEGGum7g0uLaoMObjqeCRLJcbqo080FQdgxt60QBGTBxcgB42OTkO6Kw-FhVkFGmV0rZU2hUAsDicPjv2hRxQIae_MsCtKPGrKPjgTW7QXiTXCY/s400/gprs-ip-geo.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5185016090953571106" /></a><br />On the other hand, using Anchorfree's <a href="http://www.anchorfree.com/downloads/hotspot-shield/" target="_blank">Hotspot Shield</a> wifi gateway plants me on the other side of the globe at Washington DC. Well, at least it's the same planet.. <br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2-XsZfOUw6m7KRawTVSNLGkiMWTUJiS5MwAVukipPg1QO3hE8Lu7fYqLtdXNAOXOwcCAzEl1N2BgF_kJLUoWAf5AgOYIB2b8W2Y1gjmbIWKvSBFroXv3QYaNk6UjWUAp-JK1l0gKPzCo/s1600-h/wifi-ip-geo.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2-XsZfOUw6m7KRawTVSNLGkiMWTUJiS5MwAVukipPg1QO3hE8Lu7fYqLtdXNAOXOwcCAzEl1N2BgF_kJLUoWAf5AgOYIB2b8W2Y1gjmbIWKvSBFroXv3QYaNk6UjWUAp-JK1l0gKPzCo/s320/wifi-ip-geo.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5185021425302952770" /></a>pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com0tag:blogger.com,1999:blog-3225499268556347805.post-70193694520392673252008-03-23T04:32:00.000-07:002008-12-10T05:27:15.603-08:00IP Geolocation GadgetGeolocation by IP address is the method of determining the geographic location of an Internet-connected device by examining data related to the IP address it is using. Google is effectively using <a href="http://searchengineland.com/070813-082025.php">geolocation</a> to deliver targeted content by redirecting Google visitors to pages translated into their local language. On the other hand, geolocation can also be used to filter content. Just recently, selected YouTube videos have been <a href="http://opennet.net/blog/?p=232">discovered</a> to bear special tags indicating that it is inappropriate for viewing in some countries .<br /><br />There are several IP geolocation services in the Internet so I gave some of them a spin. Here are the results according to increasing accuracy in determining my location.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXPpfxGpEnjU3XlT_FwmmhjGGqwg1Zx1Xo_UEuYgIIcdOGOIvxQTOZ9-Y2P75rcxniSD4bL_pSwKdQktHquutbiQHIuBT_dcue1mFwDHZw1D-NCD5vYiB1BoajAGe4Y1zLC_PJi0YEB24/s1600-h/ip2loc.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXPpfxGpEnjU3XlT_FwmmhjGGqwg1Zx1Xo_UEuYgIIcdOGOIvxQTOZ9-Y2P75rcxniSD4bL_pSwKdQktHquutbiQHIuBT_dcue1mFwDHZw1D-NCD5vYiB1BoajAGe4Y1zLC_PJi0YEB24/s320/ip2loc.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5183153891918273282" /></a><br />- <a href="http://www.ip2location.com/">IP2location</a> got my country right but was not able to provide my city.<br />- <a href="http://www.ipligence.com/">IPligence</a> got my city wrong.. or maybe it did not know my city and gave the national capital instead as default.<br />- <a href="http://www.geobytes.com/IpLocator.htm">Geobytes</a> and <a href="http://www.maxmind.com/app/mylocation">Maxmind</a> got my city right. <br />- <a href="http://www.hostip.info/">HostIP.info</a> not only got my city right but also has an API to go with it. And did I mention that the service is free? <br /><br />Point your browser to <a href="http://api.hostip.info/">http://api.hostip.info/</a> and you get an XML feed containing not only your City and Country but also your geographic coordinates as well. Sweet!<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhPDSxeWvuwA0UFskLfiqKCcxD9r_YJ3ZhIT_rM_AWTxGBa1-WJwI1PpgeLtufLgad4qiddgEh443gDPTecXqQBGk9LhqyRA3qs0b0fVGw0VTOo_K-rO9gOw7keClwoKuwjAV24QHo6RU/s1600-h/hostip.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhPDSxeWvuwA0UFskLfiqKCcxD9r_YJ3ZhIT_rM_AWTxGBa1-WJwI1PpgeLtufLgad4qiddgEh443gDPTecXqQBGk9LhqyRA3qs0b0fVGw0VTOo_K-rO9gOw7keClwoKuwjAV24QHo6RU/s320/hostip.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5182835677791312610" /></a><br />I can't resist the temptation to use this geolocation service and mix it up with Google Maps API into a Google gadget.. so I came up with another widget called <span style="font-weight:bold;">WTHAMI?</span>. Here it is in action..<br /><br /><center><a href="http://www.google.com/ig/adde?moduleurl=hosting.gmodules.com/ig/gadgets/file/109975195701238751540/ip-locator.xml" target="_blank"><img src="http://hosting.gmodules.com/ig/gadgets/file/109975195701238751540/WTHAMI-full.PNG"/></a></center><br />If it doesn't get your location right, don't sue me. You can update your location at <a href="http://www.hostip.info/index.html">HostIP.info</a>.pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com1tag:blogger.com,1999:blog-3225499268556347805.post-45472202716468877452008-03-22T10:33:00.000-07:002008-03-23T09:42:25.924-07:00Cebumapia, the Google GadgetI've always wondered if I could package Cebumapia as a <a href="http://code.google.com/apis/gadgets/">Google Gadget</a>.. After taking a peek at the other Gadget samples, I was determined to build it. The wondering stage is over now..<br /><br /><center><a href="http://www.google.com/ig/adde?moduleurl=hosting.gmodules.com/ig/gadgets/file/109975195701238751540/cebumapia.xml" target="_blank"><img align="center" src="http://hosting.gmodules.com/ig/gadgets/file/109975195701238751540/cebumapia-full.png"/></a></center><br /><br />The gadget uses the <a href="http://code.google.com/apis/maps/documentation/index.html">Google Maps API</a> to render the map, overlay markers and trigger events when the mouse hovers on markers and when these are clicked. Markers are stored in xml files and fetched using the gadget-specific _IG_FetchXmlContent function. <br /><br />The Cebumapia gadget code is miniscule - only 200 lines. But then, functionality is trimmed down to the very basic and UI is just as minimalistic. Take out the module header, css and html portions, and you are left with only 100 lines of javascript code. <br /><br />If you've been wanting to create your own killer gadget and thinking you don't have the time, <a href="http://code.google.com/apis/gadgets/docs/gs.html#Scratchpad">start now</a>! My advise.. Start with small reliable code and incrementally build on it. Me? I'm planning to add a local news feed.. spruce up the UI for an iPhone-ish look.. or maybe not.<br /><br />Add the Cebumapia gadget to your iGoogle page.. <a href="http://www.google.com/ig/add?moduleurl=http%3A%2F%2Fhosting.gmodules.com%2Fig%2Fgadgets%2Ffile%2F109975195701238751540%2Fcebumapia.xml" target="_blank"><img src="http://gmodules.com/ig/images/plus_google.gif"/></a><br /><br />See the gadget embedded in Blogger template at <a href="http://cebumapia.blogspot.com/">Cebumapia</a>.pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com0tag:blogger.com,1999:blog-3225499268556347805.post-410057784508750502008-03-13T09:13:00.000-07:002008-12-10T05:27:16.730-08:00Testing ZK Ajax Framework with iSeries/AS400 using JDBC<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7xf7Zoa7I1lDV1rrdqP_Mlm4yMWtonHZe5_mle9U_KpeQj1qCTKoRgf_ZNEakGP10KzCehQ_CfqBe3OXbmS9LwlKDJ7-hMthIlUCUiNfp2xJPu-pkAJDyqF0rj49gss9rlpJfg3fiQ7I/s1600-h/zkLogo.PNG"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7xf7Zoa7I1lDV1rrdqP_Mlm4yMWtonHZe5_mle9U_KpeQj1qCTKoRgf_ZNEakGP10KzCehQ_CfqBe3OXbmS9LwlKDJ7-hMthIlUCUiNfp2xJPu-pkAJDyqF0rj49gss9rlpJfg3fiQ7I/s400/zkLogo.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5177284869543534274" /></a>The <a href="http://www.zkoss.org/">ZK Ajax Framework</a> standalone zkdemo application has a sample program that uses JDBC to provide database support to an Ajax app. I decided to give it a try using an iSeries datasource. Here's how it was done..<br /><br />ZK downloads are <a href="http://www.zkoss.org/download/">here</a>.<br /><br />- Download ZK-quickstart-x.y.z.pdf <br />- Download and install <a href="http://tomcat.apache.org/download-55.cgi">Tomcat</a>. I used version 5.5 as this was the version referred to in the manual.<br />- Download zk-demo-x.y.z.zip and extract the package. Copy the zkdemo.war package to the webapps directory of Tomcat (C:\Program Files\Apache Software Foundation\Tomcat 5.5)<br />- Restart Tomcat and open the url <a href="http://localhost:8080/zkdemo/userguide/">http://localhost:8080/zkdemo/userguide/</a><br /><br />Shutdown Tomcat. I copied the ...\webapps\zkdemo directory to ...\webapps\myzk so I can make changes to the sample code without touching the demo application. I then copied ...\webapps\myzk\userguide\dbconnect\jdbc.zul to ...\webapps\myzk\dbconnect\jdbc.zul and modified the submit() function, as follows:<br /><small><pre><br />void submit() {<br /> // Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");<br /> // DriverManager.registerDriver(new com.ibm.as400.access.AS400JDBCDriver());<br /> Class.forName("com.ibm.as400.access.AS400JDBCDriver");<br /> // String url = "jdbc:odbc:Fred";<br /> String mySchema = "REXJUN1";<br /> String myAS400 = "m170pub1.rzkh.de";<br /> String myUserId = "REXJUN";<br /> String myPasswd = "-change-me-";<br /> String url = "jdbc:as400://" + myAS400 + "/" + mySchema;<br /> Connection con = DriverManager.getConnection(url,myUserId, myPasswd);<br /> PreparedStatement stmt = con.prepareStatement("INSERT INTO BASICJDBC values(?, ?)");<br /> //insert what end user entered into database table<br /> stmt.setString(1, id.value);<br /> stmt.setString(2, name.value);<br /> //execute the statement<br /> stmt.executeUpdate();<br /> //commit<br /> con.commit();<br /> //close the jdbc connection<br /> con.close();<br />}</pre></small><br />Add the jt400.jar from <a href="http://jt400.sourceforge.net/">JTOpen</a> to the ...\webapps\myzk\WEB-INF\lib directory. This jar file contains the JDBC driver for iSeries.<br /><br />Restart Tomcat. Opening the url <a href="http://localhost:8080/myzk/dbconnect/jdbc.zul">http://localhost:8080/myzk/dbconnect/jdbc.zul</a> should give you this..<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD73CMy-CK7MnvFVNh0NcaxG04kZlrGTOHZtmJnPDkHPsIMKOinmEpbd5pNvJblLDrpjkZGLFzXtN6rntML21cX1F1DcmMCelJqOZzdYrC6T_uymZTGixWyTomW1uiynP9s_2QyVmHIUs/s1600-h/DataEntry.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD73CMy-CK7MnvFVNh0NcaxG04kZlrGTOHZtmJnPDkHPsIMKOinmEpbd5pNvJblLDrpjkZGLFzXtN6rntML21cX1F1DcmMCelJqOZzdYrC6T_uymZTGixWyTomW1uiynP9s_2QyVmHIUs/s400/DataEntry.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5177281300425711266" /></a><br />A wrong password does not trigger an error and the application seems to hang -- the host system may have requested a password re-entry but the UI failed to render.<br /><br />Reviewing the file contents shows the successful addition of new records..<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnJkw54oeMyj6cR20ylHyjQaoc5rzoeYZkciOrNIB6zwcirQrkFIKy5XCT1UW0g_PLVTgO0W0T6_miFOjbZDxmg4eMffH7IzQES4gvN5B5xbHVCksYV7at3NQiP6ZhbBN4ZgBAhBOtfas/s1600-h/SQLReview.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnJkw54oeMyj6cR20ylHyjQaoc5rzoeYZkciOrNIB6zwcirQrkFIKy5XCT1UW0g_PLVTgO0W0T6_miFOjbZDxmg4eMffH7IzQES4gvN5B5xbHVCksYV7at3NQiP6ZhbBN4ZgBAhBOtfas/s320/SQLReview.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5177282554556161714" /></a><br />ZK also released <a href="http://www.zkoss.org/release/zkmob-rn-0.8.7.dsp">ZK Mobile 0.8.7</a> for the mobile platform on November 07, 2007.pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com0tag:blogger.com,1999:blog-3225499268556347805.post-71200775298057492182008-03-04T04:47:00.000-08:002008-12-10T05:27:17.130-08:00Gaga over Google MapsI gotta admit it, I'm hooked on <a href="http://maps.google.com/">Google Maps</a>, specifically its <a href="http://code.google.com/apis/maps/">API</a>. I've seen the maps of <a href="http://www.mtr.com.hk/eng/facilities/lm.html">Hongkong's MTR</a> system and with it you can practically plan your trips down to the nearest entry and exit points. <br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD6KtU3PstnHZCOBGRc05aZFSDLGakdfIJehjIyk4MxBwRM0dwicT7epAZIPAVngzI2SCpCsV0yo3C0XSnTgk21d6T-bPqHclur43-oIMv7SMFHzlHCHbXnqsnn0Bgmokr6rxv8R_Y2FQ/s1600-h/locmap-tst.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD6KtU3PstnHZCOBGRc05aZFSDLGakdfIJehjIyk4MxBwRM0dwicT7epAZIPAVngzI2SCpCsV0yo3C0XSnTgk21d6T-bPqHclur43-oIMv7SMFHzlHCHbXnqsnn0Bgmokr6rxv8R_Y2FQ/s400/locmap-tst.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5173888891594831922" /></a><br />Cebu of the Philippines is likewise a destination for many. Although several travel guides featuring Cebu abound on the web, maps are seldom employed to aid those needing directions. With the availability of rooftop-level satellite imagery offered by Google Maps, I decided to overlay Cebu's streets and places of interest with markers. To spice up the pages, I interspersed local info with impressive photos at <a href="http://www.panoramio.com/">Panoramio</a> and <a href="http://www.flickr.com/">Flickr</a> courtesy of camera enthusiasts.<br /><br />Before I forget, let me introduce you to <a href="http://cebumapia.blogspot.com/">Cebumapia</a> - a Google Map mashup of Cebu's places of interest! And shall I add, always a Work In Progress!<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpdmBxOzErxe9AWybtlNj_zzd60XIN60BpvSTYrirosC-xSlUZUrv9q2IlOa4e1-CwheSg-eSxTk6veY3cRf5ylP4LzBOw5IsqYxuVvZbXeJYn3LB3Zxh19BTwpvuBXgs7Wki3aJqko_M/s1600-h/welcome.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpdmBxOzErxe9AWybtlNj_zzd60XIN60BpvSTYrirosC-xSlUZUrv9q2IlOa4e1-CwheSg-eSxTk6veY3cRf5ylP4LzBOw5IsqYxuVvZbXeJYn3LB3Zxh19BTwpvuBXgs7Wki3aJqko_M/s400/welcome.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5173888466393069602" /></a><br />I've started with markers, or should I say.. I planned to use only markers. But as complexity started to evaporate, I found myself twiddling with infowindows and polylines to spruce things up. After the 30th or so marker in place, I realized I barely scratched the surface... so many markers, so little time! I needed an easier way to add and modify map objects without further mangling the html and javascript code of my Blogger template. <br /><br /><a href="http://docs.google.com/">Google Docs</a> to the rescue! By migrating the coordinates, waypoints and even descriptions into Google spreadsheets, I can now change map info even without having to log into Blogger. Hmmm... I'm now thinking of letting visitors add their own sites so I don't have to do anything at all!<br /><br />I've learned a lot of new things already while building this site. Enjoy it as much as I did... or still do.pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com0tag:blogger.com,1999:blog-3225499268556347805.post-34079985851194357812008-02-06T08:59:00.000-08:002008-02-06T09:53:36.010-08:00Using Beanshell with the iSeries/AS400 JTOpen JDBC driverWhat seemed to be simple and straightforward task is not as what I expected it to be. And I'm referring to making <a href="http://jt400.sourceforge.net/">JTOpen</a> JDBC work with Beanshell. Isn't it supposed to be as easy as load and connect? I guess not..<br /><br />The common method of invoking java.sql.DriverManager to load the JTOpen JDBC drivers for IBM iSeries (erstwhile AS400) doesn't seem to work with Beanshell. The subsequent calls to DriverManager.getConnection result to a message "No suitable driver found..".<br /><br />The closest clue I got without going thru the code is contained in this <a href="http://programarenjava.blogspot.com/2006/09/beanshell-y-jdbc-pensaba-que-iba-ser.html">post</a>. Sad to say it is in Spanish --- but there's always <a href="http://babelfish.altavista.com/">Babelfish</a> to the rescue. Still, the translation is wanting, but good enough to tell me not to use DriverManager. <br /><br />Here's an alternative code. Most of the statements were lifted from <a href="http://publib.boulder.ibm.com/infocenter/iseries/v5r4/topic/rzaha/rzaha.pdf">IBM</a>.<br /><pre><small><br />addClassPath ("./jt400.jar");<br /><br />import java.sql.*;<br />import java.util.Properties;<br />import com.ibm.as400.access.AS400;<br />import com.ibm.as400.access.AS400JDBCDriver;<br /><br />private Connection connection = null;<br />private Statement s = null;<br />private String mySchema = "REXJUN1";<br />private String myAS400 = "m170pub1.rzkh.de";<br />private String myUserId = "REXJUN";<br />private String myPasswd = "--change-me-";<br /><br />System.out.println("Loading JDBC driver..");<br />try {<br /> AS400JDBCDriver d = new AS400JDBCDriver();<br /> AS400 o = new AS400(myAS400, myUserId, myPasswd);<br /> Properties p = new Properties();<br /> Connection c = d.connect (o, p, mySchema);<br /> s = c.createStatement();<br />} catch (Exception e) {<br /> System.out.println("Caught exception: " + e.getMessage());<br /> System.exit(0);<br />}<br />System.out.println("Setting up connection..");<br />try {<br /> s.executeUpdate("drop table basicjdbc");<br />} catch (SQLException e) {<br /> // Do not perform anything if an exception occurred. Assume<br /> // that the problem is that the table that was dropped does not<br /> // exist and that it can be created next. <br /> System.out.println("Table may not have been dropped.");<br />}<br />System.out.println("Creating table..");<br />try {<br /> s.executeUpdate("create table basicjdbc(id int, name char(15))");<br /> s.executeUpdate("insert into basicjdbc values(1, 'Frank Johnson')");<br /> s.executeUpdate("insert into basicjdbc values(2, 'Neil Schwartz')");<br /> s.executeUpdate("insert into basicjdbc values(3, 'Ben Rodman')");<br /> s.executeUpdate("insert into basicjdbc values(4, 'Dan Gloore')");<br />} catch (SQLException sqle) {<br /> System.out.println("Failure occurred while setting up " + <br /> " for running the test.");<br /> System.out.println("Test will not continue.");<br /> System.exit(0);<br />}<br />System.out.println("Dumping table..");<br />try {<br /> ResultSet rs = s.executeQuery("select * from basicjdbc");<br /> System.out.println("--------------------");<br /> int i = 0;<br /> while (rs.next()) {<br /> System.out.println("| " + rs.getInt(1) + " | " + rs.getString(2) + "|");<br /> i++;<br /> }<br /> System.out.println("--------------------");<br /> System.out.println("There were " + i + " rows returned.");<br /> System.out.println("Output is complete.");<br />} catch (SQLException e) {<br /> System.out.println("SQLException exception: ");<br /> System.out.println("Message:....." + e.getMessage());<br /> System.out.println("SQLState:...." + e.getSQLState());<br /> System.out.println("Vendor Code:." + e.getErrorCode());<br /> e.printStackTrace();<br />}<br />System.out.println("Clean-up..");<br />try {<br /> if (connection != null) <br /> connection.close();<br />} catch (Exception e) {<br /> System.out.println("Caught exception: ");<br /> e.printStackTrace();<br />}<br /></small></pre>pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com0tag:blogger.com,1999:blog-3225499268556347805.post-87880823437600675682008-02-03T05:25:00.000-08:002008-12-10T05:27:17.382-08:00Sending mail using Gmail SMTP server with JavaThis is a companion project of my previous experiment with <a href="http://pipoltek.blogspot.com/2008/02/smime-encryption-using-bouncy-castle.html">S/Mime encryption</a>. This script is also based on <a href="http://www.beanshell.org/">Beanshell</a> and it's purpose is basically to connect to <a href="http://www.gmail.com">Gmail</a> SMTP servers and deliver the encrypted payload to the message recipients.<br /><br />There are several examples off the Internet but, somehow, I had to combine the techniques before I finally pulled this off. I've enabled debug, otherwise this post would not have any image at all!<br /><br />Here's the debug output..<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhd40Sy2meKgvWhkbEshCFwAHumepI124EI0XOjfG6YOxezMzwW0SAu3jjy60cj9fRX0sbGSmUetlKcoB7xTMAXQWyFnbbel7JGoJ_C501HUyEvcwI9J8aQcggq6LdvwrJEeRPbN1mI3s/s1600-h/debug.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhd40Sy2meKgvWhkbEshCFwAHumepI124EI0XOjfG6YOxezMzwW0SAu3jjy60cj9fRX0sbGSmUetlKcoB7xTMAXQWyFnbbel7JGoJ_C501HUyEvcwI9J8aQcggq6LdvwrJEeRPbN1mI3s/s400/debug.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5163156913762290994" /></a><br />Here's the script..<br /><pre><small><br />addClassPath( "./mail.jar" );<br />addClassPath( "./activation.jar" );<br /><br />import java.security.Security;<br />import javax.mail.Session;<br />import javax.mail.Transport;<br />import javax.mail.Authenticator;<br />import javax.mail.internet.MimeMessage;<br /><br />private class SMTPAuthenticator extends javax.mail.Authenticator {<br /> public PasswordAuthentication getPasswordAuthentication()<br /> {<br /> return new PasswordAuthentication(smtpUsername, smtpPassword);<br /> }<br />}<br /><br />public static final String smtpHost = "smtp.gmail.com";<br />public static final String smtpUsername = "rexjun@gmail.com";<br />public static final String smtpPassword = "-change-me-";<br />public static final String smtpPort = "465";<br /><br />Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());<br />Properties props = new Properties();<br />props.put("mail.smtp.user", smtpUsername);<br />props.put("mail.smtp.host", smtpHost);<br />props.put("mail.smtp.port", smtpPort);<br />props.put("mail.smtp.starttls.enable","true");<br />props.put("mail.smtps.auth", "true");<br />props.put("mail.smtp.debug", "true");<br />props.put("mail.smtp.socketFactory.port", smtpPort);<br />props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");<br />props.put("mail.smtp.socketFactory.fallback", "false");<br />props.put("mail.smtp.ssl","true");<br /><br />SecurityManager security = System.getSecurityManager();<br />Authenticator auth = new SMTPAuthenticator();<br />Session smtpSession = Session.getInstance(props, auth);<br />smtpSession.setDebug(true);<br /><br />MimeMessage smtpMessage = new MimeMessage(smtpSession,<br /> new FileInputStream("Encrypted.eml"));<br />smtpMessage.saveChanges();<br />smtpMessage.setSentDate(new Date());<br /><br />Transport tr = smtpSession.getTransport("smtp"); <br />tr.connect(smtpHost, smtpUsername, smtpPassword);<br />tr.sendMessage(smtpMessage, smtpMessage.getAllRecipients());<br />tr.close();<br /><br /></small></pre>pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com7tag:blogger.com,1999:blog-3225499268556347805.post-53909681189703865082008-02-02T23:26:00.000-08:002008-12-10T05:27:17.700-08:00S/MIME Encryption using Bouncy Castle Crypto API for JavaAt this time and age, it is somewhat irresponsible for banks to accept uploads of plain-text files to their online banking services. Secure HHTP (HTTPS) alone does not address total security as somebody in one's organization has the ability to tamper the files prior to upload. And end-to-end encryption is not a one-sided affair --- both the bank and the customer application has to support it before it can be realized.<br /><br />Of the four banks I've been involved with, two international banks support both plain-text and encrypted file uploads. One local bank accepts plain-text only; the other uses proprietary encryption BUT gives the encryption algo to your programmers!<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://i25.tinypic.com/2pr8jsm.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px;" src="http://i25.tinypic.com/2pr8jsm.png" border="0" alt="" /></a><br />At this time and age, there should be no excuse not to adopt industrial-strength cryptography. I managed to create a <a href="http://www.beanshell.org/">BeanShell</a> script to encrypt files using the <a href="http://www.bouncycastle.org/java.html">Bouncy Castle</a> cryptography API for <a href="http://java.sun.com/">Java</a>. The script produces an encrypted file named <span style="font-style:italic;">Encrypted.eml</span> which can be opened and viewed by Mozilla Thunderbird. The encrypted payload can be delivered using this <a href="http://pipoltek.blogspot.com/2008/02/sending-mail-using-gmail-smtp-server.html">companion code</a>.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3dqx3RAZslAgJYWLcZfbFwoJ240GkqMuhmcV7dGgjCfYyWBZi7DBiB3kAb4VAKITY0YgYUuhkFAHcpnpDgxD6Ra5qyOykR27aNfhg22MWyepOm-WIfR6f0Sp_phfXDItk6PVrOlPAOio/s1600-h/encrypted.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3dqx3RAZslAgJYWLcZfbFwoJ240GkqMuhmcV7dGgjCfYyWBZi7DBiB3kAb4VAKITY0YgYUuhkFAHcpnpDgxD6Ra5qyOykR27aNfhg22MWyepOm-WIfR6f0Sp_phfXDItk6PVrOlPAOio/s320/encrypted.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5162673545257897090" /></a><br />You would need your own digital certificate, a public-key for your recipient and the file that you want encrypted. Get your free digital certificates from <a href="http://www.comodo.com/products/certificate_services/email_certificate.html">Comodo</a>. To run the script, execute the command <span style="font-style:italic;">java -classpath ./bsh-2.0b4.jar bsh.Interpreter SnE.bsh</span>, where SnE.bsh is the script name. Lastly, here's the code..<br /><pre><small><br />addClassPath( "./mail.jar" );<br />addClassPath( "./activation.jar" );<br />addClassPath( "./bcprov-jdk16-138.jar" );<br />addClassPath( "./bcmail-jdk16-138.jar" );<br /><br />import javax.activation.FileDataSource;<br />import javax.activation.DataHandler;<br /><br />import java.io.FileInputStream;<br />import java.io.ByteArrayOutputStream;<br />import java.io.ByteArrayInputStream;<br />import java.security.KeyStore;<br />import java.security.Security;<br />import java.security.PrivateKey;<br />import java.security.cert.CertificateFactory;<br />import java.security.cert.Certificate;<br />import java.security.cert.X509Certificate;<br />import java.security.cert.CertStore;<br />import java.security.cert.CollectionCertStoreParameters;<br />import java.util.Properties;<br />import java.util.Enumeration;<br />import java.util.List;<br />import java.util.ArrayList;<br /><br />import javax.mail.Message;<br />import javax.mail.Session;<br />import javax.mail.internet.InternetAddress;<br />import javax.mail.internet.MimeBodyPart;<br />import javax.mail.internet.MimeMessage;<br />import javax.mail.internet.MimeMultipart;<br />import javax.activation.MailcapCommandMap;<br />import javax.activation.CommandMap;<br /><br />import org.bouncycastle.jce.provider.BouncyCastleProvider;<br />import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator;<br />import org.bouncycastle.mail.smime.SMIMEException;<br />import org.bouncycastle.mail.smime.SMIMESignedGenerator;<br />import org.bouncycastle.util.Strings;<br />import org.bouncycastle.asn1.smime.SMIMECapabilityVector;<br />import org.bouncycastle.asn1.smime.SMIMECapability;<br />import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute;<br />import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute;<br />import org.bouncycastle.asn1.ASN1EncodableVector;<br />import org.bouncycastle.asn1.x509.X509Name;<br />import org.bouncycastle.asn1.cms.IssuerAndSerialNumber;<br />import org.bouncycastle.asn1.cms.AttributeTable;<br /><br />public static final String pkcs12Keystore = "./certs/myOwn.p12";<br />public static final String rcptCertfile = "./certs/myBank.cer";<br />public static final String sendFile = "./messages/hello.txt";<br />public static final String ksPassword = "pipoltek";<br />public static final String frAddress = "rexjun@somewhere.com";<br />public static final String toAddress = "ca@myBank.com";<br /><br />try<br />{<br /> MailcapCommandMap mailcap = (MailcapCommandMap)CommandMap .getDefaultCommandMap();<br /> mailcap .addMailcap("application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature");<br /> mailcap .addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime");<br /> mailcap .addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature");<br /> mailcap .addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime");<br /> mailcap .addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed");<br /> CommandMap.setDefaultCommandMap(mailcap);<br /> <br /> /* Add BC */<br /> Security.addProvider(new BouncyCastleProvider());<br /><br /> /* Open the keystore */<br /> KeyStore keystore = KeyStore.getInstance("PKCS12", "BC");<br /> keystore.load (new FileInputStream(pkcs12Keystore), ksPassword.toCharArray());<br /> Enumeration e = keystore.aliases();<br /> String keyAlias = null;<br /> while (e.hasMoreElements() && (keyAlias == null)) {<br /> String alias = (String)e.nextElement();<br /> keyAlias = keystore.isKeyEntry(alias) ? alias : null;<br /> }<br /> if (keyAlias == null) {<br /> System.err.println("Can't find a private key!");<br /> System.exit(0);<br /> }<br /> Certificate[] chain = keystore.getCertificateChain(keyAlias);<br /><br /> /* Get the private key to sign the message with */<br /> PrivateKey privateKey = (PrivateKey)keystore.getKey(keyAlias,<br /> ksPassword.toCharArray());<br /> if (privateKey == null) {<br /> throw new Exception("No private key for alias: " + keyAlias);<br /> }<br /><br /> /* Get public key of recipient for encryption */<br /> FileInputStream fis = new FileInputStream(rcptCertfile);<br /> BufferedInputStream bis = new BufferedInputStream(fis); <br /> CertificateFactory cf = CertificateFactory.getInstance("X.509"); <br /> Certificate rcptCert = cf.generateCertificate(bis);<br /><br /> /* Attach the file to encrypt */<br /> MimeBodyPart bodyPart = new MimeBodyPart();<br /> FileDataSource fds = new FileDataSource(sendFile);<br /> bodyPart.setDataHandler(new DataHandler(fds));<br /> bodyPart.setFileName(fds.getName());<br /> MimeMultipart bodyMulti = new MimeMultipart();<br /> bodyMulti.addBodyPart(bodyPart); <br /><br /> Session session = Session.getDefaultInstance(System.getProperties());<br /> MimeMessage body = new MimeMessage(session);<br /> body.setFrom(new InternetAddress(frAddress));<br /> body.setRecipient(Message.RecipientType.TO, new InternetAddress(<br /> toAddress));<br /> body.setSentDate(new Date());<br /> body.setSubject("Encrypted Mail");<br /> body.setContent(bodyMulti,bodyMulti.getContentType());<br /> body.saveChanges();<br /><br /> /* Create the SMIMESignedGenerator */<br /> SMIMECapabilityVector capabilities = new SMIMECapabilityVector();<br /> capabilities.addCapability(SMIMECapability.dES_EDE3_CBC);<br /> capabilities.addCapability(SMIMECapability.rC2_CBC, 128);<br /> capabilities.addCapability(SMIMECapability.dES_CBC);<br /><br /> ASN1EncodableVector attributes = new ASN1EncodableVector();<br /> attributes.add(new SMIMEEncryptionKeyPreferenceAttribute(<br /> new IssuerAndSerialNumber(<br /> new X509Name(((X509Certificate)chain[0])<br /> .getIssuerDN().getName()),<br /> ((X509Certificate)chain[0]).getSerialNumber())));<br /> attributes.add(new SMIMECapabilitiesAttribute(capabilities));<br /><br /> SMIMESignedGenerator signer = new SMIMESignedGenerator();<br /> signer .addSigner(privateKey, (X509Certificate)chain[0],<br /> "DSA".equals(privateKey.getAlgorithm()) ? <br /> SMIMESignedGenerator.DIGEST_SHA1 : SMIMESignedGenerator.DIGEST_MD5,<br /> new AttributeTable(attributes), null);<br /><br /> /* Add the list of certs to the generator */<br /> List certList = new ArrayList();<br /> certList.add(chain[0]);<br /> CertStore certs = CertStore.getInstance("Collection",<br /> new CollectionCertStoreParameters(certList), "BC");<br /> signer.addCertificatesAndCRLs(certs);<br /><br /> /* Sign the message and copy all headers from original message */<br /> MimeMultipart multiPart = signer.generate(body, "BC");<br /> MimeMessage signedMessage = new MimeMessage(session);<br /> Enumeration headers = body.getAllHeaderLines();<br /> while (headers.hasMoreElements()) {<br /> signedMessage.addHeaderLine((String)headers.nextElement());<br /> }<br /> signedMessage.setContent(multiPart);<br /> signedMessage.saveChanges();<br /><br /> /* Create the encrypter and encrypt the message */<br /> SMIMEEnvelopedGenerator encrypter = new SMIMEEnvelopedGenerator();<br /> encrypter.addKeyTransRecipient((X509Certificate)chain[0]);<br /> encrypter.addKeyTransRecipient(rcptCert);<br /> MimeBodyPart encryptedPart = encrypter.generate(signedMessage,<br /> SMIMEEnvelopedGenerator.RC2_CBC, 128, "BC");<br /> ByteArrayOutputStream out = new ByteArrayOutputStream();<br /> encryptedPart.writeTo(out);<br /> <br /> /* Create a new MimeMessage for the encrypted and signed content */<br /> <br /> Properties props = new Properties();<br /> Session smtpSession = Session.getInstance(props, null);<br /> MimeMessage smtpMessage = new MimeMessage(smtpSession,<br /> new ByteArrayInputStream(out.toByteArray()));<br /> smtpMessage.saveChanges();<br /> <br /> /* Set all original MIME headers in the encrypted message */<br /> headers = body.getAllHeaderLines();<br /> while (headers.hasMoreElements()) {<br /> String headerLine = (String)headers.nextElement();<br /> /* Do not override content-* headers from the original message */<br /> if (!Strings.toLowerCase(headerLine).startsWith("content-")) {<br /> smtpMessage.addHeaderLine(headerLine);<br /> }<br /> }<br /> <br /> smtpMessage.writeTo(new FileOutputStream("Encrypted.eml")); <br /> <br />}<br />catch (SMIMEException ex)<br />{<br /> ex.getUnderlyingException().printStackTrace(System.err);<br /> ex.printStackTrace(System.err);<br />}<br />catch (Exception ex)<br />{<br /> ex.printStackTrace(System.err);<br />}<br /><br /></small></pre>pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com2tag:blogger.com,1999:blog-3225499268556347805.post-30120975847564206502008-01-29T07:32:00.000-08:002008-12-10T05:27:18.229-08:00Getting a Commercial Digital CertificateI need to acquire a digital certificate to be used for encrypting files prior to uploading it to a bank's online service. Three commercial Certificate Authorities (CAs) were recommended by the bank, namely: Entrust, Thawte and Verisign.<br /><br />I was given six (6) characteristics of what I should be looking for. These items cover specs like the type of MDA, encryption algo, key size, certificate export formats, etc. Couldn't I just have the SKU number?<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0PFOJi_Oj7P-vh6idB-P2v-5U5n9i0m-PYxKXyPmu-AhYxPd9cdfOBIhIynujdJp-eNn4HEgBij-OjKh4VT8z8iljoA4dmTb_JiBvMRX-6pG78Hq1gB8F2dKH4CCzJHlE0fpoaOjIXDo/s1600-h/barcode.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0PFOJi_Oj7P-vh6idB-P2v-5U5n9i0m-PYxKXyPmu-AhYxPd9cdfOBIhIynujdJp-eNn4HEgBij-OjKh4VT8z8iljoA4dmTb_JiBvMRX-6pG78Hq1gB8F2dKH4CCzJHlE0fpoaOjIXDo/s200/barcode.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5161263700768148578" /></a>An SKU would have been most useful. The CA websites and storefronts were basically stocked with a slew of server SSL products -- my digital certificate is buried in some obscure page somewhere. Before I entirely lost my shopping appetite, Verisign's livechat popped into peripheral view. Good thing! I was about to put this off for another day.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6a9wt1mUr-YcmeRLq5HtxkXoWgELgMAPK81m7epPR3xzvQJjUFkBp6EfoZNWGUUN0vBPrS2Xe489M1bNAL3dR9p2LcyBKU__-N3LKS4Wu90i4nhRE7sfyBn_ZOx3GfCC17RQ-ZMlzC40/s1600-h/yawn1.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6a9wt1mUr-YcmeRLq5HtxkXoWgELgMAPK81m7epPR3xzvQJjUFkBp6EfoZNWGUUN0vBPrS2Xe489M1bNAL3dR9p2LcyBKU__-N3LKS4Wu90i4nhRE7sfyBn_ZOx3GfCC17RQ-ZMlzC40/s200/yawn1.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5160937644030905362" /></a><br />After a couple of minutes, I got my answer. I need a Class 1 Digital ID and the product page is tucked <a href="http://www.verisign.com/products-services/security-services/pki/pki-application/email-digital-id/index.html">here</a>. Thawte has a livechat button, too -- but after three reps and twice the wait, I was informed politely that Thawte does not sell client certificates for commercial use. Entrust has no livechat and email response is rather sluggish. <br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0XV-GBq08wppgubVMCNpjrD4YrGxglkrZ3u8JIFSVSInecIvjDYUUX3v4gbV7Peb10-fVlz5aBwIN3A_J05mV9yYwqhQ20PQlr9AQSyrSAL99Fq3EVo1r9HnfyQ7pz4nJmvGrSdWks6A/s1600-h/sold.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0XV-GBq08wppgubVMCNpjrD4YrGxglkrZ3u8JIFSVSInecIvjDYUUX3v4gbV7Peb10-fVlz5aBwIN3A_J05mV9yYwqhQ20PQlr9AQSyrSAL99Fq3EVo1r9HnfyQ7pz4nJmvGrSdWks6A/s320/sold.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5161262601256520786" /></a><br />You can purchase a Verisign Digital ID <a href="http://www.verisign.com/products-services/security-services/pki/pki-application/email-digital-id/page_dev004002.html">online</a> for US$19.95 per year. A 60-day trial is also available for free. International customers, though, are served by the VeriSign Trust Network of International <a href="http://www.verisign.com/verisign-worldwide/index.html">affiliates</a>. That's me! I pray that dealing with their local affiliate is just as breezy.pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com1tag:blogger.com,1999:blog-3225499268556347805.post-72718819546162791832008-01-21T06:08:00.000-08:002008-12-10T05:27:18.434-08:00A Tcl Web Service client for KnowledgeTree Document Management SystemSometime last year, I dabbled with <a href="http://knowledgetree.com">KnowledgeTree</a>'s web services and (somehow I've forgotten why) I ended up with a Tcl client to perform a document upload. <br /><br />Before I lose this chunk of code or forget about it altogether (and it happens a lot), I decided to post it here:<br /><pre><small><br />package require SOAP<br />package require http<br />package require TclCurl<br /><br />set prx "http://192.168.211.128/ktwebservice/webservice.php"<br />set url "http://192.168.211.128/ktwebservice/upload.php"<br />set usr "admin"<br />set pas "admin"<br />set ipa "any"<br /><br />set upf "upload-me.txt"<br />set typ "multipart/form-data"<br /><br />proc log_it { chn msg } {<br /> set stm [clock format [clock seconds] -format "%Y/%m/%d %H:%M:%S %a"]<br /> puts $chn "$stm : $msg"<br />}<br /><br />SOAP::create kt_login \<br /> -proxy $prx \<br /> -params { "username" "string" "password" "string" "ip" "string"} \<br /> -name login<br />SOAP::create kt_add_document \<br /> -proxy $prx \<br /> -params { "session_id" "string" "folder_id" "int" "title" "string" "filename" "string" \<br /> "documentype" "string" "tempfilename" "string" } \<br /> -name add_document<br />SOAP::create kt_logout \<br /> -proxy $prx \<br /> -params { "session_id" "string"} \<br /> -name logout<br /><br />set log "debug.log"<br /><br />if { [catch {open $log a} out] } {<br /> puts stderr "Error: $out"<br /> set out "stderr"<br />} <br /> <br />set rsp [kt_login $usr $pas $ipa]<br />set sta [lindex $rsp 1]<br />set ses [lindex $rsp 3]<br />log_it $out "Login: status ($sta); session ($ses)"<br /><br />set opt "session_id $ses action A"<br />set crl [curl::init]<br />set rsp [$crl configure -url $url -bodyvar rsp -post 1 \<br /> -httppost [list name "file1" file $upf contenttype $typ] \<br /> -httppost [list name "session_id" contents $ses] \<br /> -httppost [list name "action" contents A] \<br /> -httppost [list name "output" contents php] \<br /> ]<br />catch { $crl perform } curlErrorNumber<br />if { $curlErrorNumber != 0 } {<br /> error [curl::easystrerror $curlErrorNumber]<br />}<br />$crl cleanup<br /><br />log_it $out "Upload: response ($rsp)"<br /><br />set ps1 [string first "\"tmp_name\";s:" $rsp 0]<br />set ps2 [string first ":\"" $rsp [expr $ps1 + 12]]<br />set ps3 [string first "\";s:5:\"error\"" $rsp 0]<br />set tmp [string range $rsp [expr $ps2 + 2] [expr $ps3 - 1]]<br /><br /># Define folder where to upload files<br />set fld 1;<br />set ttl "My Document";<br />set doc "Default" <br /><br />set rsp [kt_add_document $ses $fld $ttl $upf $doc $tmp]<br />log_it $out "Add Document: response ($rsp)"<br /><br />set rsp [kt_logout $ses]<br />log_it $out "Logout: response ($rsp)"<br /><br />close $out<br /></small></pre><br />The upload facility is implemented by upload.php and returns a response coming out of php's serialize() function. I've mangled upload.php to return a response in xml or json format. The code changes are posted in the Knowledgetree community forum <a href="http://forums.knowledgetree.com/viewtopic.php?t=3138">here</a>.<br /><br />The above Tcl code digests the php's serialize() output.<br /><br />For xml output, here are the relevant changes:<br /><pre><small><br />set crl [curl::init]<br />set rsp [$crl configure -url $url -bodyvar xml -post 1 \<br /> -httppost [list name "file1" file $upf contenttype $typ] \<br /> -httppost [list name "session_id" contents $ses] \<br /> -httppost [list name "action" contents A] \<br /> -httppost [list name "output" contents xml] \<br /> ]<br />...<br />set top [dom parse $xml]<br />set sel [$top selectNodes /results/uploads/document/tmp_name/text()]<br />set tmp [$sel nodeValue]<br />$top delete<br /></small></pre><br />And for json..<br /><pre><small><br />set rsp [$crl configure -url $url -bodyvar rsp -post 1 \<br /> -httppost [list name "file1" file $upf contenttype $typ] \<br /> -httppost [list name "session_id" contents $ses] \<br /> -httppost [list name "action" contents A] \<br /> -httppost [list name "output" contents json] \<br /> ]<br />...<br />set ps1 [string first "\"tmp_name\":\"" $rsp 0]<br />set ps2 [string first "\",\"error\"" $rsp 0]<br />set tmp [string range $rsp [expr $ps1 + 12] [expr $ps2 - 1]]<br /></small></pre><br />Check the contents of debug.log for any errors. A successful operation produces this output:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXOMUC3yay6zPHYaHnvAtYWM7BToUSPzVdrekLMESMLI9q8S-yaG0-nTU_clvbMopmgzbuHCaTEP-woUa1BGxylUPsr7Sd6NESA47aIz11uSKOPCXxOtOgDW8A4Y3I5mtzXpmgNQNpoUY/s1600-h/debug-log.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXOMUC3yay6zPHYaHnvAtYWM7BToUSPzVdrekLMESMLI9q8S-yaG0-nTU_clvbMopmgzbuHCaTEP-woUa1BGxylUPsr7Sd6NESA47aIz11uSKOPCXxOtOgDW8A4Y3I5mtzXpmgNQNpoUY/s400/debug-log.PNG" border="1" alt=""id="BLOGGER_PHOTO_ID_5157946677012197234" /></a>pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com4tag:blogger.com,1999:blog-3225499268556347805.post-64291464362772567212007-12-04T15:27:00.000-08:002008-02-06T16:36:51.775-08:00Postgres on CygwinI'm working on a project that requires database support and I decided to use <a href="http://www.postgresql.org/">Postgres</a> on <a href="http://www.cygwin.com/">Cygwin</a>. I encountered mild difficulty (and lots of confusion) in setting it up so I decided to document what I have done. Here goes..<br /><br /><span style="font-weight: bold;">Install and run Cygserver as background service<br /><br /></span>The Cygwin User's Manual states that <a href="http://www.cygwin.com/cygwin-ug-net/using-cygserver.html">Cygserver</a> provides Cygwin applications with services which require security arbitration or which need to persist while no other cygwin application is running.<br /><br />Once installed as a service, you can start cygserver by running the <span style="font-style: italic;">net start cygserver</span> command. Consequently, the service can be stopped by issuing a <span style="font-style: italic;">net stop cygserver</span> command.<br /><br /><blockquote></blockquote><span style="font-weight: bold;">Create the </span><span style="font-style: italic; font-weight: bold;">postgres</span><span style="font-weight: bold;"> Windows user account</span><br /><br />The account shall be used to run <span style="font-style: italic;">postgres</span> as a service. Execute the command <span style="font-style: italic;">mkpasswd -l > /etc/passwd</span><span style="font-style: italic; font-weight: bold;"> </span>to update the local password file.<br /><br />Additionally, grant the <span style="font-style: italic;">postgres</span> account the rights to <span style="font-style: italic;">Logon as a service. </span>This can be done by using the local security policy editor found under the Administrative Tools of the Windows Control Panel.<br /><br /><span style="font-weight: bold;">Initialize the database</span><br /><br />Initialize the database by executing the command <span style="font-style: italic;">initdb -D {dir}</span><span style="font-style: italic; font-weight: bold;">. </span>Popular choices for data directory are<span style="font-style: italic; font-weight: bold;"> </span><span style="font-style: italic;">/var/postgresql/data, </span><span style="font-style: italic;">/usr/local/pgsql/data</span>, or variations thereof. Change the ownership of the data directory and its sub-directories to <span style="font-style: italic;">postgres.</span><br /><br /><span style="font-weight: bold;">Install the <span style="font-style: italic;">postmaster</span> service</span><br /><br />Firstly, change the ownership of <span style="font-style: italic;">/usr/sbin/postgres.exe </span>to<span style="font-style: italic;"> postgres. </span>Install <span style="font-style: italic;">postmaster</span> as a service by running the command<br /><br /><code>cygrunsrv --install postmaster --disp "CYGWIN postmaster" --path /usr/sbin/postmaster --args "-D /usr/local/pgsql/data -i" --dep cygserver --termsig INT --shutdown --env CYGWIN=server --user postgres</code><br /><br />The dependency (--dep) option automatically launches cygserver, if not yet started, when the postmaster service is started.<br /><br /><span style="font-weight: bold;">My Configuration:<br /><br /></span>- Windows XP Prof Service Pack 2<br />- Cygwin DLL release version 1.5.24(0.156/4/2)<br />- PostgreSQL version 8.0.7pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com0tag:blogger.com,1999:blog-3225499268556347805.post-43236997702743716142007-11-03T08:13:00.000-07:002008-12-10T05:27:18.814-08:00SNMP monitoring using getif and nagiosI use getif. a free Windows GUI-based network tool written by Philippe Simonet, to make a quick query of SNMP values from SNMP informant. You may download getif <a href="http://www.blogger.com/%E2%80%9Dhttp://www.wtcs.org/snmp4tpc/getif.htm%E2%80%9D">here</a>.<br /><br />Once installed, place the downloaded MIBs of SNMP-Informant under the Mibs sub-directory of GETIF. Here's a screenshot of getif in action:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvXC1tedTvX_TXApoWGU0bGUZZlAYG5ScV4E7yqEUX2t7uHmsZtrrcD68K33j1eUdv82BPpV735Se1l7vxpDkSQrSDbkSqG0YCPeJPAQZNmq25yhzosC9DkBOyRYqKKoqzZpHm7JvAFjg/s1600-h/getif.JPG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvXC1tedTvX_TXApoWGU0bGUZZlAYG5ScV4E7yqEUX2t7uHmsZtrrcD68K33j1eUdv82BPpV735Se1l7vxpDkSQrSDbkSqG0YCPeJPAQZNmq25yhzosC9DkBOyRYqKKoqzZpHm7JvAFjg/s400/getif.JPG" alt="" id="BLOGGER_PHOTO_ID_5128634040912550962" border="0" /></a><br />For continuous monitoring of servers and networks, I use <a href="http://www.nagios.org/">nagios</a> to regularly poll environmental and performance statistics. The results can be graphed for better visualization and reporting.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm-FwjdCAlIOhg-0UaBos7aVleCK4rfJiKvM-z4F6mmOScGGwIYeAHOxFmhwUSzr635TNHcwaw3nkfjj_lzqNEYR0CCNC5IHIuh2hPeul1dbd8dHe2wzfSXAVS8My5D7BzRQJkyatiUcA/s1600-h/nagios.JPG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm-FwjdCAlIOhg-0UaBos7aVleCK4rfJiKvM-z4F6mmOScGGwIYeAHOxFmhwUSzr635TNHcwaw3nkfjj_lzqNEYR0CCNC5IHIuh2hPeul1dbd8dHe2wzfSXAVS8My5D7BzRQJkyatiUcA/s400/nagios.JPG" alt="" id="BLOGGER_PHOTO_ID_5128638052412005442" border="0" /></a>Here are the pertinent nagios <span style="font-style: italic;">service</span> and <span style="font-style: italic;">command</span> configuration entries..<br /><pre>define service{<br />hostgroup_name windows<br />service_description mb-temp<br />check_command check_mbtemp!40!42<br />use template-service<br />}<br /><br />define command{<br />command_name check_mbtemp<br />command_line $USER1$/check_snmp -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$ -o .1.3.6.1.4.1.9600.1.10.6.1.5.1 -l 'MB temp' -u 'Celsius (Warn=$ARG1$ Crit=$ARG2$)'<br />}<br /></pre>pipoltekhttp://www.blogger.com/profile/10502965397257778282noreply@blogger.com1