This is part 2 in a series of posts about writing service brokers in .NET Core. In the previous post we implemented the bare minimum: a catalog and a blocking implementation of (de)provisioning a service. In this post we will look at a blocking implementation of service (un)binding. All posts in the series:
- Marketplace and service provisioning
- Service binding (this post)
- Provisioning an Azure Storage account
- Binding an Azure Storage account
Setting the stage
As in the first post, we implement (parts of) the Open Service Broker API specification. We use the OpenServiceBroker .NET library that already defines all necessary endpoints and provides implementation hooks for binding and unbinding. We use Pivotal Cloud Foundry, hosted at https://run.pivotal.io for testing our implementation and CF CLI for communicating with the platform.
All source code for this blog post can be found at: https://github.com/orangeglasses/service-broker-dotnet/tree/master.
What to bind to
When we want to bind a service to an application, we need an actual application. So we implement a second (empty) .NET Core application.
We now have two applications: the service broker and a client application that we can bind to, called rwwilden-client
.
Updating the catalog
In the first post we introduced a service catalog that advertised the rwwilden
service. We chose to make the service not-bindable because at that time, service binding was not implemented. When we try to bind the service anyway, an error occurs:
So we need to update the catalog to advertise a bindable service:
loading...
The only changes are at lines 14 and 32 where we set Bindable
to true
. Note that just setting Bindable
to true
at the plan level would also have been enough. Lower-level settings override higher-level ones.
Bind and unbind
Next step is to implement binding and unbinding. There are 4 different types of binding defined by the OSBAPI spec: credentials, log drain, route service and volume service. For this post we will implement the most common one: credentials. Since our service broker does not have an actual backing service, this is quite simple. In real life, you might have a MySQL service broker that provisions a database during bind and returns a connection string that allows your application to access the database.
The OSBAPI server library I used in the previous post provides hooks for implementing blocking (un)binding in the form of the IServiceBindingBlocking
interface so we just need to implement the BindAsync
and UnbindAsync
methods:
loading...
As you can see, our bind implementation simply returns a JObject
with a very secret connection string.
The final change to our code is to register the IServiceBindingBlocking
implementation with the DI container (line 4):
loading...
Updating the service broker
When we push the new service broker application, the platform (PCF) does not yet know that the service broker has changed. So when we try to bind a service to an application, this still fails with the error: the service instance doesn't support binding. To fix this, we can update the service broker using cf update-service-broker
:
Binding and unbinding the service
With an updated service broker in place that supports binding we have finally reached the goal of this post: binding to and unbinding from the my-rwwilden
service:
With the first command we bind the rwwilden-client
application to the my-rwwilden
service and give the binding a name: client-to-service-binding-rwwilden
.
With the second command, cf env rwwilden-client
, we check whether the credentials that the service broker provides when binding, are actually injected into the rwwilden-client
application environment. And alas, there is our 'very secret connection string'.
Conclusion
In the first post we implemented a service broker with a service catalog and (de)provisioning of a service. In this post we actually bound the service we created to an application and saw that the credentials the service broker returned when binding were injected into the application environment.
Until now, everything was happening in-memory and there was no actual service being provisioned. In the next post we will (de)provision and (un)bind an actual service, both still as blocking operations.