{"action":"created","comment":{"url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/pulls/comments/30194034","id":30194034,"diff_hunk":"@@ -0,0 +1,325 @@\n+============================================\n+Batch Data Processing in CDAP using Workflow\n+============================================\n+\n+The Workflow system in `Cask Data Application Platform (CDAP) <http://cdap.io>`__\n+allows specifying, executing, scheduling, and monitoring complex series of jobs\n+and tasks. In this guide, you will learn how it can facilitate the execution of\n+`MapReduce <http://research.google.com/archive/mapreduce.html>`__\n+programs in parallel based on the evaluation of the boolean predicate.\n+\n+What You Will Build\n+===================\n+\n+This guide will take you through building a\n+`CDAP application <http://docs.cdap.io/cdap/current/en/developers-manual/building-blocks/applications.html>`__\n+that uses ingested raw purchase events (of the form '<name> bought <n> <items> for $<price>') to compute\n+the total purchases made by user along with the total purchases made for the particular product.\n+\n+You will:\n+\n+- Build ``PurchaseEventParser``, a\n+  `MapReduce program <http://docs.cdap.io/cdap/current/en/developers-manual/building-blocks/mapreduce-programs.html>`__\n+  to parse the raw purchase events and create ``Purchase`` objects for them;\n+- Build ``PurchaseCounterByUser``, a\n+  `MapReduce program <http://docs.cdap.io/cdap/current/en/developers-manual/building-blocks/mapreduce-programs.html>`__\n+  to count the purchases made per user;\n+- Build ``PurchaseCounterByProduct``, a\n+  `MapReduce program <http://docs.cdap.io/cdap/current/en/developers-manual/building-blocks/mapreduce-programs.html>`__\n+  to count the purchases made per product;\n+- Build ``PurchaseWorkflow``, a\n+  `Workflow program <http://docs.cdap.io/cdap/current/en/developers-manual/building-blocks/workflows.html>`__\n+  which will first execute the MapReduce program ``PurchaseEventParser``. Then if the predicate ``PurchaseEventVerifier``\n+  evaluates to true, will parallely execute the MapReduce programs ``PurchaseCounterByUser`` and\n+  ``PurchaseCounterByProduct``, otherwise it will execute action ``EmailNotifier``;\n+- Use a\n+  `Dataset <http://docs.cdap.io/cdap/current/en/developers-manual/building-blocks/datasets/index.html>`__\n+  to persist results of the MapReduce programs; and\n+- Build a\n+  `Service <http://docs.cdap.io/cdap/current/en/developers-manual/building-blocks/services.html>`__\n+  to serve the results via HTTP.\n+\n+What You Will Need\n+==================\n+\n+- `JDK 7 <http://www.oracle.com/technetwork/java/javase/downloads/index.html>`__\n+- `Apache Maven 3.1+ <http://maven.apache.org/>`__\n+- `CDAP SDK <http://docs.cdap.io/cdap/current/en/developers-manual/getting-started/standalone/index.html>`__\n+\n+Let’s Build It!\n+===============\n+\n+The following sections will guide you through building an application from scratch. If you\n+are interested in deploying and running the application right away, you can clone its\n+source code from this GitHub repository. In that case, feel free to skip the next two\n+sections and jump right to the\n+`Build and Run Application <#build-and-run-application>`__ section.\n+\n+Application Design\n+------------------\n+\n+The application will assume that the purchase events are ingested\n+into a Stream. The events can be ingested into a Stream continuously\n+in realtime or in batches; whichever way, it doesn’t affect the ability\n+of the MapReduce programs to consume them.\n+\n+The ``PurchaseWorkflow`` encapsulates set of MapReduce programs, which extracts the required information from the\n+raw purchase events and computes the total purchases made by the particular user and total purchases made for the\n+particular product in a specific time range. The results of the computation are persisted in a Dataset.\n+\n+Finally, the application contains a Service that exposes an HTTP endpoint to access the data stored in the Dataset.\n+\n+.. image:: docs/images/app-design.png\n+   :width: 8in\n+   :align: center\n+\n+Implementation\n+--------------\n+\n+The first step is to construct our application structure. We will use a\n+standard Maven project structure for all of the source code files::\n+\n+  ./pom.xml\n+  ./src/main/java/co/cdap/guides/workflow/EmailNotifier.java\n+  ./src/main/java/co/cdap/guides/workflow/Purchase.java\n+  ./src/main/java/co/cdap/guides/workflow/PurchaseCounterByProduct.java\n+  ./src/main/java/co/cdap/guides/workflow/PurchaseCounterByUser.java\n+  ./src/main/java/co/cdap/guides/workflow/PurchaseEventParser.java\n+  ./src/main/java/co/cdap/guides/workflow/PurchaseEventVerifier.java\n+  ./src/main/java/co/cdap/guides/workflow/PurchaseResultService.java\n+  ./src/main/java/co/cdap/guides/workflow/PurchaseWorkflow.java\n+  ./src/main/java/co/cdap/guides/workflow/PurchaseWorkflowApp.java\n+\n+The CDAP application is identified by the ``PurchaseWorkflowApp`` class. This\n+class extends an `AbstractApplication\n+<http://docs.cdap.io/cdap/current/en/reference-manual/javadocs/co/cask/cdap/api/app/AbstractApplication.html>`__,\n+and overrides the ``configure()`` method to define all of the application components:\n+\n+.. code:: java\n+\n+  public class PurchaseWorkflowApp extends AbstractApplication {\n+    @Override\n+    public void configure() {\n+      setName(\"PurchaseWorkflowApp\");\n+      setDescription(\"Application describing the Workflow\");\n+\n+      addStream(new Stream(\"purchaseEvents\"));\n+\n+      addMapReduce(new PurchaseEventParser());\n+      addMapReduce(new PurchaseCounterByUser());\n+      addMapReduce(new PurchaseCounterByProduct());\n+      addWorkflow(new PurchaseWorkflow());\n+\n+      scheduleWorkflow(Schedules.createTimeSchedule(\"HourlySchedule\", \"Schedule execution every 1 hour\", \"0 * * * *\"),\n+                       \"PurchaseWorkflow\");\n+\n+      addService(new PurchaseResultService());\n+\n+      createDataset(\"purchaseRecords\", KeyValueTable.class);\n+      createDataset(\"userPurchases\", KeyValueTable.class);\n+      createDataset(\"productPurchases\", KeyValueTable.class);\n+    }\n+  }\n+  \n+The ``PurchaseWorkflowApp`` application defines a new `Stream\n+<http://docs.cdap.io/cdap/current/en/developers-manual/building-blocks/streams.html>`__\n+where purchase events are ingested. Once the data is\n+ingested, the events can be processed in realtime or batch. In our\n+application, we will process the events in batch using the\n+``PurchaseWorkflow`` program and compute the total purchases made by the particular user\n+and total purchases made for the particular product in a specific time range. We will use three MapReduce\n+programs ``PurchaseEventParser``, ``PurchaseCounterByUser``, and ``PurchaseCounterByProduct`` to apply\n+different processing on the purchase events and Workflow ``PurchaseWorkflow`` to connect these MapReduce\n+programs in a desired fashion.\n+\n+The result of the Workflow execution is persisted into a Dataset; the\n+application uses the ``createDataset`` method to define the Dataset. We use three datasets,\n+``purchaseRecords`` to store the valid parsed purchase events, ``userPurchases`` to store the total purchases\n+made by particular user, and ``productPurchases`` to store the total purchases made for per product.\n+The ``Purchase`` class defines the type used to store the parsed purchase events.\n+\n+The application also adds a custom Workflow action ``EmailNotifier``. When Workflow executes a custom action,\n+the ``run`` method in it gets invoked. In ``EmailNotifier``, we only add a log statement, however it can be\n+customized to send emails to the concerned parties.\n+\n+The ``PurchaseWorkflow`` is scheduled to execute every one hour.\n+\n+Finally, the application adds a service for querying the results from the Dataset.\n+\n+Let's take a closer look at the Workflow program.\n+\n+The ``PurchaseWorkflow`` extends an `AbstractWorkflow\n+<http://docs.cdap.io/cdap/current/en/reference-manual/javadocs/co/cask/cdap/api/workflow/AbstractWorkflow.html>`__\n+class and overrides the ``configure()`` method:\n+\n+.. code:: java\n+\n+  public class PurchaseWorkflow extends AbstractWorkflow {\n+    @Override\n+    protected void configure() {\n+      setName(\"PurchaseWorkflow\");\n+      setDescription(\"Workflow to parse the purchase events and count the revenue per user and per product\");\n+\n+      addMapReduce(\"PurchaseEventParser\");\n+\n+      condition(new PurchaseEventVerifier())\n+        .fork()\n+          .addMapReduce(\"PurchaseCounterByUser\")\n+        .also()\n+          .addMapReduce(\"PurchaseCounterByProduct\")\n+        .join()\n+      .otherwise()\n+        .addAction(new NotifyByEmail())\n+      .end();\n+    }\n+  }\n+\n+In the ``configure()`` method we specify the topology for connecting the programs which will run as a part of\n+the Workflow execution. For ``PurchaseWorkflow``, after setting the name and description for the Workflow, we add\n+MapReduce program ``PurchaseEventParser``. This program will parse the raw purchase events to create the ``Purchase``\n+objects from it. After this, we add ``condition`` in the Workflow, which takes a predicate ``PurchaseEventVerifier``.\n+If the predicate evaluates to true, we `fork` the execution of the Workflow into two parallel branches.\n+One branch executes the ``PurchaseCounterByUser`` MapReduce program, while other executes the\n+``PurchaseCounterByProduct`` MapReduce program. If the predicate evaluates to false, then the programs added\n+in the ``otherwise`` section will get executed. We have added one dummy custom action, ``EmailNotifier()`` to the\n+``otherwise`` section.\n+\n+Lets take a closer look at the predicate ``PurchaseEventVerifier``.\n+\n+.. code:: java\n+\n+  public class PurchaseEventVerifier implements Predicate<WorkflowContext> {\n+\n+    @Override\n+    public boolean apply(WorkflowContext workflowContext) {\n+      if (workflowContext == null) {\n+        return false;\n+      }\n+\n+      WorkflowToken token = workflowContext.getToken();\n+      if (token == null) {\n+        return false;\n+      }\n+\n+      Map<String, Map<String, Long>> hadoopCounters = token.getMapReduceCounters();\n+      if (hadoopCounters == null) {\n+        return false;\n+      }\n+\n+      Map<String, Long> taskCounter = hadoopCounters.get(\"org.apache.hadoop.mapreduce.TaskCounter\");\n+\n+      if (taskCounter.containsKey(\"MAP_INPUT_RECORDS\")) {\n+        long mapInputRecordNumber = taskCounter.get(\"MAP_INPUT_RECORDS\");\n+        long mapOutputRecordNumber = taskCounter.get(\"MAP_OUTPUT_RECORDS\");\n+        // Return true if at least 80% of the records were processed by previous map job\n+        return (mapOutputRecordNumber >= (mapInputRecordNumber * 80/100));\n+      }\n+\n+      return false;\n+    }\n+  }\n+\n+``PurchaseEventVerifier`` needs to be a public class which implements the interface ``Predicate<WorkflowContext>``.\n+The ``apply`` method in the predicate takes ``WorkflowContext`` as a parameter. The hadoop counters emitted by\n+the previous MapReduce program (in our case ``PurchaseEventParser``) can be retrieved in this method using\n+``workflowContext`` object. We query for the number of input records to the mapper and number of records\n+emitted by the mapper. If at least 80% of the records were processed by the mapper, the method returns true,\n+in which case the `fork` in the Workflow will get executed. If the method returns false, ``otherwise`` section in\n+the ``condition`` gets executed, which contains ``EmailNotifier`` custom action.\n+\n+\n+Build and Run Application\n+=========================\n+\n+The ``PurchaseWorkflowApp`` can be built and packaged using the Apache Maven command::\n+\n+  $ mvn clean package\n+\n+Note that the remaining commands assume that the ``cdap-cli.sh`` script is\n+available on your PATH. If this is not the case, please add it::\n+\n+  $ export PATH=$PATH:<CDAP home>/bin\n+\n+If you haven't already started a standalone CDAP installation, start it with the command::\n+\n+  $ cdap.sh start\n+\n+We can then deploy the application to the standalone CDAP installation::\n+\n+  $ cdap-cli.sh deploy app target/cdap-workflow-guide-<version>.jar\n+\n+Next, we will send some sample purchase events into the stream\n+for processing::\n+\n+  $ cdap-cli.sh send stream purchaseEvents \\'bob bought 3 apples for \\$30\\'\n+  $ cdap-cli.sh send stream purchaseEvents \\'joe bought 1 apple for \\$100\\'\n+  $ cdap-cli.sh send stream purchaseEvents \\'joe bought 10 pineapples for \\$20\\'\n+  $ cdap-cli.sh send stream purchaseEvents \\'cat bought 3 bottles for \\$12\\'\n+  $ cdap-cli.sh send stream purchaseEvents \\'cat bought 2 pops for \\$14\\'\n+\n+We can now start the Workflow program to process the events that were\n+ingested::\n+\n+  $ cdap-cli.sh start workflow PurchaseWorkflowApp.PurchaseWorkflow\n+\n+The Workflow program will take a couple of minutes to execute.\n+\n+We can then start the ``PurchaseResultService`` and then query the processed\n+results::\n+\n+  $ cdap-cli.sh start service PurchaseWorkflowApp.PurchaseResultService\n+\n+- Get purchase records for user ``joe``::\n+\n+  $ curl http://localhost:10000/v3/namespaces/default/apps/PurchaseWorkflowApp/services/PurchaseResultService/methods/purchaserecords/joe\n+\n+Example output::\n+\n+  [{\"customer\":\"joe\",\"product\":\"pineapple\",\"quantity\":10,\"price\":20,\"purchaseTime\":1430962917227},{\"customer\":\"joe\",\"product\":\"apple\",\"quantity\":1,\"price\":100,\"purchaseTime\":1430962917227}]\n+\n+- Get the total purchases made by user ``joe``::\n+\n+  $ curl http://localhost:10000/v3/namespaces/default/apps/PurchaseWorkflowApp/services/PurchaseResultService/methods/purchases/users/joe\n+\n+Example output::\n+\n+  120\n+\n+- Get the total purchases made for product ``apple``::\n+\n+  $ curl http://localhost:10000/v3/namespaces/default/apps/PurchaseWorkflowApp/services/PurchaseResultService/methods/purchases/products/apple\n+\n+Example output::\n+\n+  160\n+\n+You have now learned how to write a Workflow program to connect different MapReduce programs and run them in parallel\n+based on the condition.\n+\n+Related Topics\n+==============\n+\n+- `CDAP MapReduce Guide <https://github.com/cdap-guides/cdap-mapreduce-guide>`__ tutorial for MapReduce\n+- `Wise: Web Analytics <http://docs.cask.co/tutorial/current/en/tutorial2.html>`__ tutorial, part of CDAP","path":"README.rst","position":303,"original_position":303,"commit_id":"2e4dacf03a867e3656b4a0d81f595953eb0ea095","original_commit_id":"2e4dacf03a867e3656b4a0d81f595953eb0ea095","user":{"login":"awholegunch","id":6394794,"avatar_url":"https://avatars.githubusercontent.com/u/6394794?v=3","gravatar_id":"","url":"https://api.github.com/users/awholegunch","html_url":"https://github.com/awholegunch","followers_url":"https://api.github.com/users/awholegunch/followers","following_url":"https://api.github.com/users/awholegunch/following{/other_user}","gists_url":"https://api.github.com/users/awholegunch/gists{/gist_id}","starred_url":"https://api.github.com/users/awholegunch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/awholegunch/subscriptions","organizations_url":"https://api.github.com/users/awholegunch/orgs","repos_url":"https://api.github.com/users/awholegunch/repos","events_url":"https://api.github.com/users/awholegunch/events{/privacy}","received_events_url":"https://api.github.com/users/awholegunch/received_events","type":"User","site_admin":false},"body":"- `Wise: Web Analytics <http://docs.cdap.io/cdap/current/en/examples-manual/tutorials/wise.html>`__ tutorial, part of CDAP","created_at":"2015-05-13T00:28:48Z","updated_at":"2015-05-13T00:28:48Z","html_url":"https://github.com/cdap-guides/cdap-workflow-guide/pull/1#discussion_r30194034","pull_request_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/pulls/1","_links":{"self":{"href":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/pulls/comments/30194034"},"html":{"href":"https://github.com/cdap-guides/cdap-workflow-guide/pull/1#discussion_r30194034"},"pull_request":{"href":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/pulls/1"}}},"pull_request":{"url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/pulls/1","id":34960998,"html_url":"https://github.com/cdap-guides/cdap-workflow-guide/pull/1","diff_url":"https://github.com/cdap-guides/cdap-workflow-guide/pull/1.diff","patch_url":"https://github.com/cdap-guides/cdap-workflow-guide/pull/1.patch","issue_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/issues/1","number":1,"state":"open","locked":false,"title":"Workflow guide","user":{"login":"sagarkapare","id":5713570,"avatar_url":"https://avatars.githubusercontent.com/u/5713570?v=3","gravatar_id":"","url":"https://api.github.com/users/sagarkapare","html_url":"https://github.com/sagarkapare","followers_url":"https://api.github.com/users/sagarkapare/followers","following_url":"https://api.github.com/users/sagarkapare/following{/other_user}","gists_url":"https://api.github.com/users/sagarkapare/gists{/gist_id}","starred_url":"https://api.github.com/users/sagarkapare/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sagarkapare/subscriptions","organizations_url":"https://api.github.com/users/sagarkapare/orgs","repos_url":"https://api.github.com/users/sagarkapare/repos","events_url":"https://api.github.com/users/sagarkapare/events{/privacy}","received_events_url":"https://api.github.com/users/sagarkapare/received_events","type":"User","site_admin":false},"body":"Pending things: unit test case.","created_at":"2015-05-07T21:36:50Z","updated_at":"2015-05-13T00:28:48Z","closed_at":null,"merged_at":null,"merge_commit_sha":"61b2611b7d6a0d7fff4b995fc5febfe0e2b164b2","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/pulls/1/commits","review_comments_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/pulls/1/comments","review_comment_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/pulls/comments{/number}","comments_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/issues/1/comments","statuses_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/statuses/2e4dacf03a867e3656b4a0d81f595953eb0ea095","head":{"label":"cdap-guides:workflow-guide","ref":"workflow-guide","sha":"2e4dacf03a867e3656b4a0d81f595953eb0ea095","user":{"login":"cdap-guides","id":9012786,"avatar_url":"https://avatars.githubusercontent.com/u/9012786?v=3","gravatar_id":"","url":"https://api.github.com/users/cdap-guides","html_url":"https://github.com/cdap-guides","followers_url":"https://api.github.com/users/cdap-guides/followers","following_url":"https://api.github.com/users/cdap-guides/following{/other_user}","gists_url":"https://api.github.com/users/cdap-guides/gists{/gist_id}","starred_url":"https://api.github.com/users/cdap-guides/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cdap-guides/subscriptions","organizations_url":"https://api.github.com/users/cdap-guides/orgs","repos_url":"https://api.github.com/users/cdap-guides/repos","events_url":"https://api.github.com/users/cdap-guides/events{/privacy}","received_events_url":"https://api.github.com/users/cdap-guides/received_events","type":"Organization","site_admin":false},"repo":{"id":35059852,"name":"cdap-workflow-guide","full_name":"cdap-guides/cdap-workflow-guide","owner":{"login":"cdap-guides","id":9012786,"avatar_url":"https://avatars.githubusercontent.com/u/9012786?v=3","gravatar_id":"","url":"https://api.github.com/users/cdap-guides","html_url":"https://github.com/cdap-guides","followers_url":"https://api.github.com/users/cdap-guides/followers","following_url":"https://api.github.com/users/cdap-guides/following{/other_user}","gists_url":"https://api.github.com/users/cdap-guides/gists{/gist_id}","starred_url":"https://api.github.com/users/cdap-guides/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cdap-guides/subscriptions","organizations_url":"https://api.github.com/users/cdap-guides/orgs","repos_url":"https://api.github.com/users/cdap-guides/repos","events_url":"https://api.github.com/users/cdap-guides/events{/privacy}","received_events_url":"https://api.github.com/users/cdap-guides/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/cdap-guides/cdap-workflow-guide","description":"","fork":false,"url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide","forks_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/forks","keys_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/teams","hooks_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/hooks","issue_events_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/issues/events{/number}","events_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/events","assignees_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/assignees{/user}","branches_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/branches{/branch}","tags_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/tags","blobs_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/git/refs{/sha}","trees_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/statuses/{sha}","languages_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/languages","stargazers_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/stargazers","contributors_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/contributors","subscribers_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/subscribers","subscription_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/subscription","commits_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/commits{/sha}","git_commits_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/git/commits{/sha}","comments_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/comments{/number}","issue_comment_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/issues/comments{/number}","contents_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/contents/{+path}","compare_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/merges","archive_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/downloads","issues_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/issues{/number}","pulls_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/pulls{/number}","milestones_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/milestones{/number}","notifications_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/labels{/name}","releases_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/releases{/id}","created_at":"2015-05-04T21:08:52Z","updated_at":"2015-05-04T21:08:52Z","pushed_at":"2015-05-12T20:03:21Z","git_url":"git://github.com/cdap-guides/cdap-workflow-guide.git","ssh_url":"git@github.com:cdap-guides/cdap-workflow-guide.git","clone_url":"https://github.com/cdap-guides/cdap-workflow-guide.git","svn_url":"https://github.com/cdap-guides/cdap-workflow-guide","homepage":null,"size":264,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"develop"}},"base":{"label":"cdap-guides:develop","ref":"develop","sha":"1b4247f4a4785ee8a4a17710749c069f69a2e16c","user":{"login":"cdap-guides","id":9012786,"avatar_url":"https://avatars.githubusercontent.com/u/9012786?v=3","gravatar_id":"","url":"https://api.github.com/users/cdap-guides","html_url":"https://github.com/cdap-guides","followers_url":"https://api.github.com/users/cdap-guides/followers","following_url":"https://api.github.com/users/cdap-guides/following{/other_user}","gists_url":"https://api.github.com/users/cdap-guides/gists{/gist_id}","starred_url":"https://api.github.com/users/cdap-guides/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cdap-guides/subscriptions","organizations_url":"https://api.github.com/users/cdap-guides/orgs","repos_url":"https://api.github.com/users/cdap-guides/repos","events_url":"https://api.github.com/users/cdap-guides/events{/privacy}","received_events_url":"https://api.github.com/users/cdap-guides/received_events","type":"Organization","site_admin":false},"repo":{"id":35059852,"name":"cdap-workflow-guide","full_name":"cdap-guides/cdap-workflow-guide","owner":{"login":"cdap-guides","id":9012786,"avatar_url":"https://avatars.githubusercontent.com/u/9012786?v=3","gravatar_id":"","url":"https://api.github.com/users/cdap-guides","html_url":"https://github.com/cdap-guides","followers_url":"https://api.github.com/users/cdap-guides/followers","following_url":"https://api.github.com/users/cdap-guides/following{/other_user}","gists_url":"https://api.github.com/users/cdap-guides/gists{/gist_id}","starred_url":"https://api.github.com/users/cdap-guides/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cdap-guides/subscriptions","organizations_url":"https://api.github.com/users/cdap-guides/orgs","repos_url":"https://api.github.com/users/cdap-guides/repos","events_url":"https://api.github.com/users/cdap-guides/events{/privacy}","received_events_url":"https://api.github.com/users/cdap-guides/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/cdap-guides/cdap-workflow-guide","description":"","fork":false,"url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide","forks_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/forks","keys_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/teams","hooks_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/hooks","issue_events_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/issues/events{/number}","events_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/events","assignees_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/assignees{/user}","branches_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/branches{/branch}","tags_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/tags","blobs_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/git/refs{/sha}","trees_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/statuses/{sha}","languages_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/languages","stargazers_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/stargazers","contributors_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/contributors","subscribers_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/subscribers","subscription_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/subscription","commits_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/commits{/sha}","git_commits_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/git/commits{/sha}","comments_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/comments{/number}","issue_comment_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/issues/comments{/number}","contents_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/contents/{+path}","compare_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/merges","archive_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/downloads","issues_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/issues{/number}","pulls_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/pulls{/number}","milestones_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/milestones{/number}","notifications_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/labels{/name}","releases_url":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/releases{/id}","created_at":"2015-05-04T21:08:52Z","updated_at":"2015-05-04T21:08:52Z","pushed_at":"2015-05-12T20:03:21Z","git_url":"git://github.com/cdap-guides/cdap-workflow-guide.git","ssh_url":"git@github.com:cdap-guides/cdap-workflow-guide.git","clone_url":"https://github.com/cdap-guides/cdap-workflow-guide.git","svn_url":"https://github.com/cdap-guides/cdap-workflow-guide","homepage":null,"size":264,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/pulls/1"},"html":{"href":"https://github.com/cdap-guides/cdap-workflow-guide/pull/1"},"issue":{"href":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/issues/1"},"comments":{"href":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/issues/1/comments"},"review_comments":{"href":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/pulls/1/comments"},"review_comment":{"href":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/pulls/1/commits"},"statuses":{"href":"https://api.github.com/repos/cdap-guides/cdap-workflow-guide/statuses/2e4dacf03a867e3656b4a0d81f595953eb0ea095"}}}}