You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

168 lines
4.3 KiB

package main
import (
"context"
"crypto/tls"
"fmt"
"io"
"log"
"net/http"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"src.whiteboxsystems.nl/decozo/okapidemo/dvzaservice/model"
"src.whiteboxsystems.nl/decozo/okapidemo/sharedmodel"
)
type UIService struct {
srv *http.Server
inited bool
data *gorm.DB
clientCert tls.Certificate
}
func (srv *UIService) LoadData(location string) error {
var err error
srv.data, err = model.GetDB(location)
return err
}
func (srv *UIService) Addr() string {
if srv.srv == nil {
return ""
}
return srv.srv.Addr
}
func (srv *UIService) ListenAndServe() {
if !srv.inited {
srv.init()
}
log.Printf("Listening on %v\n", srv.srv.Addr)
srv.srv.ListenAndServe()
}
func (srv *UIService) Shutdown(ctx context.Context) error {
return srv.srv.Shutdown(ctx)
}
func (srv *UIService) init() {
r := srv.srv.Handler.(*gin.Engine)
r.LoadHTMLGlob("templates/*")
r.Static("/assets", "./assets")
r.Use(srv.Authenticate)
r.GET("/", func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "/ui")
})
r.GET("/ui", srv.GetIndex)
r.GET("/ui/*page", srv.GetIndex)
r.GET("/api/connections", srv.GetConnections)
r.GET("/api/connections/:connID", srv.GetConnection)
r.GET("/api/connections/:connID/:serviceID", srv.GetSubscriptions)
r.GET("/api/connections/:connID/:serviceID/:patientID", srv.GetPatient)
r.GET("/api/registrations", srv.GetRegistrations)
// r.GET("/api/systems/:sysid/patients", srv.GetPatients)
// r.GET("/api/systems/:sysid/patients/:patid", srv.GetPatient)
srv.inited = true
}
func (srv *UIService) GetIndex(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", gin.H{"externalURL": extRpcAddr})
}
func (srv *UIService) GetConnection(c *gin.Context) {
connID := c.Param("connID")
connection := &sharedmodel.Connection{}
srv.data.Where("id = ?", connID).Find(&connection)
c.JSON(http.StatusOK, connection)
}
func (srv *UIService) GetSubscriptions(c *gin.Context) {
connID := c.Param("connID")
serviceID := c.Param("serviceID")
serviceConfig := &sharedmodel.ServiceConfig{}
srv.data.Preload("Service").Preload("Subscriptions").Where("connection_id = ? and id = ?", connID, serviceID).Find(&serviceConfig)
c.JSON(http.StatusOK, serviceConfig)
}
func (srv *UIService) GetPatient(c *gin.Context) {
connID := c.Param("connID")
serviceID := c.Param("serviceID")
patientID := c.Param("patientID")
patient := &sharedmodel.Subscription{}
serviceConfig := &sharedmodel.ServiceConfig{}
srv.data.Preload("FetchProtocol").Preload("FetchProtocol.AuthConfig").Preload("Service").Where("connection_id = ? and id = ?", connID, serviceID).Find(&serviceConfig)
srv.data.Where("service_config_id = ? and id = ?", serviceID, patientID).Find(&patient)
protoconfig := map[string]string{}
protometa := map[string]string{}
err := serviceConfig.FetchProtocol.UnmarshalConfig(&protoconfig)
if err != nil {
c.AbortWithStatus(http.StatusBadRequest)
return
}
err = patient.GetProtocolMeta(&protometa)
if err != nil {
c.AbortWithStatus(http.StatusBadRequest)
return
}
url := fmt.Sprintf("%v?id=%v", protoconfig["url"], protometa["patientID"])
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", serviceConfig.FetchProtocol.AuthConfig.Raw)
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
}
resp, err := client.Do(req)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
if resp.StatusCode >= 400 {
c.AbortWithError(resp.StatusCode, fmt.Errorf("%v", resp.Status))
return
}
io.Copy(c.Writer, resp.Body)
}
func (srv *UIService) Authenticate(c *gin.Context) {
// Maybe authenticate user
}
func (srv *UIService) GetConnections(c *gin.Context) {
connections := []*sharedmodel.Connection{}
srv.data.Preload("Services").Preload("Services.Service").Preload("Services.Subscriptions").Find(&connections)
c.JSON(http.StatusOK, connections)
}
func (srv *UIService) GetRegistrations(c *gin.Context) {
registrations := []*sharedmodel.Registration{}
srv.data.Where("status = ?", sharedmodel.RegistrationStatusPending).Find(&registrations)
c.JSON(http.StatusOK, registrations)
}
func NewUIServer(addr string) *UIService {
cert := loadCert()
srv := &UIService{srv: &http.Server{
Addr: addr,
Handler: gin.Default(),
}, clientCert: *cert}
return srv
}