<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>John Ra &#8211; J O H N R A . M E</title>
	<atom:link href="/author/johnra/feed/" rel="self" type="application/rss+xml" />
	<link>/</link>
	<description>...yet another musings of a techie</description>
	<lastBuildDate>Sat, 18 May 2024 12:16:01 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.5.3</generator>
	<item>
		<title>Synology + UPS as NUT Primary</title>
		<link>/2024/05/16/synology-ups-as-nut-primary/</link>
		
		<dc:creator><![CDATA[John Ra]]></dc:creator>
		<pubDate>Thu, 16 May 2024 00:39:58 +0000</pubDate>
				<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[NUT]]></category>
		<category><![CDATA[Synology]]></category>
		<category><![CDATA[UPS]]></category>
		<guid isPermaLink="false">/?p=632</guid>

					<description><![CDATA[I recently purchased a CyberPower CST135XLU Uninterruptible Power Supply (UPS) for my linux server, Orbi Wifi Router, and Synology NAS. However, I only need my Orbi running on UPS in the event of a power outage; the others don&#8217;t need to be running. With my Fios on a dedicated UPS and Orbi on this new UPS, I will be able to stay on line while I wait for the power to be restored. This means I need to setup Network UPS Tools (NUT) so that I can gracefully shutdown my Synology NAS and linux server &#8211; giving my Orbi extended&#8230;]]></description>
										<content:encoded><![CDATA[
<p>I recently purchased a CyberPower CST135XLU Uninterruptible Power Supply (UPS) for my linux server, Orbi Wifi Router, and  Synology NAS. However, I only need my Orbi running on UPS in the event of a power outage; the others don&#8217;t need to be running. With my Fios on a dedicated UPS and Orbi on this new UPS, I will be able to stay on line while I wait for the power to be restored. This means I need to setup Network UPS Tools (NUT) so that I can gracefully shutdown my Synology NAS and linux server &#8211; giving my Orbi extended uptime on UPS battery mode. </p>



<h3 class="wp-block-heading">Options</h3>



<p>I can either attach the UPS to my linux server with NUT as primary then setup Synology NAS as secondary. Or, reverse it with Synology NAS as primary with linux as secondary. There are many other factors but, ultimately, primary has to stay up longer than secondary to avoid unexpected behavior caused by loss of communication to primary. Additionally, given that my linux server consumes more raw power than my Synology, it was an obvious decision to make Synology my primary.</p>



<h3 class="wp-block-heading">Synology UPS Setup</h3>



<p>To setup local UPS support, connect the UPS device to a USB port of the Synology NAS. Login to your DSM and navigate to &#8220;Control Panel&#8221; then click &#8220;Hardware &amp; Power&#8221;. Under the UPS tab, &#8220;Enable UPS support&#8221; and select &#8220;USB UPS&#8221;. In my case, I want to gracefully shutdown after 5 minutes &#8211; not have it running &#8220;Until low battery&#8221;</p>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="585" height="463" src="/wp-content/uploads/2024/05/image.png" alt="" class="wp-image-635" srcset="/wp-content/uploads/2024/05/image.png 585w, /wp-content/uploads/2024/05/image-300x237.png 300w" sizes="(max-width: 585px) 100vw, 585px" /></figure>



<p>Tick &#8220;Enable network UPS server&#8221; to allow NUT client to connect to this service as secondary. Click &#8220;Permitted DiskStation Devices&#8221; and enter the client IP address &#8211; in my case, this would be my linux server&#8217;s fixed IP address.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="530" height="270" src="/wp-content/uploads/2024/05/image-1.png" alt="" class="wp-image-636" srcset="/wp-content/uploads/2024/05/image-1.png 530w, /wp-content/uploads/2024/05/image-1-300x153.png 300w" sizes="(max-width: 530px) 100vw, 530px" /></figure>



<p>Click &#8220;OK&#8221; then click &#8220;Apply&#8221;. You now have NUT service running on Synology as primary. </p>



<h4 class="wp-block-heading">Extract Required NUT client details</h4>



<p>To access required data to properly configure NUT client, you must login to DSM via terminal over SSH. From DSM, go to &#8220;Control Panel&#8221; and click &#8220;Terminal &amp; SNMP&#8221;. Under &#8220;Terminal&#8221; tab, tick &#8220;Enable SSH service&#8221;. </p>



<p>SSH into DSM as user with administrative role. Once logged in, run <code>sudo tail /etc/ups/upsd.users</code> command. Look for the line <code>password = &lt;password&gt;</code>, note this password down. Prior to the password line, note down the username defined within square brackets ([monuser]). Then, run <code>sudo tail /etc/ups/ups.conf</code>. The name within square braces is the UPS name. See green outline in screenshot</p>



<figure class="wp-block-image size-full"><img decoding="async" width="979" height="631" src="/wp-content/uploads/2024/05/console.png" alt="" class="wp-image-641" srcset="/wp-content/uploads/2024/05/console.png 979w, /wp-content/uploads/2024/05/console-300x193.png 300w, /wp-content/uploads/2024/05/console-768x495.png 768w" sizes="(max-width: 979px) 100vw, 979px" /></figure>



<p></p>



<h3 class="wp-block-heading">Linux Server Setup as NUT client</h3>



<h4 class="wp-block-heading">Pre-requisite</h4>



<p>First install Network UPS Tools &#8211; if not already installed</p>



<pre class="wp-block-code"><code>$ sudo apt update
$ sudo apt install nut</code></pre>



<h4 class="wp-block-heading">Setup NUT Monitor</h4>



<p>First, configure NUT as netclient by editing <code>/var/nut/nut.conf</code>. Look for MODE and change it to netclient</p>



<pre class="wp-block-code"><code>MODE=netclient</code></pre>



<p>Then, edit <code>/etc/nut/upsmon.conf</code>  to add MONITOR line with the name capture from ups.conf along with the monitor user (e.g. monuser) and password from upsd.user from above Synology section. </p>



<pre class="wp-block-code"><code>MONITOR &lt;name from ups.conf on synology&gt;@&lt;ip address of your synology&gt; 1 &lt;monitor user from above&gt; &lt;password from above&gt; slave</code></pre>



<p>Then setup NOTIFYFLAG. If NOTIFYFLAG are commented out, please add the follow. Otherwise, edit them according. </p>



<pre class="wp-block-code"><code>NOTIFYFLAG ONLINE     SYSLOG+EXEC
NOTIFYFLAG ONBATT     SYSLOG+EXEC
NOTIFYFLAG LOWBATT    SYSLOG+EXEC
NOTIFYFLAG FSD        SYSLOG+WALL+EXEC
NOTIFYFLAG COMMOK     SYSLOG+EXEC
NOTIFYFLAG COMMBAD    SYSLOG+EXEC
NOTIFYFLAG SHUTDOWN   SYSLOG+WALL+EXEC
NOTIFYFLAG REPLBATT   SYSLOG+WALL+EXEC
NOTIFYFLAG NOCOMM     SYSLOG+WALL+EXEC
NOTIFYFLAG NOPARENT   SYSLOG+WALL+EXEC</code></pre>



<p>The SYSLOG will trigger logging. WALL will send message to all terminal sessions. The EXEC command will trigger script defined by NOTIFYCMD. This will be further discussed in next section. </p>



<pre class="wp-block-code"><code>NOTIFYCMD /usr/sbin/upssched</code></pre>



<p>This will enable NUT to monitor your UPS status on Synology and notify and/or execute action</p>



<h4 class="wp-block-heading">Setup NUT Schedule</h4>



<p>When UPS notification occurs, NOTIFYFLAG is used to perform actions for a given notification type. For example, when UPS moves to battery mode, ONBATT will be triggered. In the above case,  It will perform SYSLOG which will log to <code>/var/log/syslog</code> and EXEC will trigger the script defined by NOTIFYCMD. When power is restored to UPS, ONLINE will be trigger. </p>



<p>Edit <code>/etc/nut/upssched.conf</code> uncomment the following line. This sets the file name of the First In First Out (FIFO) between processes to start and stop timer.</p>



<pre class="wp-block-code"><code>PIPEFN /run/nut/upssched/upssched.pipe</code></pre>



<p>Then uncomment the following line. This will prevent race condition.</p>



<pre class="wp-block-code"><code>LOCKFN /run/nut/upssched/upssched.lock</code></pre>



<p>Add the following commands</p>



<pre class="wp-block-code"><code>AT ONLINE * EXECUTE online
AT ONBATT * EXECUTE onbatt</code></pre>



<p>Search for CMDSCRIPT and edit the file referenced (e.g. <code>/bin/upssched-cmd</code>). Replace with following:</p>



<pre class="wp-block-code"><code>#! /bin/sh
#
# This script should be called by upssched via the CMDSCRIPT directive.
#
# Here is a quick example to show how to handle a bunch of possible
# timer names with the help of the case structure.
#
# This script may be replaced with another program without harm.
#
# The first argument passed to your CMDSCRIPT is the name of the timer
# from your AT lines.

UPS="&lt;name from ups.conf on synology&gt;@&lt;ip address of your synology&gt;"

STATUS=$( upsc $UPS ups.status )
CHARGE=$( upsc $UPS battery.charge )
CHMSG="&#091;$STATUS]:$CHARGE%"

case $1 in
        online)
                MSG="$UPS, $CHMSG - power supply has been restored."
                /sbin/shutdown -c
                ;;
        onbatt)
                MSG="$UPS, $CHMSG - power failure - save your work!"
                /sbin/shutdown -h +2
                ;;
        lowbatt)
                MSG="$UPS, $CHMSG - shutdown now!"
                /sbin/shutdown -h now
                ;;
        upsgone) MSG="The UPS $UPS has been gone for awhile" ;;
        *) MSG="$UPS, $CHMSG - Unrecognized command: $1" ;;
