{"id":330,"date":"2013-01-04T06:43:42","date_gmt":"2013-01-04T06:43:42","guid":{"rendered":"http:\/\/corneliadavis.com\/blog\/?p=330"},"modified":"2013-01-04T06:43:42","modified_gmt":"2013-01-04T06:43:42","slug":"learning-how-to-add-services-to-cloud-foundry","status":"publish","type":"post","link":"https:\/\/corneliadavis.com\/blog\/2013\/01\/04\/learning-how-to-add-services-to-cloud-foundry\/","title":{"rendered":"Learning how to add services to Cloud Foundry"},"content":{"rendered":"<p>There are a lot of things we want to do with Cloud Foundry, at the moment we are focusing on adding services such as Cassandra.\u00a0 We\u2019ve been studying the code for existing Cloud Foundry services (i.e. Postgres) and we\u2019ve deployed the sample Echo service, a couple of times.\u00a0 This was a pretty significant investment that is now set to pay off as we really feel like we know how to tackle the problem.\u00a0 What I\u2019m going to do in a series of posts is first (in this post) update the instructions you can find <a href=\"http:\/\/support.cloudfoundry.com\/entries\/20485171-how-to-add-a-system-service-to-oss-cloud-foundry-step-by-step-guide\">here<\/a> on deploying the Echo service to a non-BOSH based deployment of Cloud Foundry, second more fully explain what the Echo service and client are doing and clarify what the various components are, and third, detail what we did to get things running in a BOSH-based Cloud Foundry deployment. \u00a0This mirrors the progression of our investigative work and I hope you might find it useful.<\/p>\n<p>There are two versions of a guide on deploying the Echo service (and a client app utilizing it) \u2013 <a href=\"http:\/\/support.cloudfoundry.com\/entries\/20485171-how-to-add-a-system-service-to-oss-cloud-foundry-step-by-step-guide\">one on the support site<\/a> and<a href=\"https:\/\/github.com\/cloudfoundry\/oss-docs\/tree\/master\/vcap\/adding_a_system_service\"> another in github<\/a>. They differ slightly but both are about the same vintage (September 2011) and a bit out of date with the current Cloud Foundry code.\u00a0 Also, I had to make some changes to the Echo service itself to get things running.\u00a0 Here are the details \u2013 I\u2019ll generally work from the version that is on the support site:<\/p>\n<h1>Create Single Node Cloud Foundry Instance<\/h1>\n<p>First things first, I did this deployment of Echo to a single-node Cloud Foundry instance that I installed using<a href=\"https:\/\/github.com\/cloudfoundry\/vcap\"> these instructions<\/a> (as a services developer, <a href=\"http:\/\/corneliadavis.com\/blog\/2012\/11\/29\/customizing-micro-cloud-foundry\/\">micro-cloud foundry is NOT the local cloud solution<\/a>).\u00a0 I started with the Ubuntu 10.04 <span style=\"text-decoration: underline;\">desktop<\/span> image simply because I have been spending a fair bit of time poking around the contents of Cloud Foundry files and doing so with multiple windows is nice; you could also use the server version . The Cloud Foundry install went pretty smoothly, though I did have to restart it once because one of the required resources wasn\u2019t accessible (reported \u201cCould not reach http:\/\/rubygems.org\/\u201d) the first time through; that is,\u00a0 after\u00a0 seeing an error, I simply executed the following command again and things continued to a successful install.<\/p>\n<pre><code>bash &lt; &lt;(curl -s -k -B https:\/\/raw.github.com\/cloudfoundry\/vcap\/master\/dev_setup\/bin\/vcap_dev_setup)<\/code><\/pre>\n<p>Do a quick check to make sure it\u2019s all installed and working properly \u2013 start the server (step 3 in the instructions) and push an app \u2013 something like <a href=\"http:\/\/docs.cloudfoundry.com\/tools\/vmc\/installing-vmc.html#creating-a-simple-sinatra-application\">this one<\/a><a href=\"http:\/\/docs.cloudfoundry.com\/tools\/vmc\/installing-vmc.html#creating-a-simple-sinatra-application\"><\/a> is super simple.<\/p>\n<p><span style=\"text-decoration: underline;\">Make a snapshot of your image now.<\/span><\/p>\n<h1>Adding Echo<\/h1>\n<p>I\u2019ll go into more details in the second part of this blog series, but there are three pieces to the Echo service; the echo gateway, which services provisioning requests (i.e. as a part of a push), the echo node, which does the actual work of provisioning the service, and the service itself.\u00a0 All three are covered in the original doc, but it\u2019s not entirely clear what is happening where \u2013 I\u2019ll try to crisp that up a bit here.<\/p>\n<h2>Echo Node and Echo Gateway<\/h2>\n<p>In the original doc, this is what is happening in steps 1-8 \u2013 here are my updates to those steps:<\/p>\n<p><strong>Step 1<\/strong>: Do just what they say. One thing to note, however, is that when you are adding your own service, not echo, to a non-BOSH based cloud this will not be enough.\u00a0 There is an innocuous little piece of the cloud foundry code base (I would call this a bug, but it\u2019s an engineered bug) that has service names hard coded in it.\u00a0 At <a href=\"https:\/\/github.com\/cloudfoundry\/vcap\/blob\/master\/dev_setup\/lib\/vcap_components.rb#L399\">https:\/\/github.com\/cloudfoundry\/vcap\/blob\/master\/dev_setup\/lib\/vcap_components.rb#L399<\/a> (and a few more lines below it) you\u2019ll see that there is a list of services \u2013 and you\u2019ll note that echo is already in that list; that is, echo is already sort-of included in the base cloud foundry vcap code base.\u00a0 If you are starting with something net-new, this is one place you will also have to make changes.\u00a0 I\u2019ll try to get to a separate post on this little gem, but in short, the names included in this list are used in the directory paths to the node and gateway bits of the service \u2013 that is how start and stop scripts are found, for example.<\/p>\n<p>The good news is that this engineered bug is gone in BOSH-based deployments of cloud foundry.\u00a0 Makes sense, BOSH is concerned with the components of the deployment, cloud foundry itself no longer is.\u00a0 More on that in part III.<\/p>\n<p><strong>Steps 2 and 3<\/strong>: Do them just as described, though the lines for step 3 are already present in that file when cloud foundry is installed.<\/p>\n<p><strong>Step 4 is no longer needed<\/strong>.\u00a0 In fact, the bin\/services directory no longer exists in the current version of cloud foundry vcap.\u00a0 These files were the executables for the service gateway and service node and were just proxies for the files that held the real startup details.\u00a0 It looks like the startup mechanism changed from earlier versions.\u00a0 Now, the aforementioned vcap_components.rb file has encoded into it THE place that the executables for the node and gateway are to be placed \u2013 convention over configuration!\u00a0 That convention is as follows: Given the &lt;name&gt; of a service the node and gateway executables are placed as follows:<\/p>\n<pre><code>...\/cloudfoundry\/vcap\/services\/&lt;name&gt;\/bin\/&lt;name&gt;_node\n...\/cloudfoundry\/vcap\/services\/&lt;name&gt;\/bin\/&lt;name&gt;_gateway<\/code><\/pre>\n<p><strong>Step 5<\/strong>: This step involves two things 1) dropping the node and gateway implementations in the right location and 2) configuring them appropriately.<\/p>\n<p>As I already mentioned, the echo service is mostly already included in the cloud foundry vcap code base so the first part already done for you.\u00a0 I took a close look at the implementation that is in the vcap repository and compared it to that which is in the echo_sp.zip file linked from the original article, and it looks to me like the code that is part of vcap is more up to date.<\/p>\n<p>For configuration, you are first instructed to copy the echo_node.yml and echo_gateway.yml files from the &#8230;\/cloudfoundry\/vcap\/services\/echo\/config directory to the &#8230;\/cloudfoundry\/.deployments\/devbox\/config directory.\u00a0 While this step isn\u2019t absolutely essential because on startup if the .yml file isn\u2019t found in the latter location it will search the former, making the copy begins to give you an idea of how a BOSH deployment handles this \u2013 think of the copies under vcap&#8230; as a template that is instantiated into the .deployments&#8230; location; more on this is part III.<\/p>\n<p>When you are editing the yml files in the .deployment&#8230; directory, the instructions are quite out of date \u2013 there are more required properties for those components than there were a bit more than a year ago; even the .yml files for echo that are part of the vcap source (which is what we are using) are not up to date.\u00a0 The echo_gateway.yml should read:<\/p>\n<pre><code>---\ncloud_controller_uri: api.vcap.me\nservice:\n  name: echo\n  version: \"1.0\"\n  description: 'Echo service'\n  plans: ['free']\n  default_plan: free\n  tags: ['echo', 'echo-1.0', 'echobased', 'demo']\n  timeout: 15\n  supported_versions: ['1.0']\n  version_aliases:\n    \"current\" : \"1.0\"\nip_route: localhost\nindex: 0\ntoken: changeechotoken\nlogging:\n  level: debug\nmbus: nats:\/\/nats:nats@&lt;nats_host&gt;:&lt;nats_port&gt;\/\npid: \/var\/vcap\/sys\/run\/echo_service.pid\nnode_timeout: 2<\/code><\/pre>\n<p>And the echo_node.yml should read:<\/p>\n<pre><code>---\nplan: free\ncapacity: 100\nlocal_db: sqlite3:\/var\/vcap\/services\/echo\/echo_node.db\nmbus: nats:\/\/nats:nats@:&lt;nats_host&gt;:&lt;nats_port&gt;\/\nbase_dir: \/var\/vcap\/services\/echo\/\nindex: 0\nlogging:\n  level: debug\npid: \/var\/vcap\/sys\/run\/echo_node.pid\nnode_id: echo_node_1\nport: 5002\nhost: &lt;host_ip_address&gt;\nsupported_versions: [\"1.0\"]\ndefault_version: \"1.0\"<\/code><\/pre>\n<p>Note the comment in the original instructions that indicates a preference for IP addresses.\u00a0 Hint \u2013 have a look at one of the other service _node.yml or _gateway.yml files and grab the mbus value from there.<\/p>\n<p><strong>Steps 6 &amp; 7<\/strong>: Exactly as written in the original<\/p>\n<p>A this point you have the echo_node and echo_gateway running, BUT the actual echo service is not yet running.<\/p>\n<h2>Echo Service<\/h2>\n<p>The echo service is a very simple java program that simply starts listening over sockets on the port you supply as a command line argument.\u00a0 In the original instructions this was the very last step (I thought it a bit odd that the instructions had you push an app before the service was available &#8211; it&#8217;s okay, but a bit odd) \u2013 that is, step 3 in the section on \u201cConsuming the echo service\u201d (again, a misleading title as only steps 1 &amp; 2 are part of the consumption; step 3 provides the service).<\/p>\n<p>I wasn\u2019t able to get the ssh tunneling (step 4 in the cloud foundry vcap installation instructions) working on my machine, instead I put entries for *.vcap.me in my dev VM hosts file, so I had to modify the Echo service to open the socket on my IP address of 192.168.1.xxx instead of on 127.0.0.1.\u00a0 More details to follow in part II of this series.<\/p>\n<p>But then I started the service with:<\/p>\n<pre>java \u2013jar echo_service.jar \u2013port 5002<\/pre>\n<h2>Echo App<\/h2>\n<p>Okay, so now we are ready to deploy an application that consumes this service.\u00a0 The original instructions have you do it in two steps, provisioning a service and then binding it to an application during the push.\u00a0 You can do all of this during the app push.\u00a0 The app.war posted with the original article works fine, provided you have everything configured properly; if not, you\u2019ll probably get a stack trace (again, I\u2019ll cover this in the second part of this series).\u00a0 A couple of things to be careful of while you are doing the push.<\/p>\n<ol>\n<li>Choose java, not java7 for the java version \u2013 the app is complied with 1.6.<\/li>\n<li>When you provision the echo service, make sure to use the name myecho for the name of the instantiated service.<\/li>\n<\/ol>\n<p><a href=\"https:\/\/i0.wp.com\/corneliadavis.com\/blog\/wp-content\/uploads\/2013\/01\/DeployEchoClient1.jpg\"><img data-recalc-dims=\"1\" decoding=\"async\" loading=\"lazy\" class=\"alignnone size-thumbnail wp-image-333\" title=\"DeployEchoClient\" src=\"https:\/\/i0.wp.com\/corneliadavis.com\/blog\/wp-content\/uploads\/2013\/01\/DeployEchoClient1-150x150.jpg?resize=150%2C150\" alt=\"\" width=\"150\" height=\"150\" \/><\/a><\/p>\n<p>And that should do it &#8211; browse to echotest.vcap.me and give it a shot.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are a lot of things we want to do with Cloud Foundry, at the moment we are focusing on adding services such as Cassandra.\u00a0 We\u2019ve been studying the code for existing Cloud Foundry services (i.e. Postgres) and we\u2019ve deployed the sample Echo service, a couple of times.\u00a0 This was a pretty significant investment that [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[13,21],"tags":[53],"class_list":["post-330","post","type-post","status-publish","format-standard","hentry","category-howto","category-paas","tag-cloudfoundry"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/posts\/330","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/comments?post=330"}],"version-history":[{"count":0,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/posts\/330\/revisions"}],"wp:attachment":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/media?parent=330"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/categories?post=330"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/tags?post=330"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}