{"action":"created","comment":{"url":"https://api.github.com/repos/apache/flink/pulls/comments/27808253","id":27808253,"diff_hunk":"@@ -0,0 +1,362 @@\n+/*\n+ * Licensed to the Apache Software Foundation (ASF) under one\n+ * or more contributor license agreements.  See the NOTICE file\n+ * distributed with this work for additional information\n+ * regarding copyright ownership.  The ASF licenses this file\n+ * to you under the Apache License, Version 2.0 (the\n+ * \"License\"); you may not use this file except in compliance\n+ * with the License.  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+package org.apache.flink.stormcompatibility.api;\n+\n+import java.io.File;\n+import java.io.IOException;\n+import java.net.InetSocketAddress;\n+import java.util.ArrayList;\n+import java.util.HashMap;\n+import java.util.List;\n+import java.util.Map;\n+\n+import org.apache.flink.api.common.JobID;\n+import org.apache.flink.api.common.JobSubmissionResult;\n+import org.apache.flink.client.program.Client;\n+import org.apache.flink.client.program.JobWithJars;\n+import org.apache.flink.client.program.ProgramInvocationException;\n+import org.apache.flink.configuration.ConfigConstants;\n+import org.apache.flink.configuration.Configuration;\n+import org.apache.flink.configuration.GlobalConfiguration;\n+import org.apache.flink.core.fs.Path;\n+import org.apache.flink.runtime.akka.AkkaUtils;\n+import org.apache.flink.runtime.jobgraph.JobGraph;\n+import org.apache.flink.runtime.jobmanager.JobManager;\n+import org.apache.flink.runtime.messages.JobManagerMessages.CancelJob;\n+\n+import scala.Some;\n+import scala.concurrent.Await;\n+import scala.concurrent.Future;\n+import scala.concurrent.duration.FiniteDuration;\n+import akka.actor.ActorRef;\n+import akka.actor.ActorSystem;\n+import akka.pattern.Patterns;\n+import akka.util.Timeout;\n+import backtype.storm.Config;\n+import backtype.storm.generated.AlreadyAliveException;\n+import backtype.storm.generated.ClusterSummary;\n+import backtype.storm.generated.InvalidTopologyException;\n+import backtype.storm.generated.KillOptions;\n+import backtype.storm.generated.NotAliveException;\n+import backtype.storm.generated.SubmitOptions;\n+import backtype.storm.utils.NimbusClient;\n+import backtype.storm.utils.Utils;\n+\n+\n+\n+\n+\n+/**\n+ * {@link FlinkClient} mimics a Storm {@link NimbusClient} and {@link backtype.storm.generated.Nimbus.Client\n+ * Nimbus.Client} at once, to interact with Flink's JobManager instead of Storm's Nimbus.\n+ * \n+ * @author mjsax\n+ */\n+public class FlinkClient {\n+\t/**\n+\t * Configuration key to specify the location of the file storm-core-0.9.4.jar (for org.apache.storm).\n+\t */\n+\tpublic final static String FLINK_STROM_CORE_JAR_LOCATION = \"flink.storm.jar-location.storm-core\";\n+\t/**\n+\t * Configuration key to specify the location of the file json-simple-1.1.jar (for com.googlecode.json-simple).\n+\t */\n+\tpublic final static String FLINK_STROM_JSON_SIMPLE_JAR_LOCATION = \"flink.storm.jar-location.json-simple\";\n+\t\n+\t\n+\t\n+\t/**\n+\t * The users specified configuration.\n+\t */\n+\tprivate final Map<?, ?> config;\n+\t/**\n+\t * The jobmanager's host name.\n+\t */\n+\tprivate final String jobManagerHost;\n+\t/**\n+\t * The jobmanager's rpc port.\n+\t */\n+\tprivate final int jobManagerPort;\n+\t/**\n+\t * The user specified timeout in milliseconds.\n+\t */\n+\tprivate final String timeout;\n+\t/**\n+\t * Maps the names of running topologies to the corresponding Flink {@link JobID}.\n+\t */\n+\tprivate final Map<String, JobID> topologyNameToJobId = new HashMap<String, JobID>();\n+\t/**\n+\t * Maps the names of running topologies to the corresponding {@link FlinkTopology}.\n+\t */\n+\tprivate final Map<String, FlinkTopology> topologies = new HashMap<String, FlinkTopology>();\n+\t\n+\t\n+\t\n+\t/*\n+\t * The following methods are derived from \"backtype.storm.utils.NimbusClient\"\n+\t */\n+\t\n+\t/**\n+\t * Instantiates a new {@link FlinkClient} for the given configuration, host name, and port. If values for\n+\t * {@link Config#NIMBUS_HOST} and {@link Config#NIMBUS_THRIFT_PORT} of the given configuration are ignored.\n+\t * \n+\t * @param conf\n+\t *            A configuration.\n+\t * @param host\n+\t *            The jobmanager's host name.\n+\t * @param port\n+\t *            The jobmanager's rpc port.\n+\t */\n+\tpublic FlinkClient(final Map<?, ?> conf, final String host, final int port) {\n+\t\tthis(conf, host, port, null);\n+\t}\n+\t\n+\t/**\n+\t * Instantiates a new {@link FlinkClient} for the given configuration, host name, and port. If values for\n+\t * {@link Config#NIMBUS_HOST} and {@link Config#NIMBUS_THRIFT_PORT} of the given configuration are ignored.\n+\t * \n+\t * @param conf\n+\t *            A configuration.\n+\t * @param host\n+\t *            The jobmanager's host name.\n+\t * @param port\n+\t *            The jobmanager's rpc port.\n+\t * @param timeout\n+\t */\n+\tpublic FlinkClient(final Map<?, ?> conf, final String host, final int port, final Integer timeout) {\n+\t\tthis.config = conf;\n+\t\tthis.jobManagerHost = host;\n+\t\tthis.jobManagerPort = port;\n+\t\tif(timeout != null) {\n+\t\t\tthis.timeout = timeout + \" ms\";\n+\t\t} else {\n+\t\t\tthis.timeout = null;\n+\t\t}\n+\t}\n+\t\n+\t\n+\t\n+\t/**\n+\t * Returns a {@link FlinkClient} that uses the configured {@link Config#NIMBUS_HOST} and\n+\t * {@link Config#NIMBUS_THRIFT_PORT} as JobManager address.\n+\t * \n+\t * @param conf\n+\t *            Configuration that contains the jobmanager's hostname and port.\n+\t * \n+\t * @return A configured {@link FlinkClient}.\n+\t */\n+\tpublic static FlinkClient getConfiguredClient(@SuppressWarnings(\"rawtypes\") final Map conf) {\n+\t\tfinal String nimbusHost = (String)conf.get(Config.NIMBUS_HOST);\n+\t\tfinal int nimbusPort = Utils.getInt(conf.get(Config.NIMBUS_THRIFT_PORT)).intValue();\n+\t\treturn new FlinkClient(conf, nimbusHost, nimbusPort);\n+\t}\n+\t\n+\t\n+\t\n+\t/**\n+\t * Return a reference to itself.\n+\t * \n+\t * {@link FlinkClient} mimics both, {@link NimbusClient} and {@link backtype.storm.generated.Nimubs.Client\n+\t * Nimbus.Client}, at once.\n+\t * \n+\t * @return A reference to itself.\n+\t */\n+\tpublic FlinkClient getClient() {\n+\t\treturn this;\n+\t}\n+\t\n+\tpublic void close() { /* nothing to do */}\n+\t\n+\t\n+\t/*\n+\t * The following methods are derived from \"backtype.storm.generated.Nimubs.Client\"\n+\t */\n+\t\n+\t/**\n+\t * Parameter {@code uploadedJarLocation} is actually used to point to the local jar, because Flink does not support\n+\t * uploading a jar file before hand. Jar files are always uploaded directly when a program is submitted.\n+\t */\n+\tpublic void submitTopology(final String name, final String uploadedJarLocation, final String jsonConf, final FlinkTopology topology)\n+\t\tthrows AlreadyAliveException, InvalidTopologyException {\n+\t\tthis.submitTopologyWithOpts(name, uploadedJarLocation, jsonConf, topology, null);\n+\t}\n+\t\n+\t/**\n+\t * Parameter {@code uploadedJarLocation} is actually used to point to the local jar, because Flink does not support\n+\t * uploading a jar file before hand. Jar files are always uploaded directly when a program is submitted.\n+\t */\n+\t@SuppressWarnings(\"unused\")\n+\tpublic void submitTopologyWithOpts(final String name, final String uploadedJarLocation, final String jsonConf, final FlinkTopology topology, final SubmitOptions options)\n+\t\tthrows AlreadyAliveException, InvalidTopologyException {\n+\t\t\n+\t\t// TODO improve by checking job manager, if running\n+\t\tif(this.topologyNameToJobId.containsKey(name)) {\n+\t\t\tthrow new AlreadyAliveException();\n+\t\t}\n+\t\t\n+\t\t// TODO refactor and combine shared code (copied from RemoveStreamEnvironment)\n+\t\ttry {\n+\t\t\tfinal JobGraph jobGraph = topology.getStreamGraph().getJobGraph(name);\n+\t\t\t\n+\t\t\t// TODO improve error handling for missing config values and uploadedJarLocation==null\n+\t\t\tfinal String stormCoreJar = (String)this.config.get(FLINK_STROM_CORE_JAR_LOCATION);\n+\t\t\tfinal String jsonSimpleJar = (String)this.config.get(FLINK_STROM_JSON_SIMPLE_JAR_LOCATION);\n+\t\t\tfinal String[] jarFileNames = new String[] {stormCoreJar, jsonSimpleJar, uploadedJarLocation};\n+\t\t\t\n+\t\t\tfinal List<File> jarFiles = new ArrayList<File>();\n+\t\t\tfor(int i = 0; i < jarFileNames.length; i++) {\n+\t\t\t\tfinal File file = new File(jarFileNames[i]);\n+\t\t\t\ttry {\n+\t\t\t\t\tJobWithJars.checkJarFile(file);\n+\t\t\t\t} catch(final IOException e) {\n+\t\t\t\t\tthrow new RuntimeException(\"Problem with jar file \" + file.getAbsolutePath(), e);\n+\t\t\t\t}\n+\t\t\t\tjarFiles.add(file);\n+\t\t\t}\n+\t\t\t\n+\t\t\tfor(final File file : jarFiles) {\n+\t\t\t\tjobGraph.addJar(new Path(file.getAbsolutePath()));\n+\t\t\t}\n+\t\t\t\n+\t\t\tfinal Configuration configuration = jobGraph.getJobConfiguration();\n+\t\t\tfinal Client client = new Client(new InetSocketAddress(this.jobManagerHost, this.jobManagerPort),\n+\t\t\t\tconfiguration, JobWithJars.buildUserCodeClassLoader(jarFiles, JobWithJars.class.getClassLoader()), -1);\n+\t\t\t\n+\t\t\ttry {\n+\t\t\t\tfinal JobSubmissionResult result = client.run(jobGraph, false);\n+\t\t\t\tthis.topologyNameToJobId.put(name, result.getJobID());\n+\t\t\t\tthis.topologies.put(name, topology);\n+\t\t\t} catch(final ProgramInvocationException e) {\n+\t\t\t\tthrow new RuntimeException(\"Cannot execute job due to ProgramInvocationException\", e);\n+\t\t\t}\n+\t\t\t\n+\t\t} catch(final Exception e) {\n+\t\t\te.printStackTrace();\n+\t\t}\n+\t}\n+\t\n+\tpublic void killTopology(final String name) throws NotAliveException {\n+\t\tthis.killTopologyWithOpts(name, null);\n+\t}\n+\t\n+\t@SuppressWarnings(\"unused\")\n+\tpublic void killTopologyWithOpts(final String name, final KillOptions options) throws NotAliveException {\n+\t\tfinal Configuration configuration = GlobalConfiguration.getConfiguration();\n+\t\tif(this.timeout != null) {\n+\t\t\tconfiguration.setString(ConfigConstants.AKKA_ASK_TIMEOUT, this.timeout);\n+\t\t}\n+\t\tfinal FiniteDuration askTimeout = AkkaUtils.getTimeout(configuration);\n+\t\t\n+\t\tActorSystem actorSystem;\n+\t\ttry {\n+\t\t\tfinal scala.Tuple2<String, Object> systemEndpoint = new scala.Tuple2<String, Object>(\"\", new Integer(0));\n+\t\t\tactorSystem = AkkaUtils.createActorSystem(configuration, new Some<scala.Tuple2<String, Object>>(\n+\t\t\t\tsystemEndpoint));\n+\t\t} catch(final Exception e) {\n+\t\t\tthrow new RuntimeException(\"Could not start actor system to communicate with JobManager\", e);\n+\t\t}\n+\t\t\n+\t\tActorRef jobManager;\n+\t\ttry {\n+\t\t\tjobManager = JobManager.getJobManagerRemoteReference(new InetSocketAddress(this.jobManagerHost,\n+\t\t\t\tthis.jobManagerPort), actorSystem, AkkaUtils.getLookupTimeout(configuration));\n+\t\t\t\n+\t\t\tif(options != null) {\n+\t\t\t\ttry {\n+\t\t\t\t\tThread.sleep(1000 * options.get_wait_secs());\n+\t\t\t\t} catch(final InterruptedException e) {\n+\t\t\t\t\te.printStackTrace();\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\t\n+\t\t\tfinal Future<Object> response = Patterns.ask(jobManager, new CancelJob(this.topologyNameToJobId.get(name)),\n+\t\t\t\tnew Timeout(askTimeout));\n+\t\t\t\n+\t\t\ttry {\n+\t\t\t\tAwait.result(response, askTimeout);\n+\t\t\t} catch(final Exception e) {\n+\t\t\t\tthrow new RuntimeException(\"Killing topology \" + name + \" with Flink job ID \"\n+\t\t\t\t\t+ this.topologyNameToJobId.get(name) + \" failed.\", e);\n+\t\t\t}\n+\t\t\t\n+\t\t\tthis.topologyNameToJobId.remove(name);\n+\t\t\tthis.topologies.remove(name);\n+\t\t} catch(final IOException e) {\n+\t\t\tthrow new RuntimeException(\"Could not connect to Flink JobManager with address \" + this.jobManagerHost\n+\t\t\t\t+ \":\" + this.jobManagerPort, e);\n+\t\t}\n+\t}\n+\t\n+\t// not sure if the following methods can be supported or not...\n+\t\n+\t// public void activate(final String name) throws NotAliveException {}\n+\t\n+\t// public void deactivate(final String name) throws NotAliveException {}\n+\t\n+\t// public void rebalance(final String name, final RebalanceOptions options) throws NotAliveException,\n+\t// InvalidTopologyException {}\n+\t\n+\t// public String beginFileUpload() {\n+\t// return null;\n+\t// }\n+\t\n+\t// public void uploadChunk(final String location, final ByteBuffer chunk) {}\n+\t\n+\t// public void finishFileUpload(final String location) {}\n+\t\n+\t// public String beginFileDownload(final String file) {\n+\t// return null;\n+\t// }\n+\t\n+\t// public ByteBuffer downloadChunk(final String id) {\n+\t// return null;\n+\t// }\n+\t\n+\t// public void send_downloadChunk(final String id) {}\n+\t\n+\t// public String getNimbusConf() {\n+\t// return null;\n+\t// }","path":"flink-staging/flink-streaming/flink-storm-compatibility/src/main/java/org/apache/flink/stormcompatibility/api/FlinkClient.java","position":333,"original_position":333,"commit_id":"605de53a9990dbe2941261d1365654fe62a7c91d","original_commit_id":"605de53a9990dbe2941261d1365654fe62a7c91d","user":{"login":"mbalassi","id":5990983,"avatar_url":"https://avatars.githubusercontent.com/u/5990983?v=3","gravatar_id":"","url":"https://api.github.com/users/mbalassi","html_url":"https://github.com/mbalassi","followers_url":"https://api.github.com/users/mbalassi/followers","following_url":"https://api.github.com/users/mbalassi/following{/other_user}","gists_url":"https://api.github.com/users/mbalassi/gists{/gist_id}","starred_url":"https://api.github.com/users/mbalassi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbalassi/subscriptions","organizations_url":"https://api.github.com/users/mbalassi/orgs","repos_url":"https://api.github.com/users/mbalassi/repos","events_url":"https://api.github.com/users/mbalassi/events{/privacy}","received_events_url":"https://api.github.com/users/mbalassi/received_events","type":"User","site_admin":false},"body":"This is a bit too much comment here to merge, but we should definitely discuss these.","created_at":"2015-04-06T16:30:28Z","updated_at":"2015-04-06T16:30:28Z","html_url":"https://github.com/apache/flink/pull/573#discussion_r27808253","pull_request_url":"https://api.github.com/repos/apache/flink/pulls/573","_links":{"self":{"href":"https://api.github.com/repos/apache/flink/pulls/comments/27808253"},"html":{"href":"https://github.com/apache/flink/pull/573#discussion_r27808253"},"pull_request":{"href":"https://api.github.com/repos/apache/flink/pulls/573"}}},"pull_request":{"url":"https://api.github.com/repos/apache/flink/pulls/573","id":32688584,"html_url":"https://github.com/apache/flink/pull/573","diff_url":"https://github.com/apache/flink/pull/573.diff","patch_url":"https://github.com/apache/flink/pull/573.patch","issue_url":"https://api.github.com/repos/apache/flink/issues/573","number":573,"state":"open","locked":false,"title":"Flink Storm compatibility","user":{"login":"mjsax","id":8959638,"avatar_url":"https://avatars.githubusercontent.com/u/8959638?v=3","gravatar_id":"","url":"https://api.github.com/users/mjsax","html_url":"https://github.com/mjsax","followers_url":"https://api.github.com/users/mjsax/followers","following_url":"https://api.github.com/users/mjsax/following{/other_user}","gists_url":"https://api.github.com/users/mjsax/gists{/gist_id}","starred_url":"https://api.github.com/users/mjsax/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mjsax/subscriptions","organizations_url":"https://api.github.com/users/mjsax/orgs","repos_url":"https://api.github.com/users/mjsax/repos","events_url":"https://api.github.com/users/mjsax/events{/privacy}","received_events_url":"https://api.github.com/users/mjsax/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-04-06T16:11:27Z","updated_at":"2015-04-06T16:30:28Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e558285822e04a5be0197acbac95e9edf697b6af","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/apache/flink/pulls/573/commits","review_comments_url":"https://api.github.com/repos/apache/flink/pulls/573/comments","review_comment_url":"https://api.github.com/repos/apache/flink/pulls/comments{/number}","comments_url":"https://api.github.com/repos/apache/flink/issues/573/comments","statuses_url":"https://api.github.com/repos/apache/flink/statuses/605de53a9990dbe2941261d1365654fe62a7c91d","head":{"label":"mjsax:flink-storm-compatibility","ref":"flink-storm-compatibility","sha":"605de53a9990dbe2941261d1365654fe62a7c91d","user":{"login":"mjsax","id":8959638,"avatar_url":"https://avatars.githubusercontent.com/u/8959638?v=3","gravatar_id":"","url":"https://api.github.com/users/mjsax","html_url":"https://github.com/mjsax","followers_url":"https://api.github.com/users/mjsax/followers","following_url":"https://api.github.com/users/mjsax/following{/other_user}","gists_url":"https://api.github.com/users/mjsax/gists{/gist_id}","starred_url":"https://api.github.com/users/mjsax/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mjsax/subscriptions","organizations_url":"https://api.github.com/users/mjsax/orgs","repos_url":"https://api.github.com/users/mjsax/repos","events_url":"https://api.github.com/users/mjsax/events{/privacy}","received_events_url":"https://api.github.com/users/mjsax/received_events","type":"User","site_admin":false},"repo":{"id":28905963,"name":"flink","full_name":"mjsax/flink","owner":{"login":"mjsax","id":8959638,"avatar_url":"https://avatars.githubusercontent.com/u/8959638?v=3","gravatar_id":"","url":"https://api.github.com/users/mjsax","html_url":"https://github.com/mjsax","followers_url":"https://api.github.com/users/mjsax/followers","following_url":"https://api.github.com/users/mjsax/following{/other_user}","gists_url":"https://api.github.com/users/mjsax/gists{/gist_id}","starred_url":"https://api.github.com/users/mjsax/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mjsax/subscriptions","organizations_url":"https://api.github.com/users/mjsax/orgs","repos_url":"https://api.github.com/users/mjsax/repos","events_url":"https://api.github.com/users/mjsax/events{/privacy}","received_events_url":"https://api.github.com/users/mjsax/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/mjsax/flink","description":"Mirror of Apache Flink","fork":true,"url":"https://api.github.com/repos/mjsax/flink","forks_url":"https://api.github.com/repos/mjsax/flink/forks","keys_url":"https://api.github.com/repos/mjsax/flink/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mjsax/flink/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mjsax/flink/teams","hooks_url":"https://api.github.com/repos/mjsax/flink/hooks","issue_events_url":"https://api.github.com/repos/mjsax/flink/issues/events{/number}","events_url":"https://api.github.com/repos/mjsax/flink/events","assignees_url":"https://api.github.com/repos/mjsax/flink/assignees{/user}","branches_url":"https://api.github.com/repos/mjsax/flink/branches{/branch}","tags_url":"https://api.github.com/repos/mjsax/flink/tags","blobs_url":"https://api.github.com/repos/mjsax/flink/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mjsax/flink/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mjsax/flink/git/refs{/sha}","trees_url":"https://api.github.com/repos/mjsax/flink/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mjsax/flink/statuses/{sha}","languages_url":"https://api.github.com/repos/mjsax/flink/languages","stargazers_url":"https://api.github.com/repos/mjsax/flink/stargazers","contributors_url":"https://api.github.com/repos/mjsax/flink/contributors","subscribers_url":"https://api.github.com/repos/mjsax/flink/subscribers","subscription_url":"https://api.github.com/repos/mjsax/flink/subscription","commits_url":"https://api.github.com/repos/mjsax/flink/commits{/sha}","git_commits_url":"https://api.github.com/repos/mjsax/flink/git/commits{/sha}","comments_url":"https://api.github.com/repos/mjsax/flink/comments{/number}","issue_comment_url":"https://api.github.com/repos/mjsax/flink/issues/comments{/number}","contents_url":"https://api.github.com/repos/mjsax/flink/contents/{+path}","compare_url":"https://api.github.com/repos/mjsax/flink/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mjsax/flink/merges","archive_url":"https://api.github.com/repos/mjsax/flink/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mjsax/flink/downloads","issues_url":"https://api.github.com/repos/mjsax/flink/issues{/number}","pulls_url":"https://api.github.com/repos/mjsax/flink/pulls{/number}","milestones_url":"https://api.github.com/repos/mjsax/flink/milestones{/number}","notifications_url":"https://api.github.com/repos/mjsax/flink/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mjsax/flink/labels{/name}","releases_url":"https://api.github.com/repos/mjsax/flink/releases{/id}","created_at":"2015-01-07T08:38:24Z","updated_at":"2015-03-20T16:25:44Z","pushed_at":"2015-04-06T13:41:08Z","git_url":"git://github.com/mjsax/flink.git","ssh_url":"git@github.com:mjsax/flink.git","clone_url":"https://github.com/mjsax/flink.git","svn_url":"https://github.com/mjsax/flink","homepage":null,"size":45151,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"apache:master","ref":"master","sha":"12c555f5f31aa6a14d39d2a96bcf7412ec17495f","user":{"login":"apache","id":47359,"avatar_url":"https://avatars.githubusercontent.com/u/47359?v=3","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"repo":{"id":20587599,"name":"flink","full_name":"apache/flink","owner":{"login":"apache","id":47359,"avatar_url":"https://avatars.githubusercontent.com/u/47359?v=3","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/apache/flink","description":"Mirror of Apache Flink","fork":false,"url":"https://api.github.com/repos/apache/flink","forks_url":"https://api.github.com/repos/apache/flink/forks","keys_url":"https://api.github.com/repos/apache/flink/keys{/key_id}","collaborators_url":"https://api.github.com/repos/apache/flink/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/apache/flink/teams","hooks_url":"https://api.github.com/repos/apache/flink/hooks","issue_events_url":"https://api.github.com/repos/apache/flink/issues/events{/number}","events_url":"https://api.github.com/repos/apache/flink/events","assignees_url":"https://api.github.com/repos/apache/flink/assignees{/user}","branches_url":"https://api.github.com/repos/apache/flink/branches{/branch}","tags_url":"https://api.github.com/repos/apache/flink/tags","blobs_url":"https://api.github.com/repos/apache/flink/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/apache/flink/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/apache/flink/git/refs{/sha}","trees_url":"https://api.github.com/repos/apache/flink/git/trees{/sha}","statuses_url":"https://api.github.com/repos/apache/flink/statuses/{sha}","languages_url":"https://api.github.com/repos/apache/flink/languages","stargazers_url":"https://api.github.com/repos/apache/flink/stargazers","contributors_url":"https://api.github.com/repos/apache/flink/contributors","subscribers_url":"https://api.github.com/repos/apache/flink/subscribers","subscription_url":"https://api.github.com/repos/apache/flink/subscription","commits_url":"https://api.github.com/repos/apache/flink/commits{/sha}","git_commits_url":"https://api.github.com/repos/apache/flink/git/commits{/sha}","comments_url":"https://api.github.com/repos/apache/flink/comments{/number}","issue_comment_url":"https://api.github.com/repos/apache/flink/issues/comments{/number}","contents_url":"https://api.github.com/repos/apache/flink/contents/{+path}","compare_url":"https://api.github.com/repos/apache/flink/compare/{base}...{head}","merges_url":"https://api.github.com/repos/apache/flink/merges","archive_url":"https://api.github.com/repos/apache/flink/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/apache/flink/downloads","issues_url":"https://api.github.com/repos/apache/flink/issues{/number}","pulls_url":"https://api.github.com/repos/apache/flink/pulls{/number}","milestones_url":"https://api.github.com/repos/apache/flink/milestones{/number}","notifications_url":"https://api.github.com/repos/apache/flink/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/apache/flink/labels{/name}","releases_url":"https://api.github.com/repos/apache/flink/releases{/id}","created_at":"2014-06-07T07:00:10Z","updated_at":"2015-04-06T15:49:55Z","pushed_at":"2015-04-06T16:11:27Z","git_url":"git://github.com/apache/flink.git","ssh_url":"git@github.com:apache/flink.git","clone_url":"https://github.com/apache/flink.git","svn_url":"https://github.com/apache/flink","homepage":null,"size":2912014,"stargazers_count":350,"watchers_count":350,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":201,"mirror_url":"git://git.apache.org/incubator-flink.git","open_issues_count":41,"forks":201,"open_issues":41,"watchers":350,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/apache/flink/pulls/573"},"html":{"href":"https://github.com/apache/flink/pull/573"},"issue":{"href":"https://api.github.com/repos/apache/flink/issues/573"},"comments":{"href":"https://api.github.com/repos/apache/flink/issues/573/comments"},"review_comments":{"href":"https://api.github.com/repos/apache/flink/pulls/573/comments"},"review_comment":{"href":"https://api.github.com/repos/apache/flink/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/apache/flink/pulls/573/commits"},"statuses":{"href":"https://api.github.com/repos/apache/flink/statuses/605de53a9990dbe2941261d1365654fe62a7c91d"}}}}