{"action":"created","comment":{"url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/pulls/comments/64887498","id":64887498,"diff_hunk":"@@ -0,0 +1,326 @@\n+/**\n+* Project Clearwater - IMS in the Cloud\n+* Copyright (C) 2016 Metaswitch Networks Ltd\n+*\n+* This program is free software: you can redistribute it and/or modify it\n+* under the terms of the GNU General Public License as published by the\n+* Free Software Foundation, either version 3 of the License, or (at your\n+* option) any later version, along with the \"Special Exception\" for use of\n+* the program along with SSL, set forth below. This program is distributed\n+* in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR\n+* A PARTICULAR PURPOSE. See the GNU General Public License for more\n+* details. You should have received a copy of the GNU General Public\n+* License along with this program. If not, see\n+* <http://www.gnu.org/licenses/>.\n+*\n+* The author can be reached by email at clearwater@metaswitch.com or by\n+* post at Metaswitch Networks Ltd, 100 Church St, Enfield EN2 6BQ, UK\n+*\n+* Special Exception\n+* Metaswitch Networks Ltd grants you permission to copy, modify,\n+* propagate, and distribute a work formed by combining OpenSSL with The\n+* Software, or a work derivative of such a combination, even if such\n+* copying, modification, propagation, or distribution would otherwise\n+* violate the terms of the GPL. You must comply with the GPL in all\n+* respects for all of the code used other than OpenSSL.\n+* \"OpenSSL\" means OpenSSL toolkit software distributed by the OpenSSL\n+* Project and licensed under the OpenSSL Licenses, or a work based on such\n+* software and licensed under the OpenSSL Licenses.\n+* \"OpenSSL Licenses\" means the OpenSSL License and Original SSLeay License\n+* under which the OpenSSL Project distributes the OpenSSL toolkit software,\n+* as those licenses appear in the file LICENSE-OPENSSL.\n+*/\n+\n+#include <stdexcept>\n+#include <time.h>\n+#include <cmath>\n+#include <arpa/inet.h>\n+\n+#include \"log.h\"\n+#include \"alarm_heap.hpp\"\n+#include \"itu_alarm_table.hpp\"\n+#include \"alarm_active_table.hpp\"\n+\n+AlarmInfo::~AlarmInfo()\n+{\n+  delete _alarm_in_heap; _alarm_in_heap = NULL;\n+}\n+\n+AlarmSeverityChange AlarmInfo::new_alarm_severity(AlarmDef::Severity severity)\n+{\n+  // Order the severities so we can do a simple comparison to determine any\n+  // severity change.\n+  unsigned int ordered_severities[] = {0, 1, 2, 6, 5, 4, 3};\n+  int old_severity = ordered_severities[_severity];\n+  int new_severity = ordered_severities[severity];\n+\n+  if (old_severity == new_severity)\n+  {\n+    return AlarmSeverityChange::NO_CHANGE;\n+  }\n+  else if (old_severity > new_severity)\n+  {\n+    return AlarmSeverityChange::REDUCED_SEVERITY;\n+  }\n+  else\n+  {\n+    return AlarmSeverityChange::INCREASED_SEVERITY;\n+  }\n+}\n+\n+void AlarmInfo::set_severity(AlarmTableDef& alarm_table_def)\n+{\n+  // Update the severity in the map.\n+  _severity = alarm_table_def.severity();\n+\n+  // Update the ActiveAlarmTable.\n+  alarmActiveTable_trap_handler(alarm_table_def);\n+}\n+\n+void AlarmInfo::update_alarm_in_heap(AlarmDef::Severity new_severity,\n+                                     uint64_t time_to_delay)\n+{\n+  // Update the alarm in the heap's severity, and update its time to pop\n+  // (which also rebalances the heap).\n+  if (new_severity != _alarm_in_heap->severity())\n+  {\n+    _alarm_in_heap->set_severity(new_severity);\n+    _alarm_in_heap->update_pop_time(time_to_delay);\n+  }\n+}\n+\n+AlarmHeap::AlarmHeap(AlarmTableDefs* alarm_table_defs) :\n+  _terminated(false),\n+  _alarm_table_defs(alarm_table_defs),\n+  _alarm_trap_sender(new AlarmTrapSender(this))\n+{\n+  // Create the lock/condition variables.\n+  pthread_mutex_init(&_lock, NULL);\n+  _cond = new CondVar(&_lock);\n+\n+  // Populate the alarm state map\n+  for (AlarmTableDefsIterator it = _alarm_table_defs->begin();\n+                              it != _alarm_table_defs->end();\n+                              it++)\n+  {\n+    AllAlarmsStateMap::iterator index = _all_alarms_state.find(it->alarm_index());\n+\n+    if (index == _all_alarms_state.end())\n+    {\n+      // We only have one entry for each alarm index (not one per severity).\n+      AlarmInHeap* alarm_in_heap = new AlarmInHeap(it->alarm_index());\n+      AlarmInfo* alarm_info = new AlarmInfo(alarm_in_heap,\n+                                            AlarmDef::Severity::UNDEFINED_SEVERITY);\n+      _all_alarms_state.insert(std::pair<unsigned int, AlarmInfo*>(it->alarm_index(),\n+                                                                   alarm_info));\n+    }\n+  }\n+\n+  // Finally, create the heap thread. This covers getting any alarms to send\n+  // from the heap and passing them to the trap sender to actually send.\n+  int rc = pthread_create(&_heap_sender_thread, NULL, heap_sender_function, this);\n+\n+  if (rc < 0)\n+  {\n+    // LCOV_EXCL_START\n+    printf(\"Failed to start heap pop thread: %s\", strerror(errno));\n+    exit(2);\n+    // LCOV_EXCL_STOP\n+  }\n+}\n+\n+AlarmHeap::~AlarmHeap()\n+{\n+  pthread_mutex_lock(&_lock);\n+  _terminated = true;\n+  _cond->signal();\n+  pthread_mutex_unlock(&_lock);\n+\n+  pthread_join(_heap_sender_thread, NULL);\n+  delete _cond; _cond = NULL;\n+\n+  pthread_mutex_destroy(&_lock);\n+\n+  delete _alarm_trap_sender; _alarm_trap_sender = NULL;\n+  _alarm_heap.clear();\n+\n+  for (AllAlarmsStateMap::iterator it = _all_alarms_state.begin();\n+                               it != _all_alarms_state.end();\n+                               it++)\n+  {\n+    delete (*it).second;\n+  }\n+}\n+\n+void* AlarmHeap::heap_sender_function(void* data)\n+{\n+  ((AlarmHeap*)data)->heap_sender();\n+  return NULL;\n+}\n+\n+void AlarmHeap::heap_sender()\n+{\n+  pthread_mutex_lock(&_lock);\n+\n+  while (!_terminated)\n+  {\n+    uint64_t time_now_in_ms = Utils::get_time();\n+    AlarmInHeap* alarm_in_heap = (AlarmInHeap*)_alarm_heap.get_next_timer();\n+\n+    while ((alarm_in_heap) &&\n+           (alarm_in_heap->get_pop_time() <= time_now_in_ms))\n+    {\n+      // While the next alarm in the heap is due to be sent, we:\n+      //  - Pull out the alarm definition for its index and severity.\n+      //  - Pass the alarm definition to the trap sender (which is responsible\n+      //    for actually sending any INFORMs).\n+      //  - Update the master view of the current severity for this alarm (by\n+      //    updating the _all_alarms_state map).\n+      //  - Finally, we then remove the alarm from the heap.\n+      AlarmTableDef& alarm_table_def =\n+              _alarm_table_defs->get_definition(alarm_in_heap->index(),\n+                                                alarm_in_heap->severity());\n+\n+      if (alarm_table_def.is_valid())\n+      {\n+        _alarm_trap_sender->send_trap(alarm_table_def);\n+        AllAlarmsStateMap::iterator alarm = _all_alarms_state.find(alarm_in_heap->index());\n+\n+        if (alarm != _all_alarms_state.end())\n+        {\n+          (*alarm).second->set_severity(alarm_table_def);\n+        }\n+      }\n+\n+      alarm_in_heap->remove_from_heap();\n+      alarm_in_heap = (AlarmInHeap*)_alarm_heap.get_next_timer();\n+    }\n+\n+    // The next alarm in the heap isn't due to pop yet. Wait until it's due.\n+    if (alarm_in_heap)\n+    {\n+      // The next alarm in the heap isn't due to pop yet. Wait until it's due.\n+      struct timespec time;\n+      time.tv_sec = alarm_in_heap->get_pop_time() / 1000;\n+      time.tv_nsec = (alarm_in_heap->get_pop_time() % 1000) * 1000000;\n+      _cond->timedwait(&time);\n+    }\n+    else\n+    {\n+      // There's no alarms in the heap. Wait until we're signalled.\n+      _cond->wait();\n+    }\n+  }\n+\n+  pthread_mutex_unlock(&_lock);\n+}\n+\n+void AlarmHeap::update_alarm_in_heap(AlarmInfo* alarm_info,\n+                                     AlarmDef::Severity severity,\n+                                     uint64_t alarm_pop_time)\n+{\n+  _alarm_heap.insert(alarm_info->alarm_in_heap());\n+  alarm_info->update_alarm_in_heap(severity, alarm_pop_time);\n+}\n+\n+void AlarmHeap::issue_alarm(const std::string& issuer,\n+                            const std::string& identifier)\n+{\n+  unsigned int index;\n+  unsigned int severity;\n+  if (sscanf(identifier.c_str(), \"%u.%u\", &index, &severity) != 2)\n+  {\n+    TRC_ERROR(\"malformed alarm identifier: %s\", identifier.c_str());\n+    return;\n+  }\n+\n+  AlarmTableDef& alarm_table_def = _alarm_table_defs->get_definition(index,\n+                                                                     severity);\n+\n+  if (alarm_table_def.is_valid())\n+  {\n+    pthread_mutex_lock(&_lock);\n+\n+    AllAlarmsStateMap::iterator alarm = _all_alarms_state.find(index);\n+\n+    if (alarm != _all_alarms_state.end())\n+    {\n+      AlarmDef::Severity severity_as_enum = (AlarmDef::Severity)severity;\n+      AlarmSeverityChange severity_change =\n+                  (*alarm).second->new_alarm_severity(severity_as_enum);\n+\n+      if (severity_change == AlarmSeverityChange::INCREASED_SEVERITY)\n+      {\n+        TRC_DEBUG(\"Severity of the alarm %lu has increased\", index);\n+        update_alarm_in_heap((*alarm).second, severity_as_enum, ALARM_INCREASED);\n+        _cond->signal();\n+      }\n+      else if (severity_change == AlarmSeverityChange::REDUCED_SEVERITY)\n+      {\n+        TRC_DEBUG(\"Severity of the alarm %lu has reduced\", index);\n+        _alarm_heap.insert((*alarm).second->alarm_in_heap());\n+        update_alarm_in_heap((*alarm).second, severity_as_enum, ALARM_REDUCED);\n+        _cond->signal();\n+      }\n+      else\n+      {\n+        // The severity of the alarm hasn't changed. Remove it from the heap\n+        // (safe to call even if it's already not in the heap).\n+        _alarm_heap.remove((*alarm).second->alarm_in_heap());\n+      }\n+    }\n+\n+    pthread_mutex_unlock(&_lock);\n+  }\n+  else\n+  {\n+    TRC_ERROR(\"Unknown alarm definition: %s\", identifier.c_str());\n+  }\n+}\n+\n+void AlarmHeap::sync_alarms()\n+{\n+  TRC_STATUS(\"Resyncing all alarms\");\n+\n+  pthread_mutex_lock(&_lock);\n+\n+  for (AllAlarmsStateMap::iterator it = _all_alarms_state.begin();\n+                               it != _all_alarms_state.end();\n+                               it++)\n+  {\n+    AlarmDef::Severity current_severity = (*it).second->get_severity();\n+\n+    if (current_severity != AlarmDef::Severity::UNDEFINED_SEVERITY)\n+    {\n+      update_alarm_in_heap((*it).second, current_severity, ALARM_RESYNC_DELAY);\n+    }\n+  }\n+\n+  _cond->signal();\n+  pthread_mutex_unlock(&_lock);\n+}\n+\n+void AlarmHeap::handle_failed_alarm(AlarmTableDef& alarm_table_def)\n+{\n+  TRC_DEBUG(\"Handling a failed callback for the alarm: %lu\",\n+            alarm_table_def.alarm_index());\n+\n+  pthread_mutex_lock(&_lock);\n+\n+  AllAlarmsStateMap::iterator alarm =","path":"src/alarm_heap.cpp","position":311,"original_position":311,"commit_id":"199d8421b717b64129956b5994b22df7ebd5e442","original_commit_id":"199d8421b717b64129956b5994b22df7ebd5e442","user":{"login":"rkd-msw","id":4363492,"avatar_url":"https://avatars.githubusercontent.com/u/4363492?v=3","gravatar_id":"","url":"https://api.github.com/users/rkd-msw","html_url":"https://github.com/rkd-msw","followers_url":"https://api.github.com/users/rkd-msw/followers","following_url":"https://api.github.com/users/rkd-msw/following{/other_user}","gists_url":"https://api.github.com/users/rkd-msw/gists{/gist_id}","starred_url":"https://api.github.com/users/rkd-msw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rkd-msw/subscriptions","organizations_url":"https://api.github.com/users/rkd-msw/orgs","repos_url":"https://api.github.com/users/rkd-msw/repos","events_url":"https://api.github.com/users/rkd-msw/events{/privacy}","received_events_url":"https://api.github.com/users/rkd-msw/received_events","type":"User","site_admin":false},"body":"Again, this is probably overdefensive.","created_at":"2016-05-27T10:39:21Z","updated_at":"2016-05-27T10:39:21Z","html_url":"https://github.com/Metaswitch/clearwater-snmp-handlers/pull/147#discussion_r64887498","pull_request_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/pulls/147","_links":{"self":{"href":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/pulls/comments/64887498"},"html":{"href":"https://github.com/Metaswitch/clearwater-snmp-handlers/pull/147#discussion_r64887498"},"pull_request":{"href":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/pulls/147"}}},"pull_request":{"url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/pulls/147","id":71614612,"html_url":"https://github.com/Metaswitch/clearwater-snmp-handlers/pull/147","diff_url":"https://github.com/Metaswitch/clearwater-snmp-handlers/pull/147.diff","patch_url":"https://github.com/Metaswitch/clearwater-snmp-handlers/pull/147.patch","issue_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/issues/147","number":147,"state":"open","locked":false,"title":"[Reviewer: Rob] Alarm refactor","user":{"login":"eleanor-merry","id":5425325,"avatar_url":"https://avatars.githubusercontent.com/u/5425325?v=3","gravatar_id":"","url":"https://api.github.com/users/eleanor-merry","html_url":"https://github.com/eleanor-merry","followers_url":"https://api.github.com/users/eleanor-merry/followers","following_url":"https://api.github.com/users/eleanor-merry/following{/other_user}","gists_url":"https://api.github.com/users/eleanor-merry/gists{/gist_id}","starred_url":"https://api.github.com/users/eleanor-merry/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eleanor-merry/subscriptions","organizations_url":"https://api.github.com/users/eleanor-merry/orgs","repos_url":"https://api.github.com/users/eleanor-merry/repos","events_url":"https://api.github.com/users/eleanor-merry/events{/privacy}","received_events_url":"https://api.github.com/users/eleanor-merry/received_events","type":"User","site_admin":false},"body":"Rob, can you please review this refactoring of the alarm agent.\r\n\r\nI've changed how INFORMs are sent by the alarm agent, splitting up the sending INFORMs into its own component, and adding a heap that alarms are queued on (to make the retry/resync/flicker behaviour correct and easy to maintain).\r\n\r\nI've also moved us away from using singletons","created_at":"2016-05-26T19:57:07Z","updated_at":"2016-05-27T10:39:21Z","closed_at":null,"merged_at":null,"merge_commit_sha":"60c0a96f19e70274d33e2c0a9db1d06e1003d233","assignee":{"login":"rkd-msw","id":4363492,"avatar_url":"https://avatars.githubusercontent.com/u/4363492?v=3","gravatar_id":"","url":"https://api.github.com/users/rkd-msw","html_url":"https://github.com/rkd-msw","followers_url":"https://api.github.com/users/rkd-msw/followers","following_url":"https://api.github.com/users/rkd-msw/following{/other_user}","gists_url":"https://api.github.com/users/rkd-msw/gists{/gist_id}","starred_url":"https://api.github.com/users/rkd-msw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rkd-msw/subscriptions","organizations_url":"https://api.github.com/users/rkd-msw/orgs","repos_url":"https://api.github.com/users/rkd-msw/repos","events_url":"https://api.github.com/users/rkd-msw/events{/privacy}","received_events_url":"https://api.github.com/users/rkd-msw/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/pulls/147/commits","review_comments_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/pulls/147/comments","review_comment_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/issues/147/comments","statuses_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/statuses/199d8421b717b64129956b5994b22df7ebd5e442","head":{"label":"Metaswitch:alarm_refactor","ref":"alarm_refactor","sha":"199d8421b717b64129956b5994b22df7ebd5e442","user":{"login":"Metaswitch","id":453759,"avatar_url":"https://avatars.githubusercontent.com/u/453759?v=3","gravatar_id":"","url":"https://api.github.com/users/Metaswitch","html_url":"https://github.com/Metaswitch","followers_url":"https://api.github.com/users/Metaswitch/followers","following_url":"https://api.github.com/users/Metaswitch/following{/other_user}","gists_url":"https://api.github.com/users/Metaswitch/gists{/gist_id}","starred_url":"https://api.github.com/users/Metaswitch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Metaswitch/subscriptions","organizations_url":"https://api.github.com/users/Metaswitch/orgs","repos_url":"https://api.github.com/users/Metaswitch/repos","events_url":"https://api.github.com/users/Metaswitch/events{/privacy}","received_events_url":"https://api.github.com/users/Metaswitch/received_events","type":"Organization","site_admin":false},"repo":{"id":13772926,"name":"clearwater-snmp-handlers","full_name":"Metaswitch/clearwater-snmp-handlers","owner":{"login":"Metaswitch","id":453759,"avatar_url":"https://avatars.githubusercontent.com/u/453759?v=3","gravatar_id":"","url":"https://api.github.com/users/Metaswitch","html_url":"https://github.com/Metaswitch","followers_url":"https://api.github.com/users/Metaswitch/followers","following_url":"https://api.github.com/users/Metaswitch/following{/other_user}","gists_url":"https://api.github.com/users/Metaswitch/gists{/gist_id}","starred_url":"https://api.github.com/users/Metaswitch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Metaswitch/subscriptions","organizations_url":"https://api.github.com/users/Metaswitch/orgs","repos_url":"https://api.github.com/users/Metaswitch/repos","events_url":"https://api.github.com/users/Metaswitch/events{/privacy}","received_events_url":"https://api.github.com/users/Metaswitch/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Metaswitch/clearwater-snmp-handlers","description":"SNMP extension modules to provide stats for Clearwater nodes","fork":false,"url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers","forks_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/forks","keys_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/teams","hooks_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/hooks","issue_events_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/issues/events{/number}","events_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/events","assignees_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/assignees{/user}","branches_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/branches{/branch}","tags_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/tags","blobs_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/git/refs{/sha}","trees_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/statuses/{sha}","languages_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/languages","stargazers_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/stargazers","contributors_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/contributors","subscribers_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/subscribers","subscription_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/subscription","commits_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/commits{/sha}","git_commits_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/git/commits{/sha}","comments_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/comments{/number}","issue_comment_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/issues/comments{/number}","contents_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/contents/{+path}","compare_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/merges","archive_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/downloads","issues_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/issues{/number}","pulls_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/pulls{/number}","milestones_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/milestones{/number}","notifications_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/labels{/name}","releases_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/releases{/id}","deployments_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/deployments","created_at":"2013-10-22T12:45:34Z","updated_at":"2016-01-11T14:34:17Z","pushed_at":"2016-05-26T19:57:07Z","git_url":"git://github.com/Metaswitch/clearwater-snmp-handlers.git","ssh_url":"git@github.com:Metaswitch/clearwater-snmp-handlers.git","clone_url":"https://github.com/Metaswitch/clearwater-snmp-handlers.git","svn_url":"https://github.com/Metaswitch/clearwater-snmp-handlers","homepage":null,"size":837,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":5,"forks":4,"open_issues":5,"watchers":0,"default_branch":"master"}},"base":{"label":"Metaswitch:master","ref":"master","sha":"41eceff3cab769acc9193fefa41b11ccbe0b3899","user":{"login":"Metaswitch","id":453759,"avatar_url":"https://avatars.githubusercontent.com/u/453759?v=3","gravatar_id":"","url":"https://api.github.com/users/Metaswitch","html_url":"https://github.com/Metaswitch","followers_url":"https://api.github.com/users/Metaswitch/followers","following_url":"https://api.github.com/users/Metaswitch/following{/other_user}","gists_url":"https://api.github.com/users/Metaswitch/gists{/gist_id}","starred_url":"https://api.github.com/users/Metaswitch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Metaswitch/subscriptions","organizations_url":"https://api.github.com/users/Metaswitch/orgs","repos_url":"https://api.github.com/users/Metaswitch/repos","events_url":"https://api.github.com/users/Metaswitch/events{/privacy}","received_events_url":"https://api.github.com/users/Metaswitch/received_events","type":"Organization","site_admin":false},"repo":{"id":13772926,"name":"clearwater-snmp-handlers","full_name":"Metaswitch/clearwater-snmp-handlers","owner":{"login":"Metaswitch","id":453759,"avatar_url":"https://avatars.githubusercontent.com/u/453759?v=3","gravatar_id":"","url":"https://api.github.com/users/Metaswitch","html_url":"https://github.com/Metaswitch","followers_url":"https://api.github.com/users/Metaswitch/followers","following_url":"https://api.github.com/users/Metaswitch/following{/other_user}","gists_url":"https://api.github.com/users/Metaswitch/gists{/gist_id}","starred_url":"https://api.github.com/users/Metaswitch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Metaswitch/subscriptions","organizations_url":"https://api.github.com/users/Metaswitch/orgs","repos_url":"https://api.github.com/users/Metaswitch/repos","events_url":"https://api.github.com/users/Metaswitch/events{/privacy}","received_events_url":"https://api.github.com/users/Metaswitch/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Metaswitch/clearwater-snmp-handlers","description":"SNMP extension modules to provide stats for Clearwater nodes","fork":false,"url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers","forks_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/forks","keys_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/teams","hooks_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/hooks","issue_events_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/issues/events{/number}","events_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/events","assignees_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/assignees{/user}","branches_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/branches{/branch}","tags_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/tags","blobs_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/git/refs{/sha}","trees_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/statuses/{sha}","languages_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/languages","stargazers_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/stargazers","contributors_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/contributors","subscribers_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/subscribers","subscription_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/subscription","commits_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/commits{/sha}","git_commits_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/git/commits{/sha}","comments_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/comments{/number}","issue_comment_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/issues/comments{/number}","contents_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/contents/{+path}","compare_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/merges","archive_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/downloads","issues_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/issues{/number}","pulls_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/pulls{/number}","milestones_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/milestones{/number}","notifications_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/labels{/name}","releases_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/releases{/id}","deployments_url":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/deployments","created_at":"2013-10-22T12:45:34Z","updated_at":"2016-01-11T14:34:17Z","pushed_at":"2016-05-26T19:57:07Z","git_url":"git://github.com/Metaswitch/clearwater-snmp-handlers.git","ssh_url":"git@github.com:Metaswitch/clearwater-snmp-handlers.git","clone_url":"https://github.com/Metaswitch/clearwater-snmp-handlers.git","svn_url":"https://github.com/Metaswitch/clearwater-snmp-handlers","homepage":null,"size":837,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":5,"forks":4,"open_issues":5,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/pulls/147"},"html":{"href":"https://github.com/Metaswitch/clearwater-snmp-handlers/pull/147"},"issue":{"href":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/issues/147"},"comments":{"href":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/issues/147/comments"},"review_comments":{"href":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/pulls/147/comments"},"review_comment":{"href":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/pulls/147/commits"},"statuses":{"href":"https://api.github.com/repos/Metaswitch/clearwater-snmp-handlers/statuses/199d8421b717b64129956b5994b22df7ebd5e442"}}}}
{"actor":{"display_login":"rkd-msw"}}