Project Repo: Interoperability Black Box
First steps. Let’s get .NET installed and setup. I’m running Ubuntu 18.04 for this setup and start of project. To install .NET on Ubuntu one needs to go through a multi-command process of keys and some other stuff, fortunately Microsoft’s teams have made this almost easy by providing the commands for the various Linux distributions here. The commands I ran are as follows to get all this initial setup done.
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/ wget -q https://packages.microsoft.com/config/ubuntu/18.04/prod.list sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list
After all this I could then install the .NET SDK. It’s been so long since I actually installed .NET on anything that I wasn’t sure if I just needed the runtime, the SDK, or what I’d actually need. I just assumed it would be safe to install the SDK and then install the runtime too.
sudo apt-get install apt-transport-https sudo apt-get update sudo apt-get install dotnet-sdk-2.1
Then the runtime.
sudo apt-get install aspnetcore-runtime-2.1
Alright. Now with this installed, I wanted to also see if Jetbrains Rider would detect – or at least what would I have to do – to have the IDE detect that .NET is now installed. So I opened up the IDE to see what the results would be. Over the left hand side of the new solution dialog, if anything isn’t installed Rider usually will display a message that X whatever needs installed. But it looked like everything is showing up as installed, “yay for things working (at this point)!”
Next up is to get a solution started with the pertinent projects for what I want to build.
For the next stage I created three projects.
- InteroperationalBlackBox – A basic class library that will be used by a console application or whatever other application or service that may need access to the specific business logic or what not.
- InteroperationalBlackBox.Tests – An xunit testing project for testing anything that might need some good ole’ testing.
- InteroperationalBlackBox.Cli – A console application (CLI) that I’ll use to interact with the class library and add capabilities going forward.
Alright, now that all the basic projects are setup in the solution, I’ll go out and see about the .NET DataStax Enterprise driver. Inside Jetbrains Rider I can right click on a particular project that I want to add or manage dependencies for. I did that and then put “dse” in the search box. The dialog pops up from the bottom of the IDE and you can add it by clicking on the bottom right plus sign in the description box to the right. Once you click the plus sign, once installed, it becomes a little red x.
Alright. Now it’s almost time to get some code working. We need ourselves a database first however. I’m going to setup a cluster in Google Cloud Platform (GCP), but feel free to use whatever cluster you’ve got. These instructions will basically be reusable across wherever you’ve got your cluster setup. I wrote up a walk through and instructions for the GCP Marketplace a few weeks ago. I used the same offering to get this example cluster up and running to use. So, now back to getting the first snippets of code working.
Let’s write a test first.
[Fact] public void ConfirmDatabase_Connects_False() { var box = new BlackBox(); Assert.Equal(false, box.ConfirmConnection()); }
In this test, I named the class called BlackBox and am planning to have a parameterless constructor. But as things go tests are very fluid, or ought to be, and I may change it in the next iteration. I’m thinking, at least to get started, that I’ll have a method to test and confirm a connection for the CLI. I’ve named it ConfirmConnection for that purpose. Initially I’m going to test for false, but that’s primarily just to get started. Now, time to implement.
namespace InteroperabilityBlackBox using System; using Dse; using Dse.Auth; namespace InteroperabilityBlackBox { public class BlackBox { public BlackBox() {} public bool ConfirmConnection() { return false; } } }
That gives a passing test and I move forward. For more of the run through of moving from this first step to the finished code session check out this
By the end of the coding session I had a few tests.
using Xunit; namespace InteroperabilityBlackBox.Tests { public class MakingSureItWorksIntegrationTests { [Fact] public void ConfirmDatabase_Connects_False() { var box = new BlackBox(); Assert.Equal(false, box.ConfirmConnection()); } [Fact] public void ConfirmDatabase_PassedValuesConnects_True() { var box = new BlackBox("cassandra", "", ""); Assert.Equal(false, box.ConfirmConnection()); } [Fact] public void ConfirmDatabase_PassedValuesConnects_False() { var box = new BlackBox("cassandra", "notThePassword", ""); Assert.Equal(false, box.ConfirmConnection()); } } }
The respective code for connecting to the database cluster, per the walk through I wrote about here, at session end looked like this.
using System; using Dse; using Dse.Auth; namespace InteroperabilityBlackBox { public class BlackBox : IBoxConnection { public BlackBox(string username, string password, string contactPoint) { UserName = username; Password = password; ContactPoint = contactPoint; } public BlackBox() { UserName = "ConfigValueFromSecretsVault"; Password = "ConfigValueFromSecretsVault"; ContactPoint = "ConfigValue"; } public string ContactPoint { get; set; } public string UserName { get; set; } public string Password { get; set; } public bool ConfirmConnection() { IDseCluster cluster = DseCluster.Builder() .AddContactPoint(ContactPoint) .WithAuthProvider(new DsePlainTextAuthProvider(UserName, Password)) .Build(); try { cluster.Connect(); return true; } catch (Exception e) { Console.WriteLine(e); return false; } } } }
With my interface providing the contract to meet.
namespace InteroperabilityBlackBox { public interface IBoxConnection { string ContactPoint { get; set; } string UserName { get; set; } string Password { get; set; } bool ConfirmConnection(); } }
Conclusions & Next Steps
After I wrapped up the session two things stood out that needed fixed for the next session. I’ll be sure to add these as objectives for the next coding session at 3pm PST on Thursday.
- The tests really needed to more resiliently confirm the integrations that I was working to prove out. My plan at this point is to add some Docker images that would provide the development integration tests a point to work against. This would alleviate the need for something outside of the actual project in the repository to exist. Removing that fragility.
- The application, in its “Black Box”, should do something. For the next session we’ll write up some feature requests we’d want, or maybe someone has some suggestions of functionality they’d like to see implemented in a CLI using .NET Core working against a DataStax Enterprise Cassandra Database Cluster? Feel free to leave a comment or three about a feature, I’ll work on adding it during the next session.
- Project Repo: https://github.com/Adron/InteroperabilityBlackBox
- File an Feature Request: https://github.com/Adron/InteroperabilityBlackBox/issues/new?template=feature_request.md