﻿<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:a10="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title>Latest Articles from Joe Pruitt | F5 DevCentral</title>
    <link>https://devcentral.f5.com/</link>
    <description>The latest Articles from Joe Pruitt on F5's Technical Community!</description>
    <language>en-us</language>
    <copyright>Copyright by F5 Networks</copyright>
    <a10:link rel="self" href="https://devcentral.f5.com/" />
    <item>
      <link>https://devcentral.f5.com/articles/getting-started-with-icontrol-history-20463</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>DevCentral Basics</category>
      <category>devops</category>
      <category>icontrol</category>
      <category>icontrolrest</category>
      <category>programmability</category>
      <title>Getting Started with iControl: History</title>
      <description>&lt;p&gt;&lt;img alt="DevCentral_Basics_iControl" class="img-responsive" src="/Portals/0/userfiles/15006/devcentral_basics_article_banner.png" /&gt;&lt;/p&gt;

&lt;p class="alert alert-info"&gt;tl;dr - iControl provides access to BIG-IP management plane services through SOAP and REST API interfaces.&lt;/p&gt;

&lt;h3&gt;The Early Days&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/corba5.gif"&gt;&lt;img align="right" alt="corba5" border="0" height="122" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/corba5_thumb.gif" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 10px; border-left: 0px; display: inline; padding-right: 0px" title="corba5" width="181" /&gt;&lt;/a&gt;iControl started back in early 2000.&amp;nbsp; F5 had 2 main products: BIG-IP and 3-DNS (later GTM, now BIG-IP DNS).&amp;nbsp; BIG-IP managed the local datacenter&amp;#39;s traffic, while 3-DNS was the DNS orchestrator for all the BIG-IP&amp;#39;s in numerous data centers.&amp;nbsp; The two products needed a way to communicate with each other to ensure they were making the right traffic management decisions respective to all of the products in the system.&amp;nbsp; At the time, the development team was focused on developing the fastest running code possible and that idea found it&amp;#39;s way into the cross product communication feature that was developed.&amp;nbsp; The technology the team chose to use was the Common Object Request Broker Architecture (CORBA) as standardized by the Object Management Group (OMG).&amp;nbsp; Coming hot off the heels of F5&amp;#39;s first management product SEE-IT (which was another one of my babies), the dev team coined this internal feature as &amp;quot;LINK-IT&amp;quot; since it &amp;quot;linked&amp;quot; the two products together.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;With the development of our management, monitoring, and visualization product SEE-IT, we needed a way to get the data off of the BIG-IP.&amp;nbsp; SEE-IT was written for Windows Server and we really didn&amp;#39;t want to go down the route of integrating into the CORBA interface due to several factors.&amp;nbsp; So, we wrote a custom XML provider on BIG-IP and 3-DNS to allow for configuration and statistic data to be retrieved and consumed by SEE-IT.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;It was becoming clear to me that automation and customization of our products would be beneficial to our customers who had been previously relying on our SNMP offerings.&amp;nbsp; We now had 2 interfaces for managing and monitoring our devices: one purely internal (LINK-IT) and the other partially (XML provider). The XML provider was very specific to our SEE-IT products use case and we didn&amp;#39;t see a benefit of trying to morph that so we looked back at LINK-IT to see what we could to do make that a publicly supported interface.&amp;nbsp; We began work on documenting and packaging it into F5&amp;#39;s first public SDK.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/soap2.gif"&gt;&lt;img align="left" alt="soap2" border="0" height="81" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/soap2_thumb.gif" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: left; padding-top: 0px; padding-left: 0px; margin: 10px; border-left: 0px; display: inline; padding-right: 0px" title="soap2" width="143" /&gt;&lt;/a&gt;About that time, a new standard was emerging for exchanging structured information.&amp;nbsp; &lt;a href="https://en.wikipedia.org/wiki/SOAP"&gt;The Simple Object Access Protocol (SOAP)&lt;/a&gt;, which allows for structured information exchange, was being developed but not fully ratified until version 1.2 in 2003.&amp;nbsp; I had to choose to roll our own XML implementation or make use of this new proposed specification.&amp;nbsp; There was risk as the specification was not a standard yet but I made the choice to go the SOAP route as I felt that picking a standard format would give us the best 3rd party software compatibility down the road.&amp;nbsp; Our CORBA interface was built on a nice class model which I used as a basis for an SOAP/XML wrapper on top of that code.&amp;nbsp; I even had a great code name for the interface: X-LINK-IT!&amp;nbsp; For those who were around when I gave my &amp;quot;XML at F5&amp;quot; presentation to F5 Product Development, you may remember the snide comments going around afterwards about how XML was not a great technology and a big mistake supporting.&amp;nbsp; Good thing I didn&amp;#39;t listen to them...&lt;/p&gt;

&lt;p&gt;At this point in mid-2001, the LINK-IT SDK was ready to go and development of X-LINK-IT was well underway.&amp;nbsp; Well, let&amp;#39;s just say that Marketing didn&amp;#39;t agree with our ingenious product naming and jumped in to VETO our internal code names for our public release.&amp;nbsp; I&amp;#39;ll give our Chief Marketer Jeff Pancottine credit for coining the term &amp;quot;iControl&amp;quot; which was explained to me as &amp;quot;Internet Control&amp;quot;.&amp;nbsp; This was the start of F5&amp;#39;s whole Internet Controlled Architecture messaging by the way.&amp;nbsp; So, LINK-IT and X-LINK-IT were dead and iControl CORBA and iControl SOAP were born.&lt;/p&gt;

&lt;h3&gt;The Death of CORBA, All Hail SOAP&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/iControlDiscLabel-2001.jpg"&gt;&lt;img align="right" alt="iControlDiscLabel-2001" border="0" height="111" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/iControlDiscLabel-2001_thumb.jpg" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 10px; border-left: 0px; display: inline; padding-right: 0px" title="iControlDiscLabel-2001" width="147" /&gt;&lt;/a&gt;The first version of the iControl SDK for CORBA was released on 5/25/2001 with the SOAP version trailing it by a few months.&amp;nbsp; This was around the BIG-IP version 3 time frame.&amp;nbsp; We chugged along for a few years through the BIG-IP version 4 life and then a big event occurred that was the demise for CORBA - well, it&amp;#39;s actually 2 events.&amp;nbsp; The first event was the full rewrite of the BIG-IP data plane when TMOS was introduced in BIG-IP, version 9 (we skipped from version 4 to version 9 for some reason that slips my mind).&amp;nbsp; Since virtually the entire product was rewritten, the interfaces that were tied to the product features, would have to change drastically.&amp;nbsp; We used this as an opportunity to look at the next evolution of iControl.&amp;nbsp; Until this point, iControl SOAP was just a shim on top of CORBA and it had some performance issues so we worked at splitting them apart and having SOAP talk directly to our configuration engine.&amp;nbsp; Now we had 2 interface stacks side by side.&amp;nbsp; The second event was learning we only had 1 confirmed customer using the CORBA interface compared to the 100&amp;#39;s using SOAP.&amp;nbsp; Given that knowledge and now that BIG-IP and 3-DNS no longer used iControl CORBA to talk to each other, the decision was made to End of Life iControl CORBA with Version 9.0.&amp;nbsp; But, iControl SOAP still used the CORBA IDL files for it&amp;#39;s API definitions and documentation so fun trivia note: the same CORBA tools are still in place in today&amp;#39;s iControl SOAP build tools that were there in version 3 of BIG-IP.&amp;nbsp; I&amp;#39;m fairly sure that is the longest running component in our build system.&lt;/p&gt;

&lt;h3&gt;The Birth of DevCentral&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/f5.png"&gt;&lt;img align="left" alt="f5" border="0" height="46" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/f5_thumb.png" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: left; padding-top: 0px; padding-left: 0px; margin: 10px 10px 10px 0px; border-left: 0px; display: inline; padding-right: 0px" title="f5" width="172" /&gt;&lt;/a&gt;I can&amp;#39;t speak about iControl without mentioning DevCentral.&amp;nbsp; We had our iControl SDK out but no where to directly support the developers using it.&amp;nbsp; At that time, F5 was a &amp;quot;hardware&amp;quot; company and product support wasn&amp;#39;t ready to support application developers.&amp;nbsp; Not many know that DevCentral was created due to the popularity of iControl with our customer base and was born on a PC under my desk in 2003.&amp;nbsp; I continued to help with DevCentral part time for a few years but in 2007 I decided to work full time on building our community and focusing 100% on DevCentral.&amp;nbsp; It was about this time that we were pushing the idea of merging the application and infrastructure teams together - or at least getting them to talk more frequently.&amp;nbsp; This was a precursor to the whole DevOps mentality so I&amp;#39;d like to think we were a bit ahead of the curve on that.&lt;/p&gt;

&lt;h3&gt;Enter iControl REST&lt;/h3&gt;

&lt;p&gt;In 2013, iControl was reaching it&amp;#39;s teenage years and starting to show it&amp;#39;s age a bit.&amp;nbsp; While SOAP is still supported by all the major tool vendors, application development was shifting to richer browser-based apps.&amp;nbsp; And with that, Representational State Transfer (REST) was gaining steam.&amp;nbsp;&amp;nbsp; REST defined a usage pattern for using browser based mechanisms with HTTP to access objects across the network with a JavaScript Object Notation (JSON) format for the content.&amp;nbsp; To keep up with current technologies, the PD team at F5 developed the first REST/JSON interface in BIG-IP version 11.5 as Early Access and was made Generally Available in version 11.6.&amp;nbsp; With the REST interface, more modern web paradigms could be supported and you could actually code to iControl directly from a browser! There were also additional interface based tools for developing and debugging built directly into the service to give service listings and schema definitions.&lt;br /&gt;
At the time of this writing, F5 supports both of the main iControl interfaces (SOAP and REST) but are focusing all new energy on our REST platform for the future.&amp;nbsp; For those who have developed SOAP integrations, have no fear as that interface is not going away.&amp;nbsp; It will just likely not get all the new feature support that will be added into the REST interfaces over time.&lt;/p&gt;

&lt;h3&gt;SDKs, Toolkits, and Libraries&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/iControlPowerShell.jpg"&gt;&lt;img align="right" alt="iControlPowerShell" border="0" height="110" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/iControlPowerShell_thumb.jpg" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 10px; border-left: 0px; display: inline; padding-right: 0px" title="iControlPowerShell" width="142" /&gt;&lt;/a&gt;Through the years, I&amp;#39;ve developed several client libraries (.Net, PowerShell, Java) for iControl SOAP to assist with ramp-up time for initial development.&amp;nbsp; There have also been numerous other language based libraries for languages like Ruby, PHP, and Python developed by the community and other development teams.&amp;nbsp; Most recently, F5 has published the iControl library for Python which is available as part of our OpenStack integration.&amp;nbsp; DevCentral is your place to for our API documentation where we update our wiki with API changes on each major release.&amp;nbsp; And as time rolls on, we are adding REST support for new and existing products such as iWorkflow, BIG-IQ, and other products yet to be released that will include SDKs and other reference material.&lt;/p&gt;

&lt;p&gt;F5 has a strong commitment to our end users and their automation and integration projects with F5 technologies.&amp;nbsp; Coming full circle, my current role is overseeing APIs and SDKs for standards, consistency, and completeness in our Programmability and Orchestration (P&amp;amp;O) team so keep a look out for future articles from me on our efforts on that front.&amp;nbsp; And REST assured, we will continue to do all we can to help our customers move to new architectures and deployment models with programmability and automation with F5 technologies.&lt;/p&gt;
</description>
      <pubDate>Mon, 13 Jun 2016 04:00:00 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/devops-101-automation</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>101</category>
      <category>deployment</category>
      <category>devops</category>
      <category>icontrol</category>
      <category>irules</category>
      <title>DevOps 101 - Automation</title>
      <description>&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/Automation.png"&gt;&lt;img align="right" alt="Automation" border="0" height="244" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/Automation_thumb.png" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 10px; border-left: 0px; display: inline; padding-right: 0px" title="Automation" width="187" /&gt;&lt;/a&gt;In my last few articles, I&amp;#39;ve begun the discussion on the 6 pillars of DevOps and have covered Management, Integration, Communication, and Collaboration:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/devops-101-management"&gt;Management&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/devops-101-integration"&gt;Integration&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/devops-101-communication"&gt;Communication and information sharing&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/devops-101-collaboration"&gt;Collaboration&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
 &lt;li&gt;Automation&lt;/li&gt;
 &lt;li&gt;Measurement&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;The Fifth Pillar&lt;/h2&gt;

&lt;p&gt;Next on the list is Automation.&amp;nbsp; Automation is defined as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;The technique, method, or system of operating or controlling a process by highly automatic means, as by electronic devices, reducing human intervention to a minimum.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Back in the day when deployment meant copying code to the one server you had connected directly to the internet, you could get away with manual processes, but it was still fraught with potential issues.&amp;nbsp; That is definitely not true with today&amp;#39;s rats nest of wires, servers, virtual machines, proxies, load balancers, firewalls, and all the other components needed to host a scalable and secure network.&lt;/p&gt;

&lt;p&gt;In the early 2000&amp;#39;s when I developed &lt;a href="https://devcentral.f5.com/icontrol"&gt;iControl&lt;/a&gt; (F5&amp;#39;s first web service based management interface), I saw the pain that developers and network ops faced when dealing with application deployment.&amp;nbsp; I talked about this in my &amp;quot;&lt;a href="https://devcentral.f5.com/articles/devops-101-a-brief-history-of-time"&gt;DevOps - A Brief History of Time&lt;/a&gt;&amp;quot;&amp;nbsp; article I wrote earlier this year.&amp;nbsp; Developers needed a better way to get their code pushed to the end user and Network ops needed a better way to understand how the applications worked and trust the development team to be a part of the deployment process.&amp;nbsp; I talked a lot about the brick wall the existed between Dev and Ops and that automation was critical in leveraging the talents from both sides.&lt;/p&gt;

&lt;h2&gt;Automation - The Glue That Binds Dev to Ops&lt;/h2&gt;

&lt;p&gt;It&amp;#39;s taken over 10 years, but DevOps has been the catalyst to blowing up that brick wall and coordinating the two teams together.&amp;nbsp; But, network ops would never hand the keys to the network kingdom over to the developers so something was going to have to be put in place that was testable, reliable, and free from the risk of fat-fingering a config option that could take down the network.&lt;/p&gt;

&lt;p&gt;Automation is the key to providing the trust and reliability into the equation and acts as the glue that binds the two teams together during the production phase.&amp;nbsp; Automation fits into all aspects of the deployment process including development, testing, deployment, and all of the sub-processes within.&amp;nbsp; Care needs to be made to ensure that all components in your system can be automated via software integrations or APIs.&amp;nbsp; The build system, the testing tools, and the network components (load balancers, firewalls, application delivery devices, security appliances, etc) all need to be able to be scripted or programmed.&lt;/p&gt;

&lt;p&gt;When dealing with 2 or 2000 developers, tools are needed to ensure that the collaborative work done can be integrated with success to achieve the desired results.&amp;nbsp; Continuous Integration is the process of merging all development code into a shared codebase on frequent intervals.&amp;nbsp; Merges aren&amp;#39;t complete with out validation to ensure the merge didn&amp;#39;t break anything so integrated testing is also a critical component.&amp;nbsp; When merges occur, automated tests are triggered so that the developers will know right away if their work needs a little bit more &lt;a href="https://en.wiktionary.org/wiki/tender_loving_care"&gt;TLC&lt;/a&gt; .&amp;nbsp; When check-ins occur to the revision control system, automated build servers compile the code and run the automated tests.&amp;nbsp; In addition to functional testing, performance and optimization testing is also occurring during this process.&lt;/p&gt;

&lt;h3&gt;Build tools&lt;/h3&gt;

&lt;p&gt;For the system to flow together, a centralized build system is needed that will interact with the various test and deployment systems.&amp;nbsp; Vendors/Tools in the &amp;quot;Build&amp;quot; space are&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;a href="https://ant.apache.org/"&gt;Ant&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://inedo.com/buildmaster"&gt;BuildMaster&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://buildr.apache.org/"&gt;Buildr&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://maven.apache.org/"&gt;Maven&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://github.com/ruby/rake"&gt;Rake&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Automated Testing&lt;/h3&gt;

&lt;p&gt;Integrating testing into the development and build process both locally and at the central build server is done to ensure an issue-free code base.&amp;nbsp; Tools in this space include&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;a href="https://xebialabs.com/"&gt;Appium&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://cucumber.io/"&gt;Cucumber&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://fitnesse.org/"&gt;FitNesse&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://junit.org/"&gt;JUnit&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://docs.seleniumhq.org/"&gt;Selenium&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://xebialabs.com/products/xl-testview/"&gt;XL TestView&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Continuous Integration&lt;/h3&gt;

&lt;p&gt;CI should occur frequently enough that no errors can arise in the compilation or testing of the code without developers noticing and correcting them immediately.&amp;nbsp; Typical practice is to trigger a build every time code is committed to a revision control system, rather than periodic scheduled builds.&amp;nbsp; To achieve this, CI relies on a code repository, build automation, build self-testing, commits auto-build, and having a replica of the production environment to perform tests.&amp;nbsp; Vendors and tools in the CI space include:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;a href="https://www.atlassian.com/software/bamboo"&gt;Bamboo&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://continuum.apache.org/"&gt;Continuum&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://cruisecontrol.sourceforge.net/"&gt;CruiseControl&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://gump.apache.org/"&gt;Gump&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://hudson-ci.org/"&gt;Hudson&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://jenkins-ci.org/"&gt;Jenkins&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Continuous Delivery&lt;/h3&gt;

&lt;p&gt;Continuous Delivery (CD) is the process of building a deployment pipeline where a set of tests are performed that must pass before a piece of software is allowed to be released.&amp;nbsp; Teams produce software updates in short cycles to ensure the software can be reliably released at any time.&amp;nbsp; CD builds on CI by adding regular deployments to production as part of the build process.&amp;nbsp; A healthy CD process aids in accelerated time to market, improved productivity, reliability, quality, and customer satisfaction.&amp;nbsp; Vendors in the CD space include:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;a href="http://www.ansible.com/home"&gt;Ansible&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://www.chef.io/"&gt;Chef&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://www.thoughtworks.com/products/go-continuous-delivery"&gt;Go&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://electric-cloud.com/products/electricflow/"&gt;Electric Cloud&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://www.ibm.com/software/tivoli"&gt;IBM Tivoli&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://puppetlabs.com/"&gt;Puppet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;It Doesn&amp;rsquo;t Stop There&lt;/h2&gt;

&lt;p&gt;Automation can take place at virtually every step of the application delivery process.&amp;nbsp; A successful implementation of automation within the DevOps methodology will lead to better products and thus much happier customers.&amp;nbsp; For those just tackling DevOps, start small by automating with scripts manual processes that are time consuming.&amp;nbsp; Then move into software solutions that assist with the build/test/deploy areas, then look on how to tie them together.&amp;nbsp;&amp;nbsp; The hard part is going to be picking which solutions to use to achieve this goal but luckily there are many vendors and products in this space so it&amp;rsquo;ll be just a matter of you finding what works for your environment.&lt;/p&gt;
</description>
      <pubDate>Thu, 24 Sep 2015 13:08:31 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/nodejs-abcs-p-is-for-post</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>devops</category>
      <category>node</category>
      <title>Node.js ABC’s - P is for POST</title>
      <description>&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/HTTPMethods.gif"&gt;&lt;img title="HTTPMethods" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 10px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="HTTPMethods" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/HTTPMethods_thumb.gif" width="240" align="right" height="142"&gt;&lt;/a&gt;With the web services that are popping from your corporate networks to the wild-internet, accessing HTTP based resources is becoming a critical component to any and all application development.  One of the more popular API application design styles is &lt;a href="https://en.wikipedia.org/wiki/Representational_state_transfer"&gt;Representational State Transfer&lt;/a&gt;  (or REST).   REST implementations are typically developed on top of HTTP with the objects you are effecting being in the URI and the actions, or verbs, being the HTTP methods.  The HTTP methods follow the four basic methods of persistent storage as referenced in the &lt;a href="https://en.wikipedia.org/wiki/Create,_read,_update_and_delete"&gt;CRUD&lt;/a&gt;  acronym of Create, Read, Update, and Delete acronym.&lt;/p&gt; &lt;h2&gt;The Verbs (Actions)&lt;/h2&gt; &lt;ul&gt; &lt;li&gt;POST - Create new object  &lt;li&gt;GET - Read the contents of an existing object  &lt;li&gt;PUT - Update an existing object  &lt;li&gt;DELETE - Delete an object&lt;/li&gt;&lt;/ul&gt; &lt;h2&gt;The Nouns (Objects)&lt;/h2&gt; &lt;p&gt;While the HTTP method defines the action you take, the URI defines the object you wish to act on.  The URI path can be used to specify hierarchy as illustrated in the following set of resources&lt;/p&gt; &lt;ul&gt; &lt;li&gt;POST /article - create an article  &lt;li&gt;PUT /article/10 - update article #10  &lt;li&gt;POST /article/10/comment - create a comment on article #10  &lt;li&gt;DELETE /article/10/comment/1 - delete comment #1 on article #10&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;In the above examples, the id's of the objects were included in the URI paths to identify the various specific objects.  This is a typical pattern in API design but it's also possible to include those values as part of the payload in the requests&lt;/p&gt; &lt;h2&gt;Sample Client and Server&lt;/h2&gt; &lt;p&gt;If you are implementing a Node.js based solution, you will likely come into a spot where you need to write either a HTTP client, HTTP server, or both.  While the different verbs have subtle differences in how you pass data (GET and DELETE pass parameters in the URI, while POST and PUT utilize payload data within the request), I'll focus this article on how to build a simple client and server that accept POST data (for new object creation).&lt;/p&gt; &lt;h3&gt;The Server (http-server.js)&lt;/h3&gt; &lt;p&gt;The server code for this article is a basic HTTP listener that supports both GET and POST requests.  It logs the request content and then returns a message to the calling application.&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;var http = require('http');

