How to Code With DSE6 + .NET
A developer shows us how to set up a developer environment on Ubuntu using .NET, and then get some test code running to make sure everything works.
Join the DZone community and get the full member experience.
Join For FreeFirst steps. Let's get .NET installed and setup. I'm running Ubuntu 18.04 for this setup. 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 on the left-hand side of the new solution dialog, if anything isn't installed, Rider will usually display a message that X whatever needs to be 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 plus sign in the description box on the bottom right-hand corner. When 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 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 video:
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 the session's 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 and 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 sessiona.
- The tests really needed to more resilient to confirm the integrations that I was working to prove. 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.
Published at DZone with permission of Adron Hall, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments