Skip to content

Commit d58d726

Browse files
committed
pacsoi service weight dist
1 parent 85a7d42 commit d58d726

49 files changed

Lines changed: 1672 additions & 12149 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ More on accessing services in the [documentation](/docs/deploying-services.md)
101101

102102
### Cluster Management
103103
```bash
104-
make init # Create cluster, build & load containers, start cleaner
104+
make kind-init # Create cluster, build & load containers, start cleaner
105105
make kind-start # Create/start Kind cluster only
106106
make kind-stop # Pause Kind cluster
107107
make kind-delete # Delete Kind Cluster
@@ -164,12 +164,11 @@ sudo apt install -y golang-go
164164

165165
### Integration Tests
166166

167-
Integration tests use the existing Kind cluster created by `make init`.
167+
Integration tests use the existing Kind cluster created by `make kind-init`.
168168

169169
```bash
170170
# First-time setup
171-
make init
172-
make deploy
171+
make kind-init
173172

174173
# Run tests (uses existing cluster)
175174
make integration-test

containers/aggregator-server/config/client.go

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package config
33
import (
44
"aggregator/model"
55
"encoding/json"
6+
"fmt"
67
"net/http"
78

89
"github.com/sirupsen/logrus"
@@ -13,14 +14,17 @@ type ClientIdentifierDocument struct {
1314
ClientID string `json:"client_id"`
1415
}
1516

16-
var clientIdentifierJSONLD []byte
17+
var (
18+
clientIdentifierJSON []byte
19+
clientIdentifierJSONLD []byte
20+
)
1721

1822
func InitClientIdentifier(mux *http.ServeMux) {
1923
logrus.Info("Initializing client identifier endpoint")
20-
model.SolidClientId = model.ExternalURL() + "/client.jsonld"
2124

22-
var err error
25+
model.SolidClientId = fmt.Sprintf("%s/id", model.ExternalURL())
2326

27+
var err error
2428
// Pre-encode JSON-LD version (with context)
2529
clientDocLD := ClientIdentifierDocument{
2630
Context: []string{"https://www.w3.org/ns/solid/oidc-context.jsonld"},
@@ -31,7 +35,16 @@ func InitClientIdentifier(mux *http.ServeMux) {
3135
logrus.WithError(err).Fatal("Failed to marshal client identifier JSON-LD document")
3236
}
3337

34-
mux.HandleFunc("/client.jsonld", handleClientIdentifier)
38+
// Pre-encode JSON version (without context)
39+
clientDocJSON := ClientIdentifierDocument{
40+
ClientID: model.SolidClientId,
41+
}
42+
clientIdentifierJSON, err = json.Marshal(clientDocJSON)
43+
if err != nil {
44+
logrus.WithError(err).Fatal("Failed to marshal client identifier JSON document")
45+
}
46+
47+
mux.HandleFunc("/id", handleClientIdentifier)
3548
logrus.Info("Client identifier endpoint initialization completed")
3649
}
3750

@@ -41,13 +54,28 @@ func handleClientIdentifier(w http.ResponseWriter, r *http.Request) {
4154
return
4255
}
4356

44-
w.Header().Set("Content-Type", "application/ld+json")
57+
accept := r.Header.Get("Accept")
58+
59+
var contentType string
60+
var body []byte
61+
62+
preferredType := negotiateContentType(accept, []string{"application/ld+json", "application/json"})
63+
64+
if preferredType == "application/json" {
65+
contentType = "application/json"
66+
body = clientIdentifierJSON
67+
} else {
68+
contentType = "application/ld+json"
69+
body = clientIdentifierJSONLD
70+
}
71+
72+
w.Header().Set("Content-Type", contentType)
4573

4674
if r.Method == http.MethodHead {
4775
return
4876
}
4977

50-
if _, err := w.Write(clientIdentifierJSONLD); err != nil {
78+
if _, err := w.Write(body); err != nil {
5179
logrus.WithError(err).Error("Failed to write client identifier document")
5280
}
5381
}

containers/aggregator-server/config/description.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ type AggregatorServerDescription struct {
1212
RegistrationEndpoint string `json:"registration_endpoint"`
1313
SupportedRegistrationTypes []string `json:"supported_registration_types"`
1414
Version string `json:"version"`
15-
ClientIdentifier string `json:"client_identifier"`
15+
ClientIdentifier string `json:"client_identifier,omitempty"`
1616
TransformationCatalog string `json:"transformation_catalog"`
1717
}
1818

@@ -33,15 +33,12 @@ func handleServerDescription(w http.ResponseWriter, r *http.Request) {
3333

3434
// TODO: semantic representations need to be added at some point
3535
supported := model.AllowedRegistrationTypes
36-
if len(supported) == 0 {
37-
supported = []string{"authorization_code"}
38-
}
3936

4037
desc := AggregatorServerDescription{
4138
RegistrationEndpoint: fmt.Sprintf("%s%s", model.ExternalURL(), model.RegistrationEndpoint),
4239
SupportedRegistrationTypes: supported,
4340
Version: "1.0.0",
44-
ClientIdentifier: fmt.Sprintf("%s/client.jsonld", model.ExternalURL()),
41+
ClientIdentifier: model.SolidClientId,
4542
TransformationCatalog: fmt.Sprintf("%s%s", model.ExternalURL(), model.TransformationCatalog),
4643
}
4744

containers/aggregator-server/instance/deployment.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ import (
44
"aggregator/model"
55
"context"
66
"fmt"
7+
"time"
78

89
appsv1 "k8s.io/api/apps/v1"
910
corev1 "k8s.io/api/core/v1"
1011
networkingv1 "k8s.io/api/networking/v1"
1112
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1213
"k8s.io/apimachinery/pkg/util/intstr"
14+
"k8s.io/client-go/kubernetes"
1315
)
1416

1517
func ensureDeployment(
@@ -183,6 +185,18 @@ func ensureDeployment(
183185
ReadOnly: true,
184186
},
185187
},
188+
ReadinessProbe: &corev1.Probe{
189+
ProbeHandler: corev1.ProbeHandler{
190+
HTTPGet: &corev1.HTTPGetAction{
191+
Path: "/healthz",
192+
Port: intstr.FromInt(5000),
193+
},
194+
},
195+
InitialDelaySeconds: 1,
196+
PeriodSeconds: 2,
197+
TimeoutSeconds: 5,
198+
FailureThreshold: 5,
199+
},
186200
},
187201
},
188202
Volumes: []corev1.Volume{
@@ -206,5 +220,36 @@ func ensureDeployment(
206220
if err != nil {
207221
return fmt.Errorf("failed to create deployment: %w", err)
208222
}
223+
224+
err = waitForDeploymentReady(model.Clientset, model.Namespace, deployment.Name, 2*time.Minute)
225+
if err != nil {
226+
return err
227+
}
228+
209229
return nil
210230
}
231+
232+
func waitForDeploymentReady(client kubernetes.Interface, namespace, name string, timeout time.Duration) error {
233+
deadline := time.Now().Add(timeout)
234+
235+
for {
236+
dep, err := client.AppsV1().
237+
Deployments(namespace).
238+
Get(context.TODO(), name, metav1.GetOptions{})
239+
if err != nil {
240+
return err
241+
}
242+
243+
// Check if desired replicas are ready
244+
if dep.Status.ReadyReplicas == *dep.Spec.Replicas &&
245+
dep.Status.AvailableReplicas == *dep.Spec.Replicas {
246+
return nil
247+
}
248+
249+
if time.Now().After(deadline) {
250+
return fmt.Errorf("timeout waiting for deployment to be ready")
251+
}
252+
253+
time.Sleep(2 * time.Second)
254+
}
255+
}

containers/aggregator-server/main.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,10 @@ func main() {
189189
logrus.WithError(err).Warn("Failed to set up configuration endpoint (UMA might be down)")
190190
}
191191

192-
// Client Identifier endpoint
193-
config.InitClientIdentifier(serverMux)
192+
// Solid Client Identifier endpoint
193+
if solidOIDCEnabled {
194+
config.InitClientIdentifier(serverMux)
195+
}
194196

195197
// Server Description endpoint
196198
config.InitServerDescription(serverMux)

containers/aggregator-server/registration/registration.go

Lines changed: 65 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -27,58 +27,95 @@ func RegistrationHandler(w http.ResponseWriter, r *http.Request) {
2727

2828
// handleRegistrationPost handles POST requests for creating/updating aggregators
2929
func handleRegistrationPost(w http.ResponseWriter, r *http.Request) {
30+
log := logrus.WithField("handler", "handleRegistrationPost")
31+
log.Info("Incoming registration request")
32+
3033
// Parse request body
3134
var req model.RegistrationRequest
3235
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
33-
logrus.WithError(err).Warn("Invalid JSON body")
36+
log.WithError(err).
37+
WithField("stage", "decode_body").
38+
Warn("Failed to decode JSON body")
3439
http.Error(w, "Invalid JSON body", http.StatusBadRequest)
3540
return
3641
}
42+
log.Debug("Request body successfully decoded")
3743

38-
// Validate registration_type is present
44+
// Validate registration_type
3945
if req.RegistrationType == "" {
40-
logrus.Warn("Missing registration_type")
46+
log.WithField("stage", "validation").
47+
Error("Missing registration_type")
4148
http.Error(w, "registration_type is required", http.StatusBadRequest)
4249
return
4350
}
4451

4552
registrationType := strings.ToLower(req.RegistrationType)
53+
log = log.WithField("registration_type", registrationType)
54+
4655
if !isRegistrationTypeAllowed(registrationType) {
47-
logrus.Warnf("Registration type not allowed: %s", registrationType)
56+
log.WithField("stage", "validation").
57+
Warn("Unsupported registration_type")
4858
http.Error(w, "Unsupported registration_type", http.StatusBadRequest)
4959
return
5060
}
61+
log.Debug("registration_type validated")
5162

63+
// Public flows (no auth required)
5264
switch registrationType {
5365
case "device_code":
66+
log.Info("Routing to device_code flow")
5467
handleDeviceCodeFlow(w, req)
68+
return
69+
5570
case "none":
71+
log.Info("Routing to none flow")
5672
handleNoneFlow(w, req)
57-
default:
58-
issuer, id, mode, err := authenticateRequest(r)
59-
if err != nil {
60-
logrus.WithError(err).Warn("Authentication failed")
61-
http.Error(w, "Unauthorized", http.StatusUnauthorized)
62-
return
63-
}
64-
if id == "" {
65-
logrus.Warn("Authentication missing for registration request")
66-
http.Error(w, "Unauthorized", http.StatusUnauthorized)
67-
return
68-
}
73+
return
74+
}
6975

70-
// Route to appropriate handler based on registration_type
71-
switch registrationType {
72-
case "provision":
73-
handleProvisionFlow(w, req, id)
74-
case "authorization_code":
75-
handleAuthorizationCodeFlow(w, req, issuer, id, mode)
76-
case "client_credentials":
77-
handleClientCredentialsFlow(w, req, issuer, id)
78-
default:
79-
logrus.Warnf("Unsupported registration_type: %s", registrationType)
80-
http.Error(w, "Unsupported registration_type", http.StatusBadRequest)
81-
}
76+
// Authentication required for remaining flows
77+
log.Debug("Authenticating request")
78+
issuer, id, mode, err := authenticateRequest(r)
79+
if err != nil {
80+
log.WithError(err).
81+
WithField("stage", "authentication").
82+
Warn("Authentication failed")
83+
http.Error(w, "Unauthorized", http.StatusUnauthorized)
84+
return
85+
}
86+
87+
if id == "" {
88+
log.WithField("stage", "authentication").
89+
Warn("Missing subject identifier in authentication")
90+
http.Error(w, "Unauthorized", http.StatusUnauthorized)
91+
return
92+
}
93+
94+
log = log.WithFields(logrus.Fields{
95+
"issuer": issuer,
96+
"client_id": id,
97+
"auth_mode": mode,
98+
})
99+
log.Debug("Authentication successful")
100+
101+
// Route to authenticated flows
102+
switch registrationType {
103+
case "provision":
104+
log.Info("Routing to provision flow")
105+
handleProvisionFlow(w, req, id)
106+
107+
case "authorization_code":
108+
log.Info("Routing to authorization_code flow")
109+
handleAuthorizationCodeFlow(w, req, issuer, id, mode)
110+
111+
case "client_credentials":
112+
log.Info("Routing to client_credentials flow")
113+
handleClientCredentialsFlow(w, req, issuer, id)
114+
115+
default:
116+
log.WithField("stage", "routing").
117+
Warn("Reached unexpected registration_type")
118+
http.Error(w, "Unsupported registration_type", http.StatusBadRequest)
82119
}
83120
}
84121

0 commit comments

Comments
 (0)