Last week I was struggling to find out how to make good use of metadata within NancyFx. I was reading through their extensive documentation along with searching Google for answers. The closest I could find was a single blog post written by Jim Liddell and unfortunately it did not cover the specifics of what I wanted to try and achieve.

I wanted to provide metadata for specific routes within specific modules, in a clean and structured manner. I did not want to add any extra layers of complexity, I just wanted something simple that just worked. I spent a few hours trying to get it working with how I believed it should be working, based off of the methods in the framework but unfortunately kept on hitting runtime errors. So in the end, I created a gist of what I was trying to do, and sent it to Andreas Håkansson via email, asking what I was doing wrong. A couple of days later, he came back to me with the answer and of course at that moment I instantly realized how it all worked. This was still not what I wanted as an end result, but by knowing how the framework worked, I could make it work the way I wanted.

I wanted to be able to create a MetadataModule file for each Module that I wanted to provide Metadata for, and have it work with paths that were relative (the base path) to what was already found my existing Nancy Modules. So this is what I did…

I created an interface named IDataModule, that would allow me to have a structured way of retrieving my information from each of my MetadataModule files.

public interface IDataModule<T>
{
    T Get(string path);
}

Along with a simple object structure that would serve as my Metadata itself.

public class MetadataModel
{
    public int Index { get; set; }
}

I then created an instance of a MetadataModule file, but I decided to try and keep a bit of structure to this, just to make my life a little easier. So currently all my Nancy Modules live in a folder named Modules so I decided my Metadata files should live in a folder named Metadata. I also decided that since my Modules have the naming convention of NameModule that my Metadata should have a matching convention, so a matching file would be NameMetadataModule. So for HomeModule I would then have a matching HomeMetadataModule file.

public class HomeMetadataModule : IDataModule<MetadataModel>
{
    private readonly Dictionary<string, MetadataModel> _paths = new Dictionary<string, MetadataModel>
    {
        {"/", new MetadataModel {Index = 1}}
    };

    public MetadataModel Get(string path)
    {
        return _paths.ContainsKey(path) ? _paths[path] : null;
    }
}

Now for this all to work, I needed an IRouteMetadataProvider instance, which supported all these rules I put into place. It is perhaps not the cleanest implementation, but it works perfectly for my needs.

public class RouteMetadataProvider : IRouteMetadataProvider
{
    public Type GetMetadataType(INancyModule module, RouteDescription routeDescription)
    {
        return typeof (MetadataModel);
    }

    public object GetMetadata(INancyModule module, RouteDescription routeDescription)
    {
        var moduleType = module.GetType();
        var moduleName = moduleType.FullName;
        var parts = moduleName.Split('.').ToArray();
        if (parts[0] != GetType().FullName.Split('.')[0]) return null;
        if (parts[parts.Length - 2] != "Modules") return null;
        parts[parts.Length - 2] = "Metadata";
        parts[parts.Length - 1] = ReplaceModuleWithMetadataModule(parts[parts.Length - 1]);
        var metadataModuleName = string.Join(".", parts);
        var type = Type.GetType(metadataModuleName);
        var dataModuleType = type == null ? null : TinyIoCContainer.Current.Resolve(type) as IDataModule<MetadataModel>;
        if (dataModuleType == null) return null;
        var requestPath = routeDescription.Path.Substring(module.ModulePath.Length) + "/";
        return dataModuleType.Get(requestPath);
    }

    private string ReplaceModuleWithMetadataModule(string moduleName)
    {
        var i = moduleName.LastIndexOf("Module", StringComparison.Ordinal);
        return moduleName.Substring(0, i) + "MetadataModule";
    }
}

Now in my instance usage case, I wanted this to store an index position so that I could create an object for generating a navbar. I used a very simple object for storing my navbar.

public class LinkModel
{
    public string Link { get; set; }
    public string Text { get; set; }
}

I then created a simple method for reading the data for me, including the Metadata, from the IRouteCache instance.

public IEnumerable<LinkModel> GetMainLinks(IRouteCache routeCache)
{
    return routeCache
        .SelectMany(routes =>
    {
        return routes.Value
            .Where(route => route.Item1 == 0 &&
                            route.Item2.Method == "GET" &&
                            route.Item2.Name != string.Empty)
            .Select(route => new
            {
                route.Item2.Metadata.Retrieve<MetadataModel>().Index,
                route.Item2.Path,
                route.Item2.Name
            });
    })
        .OrderBy(route => route.Index)
        .Select(route => new LinkModel
        {
            Link = route.Path,
            Text = route.Name
        });
}