function requestHandler(request, response) {
  console.log("--------------------------");
  console.log(request.method + ": " + request.url);
  if ( request.method == "POST" ) {
    request.setEncoding('utf8');
    var data = "";
    request.on("data", function(chunk) {
      data += chunk;
    });
    request.on("end", function() {
      console.log("DATA: " + data);
    });
  }
  response.end("Thank you for " + request.method + "ing the uri '" + request.url + "'");
}

var server = http.createServer(requestHandler);

server.listen(8080, function() {
  console.log("Listening on http://localhost");
});&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;The Client (http-client.js)&lt;/h3&gt;
&lt;p&gt;The client application illustrates how to make a simple GET request and a POST request with payload data.  The GET request is meant to retrieve a listing of articles, and the POST request will create a comment on an existing article.&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;var http = require("http");

// GET
var get_options = {
  host: "localhost",
  port: 8080,
  path: "/article"
};

http.get(get_options, function(response) {
  response.setEncoding("utf8");
  console.log("Response status code: " + response.statusCode);
  response.on("data", function(data) {
    console.log("Data: " + data);
  });
});

// POST
var post_data = "{'content': 'Blah Blah Blah'}";
var post_options = {
  host: "localhost",
  port: 8080,
  path: "/article/10/comment",
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Content-Length": post_data.length
  }
};

var request = http.request(post_options, function(response) {
  response.setEncoding("utf8");
  console.log("Response status code: " + response.statusCode);
  response.on("data", function(data) {
    console.log("Data: " + data);
  });
});
request.write(post_data);
request.end();&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Running the code&lt;/h3&gt;
&lt;p&gt;The client and the server programs can be run by loading them with the node runtime&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;$ node http-server.js
Listening on http://localhost
--------------------------
GET: /article
--------------------------
POST: /article/10/comment
DATA: {'content': 'Blah Blah Blah'}&lt;/code&gt;&lt;/pre&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;$ node http-client.js
Response status code: 200
Data: Thank you for GETing the uri '/article'
Response status code: 200
Data: Thank you for POSTing the uri '/article/10/comment'&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;With the built-in http node package, calling a HTTP POST method is very seamless and you can be well on your way to building a client or server as part of your architectural solution.&lt;/p&gt;</description>
      <pubDate>Mon, 21 Sep 2015 14:19:05 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/nodejs-abcs-o-is-for-object</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>devops</category>
      <category>node</category>
      <title>Node.js ABC’s - O is for Object</title>
      <description>&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/object.png"&gt;&lt;img title="object" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 10px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="object" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/object_thumb.png" width="259" align="right" height="260"&gt;&lt;/a&gt;Objects are one of the core components of the JavaScript language and something that you will interact with every time you look at a pice of JavaScript code.  The easiest way to explain what a JavaScript Object is would be to compare it to an "object" in real life.  In JavaScript, an Object is a single entity with properties and a type.  Compare that to a car.  A car is a standalone object with properties too.  A car has weight, design, color, materials, passenger capacity, etc.  In the same way, a JavaScript object can have it's own set of properties which define it's characteristics.&lt;/p&gt; &lt;h2&gt;Constructing and Object&lt;/h2&gt; &lt;p&gt;There are several ways to create an object from scratch.  You can use the Object constructor with the new operator or you can use the alternate object literal syntax by using curly-braces.  These are called "Object Initializers".&lt;/p&gt; &lt;h3&gt;Object Initializers&lt;/h3&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;// create object from Object's constructor&lt;br&gt;var car = new Object();
