{"action":"created","comment":{"url":"https://api.github.com/repos/caskdata/cdap/pulls/comments/54826575","id":54826575,"diff_hunk":"@@ -0,0 +1,226 @@\n+/*\n+ * Copyright © 2016 Cask Data, Inc.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n+ * use this file except in compliance with the License. You may obtain a copy of\n+ * 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, WITHOUT\n+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n+ * License for the specific language governing permissions and limitations under\n+ * the License.\n+ */\n+\n+class myLineageService {\n+\n+  /**\n+   *  Takes in the response from backend, and returns an object with list of\n+   *  nodes and connections.\n+   **/\n+  parseLineageResponse(response, params) {\n+    let currentActiveNode = [\n+      params.entityType === 'datasets' ? 'dataset' : 'stream',\n+      params.namespace,\n+      params.entityId\n+    ].join('.');\n+\n+    let connections = [];\n+    let uniqueNodes = {};\n+    let nodes = [];\n+\n+    /* SETTING NODES */\n+    angular.forEach(response.programs, (value, key) => {\n+      let nodeObj = {\n+        label: value.entityId.id.id,\n+        id: key,\n+        nodeType: 'program',\n+        applicationId: value.entityId.id.application.applicationId,\n+        entityId: value.entityId.id.id,\n+        entityType: this.parseProgramType(value.entityId.id.type),\n+        displayType: value.entityId.id.type,\n+        icon: this.getProgramIcon(value.entityId.id.type),\n+        runs: []\n+      };\n+\n+      uniqueNodes[key] = nodeObj;\n+    });\n+\n+    angular.forEach(response.data, (value, key) => {\n+      let data = this.parseDataInfo(value);\n+\n+      let nodeObj = {\n+        label: data.name,\n+        id: key,\n+        nodeType: 'data',\n+        entityId: data.name,\n+        entityType: data.type,\n+        displayType: data.displayType,\n+        icon: data.icon\n+      };\n+\n+      uniqueNodes[key] = nodeObj;\n+    });\n+\n+\n+    /* SETTING CONNECTIONS */\n+    angular.forEach(response.relations, (rel) => {\n+      let isUnknownOrBoth = rel.access === 'both' || rel.access === 'unknown';\n+\n+      if (rel.access === 'read' || isUnknownOrBoth) {\n+        let dataId = rel.data === currentActiveNode ? rel.data : rel.data + '-read';\n+        let programId = rel.data === currentActiveNode ? rel.program + '-read' : rel.program + '-write';\n+        connections.push({\n+          source: dataId,\n+          target: programId,\n+          type: 'read'\n+        });\n+\n+        nodes.push({\n+          dataId: dataId,\n+          uniqueNodeId: rel.data,\n+          isLeftEdge: rel.data !== currentActiveNode\n+        });\n+        nodes.push({\n+          dataId: programId,\n+          uniqueNodeId: rel.program\n+        });\n+      }\n+\n+      if (rel.access === 'write' || isUnknownOrBoth) {\n+        let dataId = rel.data === currentActiveNode ? rel.data : rel.data + '-write';\n+        let programId = rel.data === currentActiveNode ? rel.program + '-write' : rel.program + '-read';\n+        connections.push({\n+          source: programId,\n+          target: dataId,\n+          type: 'write'\n+        });\n+\n+        nodes.push({\n+          dataId: dataId,\n+          uniqueNodeId: rel.data,\n+          isRightEdge: rel.data !== currentActiveNode\n+        });\n+        nodes.push({\n+          dataId: programId,\n+          uniqueNodeId: rel.program\n+        });\n+      }\n+\n+      uniqueNodes[rel.program].runs = uniqueNodes[rel.program].runs.concat(rel.runs);\n+      uniqueNodes[rel.program].runs = _.uniq(uniqueNodes[rel.program].runs);\n+    });\n+\n+    nodes = _.uniq(nodes, (n) => { return n.dataId; });\n+    let graph = this.getGraphLayout(nodes, connections);\n+    this.mapNodesLocation(nodes, graph);\n+\n+    return {\n+      connections: connections,\n+      nodes: nodes,\n+      uniqueNodes: uniqueNodes,\n+      graph: graph\n+    };\n+  }\n+\n+  parseProgramType(programType) {\n+    let program = '';\n+    switch (programType) {\n+      case 'Flow':\n+        program = 'flows';\n+        break;\n+      case 'Mapreduce':\n+        program = 'mapreduce';\n+        break;\n+      case 'Spark':\n+        program = 'spark';\n+        break;\n+      case 'Worker':\n+        program = 'workers';\n+        break;\n+      case 'Workflow':\n+        program = 'workflows';\n+        break;\n+      case 'Service':\n+        program = 'services';\n+        break;\n+    }\n+\n+    return program;\n+  }\n+\n+  parseDataInfo(data) {\n+    let obj = {};\n+    if (data.entityId.type === 'datasetinstance') {\n+      obj = {\n+        name: data.entityId.id.instanceId,\n+        type: 'datasets',\n+        icon: 'icon-datasets',\n+        displayType: 'Dataset'\n+      };\n+    } else {\n+      obj = {\n+        name: data.entityId.id.streamName,\n+        type: 'streams',\n+        icon: 'icon-streams',\n+        displayType: 'Stream'\n+      };\n+    }\n+\n+    return obj;\n+  }\n+\n+  getProgramIcon(programType) {\n+    let iconMap = {\n+      'Flow': 'icon-tigon',\n+      'Mapreduce': 'icon-mapreduce',\n+      'Spark': 'icon-spark',\n+      'Worker': 'icon-worker',\n+      'Workflow': 'icon-workflow',\n+      'Service': 'icon-service'\n+    };\n+\n+    return iconMap[programType];\n+  }\n+\n+  getGraphLayout(nodes, connections) {\n+    var graph = new dagre.graphlib.Graph();\n+    graph.setGraph({\n+      nodesep: 90,\n+      ranksep: 50,\n+      rankdir: 'LR',\n+      marginx: 90,\n+      marginy: 25\n+    });\n+    graph.setDefaultEdgeLabel(function() { return {}; });\n+\n+    angular.forEach(nodes, (node) => {\n+      var id = node.dataId;\n+      graph.setNode(id, { width: 175, height: 55 });\n+    });\n+\n+    angular.forEach(connections, (connection) => {\n+      graph.setEdge(connection.source, connection.target);\n+    });\n+\n+    dagre.layout(graph);\n+\n+    return graph;\n+  }\n+\n+  mapNodesLocation(nodes, graph) {\n+    angular.forEach(nodes, (node) => {\n+      node._uiLocation = {\n+        top: graph._nodes[node.dataId].y + 'px',\n+        left: graph._nodes[node.dataId].x + 'px'\n+      };\n+    });\n+  }\n+}\n+\n+myLineageService.$inject = [];\n+\n+angular.module(PKG.name + '.feature.tracker')\n+  .service('myLineageService', myLineageService);","path":"cdap-ui/app/features/tracker/services/my-lineage-service.js","position":226,"original_position":226,"commit_id":"aa3308919208bb2fbed85872ea20ed3254331484","original_commit_id":"384b571dc280d4dda6c3f0fa4a5c74f0dff8bb83","user":{"login":"elfenheart","id":4398643,"avatar_url":"https://avatars.githubusercontent.com/u/4398643?v=3","gravatar_id":"","url":"https://api.github.com/users/elfenheart","html_url":"https://github.com/elfenheart","followers_url":"https://api.github.com/users/elfenheart/followers","following_url":"https://api.github.com/users/elfenheart/following{/other_user}","gists_url":"https://api.github.com/users/elfenheart/gists{/gist_id}","starred_url":"https://api.github.com/users/elfenheart/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elfenheart/subscriptions","organizations_url":"https://api.github.com/users/elfenheart/orgs","repos_url":"https://api.github.com/users/elfenheart/repos","events_url":"https://api.github.com/users/elfenheart/events{/privacy}","received_events_url":"https://api.github.com/users/elfenheart/received_events","type":"User","site_admin":false},"body":"more like convention, anything we prefix with 'my' start with lowercase. The flux services is UpperCase","created_at":"2016-03-03T02:05:12Z","updated_at":"2016-03-03T02:05:12Z","html_url":"https://github.com/caskdata/cdap/pull/5225#discussion_r54826575","pull_request_url":"https://api.github.com/repos/caskdata/cdap/pulls/5225","_links":{"self":{"href":"https://api.github.com/repos/caskdata/cdap/pulls/comments/54826575"},"html":{"href":"https://github.com/caskdata/cdap/pull/5225#discussion_r54826575"},"pull_request":{"href":"https://api.github.com/repos/caskdata/cdap/pulls/5225"}}},"pull_request":{"url":"https://api.github.com/repos/caskdata/cdap/pulls/5225","id":61498074,"html_url":"https://github.com/caskdata/cdap/pull/5225","diff_url":"https://github.com/caskdata/cdap/pull/5225.diff","patch_url":"https://github.com/caskdata/cdap/pull/5225.patch","issue_url":"https://api.github.com/repos/caskdata/cdap/issues/5225","number":5225,"state":"open","locked":false,"title":"[CDAP-5008] Feature/ui traker lineage","user":{"login":"elfenheart","id":4398643,"avatar_url":"https://avatars.githubusercontent.com/u/4398643?v=3","gravatar_id":"","url":"https://api.github.com/users/elfenheart","html_url":"https://github.com/elfenheart","followers_url":"https://api.github.com/users/elfenheart/followers","following_url":"https://api.github.com/users/elfenheart/following{/other_user}","gists_url":"https://api.github.com/users/elfenheart/gists{/gist_id}","starred_url":"https://api.github.com/users/elfenheart/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elfenheart/subscriptions","organizations_url":"https://api.github.com/users/elfenheart/orgs","repos_url":"https://api.github.com/users/elfenheart/repos","events_url":"https://api.github.com/users/elfenheart/events{/privacy}","received_events_url":"https://api.github.com/users/elfenheart/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-03-03T01:40:46Z","updated_at":"2016-03-03T02:05:12Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3884439aff664f7adc0ed15e04f5f37b1c55df5c","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/caskdata/cdap/pulls/5225/commits","review_comments_url":"https://api.github.com/repos/caskdata/cdap/pulls/5225/comments","review_comment_url":"https://api.github.com/repos/caskdata/cdap/pulls/comments{/number}","comments_url":"https://api.github.com/repos/caskdata/cdap/issues/5225/comments","statuses_url":"https://api.github.com/repos/caskdata/cdap/statuses/aa3308919208bb2fbed85872ea20ed3254331484","head":{"label":"caskdata:feature/ui-traker-lineage","ref":"feature/ui-traker-lineage","sha":"aa3308919208bb2fbed85872ea20ed3254331484","user":{"login":"caskdata","id":8123023,"avatar_url":"https://avatars.githubusercontent.com/u/8123023?v=3","gravatar_id":"","url":"https://api.github.com/users/caskdata","html_url":"https://github.com/caskdata","followers_url":"https://api.github.com/users/caskdata/followers","following_url":"https://api.github.com/users/caskdata/following{/other_user}","gists_url":"https://api.github.com/users/caskdata/gists{/gist_id}","starred_url":"https://api.github.com/users/caskdata/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caskdata/subscriptions","organizations_url":"https://api.github.com/users/caskdata/orgs","repos_url":"https://api.github.com/users/caskdata/repos","events_url":"https://api.github.com/users/caskdata/events{/privacy}","received_events_url":"https://api.github.com/users/caskdata/received_events","type":"Organization","site_admin":false},"repo":{"id":22542759,"name":"cdap","full_name":"caskdata/cdap","owner":{"login":"caskdata","id":8123023,"avatar_url":"https://avatars.githubusercontent.com/u/8123023?v=3","gravatar_id":"","url":"https://api.github.com/users/caskdata","html_url":"https://github.com/caskdata","followers_url":"https://api.github.com/users/caskdata/followers","following_url":"https://api.github.com/users/caskdata/following{/other_user}","gists_url":"https://api.github.com/users/caskdata/gists{/gist_id}","starred_url":"https://api.github.com/users/caskdata/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caskdata/subscriptions","organizations_url":"https://api.github.com/users/caskdata/orgs","repos_url":"https://api.github.com/users/caskdata/repos","events_url":"https://api.github.com/users/caskdata/events{/privacy}","received_events_url":"https://api.github.com/users/caskdata/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/caskdata/cdap","description":"Cask Data Application Platform (CDAP)","fork":false,"url":"https://api.github.com/repos/caskdata/cdap","forks_url":"https://api.github.com/repos/caskdata/cdap/forks","keys_url":"https://api.github.com/repos/caskdata/cdap/keys{/key_id}","collaborators_url":"https://api.github.com/repos/caskdata/cdap/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/caskdata/cdap/teams","hooks_url":"https://api.github.com/repos/caskdata/cdap/hooks","issue_events_url":"https://api.github.com/repos/caskdata/cdap/issues/events{/number}","events_url":"https://api.github.com/repos/caskdata/cdap/events","assignees_url":"https://api.github.com/repos/caskdata/cdap/assignees{/user}","branches_url":"https://api.github.com/repos/caskdata/cdap/branches{/branch}","tags_url":"https://api.github.com/repos/caskdata/cdap/tags","blobs_url":"https://api.github.com/repos/caskdata/cdap/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/caskdata/cdap/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/caskdata/cdap/git/refs{/sha}","trees_url":"https://api.github.com/repos/caskdata/cdap/git/trees{/sha}","statuses_url":"https://api.github.com/repos/caskdata/cdap/statuses/{sha}","languages_url":"https://api.github.com/repos/caskdata/cdap/languages","stargazers_url":"https://api.github.com/repos/caskdata/cdap/stargazers","contributors_url":"https://api.github.com/repos/caskdata/cdap/contributors","subscribers_url":"https://api.github.com/repos/caskdata/cdap/subscribers","subscription_url":"https://api.github.com/repos/caskdata/cdap/subscription","commits_url":"https://api.github.com/repos/caskdata/cdap/commits{/sha}","git_commits_url":"https://api.github.com/repos/caskdata/cdap/git/commits{/sha}","comments_url":"https://api.github.com/repos/caskdata/cdap/comments{/number}","issue_comment_url":"https://api.github.com/repos/caskdata/cdap/issues/comments{/number}","contents_url":"https://api.github.com/repos/caskdata/cdap/contents/{+path}","compare_url":"https://api.github.com/repos/caskdata/cdap/compare/{base}...{head}","merges_url":"https://api.github.com/repos/caskdata/cdap/merges","archive_url":"https://api.github.com/repos/caskdata/cdap/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/caskdata/cdap/downloads","issues_url":"https://api.github.com/repos/caskdata/cdap/issues{/number}","pulls_url":"https://api.github.com/repos/caskdata/cdap/pulls{/number}","milestones_url":"https://api.github.com/repos/caskdata/cdap/milestones{/number}","notifications_url":"https://api.github.com/repos/caskdata/cdap/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/caskdata/cdap/labels{/name}","releases_url":"https://api.github.com/repos/caskdata/cdap/releases{/id}","deployments_url":"https://api.github.com/repos/caskdata/cdap/deployments","created_at":"2014-08-02T09:00:10Z","updated_at":"2016-02-26T00:00:39Z","pushed_at":"2016-03-03T02:00:59Z","git_url":"git://github.com/caskdata/cdap.git","ssh_url":"git@github.com:caskdata/cdap.git","clone_url":"https://github.com/caskdata/cdap.git","svn_url":"https://github.com/caskdata/cdap","homepage":"http://cdap.io","size":531890,"stargazers_count":103,"watchers_count":103,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":36,"mirror_url":null,"open_issues_count":15,"forks":36,"open_issues":15,"watchers":103,"default_branch":"develop"}},"base":{"label":"caskdata:develop","ref":"develop","sha":"1c0c91ae03da30311b964d67663d3ad65cdada87","user":{"login":"caskdata","id":8123023,"avatar_url":"https://avatars.githubusercontent.com/u/8123023?v=3","gravatar_id":"","url":"https://api.github.com/users/caskdata","html_url":"https://github.com/caskdata","followers_url":"https://api.github.com/users/caskdata/followers","following_url":"https://api.github.com/users/caskdata/following{/other_user}","gists_url":"https://api.github.com/users/caskdata/gists{/gist_id}","starred_url":"https://api.github.com/users/caskdata/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caskdata/subscriptions","organizations_url":"https://api.github.com/users/caskdata/orgs","repos_url":"https://api.github.com/users/caskdata/repos","events_url":"https://api.github.com/users/caskdata/events{/privacy}","received_events_url":"https://api.github.com/users/caskdata/received_events","type":"Organization","site_admin":false},"repo":{"id":22542759,"name":"cdap","full_name":"caskdata/cdap","owner":{"login":"caskdata","id":8123023,"avatar_url":"https://avatars.githubusercontent.com/u/8123023?v=3","gravatar_id":"","url":"https://api.github.com/users/caskdata","html_url":"https://github.com/caskdata","followers_url":"https://api.github.com/users/caskdata/followers","following_url":"https://api.github.com/users/caskdata/following{/other_user}","gists_url":"https://api.github.com/users/caskdata/gists{/gist_id}","starred_url":"https://api.github.com/users/caskdata/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caskdata/subscriptions","organizations_url":"https://api.github.com/users/caskdata/orgs","repos_url":"https://api.github.com/users/caskdata/repos","events_url":"https://api.github.com/users/caskdata/events{/privacy}","received_events_url":"https://api.github.com/users/caskdata/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/caskdata/cdap","description":"Cask Data Application Platform (CDAP)","fork":false,"url":"https://api.github.com/repos/caskdata/cdap","forks_url":"https://api.github.com/repos/caskdata/cdap/forks","keys_url":"https://api.github.com/repos/caskdata/cdap/keys{/key_id}","collaborators_url":"https://api.github.com/repos/caskdata/cdap/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/caskdata/cdap/teams","hooks_url":"https://api.github.com/repos/caskdata/cdap/hooks","issue_events_url":"https://api.github.com/repos/caskdata/cdap/issues/events{/number}","events_url":"https://api.github.com/repos/caskdata/cdap/events","assignees_url":"https://api.github.com/repos/caskdata/cdap/assignees{/user}","branches_url":"https://api.github.com/repos/caskdata/cdap/branches{/branch}","tags_url":"https://api.github.com/repos/caskdata/cdap/tags","blobs_url":"https://api.github.com/repos/caskdata/cdap/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/caskdata/cdap/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/caskdata/cdap/git/refs{/sha}","trees_url":"https://api.github.com/repos/caskdata/cdap/git/trees{/sha}","statuses_url":"https://api.github.com/repos/caskdata/cdap/statuses/{sha}","languages_url":"https://api.github.com/repos/caskdata/cdap/languages","stargazers_url":"https://api.github.com/repos/caskdata/cdap/stargazers","contributors_url":"https://api.github.com/repos/caskdata/cdap/contributors","subscribers_url":"https://api.github.com/repos/caskdata/cdap/subscribers","subscription_url":"https://api.github.com/repos/caskdata/cdap/subscription","commits_url":"https://api.github.com/repos/caskdata/cdap/commits{/sha}","git_commits_url":"https://api.github.com/repos/caskdata/cdap/git/commits{/sha}","comments_url":"https://api.github.com/repos/caskdata/cdap/comments{/number}","issue_comment_url":"https://api.github.com/repos/caskdata/cdap/issues/comments{/number}","contents_url":"https://api.github.com/repos/caskdata/cdap/contents/{+path}","compare_url":"https://api.github.com/repos/caskdata/cdap/compare/{base}...{head}","merges_url":"https://api.github.com/repos/caskdata/cdap/merges","archive_url":"https://api.github.com/repos/caskdata/cdap/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/caskdata/cdap/downloads","issues_url":"https://api.github.com/repos/caskdata/cdap/issues{/number}","pulls_url":"https://api.github.com/repos/caskdata/cdap/pulls{/number}","milestones_url":"https://api.github.com/repos/caskdata/cdap/milestones{/number}","notifications_url":"https://api.github.com/repos/caskdata/cdap/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/caskdata/cdap/labels{/name}","releases_url":"https://api.github.com/repos/caskdata/cdap/releases{/id}","deployments_url":"https://api.github.com/repos/caskdata/cdap/deployments","created_at":"2014-08-02T09:00:10Z","updated_at":"2016-02-26T00:00:39Z","pushed_at":"2016-03-03T02:00:59Z","git_url":"git://github.com/caskdata/cdap.git","ssh_url":"git@github.com:caskdata/cdap.git","clone_url":"https://github.com/caskdata/cdap.git","svn_url":"https://github.com/caskdata/cdap","homepage":"http://cdap.io","size":531890,"stargazers_count":103,"watchers_count":103,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":36,"mirror_url":null,"open_issues_count":15,"forks":36,"open_issues":15,"watchers":103,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/caskdata/cdap/pulls/5225"},"html":{"href":"https://github.com/caskdata/cdap/pull/5225"},"issue":{"href":"https://api.github.com/repos/caskdata/cdap/issues/5225"},"comments":{"href":"https://api.github.com/repos/caskdata/cdap/issues/5225/comments"},"review_comments":{"href":"https://api.github.com/repos/caskdata/cdap/pulls/5225/comments"},"review_comment":{"href":"https://api.github.com/repos/caskdata/cdap/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/caskdata/cdap/pulls/5225/commits"},"statuses":{"href":"https://api.github.com/repos/caskdata/cdap/statuses/aa3308919208bb2fbed85872ea20ed3254331484"}}}}