info.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * EliasDB
  3. *
  4. * Copyright 2016 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the Mozilla Public
  7. * License, v. 2.0. If a copy of the MPL was not distributed with this
  8. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. */
  10. package v1
  11. import (
  12. "encoding/json"
  13. "fmt"
  14. "net/http"
  15. "devt.de/krotik/eliasdb/api"
  16. )
  17. /*
  18. EndpointInfoQuery is the info endpoint URL (rooted). Handles everything under info/...
  19. */
  20. const EndpointInfoQuery = api.APIRoot + APIv1 + "/info/"
  21. /*
  22. InfoEndpointInst creates a new endpoint handler.
  23. */
  24. func InfoEndpointInst() api.RestEndpointHandler {
  25. return &infoEndpoint{}
  26. }
  27. /*
  28. Handler object for info queries.
  29. */
  30. type infoEndpoint struct {
  31. *api.DefaultEndpointHandler
  32. }
  33. /*
  34. HandleGET handles a info query REST call.
  35. */
  36. func (ie *infoEndpoint) HandleGET(w http.ResponseWriter, r *http.Request, resources []string) {
  37. data := make(map[string]interface{})
  38. if len(resources) > 0 {
  39. if resources[0] == "kind" {
  40. // Kind info is requested
  41. if len(resources) == 1 {
  42. http.Error(w, "Missing node kind", http.StatusBadRequest)
  43. return
  44. }
  45. na := api.GM.NodeAttrs(resources[1])
  46. ea := api.GM.EdgeAttrs(resources[1])
  47. if len(na) == 0 && len(ea) == 0 {
  48. http.Error(w, fmt.Sprint("Unknown node kind ", resources[1]), http.StatusBadRequest)
  49. return
  50. }
  51. data["node_attrs"] = na
  52. data["node_edges"] = api.GM.NodeEdges(resources[1])
  53. data["edge_attrs"] = ea
  54. }
  55. } else {
  56. // Get general information
  57. data["partitions"] = api.GM.Partitions()
  58. nks := api.GM.NodeKinds()
  59. data["node_kinds"] = nks
  60. ncs := make(map[string]uint64)
  61. for _, nk := range nks {
  62. ncs[nk] = api.GM.NodeCount(nk)
  63. }
  64. data["node_counts"] = ncs
  65. eks := api.GM.EdgeKinds()
  66. data["edge_kinds"] = eks
  67. ecs := make(map[string]uint64)
  68. for _, ek := range eks {
  69. ecs[ek] = api.GM.EdgeCount(ek)
  70. }
  71. data["edge_counts"] = ecs
  72. }
  73. // Write data
  74. w.Header().Set("content-type", "application/json; charset=utf-8")
  75. ret := json.NewEncoder(w)
  76. ret.Encode(data)
  77. }
  78. /*
  79. SwaggerDefs is used to describe the endpoint in swagger.
  80. */
  81. func (ie *infoEndpoint) SwaggerDefs(s map[string]interface{}) {
  82. s["paths"].(map[string]interface{})["/v1/info"] = map[string]interface{}{
  83. "get": map[string]interface{}{
  84. "summary": "Return general datastore information.",
  85. "description": "The info endpoint returns general database information such as known node kinds, known attributes, etc.",
  86. "produces": []string{
  87. "text/plain",
  88. "application/json",
  89. },
  90. "responses": map[string]interface{}{
  91. "200": map[string]interface{}{
  92. "description": "A key-value map.",
  93. },
  94. "default": map[string]interface{}{
  95. "description": "Error response",
  96. "schema": map[string]interface{}{
  97. "$ref": "#/definitions/Error",
  98. },
  99. },
  100. },
  101. },
  102. }
  103. s["paths"].(map[string]interface{})["/v1/info/kind/{kind}"] = map[string]interface{}{
  104. "get": map[string]interface{}{
  105. "summary": "Return information on a given node or edge kind.",
  106. "description": "The info kind endpoint returns information on a given node kind such as known attributes and edges.",
  107. "produces": []string{
  108. "text/plain",
  109. "application/json",
  110. },
  111. "parameters": []map[string]interface{}{
  112. map[string]interface{}{
  113. "name": "kind",
  114. "in": "path",
  115. "description": "Node or edge kind to be queried.",
  116. "required": true,
  117. "type": "string",
  118. },
  119. },
  120. "responses": map[string]interface{}{
  121. "200": map[string]interface{}{
  122. "description": "A key-value map.",
  123. },
  124. "default": map[string]interface{}{
  125. "description": "Error response",
  126. "schema": map[string]interface{}{
  127. "$ref": "#/definitions/Error",
  128. },
  129. },
  130. },
  131. },
  132. }
  133. // Add generic error object to definition
  134. s["definitions"].(map[string]interface{})["Error"] = map[string]interface{}{
  135. "description": "A human readable error mesage.",
  136. "type": "string",
  137. }
  138. }