{"action":"created","comment":{"url":"https://api.github.com/repos/TWCable/grabbit/pulls/comments/47452172","id":47452172,"diff_hunk":"@@ -0,0 +1,123 @@\n+package com.twcable.grabbit.client.batch.steps.http\n+\n+import com.twcable.grabbit.client.batch.ClientBatchJob\n+import com.twcable.grabbit.client.batch.ClientBatchJobContext\n+import org.apache.http.HttpEntity\n+import org.apache.http.HttpHost\n+import org.apache.http.HttpResponse\n+import org.apache.http.auth.AuthScope\n+import org.apache.http.auth.UsernamePasswordCredentials\n+import org.apache.http.client.AuthCache\n+import org.apache.http.client.CredentialsProvider\n+import org.apache.http.client.HttpClient\n+import org.apache.http.client.methods.HttpGet\n+import org.apache.http.client.protocol.HttpClientContext\n+import org.apache.http.client.utils.URIBuilder\n+import org.apache.http.impl.auth.BasicScheme\n+import org.apache.http.impl.client.BasicAuthCache\n+import org.apache.http.impl.client.BasicCredentialsProvider\n+import org.apache.http.impl.client.DefaultHttpClient\n+import org.springframework.batch.core.StepContribution\n+import org.springframework.batch.core.scope.context.ChunkContext\n+import org.springframework.batch.core.step.tasklet.Tasklet\n+import org.springframework.batch.repeat.RepeatStatus\n+\n+/*\n+ * Copyright 2015 Time Warner Cable, Inc.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ * http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+/**\n+ * This tasklet opens an HTTP session for the current job, and places the input stream on the {@link ClientBatchJobContext}\n+ */\n+class CreateHttpConnectionTasklet implements Tasklet {\n+\n+    @Override\n+    RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {\n+        HttpResponse response = doRequest(chunkContext.stepContext.jobParameters)\n+        HttpEntity responseEntity = response.entity\n+        ClientBatchJobContext.setInputStream(responseEntity.content)\n+        return RepeatStatus.FINISHED\n+    }\n+\n+    /**\n+     * Makes a Http Get request to the grab path and returns the response\n+     * @param jobParameters that contain information like the path, host, port, etc.\n+     * @return the httpResponse\n+     */\n+    private HttpResponse doRequest(Map jobParameters) {\n+        final String path = jobParameters.get(ClientBatchJob.PATH)\n+        final String excludePathParam = jobParameters.get(ClientBatchJob.EXCLUDE_PATHS)\n+        final excludePaths = (excludePathParam != null && !excludePathParam.isEmpty() ? excludePathParam.split(/\\*/) : Collections.EMPTY_LIST) as Collection<String>\n+        final String host = jobParameters.get(ClientBatchJob.HOST)\n+        final String port = jobParameters.get(ClientBatchJob.PORT)\n+        final String username = jobParameters.get(ClientBatchJob.SERVER_USERNAME)\n+        final String password = jobParameters.get(ClientBatchJob.SERVER_PASSWORD)\n+        final String contentAfterDate = jobParameters.get(ClientBatchJob.CONTENT_AFTER_DATE) ?: \"\"\n+\n+        final String encodedContentAfterDate = URLEncoder.encode(contentAfterDate, 'utf-8')\n+        final String encodedPath = URLEncoder.encode(path, 'utf-8')\n+\n+        URIBuilder uriBuilder = new URIBuilder(scheme: \"http\", host: host, port: port as Integer, path: \"/grabbit/job\")\n+        uriBuilder.addParameter(\"path\", encodedPath)\n+        uriBuilder.addParameter(\"after\", encodedContentAfterDate)\n+        for(String excludePath : excludePaths) {\n+            uriBuilder.addParameter(\"excludePath\", URLEncoder.encode(excludePath, 'UTF-8'))\n+        }\n+\n+        //create the get request\n+        HttpGet get = new HttpGet(uriBuilder.build())\n+        HttpClient client = getHttpClient(username, password)\n+        HttpClientContext context = getHttpClientContext(get)\n+        HttpResponse response = client.execute(get, context)\n+        response\n+    }\n+\n+    /**\n+     * Gets a Http Get connection for the provided authentication information\n+     * @param username\n+     * @param password\n+     * @return a {@link org.apache.http.impl.client.DefaultHttpClient} instance\n+     */\n+    private DefaultHttpClient getHttpClient(final String username, final String password) {\n+        DefaultHttpClient client = new DefaultHttpClient()\n+\n+        CredentialsProvider credentialsProvider = new BasicCredentialsProvider()\n+        credentialsProvider.setCredentials(\n+                new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),\n+                new UsernamePasswordCredentials(username, password)\n+        )\n+        client.setCredentialsProvider(credentialsProvider)\n+        client\n+    }\n+\n+    /**\n+     * Gets a new HttpClientContext for the given HttpRequest. The ClientContext sets up preemptive\n+     * authentication using BasicAuthCache\n+     * @param get the HttpGet request\n+     * @return the HttpClientContext for given HttpRequest\n+     */\n+    private HttpClientContext getHttpClientContext(HttpGet get) {","path":"grabbit/src/main/groovy/com/twcable/grabbit/client/batch/steps/http/CreateHttpConnectionTasklet.groovy","position":111,"original_position":111,"commit_id":"783d3510a55c4c8dbd82979f3803aad9dd955e38","original_commit_id":"783d3510a55c4c8dbd82979f3803aad9dd955e38","user":{"login":"sagarsane","id":667114,"avatar_url":"https://avatars.githubusercontent.com/u/667114?v=3","gravatar_id":"","url":"https://api.github.com/users/sagarsane","html_url":"https://github.com/sagarsane","followers_url":"https://api.github.com/users/sagarsane/followers","following_url":"https://api.github.com/users/sagarsane/following{/other_user}","gists_url":"https://api.github.com/users/sagarsane/gists{/gist_id}","starred_url":"https://api.github.com/users/sagarsane/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sagarsane/subscriptions","organizations_url":"https://api.github.com/users/sagarsane/orgs","repos_url":"https://api.github.com/users/sagarsane/repos","events_url":"https://api.github.com/users/sagarsane/events{/privacy}","received_events_url":"https://api.github.com/users/sagarsane/received_events","type":"User","site_admin":false},"body":"Minor : Can be static.","created_at":"2015-12-13T23:08:59Z","updated_at":"2015-12-13T23:08:59Z","html_url":"https://github.com/TWCable/grabbit/pull/93#discussion_r47452172","pull_request_url":"https://api.github.com/repos/TWCable/grabbit/pulls/93","_links":{"self":{"href":"https://api.github.com/repos/TWCable/grabbit/pulls/comments/47452172"},"html":{"href":"https://github.com/TWCable/grabbit/pull/93#discussion_r47452172"},"pull_request":{"href":"https://api.github.com/repos/TWCable/grabbit/pulls/93"}}},"pull_request":{"url":"https://api.github.com/repos/TWCable/grabbit/pulls/93","id":50457501,"html_url":"https://github.com/TWCable/grabbit/pull/93","diff_url":"https://github.com/TWCable/grabbit/pull/93.diff","patch_url":"https://github.com/TWCable/grabbit/pull/93.patch","issue_url":"https://api.github.com/repos/TWCable/grabbit/issues/93","number":93,"state":"open","locked":false,"title":"Issue 92 validate parent path","user":{"login":"jbornemann","id":4540994,"avatar_url":"https://avatars.githubusercontent.com/u/4540994?v=3","gravatar_id":"","url":"https://api.github.com/users/jbornemann","html_url":"https://github.com/jbornemann","followers_url":"https://api.github.com/users/jbornemann/followers","following_url":"https://api.github.com/users/jbornemann/following{/other_user}","gists_url":"https://api.github.com/users/jbornemann/gists{/gist_id}","starred_url":"https://api.github.com/users/jbornemann/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jbornemann/subscriptions","organizations_url":"https://api.github.com/users/jbornemann/orgs","repos_url":"https://api.github.com/users/jbornemann/repos","events_url":"https://api.github.com/users/jbornemann/events{/privacy}","received_events_url":"https://api.github.com/users/jbornemann/received_events","type":"User","site_admin":false},"body":"#92 \r\n\r\nWIP, for visibility @jdigger @sagarsane ","created_at":"2015-11-12T00:39:01Z","updated_at":"2015-12-13T23:08:59Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e4656d71768d7948feaa0bac18f7ac9a02152aa6","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/TWCable/grabbit/pulls/93/commits","review_comments_url":"https://api.github.com/repos/TWCable/grabbit/pulls/93/comments","review_comment_url":"https://api.github.com/repos/TWCable/grabbit/pulls/comments{/number}","comments_url":"https://api.github.com/repos/TWCable/grabbit/issues/93/comments","statuses_url":"https://api.github.com/repos/TWCable/grabbit/statuses/783d3510a55c4c8dbd82979f3803aad9dd955e38","head":{"label":"TWCable:issue-92-validate-parent-path","ref":"issue-92-validate-parent-path","sha":"783d3510a55c4c8dbd82979f3803aad9dd955e38","user":{"login":"TWCable","id":10778149,"avatar_url":"https://avatars.githubusercontent.com/u/10778149?v=3","gravatar_id":"","url":"https://api.github.com/users/TWCable","html_url":"https://github.com/TWCable","followers_url":"https://api.github.com/users/TWCable/followers","following_url":"https://api.github.com/users/TWCable/following{/other_user}","gists_url":"https://api.github.com/users/TWCable/gists{/gist_id}","starred_url":"https://api.github.com/users/TWCable/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TWCable/subscriptions","organizations_url":"https://api.github.com/users/TWCable/orgs","repos_url":"https://api.github.com/users/TWCable/repos","events_url":"https://api.github.com/users/TWCable/events{/privacy}","received_events_url":"https://api.github.com/users/TWCable/received_events","type":"Organization","site_admin":false},"repo":{"id":31395930,"name":"grabbit","full_name":"TWCable/grabbit","owner":{"login":"TWCable","id":10778149,"avatar_url":"https://avatars.githubusercontent.com/u/10778149?v=3","gravatar_id":"","url":"https://api.github.com/users/TWCable","html_url":"https://github.com/TWCable","followers_url":"https://api.github.com/users/TWCable/followers","following_url":"https://api.github.com/users/TWCable/following{/other_user}","gists_url":"https://api.github.com/users/TWCable/gists{/gist_id}","starred_url":"https://api.github.com/users/TWCable/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TWCable/subscriptions","organizations_url":"https://api.github.com/users/TWCable/orgs","repos_url":"https://api.github.com/users/TWCable/repos","events_url":"https://api.github.com/users/TWCable/events{/privacy}","received_events_url":"https://api.github.com/users/TWCable/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/TWCable/grabbit","description":"Grabbit - Fast Content Sync tool for AEM/CQ","fork":false,"url":"https://api.github.com/repos/TWCable/grabbit","forks_url":"https://api.github.com/repos/TWCable/grabbit/forks","keys_url":"https://api.github.com/repos/TWCable/grabbit/keys{/key_id}","collaborators_url":"https://api.github.com/repos/TWCable/grabbit/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/TWCable/grabbit/teams","hooks_url":"https://api.github.com/repos/TWCable/grabbit/hooks","issue_events_url":"https://api.github.com/repos/TWCable/grabbit/issues/events{/number}","events_url":"https://api.github.com/repos/TWCable/grabbit/events","assignees_url":"https://api.github.com/repos/TWCable/grabbit/assignees{/user}","branches_url":"https://api.github.com/repos/TWCable/grabbit/branches{/branch}","tags_url":"https://api.github.com/repos/TWCable/grabbit/tags","blobs_url":"https://api.github.com/repos/TWCable/grabbit/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/TWCable/grabbit/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/TWCable/grabbit/git/refs{/sha}","trees_url":"https://api.github.com/repos/TWCable/grabbit/git/trees{/sha}","statuses_url":"https://api.github.com/repos/TWCable/grabbit/statuses/{sha}","languages_url":"https://api.github.com/repos/TWCable/grabbit/languages","stargazers_url":"https://api.github.com/repos/TWCable/grabbit/stargazers","contributors_url":"https://api.github.com/repos/TWCable/grabbit/contributors","subscribers_url":"https://api.github.com/repos/TWCable/grabbit/subscribers","subscription_url":"https://api.github.com/repos/TWCable/grabbit/subscription","commits_url":"https://api.github.com/repos/TWCable/grabbit/commits{/sha}","git_commits_url":"https://api.github.com/repos/TWCable/grabbit/git/commits{/sha}","comments_url":"https://api.github.com/repos/TWCable/grabbit/comments{/number}","issue_comment_url":"https://api.github.com/repos/TWCable/grabbit/issues/comments{/number}","contents_url":"https://api.github.com/repos/TWCable/grabbit/contents/{+path}","compare_url":"https://api.github.com/repos/TWCable/grabbit/compare/{base}...{head}","merges_url":"https://api.github.com/repos/TWCable/grabbit/merges","archive_url":"https://api.github.com/repos/TWCable/grabbit/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/TWCable/grabbit/downloads","issues_url":"https://api.github.com/repos/TWCable/grabbit/issues{/number}","pulls_url":"https://api.github.com/repos/TWCable/grabbit/pulls{/number}","milestones_url":"https://api.github.com/repos/TWCable/grabbit/milestones{/number}","notifications_url":"https://api.github.com/repos/TWCable/grabbit/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/TWCable/grabbit/labels{/name}","releases_url":"https://api.github.com/repos/TWCable/grabbit/releases{/id}","created_at":"2015-02-27T00:24:35Z","updated_at":"2015-12-09T17:23:22Z","pushed_at":"2015-12-07T17:15:20Z","git_url":"git://github.com/TWCable/grabbit.git","ssh_url":"git@github.com:TWCable/grabbit.git","clone_url":"https://github.com/TWCable/grabbit.git","svn_url":"https://github.com/TWCable/grabbit","homepage":"","size":921,"stargazers_count":37,"watchers_count":37,"language":"Groovy","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":10,"mirror_url":null,"open_issues_count":43,"forks":10,"open_issues":43,"watchers":37,"default_branch":"master"}},"base":{"label":"TWCable:master","ref":"master","sha":"e43e2e15606cd26484fe8775ed89d74fca3d8143","user":{"login":"TWCable","id":10778149,"avatar_url":"https://avatars.githubusercontent.com/u/10778149?v=3","gravatar_id":"","url":"https://api.github.com/users/TWCable","html_url":"https://github.com/TWCable","followers_url":"https://api.github.com/users/TWCable/followers","following_url":"https://api.github.com/users/TWCable/following{/other_user}","gists_url":"https://api.github.com/users/TWCable/gists{/gist_id}","starred_url":"https://api.github.com/users/TWCable/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TWCable/subscriptions","organizations_url":"https://api.github.com/users/TWCable/orgs","repos_url":"https://api.github.com/users/TWCable/repos","events_url":"https://api.github.com/users/TWCable/events{/privacy}","received_events_url":"https://api.github.com/users/TWCable/received_events","type":"Organization","site_admin":false},"repo":{"id":31395930,"name":"grabbit","full_name":"TWCable/grabbit","owner":{"login":"TWCable","id":10778149,"avatar_url":"https://avatars.githubusercontent.com/u/10778149?v=3","gravatar_id":"","url":"https://api.github.com/users/TWCable","html_url":"https://github.com/TWCable","followers_url":"https://api.github.com/users/TWCable/followers","following_url":"https://api.github.com/users/TWCable/following{/other_user}","gists_url":"https://api.github.com/users/TWCable/gists{/gist_id}","starred_url":"https://api.github.com/users/TWCable/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TWCable/subscriptions","organizations_url":"https://api.github.com/users/TWCable/orgs","repos_url":"https://api.github.com/users/TWCable/repos","events_url":"https://api.github.com/users/TWCable/events{/privacy}","received_events_url":"https://api.github.com/users/TWCable/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/TWCable/grabbit","description":"Grabbit - Fast Content Sync tool for AEM/CQ","fork":false,"url":"https://api.github.com/repos/TWCable/grabbit","forks_url":"https://api.github.com/repos/TWCable/grabbit/forks","keys_url":"https://api.github.com/repos/TWCable/grabbit/keys{/key_id}","collaborators_url":"https://api.github.com/repos/TWCable/grabbit/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/TWCable/grabbit/teams","hooks_url":"https://api.github.com/repos/TWCable/grabbit/hooks","issue_events_url":"https://api.github.com/repos/TWCable/grabbit/issues/events{/number}","events_url":"https://api.github.com/repos/TWCable/grabbit/events","assignees_url":"https://api.github.com/repos/TWCable/grabbit/assignees{/user}","branches_url":"https://api.github.com/repos/TWCable/grabbit/branches{/branch}","tags_url":"https://api.github.com/repos/TWCable/grabbit/tags","blobs_url":"https://api.github.com/repos/TWCable/grabbit/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/TWCable/grabbit/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/TWCable/grabbit/git/refs{/sha}","trees_url":"https://api.github.com/repos/TWCable/grabbit/git/trees{/sha}","statuses_url":"https://api.github.com/repos/TWCable/grabbit/statuses/{sha}","languages_url":"https://api.github.com/repos/TWCable/grabbit/languages","stargazers_url":"https://api.github.com/repos/TWCable/grabbit/stargazers","contributors_url":"https://api.github.com/repos/TWCable/grabbit/contributors","subscribers_url":"https://api.github.com/repos/TWCable/grabbit/subscribers","subscription_url":"https://api.github.com/repos/TWCable/grabbit/subscription","commits_url":"https://api.github.com/repos/TWCable/grabbit/commits{/sha}","git_commits_url":"https://api.github.com/repos/TWCable/grabbit/git/commits{/sha}","comments_url":"https://api.github.com/repos/TWCable/grabbit/comments{/number}","issue_comment_url":"https://api.github.com/repos/TWCable/grabbit/issues/comments{/number}","contents_url":"https://api.github.com/repos/TWCable/grabbit/contents/{+path}","compare_url":"https://api.github.com/repos/TWCable/grabbit/compare/{base}...{head}","merges_url":"https://api.github.com/repos/TWCable/grabbit/merges","archive_url":"https://api.github.com/repos/TWCable/grabbit/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/TWCable/grabbit/downloads","issues_url":"https://api.github.com/repos/TWCable/grabbit/issues{/number}","pulls_url":"https://api.github.com/repos/TWCable/grabbit/pulls{/number}","milestones_url":"https://api.github.com/repos/TWCable/grabbit/milestones{/number}","notifications_url":"https://api.github.com/repos/TWCable/grabbit/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/TWCable/grabbit/labels{/name}","releases_url":"https://api.github.com/repos/TWCable/grabbit/releases{/id}","created_at":"2015-02-27T00:24:35Z","updated_at":"2015-12-09T17:23:22Z","pushed_at":"2015-12-07T17:15:20Z","git_url":"git://github.com/TWCable/grabbit.git","ssh_url":"git@github.com:TWCable/grabbit.git","clone_url":"https://github.com/TWCable/grabbit.git","svn_url":"https://github.com/TWCable/grabbit","homepage":"","size":921,"stargazers_count":37,"watchers_count":37,"language":"Groovy","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":10,"mirror_url":null,"open_issues_count":43,"forks":10,"open_issues":43,"watchers":37,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/TWCable/grabbit/pulls/93"},"html":{"href":"https://github.com/TWCable/grabbit/pull/93"},"issue":{"href":"https://api.github.com/repos/TWCable/grabbit/issues/93"},"comments":{"href":"https://api.github.com/repos/TWCable/grabbit/issues/93/comments"},"review_comments":{"href":"https://api.github.com/repos/TWCable/grabbit/pulls/93/comments"},"review_comment":{"href":"https://api.github.com/repos/TWCable/grabbit/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/TWCable/grabbit/pulls/93/commits"},"statuses":{"href":"https://api.github.com/repos/TWCable/grabbit/statuses/783d3510a55c4c8dbd82979f3803aad9dd955e38"}}}}