esac
logger -i -t upssched-cmd $MSG</code></pre>



<p>In above example, when NOTIFYFLAG ONBATT occurs, it will execute <code>/usr/sbin/upssched</code> defined by NOTIFYCMD. This will trigger <code>AT ONLINE * EXECUTE online</code> which will call <code>/bin/upssched-cmd</code> defined by CMDSCRIPT. In <code>/bin/upssched-cmd</code> onbatt case will result execute shutdown in 2 minutes (see <code>/sbin/shutdown -h +2</code>). However, when power is restored, the online trigger will cancel the shutdown (see <code>/sbin/shutdown -c</code>).</p>



<h4 class="wp-block-heading">Restart NUT Monitor</h4>



<p>Reload NUT monitor with the latest changes by executing following commands</p>



<pre class="wp-block-code"><code>$ sudo service nut-monitor stop
$ sudo service nut-monitor start</code></pre>



<p>To test, unplug your battery from power source to trigger ONBATT notification then plug it back in. If everything is setup correctly, you should see in the <code>/var/log/syslog</code> similar to below. </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="186" src="/wp-content/uploads/2024/05/console-1-1024x186.png" alt="" class="wp-image-646" srcset="/wp-content/uploads/2024/05/console-1-1024x186.png 1024w, /wp-content/uploads/2024/05/console-1-300x55.png 300w, /wp-content/uploads/2024/05/console-1-768x140.png 768w, /wp-content/uploads/2024/05/console-1.png 1056w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Context Matters</title>
		<link>/2024/04/10/context-matters/</link>
		
		<dc:creator><![CDATA[John Ra]]></dc:creator>
		<pubDate>Wed, 10 Apr 2024 18:42:05 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Development]]></category>
		<guid isPermaLink="false">/?p=582</guid>

					<description><![CDATA[Understanding context is essential in becoming an effective software engineer. It is not sufficient to possess deep technical skills. Understanding the context (business domain) you operate in provides the necessary background to build the right solution. It elevates the skill programmer to a value-added software engineer. It allows software engineers to ensure solution fit the situation, background, and purpose, thereby enhancing clarity and reducing the likelihood of misunderstandings. Misunderstanding will only lead to defects. By being mindful of the contexts, software engineer can navigate complex landscapes and build stronger, more meaningful solution. In the realm of building the right solution,&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Understanding context is essential in becoming an effective software engineer. It is not sufficient to possess deep technical skills. Understanding the context (business domain) you operate in provides the necessary background to build the right solution. It elevates the skill programmer to a value-added software engineer. It allows software engineers to ensure solution fit the situation, background, and purpose, thereby enhancing clarity and reducing the likelihood of misunderstandings. Misunderstanding will only lead to defects. By being mindful of the contexts, software engineer can navigate complex landscapes and build stronger, more meaningful solution.</p>



<p>In the realm of building the right solution, business domain is not just a backdrop; it&#8217;s a pivotal player in the interpretation and understanding of requirements. The importance of context cannot be overstressed, as it is the lens through which we perceive and make sense of the requirements. Without good understanding of the business domain, the result is &#8220;blind leading the blind&#8221; solution. Successful software engineers, who take the time to understand the context they operate in, provide higher value. </p>



<p>Context is the invisible force that molds our understanding of product intent. It is the difference between a solution that resonates and one that falls flat. As we navigate through daily agile ceremonies, recognizing and understanding the context will lead to more successful product and overall solution.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>It&#8217;s a trap!</title>
		<link>/2022/03/29/its-a-trap/</link>
		
		<dc:creator><![CDATA[John Ra]]></dc:creator>
		<pubDate>Tue, 29 Mar 2022 15:29:54 +0000</pubDate>
				<category><![CDATA[Rants]]></category>
		<guid isPermaLink="false">http://10.0.0.60/?p=560</guid>

					<description><![CDATA[Confirmation bias &#8211; the tendency to discredit non-confirmative evidence, or to seek out (actively or subconsciously) primarily confirming evidence &#8211; is part of all of us. We all suffer from it, every day. As technologist, we could do better. We should always re-evaluate all the facts and not fall into the traps of our dogma/orthodoxy &#8211; what we see or want to see. Rather than reviewing all the facts, we too often hold onto our beliefs. Ask a front-end developer which library/framework should be used for a given project, it&#8217;s rarely followed by a question on what the requirements are.&#8230;]]></description>
										<content:encoded><![CDATA[<p>Confirmation bias &#8211; the tendency to discredit non-confirmative evidence, or to seek out (actively or subconsciously) primarily confirming evidence &#8211; is part of all of us. We all suffer from it, every day. As technologist, we could do better. We should always re-evaluate all the facts and not fall into the traps of our dogma/orthodoxy &#8211; what we see or want to see.</p>


<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="525" height="354" src="/wp-content/uploads/2022/03/bias.png" alt="" class="wp-image-565"/></figure></div>



<p>Rather than reviewing all the facts, we too often hold onto our beliefs. Ask a front-end developer which library/framework should be used for a given project, it&#8217;s rarely followed by a question on what the requirements are. Rather, if they are a ReactJS developer, they will automatically respond with ReactJS. An Angular developer is no different. We end up choosing a solution first then justify its fit. Just ask why ReactJS is better solution, they will point to facts like, &#8220;it&#8217;s the most downloaded library&#8221;</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="809" height="429" src="/wp-content/uploads/2022/03/reactstat.png" alt="" class="wp-image-566"/></figure></div>



<p>By that logic, I should just go buy <a href="https://www.edmunds.com/most-popular-cars/">a Ford F-Series truck</a>. If I&#8217;m an eco-friendly individual that never needs the truck to carry loads, maybe I don&#8217;t need a truck. Maybe an electric vehicle is a better fit. Yet, because it is the most sold vehicle in America, do you think it&#8217;s the right fit. Failure to take into considerations of the facts of the requirements and/or the make-up of the engineering team, we do a disservice to our clients/customers. </p>



<h2 class="wp-block-heading">How to Avoid Confirmation Bias?</h2>



<p>Discuss your thoughts with others. Don&#8217;t jump to conclusions. Gather as much facts. Surround yourself with a diverse group of people, and don&#8217;t be afraid to listen. The simplest way to avoid confirmation bias is to look at your own beliefs. Search out ways in which your default solution may be wrong, rather than the ways in which it is right. Always be learning. Seek out competitive solutions and learn from it.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>7-Minute Abs</title>
		<link>/2022/02/02/7-minute-abs/</link>
		
		<dc:creator><![CDATA[John Ra]]></dc:creator>
		<pubDate>Wed, 02 Feb 2022 15:20:32 +0000</pubDate>
				<category><![CDATA[Humor]]></category>
		<guid isPermaLink="false">http://10.0.0.60/?p=546</guid>

					<description><![CDATA[Unless you&#8217;ve abstained from social networks, you&#8217;re probably heard of Wordle or have seen blocks of green, black, and yellow on your social feed. I have to admit, I&#8217;ve been caught up on the riptide &#8211; even google has acknowledged the popularity of it I tend to stay away from mainstream fad &#8211; especially those on social media platforms. I did, however, read the article on New York Times &#8211; who later purchased it for 7-figures. Eventually, I gave in and played to see what the craze was about. To my surprise, I was instantly hooked. I was surprised by&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Unless you&#8217;ve abstained from social networks, you&#8217;re probably heard of <a href="https://www.powerlanguage.co.uk/wordle/">Wordle</a> or have seen blocks of green, black, and yellow on your social feed. I have to admit, I&#8217;ve been caught up on the riptide &#8211; even google has acknowledged the popularity of it </p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="345" height="151" src="/wp-content/uploads/2022/02/google-wordle.png" alt="" class="wp-image-539"/></figure></div>



<p>I tend to stay away from mainstream fad &#8211; especially those on social media platforms. I did, however, read the <a href="https://www.nytimes.com/2022/01/03/technology/wordle-word-game-creator.html">article on New York Times</a> &#8211; who later <a href="https://www.inc.com/bill-murphy-jr/the-creator-of-wordle-just-sold-it-for-seven-figures-taught-5-smart-lessons-in-process.html">purchased it for 7-figures</a>. Eventually, I gave in and played to see what the craze was about. To my surprise, I was instantly hooked. I was surprised by the simplicity of it. I&#8217;ve written 2 mobile games that I published on both Apple App Store and Android Play Store &#8211; both failed to retain players. My games were too monotonous and lacked meaningful engagement to maintain revisit. I never considered the &#8220;less is more&#8221; approach. The simple idea of releasing one puzzle a day is genius.</p>



<p>This brings me to the title, &#8220;7-Minute Abs.&#8221; An old colleague mentioned it when I shared <a href="https://www.wordhex.app/">WordHex</a>, an app I created over the weekend.  &#8220;7-Minute Abs&#8221; is a <a href="https://youtu.be/rnso4nfdM9w">scene from &#8220;Something About Mary&#8221;</a> where the hitchhiker shares his business idea based on &#8220;8-Minute Abs&#8221; but in 7 minutes! It&#8217;s a little spot on.</p>



<p>I created WordHex based on Wordle except it&#8217;s 6-letter words. One puzzle a day was just not enough for me. I wanted to play another round. I also hadn&#8217;t coded in a while. Last time I did, it was in golang &#8211; I may share the back story on that in the future. WordHex is available in beta. Once it&#8217;s stable, a friend suggested I create one for 4-letter, 7-letter, and 8-letter words as well. </p>



<p>If you do find Wordle entertaining and, like me, can&#8217;t wait another day; please visit <a href="https://www.wordhex.app/">WordHex</a>. </p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>I&#8217;m Back?</title>
		<link>/2022/01/23/restart/</link>
		
		<dc:creator><![CDATA[John Ra]]></dc:creator>
		<pubDate>Sun, 23 Jan 2022 22:59:21 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://10.0.0.60/?p=527</guid>

					<description><![CDATA[It&#8217;s been a while since I posted an entry &#8211; just go ahead and look at the date on my prior post. I don&#8217;t even know if blogging is a thing anymore in the world of TikTok. Granted, given how vastness and complex technology space is, I don&#8217;t think anyone can do justice on a short video. Look, it&#8217;s not like this is my New Year&#8217;s resolution or anything like that. Let&#8217;s see if I can try to post at least once a month. And yes, I get credit for this post towards January.]]></description>
										<content:encoded><![CDATA[
<p>It&#8217;s been a while since I posted an entry &#8211; just go ahead and look at the date on my prior post.  I don&#8217;t even know if blogging is a thing anymore in the world of TikTok. Granted, given how vastness and complex technology space is, I don&#8217;t think anyone can do justice on a short video. </p>



<p>Look, it&#8217;s not like this is my New Year&#8217;s resolution or anything like that. Let&#8217;s see if I can try to post at least once a month. And yes, I get credit for this post towards January.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Design Pattern: Chain of Responsibility</title>
		<link>/2014/05/06/design-pattern-chain-of-responsibility/</link>
		
		<dc:creator><![CDATA[John Ra]]></dc:creator>
		<pubDate>Tue, 06 May 2014 21:33:01 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Development]]></category>
		<guid isPermaLink="false">http://blog.jstrgames.com/?p=387</guid>

					<description><![CDATA[In my original Tetris code base, I started out with a simple RotationController class. As I recall, this was a trivial class with a single shape. However, as more shapes were added, it quickly became unwieldy. Looking back at this code, I want to cringe at my lack of discipline in following proper design principles. On the bright side, I have something to blog about. Chain of Responsibility The chain of responsibility design pattern is known as a behavioral pattern consisting of client objects and a series of handler objects. It provides more than one object the opportunity to handle a request by&#8230;]]></description>
										<content:encoded><![CDATA[<p>In my original <a href="https://github.com/johnra74/tetris">Tetris code base</a>, I started out with a simple <a href="https://github.com/johnra74/tetris/blob/82b3f058fbf62c036623a3b3eb16ca3bf2550f2d/tetris/tetris-core/src/main/java/com/jstrgames/tetris/core/controller/RotateController.java">RotationController class</a>. As I recall, this was a trivial class with a single shape. However, as more shapes were added, it quickly became unwieldy. Looking back at this code, I want to cringe at my lack of discipline in following proper design principles. On the bright side, I have something to blog about.</p>
<p><strong>Chain of Responsibility</strong></p>
<p><a href="/wp-content/uploads/2014/05/chain_of_resp_pattern.png"><img loading="lazy" decoding="async" class="alignleft size-medium wp-image-399" src="/wp-content/uploads/2014/05/chain_of_resp_pattern-300x124.png" alt="chain_of_resp_pattern" width="300" height="124" /></a>The chain of responsibility design pattern is known as a behavioral pattern consisting of client objects and a series of handler objects. It provides more than one object the opportunity to handle a request by linking receivers together (see left UML diagram). Instead of having one monolithic class, as I have or coupling your code to each and every concrete class, with the chain of responsibility pattern, you can avoid both.</p>
<p><strong>Refactoring Rotation Controller</strong></p>
<p><a href="/wp-content/uploads/2014/05/action_controller_before.png"><img loading="lazy" decoding="async" class="alignright size-medium wp-image-394" src="/wp-content/uploads/2014/05/action_controller_before-300x240.png" alt="action_controller_before" width="300" height="240" /></a>On the right is the UML diagram for handling user inputs in my game. The ControlListener implements the Java AWT Event KeyListener. The ControlListener listens for various keyboard actions (UP_ARROW &#8211; rotate clockwise, DOWN_ARROW &#8211; drop, LEFT_ARROW &#8211; move left, RIGHT_ARROW &#8211; move right, Q &#8211; rotate counter-clockwise, and W &#8211; rotate clockwise). When user presses UP_ARROW, Q, or W, it will create an instance of RotateController class to handle the respective rotation action. On the original UML diagram, you can see the long list of private methods I&#8217;ve implemented to handle the rotation action for various tetris shapes.</p>
<p><a href="/wp-content/uploads/2014/05/action_controller_after.png"><img loading="lazy" decoding="async" class="alignleft size-medium wp-image-404" src="/wp-content/uploads/2014/05/action_controller_after-300x242.png" alt="action_controller_after" width="300" height="242" /></a>On the left is the refactored UML diagram with the rotation logic implemented using the chain of responsibility design pattern. Gone are the many private methods created to handle every possible shapes. For each shape, we now have a respective handler class responsible for rotating the shape. The chain of these rotation handler will check if can handle the rotation request by inspecting the shape associated with the request.</p>
<p> </p>


<pre class="wp-block-code"><code>public Coordinate&#91;] executeRequest(RotateRequest request) {
  final Coordinate&#91;] coordinate;
  final IShape shape = request.getShape();
  final Rotate rotate = request.getRotate();

  if( shape.getShape() == this.getShape()) {
    coordinate = getTargetCoordinates(shape, rotate);
  } else {
    if(this.nextHandler == null) {
      throw new HandlerNotFoundException("No handler defined for " + shape.getShape());
    } else {
      coordinate = this.nextHandler.executeRequest(request);
    }
  }

  return coordinate;
}</code></pre>



<p>If it cannot handle the request, it will pass the request to the next handler. If it reaches the end of the chain and no handler is found, a runtime exception will be thrown. Feel free to browse the final code base on <a href="https://github.com/johnra74/tetris/tree/master/tetris/tetris-core/src/main/java/com/jstrgames/tetris/core/controller">GitHub</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Java-based Tetris Game</title>
		<link>/2014/04/06/java-based-tetris-game/</link>
		
		<dc:creator><![CDATA[John Ra]]></dc:creator>
		<pubDate>Sun, 06 Apr 2014 20:44:43 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<guid isPermaLink="false">http://blog.jstrgames.com/?p=383</guid>

					<description><![CDATA[I&#8217;ve been planning to write some tutorials on design patterns. I just need to find some time and my day job at the corporate world has kept me busy. I plan to use this code base from a java tetris application I wrote a while back. I&#8217;ve done some clean ups &#8211; who&#8217;s not embarrassed by their old code. Don&#8217;t worry, I haven&#8217;t completely cleaned it up. After all, the plan is to write tutorials on design patterns that would help improve this code. My first topic, when I do get some time, will be Chain of Responsibility.]]></description>
										<content:encoded><![CDATA[<p>I&#8217;ve been planning to write some tutorials on design patterns. I just need to find some time and my day job at the corporate world has kept me busy. I plan to use <a href="https://github.com/johnra74/tetris">this code base</a> from a java tetris application I wrote a while back. I&#8217;ve done some clean ups &#8211; who&#8217;s not embarrassed by their old code. Don&#8217;t worry, I haven&#8217;t completely cleaned it up. After all, the plan is to write tutorials on design patterns that would help improve this code. My first topic, when I do get some time, will be <a href="/2014/05/06/design-pattern-chain-of-responsibility/">Chain of Responsibility</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Gradle Plug-in: WSDL to Java Code Generation</title>
		<link>/2014/03/08/gradle-plug-in-wsdl-to-java-code-generation/</link>
		
		<dc:creator><![CDATA[John Ra]]></dc:creator>
		<pubDate>Sat, 08 Mar 2014 14:39:38 +0000</pubDate>
				<category><![CDATA[Gradle]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Development]]></category>
		<guid isPermaLink="false">http://blog.jstrgames.com/?p=373</guid>

					<description><![CDATA[It didn&#8217;t take long for me to fall in love with Gradle. Once I was introduced to it, I never looked back. It was the same with Ant as I transitioned from Make. But, Gradle is different. I always felt building was necessary evil. It was often done way after first code was ever written. This isn&#8217;t true with Gradle. Before any code is written, I start every project by setting up my Gradle build. I actually look forward to adding more features to my build. How crazy is that?! WSDL to JavaRecently, I published one of my old SharePoint&#8230;]]></description>
										<content:encoded><![CDATA[<p>It didn&#8217;t take long for me to fall in love with <a href="http://www.gradle.org/">Gradle</a>. Once I was introduced to it, I never looked back. It was the same with <a href="http://ant.apache.org/">Ant</a> as I transitioned from <a href="https://www.gnu.org/software/make/">Make</a>. But, Gradle is different. I always felt building was necessary evil. It was often done way after first code was ever written. This isn&#8217;t true with Gradle. Before any code is written, I start every project by setting up my Gradle build. I actually look forward to adding more features to my build. How crazy is that?!</p>
<p><strong>WSDL to Java</strong><br />Recently, I published one of my old <a href="https://github.com/johnra74/sharepoint-api">SharePoint API</a> to GitHub. Originally, I had written the build script using Ant for this project. One of the task I had was to take the SharePoint List WSDL and generate the corresponding java soap client classes. This is fairly trivial task in Ant &#8211; in fact, axis already provides <a href="http://axis.apache.org/axis/java/ant/ant.html">an ant task</a>. Sure, I could google for Gradle plug-in for WSDL to Java but I wanted to use this opportunity to learn to write my own plug-in. I&#8217;ve also been looking to <a href="/2013/07/25/thats-groovy/">write more Groovy code</a>.</p>
<p><strong>Creating a Custom Gradle Task</strong><br /><a href="/wp-content/uploads/2014/03/gradle1.png"><img loading="lazy" decoding="async" class="alignright size-thumbnail wp-image-375" src="/wp-content/uploads/2014/03/gradle1-150x150.png" alt="gradle buildSrc" width="150" height="150" /></a>All custom Gradle tasks resides under buildSrc at the root of your project. If you are familiar with Gradle multiproject then you will notice that buildSrc is structured like a subproject. In fact, it is a subproject. Since I will be writing my custom task using Groovy, my source file will reside under src/main/groovy. If you wanted to write your custom task in Java, you would create it under src/main/java.</p>
<p>Since my custom task is merely a wrapper for Axis2 class org.apache.axis2.wsdl.WSDL2Java, the build.gradle file will contain the Axis2 dependencies. Note, if your custom task does not require any dependencies besides core java, then you do not need to define the build.gradle file. Here&#8217;s my build.gradle file:</p>


<pre class="wp-block-code"><code>repositories {
  mavenCentral()
}

dependencies {
  compile 'org.apache.axis2:axis2:1.6.2'
  compile 'org.apache.axis2:axis2-xmlbeans:1.6.2'
  compile 'org.apache.xmlbeans:xmlbeans:2.6.0'
}</code></pre>



<p>Once the build.gradle has been defined, I create my custom task in Groovy &#8211; WSDL2Java.groovy. The below Groovy class is a simple implementation. As you can see, there are no validation checks. It assumes all properties will be set.</p>



<pre class="wp-block-code"><code>import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
// since this groovy class has the same name as the axis2 class, alias axis2 class to CodeGen
import org.apache.axis2.wsdl.WSDL2Java as CodeGen

class WSDL2Java extends DefaultTask {
  // source location of the WSDL file
  String wsdlfilename
  // specify the binding type - xmlbeans, adb, or jibx
  String databindingName
  // target location where java classes should be created under
  String targetSourceFolderLocation
  // base package name
  String packageName

  @TaskAction
  def generateJava() {
    String&#91;] args =
      &#91;
        "-o", targetSourceFolderLocation,
        "-p", packageName,
        "-d", databindingName,
        "-or",
        "-uri", wsdlfilename
      ]
    CodeGen.main(args)
  }
}</code></pre>



<p>Here&#8217;s how this custom task is called within the project. First, I define a task called &#8220;genJavaFromWSDL&#8221; with type WSDL2Java &#8211; the Groovy class name. Within this custom task, I set all properties. Then, I update the dependency of java compile task to this custom task. This will ensure the java soap client is created before build is trigger.</p>



<pre class="wp-block-code"><code>// define the WSDL2Java task
task genJavaFromWSDL(type: WSDL2Java) {
  wsdlfilename= "$buildDir/../src/main/wsdl/Lists.SP2013.wsdl"
  databindingName='xmlbeans'
  targetSourceFolderLocation= "$buildDir/generated/wsdl/main"
  packageName='com.microsoft.sharepoint'
}

// add prior hook before compile
compileJava.dependsOn genJavaFromWSDL

// add generated wsdl java classes to source dir
sourceSets.main.java.srcDir "$buildDir/generated/wsdl/main/src"
sourceSets.main.java.srcDir "$buildDir/generated/wsdl/main/resources"</code></pre>



<div class="wp-block-image"><figure class="alignleft"><a href="/wp-content/uploads/2014/03/gradle2.png"><img decoding="async" src="/wp-content/uploads/2014/03/gradle2.png" alt="Gradle Project" class="wp-image-378"/></a></figure></div>



<p>Finally, I add the generated source and resources to the Groovy sourceSet so that the generated sources are properly compiled. It also allows them to appear under Eclipse.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Fluent Interface by Example</title>
		<link>/2014/03/01/fluent-interface-by-example/</link>
		
		<dc:creator><![CDATA[John Ra]]></dc:creator>
		<pubDate>Sat, 01 Mar 2014 22:30:17 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[SharePoint]]></category>
		<guid isPermaLink="false">http://blog.jstrgames.com/?p=364</guid>

					<description><![CDATA[Chances are you have seen Fluent Interface in action. I&#8217;ve seen it without realizing what they were until I stumbled across Martin Fowler&#8217;s blog. The aim is simple &#8211; to provide for a more readable code. SharePoint APISeveral years ago, I wrote a SharePoint API in Java to interact with its List Soap Service. This soap service had a feature to query the target list using Collaborative Application Markup Language (CAML). Here&#8217;s an example of CAML query to filter the task list where the TaskName is &#8220;Foo Bar&#8221; and the Status is &#8220;In Progress&#8221;. As part of this SharePoint API,&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Chances are you have seen Fluent Interface in action. I&#8217;ve seen it without realizing what they were until I stumbled across <a href="http://martinfowler.com/bliki/FluentInterface.html">Martin Fowler&#8217;s blog</a>. The aim is simple &#8211; to provide for a more readable code.</p>



<p><strong>SharePoint API</strong><br>Several years ago, I wrote a SharePoint API in Java to interact with its List Soap Service. This soap service had a feature to query the target list using <a href="http://msdn.microsoft.com/en-us/library/office/ms467521(v=office.15).aspx">Collaborative Application Markup Language (CAML)</a>. Here&#8217;s an example of CAML query to filter the task list where the TaskName is &#8220;Foo Bar&#8221; and the Status is &#8220;In Progress&#8221;.</p>



<pre class="wp-block-code"><code>&lt;query&gt;
  &lt;where&gt;
    &lt;and&gt;
      &lt;eq&gt;
        &lt;fieldref name="TaskName"&gt;
        &lt;value type="Text"&gt;Foo Bar&lt;/value&gt;
      &lt;/fieldref&gt;&lt;/eq&gt;
      &lt;eq&gt;
        &lt;fieldref name="Status"&gt;
        &lt;value type="Text"&gt;In Progress&lt;/value&gt;
      &lt;/fieldref&gt;&lt;/eq&gt;
    &lt;/and&gt;
   &lt;/where&gt;
&lt;/query&gt;</code></pre>



<p>As part of this SharePoint API, I had written a corresponding set of Java classes &#8211; each node represented by a class. For trivial query like above, it would look like the following:</p>



<pre class="wp-block-code"><code>final Expression leftExpression = new Equals(new Field("TaskName", "Foo Bar"));
final Expression rightExpression = new Equals(new Field("Status", "In Progress"));
final Condition condition = new And(leftExpression, rightExpression);
final Where clause = new Where(condition);
final Query query = new Query(clause);</code></pre>



<p>As you can predict, for complicated scenarios, this would quickly become unreadable. By applying the concept of Fluent Interface, we can make it far more readable. For example, the above become the following:</p>



<pre class="wp-block-code"><code>final Where clause =
  new Where(
    and(eq("TaskName", "Foo Bar"),
        eq("Status", "In Progress")));</code></pre>



<p><strong>Applying Fluent Interface</strong><br>A good Fluent Interface takes a while to build. It should be built with the goal of readability and flow in mind. Return type should be chosen based on what you need to continue fluent action. Here&#8217;s the SharePoint API implementation. For the complete implementation, please see <a href="https://github.com/johnra74/sharepoint-api/blob/master/sharepoint/sharepoint-lib/src/main/java/com/jstrgames/sharepoint/query/Where.java">GitHub Source</a>.</p>



<pre class="wp-block-code"><code>.
.
.
public static Condition and(Expression left, Expression right) {
  return new And(left, right);
}

public static Condition and(Expression left, Condition right) {
  return new And(left, right);
}

public static Condition and(Condition left, Expression right) {
  return new And(left, right);
}

public static Condition and(Condition left, Condition right) {
  return new And(left, right);
}
.
.
.
public static Expression eq(Field field) {
  return new Equals(field);
}</code></pre>



<p>For complicated scenarios where you want to get all task assigned to John with status in &#8220;New&#8221; or &#8220;In Progress&#8221; and task created after Jan 1, 2014, the CAML would like the following.</p>



<pre class="wp-block-code"><code>&lt;query&gt;
  &lt;where&gt;
    &lt;and&gt;
      &lt;eq&gt;
        &lt;fieldref name="AssignedTo"&gt;
        &lt;value type="Text"&gt;John&lt;/value&gt;
      &lt;/fieldref&gt;&lt;/eq&gt;
      &lt;and&gt;
        &lt;or&gt;
          &lt;eq&gt;
            &lt;fieldref name="Status"&gt;
            &lt;value type="Text"&gt;New&lt;/value&gt;
          &lt;/fieldref&gt;&lt;/eq&gt;
          &lt;eq&gt;
            &lt;fieldref name="Status"&gt;
            &lt;value type="Text"&gt;In Progress&lt;/value&gt;
          &lt;/fieldref&gt;&lt;/eq&gt;
        &lt;/or&gt;
        &lt;gt&gt;
          &lt;fieldref name="CreateDate"&gt;
          &lt;value type="DateTime"&gt;2014-01-01T00:00:00Z&lt;/value&gt;
        &lt;/fieldref&gt;&lt;/gt&gt;
    &lt;/and&gt;
   &lt;/and&gt;&lt;/where&gt;
&lt;/query&gt;</code></pre>



<p>Here&#8217;s the same in Fluent Interface</p>



<pre class="wp-block-code"><code>final Where clause =
  new Where(
    and(eq("AssignedTo", "John"),
    and(
      or(eq("Status", "New"),
         eq("Status", "In Progress")),
      gt("CreateDate", "2014-01-01T00:00:00Z"))));</code></pre>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Application Health Monitor</title>
		<link>/2013/09/06/application-health-monitor/</link>
		
		<dc:creator><![CDATA[John Ra]]></dc:creator>
		<pubDate>Sat, 07 Sep 2013 00:57:13 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[HttpComponent]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Maintenance]]></category>
		<category><![CDATA[Productivity]]></category>
		<guid isPermaLink="false">http://blog.jstrgames.com/?p=341</guid>

					<description><![CDATA[I&#8217;ve been meaning to contribute to open source for some time. I really didn&#8217;t have anything particularly in mind to what I wanted to publish. However, I&#8217;ve been dealing with varying degree of integration complexityÂ to some of my application environments at the office. Inevitably, someone would scratch their head for several minutes trying to figure out why something failed only to realize that it was due to an external dependency. Needless to say, a simple tool that would provide a holistic view of the system could have saved them some pain. This could then be expanded to other environments: shared&#8230;]]></description>
										<content:encoded><![CDATA[<p>I&#8217;ve been meaning to contribute to open source for some time. I really didn&#8217;t have anything particularly in mind to what I wanted to publish. However, I&#8217;ve been dealing with varying degree of integration complexityÂ to some of my application environments at the office. Inevitably, someone would scratch their head for several minutes trying to figure out why something failed only to realize that it was due to an external dependency. Needless to say, a simple tool that would provide a holistic view of the system could have saved them some pain. This could then be expanded to other environments: shared development, integration, UAT, QA, and Production. A single page that would provide an overview of the health of the specified environment would be very helpful.</p>
<p><strong>Application Monitoring</strong></p>
<p>There are several things to consider when monitoring an application. This is not meant as an exhaustive list but here are few items:</p>
<ul>
<li>application state</li>
<li>resource utilization</li>
<li>proactively report application errors</li>
<li>module/component status</li>
<li>external dependency status (databases, services, etc.)</li>
</ul>
<p>The monitor should be proactive and not reactive. It should provide early enough warning before something goes wrong. This includes monitoring dependencies and the application itself.Â There are tools that monitor logs and report when it detects various errors in the log file. Although this is better than nothing, it&#8217;s too reactive. If you&#8217;re lucky enough to have nagios in-house, this is better. However, in most cases, they are configured only for Production and, if lucky, QA. However, for other environments, it may be an overkill to use nagios.</p>
<p><strong>Health Monitoring</strong></p>
<p>The purpose of my <a href="https://github.com/johnra74/health-monitor">health monitor tool</a> is to provide a simple framework to quickly setup and actively check the overall health of any application.</p>
<p><a href="/wp-content/uploads/2013/09/healthmonitor.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-345" src="/wp-content/uploads/2013/09/healthmonitor.png" alt="healthmonitor" width="749" height="349" /></a></p>
<p>Health monitoring tool is built on the following open source frameworks:</p>
<ul>
<li><a href="http://quartz-scheduler.org/">quartz-scheduler</a> &#8211; used to schedule recurring checks to verify your site, components/modules, and dependencies</li>
<li><a href="http://hc.apache.org/">apache httpcomponents</a> &#8211; used to retrieve resources (JSON/HTML) from HTTP/HTTPS servers</li>
<li><a href="http://grizzly.java.net/">grizzly NIO framework</a> &#8211; used as embedded web container to host status page (see above screenshot)</li>
<li><a href="https://github.com/FasterXML/jackson">jackson</a> &#8211; used to parse JSON resources and configuration</li>
<li><a href="http://freemarker.org/">freemarker</a> &#8211; used for web/email template</li>
<li><a href="http://www.oracle.com/technetwork/java/javamail/index.html">javamail</a> &#8211; used to send failure notification</li>
</ul>
<p>It can proactively check your application and its dependencies with predefined service checks:</p>
<ul>
<li><a href="https://github.com/johnra74/health-monitor/blob/master/health-monitor/src/main/java/com/jstrgames/monitor/svc/impl/HttpService.java">com.jstrgames.monitor.svc.impl.HttpService</a> &#8211; make non-SSL web call</li>
<li><a href="https://github.com/johnra74/health-monitor/blob/master/health-monitor/src/main/java/com/jstrgames/monitor/svc/impl/HttpsService.java">com.jstrgames.monitor.svc.impl.HttpsService</a> &#8211; make SSL web call</li>
<li><a href="https://github.com/johnra74/health-monitor/blob/master/health-monitor/src/main/java/com/jstrgames/monitor/svc/impl/SimpleJmxService.java">com.jstrgames.monitor.svc.impl.SimpleJmxService</a> &#8211; make simple remote JMX calls</li>
<li><a href="https://github.com/johnra74/health-monitor/blob/master/health-monitor/src/main/java/com/jstrgames/monitor/svc/impl/SocketService.java">com.jstrgames.monitor.svc.impl.SocketService</a> &#8211; make a client socket call</li>
</ul>
<p>It can then verify these services with predefined rules:</p>
<ul>
<li><a href="https://github.com/johnra74/health-monitor/blob/master/health-monitor/src/main/java/com/jstrgames/monitor/rule/HttpResponseCode.java">com.jstrgames.monitor.rule.HttpResponseCode</a> &#8211; check if expected status code returned</li>
<li><a href="https://github.com/johnra74/health-monitor/blob/master/health-monitor/src/main/java/com/jstrgames/monitor/rule/HttpResponseBody.java">com.jstrgames.monitor.rule.HttpResponseBody</a> &#8211; check if body contains expected values</li>
<li><a href="https://github.com/johnra74/health-monitor/blob/master/health-monitor/src/main/java/com/jstrgames/monitor/rule/JsonResponse.java">com.jstrgames.monitor.rule.JsonResponse</a> &#8211; check if specified JSON key has expected value</li>
<li><a href="https://github.com/johnra74/health-monitor/blob/master/health-monitor/src/main/java/com/jstrgames/monitor/rule/SimpleJmxResult.java">com.jstrgames.monitor.rule.SimpleJmxResult</a> &#8211; check if specified JMX attribute has expected value</li>
</ul>
<p>All can be configured on a simple <a href="https://github.com/johnra74/health-monitor/blob/master/health-monitor/src/test/resources/demo.services.json">JSON format configuration file</a>.</p>
<p><strong>Example: Checking HTTPS site</strong></p>
<p>The use case is to verify that the text &#8220;Google Search&#8221; and &#8220;I&#8217;m Feeling Lucky&#8221; appears on the google.com page every 5 minutes:</p>


<pre class="wp-block-code"><code>&#91;{"servicename": "HTTPS Example (SSL)",
  "classname": "com.jstrgames.monitor.svc.impl.HttpsService",
  "schedule": "0 0/5 * * * ?",
  "hostname": "www.google.com",
  "port": 443,
  "uri": "/",
  "rules": &#91;{
    "classname": "com.jstrgames.monitor.rule.HttpResponseCode",
    "condition": "equals",
    "expected": 200
  },{
    "classname": "com.jstrgames.monitor.rule.HttpResponseBody",
    "condition": "contains",
    "expected": "Google Search"
  },{
    "classname": "com.jstrgames.monitor.rule.HttpResponseBody",
    "condition": "contains",
    "expected": "I'm Feeling Lucky"
  }]
}]</code></pre>



<p>Here, class com.jstrgames.monitor.svc.impl.HttpsService is used check www.google.com at port 443. Once the resource has been retrieved, 3 rules are executed:</p>



<ul><li>verify http response code is 200</li><li>verify http response body contains the phrase &#8220;Google Search&#8221;</li><li>verify http response body contains the phrase &#8220;I&#8217;m Feeling Lucky&#8221;</li></ul>



<p>If any of the above checks fails, service is considered to be in &#8220;FAIL&#8221; status. If it fails to connect to said service, it is in &#8220;ERROR&#8221; status. It will also send out a notification and user will see a similar content in their inbox, granted, not as pretty.</p>



<div class="wp-block-image"><figure class="aligncenter"><a href="/wp-content/uploads/2013/09/healthmonitor.email_.png"><img decoding="async" src="/wp-content/uploads/2013/09/healthmonitor.email_.png" alt="healthmonitor.email" class="wp-image-353"/></a></figure></div>



<p>For more details, please go to my <a href="https://github.com/johnra74/health-monitor/blob/master/health-monitor">github repository</a>. I will be updating its wiki page soon.</p>



<p></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
