{"action":"created","comment":{"url":"https://api.github.com/repos/telstra/open-kilda/pulls/comments/237904203","pull_request_review_id":180283545,"id":237904203,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzNzkwNDIwMw==","diff_hunk":"@@ -0,0 +1,301 @@\n+/* Copyright 2018 Telstra Open Source\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+package org.openkilda.pce.impl;\n+\n+import static java.lang.String.format;\n+import static java.util.Collections.emptyList;\n+import static java.util.stream.Collectors.toSet;\n+\n+import org.openkilda.model.Isl;\n+import org.openkilda.model.Switch;\n+import org.openkilda.model.SwitchId;\n+\n+import com.google.common.collect.Lists;\n+import lombok.Value;\n+import lombok.extern.slf4j.Slf4j;\n+import org.apache.commons.lang3.tuple.Pair;\n+\n+import java.util.ArrayList;\n+import java.util.Comparator;\n+import java.util.Deque;\n+import java.util.HashMap;\n+import java.util.LinkedList;\n+import java.util.List;\n+import java.util.Map;\n+import java.util.Set;\n+import java.util.stream.Collectors;\n+\n+/**\n+ * This algorithm is optimized for finding a bidirectional path between the start and end nodes. It uses elements of\n+ * depth first, breadth first, and shortest path (weight) algorithms.\n+ * <p/>\n+ * For neighboring switches, it assumes there is only one link between them. The network that is passed in should\n+ * reflect the links that should be traversed.\n+ * <p/>\n+ * Algorithm Notes: 1. forward = get path (src, dst) 2. reverse = get path (dst, src, hint=forward) 3 get path: 0.\n+ * allowedDepth = 35 √ . go breadth first (majority of switches probably have 5 hops or less) √ . add cost . compare\n+ * against bestCost (if greater, then return) . have we visited this node before? - if so, was it cheaper? Yes? return.\n+ * - No, remove the prior put. We and any downstream cost (BUT .. maybe we stopped somewhere and need to continue?\n+ * Probably could just replace the old one with the current one and add the children as unvisited? Oooh .. this could\n+ * cause a loop.. if there are negative costs - So, should probably track path to this point... . if node = target,\n+ * update bestCost, return . add each neighbor to the investigation list, where neighbor.outbound.dst != current node.\n+ */\n+@Slf4j\n+public class BestCostAndShortestPathFinder implements PathFinder {\n+    private final int allowedDepth;\n+    private final int defaultLinkCost;\n+\n+    /**\n+     * Constructs the finder with the specified limit on path depth.\n+     *\n+     * @param allowedDepth    the allowed depth for a potential path.\n+     * @param defaultLinkCost the default cost for links if not defined.\n+     */\n+    public BestCostAndShortestPathFinder(int allowedDepth, int defaultLinkCost) {\n+        this.allowedDepth = allowedDepth;\n+        this.defaultLinkCost = defaultLinkCost;\n+    }\n+\n+    @Override\n+    public Pair<List<Isl>, List<Isl>> findPathInNetwork(AvailableNetwork network,\n+                                                        SwitchId startSwitchId, SwitchId endSwitchId)\n+            throws SwitchNotFoundException {\n+        Switch start = network.getSwitch(startSwitchId);\n+        if (start == null) {\n+            throw new SwitchNotFoundException(\n+                    format(\"SOURCE node doesn't exist. It isn't in the AVAILABLE network: %s\", startSwitchId));\n+        }\n+\n+        Switch end = network.getSwitch(endSwitchId);\n+        if (end == null) {\n+            throw new SwitchNotFoundException(\n+                    format(\"DESTINATION node doesn't exist. It isn't in the AVAILABLE network: %s\", endSwitchId));\n+        }\n+\n+        List<Isl> forwardPath = getPath(start, end, Integer.MAX_VALUE);\n+        List<Isl> reversePath = getPath(end, start, Integer.MAX_VALUE, forwardPath);\n+        return Pair.of(forwardPath, reversePath);\n+    }\n+\n+    /**\n+     * Call this method to find a path from start to end (srcDpid to dstDpid), particularly if you have no idea if the\n+     * path exists or what the best path is.\n+     *\n+     * @return An ordered list that represents the path from start to end, or an empty list\n+     */\n+    private List<Isl> getPath(Switch start, Switch end, long maximumCost) {\n+        long bestCost = maximumCost; // Need to be long because it stores sum of ints.\n+        SearchNode bestPath = null;\n+\n+        Deque<SearchNode> toVisit = new LinkedList<>(); // working list\n+        Map<Switch, SearchNode> visited = new HashMap<>();\n+\n+        toVisit.add(new SearchNode(start, allowedDepth, 0, emptyList()));\n+\n+        while (!toVisit.isEmpty()) {\n+            SearchNode current = toVisit.pop();\n+\n+            // Determine if this node is the destination node.\n+            if (current.dstSw.equals(end)) {\n+                // We found the destination\n+                if (current.parentCost < bestCost) {\n+                    // We found a best path. If we don't get here, then the entire graph will be\n+                    // searched until we run out of nodes or the depth is reached.\n+                    bestCost = current.parentCost;\n+                    bestPath = current;\n+                }\n+                // We found dest, no need to keep processing\n+                continue;\n+            }\n+\n+            // Otherwise, if we've been here before, see if this path is better\n+            SearchNode prior = visited.get(current.dstSw);\n+            if (prior != null && current.parentCost >= prior.parentCost) {\n+                continue;\n+            }\n+\n+            // Stop processing entirely if we've gone too far, or over bestCost\n+            if (current.allowedDepth <= 0 || current.parentCost > bestCost) {\n+                continue;\n+            }\n+\n+            // Either this is the first time, or this is cheaper .. either way, this node should\n+            // be the one in the visited list\n+            visited.put(current.dstSw, current);\n+\n+\n+            // At this stage .. haven't found END, haven't gone too deep, and we are not over cost.\n+            // So, add the outbound isls.\n+            current.dstSw.getOutgoingLinks().stream()\n+                    .sorted(Comparator.comparing(isl -> isl.getDestSwitch().getSwitchId()))","path":"services/src/kilda-pce/src/main/java/org/openkilda/pce/impl/BestCostAndShortestPathFinder.java","position":143,"original_position":143,"commit_id":"02c5f5163ee46627630aba3927ce7e0c9e4b7150","original_commit_id":"02c5f5163ee46627630aba3927ce7e0c9e4b7150","user":{"login":"Settis","id":1427656,"node_id":"MDQ6VXNlcjE0Mjc2NTY=","avatar_url":"https://avatars3.githubusercontent.com/u/1427656?v=4","gravatar_id":"","url":"https://api.github.com/users/Settis","html_url":"https://github.com/Settis","followers_url":"https://api.github.com/users/Settis/followers","following_url":"https://api.github.com/users/Settis/following{/other_user}","gists_url":"https://api.github.com/users/Settis/gists{/gist_id}","starred_url":"https://api.github.com/users/Settis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Settis/subscriptions","organizations_url":"https://api.github.com/users/Settis/orgs","repos_url":"https://api.github.com/users/Settis/repos","events_url":"https://api.github.com/users/Settis/events{/privacy}","received_events_url":"https://api.github.com/users/Settis/received_events","type":"User","site_admin":false},"body":"Why are you sorting ISLs here? As I understand you make depth search and sorting here doesn't help much. What about using PriorityQueue for toVisit instead on LinkedList?","created_at":"2018-11-30T15:45:04Z","updated_at":"2018-11-30T15:52:15Z","html_url":"https://github.com/telstra/open-kilda/pull/1448#discussion_r237904203","pull_request_url":"https://api.github.com/repos/telstra/open-kilda/pulls/1448","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/telstra/open-kilda/pulls/comments/237904203"},"html":{"href":"https://github.com/telstra/open-kilda/pull/1448#discussion_r237904203"},"pull_request":{"href":"https://api.github.com/repos/telstra/open-kilda/pulls/1448"}}},"pull_request":{"url":"https://api.github.com/repos/telstra/open-kilda/pulls/1448","id":222509865,"node_id":"MDExOlB1bGxSZXF1ZXN0MjIyNTA5ODY1","html_url":"https://github.com/telstra/open-kilda/pull/1448","diff_url":"https://github.com/telstra/open-kilda/pull/1448.diff","patch_url":"https://github.com/telstra/open-kilda/pull/1448.patch","issue_url":"https://api.github.com/repos/telstra/open-kilda/issues/1448","number":1448,"state":"open","locked":false,"title":"Reimplement PathComputation and NeoOperationsBolts to use DAO","user":{"login":"sergii-iakovenko","id":7511304,"node_id":"MDQ6VXNlcjc1MTEzMDQ=","avatar_url":"https://avatars0.githubusercontent.com/u/7511304?v=4","gravatar_id":"","url":"https://api.github.com/users/sergii-iakovenko","html_url":"https://github.com/sergii-iakovenko","followers_url":"https://api.github.com/users/sergii-iakovenko/followers","following_url":"https://api.github.com/users/sergii-iakovenko/following{/other_user}","gists_url":"https://api.github.com/users/sergii-iakovenko/gists{/gist_id}","starred_url":"https://api.github.com/users/sergii-iakovenko/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sergii-iakovenko/subscriptions","organizations_url":"https://api.github.com/users/sergii-iakovenko/orgs","repos_url":"https://api.github.com/users/sergii-iakovenko/repos","events_url":"https://api.github.com/users/sergii-iakovenko/events{/privacy}","received_events_url":"https://api.github.com/users/sergii-iakovenko/received_events","type":"User","site_admin":false},"body":"The changes:\r\n- Reimplement PathComputation to use DAO:\r\n- Reimplement NeoOperationsBolts (FlowOperationsBolt, LinkOperationsBolt, SwitchOpearationsBolt)\r\n\r\nFollows the solution #1127.\r\n\r\nResolves #1407\r\n\r\n**This must be merged right after #1398. Don't forget to change the base.**","created_at":"2018-10-12T15:46:45Z","updated_at":"2018-11-30T15:52:20Z","closed_at":null,"merged_at":null,"merge_commit_sha":"347a0dfeb9dd004e3452413786a759c711a38d63","assignee":null,"assignees":[],"requested_reviewers":[{"login":"nikitamarchenko","id":3450363,"node_id":"MDQ6VXNlcjM0NTAzNjM=","avatar_url":"https://avatars3.githubusercontent.com/u/3450363?v=4","gravatar_id":"","url":"https://api.github.com/users/nikitamarchenko","html_url":"https://github.com/nikitamarchenko","followers_url":"https://api.github.com/users/nikitamarchenko/followers","following_url":"https://api.github.com/users/nikitamarchenko/following{/other_user}","gists_url":"https://api.github.com/users/nikitamarchenko/gists{/gist_id}","starred_url":"https://api.github.com/users/nikitamarchenko/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nikitamarchenko/subscriptions","organizations_url":"https://api.github.com/users/nikitamarchenko/orgs","repos_url":"https://api.github.com/users/nikitamarchenko/repos","events_url":"https://api.github.com/users/nikitamarchenko/events{/privacy}","received_events_url":"https://api.github.com/users/nikitamarchenko/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":935982807,"node_id":"MDU6TGFiZWw5MzU5ODI4MDc=","url":"https://api.github.com/repos/telstra/open-kilda/labels/C/CACHE","name":"C/CACHE","color":"cf6fe2","default":false},{"id":935983223,"node_id":"MDU6TGFiZWw5MzU5ODMyMjM=","url":"https://api.github.com/repos/telstra/open-kilda/labels/C/FLOW","name":"C/FLOW","color":"e0cd62","default":false},{"id":936014286,"node_id":"MDU6TGFiZWw5MzYwMTQyODY=","url":"https://api.github.com/repos/telstra/open-kilda/labels/C/NB","name":"C/NB","color":"31ed3e","default":false},{"id":937212582,"node_id":"MDU6TGFiZWw5MzcyMTI1ODI=","url":"https://api.github.com/repos/telstra/open-kilda/labels/C/NBWORKER","name":"C/NBWORKER","color":"f2879b","default":false},{"id":1135337137,"node_id":"MDU6TGFiZWwxMTM1MzM3MTM3","url":"https://api.github.com/repos/telstra/open-kilda/labels/On%20Review","name":"On Review","color":"fad201","default":false},{"id":1018531150,"node_id":"MDU6TGFiZWwxMDE4NTMxMTUw","url":"https://api.github.com/repos/telstra/open-kilda/labels/epic/hub@spoke","name":"epic/hub@spoke","color":"fff6bf","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/telstra/open-kilda/pulls/1448/commits","review_comments_url":"https://api.github.com/repos/telstra/open-kilda/pulls/1448/comments","review_comment_url":"https://api.github.com/repos/telstra/open-kilda/pulls/comments{/number}","comments_url":"https://api.github.com/repos/telstra/open-kilda/issues/1448/comments","statuses_url":"https://api.github.com/repos/telstra/open-kilda/statuses/02c5f5163ee46627630aba3927ce7e0c9e4b7150","head":{"label":"telstra:feature/pce-with-dao-refactoring","ref":"feature/pce-with-dao-refactoring","sha":"02c5f5163ee46627630aba3927ce7e0c9e4b7150","user":{"login":"telstra","id":3914896,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM5MTQ4OTY=","avatar_url":"https://avatars2.githubusercontent.com/u/3914896?v=4","gravatar_id":"","url":"https://api.github.com/users/telstra","html_url":"https://github.com/telstra","followers_url":"https://api.github.com/users/telstra/followers","following_url":"https://api.github.com/users/telstra/following{/other_user}","gists_url":"https://api.github.com/users/telstra/gists{/gist_id}","starred_url":"https://api.github.com/users/telstra/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/telstra/subscriptions","organizations_url":"https://api.github.com/users/telstra/orgs","repos_url":"https://api.github.com/users/telstra/repos","events_url":"https://api.github.com/users/telstra/events{/privacy}","received_events_url":"https://api.github.com/users/telstra/received_events","type":"Organization","site_admin":false},"repo":{"id":104974693,"node_id":"MDEwOlJlcG9zaXRvcnkxMDQ5NzQ2OTM=","name":"open-kilda","full_name":"telstra/open-kilda","private":false,"owner":{"login":"telstra","id":3914896,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM5MTQ4OTY=","avatar_url":"https://avatars2.githubusercontent.com/u/3914896?v=4","gravatar_id":"","url":"https://api.github.com/users/telstra","html_url":"https://github.com/telstra","followers_url":"https://api.github.com/users/telstra/followers","following_url":"https://api.github.com/users/telstra/following{/other_user}","gists_url":"https://api.github.com/users/telstra/gists{/gist_id}","starred_url":"https://api.github.com/users/telstra/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/telstra/subscriptions","organizations_url":"https://api.github.com/users/telstra/orgs","repos_url":"https://api.github.com/users/telstra/repos","events_url":"https://api.github.com/users/telstra/events{/privacy}","received_events_url":"https://api.github.com/users/telstra/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/telstra/open-kilda","description":"OpenKilda is an open-source OpenFlow controller initially designed for use in a global network with high control-plane latency and a heavy emphasis on latency-centric data path optimisation.","fork":false,"url":"https://api.github.com/repos/telstra/open-kilda","forks_url":"https://api.github.com/repos/telstra/open-kilda/forks","keys_url":"https://api.github.com/repos/telstra/open-kilda/keys{/key_id}","collaborators_url":"https://api.github.com/repos/telstra/open-kilda/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/telstra/open-kilda/teams","hooks_url":"https://api.github.com/repos/telstra/open-kilda/hooks","issue_events_url":"https://api.github.com/repos/telstra/open-kilda/issues/events{/number}","events_url":"https://api.github.com/repos/telstra/open-kilda/events","assignees_url":"https://api.github.com/repos/telstra/open-kilda/assignees{/user}","branches_url":"https://api.github.com/repos/telstra/open-kilda/branches{/branch}","tags_url":"https://api.github.com/repos/telstra/open-kilda/tags","blobs_url":"https://api.github.com/repos/telstra/open-kilda/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/telstra/open-kilda/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/telstra/open-kilda/git/refs{/sha}","trees_url":"https://api.github.com/repos/telstra/open-kilda/git/trees{/sha}","statuses_url":"https://api.github.com/repos/telstra/open-kilda/statuses/{sha}","languages_url":"https://api.github.com/repos/telstra/open-kilda/languages","stargazers_url":"https://api.github.com/repos/telstra/open-kilda/stargazers","contributors_url":"https://api.github.com/repos/telstra/open-kilda/contributors","subscribers_url":"https://api.github.com/repos/telstra/open-kilda/subscribers","subscription_url":"https://api.github.com/repos/telstra/open-kilda/subscription","commits_url":"https://api.github.com/repos/telstra/open-kilda/commits{/sha}","git_commits_url":"https://api.github.com/repos/telstra/open-kilda/git/commits{/sha}","comments_url":"https://api.github.com/repos/telstra/open-kilda/comments{/number}","issue_comment_url":"https://api.github.com/repos/telstra/open-kilda/issues/comments{/number}","contents_url":"https://api.github.com/repos/telstra/open-kilda/contents/{+path}","compare_url":"https://api.github.com/repos/telstra/open-kilda/compare/{base}...{head}","merges_url":"https://api.github.com/repos/telstra/open-kilda/merges","archive_url":"https://api.github.com/repos/telstra/open-kilda/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/telstra/open-kilda/downloads","issues_url":"https://api.github.com/repos/telstra/open-kilda/issues{/number}","pulls_url":"https://api.github.com/repos/telstra/open-kilda/pulls{/number}","milestones_url":"https://api.github.com/repos/telstra/open-kilda/milestones{/number}","notifications_url":"https://api.github.com/repos/telstra/open-kilda/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/telstra/open-kilda/labels{/name}","releases_url":"https://api.github.com/repos/telstra/open-kilda/releases{/id}","deployments_url":"https://api.github.com/repos/telstra/open-kilda/deployments","created_at":"2017-09-27T05:13:18Z","updated_at":"2018-11-30T11:07:32Z","pushed_at":"2018-11-30T15:17:42Z","git_url":"git://github.com/telstra/open-kilda.git","ssh_url":"git@github.com:telstra/open-kilda.git","clone_url":"https://github.com/telstra/open-kilda.git","svn_url":"https://github.com/telstra/open-kilda","homepage":"","size":212260,"stargazers_count":36,"watchers_count":36,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":32,"mirror_url":null,"archived":false,"open_issues_count":300,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":32,"open_issues":300,"watchers":36,"default_branch":"develop"}},"base":{"label":"telstra:feature/poc-model-and-dao-layer","ref":"feature/poc-model-and-dao-layer","sha":"59c7fb97998b70273917e0a562bcee2b7d65e867","user":{"login":"telstra","id":3914896,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM5MTQ4OTY=","avatar_url":"https://avatars2.githubusercontent.com/u/3914896?v=4","gravatar_id":"","url":"https://api.github.com/users/telstra","html_url":"https://github.com/telstra","followers_url":"https://api.github.com/users/telstra/followers","following_url":"https://api.github.com/users/telstra/following{/other_user}","gists_url":"https://api.github.com/users/telstra/gists{/gist_id}","starred_url":"https://api.github.com/users/telstra/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/telstra/subscriptions","organizations_url":"https://api.github.com/users/telstra/orgs","repos_url":"https://api.github.com/users/telstra/repos","events_url":"https://api.github.com/users/telstra/events{/privacy}","received_events_url":"https://api.github.com/users/telstra/received_events","type":"Organization","site_admin":false},"repo":{"id":104974693,"node_id":"MDEwOlJlcG9zaXRvcnkxMDQ5NzQ2OTM=","name":"open-kilda","full_name":"telstra/open-kilda","private":false,"owner":{"login":"telstra","id":3914896,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM5MTQ4OTY=","avatar_url":"https://avatars2.githubusercontent.com/u/3914896?v=4","gravatar_id":"","url":"https://api.github.com/users/telstra","html_url":"https://github.com/telstra","followers_url":"https://api.github.com/users/telstra/followers","following_url":"https://api.github.com/users/telstra/following{/other_user}","gists_url":"https://api.github.com/users/telstra/gists{/gist_id}","starred_url":"https://api.github.com/users/telstra/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/telstra/subscriptions","organizations_url":"https://api.github.com/users/telstra/orgs","repos_url":"https://api.github.com/users/telstra/repos","events_url":"https://api.github.com/users/telstra/events{/privacy}","received_events_url":"https://api.github.com/users/telstra/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/telstra/open-kilda","description":"OpenKilda is an open-source OpenFlow controller initially designed for use in a global network with high control-plane latency and a heavy emphasis on latency-centric data path optimisation.","fork":false,"url":"https://api.github.com/repos/telstra/open-kilda","forks_url":"https://api.github.com/repos/telstra/open-kilda/forks","keys_url":"https://api.github.com/repos/telstra/open-kilda/keys{/key_id}","collaborators_url":"https://api.github.com/repos/telstra/open-kilda/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/telstra/open-kilda/teams","hooks_url":"https://api.github.com/repos/telstra/open-kilda/hooks","issue_events_url":"https://api.github.com/repos/telstra/open-kilda/issues/events{/number}","events_url":"https://api.github.com/repos/telstra/open-kilda/events","assignees_url":"https://api.github.com/repos/telstra/open-kilda/assignees{/user}","branches_url":"https://api.github.com/repos/telstra/open-kilda/branches{/branch}","tags_url":"https://api.github.com/repos/telstra/open-kilda/tags","blobs_url":"https://api.github.com/repos/telstra/open-kilda/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/telstra/open-kilda/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/telstra/open-kilda/git/refs{/sha}","trees_url":"https://api.github.com/repos/telstra/open-kilda/git/trees{/sha}","statuses_url":"https://api.github.com/repos/telstra/open-kilda/statuses/{sha}","languages_url":"https://api.github.com/repos/telstra/open-kilda/languages","stargazers_url":"https://api.github.com/repos/telstra/open-kilda/stargazers","contributors_url":"https://api.github.com/repos/telstra/open-kilda/contributors","subscribers_url":"https://api.github.com/repos/telstra/open-kilda/subscribers","subscription_url":"https://api.github.com/repos/telstra/open-kilda/subscription","commits_url":"https://api.github.com/repos/telstra/open-kilda/commits{/sha}","git_commits_url":"https://api.github.com/repos/telstra/open-kilda/git/commits{/sha}","comments_url":"https://api.github.com/repos/telstra/open-kilda/comments{/number}","issue_comment_url":"https://api.github.com/repos/telstra/open-kilda/issues/comments{/number}","contents_url":"https://api.github.com/repos/telstra/open-kilda/contents/{+path}","compare_url":"https://api.github.com/repos/telstra/open-kilda/compare/{base}...{head}","merges_url":"https://api.github.com/repos/telstra/open-kilda/merges","archive_url":"https://api.github.com/repos/telstra/open-kilda/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/telstra/open-kilda/downloads","issues_url":"https://api.github.com/repos/telstra/open-kilda/issues{/number}","pulls_url":"https://api.github.com/repos/telstra/open-kilda/pulls{/number}","milestones_url":"https://api.github.com/repos/telstra/open-kilda/milestones{/number}","notifications_url":"https://api.github.com/repos/telstra/open-kilda/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/telstra/open-kilda/labels{/name}","releases_url":"https://api.github.com/repos/telstra/open-kilda/releases{/id}","deployments_url":"https://api.github.com/repos/telstra/open-kilda/deployments","created_at":"2017-09-27T05:13:18Z","updated_at":"2018-11-30T11:07:32Z","pushed_at":"2018-11-30T15:17:42Z","git_url":"git://github.com/telstra/open-kilda.git","ssh_url":"git@github.com:telstra/open-kilda.git","clone_url":"https://github.com/telstra/open-kilda.git","svn_url":"https://github.com/telstra/open-kilda","homepage":"","size":212260,"stargazers_count":36,"watchers_count":36,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":32,"mirror_url":null,"archived":false,"open_issues_count":300,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":32,"open_issues":300,"watchers":36,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/telstra/open-kilda/pulls/1448"},"html":{"href":"https://github.com/telstra/open-kilda/pull/1448"},"issue":{"href":"https://api.github.com/repos/telstra/open-kilda/issues/1448"},"comments":{"href":"https://api.github.com/repos/telstra/open-kilda/issues/1448/comments"},"review_comments":{"href":"https://api.github.com/repos/telstra/open-kilda/pulls/1448/comments"},"review_comment":{"href":"https://api.github.com/repos/telstra/open-kilda/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/telstra/open-kilda/pulls/1448/commits"},"statuses":{"href":"https://api.github.com/repos/telstra/open-kilda/statuses/02c5f5163ee46627630aba3927ce7e0c9e4b7150"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"Settis"}}