Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement data portal router #972

Closed
rockfordlhotka opened this Issue Nov 8, 2018 · 1 comment

Comments

Projects
1 participant
@rockfordlhotka
Copy link
Member

commented Nov 8, 2018

Versioning of client apps and servers in sync can be problematic. This is particularly true for smart client scenarios, especially mobile clients (where deployment may occur over time due to Apple/Google/Microsoft stores).

This means the simple n-tier model for CSLA apps

image

may not be adequate. Versioning in this case means standing up versioned endpoints. For example:

https://example.com/v1/dataportal
https://example.com/v2/dataportal

And that's fine - that's what I've been recommending people do for years. And that's OK in some cases.

But in other cases it would be far better to have a single public endpoint for all client devices to invoke, and then that endpoint could route calls to non-public versioned endpoints.

image

In this case the public endpoint would be consistent:

https://example.com/dataportal

And the "behind the scenes" endpoints would be versioned:

https://appserver-v1/dataportal
https://appserver-v2/dataportal

This is particularly beneficial in a Docker/Kubernetes scenario, where the public endpoint is defined as a K8s service and has public security and configuration, while the K8s cluster runs n appserver-v1 and appserver-v2 instances based on load - but without the public security/configuration concerns.

Also, in a K8s scenario it is possible (if desired) to run all three containers in a single pod, allowing the public endpoint to route to "localhost" endpoints for each version of the actual appserver, differentiated by port number:

https://localhost:32123/dataportal
https://localhost:32124/dataportal

Either way, what's needed is a data portal router component that exposes the public endpoint and routes each call to an appropriate private server endpoint.

My plan is to implement this only for the HttpProxy/Host channel, because I can do that without deserializing/reserializing the message payload on the router (I don't see how to avoid that with WCF...).

It should be possible to add a version element to the payload sent from the client-side dataportal to the server, right alongside the serialized object graph. That version element can be used to route the call, with minimal overhead, to the version-specific private server endpoint.

@rockfordlhotka rockfordlhotka self-assigned this Nov 8, 2018

@rockfordlhotka rockfordlhotka added this to To do in Version 4.9.0 via automation Nov 8, 2018

@rockfordlhotka rockfordlhotka moved this from To do to In progress in Version 4.9.0 Nov 21, 2018

rockfordlhotka added a commit to rockfordlhotka/csla that referenced this issue Nov 22, 2018

rockfordlhotka added a commit to rockfordlhotka/csla that referenced this issue Nov 22, 2018

rockfordlhotka added a commit to rockfordlhotka/csla that referenced this issue Nov 22, 2018

rockfordlhotka added a commit to rockfordlhotka/csla that referenced this issue Nov 23, 2018

rockfordlhotka added a commit to rockfordlhotka/csla that referenced this issue Nov 23, 2018

rockfordlhotka added a commit to rockfordlhotka/csla that referenced this issue Nov 24, 2018

rockfordlhotka added a commit to rockfordlhotka/csla that referenced this issue Nov 26, 2018

@rockfordlhotka

This comment has been minimized.

Copy link
Member Author

commented Nov 26, 2018

This is now implemented for HttpProxy and the .NET Core Http data portal controller.

The scope of the change has changed somewhat. As per the original request it does handle routing based on app version. However, it now also allows per-type routing so data portal operations for specific root domain types can be routed to specific servers in a cluster.

There is now an ApplicationContext.VersionRoutingTag property (which can be set via config with override at runtime) that you should use to specify the version of your app. This is an arbitrary string (that can't contain '-' or '/').

There is now a DataPortalServerRoutingTag attribute you can apply to a class or interface. This allows you to attach an arbitrary routing tag string (that can't contain '-' or '/') to a specific type.

The client-side data portal passes a routing tag to the server with the following format:

"{routingTag}-{versionTag}"

If you haven't specified either value no tag is passed. If you specify only a per-type routing tag the format is:

"{routingTag}-"

If you specify only a version tag the format is:

"-{versionTag}"

In the server-side HttpPortalController constructor you must load a dictionary with key-value pairs to route calls based on these tags.

  • The key is a full routing tag as described above
  • The value is a URL of an HttpPortalController endpoint on another server that should handle the call (or "localhost" if you want this server to handle the request with no routing)

rockfordlhotka added a commit to rockfordlhotka/csla that referenced this issue Nov 26, 2018

rockfordlhotka added a commit to rockfordlhotka/csla that referenced this issue Nov 26, 2018

Version 4.9.0 automation moved this from In progress to Done Nov 26, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.