|
|
|
@ -2,22 +2,36 @@ package main |
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"context" |
|
|
|
|
"crypto/tls" |
|
|
|
|
"fmt" |
|
|
|
|
"log" |
|
|
|
|
"regexp" |
|
|
|
|
|
|
|
|
|
"google.golang.org/grpc" |
|
|
|
|
"google.golang.org/grpc/credentials" |
|
|
|
|
"google.golang.org/protobuf/types/known/structpb" |
|
|
|
|
"gorm.io/gorm" |
|
|
|
|
"whiteboxsystems.nl/openkvpoc/his/model" |
|
|
|
|
"whiteboxsystems.nl/openkvpoc/openkv" |
|
|
|
|
"whiteboxsystems.nl/openkvpoc/sharedmodel" |
|
|
|
|
"src.whiteboxsystems.nl/DECOZO/okapi" |
|
|
|
|
"whiteboxsystems.nl/okapidemo/certgen" |
|
|
|
|
"whiteboxsystems.nl/okapidemo/his/model" |
|
|
|
|
"whiteboxsystems.nl/okapidemo/sharedmodel" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
const CONN_PSK = "0000" |
|
|
|
|
func toStruct(m map[string]interface{}) *structpb.Struct { |
|
|
|
|
s, err := structpb.NewStruct(m) |
|
|
|
|
|
|
|
|
|
func getUnauthenticatedClient(addr string) (openkv.OpenKVClient, error) { |
|
|
|
|
if err != nil { |
|
|
|
|
panic(err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return s |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func getUnauthenticatedClient(addr string) (okapi.OkAPIClient, error) { |
|
|
|
|
opts := []grpc.DialOption{ |
|
|
|
|
grpc.WithInsecure(), // dont do this in any production env...
|
|
|
|
|
grpc.WithTransportCredentials( |
|
|
|
|
credentials.NewTLS(&tls.Config{InsecureSkipVerify: true}), // Don't do this in production
|
|
|
|
|
), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
conn, err := grpc.Dial(addr, opts...) |
|
|
|
@ -26,23 +40,26 @@ func getUnauthenticatedClient(addr string) (openkv.OpenKVClient, error) { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// defer conn.Close()
|
|
|
|
|
return openkv.NewOpenKVClient(conn), nil |
|
|
|
|
// defer serviceProvider.Close()
|
|
|
|
|
return okapi.NewOkAPIClient(conn), nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func getAuthenticatedClient(addr, psk string) (openkv.OpenKVClient, error) { |
|
|
|
|
func getAuthenticatedClient(serviceProvider *model.ServiceProvider, cert tls.Certificate) (okapi.OkAPIClient, error) { |
|
|
|
|
opts := []grpc.DialOption{ |
|
|
|
|
grpc.WithPerRPCCredentials(makePSKAuth(psk, true)), |
|
|
|
|
grpc.WithInsecure(), // dont do this in any production env...
|
|
|
|
|
grpc.WithTransportCredentials( |
|
|
|
|
credentials.NewTLS(&tls.Config{ |
|
|
|
|
InsecureSkipVerify: true, |
|
|
|
|
Certificates: []tls.Certificate{cert}, |
|
|
|
|
}), |
|
|
|
|
), |
|
|
|
|
} |
|
|
|
|
conn, err := grpc.Dial(addr, opts...) |
|
|
|
|
conn, err := grpc.Dial(serviceProvider.Addr, opts...) |
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// defer conn.Close()
|
|
|
|
|
return openkv.NewOpenKVClient(conn), nil |
|
|
|
|
return okapi.NewOkAPIClient(conn), nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type PSKAuth struct { |
|
|
|
@ -64,23 +81,33 @@ func makePSKAuth(psk string, insecure bool) *PSKAuth { |
|
|
|
|
return &PSKAuth{psk, insecure} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (srv *HISServer) register(addr string) (*model.Connection, error) { |
|
|
|
|
func (srv *HISServer) register(addr string) (*model.ServiceProvider, error) { |
|
|
|
|
client, err := getUnauthenticatedClient(addr) |
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
auth := &openkv.AuthConfig{ |
|
|
|
|
Method: openkv.AuthMethod_APIToken, |
|
|
|
|
Config: &openkv.AuthConfig_ApiTokenConfig{&openkv.APITokenConfig{Token: CONN_PSK}}, |
|
|
|
|
jwkBytes, err := certgen.PublicKeyToJWKJson(certgen.ExtractPublicKey(srv.clientCert.PrivateKey)) |
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
auth := &okapi.XISAuthConfiguration{ |
|
|
|
|
Method: okapi.XISAuthMethod_mTLS, |
|
|
|
|
Configuration: &okapi.XISAuthConfiguration_MtlsConfiguration{ |
|
|
|
|
MtlsConfiguration: &okapi.MTLSConfigurationParams{ |
|
|
|
|
PublicKey: string(jwkBytes), |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
resp, err := client.Register(context.Background(), &openkv.RegisterRequest{ |
|
|
|
|
OrganisationId: "00009999", |
|
|
|
|
OrganisationIdSystem: "https://vektis.nl/agbz", |
|
|
|
|
OrganisationDisplayName: "Praktijk de oude berg", |
|
|
|
|
Auth: auth, |
|
|
|
|
resp, err := client.Register(context.Background(), &okapi.RegisterRequest{ |
|
|
|
|
OrganisationIdentifier: "00009999", |
|
|
|
|
OrganisationIdentifierType: "https://vektis.nl/agbz", |
|
|
|
|
OrganisationDisplayName: "Praktijk de oude berg", |
|
|
|
|
Auth: auth, |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
@ -88,15 +115,11 @@ func (srv *HISServer) register(addr string) (*model.Connection, error) { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if !resp.Success { |
|
|
|
|
return nil, fmt.Errorf("%v", resp.Error.Message) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
connection := &model.Connection{ |
|
|
|
|
connection := &model.ServiceProvider{ |
|
|
|
|
Addr: addr, |
|
|
|
|
AuthConfig: &sharedmodel.AuthConfig{ |
|
|
|
|
Method: openkv.AuthMethod_APIToken, |
|
|
|
|
Raw: CONN_PSK, |
|
|
|
|
AuthConfig: &sharedmodel.XISAuthConfig{ |
|
|
|
|
Method: int32(okapi.XISAuthMethod_mTLS), |
|
|
|
|
Raw: string(jwkBytes), |
|
|
|
|
}, |
|
|
|
|
State: model.ConnectionStatePending, |
|
|
|
|
Reference: resp.Reference, |
|
|
|
@ -104,8 +127,8 @@ func (srv *HISServer) register(addr string) (*model.Connection, error) { |
|
|
|
|
|
|
|
|
|
meta, _ := srv.listMeta(connection) |
|
|
|
|
|
|
|
|
|
connection.Supplier = meta.Supplier |
|
|
|
|
connection.System = meta.System |
|
|
|
|
connection.Supplier = meta.SupplierDisplayName |
|
|
|
|
connection.System = meta.ProductName |
|
|
|
|
|
|
|
|
|
if err := srv.data.Create(connection).Error; err != nil { |
|
|
|
|
return nil, err |
|
|
|
@ -114,164 +137,145 @@ func (srv *HISServer) register(addr string) (*model.Connection, error) { |
|
|
|
|
return connection, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (srv *HISServer) activate(conn *model.Connection, psk string) (*model.Connection, error) { |
|
|
|
|
client, err := getAuthenticatedClient(conn.Addr, conn.AuthConfig.Raw) |
|
|
|
|
func (srv *HISServer) activate(serviceProvider *model.ServiceProvider, psk string) (*model.ServiceProvider, error) { |
|
|
|
|
client, err := getAuthenticatedClient(serviceProvider, srv.clientCert) |
|
|
|
|
if err != nil { |
|
|
|
|
panic(err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
resp, err := client.CompleteRegistration(context.Background(), &openkv.CompleteRegistrationRequest{ |
|
|
|
|
Reference: conn.Reference, |
|
|
|
|
RegistrationToken: psk, |
|
|
|
|
_, err = client.CompleteRegistration(context.Background(), &okapi.CompleteRegistrationRequest{ |
|
|
|
|
Reference: serviceProvider.Reference, |
|
|
|
|
AuthorizationToken: psk, |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
log.Printf("Err in request: %v", err) |
|
|
|
|
return nil, err |
|
|
|
|
} else if !resp.Success { |
|
|
|
|
log.Printf("success: %v; Err: %v", resp.Success, resp.Error) |
|
|
|
|
return nil, fmt.Errorf("%v", resp.Error.Message) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
meta, err := srv.listMeta(conn) |
|
|
|
|
meta, err := srv.listMeta(serviceProvider) |
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
return conn, fmt.Errorf("Failed to retreive metadata: %v ", err) |
|
|
|
|
return serviceProvider, fmt.Errorf("Failed to retreive metadata: %v ", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
conn.State = model.ConnectionStateCompleted |
|
|
|
|
conn.Supplier = meta.Supplier |
|
|
|
|
conn.System = meta.System |
|
|
|
|
serviceProvider.State = model.ConnectionStateCompleted |
|
|
|
|
serviceProvider.Supplier = meta.SupplierDisplayName |
|
|
|
|
serviceProvider.System = meta.ProductName |
|
|
|
|
|
|
|
|
|
if err := srv.data.Save(conn).Error; err != nil { |
|
|
|
|
if err := srv.data.Save(serviceProvider).Error; err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return conn, err |
|
|
|
|
return serviceProvider, err |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (srv *HISServer) listMeta(serviceProvider *model.ServiceProvider) (*okapi.GetMetadataResponse, error) { |
|
|
|
|
client, err := getUnauthenticatedClient(serviceProvider.Addr) |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
resp, err := client.GetMetadata(context.Background(), &okapi.GetMetadataRequest{}) |
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
log.Printf("Err in request: %v", err) |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return resp, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (srv *HISServer) listMeta(conn *model.Connection) (*openkv.GetMetadataResponse, error) { |
|
|
|
|
client, err := getUnauthenticatedClient(conn.Addr) |
|
|
|
|
func (srv *HISServer) listServices(serviceProvider *model.ServiceProvider) (*okapi.ListServicesResponse, error) { |
|
|
|
|
client, err := getAuthenticatedClient(serviceProvider, srv.clientCert) |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
resp, err := client.GetMetadata(context.Background(), &openkv.GetMetadataRequest{}) |
|
|
|
|
resp, err := client.ListServices(context.Background(), &okapi.ListServicesRequest{}) |
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
log.Printf("Err in request: %v", err) |
|
|
|
|
return nil, err |
|
|
|
|
} else if !resp.Success { |
|
|
|
|
log.Printf("success: %v; Err: %v", resp.Success, resp.Error) |
|
|
|
|
return nil, fmt.Errorf("%v", resp.Error.Message) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return resp, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (srv *HISServer) enableService(conn *model.Connection, service string, active bool) error { |
|
|
|
|
client, err := getAuthenticatedClient(conn.Addr, conn.AuthConfig.Raw) |
|
|
|
|
func (srv *HISServer) enableService(serviceProvider *model.ServiceProvider, serviceId string) error { |
|
|
|
|
client, err := getAuthenticatedClient(serviceProvider, srv.clientCert) |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
moddedService := &model.Service{} |
|
|
|
|
moddedServiceErr := srv.data.Where("connection_id = ? and service_id = ?", conn.ID, service).First(moddedService).Error |
|
|
|
|
moddedServiceErr := srv.data.Where("service_provider_id = ? and service_id = ?", serviceProvider.ID, serviceId).First(moddedService).Error |
|
|
|
|
|
|
|
|
|
if moddedServiceErr != nil && moddedServiceErr != gorm.ErrRecordNotFound { |
|
|
|
|
return moddedServiceErr |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if moddedServiceErr != nil && !active { |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if moddedServiceErr == nil && active { |
|
|
|
|
return nil |
|
|
|
|
if moddedServiceErr == nil { |
|
|
|
|
return fmt.Errorf("Service already activivated") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
meta, _ := srv.listMeta(conn) |
|
|
|
|
var serviceDefinition *openkv.ServiceDefinition |
|
|
|
|
meta, _ := srv.listServices(serviceProvider) |
|
|
|
|
var serviceDefinition *okapi.Service |
|
|
|
|
|
|
|
|
|
for _, sd := range meta.Services { |
|
|
|
|
if sd.Id == service { |
|
|
|
|
if sd.Id == serviceId { |
|
|
|
|
serviceDefinition = sd |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if serviceDefinition == nil { |
|
|
|
|
return fmt.Errorf("Invalid service: %v", service) |
|
|
|
|
return fmt.Errorf("Invalid service: %v", serviceId) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var resp *openkv.ConfigServiceResponse |
|
|
|
|
var resp *okapi.EnableServiceResponse |
|
|
|
|
|
|
|
|
|
if m, _ := regexp.MatchString("wbx:*", service); m { // Whitebox
|
|
|
|
|
resp, err = client.ConfigService(context.Background(), &openkv.ConfigServiceRequest{ |
|
|
|
|
Service: service, |
|
|
|
|
Enabled: active, |
|
|
|
|
Fetch: &openkv.ServiceConfig{ |
|
|
|
|
if m, _ := regexp.MatchString("wbx:*", serviceId); m { // Whitebox
|
|
|
|
|
resp, err = client.EnableService(context.Background(), &okapi.EnableServiceRequest{ |
|
|
|
|
ServiceId: serviceId, |
|
|
|
|
Fetch: &okapi.CallbackConfiguration{ |
|
|
|
|
Protocol: "https://whiteboxsystems.nl/protospecs/whitebox-fetch/http", |
|
|
|
|
Config: map[string]string{ |
|
|
|
|
Configuration: toStruct(map[string]interface{}{ |
|
|
|
|
"url": externalAddr + "/external/api", |
|
|
|
|
}, |
|
|
|
|
Auth: &openkv.AuthConfig{ |
|
|
|
|
Method: openkv.AuthMethod_APIToken, |
|
|
|
|
}), |
|
|
|
|
Auth: &okapi.ProtocolAuthConfiguration{ |
|
|
|
|
Method: sharedmodel.AuthMethodDecozoMTLS, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
Push: &openkv.ServiceConfig{ |
|
|
|
|
Push: &okapi.CallbackConfiguration{ |
|
|
|
|
Protocol: "https://whiteboxsystems.nl/protospecs/whitebox-push/http", |
|
|
|
|
Config: map[string]string{ |
|
|
|
|
Configuration: toStruct(map[string]interface{}{ |
|
|
|
|
"url": externalAddr + "/external/api", |
|
|
|
|
}, |
|
|
|
|
Auth: &openkv.AuthConfig{ |
|
|
|
|
Method: openkv.AuthMethod_APIToken, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}) |
|
|
|
|
} else if m, _ := regexp.MatchString("voorbeeld:*", service); m { // Kis
|
|
|
|
|
resp, err = client.ConfigService(context.Background(), &openkv.ConfigServiceRequest{ |
|
|
|
|
Service: service, |
|
|
|
|
Enabled: active, |
|
|
|
|
Fetch: &openkv.ServiceConfig{ |
|
|
|
|
Protocol: "https://whiteboxsystems.nl/protospecs/whitebox-fetch/http", |
|
|
|
|
Config: map[string]string{ |
|
|
|
|
"url": externalAddr + "/external/api", |
|
|
|
|
}, |
|
|
|
|
Auth: &openkv.AuthConfig{ |
|
|
|
|
Method: openkv.AuthMethod_APIToken, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
Push: &openkv.ServiceConfig{ |
|
|
|
|
Protocol: "https://whiteboxsystems.nl/protospecs/whitebox-push/http", |
|
|
|
|
Config: map[string]string{ |
|
|
|
|
"url": externalAddr + "/external/api", |
|
|
|
|
}, |
|
|
|
|
Auth: &openkv.AuthConfig{ |
|
|
|
|
Method: openkv.AuthMethod_APIToken, |
|
|
|
|
}), |
|
|
|
|
Auth: &okapi.ProtocolAuthConfiguration{ |
|
|
|
|
Method: sharedmodel.AuthMethodDecozoMTLS, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}) |
|
|
|
|
} else { // DVZA / FHIR
|
|
|
|
|
resp, err = client.ConfigService(context.Background(), &openkv.ConfigServiceRequest{ |
|
|
|
|
Service: service, |
|
|
|
|
Enabled: active, |
|
|
|
|
Fetch: &openkv.ServiceConfig{ |
|
|
|
|
resp, err = client.EnableService(context.Background(), &okapi.EnableServiceRequest{ |
|
|
|
|
ServiceId: serviceId, |
|
|
|
|
Fetch: &okapi.CallbackConfiguration{ |
|
|
|
|
Protocol: "https://hl7.org/fhir", |
|
|
|
|
Config: map[string]string{ |
|
|
|
|
Configuration: toStruct(map[string]interface{}{ |
|
|
|
|
"url": externalAddr + "/external/fhir/Patient", |
|
|
|
|
}, |
|
|
|
|
Auth: &openkv.AuthConfig{ |
|
|
|
|
Method: openkv.AuthMethod_APIToken, |
|
|
|
|
}), |
|
|
|
|
Auth: &okapi.ProtocolAuthConfiguration{ |
|
|
|
|
Method: sharedmodel.AuthMethodDecozoBearerToken, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
Push: &openkv.ServiceConfig{ |
|
|
|
|
Push: &okapi.CallbackConfiguration{ |
|
|
|
|
Protocol: "https://hl7.org/fhir", |
|
|
|
|
Config: map[string]string{ |
|
|
|
|
Configuration: toStruct(map[string]interface{}{ |
|
|
|
|
"url": externalAddr + "/external/fhir/Patient", |
|
|
|
|
}, |
|
|
|
|
Auth: &openkv.AuthConfig{ |
|
|
|
|
Method: openkv.AuthMethod_APIToken, |
|
|
|
|
}), |
|
|
|
|
Auth: &okapi.ProtocolAuthConfiguration{ |
|
|
|
|
Method: sharedmodel.AuthMethodDecozoBearerToken, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}) |
|
|
|
@ -280,94 +284,154 @@ func (srv *HISServer) enableService(conn *model.Connection, service string, acti |
|
|
|
|
if err != nil { |
|
|
|
|
log.Printf("Err in request: %v", err) |
|
|
|
|
return err |
|
|
|
|
} else if !resp.Success { |
|
|
|
|
log.Printf("success: %v; Err: %v", resp.Success, resp.Error) |
|
|
|
|
return fmt.Errorf("%v", resp.Error) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if !active { |
|
|
|
|
subs := []model.Patient{} |
|
|
|
|
|
|
|
|
|
srv.data.Model(moddedService).Association("Subscriptions").Find(&subs) |
|
|
|
|
srv.data.Model(moddedService).Association("Subscriptions").Delete(subs) |
|
|
|
|
srv.subscribePatients(conn, moddedService, false, subs) |
|
|
|
|
return srv.data.Unscoped().Delete(moddedService).Error |
|
|
|
|
} |
|
|
|
|
authConfig := sharedmodel.NewAuthConfig(resp.Fetch.Auth) |
|
|
|
|
|
|
|
|
|
return srv.data.Create(&model.Service{ |
|
|
|
|
ConnectionID: conn.ID, |
|
|
|
|
ServiceProviderID: serviceProvider.ID, |
|
|
|
|
ServiceID: serviceDefinition.Id, |
|
|
|
|
Name: serviceDefinition.Name, |
|
|
|
|
Description: serviceDefinition.Name, |
|
|
|
|
SubscriptionPolicy: serviceDefinition.SubscriptionPolicy, |
|
|
|
|
ConsentPolicy: serviceDefinition.ConsentPolicy, |
|
|
|
|
AuthConfig: &sharedmodel.AuthConfig{ |
|
|
|
|
Method: resp.Fetch.Auth.Method, |
|
|
|
|
Raw: resp.Fetch.Auth.GetApiTokenConfig().Token, |
|
|
|
|
}, |
|
|
|
|
AuthConfig: authConfig, |
|
|
|
|
}).Error |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (srv *HISServer) subscribePatients(conn *model.Connection, service *model.Service, active bool, patients []model.Patient) (*openkv.UpdateSubscriptionsResponse, error) { |
|
|
|
|
client, err := getAuthenticatedClient(conn.Addr, conn.AuthConfig.Raw) |
|
|
|
|
func (srv *HISServer) disableService(serviceProvider *model.ServiceProvider, serviceId string) error { |
|
|
|
|
client, err := getAuthenticatedClient(serviceProvider, srv.clientCert) |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
moddedService := &model.Service{} |
|
|
|
|
moddedServiceErr := srv.data.Where("service_provider_id = ? and service_id = ?", serviceProvider.ID, serviceId).First(moddedService).Error |
|
|
|
|
|
|
|
|
|
if moddedServiceErr != nil && moddedServiceErr != gorm.ErrRecordNotFound { |
|
|
|
|
return moddedServiceErr |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if moddedServiceErr != nil { |
|
|
|
|
return fmt.Errorf("Service not active") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
meta, _ := srv.listServices(serviceProvider) |
|
|
|
|
var serviceDefinition *okapi.Service |
|
|
|
|
|
|
|
|
|
for _, sd := range meta.Services { |
|
|
|
|
if sd.Id == serviceId { |
|
|
|
|
serviceDefinition = sd |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if serviceDefinition == nil { |
|
|
|
|
return fmt.Errorf("Invalid service: %v", serviceId) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_, err = client.DisableService(context.Background(), &okapi.DisableServiceRequest{ |
|
|
|
|
ServiceId: serviceId, |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
log.Printf("Err in request: %v", err) |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
subs := []model.Patient{} |
|
|
|
|
|
|
|
|
|
srv.data.Model(moddedService).Association("Subscriptions").Find(&subs) |
|
|
|
|
srv.data.Model(moddedService).Association("Subscriptions").Delete(subs) |
|
|
|
|
srv.unsubscribePatients(serviceProvider, moddedService, subs) |
|
|
|
|
return srv.data.Unscoped().Delete(moddedService).Error |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (srv *HISServer) subscribePatients(serviceProvider *model.ServiceProvider, service *model.Service, patients []model.Patient) (*okapi.CreateOrUpdatePatientRegistrationsResponse, error) { |
|
|
|
|
client, err := getAuthenticatedClient(serviceProvider, srv.clientCert) |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
subs := []*openkv.SubscriptionData{} |
|
|
|
|
subs := []*okapi.PatientRegistrationCreateOrUpdateData{} |
|
|
|
|
|
|
|
|
|
for _, pat := range patients { |
|
|
|
|
subs = append(subs, &openkv.SubscriptionData{ |
|
|
|
|
Subscribe: active, |
|
|
|
|
Subject: &openkv.PatientMeta{ |
|
|
|
|
ExternalId: pat.ExternalId, |
|
|
|
|
ExternalIdSystem: "http://fhir.nl/fhir/NamingSystem/bsn", |
|
|
|
|
Name: pat.Name, |
|
|
|
|
Birthdate: pat.Birthdate, |
|
|
|
|
subs = append(subs, &okapi.PatientRegistrationCreateOrUpdateData{ |
|
|
|
|
Id: pat.ExternalId, |
|
|
|
|
Subject: &okapi.PatientMeta{ |
|
|
|
|
Identifier: &okapi.Identifier{ |
|
|
|
|
Type: "http://fhir.nl/fhir/NamingSystem/bsn", |
|
|
|
|
Value: pat.ExternalId, |
|
|
|
|
}, |
|
|
|
|
Name: &okapi.Name{ |
|
|
|
|
Display: pat.Name, |
|
|
|
|
}, |
|
|
|
|
Address: &okapi.Address{}, |
|
|
|
|
Birthdate: pat.Birthdate, |
|
|
|
|
}, |
|
|
|
|
ProtocolMeta: map[string]string{ |
|
|
|
|
CallbackProtocolData: toStruct(map[string]interface{}{ |
|
|
|
|
"patientID": pat.PatientID, |
|
|
|
|
}, |
|
|
|
|
}), |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
req := &openkv.UpdateSubscriptionsRequest{ |
|
|
|
|
ServiceId: service.ServiceID, |
|
|
|
|
SubscriptionData: subs, |
|
|
|
|
req := &okapi.CreateOrUpdatePatientRegistrationsRequest{ |
|
|
|
|
ServiceId: service.ServiceID, |
|
|
|
|
Registrations: subs, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
resp, err := client.UpdateSubscriptions(context.Background(), req) |
|
|
|
|
resp, err := client.CreateOrUpdatePatientRegistrations(context.Background(), req) |
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
log.Printf("Err in request: %v", err) |
|
|
|
|
return nil, err |
|
|
|
|
} else if !resp.Success { |
|
|
|
|
log.Printf("success: %v; Err: %v", resp.Success, resp.Errors) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return resp, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (srv *HISServer) unsubscribePatients(serviceProvider *model.ServiceProvider, service *model.Service, patients []model.Patient) (*okapi.RemovePatientRegistrationsResponse, error) { |
|
|
|
|
client, err := getAuthenticatedClient(serviceProvider, srv.clientCert) |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
subs := []string{} |
|
|
|
|
|
|
|
|
|
for _, pat := range patients { |
|
|
|
|
subs = append(subs, pat.ExternalId) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
req := &okapi.RemovePatientRegistrationsRequest{ |
|
|
|
|
ServiceId: service.ServiceID, |
|
|
|
|
Registrations: subs, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
resp, err := client.RemovePatientRegistrations(context.Background(), req) |
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
log.Printf("Err in request: %v", err) |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return resp, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func listSubscriptions(addr, service string) { |
|
|
|
|
client, err := getAuthenticatedClient(addr, CONN_PSK) |
|
|
|
|
func (srv *HISServer) listPatientRegistrations(serviceProvider *model.ServiceProvider, service *model.Service) ([]*okapi.PatientRegistrationData, error) { |
|
|
|
|
client, err := getAuthenticatedClient(serviceProvider, srv.clientCert) |
|
|
|
|
if err != nil { |
|
|
|
|
panic(err) |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
req := &openkv.ListSubscriptionsRequest{ |
|
|
|
|
ServiceId: service, |
|
|
|
|
req := &okapi.ListPatientRegistrationsRequest{ |
|
|
|
|
ServiceId: service.ServiceID, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if resp, err := client.ListSubscriptions(context.Background(), req); err != nil { |
|
|
|
|
resp, err := client.ListPatientRegistrations(context.Background(), req) |
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
log.Printf("Err in request: %v", err) |
|
|
|
|
return |
|
|
|
|
} else { |
|
|
|
|
if !resp.Success { |
|
|
|
|
log.Printf("success: %v; Err: %v", resp.Success, resp.Error) |
|
|
|
|
} else { |
|
|
|
|
log.Printf("success: %v", resp) |
|
|
|
|
} |
|
|
|
|
return |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return resp.PatientRegistrationData, nil |
|
|
|
|
} |
|
|
|
|