github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/engine/pkg/openapi/swagger.go (about) 1 // Copyright 2022 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 // BSD 3-Clause License 15 // 16 // Copyright (c) 2020, Juan Font 17 // All rights reserved. 18 19 // This file is almost a copy of 20 // https://github.com/juanfont/headscale/blob/19455399f4762fb0ab1308a78f4625ce746b2c51/swagger.go. 21 // The only difference is the apiV1JSON variable. 22 23 package openapi 24 25 import ( 26 "bytes" 27 _ "embed" 28 "html/template" 29 "net/http" 30 31 "github.com/pingcap/log" 32 "go.uber.org/zap" 33 ) 34 35 //go:embed apiv1.swagger.json 36 var apiV1JSON []byte 37 38 // SwaggerUI renders the swagger ui. 39 func SwaggerUI( 40 writer http.ResponseWriter, 41 _ *http.Request, 42 ) { 43 swaggerTemplate := template.Must(template.New("swagger").Parse(` 44 <html> 45 <head> 46 <link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@3/swagger-ui.css"> 47 48 <script src="https://unpkg.com/swagger-ui-dist@3/swagger-ui-standalone-preset.js"></script> 49 <script src="https://unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js" charset="UTF-8"></script> 50 </head> 51 <body> 52 <div id="swagger-ui"></div> 53 <script> 54 window.addEventListener('load', (event) => { 55 const ui = SwaggerUIBundle({ 56 url: "/swagger/v1/openapiv2.json", 57 dom_id: '#swagger-ui', 58 presets: [ 59 SwaggerUIBundle.presets.apis, 60 SwaggerUIBundle.SwaggerUIStandalonePreset 61 ], 62 plugins: [ 63 SwaggerUIBundle.plugins.DownloadUrl 64 ], 65 deepLinking: true, 66 // TODO(kradalby): Figure out why this does not work 67 // layout: "StandaloneLayout", 68 }) 69 window.ui = ui 70 }); 71 </script> 72 </body> 73 </html>`)) 74 75 var payload bytes.Buffer 76 if err := swaggerTemplate.Execute(&payload, struct{}{}); err != nil { 77 log.Warn("Could not render Swagger", zap.Error(err)) 78 79 writer.Header().Set("Content-Type", "text/plain; charset=utf-8") 80 writer.WriteHeader(http.StatusInternalServerError) 81 _, err := writer.Write([]byte("Could not render Swagger")) 82 log.Warn("Failed to write response", zap.Error(err)) 83 84 return 85 } 86 87 writer.Header().Set("Content-Type", "text/html; charset=utf-8") 88 writer.WriteHeader(http.StatusOK) 89 _, err := writer.Write(payload.Bytes()) 90 if err != nil { 91 log.Warn("Failed to write response", zap.Error(err)) 92 } 93 } 94 95 // SwaggerAPIv1 serves the apiv1 swagger json file. 96 func SwaggerAPIv1( 97 writer http.ResponseWriter, 98 _ *http.Request, 99 ) { 100 writer.Header().Set("Content-Type", "application/json; charset=utf-8") 101 writer.WriteHeader(http.StatusOK) 102 if _, err := writer.Write(apiV1JSON); err != nil { 103 log.Warn("Failed to write response", zap.Error(err)) 104 } 105 }