I will most likely create some improvements on this in the near future, but for now, it works perfectly for what I need and perhaps this will serve as useful for others.

So the past week I have taken a break from social media, and includes all of the following, and perhaps a couple more :

  • Twitter,
  • Facebook
  • Skype
  • Slack
  • Google Hangouts
  • IRC

I needed a break from all the noise of the world around me, a chance to recharge my batteries and concentrate a bit more on myself and just getting my job done. Now as a software developer, working as a contractor/consultant, this provded to be a very difficult task indeed!

Part of my job involves me working with new technologies, or at least working with technology that other people may be uncertain on how to best use. I have three things which make me excel in this type of work.

I am good at reading documentation

Whenever I am faced with a new system, if I am not already familiar with the system, I am very good at finding the information I need from the documentation, along with exploring the code to find out the best way to use the system in question.

I have a lot of development experience

Many years of writing code in a number of different languages, for different companies, in different industries has trained me indirectly to know when something is good, something is bad, and often how things should really be done.

I have a large social network

If there is something I do not know, often, I know somebody who does and I can just drop them a message with a brief of what I need help understanding and they will help me out.

So what’s the problem?

Well this past week I have had a personal project which is nearing completion which makes use of NancyFX, but unfortunately the feature I was working on this week was making use of Metadata and unfortunately that is one feature that is not very well documented, simply because not many people make use of it (a future blog post will cover what I did). Now normally this is no problem, because my co-worker Andreas Håkansson is the creator of this system and I can just ping him a message on Skype, and he will help me out. Unfortunately though, if I were to do that, I would be breaking my social media restriction I imposed upon myself, so instead I spent a lot more time trying to workout exactly how to use this feature of his system. I failed. So to get around this, I created a simple gist on GitHub, and then sent him a small email with a link, explaining my plight and of course he replied a couple days later when he had time to sit down and write me an email. Now this worked fine for a personal project, as there is no concrete deadline that I need to meet, but what about my dayjob?

Unfortunately, in my day job I ran into the exact same issue with a different system which again had slightly confusing documentation around what I wanted to do. After spending a few hours trying to understand the system, I ended up having to make a small exception on my social media ban by commenting on a blog post, asking for clarification on a certain part of a system, followed by a tweet to the blog owner Karoline Klever. I received the answered I needed to complete my work, however in this instance failed at my avoidance of social media, simply because I had to just to do my job.

Summary

As a normal human being, avoiding social media is extremely easy to do, and I feel better for doing so. I am an introvert by nature and being around people for too long drives me insane, even though I am very good in social situations, I need time to charge my batteries.

As a contractor, unless I am in the rare situation where I am working on a technology that I have 100% knowledge of, it is almost impossible for me to completely avoid social media and do my job at the high speed that I do it. My social network is part of my toolset, just like my laptop and all the software I installed upon it.

This year has been one heck of a ride, almost completed another year completed and things are still extremely active and busy! So much has happened in these past few months, along with my attitude on life, and so far I have had nothing but great experiences as a result. The problem is finding time to share my experiences on a blog post for everybody else to read.

Going forward, I think instead of planning out nice big blog posts which never happen, I am going to make more frequent, smaller blog posts which should in turn provide more content to my website.

Anyway, until I begin with my useful posts covering things I have to share, here is a summary of what I have done since my last blog post.

  • Competed in Malmö Toughest 8km obstacle course
  • Competed in Helsingborg Springtime 10km race
  • Learned a load of Swedish and Danish words
  • Visited Poland
  • Backpacked around Japan
  • Was interviewed in the fashion capital of Tokyo, Japan for my style
  • Attended a coding hackathon in Spain
  • Was on the speaker’s committee for the large tech conference Leetspeak 2015 which was held in Stockholm
  • Learned NancyFX
  • Migrated a friend’s WinForms application to a self hosted NancyFX application
  • Learned Python
  • Learned EPiServer
  • Sent a load of pull requests to a number of OpenSource projects
  • Completed Hacktoberfest 2015 in under an hour
  • Bought tickets for BuildStuff 2015 in Lithuania
  • Bought plane tickets for my first trip of 2016, Amsterdam

At the beginning of January I emigrated from England to Sweden, and began my journey to discover the wonders of Sweden. The culture is completely different to what I have been used to previously, and often confusing, but ultimately is something that I am glad I got to experience.

There has been a lot of red tape involved in me moving here to Sweden, but I was lucky in that I was hired by the best company in the country. I am proud to say I am a Ninja for tretton37, a company who value knowledge and people over all else.

The biggest problem I have faced with moving to Sweden is becoming part of the society as far as the Swedish tax office is concerned. To do anything in Sweden, from opening a bank account to making purchases online, you need to have a Swedish personal number (much like a National Insurance number in the UK, and Social Security number in America). Filling in the form to obtain this number is extremely easy, however you have to submit it in person within the same city that you hold an address. Their opening hours are only week days and regular work hours, so you need to make sure that you either work in the same city that you live, or you need to book time off of work to spend 1-2 hours in a queue waiting to submit a form that takes no longer than 2 minutes to complete. It then takes a further 3+ months for your personal number to be issued to you, however you are unable to question the status of this process and have to simply wait.

Once you have a personal number, you are a person! You can actually be paid, because until you have this number, your employer is unable to tax you, so technically, you are unable to receive a salary, but many employers that are taking employees from another country will offer you an “advance” which is a set amount of your salary, but they do not know what your tax is until they have your personal number. Now you have this number, you can open a bank account to put this money into, however unfortunately you are not allowed to have online banking nor a debit card to withdraw your own money, and are forced to visit the bank with your passport every time you want to withdraw money. Why is this you may ask? The answer is that Swedish banks require that you have a Swedish ID card to obtain these, because a passport and a driver’s license are not valid ID in Sweden.

So now we need to apply for a Swedish ID card, surely that should be straight forward! Well think again, because you need to transfer some money to the tax office’s bank account giving your personal number as the reference, you cannot pay by card nor cash, you have to do it as a transfer from a Swedish account to another Swedish account, to ultimately obtain the account you cannot have in the first place! So how do you do this? You need to visit FexEx who will charge you 50 SEK for the transfer. You then need to wait at least 24 hours before visiting the tax office, after that you will be able to wait a further 2 hours at the tax office so they can measure your height, take your photo, your signature and that is it! They then tell you that it will take UP TO 2 weeks for your ID card to arrive… a little over 3 weeks later and I am still waiting for mine.

The summary of it all is this… Sweden may as well not be in the EU, simply because their tax office have made it clear that you are not a person until you have their crazy personal number which takes forever to obtain and without which you cannot be paid. Following which, all ID is not valid with the exception of their own issued ID. Once you are in the system though, you are all set. The people in general in Sweden are extremely polite, friendly, intelligent and generally good to be around. I guess this all just came as a shock to me, since I always thought Swedish people were known for efficiency yet their government is completely the opposite.

We all store a lot of data, some more than others and I personally have a LOT of data to store. So much so that I have had my own personal NAS (Network Attached Storage) since 2003. Originally I used to work on a LOT of programming projects and would want to store the raw media files which unfortunately took up a lot of space. In time I decided to turn all my CDs into MP3 files and store them in a way that I could easily find all my music without having to find the correct CD for a specific song, or worrying about it skipping if the CD ever got scratched. At the time I thought I had a lot of CDs, I had a little over 100 of them, so making them digital just made sense to me.

Moving forward a few years later, as my DVD collection increased from the single copy of The Matrix that I got as my first DVD back in 1999, up to over 2000 DVDs (including boxsets). I ran into a very similar problem that I had with my music all those years ago, I decided that enough was enough and I needed to make my video collection digital. I increased the disk size of my NAS and began to convert all my DVDs into digital format, which literally took me years to do. I am sure if I dedicated larges amounts of time every single day to do process, it would have been a lot quicker, but I had a job to do and a life to live so could not put that all on hold just to rip all my DVDs. I did them whenever I had a bit of free time, and eventually got to all of them.

As time went by, I began to find that even though hard drives got bigger in size while prices remained roughly the same (more space, no extra cost), I began to notice how expensive it was to keep all of my data stored locally. I had a couple of hard drives fail on me, but thankfully I had a NAS running on a RAID so I just had to swap out the bad disks for good ones. This unfortunately costs me money though, even though my data was saved, I had to spend money which I was not expecting to spend at the time. I also began to notice as time went by that my electricity bill was higher simply because I had these data storage boxes running 24/7, simply because I appreciated being able to access my data remotely (playing my music at work from my home server for example). I needed a solution to this, and always thought that online storage systems needed to improve for this to become an option but the fact was that they were all too expensive for large amounts of data.

One day, I discovered Bitcasa, an online storage service stating that they would be, and I quote killing the hard drive. For $99 per anum, they were offering unlimited online storage stating that they had some state of the art storage mechanisms de-duplicated all the data which meant the cost on them was less for the more people that used their service and stored the same files. They also claimed to have absolutely amazing security where none of their staff could access their customer’s files, so even if the government asked for access, they would be unable to give it even if they wanted to. I loved the idea of this, signed up to have a look around and see what it was like. The service was extremely slow for both uploads and downloads, and there was endless bugs with their system, but I was one of their first customers and I thought that this was just an initial teething problem so it was to be expected. I used my programming experience to help them not only find bugs in their systems but also telling them what the cause was, and offering them the choices they had in resolving the issues. I was constantly helping them to fix their system, rather than giving up and leaving… this was perhaps the biggest mistake that I had ever made.

Over time, I managed to get all of my data up onto their servers, completely cleared out my NAS just as a couple more disks had failed on me. They had assured me that my service would be forever unlimited, the price would remain the same, and that I should never need a NAS again with thanks to their service. They had also promised that I would get access to their service from Linux once it was available, which would be a major help as I run Linux natively and have been running a Virtual Machine of Windows to get my data up onto their system.

A year goes by, they get a new CEO and Linux support but refuse to give it to their existing customers and anybody who wanted it would need to sign up to one of their new plans which were more than ten times the original plan prices! First promise broken. A few more months go by, their service’s upload mechanism for getting data onto their system improves way better than I could have hoped, so I was able to eventually get everything I owned up onto their systems - this was my second big mistake.

A couple weeks ago, Bitcasa send out an email to every existing customer stating that they have completely changed their pricing plans (again, astronomical prices), and that they would be removing their infinite data plans. On top of this, they had stated that all customers had a week to, and I quote upgrade to a new plan or all of your data would be deleted. At this point in time I had a little over 8 terabytes of data living on their systems! I no longer owned a NAS as they told me that I would never need it again, so I had nowhere to store all my data even if I could download it all within the impossible time limit they forced upon everybody. Adding insult to injury though, their service was almost impossible to download data, this was a bug since day one, and one that I brought up with them on numerous occasions. Within the UK (and perhaps the whole of the EU), their service’s download speeds were slower than dialup internet and would often timeout, causing downloads to often fail. So getting my data from them was almost impossible. I tried to reason with them on numerous occasions, stating that legally I had already prepaid for my service for another few months and if given this amount of time, I could potentially get my data off of them and would just leave. Unfortunately they did not care about their existing customers and just wanted them off of their systems, regardless of the numerous laws they were breaking in doing so.

I was at my wits end, until a friend had discovered two amazing services.

The first service was that Google Apps for Business was charging $10 per user per month (around £7) which included 1TB of Google Drive storage, however if your Business had 5 or more users, every user would then have unlimited storage with no limits. Google always care about their customers, and always honor old pricing plans so this looked like an absolute miracle. I knew they used information based on what I stored on their systems to provide me with targeted advertisements, and a lot of people are unhappy with this type of behavior, but personally it has never bothered me. If I had anything that I feared the world from seeing, I wouldn’t put it online, it was that simple. So my friend and I created a business account with 5 users, split the cost with him and that solved a problem we both had.

The second service was MultCloud (www.multcloud.com), a completely free service which would connect to practically every major cloud storage provider, and allow you to copy/move files between the services. The absolute best part was that I did not need to keep my computer online whilst it did all of this, I could just login, queue up a load of files to move, logout and then leave it to do it’s magic. I could then log back into the service a few hours later, view the progress, queue up a few more files, and then leave it alone again. With the exception of my files that were over 2GB in size, I managed to save all of my data, and it was all thanks to MultCloud.

So in closing, I never did get all of my data back from Bitcasa, they broke a number of laws, didn’t care about their customers’ rights, and only seemed to care about offering a terrible service that just never worked. I trusted them when I really should not have, and I lost valuable data as a result. I am not a spiteful person normally, I seriously do hope that their company goes under and pulls their idiot of a CEO down with it. Although I may never need to use MultCloud again now that my data is all securely stored in a service I can trust (Google), I will always recommend them to everybody. It’s free, stable and works beautifully!