// create object with object literal syntax&lt;br&gt;var car = {};&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Object literal syntax is almost always preferred as it allows you to easily pre-populate the Object with properties.  The following example creates a new "car" object that represents a blue 2015 Honda Accord.&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;var car = {
  make: "Honda",
  model: "Accord",
  year: 2015,
  color: "blue"
};&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Object Literal Notation looks a lot like JSON (JavaScript Object Notation) but differs in that wrapping property names in single or double quotes is optional, while with JSON it's mandatory.  Certain JSON libraries allow for single quotes, but for broadest compatibility, I'd suggest using double quotes whenever possible.&lt;/p&gt;
&lt;p&gt;This alternate declaration from above is both valid Object Literal Notation as well as JSON.  &lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;var car = {
  "make": "Honda",
  "model": "Accord",
  "year": 2015,
  "color": "blue"
};&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Constructor Functions&lt;/h3&gt;
&lt;p&gt;To use this method, you create a function named the type of Object you want, and in the function body, assign property values to the "this" property.  The following example creates a "Car" constructor function and creates a new Car object of make "Honda".&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;// create a "Car" constructor function
function Car(make) {
  this.make = make
};
var car = new Car("Honda");&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;The Object.create Method&lt;/h3&gt;
&lt;p&gt;Objects can also be created using the "Object.create()" method.  This method behaves similarly to the constructor function, but allows you to choose a prototype object for the object without defining a constructor function.&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;var Car = {
  "make": "Unknown",
  "getMake": function() { return this.make; }
};
var honda = Object.create(Car);
honda.make = "Honda";&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Object Properties&lt;/h2&gt;
&lt;p&gt;As you have seen above, a JavaScript object can have properties associated with it.  Think of a property of an object as a variable attached to it.  Object properties are just like variables except that they are scoped within the context of that object.  In the above example, I created a "car" object with "make", "model", "year", and "color" properties.&lt;/p&gt;
&lt;p&gt;Properties are not limited to strings and integers.  They can be any JavaScript type object including Functions and Objects themselves.&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;var interior = {
  "upholstery": "leather",
  "color": "tan",
  "mud-guards": "all-weather"
};
var car = {
  "make": "Honda", // String
  "model", "Accord", // String
  "year", 2015, // Integer
  "color": "blue", // String
  "interior": interior, // Object
  "mileage": function() { // Function
    return 12345;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Adding Properties To An Existing Object&lt;/h3&gt;
&lt;p&gt;If you have an existing object and would like to add a property to it, it's as simple as assigning it a value with the "dot" or "bracket" notation&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;car.transmission = "manual";
car["sunroof"] = true;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An Object property name can be a string, or anything that can be dynamically converted to a string.  But, if the property name starts with, or contains special characters, you must use the "bracket" notation.&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;var prop_name = "1CoolProperty";
car[prop_name] = "some value";&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Enumerating Properties Of An Object&lt;/h3&gt;
&lt;p&gt;There are three native ways to enumerate object properties: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;"for..in" loops which traverse all enumerable properties of an object (and it's prototype chain)&lt;/li&gt;
&lt;li&gt;The "Object.keys(o)" method which returns an array with the enumerable properties of the object (not the prototype chain)&lt;/li&gt;
&lt;li&gt;The "Object.getOwnPropertyNames(o)" method which returns an array with the property names of an object.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Below is an example of iterating through all the properties of an object (including it’s inheritance chain) and filtering out only those properties that belong directly to that object.&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;for (var prop_name in car) {
  if (car.hasOwnProperty(prop_name)) {
    console.log(prop_name + " = " + car[prop_name] + "\n");
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Inheritance and Prototypes&lt;/h2&gt;
&lt;p&gt;Above I mentioned the word "prototype".  All Objects in JavaScript inherit from at least one other object.  This inherited object is known as the prototype and all inherited prototypes can be accessed with the "prototype" object of the constructor.  Discussing prototypes and inheritance is more than a single article in itself, so I'll point you to the Mozilla documentation on &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain"&gt;Inheritance and the Prototype Chain&lt;/a&gt; for further reading on that topic.&lt;/p&gt;
&lt;h2&gt;Deleting Properties&lt;/h2&gt;
&lt;p&gt;You can remove a property from an object by using the "delete" operator.  Keep in mind that you can only delete properties that are in scope with the current object (not inherited).  The following code shows you how to remove a property:&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;var car = {
  "make": "Honda",
  "model": "Accord",
  "year": 2015,
  "color": "blue"
};
delete car.color; // Deletes the color property for the car object.&lt;/code&gt;&lt;/pre&gt;</description>
      <pubDate>Wed, 16 Sep 2015 15:12:42 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/devops-101-collaboration</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>devops</category>
      <category>management</category>
      <title>DevOps 101 - Collaboration</title>
      <description>&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/Collaboration.png"&gt;&lt;img align="right" alt="Collaboration" border="0" height="244" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/Collaboration_thumb.png" style="margin: 10px; border: 0px currentColor; border-image: none; padding-top: 0px; padding-right: 0px; padding-left: 0px; float: right; display: inline; background-image: none;" title="Collaboration" width="189" /&gt;&lt;/a&gt;In my previous articles on the history of DevOps, I outlined the following pillars of the DevOps methodology&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/devops-101-management"&gt;Management&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/devops-101-integration"&gt;Integration&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/devops-101-communication"&gt;Communication and information sharing&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;Collaboration&lt;/li&gt;
 &lt;li&gt;Automation&lt;/li&gt;
 &lt;li&gt;Measurement&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;The Fourth Pillar&lt;/h2&gt;

&lt;p&gt;The fourth pillar is Collaboration.&amp;nbsp; Collaboration is defined as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;working with others to do a task and to achieve shared goals.&amp;quot;&amp;nbsp;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In traditional separated organizations, there is not often collaboration between the design, development, testing (QA), and deployment (IT) functions that go with the application delivery lifecycle.&lt;/p&gt;

&lt;p&gt;As I mentioned in my &lt;a href="https://devcentral.f5.com/articles/devops-101-communication"&gt;last article&lt;/a&gt;, Communication is essential for successful for cross-departmental teams to work together effectively to deploy applications.&amp;nbsp; But, without collaboration tools to put some structure and process around those communications, it will be very difficult to get a project completed on time, on schedule, and with any degree of accuracy.&amp;nbsp; Collaboration tools typically fall into three categories depending on the levels of collaboration:&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;Communication - An unstructured exchange of information such as email, a phone call, or hallway conversation.&lt;/li&gt;
 &lt;li&gt;Conferencing - Interactive work, such as brainstorming or voting, that leads to a shared goal.&lt;/li&gt;
 &lt;li&gt;Coordination - Complex interdependent work that leads to a combined goal.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Collaboration tools&lt;/h2&gt;

&lt;p&gt;The main shared attribute of tools in the collaboration space is that of helping to facility and manage group activities.&amp;nbsp; From electronic calendars, workflow systems, knowledge management system, social software, and project management systems, there are literally thousands of tools that fall into the category of collaboration.&lt;/p&gt;

&lt;p&gt;Below is a list of some of the vendors in the collaboration space.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.asana.com/"&gt;Asana&lt;/a&gt;&amp;nbsp; - plan and manage projects and tasks.&lt;br /&gt;
&lt;a href="https://basecamp.com/"&gt;Basecamp&lt;/a&gt;&amp;nbsp; - to-do lists, web-based text documents, milestone management, file sharing and time tracking.&lt;br /&gt;
&lt;a href="http://www.brightpod.com/"&gt;Brightpod&lt;/a&gt;&amp;nbsp; - task management, milestone tracking, task lists, file sharing, workflows, calendar, and messaging.&lt;br /&gt;
&lt;a href="http://www.collaboratecloud.com/"&gt;CollaborateCloud&lt;/a&gt;&amp;nbsp; - social work management with workflows, forms, and virtual workrooms.&lt;br /&gt;
&lt;a href="http://www.atlassian.com/software/confluence"&gt;Confluence&lt;/a&gt;&amp;nbsp; - enterprise unified wiki with social network notifications and integration of multimedia files.&lt;br /&gt;
&lt;a href="http://www.deskaway.com/"&gt;DeskAway&lt;/a&gt;&amp;nbsp; - team based project and task management, milestones, documentation, and file sharing.&lt;br /&gt;
&lt;a href="https://github.com/"&gt;Github&lt;/a&gt;&amp;nbsp; - distributed revision control and source code management.&lt;br /&gt;
&lt;a href="http://www.intellinote.net/"&gt;Intellinote&lt;/a&gt;&amp;nbsp; - meeting collaboration, task management, and idea capturing.&lt;br /&gt;
&lt;a href="http://www.jivesoftware.com/products"&gt;Jive&lt;/a&gt;&amp;nbsp; - online communities, micro-blogging, social networking, discussion forums, wikis, and instant messaging.&lt;br /&gt;
&lt;a href="http://www.liquidplanner.com/"&gt;LiquidPlanner&lt;/a&gt;&amp;nbsp; - online project management.&lt;br /&gt;
&lt;a href="http://sharepoint.com/"&gt;SharePoint&lt;/a&gt; - content and document management, personal cloud, social networking, enterprise search, and workflow management.&lt;br /&gt;
&lt;a href="https://trello.com/"&gt;Trello&lt;/a&gt;&amp;nbsp; - project management.&lt;br /&gt;
&lt;a href="http://www.wrike.com/"&gt;Wrike&lt;/a&gt;&amp;nbsp; - project management and work collaboration.&lt;br /&gt;
&lt;a href="http://www.zohocorp.com/"&gt;Zoho&lt;/a&gt; - word processor, spreadsheets, calendar, contacts, and CRM.&lt;/p&gt;
</description>
      <pubDate>Thu, 03 Sep 2015 10:02:48 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/nodejs-abcs-n-is-for-npm</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <title>Node.js ABC’s - N is for npm</title>
      <description>&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/npm.png"&gt;&lt;img align="right" alt="npm" border="0" height="155" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/npm_thumb.png" style="border-width: 0px; margin: 10px; padding-top: 0px; padding-right: 0px; padding-left: 0px; float: right; display: inline; background-image: none;" title="npm" width="155" /&gt;&lt;/a&gt;Whether you are ready to start coding your first Node.js project, or if you are a seasoned veteran and need finish up a new exciting project, odds are you will need some functionality that has been written many times before by others.&amp;nbsp; One of the beauties of the internet is the ability to create and share things.&amp;nbsp; Node.js is a great language set in itself, but one key selling point is the vast amount of code that is available for free download.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.npmjs.com/"&gt;Node Package Manager&lt;/a&gt;, also known as npm, is a software system that automates the process of installing, upgrading, configuring, and removing Node.js packages.&amp;nbsp; As of Node.js version 0.6.3, npm is bundled and installed with the environment so once you have access to the node command line tools, you also have access to the vast number of shared packages available to you.&lt;/p&gt;

&lt;p&gt;As of this writing, there are over 180,000 packages available in the npm.&amp;nbsp; You can find anything from credit card validators, to full language parsers.&amp;nbsp; If you have a task to perform, odds are there is a 3rd party package to help you along.&amp;nbsp; And the best feature I see is that packages are distributed as source script so you have full access to modify or extend the packages you pull from the repository.&lt;/p&gt;

&lt;p&gt;In my article on &lt;a href="https://devcentral.f5.com/articles/nodejs-abcs-l-is-for-loading"&gt;Loading&lt;/a&gt;, I discuss how you use the &amp;quot;require&amp;quot; command to load a module&lt;/p&gt;

&lt;h2&gt;Installing NPM&lt;/h2&gt;

&lt;p&gt;As I mentioned above, npm is included with Node.js versions 0.6.3 and above.&amp;nbsp; If you are using an older version of node, I&amp;#39;ll leave it as an exercise to the reader to find the distribution package.&amp;nbsp; Better yet, I&amp;#39;d suggest upgrading to a more recent version of Node.js!&amp;nbsp;&lt;/p&gt;

&lt;p&gt;npm is itself distributed as a package through npm so you can have npm upgrade itself.&amp;nbsp; npm is updated quite frequently, so it&amp;#39;s a good idea to upgrade npm once in a while&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;$ sudo npm install npm -g&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Installing a package&lt;/h2&gt;

&lt;p&gt;Node.js has the concept of &amp;quot;local&amp;quot; and &amp;quot;global&amp;quot; packages.&amp;nbsp; Local packages are installed as part of your current project and are not available to other projects in your system.&amp;nbsp; Global packages are installed at the system level, so distributions that include command line tools (like npm) that you will want to use &amp;quot;globally&amp;quot;, then you will want to include it in global scope.&lt;/p&gt;

&lt;h3&gt;Local Package Installation&lt;/h3&gt;

&lt;p&gt;To install a package locally, you&amp;#39;ll use the &amp;quot;install&amp;quot; npm sub command.&amp;nbsp; Most often you will just need to specify the package name as an argument.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;$ npm install package-name&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Global Package Installation&lt;/h3&gt;

&lt;p&gt;To install a package globally, you&amp;#39;ll use the &amp;quot;-g&amp;quot; argument.&amp;nbsp; Most often you will need to run this under &amp;quot;sudo&amp;quot; to allow for permissions in system folders.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;$ sudo npm install -g package-name&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Updating Packages&lt;/h2&gt;

&lt;p&gt;Since packages can be installed locally or globally, there is an update procedure for each as well.&amp;nbsp; Local updates are the easiest and can be completed with the &amp;quot;update&amp;quot; npm command.&amp;nbsp; This command will update all the packages in the local installation.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;$npm update&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To update packages globally, you add the &amp;quot;-g&amp;quot; option like you did above.&amp;nbsp;&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;$npm update -g&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But, in some cases you won&amp;#39;t want to update all global packages at once.&amp;nbsp; You can use the &amp;quot;outdated&amp;quot; command to get a listing of global packages that need updating:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;$ npm outdated -g --depth=0&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and then you can update the global package with the same install command you used above&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;$ npm install -g package-name&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Removing Packages&lt;/h2&gt;

&lt;p&gt;If the package you recently downloaded isn&amp;#39;t living up to your expectations, you can use the &amp;quot;uninstall&amp;quot; npm command to remove the package from a local or global installation.&amp;nbsp; For a global installation, use the &amp;quot;-g&amp;quot; option as above&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;$ npm uninstall package-name
$ npm uninstall -g package-name&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Creating Packages&lt;/h2&gt;

&lt;p&gt;In my article on &lt;a href="https://devcentral.f5.com/articles/nodejs-abcs-m-is-for-modules"&gt;Node.js Modules&lt;/a&gt;, I go over in detail the package creation process.&amp;nbsp; I&amp;#39;d suggest you read that article for details on creating your own package.&lt;/p&gt;

&lt;h2&gt;Publishing Packages&lt;/h2&gt;

&lt;p&gt;Once you have a great package put together, you may want to share that with the world.&amp;nbsp; The process for doing so is very easy.&amp;nbsp; You must first have a npm user account.&amp;nbsp; You can create a new user with the &amp;quot;npm adduser&amp;quot; command, or alternately login if you have an existing account with the &amp;quot;npm login&amp;quot; command.&lt;/p&gt;

&lt;p&gt;Once you are authenticated, you can use the &amp;quot;publish&amp;quot; npm command to push your package to the npm repository.&amp;nbsp; use the folder name of your package in the &amp;quot;my-cool-package&amp;quot; parameter below:&amp;nbsp;&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;$npm publish my-cool-package&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Check out the &lt;a href="https://docs.npmjs.com/getting-started"&gt;Getting Started documentation&lt;/a&gt; on the npm website for more information on getting the most out of the Node Package Manager.&lt;/p&gt;
</description>
      <pubDate>Tue, 01 Sep 2015 15:32:18 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/nodejs-abcs-m-is-for-modules</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>node</category>
      <title>Node.js ABC’s - M is for Modules</title>
      <description>&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/npm_logo.png"&gt;&lt;img align="right" alt="npm_logo" border="0" height="94" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/npm_logo_thumb.png" style="border-width: 0px; margin: 10px; padding-top: 0px; padding-right: 0px; padding-left: 0px; float: right; display: inline; background-image: none;" title="npm_logo" width="240" /&gt;&lt;/a&gt;As any one who has created a software system can tell you, after some point you get to a point in time where putting all your code in one big location becomes unmanageable and leads to maintenance issues.&amp;nbsp; The logical first step is to try to separate code that is related into smaller distinct entities and &amp;quot;include&amp;quot; them in the project in question.&amp;nbsp; But, what happens if two included file &amp;quot;A&amp;quot; and file &amp;quot;B&amp;quot; both define a &amp;quot;doSomething()&amp;quot; method?&amp;nbsp; Global Scope is sometimes convenient, but more often a cause for troubles when development and enhancing a product.&lt;/p&gt;

&lt;p&gt;Different languages handle these &amp;quot;namespace&amp;quot; collisions in different ways.&amp;nbsp; Some make them optional, some a bit more strict.&amp;nbsp; Node avoids potential &amp;quot;global scope&amp;quot; issues by not offering an easy way to accidentally over-stuff the global scope.&amp;nbsp; This is done in the form of &amp;quot;Modules&amp;quot;.&lt;/p&gt;

&lt;p&gt;At a high level, modules are just an easy way to group similar code together.&amp;nbsp; Every file in Node.js is considered a module, although modules can be a bit more complex than a single file.&amp;nbsp; Node modules allow you to select which functions and variables that are in the file are exposed to the calling application and, consequently, which ones are private.&lt;/p&gt;

&lt;p&gt;Modules can be packaged and published to an online repository (most likely the &lt;a href="https://www.npmjs.com/"&gt;Node Package Manager&lt;/a&gt; or npm) without those using the modules having to worry about one module conflicting with another in the project.&lt;/p&gt;

&lt;h2&gt;CREATING MODULES&lt;/h2&gt;

&lt;p&gt;For the sake of simplicity, we&amp;#39;ll focus the following examples on a single file module solution.&amp;nbsp; To create a new module, just create a new file with the name of your module as it&amp;#39;s file name.&amp;nbsp; Inside that file,&amp;nbsp; there is a special object calls &amp;quot;exports&amp;quot;.&amp;nbsp; It is with this object, that you specify what you want exposed to the caller.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;/* indexGenerator.js */
var counter = 0;
exports.nextIndex = function() {
  return counter++;
}
exports.reset = function() {
  counter = 0;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In this example module titled &amp;quot;indexGenerator&amp;quot;, I&amp;#39;ve exposed the following functions:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&amp;quot;nextIndex&amp;quot; that will return the next 0-based index in the set.&lt;/li&gt;
 &lt;li&gt;&amp;quot;reset&amp;quot; that will reset the index to 0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That&amp;#39;s it, you&amp;#39;ve created your first module!&amp;nbsp; The next step is to figure out how to load it and get access to it&amp;#39;s functionality.&amp;nbsp; That is done with the &amp;quot;require&amp;quot; command.&amp;nbsp; I went into this in detail in my &amp;quot;&lt;a href="https://devcentral.f5.com/articles/nodejs-abcs-l-is-for-loading"&gt;L is for Loading&lt;/a&gt;&amp;quot; article.&amp;nbsp; I&amp;#39;ll point you to that article on the ins and outs of loading a module.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;/* test.js */
var generator = require(&amp;quot;./indexGenerator.js&amp;quot;);
console.log(&amp;quot;INDEX: &amp;quot; + generator.nextIndex() + &amp;quot;\n&amp;quot;);
console.log(&amp;quot;INDEX: &amp;quot; + generator.nextIndex() + &amp;quot;\n&amp;quot;);
console.log(&amp;quot;resetting index\n&amp;quot;);
generator.reset();
console.log(&amp;quot;INDEX: &amp;quot; + generator.nextIndex() + &amp;quot;\n&amp;quot;);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;will produce the following output&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;INDEX: 0
INDEX: 1
resetting index
INDEX: 0&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;MODULE PATTERNS&lt;/h2&gt;

&lt;p&gt;The above example illustrates how to return a set of independent functions from a module.&amp;nbsp; More often then not, you will want to package your functions into an object and return that to the caller. There are several methods for returning objects from modules: The Factory and The Constructor models&lt;/p&gt;

&lt;h3&gt;The Factory Model&lt;/h3&gt;

&lt;p&gt;With the factory module, a creation function is returned in the &amp;quot;exports&amp;quot; object that, when called, will create a new instance of the object in question.&amp;nbsp; The following code illustrates this:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;/* hello.js */
function helloObject() {
  this.sayHi = function() { return &amp;quot;Hi&amp;quot;; }
  this.sayHowdy = function() { return &amp;quot;Howdy&amp;quot;; }
}
exports.createHello = function() {
  return new helloObject();
}&lt;/code&gt;&lt;/pre&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;/* test.js */
var helloFactory = require(&amp;quot;./hello.js&amp;quot;);
var helloObj = helloFactory.createHello();
console.log(&amp;quot;HI: &amp;quot; + helloObj.sayHi());&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The benefit of this approach is that you can expose many numbers of factories by adding each of them to the exports object along with all other variables and exported standalone functions.&lt;/p&gt;

&lt;h3&gt;The Constructor Model&lt;/h3&gt;

&lt;p&gt;Another way to return an object from a module is to override the exports object with the new object in question.&amp;nbsp; With this approach, you can only return a single item (in this case an object) from your module.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;/* hello.js */
function helloObject() {
  this.sayHi = function() { return &amp;quot;Hi&amp;quot;; }
  this.sayHowdy = function() { return &amp;quot;Howdy&amp;quot;; }
}
module.exports = helloObject;&lt;/code&gt;&lt;/pre&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;/* test.js */
var helloClass = require(&amp;quot;./hello.js&amp;quot;);
var helloObject = new helloClass();
console.log(&amp;quot;HI: &amp;quot; + helloObj.sayHi());&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;MODULE FOLDER FORMAT&lt;/h2&gt;

&lt;p&gt;As I mentioned above, modules can be more than just a file.&amp;nbsp; You can create a folder structure which contains meta-data, version information, and the module implementation and test files.&lt;/p&gt;

&lt;p&gt;/my-module&lt;br /&gt;
&amp;nbsp; /package.json&lt;br /&gt;
&amp;nbsp; /lib&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /module_impl.js&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /file2.js&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/p&gt;

&lt;p&gt;package.json&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; &amp;quot;name&amp;quot;: &amp;quot;my-module&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;quot;version&amp;quot;: &amp;quot;1.0.0&amp;quot;,&lt;br /&gt;
&amp;nbsp; &amp;quot;main&amp;quot;: &amp;quot;./lib/module_impl.js&amp;quot;&lt;br /&gt;
}&lt;/p&gt;

&lt;p&gt;More information on the Folder Module and the loader rules can be found in my article on &lt;a href="https://devcentral.f5.com/articles/nodejs-abcs-l-is-for-loading"&gt;Node.js Loading&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;PUBLISHING&lt;/h2&gt;

&lt;p&gt;So you&amp;#39;ve written a pretty awesome index generator module and you want to share it with the rest of the world.&amp;nbsp; The Node Package Manager makes it really simple to do so:&lt;br /&gt;
- The first step is to thoroughly test out your module.&lt;br /&gt;
- Ensure your package.json file has all the info you want to include (help can be found with the &amp;quot;npm help json&amp;quot; command).&lt;br /&gt;
- Create an account in the npm registry servers with the &amp;quot;npm adduser&amp;quot; command.&lt;br /&gt;
- run &amp;quot;npm publish&amp;quot; from within the module directory.&lt;/p&gt;

&lt;p&gt;Pretty simple isn&amp;#39;t it!&amp;nbsp; If you need to manage your package within the repository, you can do so with the &amp;quot;npm unpublish&amp;quot; command.&lt;/p&gt;

&lt;p&gt;For more information on Node.js modules, check out the &lt;a href="https://nodejs.org/api/modules.html"&gt;Modules section of the Node.js API reference&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Mon, 24 Aug 2015 14:11:54 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/nodejs-abcs-l-is-for-loading</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>node</category>
      <title>Node.js ABC’s - L is for Loading</title>
      <description>&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/LoadingDockEquipment.jpg"&gt;&lt;img title="LoadingDockEquipment" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 10px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="LoadingDockEquipment" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/LoadingDockEquipment_thumb.jpg" width="244" align="right" height="184"&gt;&lt;/a&gt;One of the great benefits of utilizing a language like Node.js is the wide assortment of 3rd party modules that are at your disposal.  From calculating the validity of credit card numbers, to managing network connections, the Node Package Manager (npm) repository has hundreds of thousands of packages available to you.  This article will explain how you can load modules into your project.&lt;/p&gt; &lt;h2&gt;Loading and Referencing a Module&lt;/h2&gt; &lt;p&gt;In Node.js, modules are accessed either by their name or the file path on the system.  Non-system modules referenced by name will eventually be mapped into a file system path.&lt;/p&gt; &lt;p&gt;Each module exposes a public interface that can be used after the module is imported with the "require" into the current script.&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;var mod = require("some_module_name");&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The previous command will import and return an object that represents the external API exposed by the module.  The value of that object is dependent on the module and can include an object, an array, a function, or any other type of JavaScript object.&lt;/p&gt;
&lt;h2&gt;Developing and Exporting Modules&lt;/h2&gt;
&lt;p&gt;For the module developer, you must use the &lt;a href="https://en.wikipedia.org/wiki/CommonJS"&gt;CommonJS Module System&lt;/a&gt; to make your modules available to the outside world.  Let's create a sample module “person.js” that exports a Person constructor.&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;/* File person.js */
function Person(name) {
  var _name = name;
  function name() {
    return _name;
  }
}
module.exports = Person;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above example, the Person function is defined and then specified with the "module.exports" object that the module will export to other scripts that require this module.&lt;/p&gt;
&lt;p&gt;As mentioned above, more complex objects can be exported by adding onto the module.exports object with whatever values you deem fit for your module.&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;/* file mymodule.js */
function sayHi() { console.log("HI!!!"); }
function sayBye() { console.log("BYE!!!"); }
module.exports.sayHi = sayHi;
module.exports.sayBye = sayBye;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Below is the code to load the module and call the sayHi and sayBye functions.&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;var mymodule = require("./mymodule");
mymodule.sayHi();
HI!!!
mymodule.sayBye();
BYE!!!&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Loading a Module&lt;/h2&gt;
&lt;p&gt;There are a couple of ways to reference modules depending on their kind.  There are core modules, 3rd party modules, or local modules.&lt;/p&gt;
&lt;h3&gt;Core Modules&lt;/h3&gt;
&lt;p&gt;Since core modules are part of the distribution, you need only refer to it by it's name (not the path).  Core modules with name collisions to local modules take precedence.  The following line will load a instance of the core "http" module.&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;var http = require('http');&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;File Module&lt;/h3&gt;
&lt;p&gt;A file module is a one that is defined in a single file on the file system.  The person.js example above is an example of a file module.  When loading a file module, you supply a path (full or relative) to the module file, optionally omitting the .js extension.&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;var mymodule = require("/home/joe/node/modules/mymodule");
var mymodule = require("./mymodule");&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In those examples the loader will look for a file named "mymodule.js" in the specified directory.&lt;/p&gt;
&lt;h3&gt;Folder Modules&lt;/h3&gt;
&lt;p&gt;Like a file module, when loading a folder module, you specify the absolute or relative location of the folder.  The Node loader will assume this folder is a package and attempt to look for a package definition file (package.json) in which the name and location of the module file are located.  If no package.json file exists, the Node loader will look for a file named index.js.&lt;/p&gt;
&lt;h2&gt;Loader search procedure&lt;/h2&gt;
&lt;p&gt;If the module name is not a path and is not a core module, the loader will attempt to find it inside the special "node_modules" folder.  If the module doesn't exist there, it will continue up the path, folder by folder, looking within node_modules folders on those directories until either finds the module or hits the root of the file system.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;That's about all there is to it for exporting and loading a Node.js module.  Creating modules is as easy as writing the module code and specifying what is returned with the module.exports object.  Then a simple call to require("module") is all the client has to write to make use of it.&lt;/p&gt;</description>
      <pubDate>Mon, 03 Aug 2015 14:50:02 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/devops-101-communication</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>devops</category>
      <category>management</category>
      <title>DevOps 101 - Communication</title>
      <description>&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/Communication.png"&gt;&lt;img title="Communication" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 10px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="Communication" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/Communication_thumb.png" width="188" align="right" height="244"&gt;&lt;/a&gt;In my previous article on the history of DevOps, I outlined the following pillars of the DevOps methodology&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/devops-101-management"&gt;Management&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/devops-101-integration"&gt;Integration&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Communication and information sharing&lt;/li&gt; &lt;li&gt;Collaboration&lt;/li&gt; &lt;li&gt;Automation&lt;/li&gt; &lt;li&gt;Measurement&lt;/li&gt;&lt;/ul&gt; &lt;h2&gt;The Third Pillar&lt;/h2&gt; &lt;p&gt;The third pillar in the DevOps stack is Communication (and Information Sharing).  Back when DevOps was Development and Operations, the two teams were typically separated by both priorities, organization, and most often geographic locations.  These separations led to many issues, one of the biggest being communication.&lt;/p&gt; &lt;h2&gt;The Development Silo&lt;/h2&gt; &lt;p&gt;As I mentioned in my article on &lt;a href="https://devcentral.f5.com/articles/devops-101-a-brief-history-of-time"&gt;DevOps History&lt;/a&gt; application releases used to be very spread out over long periods of time with a lot of changes and features.  The application team lived in a silo in that they built the application, tested it and then tossed it over the wall to the operations team to handle security testing and ultimately deployment to production environments.  Communication consisted of change order tickets that sat in a queue for weeks while operations could fit it into their queue of work.  And, when they were able to get to it, if any issue arose, it was sent back to the development team to fix and resubmit.&lt;/p&gt; &lt;p&gt;With the advent of Agile programming where the development teams worked on more frequent point releases, the "change order" process began to feel like the "&lt;a href="https://en.wikipedia.org/wiki/TPS_report"&gt;TPS report&lt;/a&gt;" in Office Space.  A new agile method of deployment was needed as "tickets" became a hindrance and wasted a lot of time for both sides of the Dev+Ops fence.  Communication and Information Sharing became a critical aspect in moving to a more agile deployment cycle.&lt;/p&gt; &lt;h2&gt;Communication Tools&lt;/h2&gt; &lt;p&gt;Each organization has it's own set of tools for allowing teams to communicate.  The trick was getting these included in the application deployment lifecycle.  Some popular tools include&lt;/p&gt; &lt;p&gt;Email solutions including Exchange, Gmail, Yahoo, Hotmail/Office 365, and others.&lt;br&gt;Instant Messenger and chat applications such as Lync, &lt;a href="http://skype.com"&gt;Skype&lt;/a&gt;, &lt;a href="http://slack.com"&gt;Slack&lt;/a&gt;, &lt;a href="http://plus.google.com/hangouts"&gt;Google Hangouts&lt;/a&gt; , and IRC systems.&lt;br&gt;Content management and social systems such as &lt;a href="http://www.jivesoftware.com"&gt;Jive&lt;/a&gt; and &lt;a href="http://www.lithium.com"&gt;Lithium&lt;/a&gt;.&lt;br&gt;Task based systems such as &lt;a href="http://www.asana.com"&gt;Asana&lt;/a&gt;, &lt;a href="http://basecamp.com"&gt;Basecamp&lt;/a&gt;, and &lt;a href="http://trello.com"&gt;Trello&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;As the "Dev" gets closer to "Ops" in departmental and procedural areas, communication becomes a bit easier but is still critical to act as the connective tissue keeping DevOps together.&lt;/p&gt;</description>
      <pubDate>Thu, 30 Jul 2015 09:03:34 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/nodejs-abcs-k-is-for-koa</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>deployment</category>
      <category>devops</category>
      <category>node</category>
      <title>Node.js ABC’s - K is for Koa</title>
      <description>&lt;p&gt;Node.js is an open source runtime environment for server-side and network based applications.&amp;nbsp; Node.js contains all the components needed to build a functioning website.&amp;nbsp; But, you need to think of Node.js as a big tool box.&amp;nbsp; As with any other art form, going to the tool box over and over to perform the same task is not productive.&amp;nbsp; The concept of tool reuse is used in all forms of artistry and development is no exception.&lt;/p&gt;

&lt;h2&gt;What is a Web Framework&lt;/h2&gt;

&lt;p&gt;In general, frameworks are code libraries that are created to save people a lot of time and unnecessary work for repetitive tasks.&amp;nbsp; A framework is a universal environment that has several key features that distinguish it from a regular library:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;Inversion of control - The control flow of the application is dictated by the framework, not the code using the framework.&lt;/li&gt;
 &lt;li&gt;Default behavior - Provide a default set of behaviors yielding a consistent outcomes.&lt;/li&gt;
 &lt;li&gt;Extensibility - Provides a layer of extensibility where the user can selectively override the default behaviors of the framework.&lt;/li&gt;
 &lt;li&gt;A non-modifiable framework - The core framework software is not intended to be modified.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Frameworks can allow you to create a server in just a few lines of code and make creating a REST API very simple.&lt;/p&gt;

&lt;h2&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/KoaTree.jpg"&gt;&lt;img align="right" alt="KoaTree" border="0" height="244" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/KoaTree_thumb.jpg" style="border-width: 0px; margin: 10px; padding-top: 0px; padding-right: 0px; padding-left: 0px; float: right; display: inline; background-image: none;" title="KoaTree" width="190" /&gt;&lt;/a&gt;Koa&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://koajs.com"&gt;Koa&lt;/a&gt; is a web framework that is being worked on by the team that wrote the Express Node.js framework.&amp;nbsp; Koa differentiates itself by not using any middleware within the core of the framework.&amp;nbsp; From Koa&amp;#39;s website&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Koa is a new web framework designed by the team behind Express, which aims to be a smaller, more expressive, and more robust foundation for web applications and APIs. Through leveraging generators Koa allows you to ditch callbacks and greatly increase error-handling. Koa does not bundle any middleware within core, and provides an elegant suite of methods that make writing servers fast and enjoyable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When building an application on top of Koa, you are creating generator functions that are composed and executed upon request.&amp;nbsp; Koa is similar to other middleware systems like Rack for Ruby.&lt;/p&gt;

&lt;h2&gt;Koa Hello World&lt;/h2&gt;

&lt;p&gt;It can&amp;#39;t finish up talking about a framework without presenting the obligatory &amp;quot;Hello World&amp;quot; example.&amp;nbsp; So, here it is in Koa:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;var koa = require(&amp;#39;koa&amp;#39;);
var application = koa();

application.use(function *() {
  this.body = &amp;quot;Hello world!!!&amp;quot;
});

var server = application.listen(8080, function() {
  console.log(&amp;quot;Koa is listening on http://localhost:8080&amp;quot;);
});&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;Koa is a fairly small set of code so it does not cause unnecessary bloat to your application.&amp;nbsp; It is basically a bare-boned framework where the developer can decide on the middleware they want to run instead of relying on that of the framework.&amp;nbsp; The current state of Koa right now is that it&amp;#39;s pretty early on in development so if you decide to investigate it, I&amp;#39;d avoid being bleeding edge and stick with the latest stable release.&lt;/p&gt;

&lt;h2&gt;Other Popular frameworks&lt;/h2&gt;

&lt;p&gt;The benefit of the open source community is that there are always alternatives to choose from.&amp;nbsp; Here is a list of some of the more popular Node.js frameworks out there:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;Express - &lt;a href="http://expressjs.com/"&gt;http://expressjs.com/&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;Locomotive- &lt;a href="http://locomotivejs.org/"&gt;http://locomotivejs.org/&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;Total.js - &lt;a href="http://www.totaljs.com/"&gt;http://www.totaljs.com/&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;Derby - &lt;a href="http://derbyjs.com/"&gt;http://derbyjs.com/&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;Meteor - &lt;a href="https://www.meteor.com/"&gt;https://www.meteor.com/&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;Mojito - &lt;a href="https://developer.yahoo.com/cocktails/mojito/"&gt;https://developer.yahoo.com/cocktails/mojito/&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;Nombo - &lt;a href="http://nombo.io/"&gt;http://nombo.io/&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;Restify - &lt;a href="http://mcavage.me/node-restify/"&gt;http://mcavage.me/node-restify/&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;Loopback - &lt;a href="http://strongloop.com/mobile-application-development/loopback/#automatically-generate-apis-to-data-models"&gt;http://strongloop.com/mobile-application-development/loopback/#automatically-generate-apis-to-data-models&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;ActionHero - &lt;a href="http://www.actionherojs.com/"&gt;http://www.actionherojs.com/&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;Frisby - &lt;a href="http://frisbyjs.com/"&gt;http://frisbyjs.com/&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;DocPad - &lt;a href="http://docpad.org/"&gt;http://docpad.org/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
      <pubDate>Mon, 20 Jul 2015 13:35:00 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/devops-101-integration</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>devops</category>
      <category>management</category>
      <title>DevOps 101 - Integration</title>
      <description>&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/DevOps-Integration.png"&gt;&lt;img title="DevOps-Integration" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 10px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="DevOps-Integration" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/DevOps-Integration_thumb.png" width="188" align="right" height="244"&gt;&lt;/a&gt;In my previous articles on the history of DevOps, I’ve outlined the following pillars of the DevOps methodology&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/devops-101-management"&gt;Management&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Integration&lt;/li&gt; &lt;li&gt;Communication and information sharing&lt;/li&gt; &lt;li&gt;Collaboration&lt;/li&gt; &lt;li&gt;Automation&lt;/li&gt; &lt;li&gt;Measurement&lt;/li&gt;&lt;/ul&gt; &lt;h2&gt;The Second Pillar&lt;/h2&gt; &lt;p&gt;The second pillar in the DevOps stack is that of Integration.  DevOps integration targets quality testing, feature development, and product delivery.  Integration, or more specifically, Systems Integration is the process of linking together different computing or component systems and software applications physically or functionally to perform as a single consolidated unit.&lt;/p&gt; &lt;p&gt;Systems integration requires a wide skill set in areas such as network architecture, protocols, systems, software engineering, documentation and communication.  A DevOps Engineer needs to have a unique skill set that combines that of both the traditional software developer with that of the IT engineer.  Typically DevOps engineers are either developers who get interested in the deployment process of their applications or system administrators who have a passion for scripting and software development.&lt;/p&gt; &lt;h2&gt;The Methods of Systems Integration&lt;/h2&gt; &lt;p&gt;System integration traditionally falls into three methods.  Vertical, Star, and Horizontal (or Enterprise Service Bus).&lt;/p&gt; &lt;h3&gt;Vertical Integration&lt;/h3&gt; &lt;p&gt;Vertical integration involves integrating systems according to their functionality by creating functional components referred to as silos.  One of the key benefits of this method is performed quickly and typically is cheaper in the shorter term.  But, a negative to this methods is that the cost of ownership is often higher and scaling the system would likely require implementing another silo.  Also subsystem reuse for new functionality is often not possible.&lt;/p&gt; &lt;h3&gt;Star Integration&lt;/h3&gt; &lt;p&gt;Star (or Spaghetti) Integration is the method of integration where multiple systems are interconnected to each other (like a plate of spaghetti).  The cost varies depending on the types of interfaces the system use.  Costs and time are greatly increased when adding additional systems.  This method is very flexible and provides high levels of reuse.&lt;/p&gt; &lt;h3&gt;Horizontal Integration&lt;/h3&gt; &lt;p&gt;Horizontal Integration (or Enterprise Service Bus) is a method where a dedicated system is used to communicate to other subsystems.  This allows for only one connection per subsystem to the service bus and the ESB translates the interface to a different system.  With this method, it is designed to allow for you to replace one subsystem with another easily by updating the ESB with the new systems interface.&lt;/p&gt; &lt;h2&gt;Conclusion&lt;/h2&gt; &lt;p&gt;Integration is just one piece of the DevOps puzzle.  In my next article I’ll discuss how communication is integral in the DevOps process.&lt;/p&gt;</description>
      <pubDate>Thu, 02 Jul 2015 10:52:56 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/nodejs-abcs-j-is-for-javascript</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>development</category>
      <category>devops</category>
      <category>node</category>
      <title>Node.js ABC’s - J is for JavaScript</title>
      <description>&lt;p&gt;Node.js is an open source runtime environment for server-side and network based applications.&amp;nbsp; At it&amp;#39;s core, Node.js uses the Google V8 JavaScript engine to execute client code and a large portion of the core basic modules are written in JavaScript.&amp;nbsp; Since, for all practical purposes, writing Node.js applications is writing JavaScript applications, it makes sense to try to understand the gist of what JavaScript is.&lt;/p&gt;

&lt;h2&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/js.jpg"&gt;&lt;img align="right" alt="js" border="0" height="331" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/js_thumb.jpg" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: right; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" title="js" width="278" /&gt;&lt;/a&gt;What is JavaScript&lt;/h2&gt;

&lt;p&gt;JavaScript is primarily a client-based dynamic scripting language most commonly used within web browsers as client-side scripts to interact with the user, browser, and communicate asynchronously to servers.&lt;/p&gt;

&lt;p&gt;If you have been part of any web-based development, odds are you have worked with JavaScript in one form or another.&amp;nbsp; In this article, I&amp;#39;ll focus on the aspects of JavaScript that are relevant within the Node.js environment.&lt;/p&gt;

&lt;h3&gt;Types&lt;/h3&gt;

&lt;p&gt;Node.js has only a few core object types including &lt;strong&gt;boolean&lt;/strong&gt;, &lt;strong&gt;number&lt;/strong&gt;, &lt;strong&gt;object&lt;/strong&gt;, and &lt;strong&gt;string&lt;/strong&gt;.&amp;nbsp; There are three complex types consisting of the &lt;strong&gt;array&lt;/strong&gt;, &lt;strong&gt;function&lt;/strong&gt;, and &lt;strong&gt;object&lt;/strong&gt;.&amp;nbsp; And, finally, &lt;strong&gt;null&lt;/strong&gt; and &lt;strong&gt;undefined&lt;/strong&gt; are special objects that are treated in their own way.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;&amp;gt; typeof 10;
&amp;#39;number&amp;#39;
&amp;gt; typeof &amp;quot;HI&amp;quot;;
&amp;#39;string&amp;#39;
&amp;gt; typeof function() { }
&amp;#39;function&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Constants&lt;/h3&gt;

&lt;p&gt;While Node.js does support the &lt;em&gt;const&lt;/em&gt; keyword, is it not widely used.&amp;nbsp; A standard practice is to use all upperscore characters when defining a constant.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;&amp;gt; var HOURS_PER_DAY = 24;&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Numbers&lt;/h3&gt;

&lt;p&gt;All numbers in JavaScript are 64-bit 754 double-precision floating-point numbers.&amp;nbsp; For numbers that can be expressed in 2&amp;amp;53 bits, their type behaves much like an integer in any other language.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;&amp;gt; 100
100
&amp;gt; 1/3
0.3333333333333333&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are functions that can help you convert strings to numbers&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;&amp;gt; parseInt(&amp;quot;12345&amp;quot;)
12345
&amp;gt; parseFloat(&amp;quot;1.2345&amp;quot;)
1.2345
&amp;gt; parseInt(&amp;quot;1.2345&amp;quot;)
1&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Booleans&lt;/h3&gt;

&lt;p&gt;The boolean type can have values of &lt;em&gt;true&lt;/em&gt; or &lt;em&gt;false&lt;/em&gt;.&amp;nbsp; false, 0, empty strings, NaN, null, and undefined all evaluate to false and all other values evaluate to true.&lt;/p&gt;

&lt;h3&gt;Strings&lt;/h3&gt;

&lt;p&gt;Strings are sequences of Unicode characters that can be wrapped in single or double quote characters. The string type has built-in properties such as &amp;quot;length&amp;quot; to give you access to attributes about the string&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;&amp;gt; var s = &amp;quot;hi there&amp;quot;
&amp;gt; s
&amp;#39;hi there&amp;#39;
&amp;gt; s.length
8&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Objects&lt;/h3&gt;

&lt;p&gt;JavaScript resolves around objects and are something you will use in virtually any JavaScript-based coding effort.&amp;nbsp; They are extensible allowing you to add and remove properties and methods.&amp;nbsp; To create an Object, you can use the new keyword or use the preferred object literal syntax&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;&amp;gt; var o = new Object();
undefined
&amp;gt; var o = {};
undefined&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;One of the benefits of Object-Literal syntax is that you can specify the contents of an object at initialization time&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;&amp;gt; var person = {
  first_name: &amp;quot;Joe&amp;quot;,
  last_name: &amp;quot;Pruitt&amp;quot;
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can also add a new property to an object like this&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;&amp;gt; person.weight = 180;
180
&amp;gt; person[&amp;#39;weight&amp;#39;] = 180;
180
&amp;gt; user
{ first_name: &amp;#39;Joe&amp;#39;,
  last_name: &amp;#39;Pruitt&amp;#39;,
  weight: 180 }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To delete an object or property, you can use the keyword:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;&amp;gt; delete user.weight
true
&amp;gt; user
{ first_name: &amp;#39;Joe&amp;#39;,
  last_name: &amp;#39;Pruitt&amp;#39; }&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Arrays&lt;/h3&gt;

&lt;p&gt;The &lt;em&gt;array&lt;/em&gt; type is a special implementation of the &lt;em&gt;object&lt;/em&gt; type.&amp;nbsp; To create arrays, you can use the traditional notation, or the array-literal syntax&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;&amp;gt; var a1 = new Array();
undefined
&amp;gt; a1
[]
&amp;gt; var a2 = [];
undefined
&amp;gt; a2
[]&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To add an item to an array, you can do one of the following&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;&amp;gt; var a = []
undefined
&amp;gt; a.push(&amp;quot;hi&amp;quot;)
1
&amp;gt; a
[ &amp;#39;hi&amp;#39; ]
&amp;gt; a[a.length] = &amp;quot;there&amp;quot;;
&amp;#39;there&amp;#39;
&amp;gt; a
[ &amp;#39;hi&amp;#39;, &amp;#39;there&amp;#39; ]&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Functions&lt;/h3&gt;

&lt;p&gt;JavaScript is a functional programming language in that functions are fully typed objects and can be extended, manipulated, and used as data.&lt;/p&gt;

&lt;p&gt;A simple function is defined with the &lt;em&gt;function&lt;/em&gt; keyword&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;&amp;gt; function hi(name) {
  console.log(&amp;quot;Hey &amp;quot; + name + &amp;quot;!&amp;quot;);
}
&amp;gt; hi(&amp;quot;Joe&amp;quot;);
Hey Joe!&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Parameters are declared in the parameter list after the function name.&amp;nbsp; If too few parameters are passed in, the missing ones will be undefined.&amp;nbsp; If too many parameters are passed in, then the extras are ignored.&lt;/p&gt;

&lt;p&gt;You can create an anonymous function without a name by using the following syntax&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;&amp;gt; var hi = function(name) {
  console.log(&amp;quot;Hey &amp;quot; + name + &amp;quot;!&amp;quot;);
}
&amp;gt; hi(&amp;quot;Joe&amp;quot;);
Hey Joe!&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It is recommended to use named functions whenever possible as debugging becomes more difficult without a named context in exception chains.&lt;/p&gt;

&lt;h3&gt;Special Global Objects&lt;/h3&gt;

&lt;p&gt;Node.js has a couple of global variables that can come in handy.&amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;strong&gt;console&lt;/strong&gt; - The &lt;strong&gt;console&lt;/strong&gt; object contains the well known &lt;strong&gt;log&lt;/strong&gt; function as well as &lt;strong&gt;warn&lt;/strong&gt;, &lt;strong&gt;time&lt;/strong&gt;, &lt;strong&gt;timeEnd&lt;/strong&gt;, and &lt;strong&gt;assert&lt;/strong&gt;.&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;global&lt;/strong&gt; - Similar to how a browser&amp;#39;s JavaScript model has the &lt;em&gt;window&lt;/em&gt; object which is global in scope, Node.js has the special &lt;strong&gt;global&lt;/strong&gt; object.&amp;nbsp; Anything attached to it is available anywhere in your node application.&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;process&lt;/strong&gt; - The &lt;strong&gt;process&lt;/strong&gt; global variable contains information and methods about the current&amp;#39;s environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;It&amp;#39;s beyond the scope of this article to get into all of the aspects of the JavaScript programming language.&amp;nbsp; For more details into the concepts I&amp;#39;ve covered, as well as others in the language, check out the JavaScript reference on w3schools.com - &lt;a href="http://www.w3schools.com/jsref/default.asp"&gt;http://www.w3schools.com/jsref/default.asp&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Mon, 29 Jun 2015 09:24:00 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/nodejs-abcs-i-is-for-inheritance</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>deployment</category>
      <category>devops</category>
      <category>node</category>
      <title>Node.js ABC’s - I is for Inheritance</title>
      <description>&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/Inheritance.jpg"&gt;&lt;img align="right" alt="Inheritance" border="0" height="182" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/Inheritance_thumb.jpg" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 10px; border-left: 0px; display: inline; padding-right: 0px" title="Inheritance" width="242" /&gt;&lt;/a&gt;The ability to create a class and then extend it is the basis for object-oriented programming.&amp;nbsp; Inheritance in object-oriented programming is when an object, or class, is derived from another object using the same core implementation.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Inheritance in JavaScript is a little different than other languages as there is no explicit class keyword and a mechanism for specify a derived relationship.&amp;nbsp; In JavaScript classes are all declared as functions as in this example&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;function MyStuff(myThings) {
  this.things = myThings;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the above example, the function MyStuff is a way to hold onto a bunch of things.&amp;nbsp; the things property is used to store the value of myThings which is passed in through the constructor.&lt;/p&gt;

&lt;h2&gt;Prototypes&lt;/h2&gt;

&lt;p&gt;Since there is no explict &amp;quot;class&amp;quot; keyword to declare class and inheritance, all objects (functions) in JavaScript have a special &amp;quot;prototype&amp;quot; property, which is used to add methods and properties available to instances of that function.&lt;/p&gt;

&lt;p&gt;If one wanted to add on a method to print the contents of the MyStuff object, you could do so like this&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;MyStuff.prototype.print = function() {
  console.log(this.things);
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you can create a new object and access the print method like this&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;var coolStuff = new MyStuff(&amp;quot;Lots of cool things here&amp;quot;);
coolStuff.print();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The above showed the use of the prototype &amp;quot;property&amp;quot;.&amp;nbsp; The second aspect of prototypes in JavaScript is the prototype &amp;quot;attribute&amp;quot;.&amp;nbsp; The prototype attribute, also commonly referred to as the &amp;quot;prototype object&amp;quot;, points to the objects &amp;quot;parent&amp;quot; that the object inherited it&amp;#39;s properties and methods from.&amp;nbsp; The prototype attribute is set automatically when you create a new object.&lt;/p&gt;

&lt;p&gt;In the above example, the coolStuff&amp;#39;s prototype attribute is MyStuff.prototype.&amp;nbsp; All objects created with the Object constructor, inherit from Object.prototype.&lt;/p&gt;

&lt;h2&gt;Inheritance&lt;/h2&gt;

&lt;p&gt;All JavaScript objects inherit the methods and properties of their prototypes.&amp;nbsp; In the following example, I&amp;#39;ll create a Pet object and then a Dog object that derives from Pet by using the parent constructor.&amp;nbsp;&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;var Pet = function() {
}
// Add a &amp;quot;feed&amp;quot; method to Pet.prototype
Pet.prototype.feed = function() {
  console.log(&amp;quot;The pet has been fed.&amp;quot;);
}
// Define a Dog constructor
function Dog() {
  // Call the parent constructor, making sure that &amp;quot;this&amp;quot; is set correctly
  Pet.call(this);
}
Dog.prototype = Object.create(Pet.prototype);
Dog.prototype.constructor = Pet;
// Add a sleep method
Dog.prototype.sleep = function() {
  console.log(&amp;quot;The dog is sleeping...&amp;quot;);
}
var pet = new Pet();
var dog = new Dog();
// Call Pet&amp;#39;s feed method
pet.feed();
// Call Dog&amp;#39;s feed method 
dog.feed();
// Call Dog&amp;#39;s sleep method
dog.sleep();
console.log(dog instanceof Pet);

$ node inheritance.js
The pet has been fed.
The pet has been fed.
The dog is sleeping...
true&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Since every object has a prototype, one can chain objects upon objects to create a hierarchy chain.&lt;/p&gt;
</description>
      <pubDate>Fri, 26 Jun 2015 11:51:00 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/nodejs-abcs-g-is-for-globals</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>development</category>
      <category>devops</category>
      <category>node</category>
      <title>Node.js ABC’s - G is for Globals</title>
      <description>&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/variableGlobal.png"&gt;&lt;img align="right" alt="variableGlobal" border="0" height="139" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/variableGlobal_thumb.png" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 10px; border-left: 0px; display: inline; padding-right: 0px" title="variableGlobal" width="244" /&gt;&lt;/a&gt;A variable is a storage location paired with an associated name, which contains the information known as a value.&amp;nbsp; Nearly every programming language under the sun supports variables in some form or another.&lt;/p&gt;

&lt;p&gt;Within the context of a single piece of code, the use of variables are straight forward: Store a value, retrieve a value, use the value.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;var sum = 1 + 2;
console.log(&amp;quot;The sum is &amp;quot; + sum);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The concept is nice and tidy within the context of a single code segment.&amp;nbsp; But not many software programs are a limited to a single instance.&amp;nbsp; With object oriented and modular programming where code logic is broken into smaller segments to enable code reuse and inheritance, sharing variables can be cumbersome.&lt;/p&gt;

&lt;h2&gt;Variable Scope&lt;/h2&gt;

&lt;p&gt;The concept of where variables are available and accessible is referred to as the variables context, or scope.&amp;nbsp; When you declare a variable, the section of code it is included in is referred to as local scope.&amp;nbsp; If you want to share a variable with different contexts (local scopes), you will need to use a global variable that lives within global scope.&amp;nbsp; Different languages use different constructs to get at global variables.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Javascript will first look for a local scoped variable and if not found look for a global scoped one and use that.&amp;nbsp; The following example shows a global &amp;quot;sum&amp;quot; with various functions taking in as parameters,&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;var sum = 3;
console.log(&amp;quot;SUM 1: &amp;quot; + sum);
function printSum2() {
  var sum = 5;
  console.log(&amp;quot;SUM 2: &amp;quot; + sum);
}
printSum2();
console.log(&amp;quot;SUM 2.5: &amp;quot; + sum);
function printSum3(sum) {
  sum = 6;
  console.log(&amp;quot;SUM 3: &amp;quot; + sum);
}
printSum3(sum);
console.log(&amp;quot;SUM 3.5: &amp;quot; + sum);
function printSum4(sum) {
  var sum = 7;
  console.log(&amp;quot;SUM 4: &amp;quot; + sum);
}
printSum4(sum);
console.log(&amp;quot;SUM 4.5: &amp;quot; + sum);

function printSum5() {
  sum = 9;
  console.log(&amp;quot;SUM 5: &amp;quot; + sum);
}
printSum5();
console.log(&amp;quot;SUM 5.5: &amp;quot; + sum);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Will result in the following output:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;SUM 1  : 3
SUM 2  : 5
SUM 2.5: 3
SUM 3  : 6
SUM 3.5: 3
SUM 4  : 7
SUM 4.5: 3
SUM 5  : 9
SUM 5.5: 9
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A problem arises when you have a local variable and a global variable with the same name and you wish to control which variable you are accessing.&amp;nbsp; Node.js has a solution for this with the &amp;quot;global&amp;quot; object.&lt;/p&gt;

&lt;h2&gt;The Global Object&lt;/h2&gt;

&lt;p&gt;Just as JavaScript in web browsers has the &amp;quot;window&amp;quot; object that is accessible to all code contexts as a global object, Node has a similar global-level object but is aptly named &amp;quot;global&amp;quot;.&amp;nbsp;&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;global.sum = 3;
function printSum() {
  var sum = 5;
  console.log("Local Sum: " + sum);
  console.log("Global Sum: " + global.sum);
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;Local Sum: 5
Global Sum: 3
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With the global object, you can initialize the variable in one context (function) and access it in another like the following:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;function printSum() {
  global.sum = 3;
  console.log(&amp;quot;Global Sum 1: &amp;quot; + global.sum);
}
function printSum2() {
  console.log(&amp;quot;Global Sum 2: &amp;quot; + global.sum);
}
printSum();
printSum2();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;Global Sum 1: 3
Global Sum 2: 3
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are semi-religious wars going on as to whether the global variables should never be used or are a necessary evil.&amp;nbsp; I fall in the later camp but do make sure you use them wisely and understand the context from which your variables are run to avoid debugging headaches later down the road.&lt;/p&gt;
</description>
      <pubDate>Mon, 01 Jun 2015 14:18:00 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/nodejs-abcs-f-is-for-functions</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>javascript</category>
      <category>linerate</category>
      <category>node</category>
      <title>Node.js ABC’s - F is for Functions</title>
      <description>&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/Functions.png"&gt;&lt;img align="right" alt="Functions" border="0" height="209" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/Functions_thumb.png" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 10px; border-left: 0px; display: inline; padding-right: 0px" title="Functions" width="240" /&gt;&lt;/a&gt;JavaScript, and thus Node.js, is at it&amp;#39;s heart a functional programming language.&amp;nbsp; Functions are fully typed objects that can be modified, extended, and used as data objects.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;A function is a block of code designed to perform a specific task and is much the same as a procedure or subroutine in other programming languages.&amp;nbsp; Node.js takes advantage quite extensively of this capability allowing the developer to define code once and reuse it many times.&lt;/p&gt;

&lt;h2&gt;Function Syntax&lt;/h2&gt;

&lt;p&gt;A JavaScript function is defined with the &amp;quot;function&amp;quot; keyword, followed by a name, followed by parentheses.&amp;nbsp; A function name has the same rules as variables in that they can contain letters, digits, underscores, and dollar signs.&amp;nbsp; The code to be executed in the function is placed inside curly braces after the function declaration.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;function name(param1, param2, ...) {
  code to be executed
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As I mentioned above, functions can be used as data objects in code and other function calls.&amp;nbsp; When passing a function in as a parameter, one could do something like this&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;function passInFunc(f) {
  f(&amp;quot;in myfunc&amp;quot;);
}
function myfunc(param) {
  console.log(param);
}
passInFunc(myfunc);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When control hits the &amp;quot;passInFunc&amp;quot; function, the name of the &amp;quot;myfunc&amp;quot; function is not relevant.&amp;nbsp; this is where &amp;quot;Anonymous functions&amp;quot; come into play.&amp;nbsp; Anonymous functions are commonly used as callback parameters when using the Event Emitter pattern described in my article on &lt;a href="https://devcentral.f5.com/articles/nodejs-abcs-e-is-for-events"&gt;Node.js Events&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;An anonymous function can be declared either as a standalone variable&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;function passInFunc(f) {
   f(&amp;quot;in myfunc&amp;quot;);
}
var f = function(param) {
  console.log(param);
}
passInFunc(f);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or more concisely as&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;function passInFunc(f) {
  console.log(&amp;quot;in myfunc&amp;quot;);
}
passInFunc(function(param) {
  console.log(param);
});&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It is this later format that you see used extensively in the Event Emitter pattern.&amp;nbsp; Anonymous functions have the drawback in that when exceptions are thrown, the debugger does not have a name context for the call stack which makes life a bit more difficult when debugging.&lt;/p&gt;

&lt;h2&gt;Function Parameters&lt;/h2&gt;

&lt;p&gt;To declare parameters, you simply list them in the parentheses separated by commas.&amp;nbsp; Since JavaScript is a loosely typed language, there is no checking of these parameters at runtime.&amp;nbsp; If a function is declared with two parameters, but the caller does not include them, the values of the parameters within the function will be set to undefined.&amp;nbsp; Within the scope of the function, parameters have local scope to the function, meaning that their values are not accessible from a global scope or from other functions.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;function func(param1, param2, param3) {}
func(&amp;quot;one&amp;quot;);  // param2, and param3 are undefined
func(&amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;); // param3 is undefined
func(&amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot;); // all parameters are defined&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Function Return Values&lt;/h2&gt;

&lt;p&gt;Functions can include return statements.&amp;nbsp; When a return statement is reached, the function will stop executing and control will be returned to the code after the statement that invoked the function call. To return a status back to the caller, the return statement can take an optional value parameter which the caller can use to make logic decisions.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;function add(a, b) {
  return a+b;
}
var sum = add(1,2)  // the sum variable will contain the value 3.&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Function Invocation&lt;/h2&gt;

&lt;p&gt;To cause the function to execute, you must include the () operator after the function name.&amp;nbsp; Referencing just the function name refers to the function object.&amp;nbsp;&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;function myfunc(param) { }
# f contains the myfunc object
var f = myfunc;

# f contains the return value from the myfunc 
var f = myfunc(param);&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Function Scope&lt;/h2&gt;

&lt;p&gt;When a function is called, a new variable scope is created.&amp;nbsp; Variables declared in the calling scope are available to the function, but variables declared within the new function scope are not available when the function completes it&amp;#39;s processing and returns.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;var best_language = &amp;quot;JavaScript&amp;quot;;
function print_best() {
  console.log(best_language);
  best_language = &amp;quot;c++&amp;quot;;
  console.log(best_language);
}
print_best();
console.log(best_language);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The above code will print the following to the console&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;JavaScript
c++
JavaScript&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Combining scope with anonymous functions can yield some interesting ways to do work with private variables that disappear when the anonymous function exits.&lt;/p&gt;
</description>
      <pubDate>Thu, 07 May 2015 10:04:00 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/devops-101-management</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>devops</category>
      <category>itil</category>
      <category>management</category>
      <category>scm</category>
      <title>DevOps 101 - Management</title>
      <description>&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/DevOps-Management.png"&gt;&lt;img align="right" alt="DevOps-Management" border="0" height="244" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/DevOps-Management_thumb.png" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 10px; border-left: 0px; display: inline; padding-right: 0px" title="DevOps-Management" width="189" /&gt;&lt;/a&gt;In my previous article on the history of DevOps, I outlined the following pillars of the DevOps methodology&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;Management&lt;/li&gt;
 &lt;li&gt;Integration&lt;/li&gt;
 &lt;li&gt;Communication and information sharing&lt;/li&gt;
 &lt;li&gt;Collaboration&lt;/li&gt;
 &lt;li&gt;Automation&lt;/li&gt;
 &lt;li&gt;Measurement&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;The First Pillar&lt;/h2&gt;

&lt;p&gt;In this article I&amp;#39;ll touch on the first pillar of DevOps: Management.&amp;nbsp; Dictionary.com&amp;#39;s definition for the term &amp;quot;&lt;a href="http://dictionary.reference.com/browse/management"&gt;management&lt;/a&gt;&amp;quot; gives a good direction to focus on to cover this topic.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Management : The act or manner of managing; handling, direction, or control&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Managing is a bit ambiguous, but handling, direction, and control are right on target with regards to DevOps.&amp;nbsp; DevOps is a set of tools and methodologies to help Developers and IT Operations work together to push software updates through the system faster and more reliably.&amp;nbsp;&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;:%s/software updates/fliers/&lt;/h3&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you think about it, DevOps is very similar to an airline company.&amp;nbsp; The goal of an airline company is to get a person from point &amp;quot;A&amp;quot; to point &amp;quot;B&amp;quot; faster and more reliably.&amp;nbsp; Much like the developer and IT teams try to get software from the developers workstation to the application server hosting the application for your user base.&lt;/p&gt;

&lt;h2&gt;The Three Managements&lt;/h2&gt;

&lt;p&gt;Many of the concepts involved in DevOps come from three types of management processes: Software Configuration Management, Enterprise Systems Management, and Software Application Release Management.&lt;/p&gt;

&lt;h3&gt;Software Configuration Management&lt;/h3&gt;

&lt;p&gt;Software configuration management (SCM) is the task of handling and controlling changes in software by utilizing revision control and the use of code stability baselines.&amp;nbsp; Revision control gives a view into who changed what and when and can also help with determining how to replicate configurations across servers.&amp;nbsp; SCM provides identification, control, auditing, build and process management, teamwork, and defect tracking.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;There are literally hundreds of free and commercially available software solutions to help with revision control.&amp;nbsp; Wikipedia has a nice list under &amp;quot;&lt;a href="http://en.wikipedia.org/wiki/List_of_revision_control_software"&gt;List of revision control software&lt;/a&gt;&amp;quot;.&lt;/p&gt;

&lt;h3&gt;Enterprise Systems Management&lt;/h3&gt;

&lt;p&gt;Once the organization has control of the software, it must be able to control the administration of the servers and distributed systems used to build and deploy the software.&amp;nbsp; Systems management includes taking software and hardware inventories, monitoring and metrics, anti-virus and anti-malware software, system and network capacity and utilization monitoring, storage, and security.&amp;nbsp; These tasks fall into the following management functions&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;Fault - troubleshooting, logging, and recovery&lt;/li&gt;
 &lt;li&gt;Configuration - hardware and software inventory, provisioning, and software deployment&lt;/li&gt;
 &lt;li&gt;Account - billing and statistics&lt;/li&gt;
 &lt;li&gt;Performance - software metering and event/metric monitoring&lt;/li&gt;
 &lt;li&gt;Security - identity and policy management.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As with the software configuration tools, there are more options here than I can list.&amp;nbsp; I&amp;#39;ll refer you to another Wikipedia listing on &lt;a href="http://en.wikipedia.org/wiki/List_of_systems_management_systems"&gt;systems management systems&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Application Release Management&lt;/h3&gt;

&lt;p&gt;Release management is the process giving direction to software releases from development, to test, and finally through to final software release.&amp;nbsp; Release managers are key to this process and they typically handle being a facilitator between business units, a gatekeeper to builds and systems, and being a coordinator of source locations, projects, and release process teams.&lt;/p&gt;

&lt;p&gt;The advent of Agile software development has brought on a much higher frequency of releases which have led to increased dependency on the release management teams to track and execute on complex release processes.&amp;nbsp; Release teams have used methodologies such as &lt;a href="http://www.itlibrary.org/"&gt;Information Technology Infrastructure Library (ITIL)&lt;/a&gt; to help achieve these needs.&lt;/p&gt;

&lt;p&gt;The list of tools in the release management space is not as broad as it&amp;#39;s configuration and systems management counterparts.&amp;nbsp; Popular solutions includes ones from &lt;a href="https://www.distelli.com/"&gt;Distelli&lt;/a&gt;, &lt;a href="https://www.chef.io/"&gt;Chef&lt;/a&gt; , &lt;a href="https://puppetlabs.com/"&gt;Puppet Labs&lt;/a&gt;, and &lt;a href="http://octopusdeploy.com/"&gt;Octopus Deploy&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Management is just one component in the DevOps &amp;quot;stack&amp;quot;.&amp;nbsp; In the next article I&amp;#39;ll be discussing how Integration fits into the DevOps puzzle.&lt;/p&gt;
</description>
      <pubDate>Wed, 06 May 2015 13:50:00 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/nodejs-abcs-e-is-for-events</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>linerate</category>
      <category>node</category>
      <title>Node.js ABC’s - E is for Events</title>
      <description>&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/EVENTS.jpg"&gt;&lt;img title="Events" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 10px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="Events" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/EVENTS_thumb.jpg" width="191" align="right" height="161"&gt;&lt;/a&gt;Node.js has it's basis in asynchronous programming. Also known as Event-driven programming, asynchronous development gives the programmer a way to write a program in such a way as to not block the progress of the program while waiting for a long-lived task to complete.  Input/Output processing for local resources such as file system access or for remote network based content such as database queries or web requests is a prime example of a operation that can take an extended period to complete.  &lt;/p&gt; &lt;h2&gt;The Event Driven Programming Style&lt;/h2&gt; &lt;p&gt;Events are a way for the underlying system to notify the calling program that a certain long lived task is finished and ready for the calling program to act on that operation.&lt;/p&gt; &lt;p&gt;In traditional synchronous programming, if you were to make a database request, you'd do something like this&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;result = query('select * from very_large_table where complex_criteria...')
process_result(result);
...
do_more_work&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, the calling process will block and not be able to perform any other processing until the result is returned from the query.  A more elegant way to do this would be to use a callback, or Event.&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;query_finished = function(result) {
 process_result(result);
}
query('select * from very_large_table where complex_criteria...', query_finished)
...
do_more_work&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this second example, we are using event callbacks.  The calling program passes in a function to the query method to call back to when the long lived operation is completed.  Meanwhile the program can continue doing work and when the query is completed, the query_finished function is called and the result can be processed.&lt;/p&gt;
&lt;h2&gt;Standard Callback Pattern&lt;/h2&gt;
&lt;p&gt;Events require 2 components, a "emitter" and a "receiver".  The receiver indicates to the emitter which events it would like to receive, and the emitter sends those events to the receiver when the event has occurred.  In Node, many objects emit events.  For instance, a TCP connection can emit a "connected" event when a new connection is made, or a HTTP request can emit a "data" event each time a new batch of data is read from it's connection.  &lt;/p&gt;
&lt;p&gt;In my first example above, a return value is used to pass back the status of the operation.  The asynchronous alternative is to use what is called "&lt;a href="http://en.wikipedia.org/wiki/Continuation-passing_style"&gt;Continuous-passing style&lt;/a&gt;" or "CPS".  For a CPS styled method, the function takes an extra argument which is a "continuation" for the completion of the function.  &lt;/p&gt;
&lt;h2&gt;Event Emitter Pattern&lt;/h2&gt;
&lt;p&gt;The standard callback pattern shown above works well when you want to let the client know of command completion, but it not optimal when several events take place during the execution, or if the events happen numerous times.  This is where the Event Emitter pattern comes into play.  There are two pieces of the Event Emitter pattern, the event emitter and the event listeners (where there can be more than one).&lt;/p&gt;
&lt;p&gt;To illustrate this, let's consider the above example of a long lived SQL query.  If the result contains a very large record set, it would likely not be optimal to return the whole result set in a single response from the function call.  Best practice would be to break the data up into smaller chunks.  For a SQL query, that could equate to rows in the resulting table.  In this case, we'd want to have an event that was emitted for each row in the result set and then one event for when the result set is complete.  This could be accomplished with something like this:&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;process_row = function(row_data) {
 // do something with row
};
process_end = function() {
 // do something to when data is complete
};
query('select * from very_large_table where complex_criteria...', function(response) {
 response.on("row", function(row_data) {
   process_row(row_data);
 });
 response.on("end", function() {
   process_end();
 });
});&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a general rule of thumb, you should use CPS when you want to regain control after an operation completes and use the emitter pattern when an event can happen more than once per method call.&lt;/p&gt;
&lt;h2&gt;More reading on Events&lt;/h2&gt;
&lt;p&gt;For information on the core Events classes, look at the Events section in the &lt;a href="https://nodejs.org/api/events.html"&gt;Node.JS Manual and Documentation&lt;/a&gt;.  the EventEmitter class is used to setup your object for emitting events to receivers.  There is a good tutorial on using the EventEmitter class over at hacksparrow.com under &lt;a href="http://www.hacksparrow.com/node-js-eventemitter-tutorial.html"&gt;Node.js EventEmitter Tutorial&lt;/a&gt;  &lt;/p&gt;
&lt;p&gt;You might also want to check out my article on &lt;a href="https://devcentral.f5.com/articles/nodejs-abcs-c-is-for-callbacks"&gt;Node.JS callbacks&lt;/a&gt; which has some more details on how to use callback functions.&lt;/p&gt;</description>
      <pubDate>Thu, 16 Apr 2015 15:25:29 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/devops-101-a-brief-history-of-time</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>apm</category>
      <category>application delivery</category>
      <category>availability</category>
      <category>cloud</category>
      <category>deployment</category>
      <category>design</category>
      <category>devops</category>
      <category>management</category>
      <category>openstack</category>
      <category>performance</category>
      <category>security</category>
      <category>virtualization</category>
      <title>DevOps 101 - A Brief History Of Time</title>
      <description>&lt;p&gt;If you have anything to do with developing products or working in IT helping to deploy and run them, chances are you have heard the term &amp;quot;&lt;a href="http://en.wikipedia.org/wiki/DevOps"&gt;DevOps&lt;/a&gt;&amp;quot; in one form or another.&amp;nbsp; Just like the ubiquitous &amp;quot;&lt;a href="http://en.wikipedia.org/wiki/Cloud_(disambiguation)"&gt;Cloud&lt;/a&gt;&amp;quot; floating out in the Internet somewhere, DevOps has become a catch-all phrase for anything that is Developer or Operations related.&lt;/p&gt;

&lt;p&gt;Before jumping into what DevOps is, I think it&amp;#39;s helpful to look back at the evolution of software development which will make it clear why DevOps was inevitable.&lt;/p&gt;

&lt;h2&gt;First Came The Developer And QA&lt;/h2&gt;

&lt;p&gt;I&amp;#39;ll start be looking back a few years when software was primarily developed and targeted as software installs on end users computers with physical media (DVDs, CDs, or dare I date myself and say Floppy Disks). Development teams would work tirelessly 6+ months on the next release of their product.&amp;nbsp; When the development team gave it the green light, it would go to the quality assurance engineers to perform end user testing, then back to Dev to fix things, then back to test and so on.&amp;nbsp; When QA gave it the green light, it would go to pressing and packaging and ultimately end up at the end user.&lt;/p&gt;

&lt;h2&gt;Next Came The Internet&lt;/h2&gt;

&lt;p&gt;Once companies discovered they could distribute their applications in &amp;quot;soft&amp;quot; copy, they eliminated the overhead and costs for physical media, paper manuals, and shipping costs while providing almost instantaneous access for their customers to their latest and greatest software.&lt;/p&gt;

&lt;h2&gt;Then The End Users Got Greedy&lt;/h2&gt;

&lt;p&gt;I&amp;#39;m not sure who first thought of a &amp;quot;hotfix&amp;quot;, but whoever did is somewhat responsible for the current need for the agile philosophies in application development.&amp;nbsp; Users no longer had to wait 6 months for a &amp;quot;bug&amp;quot; to be fixed in their local copies of the software.&amp;nbsp; Hotfixes brought an interesting dilemma as they only contained a fraction of the code needed for a major release and, consequently, needed to be produced on a much shorter timeframe and at a much higher frequency.&amp;nbsp; Developers and QA need to come up with a better way to handle the more frequent development cycles and came up with a solution with development methodologies like Agile and Scrum.&amp;nbsp; That helped them maintain sanity in their development processes. But Dev and QA needed to come up with solutions to make the delivery process more seamless.&lt;/p&gt;

&lt;h2&gt;Then Came The Web Application And Network Ops&lt;/h2&gt;

&lt;p&gt;Someone sat in a meeting in some conference room and said &amp;quot;We have a website right?&amp;nbsp; Why don&amp;#39;t we build a version of our product to run on the web?&amp;quot;&amp;nbsp; Reducing the users need to physically install software is a big bonus as they always have access to the latest and greatest.&amp;nbsp; If the hotfix wasn&amp;#39;t a turning point, then the migration of apps from standalone to web-based definitely was.&amp;nbsp; Network Operations (Net Ops) came into the scene here as they were needed facilitate distribution of the downloadable images.&amp;nbsp; This helpful IT folks make it their life&amp;#39;s goal to have the bits accessible and the download as fast as possible to all users across the internet.&amp;nbsp; They took the files, put them in their distribution channels such as ftp/web servers and Content Delivery Networks, checked the box on the release document and waited until the next request.&amp;nbsp; (Ok, I know I&amp;#39;m simplifying things and IT does a lot more than than, but this is going somewhere I promise).&lt;/p&gt;

&lt;h2&gt;Then Came The Pain&lt;/h2&gt;

&lt;p&gt;What that guy, or gal, in that conference room didn&amp;#39;t think of was the issues that would arise with the deployment of an application from physical media to the network.&amp;nbsp; No longer are the Ops folks just responsible for the &amp;quot;bits&amp;quot; passed to them to be accessible, they were now responsible about minor things like user experience, access controls, hackers, availability, compliance, etc.&amp;nbsp; Up until this point, the development and release process was fairly painless but now it just got a whole lot messier.&amp;nbsp; The Ops team&amp;#39;s jobs are now at stake for maintaining all of those &amp;quot;minor&amp;quot; things and much more.&amp;nbsp; No longer can they just take the word from the development team that a product is &amp;quot;ready&amp;quot; for distribution and blindly &amp;quot;check&amp;quot; the box on the release.&lt;/p&gt;

&lt;h2&gt;Then Came The Brick Wall&lt;/h2&gt;

&lt;p&gt;Needless to say, things went from good to worse. It started enforcing process that infused them with the dev-test-production migration.&amp;nbsp; Change tickets, request queues, and delays ensued.&amp;nbsp; A brick wall was being built between Dev and Ops.&amp;nbsp; Dev would toss a release over the wall to Ops.&amp;nbsp; A response would be tossed back over the wall to Dev with either the successful QA and deployment or rejection to fix something and try again.&amp;nbsp; Dev started seeing Ops as those trying to stifle their innovation while Ops saw Dev as reckless with no regard for how the apps run in the real world.&amp;nbsp; Distrust then led to a slow development process with logs of back and forth.&lt;/p&gt;

&lt;h2&gt;Introducing Some Sanity&lt;/h2&gt;

&lt;p&gt;Since the Agile development process was so successful in helping put sanity in the code production process, at the Agile 2008 conference, Andrew Clay Shafer and Patrick Debois discussed the new concept of &amp;quot;&lt;a href="http://www.jedi.be/blog/2008/10/09/agile-2008-toronto-agile-infrastructure-and-operations-presentation/"&gt;Agile Infrastructure&lt;/a&gt;&amp;quot;&amp;nbsp; and afterwards created the &amp;quot;Agile System Administrators&amp;quot; group on Google.&amp;nbsp; The term &amp;quot;DevOps&amp;quot; was then born and made popular through a new &amp;quot;DevOps Days&amp;quot; set of conferences that started in 2009 in Belgium.&amp;nbsp; DevOps takes the Agile development processes to the next level by adding Ops into the mix.&amp;nbsp; Welcome to the club Ops, now you are a developer too!&lt;/p&gt;

&lt;h2&gt;Enter DevOps&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/Devops.png"&gt;&lt;img align="right" alt="Devops" border="0" height="188" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/Devops_thumb.png" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 10px; border-left: 0px; display: inline; padding-right: 0px" title="Devops" width="233" /&gt;&lt;/a&gt;To put it succinctly DevOps is a set of tools and methodologies to help Dev and Ops work together to enable pushing more software updates out faster and more reliably.&amp;nbsp; Regular communication, small batches of work, and an iterative approach are just a few pieces of the puzzle.&amp;nbsp; DevOps methods stress the following pillars which I&amp;#39;ll refer to as the MICCAM model:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;Management&lt;/li&gt;
 &lt;li&gt;Integration&lt;/li&gt;
 &lt;li&gt;Communication and Information Sharing&lt;/li&gt;
 &lt;li&gt;Collaboration&lt;/li&gt;
 &lt;li&gt;Automation&lt;/li&gt;
 &lt;li&gt;Measurement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By now you see how the DevOps methodology came to be and the problems that it is trying to solve.&amp;nbsp; It&amp;#39;s important to keep in mind that &amp;quot;DevOps&amp;quot; is not a end-all-be-all solution that fits everyone to a &amp;ldquo;T&amp;rdquo;.&amp;nbsp; Just as Agile and Scrum are tweaked and adjusted by developers, the tools and execution will vary based on the companies requirements and dependencies.&amp;nbsp; To help with the execution, several companies like &lt;a href="https://www.chef.io/solutions/devops/"&gt;Chef&lt;/a&gt;, &lt;a href="http://www.ansible.com/"&gt;Ansible&lt;/a&gt;, and &lt;a href="http://www.puppetlabs.com/"&gt;Puppet Labs&lt;/a&gt; are building products and solutions to help companies adopt these ideas and become productive with application development and deployment.&lt;/p&gt;

&lt;p&gt;In upcoming articles, I&amp;#39;ll dig more deeply into the different pillars of DevOps, how companies are implementing them, and the various companies that are helping with the execution.&lt;/p&gt;
</description>
      <pubDate>Thu, 02 Apr 2015 12:55:00 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/nodejs-abcs-d-is-for-debugger</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>cloud</category>
      <category>linerate</category>
      <category>node</category>
      <title>Node.js ABC’s - D is for Debugger</title>
      <description>&lt;p&gt;When developing new software, a good debugging tool is essential to making sure your code is functioning as expected.&amp;nbsp; The console is most often used as a poor-mans debugging system by including extra code in your script that prints out status to the hosted console.&amp;nbsp; Is some simple cases this is suitable, but with Node.js&amp;#39;s asynchronous nature, you cannot rely on the synchronous nature of log statements in helping you diagnose issues with your code.&amp;nbsp; Fortunately, the Node.js runtime has built in tools to help.&lt;/p&gt;

&lt;p&gt;Node.js is built on the JavaScript engine &amp;quot;V8&amp;quot; built for Google Chrome that was open sourced by Google in 2008.&amp;nbsp; V8 includes with it an extensive debugging system for use when development your Node.js applications.&amp;nbsp; The debugger can be accessed by a TCP based TCP &lt;a href="https://code.google.com/p/v8-wiki/wiki/DebuggerProtocol"&gt;DebuggerProtocol&lt;/a&gt;&amp;nbsp; .&lt;/p&gt;

&lt;p&gt;Having an API to access the debugger is useful for 3rd party developer tools but is a bit overkill for the average developer trying to diagnose an issue with a script.&amp;nbsp; Fortunately, Node.js also has a built-in client to access the debugger.&lt;/p&gt;

&lt;h2&gt;THE BUILT-IN CONSOLE DEBUGGER&lt;/h2&gt;

&lt;p&gt;To use this client, start Node with the &amp;quot;debug&amp;quot; argument.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;$ node debug sample.js
&amp;lt; debugger listening on port 5858
connection... ok
break in sample.js:1
1 var str = &amp;quot;&amp;quot;;
2 for(var i=0; i&amp;lt;10; i++) {}
3&amp;nbsp;&amp;nbsp; str += i.toString();
debug&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;COMMANDS REFERENCE&lt;/h3&gt;

&lt;h4&gt;Stepping&lt;/h4&gt;

&lt;table border="1" cellpadding="5" cellspacing="5"&gt;
 &lt;tbody&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;cont,c&lt;/th&gt;
   &lt;td&gt;Continue execution&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;next,n&lt;/th&gt;
   &lt;td&gt;Step to next statement&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;step,s&lt;/th&gt;
   &lt;td&gt;Step in to function&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;out,o&lt;/th&gt;
   &lt;td&gt;Step out to calling function&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;pause&lt;/th&gt;
   &lt;td&gt;Pause running code similar to the pause button in the browser developer tools.&lt;/td&gt;
  &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;$ node debug sample.js 
&amp;lt; debugger listening on port 5858
connecting... ok
break in sample.js:1&amp;nbsp;&amp;nbsp; 1 &lt;strong&gt;var&lt;/strong&gt; str = &amp;quot;&amp;quot;;
  &lt;/code&gt;&lt;code&gt;2 for(var i=0; i&amp;lt;10; i++) {&amp;nbsp;&amp;nbsp; 3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; str += i.toString();
debug&amp;gt; n
break in sample.js:2&amp;nbsp;&amp;nbsp; 1 var str = &amp;quot;&amp;quot;;
&amp;nbsp; 2 &lt;strong&gt;for&lt;/strong&gt;(var i=0; i&amp;lt;10; i++) {
&amp;nbsp; 3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; str += i.toString();
&amp;nbsp; 4 }
debug&amp;gt; n
break in sample.js:3
&amp;nbsp; 1 var str = &amp;quot;&amp;quot;;
&amp;nbsp; 2 for(var i=0; i&amp;lt;10; i++) {
&amp;nbsp; 3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;str&lt;/strong&gt; += i.toString();
&amp;nbsp; 4 }
&amp;nbsp; 5 console.log(str);&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Breakpoints&lt;/h4&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;table border="1" cellpadding="5" cellspacing="5"&gt;
 &lt;tbody&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;setBreakpoint(),sb()&lt;/th&gt;
   &lt;td&gt;Set a breakpoint on the current line&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;setBreakpoint(line),sb(line)&lt;/th&gt;
   &lt;td&gt;Set a breakpoint on the specified line&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;setBreakpoint(&amp;#39;fn()&amp;#39;),sb(&amp;#39;fn()&amp;#39;)&lt;/th&gt;
   &lt;td&gt;Set a breakpoint on the first statement in a given functions body&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;setBreakpoint(&amp;#39;script.js&amp;#39;,n),sb(&amp;#39;script.js&amp;#39;,n)&lt;/th&gt;
   &lt;td&gt;Set a break point on the nth line of script.js&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;clearBreakpoint,cb()&lt;/th&gt;
   &lt;td&gt;Clear the current breakpoint&lt;/td&gt;
  &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;$ node debug sample.js 
&amp;lt; debugger listening on port 5858
connecting... ok
break in sample.js:1
  1 &lt;strong&gt;var&lt;/strong&gt; str = &amp;quot;&amp;quot;;
  2 for(var i=0; i&amp;lt;10; i++) {
  3 	str += i.toString();
debug&amp;gt; setBreakpoint(3)
  1 &lt;strong&gt;var&lt;/strong&gt; str = &amp;quot;&amp;quot;;
  2 for(var i=0; i&amp;lt;10; i++) {
* 3 	str += i.toString();
  4 }
  5 console.log(str);
  6 
debug&amp;gt; c
break in sample.js:3
  1 var str = &amp;quot;&amp;quot;;
  2 for(var i=0; i&amp;lt;10; i++) {
* 3 	&lt;strong&gt;str&lt;/strong&gt; += i.toString();
  4 }
  5 console.log(str);
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Information&lt;/h4&gt;

&lt;table border="1" cellpadding="5" cellspacing="5"&gt;
 &lt;tbody&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;backtrace,bt&lt;/th&gt;
   &lt;td&gt;Print the callstack for the current execution frame.&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;list(n)&lt;/th&gt;
   &lt;td&gt;List scripts source code with n line context (n lines before and after)&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;watch(expr)&lt;/th&gt;
   &lt;td&gt;Add an expression to the watch list&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;unwatch(expr)&lt;/th&gt;
   &lt;td&gt;Remove an expression from the watch list.&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;watchers&lt;/th&gt;
   &lt;td&gt;List all watchers and their values (which are also automatically listed on each breakpoint).&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;repl&lt;/th&gt;
   &lt;td&gt;Evaluate code remotely for evaluation in the debugging scripts context.&lt;/td&gt;
  &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;$ node debug sample.js 
&amp;lt; debugger listening on port 5858
connecting... ok
break in sample.js:1
  1 var str = &amp;quot;&amp;quot;;
  2 for(var i=0; i&amp;lt;10; i++) {
  3 	str += i.toString();
debug&amp;gt; watch(&amp;quot;str&amp;quot;)
debug&amp;gt; setBreakpoint(3)
  1 var str = &amp;quot;&amp;quot;;
  2 for(var i=0; i&amp;lt;10; i++) {
* 3 	str += i.toString();
  4 }
  5 console.log(str);
  6 
debug&amp;gt; c
break in sample.js:3
Watchers:
  0: str = &amp;quot;&amp;quot;

  1 var str = &amp;quot;&amp;quot;;
  2 for(var i=0; i&amp;lt;10; i++) {
* 3 	str += i.toString();
  4 }
  5 console.log(str);
debug&amp;gt; c
break in sample.js:3
Watchers:
  0: str = &amp;quot;0&amp;quot;

  1 var str = &amp;quot;&amp;quot;;
  2 for(var i=0; i&amp;lt;10; i++) {
* 3 	str += i.toString();
  4 }
  5 console.log(str);
debug&amp;gt; c
break in sample.js:3
Watchers:
  0: str = &amp;quot;01&amp;quot;

  1 var str = &amp;quot;&amp;quot;;
  2 for(var i=0; i&amp;lt;10; i++) {
* 3 	str += i.toString();
  4 }
  5 console.log(str);&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Execution Control&lt;/h4&gt;

&lt;table border="1" cellpadding="5" cellspacing="5"&gt;
 &lt;tbody&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;run&lt;/th&gt;
   &lt;td&gt;Run a script&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;restart&lt;/th&gt;
   &lt;td&gt;Restart a script&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;kill&lt;/th&gt;
   &lt;td&gt;Kill the current scripts execution&lt;/td&gt;
  &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4&gt;Misc&lt;/h4&gt;

&lt;table border="1" cellpadding="5" cellspacing="5"&gt;
 &lt;tbody&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;scripts&lt;/th&gt;
   &lt;td&gt;List all loaded scripts&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;th align="left"&gt;version&lt;/th&gt;
   &lt;td&gt;Display V8&amp;#39;s version.&lt;/td&gt;
  &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2&gt;THIRD PARTY SOLUTIONS&lt;/h2&gt;

&lt;p&gt;If Console debugging doesn&amp;#39;t do it for you, there are several great third party node packages out there that make use of the Debugger API.&amp;nbsp; I prefer the &lt;a href="https://github.com/node-inspector/node-inspector"&gt;node-inspector&lt;/a&gt; package that is maintained by the folks at StrongLoop.&amp;nbsp; If you have done any debugging with the built-in debugger in FireFox, then the user interface will look very familiar.&amp;nbsp; Installing the package will create a new command node-debug on your system that will start your default browser and connect to a local hosted web app that runs the debugger interface.&amp;nbsp;&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&lt;code&gt;$ node-debug program.js&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/node-debugger.png"&gt;&lt;img alt="node-debugger" border="0" height="350" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/node-debugger_thumb.png" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" title="node-debugger" width="644" /&gt;&lt;/a&gt;&lt;/p&gt;
</description>
      <pubDate>Tue, 09 Dec 2014 15:57:00 -0800</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/nodejs-abcs-c-is-for-callbacks</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>cloud</category>
      <category>linerate</category>
      <category>node</category>
      <title>Node.js ABC's - C is for Callbacks</title>
      <description>&lt;p&gt;With synchronous programming, when you make a call to function, your code is blocked until the method you are calling has processed it's work and returned it's status to you.  A good example is the "C" fopen and fread commands.&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;FILE *pFile = fopen("file.txt", "r");  // Wait...&lt;br&gt;char buf[101];&lt;br&gt;if ( NULL != pFile ) {&lt;br&gt;  fread(buf, 1, 100, pFile); // Wait...&lt;br&gt;  buf[(sizeof buf)-1] = 0;&lt;br&gt;  printf("%s", buf); // Wait...&lt;br&gt;  fclose(pFile); // Wait...&lt;br&gt;}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/Request_a_callback.jpg"&gt;&lt;img title="Request_a_callback" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 0px 10px 10px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Request_a_callback" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/Request_a_callback_thumb.jpg" width="244" align="right" height="121"&gt;&lt;/a&gt;In this code, the vast amount of time used when this code is ran is waiting for the underlying file system to access and read from the file.  It is true for most I/O based applications such as ones that utilize databases or connect to external services, your code will spend a majority of it's time sitting around waiting.&lt;/p&gt;
&lt;p&gt;One of the key components of Node.js is the concept of non-blocking I/O and asynchronous programming.  If you have seen or used the &lt;a href="http://www.w3schools.com/jsref/met_win_settimeout.asp"&gt;setTimeout()&lt;/a&gt; function in JavaScript, you already have seen how a non-blocking call works.  With the setTimeout() function, you pass in a function to call and a time after which the function should be called.&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;setTimeout(function() { console.log("Ring-a-ling...")}, 5000);&lt;br&gt;console.log("I'm Waiting for the phone to ring...");&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you run the preceding code, you'll see:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I'm waiting for the phone to ring...&lt;br&gt;Ring-a-ling...&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The code sets a timeout of 5000ms (or 5 seconds), passing in the function to call when it fires, and then it continues with the execution of the script.&lt;/p&gt;
&lt;h2&gt;The Callback Function&lt;/h2&gt;
&lt;p&gt;One of the primary patterns you will see for asynchronous programming is by using a callback function you pass to asynchronous functions.  It has at least one parameter which is to pass information about whether the call succeeded or failed.  It also frequently has a second parameter for passing back additional details about the call (a file system or network socket handle, contents of a object read requests, or the output from a database call).&lt;/p&gt;
&lt;p&gt;The following example illustrates how the &lt;a href="http://nodejs.org/api/fs.html#fs_fs_readfile_filename_options_callback"&gt;readFile&lt;/a&gt; function in the &lt;a href="http://nodejs.org/api/fs.html"&gt;file system fs core module&lt;/a&gt; works with a callback to determine the size of the file.&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;var file = "somefile.txt";
var fs = require("fs");
rs.readFile(file, function(err, data) {
  if ( err ) { throw err; }
  var len = data.toString().split("\n").length -1;   console.log("File Length: " + len);
});&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Controlling Asynchronous Calls&lt;/h2&gt;
&lt;p&gt;One can imagine when you have a complicated script that makes many asynchronous calls, you could get into some trouble in handling the callbacks in any kind of predictable order.  One handy third-party tool is the "&lt;a href="https://www.npmjs.org/package/async"&gt;async&lt;/a&gt;" module.  The async module comes with a series of helper functions for asynchronous calls and response control such as map, reduce, filter, each, etc.&lt;/p&gt;&lt;pre class="prettyprint"&gt;&lt;code&gt;async.map(['f1', 'f2', 'f3', 'f4'], fs.stat, function(err, results) {&lt;br&gt;  // results contains an array of stats for each input item
});&lt;br&gt;
// call functions at the same time and then call callback when they have all completed.
async.parallel([&lt;br&gt;  function1() { ... },&lt;br&gt;  function2() { ... },&lt;br&gt;  function3() { ... }
], callback);

// call functions one at a time in series one at a time.&lt;br&gt;async.series([&lt;br&gt;  function1() { ... },&lt;br&gt;  function2() { ... },&lt;br&gt;  function3() { ... }
])&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Synchronous Versions of Core Library Calls&lt;/h2&gt;
&lt;p&gt;Several of the core libraries include synchronous versions of their asynchronous counterparts.  This is primarily evident in the File System module (&lt;a href="http://nodejs.org/api/fs.html)"&gt;http://nodejs.org/api/fs.html)&lt;/a&gt;.  Look for functions ending in "Sync" with the omitted callback parameter.  These are useful for command line scripting where the processing delays associated with synchronous calls is not a factor.&lt;/p&gt;</description>
      <pubDate>Mon, 24 Nov 2014 13:54:36 -0800</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/nodejs-abcs-b-is-for-buffers</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>cloud</category>
      <category>linerate</category>
      <category>node</category>
      <title>Node.js ABC’s - B is for Buffers</title>
      <description>&lt;p&gt;&lt;img align="left" alt="Buffers" border="0" height="92" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/Buffers_thumb.jpg" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: left; padding-top: 0px; padding-left: 0px; margin: 0px 10px; border-left: 0px; display: inline; padding-right: 0px" title="Buffers" width="140" /&gt;Core JavaScript uses Unicode friendly interfaces for storing string data but when dealing with network protocols or file I/O that are using raw data, it&amp;#39;s necessary to handle that data as binary streams of data.&amp;nbsp; Node has several options for creating, consuming, and interacting with octet streams, one of which is a &lt;a href="http://nodejs.org/api/buffer.html"&gt;Buffer&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Node.js stores raw data in instances of a Buffer class which is similar to an array of integers but stores raw memory allocations outside the heap.&amp;nbsp; A Buffer is a region of a physical memory storage used to temporarily store data while it is being manipulated.&amp;nbsp; A Buffer class is global in scope, thus not needing a require to use it, and cannot be resized.&lt;/p&gt; &lt;h2&gt;Converting Between String Objects and Buffers&lt;/h2&gt; &lt;p&gt;To convert between a Buffer and a String Object requires you to supply an explicit encoding method.&amp;nbsp; The following is a list of the different string encodings available:&lt;/p&gt; &lt;table border="1" width="100%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;th&gt;ascii&lt;/th&gt; &lt;td&gt;To be used for 7-bit ASCII data only and limited to the ASCII character set.&amp;nbsp; This is a very fast encoding method but will strip the high-bit off if set.&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;th&gt;utf8&lt;/th&gt; &lt;td&gt;Multi-byte encoded Unicode characters typically used in many document formats including web based content.&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;th&gt;utf16le,ucs2&lt;/th&gt; &lt;td&gt;2 or 4 bytes, little endian encoded Unicode characters.&amp;nbsp; It can encode only Basic Multilingual Plane U+0000 - U+FFFF (BMP).&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;th&gt;base64&lt;/th&gt; &lt;td&gt;Base64 encoded strings&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;th&gt;binary&lt;/th&gt; &lt;td&gt;A deprecated encoding from raw binary data into strings by only using the first 8 bits of each character.&amp;nbsp; This should not be used as it will be removed from Node.js in the future.&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;th&gt;hex&lt;/th&gt; &lt;td&gt;Encode each byte as two hexidecimal characters.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;h2&gt;Creating Buffers in Node.js&lt;/h2&gt; &lt;p&gt;The Buffer object has the following constructors for creation:&lt;/p&gt; &lt;pre class="prettyprint prettyprinted"&gt; &lt;code&gt;&lt;font face="Calibri"&gt;// Allocate a new Buffer of &amp;ldquo;size&amp;rdquo; octets &lt;/font&gt;new Buffer( size // number; size of the buffer );&lt;/code&gt;&lt;/pre&gt; &lt;pre class="prettyprint prettyprinted"&gt; &lt;code&gt;&amp;gt; var buf = new Buffer(5); // Create a buffer of size 5. &amp;gt; console.log(buf); &amp;lt;Buffer 00 00 00 00 00&amp;gt;&lt;/code&gt;&lt;/pre&gt; &lt;pre class="prettyprint prettyprinted"&gt; &lt;code&gt;// Allocates a new Buffer using the supplied Array of octets new Buffer( array // array; user supplied array of data );&lt;/code&gt;&lt;/pre&gt; &lt;pre class="prettyprint prettyprinted"&gt; &lt;code&gt;&amp;gt; var buf = new Buffer([1,2,3,4,5]); // Create a buffer of size 5 with the numbers 1-5. &amp;gt; console.log(buf); &amp;lt;Buffer 00 01 02 03 04 05&amp;gt;&lt;/code&gt;&lt;/pre&gt; &lt;pre class="prettyprint prettyprinted"&gt; &lt;code&gt;/// Allocates a new buffer containing the string &amp;ldquo;str&amp;rdquo;.&amp;nbsp; The encoding defaults to &amp;ldquo;utf8&amp;rdquo;. new Buffer( &amp;nbsp; str,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // string; A input string to store in the Buffer &amp;nbsp; encoding&amp;nbsp; // string (optional); Character encoding defaulting to utf8. );&lt;/code&gt;&lt;/pre&gt; &lt;pre class="prettyprint prettyprinted"&gt; &lt;code&gt;&amp;gt;var buf = new Buffer(&amp;ldquo;Hello World!&amp;rdquo;, &amp;ldquo;utf8&amp;rdquo;); // Create a Buffer containing the string &amp;ldquo;Hello World!&amp;rdquo; &amp;gt;console.log(buf); &amp;lt;Buffer 48 65 6c 6c 6f 20 57 6f 72 6c 64 21&amp;gt;&lt;/code&gt;&lt;/pre&gt; &lt;h2&gt;Static Methods&lt;/h2&gt; &lt;p&gt;The Buffer object contains the following static methods for use when interacting with Buffer objects.&lt;/p&gt; &lt;pre class="prettyprint prettyprinted"&gt; // Test if encoding string is valid &lt;code&gt;Buffer.isEncoding( encoding // string; Encoding string to verify ); // Test if object is a Buffer Buffer.isBuffer( obj // object; object to test ); // Calculate the byte length of a string Buffer.byteLength( string, // string; input string to get length of encoding // string (optional); encoding string defaults to utf8. ); // Concatenate a list of Buffer objects into a single Buffer Buffer.concat( list, // array; Array of Buffer objects totalLength // number (optional); total length of buffers when concatenated ); &lt;/code&gt;&lt;/pre&gt; &lt;h2&gt;Writing To Buffers&lt;/h2&gt; &lt;p&gt;Buffers aren&amp;rsquo;t of much use unless you can actually manipulate the data in them.&amp;nbsp; The constructors can be used to create new Buffers with content and the&amp;nbsp; write method allows you to write a string to an existing buffer.&amp;nbsp; You can also use the [] accessor to set individual octets in the Buffer.&lt;/p&gt; &lt;pre class="prettyprint prettyprinted"&gt; &lt;code&gt;// Write a string to a Buffer buf.write( str, // string; A supplied string offset, // number (optional); The index of the buffer to start writing to (default is 0) length, // number (optional); The number of bytes to write (defaults to buf.length &amp;ndash; offset. encoding // string (encoding); The encoding to use (defaults to utf8). );&lt;/code&gt;&lt;/pre&gt; &lt;pre class="prettyprint prettyprinted"&gt; &lt;code&gt;&amp;gt; var buf = new Buffer(&amp;ldquo;Hi There); &amp;gt; buf.toString(); &amp;rdquo;Hi There&amp;rdquo; &amp;gt; buf.write(&amp;ldquo;HI&amp;rdquo;); &amp;gt; buf.toString(); &amp;rdquo;HI There&amp;rdquo; &amp;gt;buf.write(&amp;ldquo;H&amp;rdquo;, 4); &amp;gt;buf.toString(); &amp;rdquo;HI THere&amp;rdquo; &amp;gt;buf[7] = &amp;ldquo;E&amp;rdquo; &amp;gt;buf.toString(); &amp;rdquo;HI THerE&amp;rdquo;&lt;/code&gt;&lt;/pre&gt; &lt;h2&gt;Reading From Buffers&lt;/h2&gt; &lt;p&gt;Reading from Buffers can be done with the index [] accessor and the toString() method to convert the Buffer to a string&lt;/p&gt; &lt;pre class="prettyprint prettyprinted"&gt; &lt;code&gt;// decode and return a string from a Buffer buf.toString( encoding, // string (optional); The encoding to use when converting to a string (defaults to &amp;ldquo;utf8&amp;rdquo;). start, // number (optional); The index in Buffer to start at (defaults to 0). end // number (optional); The index in Buffer to end at (defaults to buf.length). );&lt;/code&gt;&lt;/pre&gt; &lt;pre class="prettyprint prettyprinted"&gt; &lt;code&gt;&amp;gt;var buf = new Buffer(&amp;ldquo;Hi There&amp;rdquo;); &amp;gt;buf.toString(); &amp;rdquo;Hi There&amp;rdquo; &amp;gt;buf[3]; &amp;rdquo;T&amp;rdquo; &amp;gt;buf.toString(&amp;ldquo;utf8&amp;rdquo;, 3); &amp;rdquo;There&amp;rdquo;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Since JSON is at the heart of JavaScript, there is the following method to convert a buffer to it&amp;rsquo;s JSON array format&lt;/p&gt; &lt;pre class="prettyprint prettyprinted"&gt; &lt;code&gt;// Return a JSON-representation of the Buffer instance. buf.toJSON();&lt;/code&gt;&lt;/pre&gt; &lt;pre class="prettyprint prettyprinted"&gt; &lt;code&gt;&amp;gt;var buf = new Buffer(&amp;ldquo;Hi There&amp;rdquo;); &amp;gt;buf.toJSON(); [ 72, 105, 32, 84, 104, 101, 104, 101 ]&lt;/code&gt;&lt;/pre&gt; &lt;h2&gt;Further Exploration&lt;/h2&gt; &lt;p&gt;To explore the full list of features of the Buffer object, check out the &lt;a href="http://nodejs.org/api/buffer.html"&gt;Buffer documentation on nodejs.org&lt;/a&gt;.&lt;/p&gt; </description>
      <pubDate>Wed, 19 Nov 2014 10:43:00 -0800</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/nodejs-abcs-a-is-for-about-nodejs</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>cloud</category>
      <category>linerate</category>
      <category>node</category>
      <title>Node.js ABCs - A is for About Node.js</title>
      <description>&lt;p&gt;&lt;a href="https://devcentral.f5.com/Portals/0/Users/030/30/30/logo-node-js-white.png"&gt;&lt;img align="right" alt="logo-node-js-white" border="0" height="82" src="https://devcentral.f5.com/Portals/0/Users/030/30/30/logo-node-js-white_thumb.png" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 0px 10px 10px; display: inline; padding-right: 0px; border-top-width: 0px" title="logo-node-js-white" width="240" /&gt;&lt;/a&gt;Back in 2008, I started a series of articles on Networking basics titled the &amp;quot;&lt;a href="https://devcentral.f5.com/articles/the-networking-abcs-a-through-z"&gt;Networking ABC&amp;rsquo;s&lt;/a&gt;&amp;quot; in which I set out to document a networking Term for each letter of the alphabet.&amp;nbsp; After some good feedback, I followed that up with The &amp;quot;&lt;a href="https://devcentral.f5.com/articles/social-media-abcs-a-to-z"&gt;Social Media ABC&amp;rsquo;s&lt;/a&gt;&amp;quot; and then the &amp;quot;&lt;a href="https://devcentral.f5.com/articles/powershell-abcs-a-to-z"&gt;PowerShell ABC&amp;rsquo;s&lt;/a&gt;&amp;quot;.&lt;/p&gt;

&lt;p&gt;After a hiatus on my ABC series, I decided to start it back up again, this time focusing on the up and coming development language &lt;a href="http://nodejs.org"&gt;Node.js&lt;/a&gt;.&amp;nbsp; With F5&amp;#39;s release of the &lt;a href="https://linerate.f5.com"&gt;Linerate Application Proxy&lt;/a&gt; earlier this year, F5 officially added Node.js to it&amp;#39;s portfolio of application APIs.&amp;nbsp; For those new to Node.js, this series aims to take 26 of the basic terms or concepts and hopefully give you some insight into how they support the language and runtime.&lt;/p&gt;

&lt;p&gt;For the first article in this series I&amp;#39;m going to try to explain what Node.js is.&amp;nbsp; For that, I&amp;#39;ll start with the definition on the &lt;a href="http://nodejs.org"&gt;Node.js website&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;What Is Node.js?&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;Node.js is a platform built on Chrome&amp;#39;s JavaScript runtime for easily building fast, scalable network applications.&amp;nbsp; Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not unlike Java, Python, or PHP, the Node.js runtime can be used to build client and server applications.&amp;nbsp; Due to it&amp;#39;s light footprint, it is also ideal for embedded systems such as F5&amp;#39;s &lt;a href="https://linerate.f5.com"&gt;Linerate Application Proxy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Node.js has a base built-in library of standard runtime functions (I/O, environment, etc) and, like Perl&amp;#39;s massive public repository of support libraries, Node.js has the same that can be managed with the Node Package Manager.&amp;nbsp; The online repository for Node.js packages can be found at &lt;a href="https://www.npmjs.org/"&gt;https://www.npmjs.org/&lt;/a&gt;.&amp;nbsp; With a whopping 104,144 packages that have been contributed by the user community, you will likely find help for any task you want to accomplish.&lt;/p&gt;

&lt;h2&gt;Getting Up And Running&lt;/h2&gt;

&lt;ol&gt;
 &lt;li&gt;Download the Node.js runtime from the &lt;a href="http://nodejs.org/download/"&gt;Downloads section&lt;/a&gt; of the Nodejs.org website.&amp;nbsp; Pre-built packages are available for Windows, OSX, Linux, SunOS.&amp;nbsp; A source package is available as well if you want to build it yourself.&lt;/li&gt;
 &lt;li&gt;Install the runtime distribution.&amp;nbsp; This will provide you with the &amp;quot;node&amp;quot; and &amp;quot;npm&amp;quot; applications.&lt;/li&gt;
 &lt;li&gt;Open a console window and run the &amp;ldquo;node&amp;rdquo; (or &amp;ldquo;node.exe on windows) command to start the runtime interpreter.&lt;/li&gt;
 &lt;li&gt;Read-up and run through some intro tutorials.&amp;nbsp; &lt;a href="http://nodeschool.io"&gt;http://nodeschool.io&lt;/a&gt; has some very good introduction materials including the &amp;quot;javascripting&amp;quot;, &amp;quot;learnyounode&amp;quot;, &amp;quot;git-it&amp;quot;, and &amp;quot;stream-adventure&amp;quot; npm packages.&amp;nbsp; You can use these to learn Node.js directly from within the node runtime.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Your First Node.js Program&lt;/h2&gt;

&lt;p&gt;For you first timers out there, here&amp;rsquo;s your typical &amp;ldquo;Hello World!&amp;rdquo; program written for node.&amp;nbsp; I&amp;rsquo;ll use the Javascript &amp;ldquo;console.log&amp;rdquo; command to print output to the console.&amp;nbsp; The first line echo&amp;rsquo;s the code into the script called prog.js.&amp;nbsp; Once the file exists, passing it as a command to the node runtime will cause the script to be executed.&lt;/p&gt;

&lt;pre class="prettyprint prettyprinted"&gt;
&lt;code&gt;
$ echo &amp;ldquo;console.log(&amp;lsquo;Hello World\!&amp;rsquo;);&amp;rdquo; &amp;gt; prog.js
$ node prog.js
Hello World!&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When you are interested in tackling some more interesting problems, check out the &amp;ldquo;learnyounode&amp;rdquo; node package linked to above.&amp;nbsp; The first few are fairly basic and the last ones can be a bit of a challenge to the intermediate level developer as well.&lt;/p&gt;

&lt;p&gt;Be on the lookout for the next article in this series where I talk about &lt;a href="https://devcentral.f5.com/articles/nodejs-abcs-b-is-for-buffers"&gt;Buffers&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Thu, 13 Nov 2014 14:16:00 -0800</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/shellshock-mitigation-with-big-ip-irules</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>application delivery</category>
      <category>devops</category>
      <category>irules</category>
      <category>security</category>
      <category>shellshock</category>
      <title>Shellshock mitigation with BIG-IP iRules</title>
      <description>&lt;p&gt;Yesterday, NIST released information on a new network exploitable vulnerability in the GNU Bash shell as demonstrated by vectors involving parts of OpenSSH sshd, the mod_cgi, and mod_cgid modules in the Apache HTTP Server, scripts executed by DHCP clients, and other situations where setting the environment around a bash process occurs.&amp;nbsp; Vulnerability &lt;a href="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-6271"&gt;CVE-2014-6271&lt;/a&gt;, or Shellshock as everyone is calling it, allows remote attackers to execute arbitrary code on the target systems.&amp;nbsp; Redhat has a great overview in their &lt;a href="https://securityblog.redhat.com/2014/09/24/bash-specially-crafted-environment-variables-code-injection-attack/"&gt;security blog posting on the topic&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What makes this vulnerability serious is the fact that server-side CGI applications running under the Apache Web Server with mod_cgi or mod_cgid are susceptible.&lt;/p&gt;

&lt;p&gt;F5&amp;#39;s Jeff Costlow is maintaining an article on the &lt;a href="https://devcentral.f5.com/articles/cve-2014-6271-shellshocked"&gt;Shellshock vulnerability &lt;/a&gt;so make sure you check back to that article for F5&amp;#39;s official stance.&lt;/p&gt;

&lt;p&gt;The first step to mitigation is to setup a plan to patch the bash shell on all of your systems.&amp;nbsp; In the interum, if you believe that any of your backend servers are vulnerable (if they are Unix-based then they likely are) and you are fronting them with a BIG-IP, below is an iRule solution you can apply to your Virtual Servers that will protect your servers against attacks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Block-Shellshocked&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Block-Shellshock iRule searches for the pattern &amp;quot;*() {*&amp;quot; in the URI and in the HTTP headers. &amp;nbsp;It is rare that this pattern of characters will occur in a URI or HTTP Header so we believe the number of false-positives will be minimal.&amp;nbsp; If the pattern is found, an audit entry will be written to the system log with the client ip as well as the URI, and optionally the HTTP header, that the attack was detected.&amp;nbsp; I chose to issue a reject on the connection.&amp;nbsp; If you want to be more polite to the hackers, you can substitute the &amp;quot;reject&amp;quot; with a 403 - Forbidden.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;when HTTP_REQUEST {
  set pattern &lt;/code&gt;&amp;quot;*() \{*&amp;quot;&lt;code&gt;; &amp;nbsp;
  if { [string match $pattern [HTTP::uri]] } {
    log local0. &amp;quot;Detected CVE-2014-6271 attack from &amp;#39;[IP::client_addr]&amp;#39; in URI &amp;#39;[HTTP::uri]&amp;#39;&amp;quot;;
    reject;
  } else {
    foreach header_name [HTTP::header names] {
      foreach header_value [HTTP::header values $header_name] {
        if { [string match $pattern $header_value] } {
          log local0. &amp;quot;Detected CVE-2014-6271 attack from &amp;#39;[IP::client_addr]&amp;#39; in HTTP Header $header_name = &amp;#39;$header_value&amp;#39;; URI = &amp;#39;[HTTP::uri]&amp;#39;&amp;quot;;
          reject;
          break;
        }
      }
    }
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Block-Shellshock-full&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first iRule gives a more detailed audit if the attack is detected. &amp;nbsp;In the case where that is not a concern and you are more concerned with performance, the HTTP::request method can be used to perform a single search across all of the request header information. &amp;nbsp;This does not cover the POST body, but at this point there is no indication that the exploit is exposed within the body portion of a POST request. &amp;nbsp;This irule reports the client IP along with the requested URI that is the source of the attack.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;when HTTP_REQUEST {
  if { [string match &lt;/code&gt;&amp;quot;*() \{*&amp;quot;&lt;code&gt; [HTTP::request]] } {
    log local0. &amp;quot;Detected CVE-2014-6271 attack from &amp;#39;[IP::client_addr]&amp;#39;; URI = &amp;#39;[HTTP::uri]&amp;#39;&amp;quot;;
    reject;
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We will be monitoring this vulnerability over the coming weeks and update the iRule solution if a more optimal one becomes available.&amp;nbsp; Please leave a comment if you have any suggestions.&amp;nbsp; And, make sure you monitor &lt;a href="https://devcentral.f5.com/articles/cve-2014-6271-shellshocked"&gt;Jeff&amp;#39;s article&lt;/a&gt; for updates.&lt;/p&gt;

&lt;p class="p1"&gt;&lt;em&gt;&lt;strong&gt;Special Considerations&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p class="p2"&gt;&lt;em&gt;&lt;span style="line-height: 1.6em;"&gt;Please be aware that this iRule will reject any connections containing the string &amp;quot;() {&amp;quot; in the URI or header.&amp;nbsp; While we are confident that this is not a valid pattern for standard headers, there could be situations where custom application values contain this string pattern and this iRule would cause issues to those applications.&amp;nbsp; We suggest running the longer iRule and actively monitoring the system log for false positives.&amp;nbsp; If you find a case where your custom application is being blocked, you can customize the first iRule to exclude the header your application relies on.&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;
</description>
      <pubDate>Thu, 25 Sep 2014 16:34:00 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/introducing-a-restful-interface-for-icontrol</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>automation</category>
      <category>development</category>
      <category>devops</category>
      <category>icontrol</category>
      <category>management</category>
      <category>us</category>
      <title>Introducing a RESTful interface for iControl</title>
      <description>&lt;!-- Injected Syntax Highlight Code --&gt;&lt;script type="text/javascript" src="/Providers/HtmlEditorProviders/CKEditor/plugins/syntaxhighlight/scripts/shCore.js"&gt;&lt;/script&gt;
&lt;link href="/Providers/HtmlEditorProviders/CKEditor/plugins/syntaxhighlight/styles/shCore.css" rel="stylesheet" type="text/css" /&gt;&lt;script type="text/javascript"&gt;SyntaxHighlighter.all();&lt;/script&gt;
&lt;h2&gt;&lt;span style="font-weight: bold;"&gt;iControl isn&amp;rsquo;t just SOAP anymore&amp;hellip;&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;&lt;a class="itcexpando" href="/Portals/0/images/metapost/News-Articles/Joe/2013/Jun/Windows-Live-Writer-Introducting-a-RESTful-interface-for-iCo_84CE-REST-Cover_2.png" onclick="return mp.expand(this,{slideshowGroup:'2988ff17'})"&gt;&lt;img align="right" alt="REST-Cover" height="260" src="/Portals/0/images/metapost/News-Articles/Joe/2013/Jun/Windows-Live-Writer-Introducting-a-RESTful-interface-for-iCo_84CE-REST-Cover_thumb.png" style="border-width: 0px; background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-style: solid; float: right;" title="REST-Cover" width="202" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No, iControl isn&amp;rsquo;t getting lazy.&amp;nbsp;&amp;nbsp; While taking it easy is an important part of life, I&amp;rsquo;m talking about the other kind of REST.&amp;nbsp;&amp;nbsp; &lt;a href="http://en.wikipedia.org/wiki/REST"&gt;REST&lt;/a&gt;, or &amp;ldquo;REpresentational State Transfer&amp;rdquo; for you technically inclined, is a style of architectural principals with which you can design web services that focus on a system&amp;rsquo;s resources.&amp;nbsp; It also defines how resource states are addressed and transferred over the network.&amp;nbsp; REST is really a &amp;ldquo;style&amp;rdquo; of getting and setting resources and doesn&amp;rsquo;t define the underlying communications.&amp;nbsp; Most implementations out there make use of HTTP and JSON as a content format, which is what we&amp;rsquo;ve chosen to do as well.&lt;/p&gt;

&lt;p&gt;There are plenty of articles on the web that compare and contrast SOAP and REST, so I won&amp;rsquo;t get into those here.&amp;nbsp; I&amp;rsquo;m also not going to go really deep into the principals of REST as you can find dozens of those easily with a web search.&amp;nbsp;&amp;nbsp; In this article, I&amp;rsquo;ll discuss how we&amp;rsquo;ve chosen to implement our REST interface for iControl and give you some examples on how to use it.&lt;/p&gt;

&lt;p&gt;Oh, and don&amp;rsquo;t get any ideas that our SOAP based interface is going anywhere.&amp;nbsp; We are creating our REST interfaces as an alternate method for performing automation and monitoring.&amp;nbsp; We don&amp;rsquo;t currently have plans on ceasing development on our SOAP interface.&lt;/p&gt;

&lt;h2&gt;&lt;span style="font-weight: bold;"&gt;iControl-REST &lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;The REST interface for iControl was introduced in BIG-IP version 11.4.&amp;nbsp; For this release, we are considering the feature as &amp;ldquo;Early Access&amp;rdquo;.&amp;nbsp; Call it beta or whatever you want.&amp;nbsp; But what that really means is that it will change in our next release.&amp;nbsp; We are using this release for feedback from the users out there to find out what works and what doesn&amp;rsquo;t.&amp;nbsp; Several key features are not implemented yet (for example versioning) which we have targeted for an upcoming product release when we finalize the implementation.&lt;/p&gt;

&lt;p&gt;Ok, with that said, now we can get into the details.&lt;/p&gt;

&lt;p&gt;iControl-REST, like it&amp;rsquo;s SOAP counterpart, is implemented on HTTPS and uses the same authentication and authorization roles for user access.&amp;nbsp; We support the following HTTP commands:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;GET - for retrieving (ie. Querying the status of a Pool)&lt;/li&gt;
 &lt;li&gt;POST - for creating (ie. Creating a Pool Member)&lt;/li&gt;
 &lt;li&gt;PUT - for updating (ie. Changing the load balancing method on a Pool)&lt;/li&gt;
 &lt;li&gt;DELETE - for deleting (ie.&amp;nbsp; Deleting a Virtual Server)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And, the format of the requests and responses is &lt;a href="http://en.wikipedia.org/wiki/JSON"&gt;JSON&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;&lt;span style="font-weight: bold;"&gt;Starting the iControl REST Service (icrd)&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;Run the &amp;ldquo;modify sys service icrd&amp;rdquo; TMSH command to add and start the iControl REST service.&amp;nbsp; Notice the nice &amp;ldquo;EA&amp;rdquo; warning.&lt;/p&gt;

&lt;pre&gt;
root@(BIG-IP1)(&amp;hellip;)(tmos) # modify sys service ircd add
WARNING: This early-access feature comes with minimal
documentation and testing.&amp;nbsp; Version control is not implemented;
therefore any scripts that you write using this API version
may not work with subsequent releases.
root@(BIG-IP1)(&amp;hellip;)(tmos) #&lt;/pre&gt;

&lt;p&gt;Once the service is running, you can use the &amp;ldquo;show sys service&amp;rdquo;, &amp;ldquo;stop sys service&amp;rdquo; and &amp;ldquo;start sys service&amp;rdquo; TMSH commands to monitor and control the status of the iControl REST service.&lt;/p&gt;

&lt;h3&gt;&lt;span style="font-weight: bold;"&gt;Writing Your First Script&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;Since iControl-REST is just using HTTPS, you can use any scripting technology you heart desires.&amp;nbsp; For this article, we&amp;rsquo;ll use the command line tool &lt;a href="http://curl.haxx.se/"&gt;cURL&lt;/a&gt;.&amp;nbsp; It&amp;rsquo;s cross platform, so you should be able to wrap a bash script for Unix, Mac, etc or PowerShell for Windows around it very easily.&lt;/p&gt;

&lt;p&gt;Use the &amp;ldquo;-u&amp;rdquo; parameter to pass in the user credentials, the &amp;ldquo;-X&amp;rdquo; parameter to specify the HTTP method, and the uri for the resource you wish to access.&lt;/p&gt;

&lt;pre&gt;
curl -k -u user:pass -X http-method uri&lt;/pre&gt;

&lt;p&gt;The URI format is as follows&lt;/p&gt;

&lt;h4&gt;&lt;span style="font-weight: bold;"&gt;Module URI&lt;/span&gt;&lt;/h4&gt;

&lt;pre&gt;
https://management-ip/mgmt/tm/module&lt;/pre&gt;

&lt;p&gt;This access all of the sub-modules and/or components under the given &lt;em&gt;module&lt;/em&gt; (ltm, gtm, etc).&lt;/p&gt;

&lt;h4&gt;&lt;span style="font-weight: bold;"&gt;Sub-module URI&lt;/span&gt;&lt;/h4&gt;

&lt;pre&gt;
https://management-ip/mgmt/tm/module/sub-module&lt;/pre&gt;

&lt;p&gt;This access all of the sub-modules and/or components under the given sub-module.&lt;/p&gt;

&lt;h4&gt;&lt;span style="font-weight: bold;"&gt;Component URI&lt;/span&gt;&lt;/h4&gt;

&lt;pre&gt;
https://management-ip/mgmt/tm/module[/sub-module]/component&lt;/pre&gt;

&lt;p&gt;This accesses the details about the given component.&amp;nbsp; The tmsh Traffic Management Shell Reference documents the hierarchy of modules and components, and identifies the details of each component.&lt;/p&gt;

&lt;h4&gt;&lt;span style="font-weight: bold;"&gt;Example&lt;/span&gt;&lt;/h4&gt;

&lt;p&gt;This curl command will query all of the information about the ltm module.&lt;/p&gt;

&lt;pre&gt;
$ curl -k -u user:pass -H &amp;ldquo;Content-Type: application/json&amp;rdquo; -X GET https://bigip_ip/mgmt/tm/ltm
{
  &amp;quot;currentItemCount&amp;quot;: 22,
  &amp;quot;items&amp;quot;: [
    {
      &amp;quot;reference&amp;quot;: {
        &amp;quot;link&amp;quot;: &amp;quot;https://bigip_ip/mgmt/tm/ltm/auth&amp;quot;
      }
    },
    {
      &amp;quot;reference&amp;quot;: {
        &amp;quot;link&amp;quot;: &amp;quot;https://bigip_ip/mgmt/tm/ltm/data-group&amp;quot;
      }
    },
    {
      &amp;quot;reference&amp;quot;: {
        &amp;quot;link&amp;quot;: &amp;quot;https://bigip_ip/mgmt/tm/ltm/dns&amp;quot;
      }
    }
    ...
  ],
  &amp;quot;kind&amp;quot;: &amp;quot;tm:ltm:ltmstate&amp;quot;,
  &amp;quot;pageIndex&amp;quot;: 1,
  &amp;quot;partition&amp;quot;: &amp;quot;/Common/&amp;quot;,
  &amp;quot;selfLink&amp;quot;: &amp;quot;https://bigip-ip/mgmt/tm/ltm&amp;quot;,
  &amp;quot;startIndex&amp;quot;: 1,
  &amp;quot;totalItems&amp;quot;: 22,
  &amp;quot;totalPages&amp;quot;: 1
}&lt;/pre&gt;

&lt;h2&gt;&lt;span style="font-weight: bold;"&gt;User Guide&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;For this release, we have provided a User Guide to assist in getting started with using the new REST interface.&amp;nbsp; It can be downloaded from this link:&amp;nbsp; &lt;a href="/d/icontrol-rest-user-guide-version-1150"&gt;iControlRest-UserGuide.pdf&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We would love to hear your feedback on using iControl-REST.&amp;nbsp; Any and all comments and questions should be posted to the &lt;a href="/community/group/aff/1/asg/51"&gt;iControl group&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;-Joe&lt;/p&gt;
</description>
      <pubDate>Thu, 20 Jun 2013 11:30:00 -0700</pubDate>
    </item>
    <item>
      <link>https://devcentral.f5.com/articles/project-acceleration-programmatic-performance-testing-with-httpwatch</link>
      <a10:author>
        <a10:name>Joe Pruitt</a10:name>
        <a10:uri>https://devcentral.f5.com/users/30</a10:uri>
      </a10:author>
      <category>aam</category>
      <category>application delivery</category>
      <category>news</category>
      <category>performance</category>
      <category>project acceleration</category>
      <category>techtip</category>
      <title>Project Acceleration: Programmatic Performance Testing with HTTPWatch</title>
      <description>&lt;!-- Injected Syntax Highlight Code --&gt;&lt;script type="text/javascript" src="/Providers/HtmlEditorProviders/CKEditor/plugins/syntaxhighlight/scripts/shCore.js"&gt;&lt;/script&gt;&lt;link type="text/css" rel="stylesheet" href="/Providers/HtmlEditorProviders/CKEditor/plugins/syntaxhighlight/styles/shCore.css"/&gt;&lt;script type="text/javascript"&gt;SyntaxHighlighter.all();&lt;/script&gt;&lt;p&gt;&lt;strong&gt;Note: As of 11.4, WebAccelerator is now a part of BIG-IP Application Acceleration Manager.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is article nine of ten in a series on DevCentral&amp;rsquo;s implementation of WebAccelerator. Join Colin Walker and product manager Dawn Parzych as they discuss the ins and outs of WebAccelerator. Colin discusses his take on implementing the technology first hand (with an appearance each from Jason Rahm and Joe Pruitt) while Dawn provides industry insight and commentary on the need for various optimization features.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/project-acceleration-the-basics"&gt;Part 1 - The Basics&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/project-acceleration-tcp-optimization-and-compression"&gt;Part 2 - TCP Optimization &amp;amp; Compression&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/project-acceleration-webaccelerator-building-blocks"&gt;Part 3 - WebAccelerator Building Blocks&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/project-acceleration-webaccelerator-intelligent-browser-referencing"&gt;Part 4 - Intelligent Browser Referencing&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/project-acceleration-webaccelerator-image-optimization"&gt;Part 5 - Image Optimization&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/project-acceleration-webaccelerator-content-reordering"&gt;Part 6 - Content Reordering&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/project-acceleration-webaccelerator-tips-tricks-and-gotchas"&gt;Part 7 - Tips, Tricks, &amp;amp; Gotchas&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/project-acceleration-test-infrastructure"&gt;Part 8 - Test Infastructure&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/project-acceleration-programmatic-performance-testing-with-httpwatch"&gt;Part 9 - Programmatic Performance Testing with HTTPWatch&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="https://devcentral.f5.com/articles/project-acceleration-conclusions"&gt;Part 10 - Conclusions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;In a recent performance project, I was asked to come up with a way to automate the page-level metric collection for various optimization profiles we were testing on DevCentral.&amp;nbsp; The idea is that we would like to come up with a simple way to compare the many performance settings side-by-side and, hopefully, give us a better view as to which would benefit the end users who are accessing the site.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ve done some automation work with &lt;a href="http://www.httpwatch.com/"&gt;HttpWatch&lt;/a&gt; in the past, so I thought that would be a good starting point.&amp;nbsp; I&amp;rsquo;ve blogged in the past about the HttpWatch COM interface in Windows, but I will give a little refresher again to give some context to the work done in this script.&lt;/p&gt;

&lt;div class="alert alert-info"&gt;
&lt;h4&gt;Dawn Says...&lt;/h4&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;img align="left" alt="" src="/profilepic.ashx?userid=20&amp;amp;w=90&amp;amp;h=90" style="margin: 10px; display: inline; float: left;" /&gt;There is a specific process that needs to be followed to get accurate, actionable metrics in relation to web page performance. It can be a very time consuming process and is prone to errors. Generally speaking you want to run a minimum of 3 test runs for each scenario and take an average of the 3. My preference is to run 10 test runs but time typically doesn&amp;rsquo;t allow for that. If you are running 4 scenarios and need to run a minimum of 3 times that is at least 12 test runs. Unfortunately I don&amp;rsquo;t think I have ever been able to run just 12 as I always make mistakes. Take the scenario of running as a first time user with a clean cache. For every test run you need to open the browser, clear the cache, launch a measurement tool of some kind like HttpWatch, access the page, save the report and close the browser. Then repeat. Mistakes that are common to make in this process (at least I pretend they are common so I don&amp;rsquo;t feel like I&amp;rsquo;m the only one that does this).&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;Forgetting to clear the cache when running as a first time user. I see the objects being returned with a response code of &amp;ldquo;Cache&amp;rdquo; and I want to scream.&lt;/li&gt;
 &lt;li&gt;Loading the page before starting to record with the measurement.&lt;/li&gt;
 &lt;li&gt;Closing the browser and forgetting to save the report&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Having a way to automate the process eliminates these mistakes and enables the running of multiple test runs without wasting a lot of time. I would much rather go get a cup of tea come back and have all my testing completed.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;I chose to implement the solution in PowerShell as that gave me an easy way to interact with the &lt;a href="http://apihelp.httpwatch.com/#Automation%20Overview.html"&gt;HttpWatch COM object&lt;/a&gt; from a scripting environment available on all recent versions of Windows.&lt;/p&gt;

&lt;h3&gt;&lt;span style="font-weight: bold;"&gt;Script Requirements&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;My colleague that offered this great opportunity to me, supplied me with the following functional steps that needed to occur&lt;/p&gt;

&lt;p&gt;Baseline: VIP:w1.x1.y1.z1; Domain:devcentral.f5.com; URL: /&lt;/p&gt;

&lt;p&gt;1. Test Initial Visits&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Empty browser cache&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Access test page with an empty cache&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Record time and data transfer metrics&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Close browser&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Repeat &amp;ldquo;x&amp;rdquo; number of times and calculate averages&lt;/p&gt;

&lt;p&gt;2. Test Repeat visits&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Reopen browser&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Access page as repeat visitor&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Record time and data transfer metrics&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Close browser&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Repeat &amp;ldquo;x&amp;rdquo; number of times and calculate averages&lt;/p&gt;

&lt;p&gt;Optimization: VIP:w2,x2,y2,z2; Domain:devcentral.f5.com: URLs:/tcp, /compress, /ibr, /img&lt;/p&gt;

&lt;p&gt;1. Repeat baseline logic for each URL.&lt;/p&gt;

&lt;p&gt;To allow for us to dynamically change optimization profiles for a given connection, we implemented a nifty bit of iRules that would trap the &amp;ldquo;/tcp&amp;rdquo;, &amp;ldquo;/compress&amp;rdquo;, &amp;ldquo;/ibr&amp;rdquo;, and &amp;ldquo;/img&amp;rdquo; URLs and issue a HTTP 301 redirect to the test page along with a cookie containing the corresponding BIG-IP profile to apply. An iRule sitting in front of the site looked for that cookie and then enabled the associated profile.&amp;nbsp; The optimization requests then contained one more request (the 301 redirect) that will need to be accounted for and subtracted from the totals (more on that later).&lt;/p&gt;

&lt;h3&gt;&lt;span style="font-weight: bold;"&gt;HttpWatch.Controller&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;The core object is the &lt;strong&gt;HttpWatch.Controller&lt;/strong&gt;.&amp;nbsp; It contains the following members:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;strong&gt;FireFox&lt;/strong&gt; &amp;ndash;Returns a reference to the FireFox object.&amp;nbsp; Use this property if you want to be using FireFox in your testing.&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;IE&lt;/strong&gt; &amp;ndash; Returns a reference to the Internet Explorere object.&amp;nbsp; Use this property if you want to use IE for your testing.&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;IsBasicEdition &lt;/strong&gt;&amp;ndash; Returns true if the product is the basic edition, false for Pro.&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;OpenLog&lt;/strong&gt;(logFileName) &amp;ndash; This allows existing HttpWatch log files to be opened and examined using the automation library.&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;Wait&lt;/strong&gt;(plugIn, timeOutSecs) &amp;ndash; Wait for a page to be fully loaded and is normally used after the GotoURL method.&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;Version &lt;/strong&gt;&amp;ndash; A string containing the current version of HttpWatch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The PowerShell code to create this object looks something like this.&lt;/p&gt;

&lt;pre class="brush: powershell"&gt;
$script:HTTPWATCH = New-Object -ComObject &amp;ldquo;HttpWatch.Controller&amp;rdquo;;&lt;/pre&gt;

&lt;p&gt;And by accessing the &lt;em&gt;FireFox.New(),&lt;/em&gt; or &lt;em&gt;IE.New()&lt;/em&gt; methods, you&amp;rsquo;ll now have access to control the HttpWatch interface.&amp;nbsp; For more info on the HttpWatch API, check out the &lt;a href="http://apihelp.httpwatch.com/#Automation%20Overview.html"&gt;HttpWatch Automation Overview&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;&lt;span style="font-weight: bold;"&gt;Main Application Logic&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;The script takes in the following parameters&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;strong&gt;num_retries&lt;/strong&gt; - the number of times to perform each test for averages&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;browser &lt;/strong&gt;- use &amp;ldquo;ff&amp;rdquo; for FireFox, or &amp;ldquo;ie&amp;rdquo; for Internet Explorer.&amp;nbsp; The default is &amp;ldquo;ff&amp;rdquo;&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;WA &lt;/strong&gt;- an optional switch to determine whether the script is run on the regular site or optimization profiles.&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;SubtractRedirects &lt;/strong&gt;- If supplied, this parameter will cause the 301 redirects mentioned above to be subtracted from the metrics on the optimization tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="brush: powershell"&gt;
param(
  $num_retries = 5,
  $browser = &amp;quot;ff&amp;quot;,
  [switch]$WA = $false,
  [switch]$SubtractRedirects = $False
);

$script:SUBTRACT_REDIRECTS = $SubtractRedirects;
$script:LOGDIR = &amp;quot;$(Split-Path $MyInvocation.MyCommand.Path)\WATests&amp;quot;;
if ( -not [System.IO.Directory]::Exists($script:LOGDIR) ) { mkdir $script:LOGDIR; }

$script:HTTPWATCH =  New-Object -ComObject &amp;quot;HttpWatch.Controller&amp;quot;;

#----------------------------------------------------------------------------
# Main App Logic
#----------------------------------------------------------------------------

$tests = @(&amp;quot;/&amp;quot;);
if ( $WA )
{
  $tests = @(&amp;quot;/tcp&amp;quot;, &amp;quot;/compress&amp;quot;, &amp;quot;/ibr&amp;quot;, &amp;quot;/img&amp;quot;);
}
$results = Do-DCPerfTest -num_retries $num_retries -browser $browser -tests $tests;
Run-Report.CSV -results $results;
&lt;/pre&gt;

&lt;h3&gt;&lt;span style="font-weight: bold;"&gt;Functional Test Logic&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;The Do-DCPerfTest() function performs various tests with the specified number of retries.&amp;nbsp; The difference between initial and return visits is the clearing cache step performed for the initial visits.&lt;/p&gt;

&lt;pre class="brush: powershell"&gt;
function Do-DCPerfTest()
{
  param(
    $num_retries = 5,
    $browser = &amp;quot;ff&amp;quot;,
    $tests = @(&amp;quot;/&amp;quot;)
  );
  
  $results = @();
  
  foreach( $test in $tests )
  {
    Write-Host &amp;quot;------------------------------------------------------------&amp;quot;;
    Write-Host &amp;quot;- Testing https://devcentral.f5.com${test} initial visit&amp;quot;;
    Write-Host &amp;quot;------------------------------------------------------------&amp;quot;;
    
    for($i=0; $i -lt $num_retries; $i++)
    {
      Clear-BrowserCache -browser $browser;
      
      $plugin = New-Plugin;
      $results += Run-TimingTest -plugin $plugin -domain &amp;quot;devcentral.f5.com&amp;quot; -url $test -index $i -note &amp;quot;I&amp;quot;;
      $plugin.CloseBrowser();
    }

    Write-Host &amp;quot;------------------------------------------------------------&amp;quot;;
    Write-Host &amp;quot;- Testing https://devcentral.f5.com${test} return visitor&amp;quot;;
    Write-Host &amp;quot;------------------------------------------------------------&amp;quot;;
    
    for($i=0; $i -lt $num_retries; $i++)
    {
      $plugin = New-Plugin;
      $results += Run-TimingTest -plugin $plugin -domain &amp;quot;devcentral.f5.com&amp;quot; -url $test -index $i -note &amp;quot;R&amp;quot;;
      $plugin.CloseBrowser();
    }
  }
  
  $results;
}&lt;/pre&gt;

&lt;h3&gt;&lt;span style="font-weight: bold;"&gt;Single Timing Test&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;The Run-TimingTest() function will first clear the HttpWatch internal log, load the URL and wait for the page to render, save the HttpWatch log (.hwl file) locally for future analysis, and then process the logs to build a PowerShell object with the results.&lt;/p&gt;

&lt;pre class="brush: powershell"&gt;
function Run-TimingTest()
{
  param(
    $plugin = $null,
    $domain = $(Throw &amp;quot;domain required!&amp;quot;),
    $url = $(Throw &amp;quot;url required!&amp;quot;),
    $index = &amp;quot;&amp;quot;,
    $note = &amp;quot;&amp;quot;,
    $is_redirect = $null
  );
  
  $results = @();
  if ( $null -ne $plugin )
  {
    Write-Host &amp;quot;Clearing HttpWatch Log...&amp;quot;;
    $plugin.Clear();
  
    # Load the url
    Load-WebPage -plugin $plugin -url &amp;quot;https://${domain}${url}&amp;quot;;

    # save logs
    $ip = Get-IPFromHostname -hostname $domain;
    
    $logname = &amp;quot;${ip}-${domain}-${url}-${note}-${index}&amp;quot;.Replace(&amp;quot;/&amp;quot;, &amp;quot;&amp;quot;);
    $log = &amp;quot;$($script:LOGDIR)\${logname}.hwl&amp;quot;;
    Write-Host &amp;quot;Saving log &amp;#39;$logname&amp;#39;&amp;quot;;
    $plugin.Log.Save($log);

    # Process logs
    $results += Process-Logs -plugin $plugin -note &amp;quot;${logname}&amp;quot;;

    Write-Host &amp;quot;Clearing HttpWatch Log...&amp;quot;;
    $plugin.Clear();
  }
  $results;
}&lt;/pre&gt;

&lt;h3&gt;&lt;span style="font-weight: bold;"&gt;Controlling HttpWatch&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;New-Plugin()&lt;/strong&gt; function will use the HttpWatch Controller to instantiate a new instance of the plugin for the given browser.&amp;nbsp; The instance of that plugin is returned to the calling code.&lt;/p&gt;

&lt;pre class="brush: powershell"&gt;
function New-Plugin()
{
  param($browser = &amp;quot;ff&amp;quot;);
  
  $plugin = $null;
  
  if ( $browser = &amp;quot;ff&amp;quot; ) { $plugin = $script:HTTPWATCH.FireFox.New(); }
  else { $plugin = $script:HTTPWATCH.IE.New(); }

  $plugin;
}&lt;/pre&gt;

&lt;p&gt;For this test, we wanted to isolate any issues of caching between plugin sessions, so we opted to have new plugins created for each functional step.&amp;nbsp; This forced a refresh of the plugin and browser objects.&amp;nbsp; The &lt;strong&gt;Clear-BrowserCache()&lt;/strong&gt; function creates a new plugin instance, Clears the browsers cache with the &lt;em&gt;plugin.ClearCache()&lt;/em&gt; method and then closes the browser with the &lt;em&gt;plugin.CloseBrowser()&lt;/em&gt; method.&lt;/p&gt;

&lt;pre class="brush: powershell"&gt;
function Clear-BrowserCache()
{
  param($plugin = &amp;quot;ff&amp;quot;);
  
  $plugin = New-Plugin -browser $browser;
  if ( $null -ne $plugin )
  {
    Write-Host &amp;quot;Clearing browser cache...&amp;quot;;
    $plugin.ClearCache();
    $plugin.CloseBrowser();
  }
}&lt;/pre&gt;

&lt;p&gt;The &lt;strong&gt;Load-WebPage()&lt;/strong&gt; function first initiates a transport level recording with the plugin.Record() method.&amp;nbsp; It then calls the asynchronous&lt;em&gt; plugin.GotoURL()&lt;/em&gt; method and waits for that load to complete with the &lt;em&gt;plugin.WaitEx()&lt;/em&gt; method.&amp;nbsp; Recording is then stopped with the&lt;em&gt; plugin.Stop()&lt;/em&gt; method and control is returned back to the calling code.&lt;/p&gt;

&lt;pre class="brush: powershell"&gt;
function Load-WebPage()
{
  param(
    $plugin = $(Throw &amp;quot;Plugin parameter required!&amp;quot;),
    $url = $(Throw &amp;quot;url parameter required!&amp;quot;),
    [switch]$ClearCache = $false
  );
  
  if ( $null -ne $plugin )
  {
    if ( $ClearCache )
    {
      $plugin.ClearCache();
    }

    Write-Host &amp;quot;Loading page &amp;#39;${url}&amp;#39;...&amp;quot;;
    $plugin.Record();
    $plugin.GotoURL($url);
    #$HttpWatch.Wait($plugin, -1) | Out-Null;
    $wait = $script:HTTPWATCH.WaitEx($plugin, -1, $true, $false, 1);
    $plugin.Stop();
  }
}&lt;/pre&gt;

&lt;p&gt;The last piece of the puzzle is processing the HttpWatch log, that is captured during the page load, and extracting all the required data.&amp;nbsp; There is a lot going on here but are the main things to look at&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;strong&gt;$plugin.Log&lt;/strong&gt; - This is where all the log data is stored from recording start to stop.&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;$plugin.Log.Pages&lt;/strong&gt; - Each URL loaded with the GotoURL() method, will get it&amp;rsquo;s own Page item.&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;$plugin.Log.Pages.Item(0)&lt;/strong&gt; - There was only one URL loaded so I&amp;rsquo;ll look at the first Page only.&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;$plugin.Log.Pages.Item(0).Events&lt;/strong&gt; - Some aggregate data for the page including DOMLoad, PageLoad, HTTPLoad, and RenderStart times.&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;$plugin.Log.Pages.Item(0).Entries&lt;/strong&gt; - This is a list of all the items requested for the given GotoURL request.&amp;nbsp; This includes redirects, embedded images, scripts, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you get those items down, the &lt;strong&gt;Process-Logs()&lt;/strong&gt; function should hopefully make sense.&lt;/p&gt;

&lt;pre class="brush: powershell"&gt;
function Process-Logs()
{
  param(
    $plugin = $null,
    $note = &amp;quot;&amp;quot;
  );
  
  $page = $plugin.Log.Pages.Item(0)
  
  $summary = $page.Entries.Summary;
  $events = $page.Events;
  $entry = $page.Entries.Item(0);
  
  $url = $entry.URL;
  $redirectTime = 0;
  $redirectBytesSent = 0;
  $redirectBytesReceived = 0;
  $redirectRoundtrips = 0;
  
  if ( $entry.IsRedirect -eq $true )
  {
    $url += &amp;quot; -&amp;gt; &amp;quot;;
    $url += $entry.RedirectURL;
    $redirectTime = $entry.Time;
    $redirectBytesSent = $entry.BytesSent;
    $redirectBytesReceived = $entry.BytesReceived;
    $redirectRoundTrips = 1;
  }
  
  $DOMLoad = $events.DOMLoad.value;
  $PageLoad = $events.PageLoad.value;
  $HTTPLoad = $events.HTTPLoad.value;
  $RenderStart = $events.RenderStart.value;
  
  $roundTrips = $summary.RoundTrips;
  $bytesReceived = $summary.BytesReceived;
  
  if ( $script:SUBTRACT_REDIRECTS )
  {
    $PageLoad -= $redirectTime;
    $HTTPLoad -= $redirectTime;
    $roundTrips -= $redirectRoundTrips;
    $bytesReceived -= $redirectBytesReceived;
  }
  
  $compressionSavedBytes = $summary.CompressionSavedBytes
  
  Write-Host &amp;quot;TIMING: $note - rt: $RoundTrips; pl: $PageLoad&amp;quot;;
  
  $o = 1 | select Note, URL, RenderStart, PageLoad, HTTPLoad, BytesReceived, CompressionSavedBytes, RoundTrips, RedirectTime
  $o.Note = $note;
  $o.URL = $url;
  $o.RenderStart = $RenderStart;
  $o.PageLoad = $PageLoad;
  $o.HTTPLoad = $HTTPLoad;
  $o.BytesReceived = $bytesReceived;
  $o.CompressionSavedBytes = $compressionSavedBytes;
  $o.RoundTrips = $roundTrips;
  $o.RedirectTime = $redirectTime;
  $o;
}&lt;/pre&gt;

&lt;h3&gt;&lt;span style="font-weight: bold;"&gt;Running the Script&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;Since the requirements called for different IP addresses for the two virtuals, I had to make a host entry before each run of the script to make sure that the browser was going to the correct VIP.&lt;/p&gt;

&lt;pre class="brush: powershell"&gt;
#for VIP 1 (substitute w.x.y.z for real IP address)
w1.x1.y1.z1 devcentral.f5.com
#for VIP 2
w2.x2.y2.z2 devcentral.f5.com
&lt;/pre&gt;

&lt;p&gt;Then the script can be run like the following:&lt;/p&gt;

&lt;pre class="brush: powershell"&gt;
PS&amp;gt; # Change IP Address to VIP 1
PS&amp;gt; .\DC-WATest.ps1 &amp;gt; results.csv
PS&amp;gt; # Change IP address to VIP 2
PS&amp;gt; .\DC-WAText.ps1 -WA &amp;gt;&amp;gt; results.csv
PS&amp;gt; type results.csv
BytesReceived,CompressionSavedBytes,HTTPLoad,Note,PageLoad,RedirectTime,RenderStart,RoundTrips,URL
1519542,467368,4.713,w1.x1.y1.z1-devcentral.f5.com--I-0,4.716,0,1.046,54,https://devcentral.f5.com/
1514991,467368,4.432,w1.x1.y1.z1-devcentral.f5.com--I-1,4.435,0,1.044,54,https://devcentral.f5.com/
1515020,467368,4.548,w1.x1.y1.z1-devcentral.f5.com--I-2,4.55,0,1.051,54,https://devcentral.f5.com/
...
BytesReceived,CompressionSavedBytes,HTTPLoad,Note,PageLoad,RedirectTime,RenderStart,RoundTrips,URL
1350376,637177,5.378,w2.x2.y2.z2-devcentral.f5.com-tcp-I-0,5.381,0.555,1.06,54,https://devcentral.f5.com/tcp -&amp;gt; https://devcentral.f5.com/
1345751,637177,4.401,w2.x2.y2.z2-devcentral.f5.com-tcp-I-1,4.403,0.637,1.171,54,https://devcentral.f5.com/tcp -&amp;gt; https://devcentral.f5.com/
1345662,637177,4.538,w2.x2.y2.z2-devcentral.f5.com-tcp-I-2,4.54,0.606,1.155,54,https://devcentral.f5.com/tcp -&amp;gt; https://devcentral.f5.com/
...
&lt;/pre&gt;

&lt;p&gt;The raw data can then be imported into a spreadsheet and processed to determine the overall effectiveness of the various optimization profiles.&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;HttpWatch proves to be a very valuable tool to integrate into your automation and monitoring environments.&amp;nbsp; For more information on HttpWatch go to their &lt;a href="http://www.httpwatch.com/"&gt;httpwatch.com&lt;/a&gt;.&amp;nbsp; The documentation for their Automation interface is located at the &lt;a href="http://apihelp.httpwatch.com/#Automation%20Overview.html"&gt;HttpWatch Automation Overview &lt;/a&gt;site.&lt;/p&gt;

&lt;h3&gt;&lt;span style="font-weight: bold;"&gt;Source Code&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;The full source for this script can be found in the &lt;a href="/wiki/AdvDesignConfig.HomePage.ashx"&gt;Advanced Design and Config wiki&lt;/a&gt; under &amp;ldquo;&lt;a href="/wiki/AdvDesignConfig.Programmatic-Performance-Testing-With-HttpWatch.ashx"&gt;Programmatic Performance Testing with HttpWatch&lt;/a&gt;&amp;rdquo;.&lt;/p&gt;

&lt;div class="d_itc_f" style="height: 11px; clear: both;"&gt;&amp;nbsp;&lt;/div&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;link href="/Providers/HtmlEditorProviders/CKEditor/plugins/syntaxhighlight/styles/shCore.css" rel="stylesheet" type="text/css" /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
</description>
      <pubDate>Tue, 09 Apr 2013 06:00:00 -0700</pubDate>
    </item>
  </channel>
</rss>