Skip to content

Commit

Permalink
Design updates for Authenticator and Broker integration (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
cpurdy committed Nov 18, 2024
1 parent 282efcf commit 5f12aab
Show file tree
Hide file tree
Showing 6 changed files with 290 additions and 306 deletions.
34 changes: 16 additions & 18 deletions lib_xenia/src/main/x/xenia/Catalog.x
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import sec.Permission;

import web.*;

import WebService.Constructor;
import WebService.Constructor as WSConstructor;

/**
* The catalog of WebApp endpoints.
Expand Down Expand Up @@ -72,7 +72,7 @@ const Catalog(WebApp webApp, String systemPath, WebServiceInfo[] services, Class
*/
static const WebServiceInfo(Int id,
String path,
Constructor constructor,
WSConstructor constructor,
EndpointInfo[] endpoints,
EndpointInfo? defaultGet,
MethodInfo[] interceptors,
Expand Down Expand Up @@ -317,7 +317,7 @@ const Catalog(WebApp webApp, String systemPath, WebServiceInfo[] services, Class
* @param extras (optional) a map of WebService classes for processing requests for
* corresponding paths
*/
static Catalog buildCatalog(WebApp app, Map<Class<WebService>, Constructor> extras = []) {
static Catalog buildCatalog(WebApp app, Map<Class<WebService>, WSConstructor> extras = []) {
ClassInfo[] classInfos = new ClassInfo[];
Class[] sessionMixins = new Class[];

Expand All @@ -326,7 +326,7 @@ const Catalog(WebApp webApp, String systemPath, WebServiceInfo[] services, Class
// collect ClassInfos for "extras"; this should be done first to account for services
// without default constructors, which those extra services possibly are
if (!extras.empty) {
for ((Class<WebService> clz, Constructor constructor) : extras) {
for ((Class<WebService> clz, WSConstructor constructor) : extras) {
if (AnnotationTemplate webServiceAnno := clz.annotatedBy(WebService)) {
String path = extractPath(webServiceAnno, declaredPaths);
classInfos += new ClassInfo(path, clz, constructor);
Expand All @@ -340,29 +340,27 @@ const Catalog(WebApp webApp, String systemPath, WebServiceInfo[] services, Class
// collect the ClassInfos for standard WebServices and Session mixins
scanClasses(app.classes, classInfos, sessionMixins, declaredPaths);

// compute the system service name and add the system service info
String systemPath = DefaultSystemPath;
for (Int i = 0; declaredPaths.contains(systemPath); i++) {
systemPath = $"{DefaultSystemPath}_{i}";
}
classInfos += new ClassInfo(systemPath, SystemService,
SystemService.PublicType.defaultConstructor() ?: assert);
// TODO CP add any endpoints on the broker(s) and authenticator(s)
// // compute the system service name and add the system service info
// String systemPath = DefaultSystemPath;
// for (Int i = 0; declaredPaths.contains(systemPath); i++) {
// systemPath = $"{DefaultSystemPath}_{i}";
// }
// classInfos += new ClassInfo(systemPath, SystemService,
// SystemService.PublicType.defaultConstructor() ?: assert);

// sort the ClassInfos based on their paths (SystemService goes first)
classInfos.sorted((ci1, ci2) ->
ci1.path == systemPath ? Lesser : (ci1.path <=> ci2.path).reversed, inPlace=True);
classInfos.sorted((ci1, ci2) -> (ci1.path <=> ci2.path).reversed, inPlace=True);

// now collect all endpoints
// collect all of the endpoints into a Catalog
WebServiceInfo[] webServiceInfos = collectEndpoints(app, classInfos);
assert webServiceInfos[0].path == systemPath;

return new Catalog(app, systemPath, webServiceInfos, sessionMixins);
}

/**
* WebService info collected during the scan phase.
*/
private static const ClassInfo(String path, Class<WebService> clz, Constructor constructor);
private static const ClassInfo(String path, Class<WebService> clz, WSConstructor constructor);

/**
* Scan all the specified classes for WebServices and add the corresponding information
Expand All @@ -379,7 +377,7 @@ const Catalog(WebApp webApp, String systemPath, WebServiceInfo[] services, Class
assert child.is(Class<WebService>);

Type<WebService> serviceType = child.PublicType;
if (Constructor constructor := serviceType.defaultConstructor()) {
if (WSConstructor constructor := serviceType.defaultConstructor()) {
String path = extractPath(webServiceAnno, declaredPaths);

classInfos += new ClassInfo(path, child, constructor);
Expand Down
23 changes: 15 additions & 8 deletions lib_xenia/src/main/x/xenia/ChainBundle.x
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ service ChainBundle {
* @param index the index of this ChainBundle in the `BundlePool`
*/
construct(Catalog catalog, Int index) {
this.catalog = catalog;
this.index = index;

registry = catalog.webApp.registry_;
services = new WebService?[catalog.serviceCount];
chains = new Handler?[catalog.endpointCount];
errorHandlers = new ErrorHandler?[catalog.serviceCount];
this.catalog = catalog;
this.index = index;
this.authenticator = catalog.webApp.authenticator.duplicate();
this.registry = catalog.webApp.registry_;
this.services = new WebService?[catalog.serviceCount];
this.chains = new Handler?[catalog.endpointCount];
this.errorHandlers = new ErrorHandler?[catalog.serviceCount];
}

/**
Expand All @@ -69,6 +69,13 @@ service ChainBundle {
*/
public/private Catalog catalog;

/**
* The application's [Authenticator]; each ChainBundle duplicates the original `Authenticator`
* to avoid contention on a single `Authenticator` in case it is implemented without concurrency
* and has high-latency (e.g. database) operations.
*/
private Authenticator authenticator;

/**
* The index of this bundle in the BundlePool.
*/
Expand Down Expand Up @@ -97,7 +104,7 @@ service ChainBundle {
/**
* Obtain a call chain for the specified endpoint.
*/
Handler ensureCallChain(EndpointInfo endpoint, Authenticator authenticator) {
Handler ensureCallChain(EndpointInfo endpoint) {
Handler? handle = chains[endpoint.id];
if (handle != Null) {
return handle;
Expand Down
Loading

0 comments on commit 5f12aab

Please sign in to comment.