Creating RavenDB-databases from a script

I’m working on setting up all servers from scripts, and tried to explicitly create a RavenDB database from a script. RavenDB will automatically create databases for you, but since the Replication bundle must be added when the database is created, I need to explicitly create databases.

The RavenDB documentation states that you can create a database just by inserting a document, but there is no example on how to do that.

I manually created a database and copied out the document that was inserted in the database:

{
   "Settings":
   {
      "Raven/DataDir": "~\\Databases\\Fido",
      "Raven/ActiveBundles": "PeriodicBackup;Replication"
   }
}

The documentation does not specify the url that you should PUT the document to, so I had to use Fiddler to trace the database creation. The url of the database document should be:

http://server/docs/raven/databases/<database>

I have a PowerShell function that wraps System.Net.WebClient to do HTTP requests, but you can use curl or wget if you prefer.

Execute-HTTPPutCommand "http://localhost:8080/docs/Raven/Databases/Fido" "{ 'Settings': { 'Raven/DataDir': '~\\Databases\\Fido', 'Raven/ActiveBundles': 'PeriodicBackup;Replication'  }}"

Simulating remote web services for testing

I recently had to troubleshoot an error in an integration with a 3rd party system. We were fetching changesets over a web service, and somehow ended up with errors in the database.

The error rate was just a few errors for every 1000 elements, so this required quite a bit of effort to figure out, because the conversion logic was quite complex. The code was tested, this was obviously a scenario that wasn’t covered by the tests.

I had to run through the code quite a few times to isolate the error in the application logic,  and I didn’t want to do the request from the source several times while I figured it out. Also, I wanted to reproduce the error on my own computer so that I could use all the tools I wanted.

First of all I got hold of the message I recieved as plain XML. This can be done in a number of ways, I had the luxury of being able to set up an extra Send Port in BizTalk that also wrote the message to a file. If you don’t have that luxury, you can use WCF Message Tracing [http://msdn.microsoft.com/en-us/library/ms730064.aspx] or you can write a request and serialize the response object to xml.

Since I had the Message as XML, my challenge was how to be able to request this without connecting to the actual web service. If I could simulate the service, I could test the integration without changing my application, and that would make me more confident that I was testing the right thing. I decided to try to simulate the  web service locally with Nancy. If you don’t know Nancy (http://nancyfx.org), it is a lightweight web application framework that can be set up to listen to http request and return any content you want it to. The most basic Nancy application looks like this:

public class MainModule : Nancy.NancyModule
{
    public MainModule()
    {
         Get["/"] = x => "Hello, world!";
    }
}

This is what I did:

First, I created a console application to host my simulated web service. Then I got the Nancy framework, and the Nancy self hosting host (There are host options for ASP.NET and WCF) from Nuget:


install-package nancy

install-package nancy.hosting.self

This small program can serve the message XML on a HTTP POST

  class Program
    {
        static void Main(string[] args)
        {
            var nancyHost = new Nancy.Hosting.Self.NancyHost(new Uri("http://webservicehost.remoteserver.com"));
            nancyHost.Start();
            Console.ReadLine();
        }
    }

    public class MainModule : Nancy.NancyModule
    {
        public MainModule()
        {

            Get["/"] = x => "Hello, world!";
            Get["/MessageService"] = ReturnStations;
            Post["/MessageService"] = ReturnStations;
        }

        private dynamic ReturnStations(dynamic o)
        {
            return Response.FromStream(File.OpenRead("message.xml"), "text/xml").WithStatusCode(HttpStatusCode.OK);
        }
    }

By wiring the request to both the Get and Post, I could verify the setup in the browser.

To trick my computer into sending the service request to itself, I added this line to my hosts file:

 127.0.0.1 webservicehost.remoteserver.com

I still had one last thing to fix before I could start: When I ran the program I got an HttpListenerException: Access Denied:

This is because port 80 is reserved, and only administrators can listen to that port. This can be fixed in two ways: Either run the application as administrator (which I try to avoid, having experienced CodeRed, Nimbda and SqlSlammer) or I can grant myself access to listen to port 80 using this command:


netsh http add urlacl url=http://webservicehost.remoteserver.com:80/ /user=Per-Frode

Now I was ready to start testing. This 5 minute setup gave me much quicker and better feedback, and made sure that I could look for errors without affecting the remote system.

One final note:

If your XML does not contain the SOAP envelope, you will get an exception from WCF:

[System.ServiceModel.CommunicationException]: {«Unrecognized message version.»}

Just wrap the Message in a SOAP envelope to fix this:


<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="<a href="http://schemas.xmlsoap.org/soap/envelope/">http://schemas.xmlsoap.org/soap/envelope/</a>"
xmlns:xsi="<a href="http://www.w3.org/1999/XMLSchema-instance">http://www.w3.org/1999/XMLSchema-instance</a>"
xmlns:xsd="<a href="http://www.w3.org/1999/XMLSchema">http://www.w3.org/1999/XMLSchema</a>">
<SOAP-ENV:Body>
      ... Insert Your Message here
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>


Error with git tfs because of case differences in pathname

I had a strange case where two files was commited to TFS, and then the folder of these files were renamed to the same name with differing case before more files were added to the folder. This leads to the unfortunate situation where git cannot track some of the files in the folder, since git is case sensitive while TFS isn’t.

C:\source\Project>git tfs pull 
C2511 = ce456058982e4b8e936b350f8900eb077ca9a300 
Updating fcdeaf9..ce45605 Fast-forward
.../Scripts/jquery/datepick/jquery.datepick-en.js | 3 ++- 
.../Scripts/jquery/datepick/jquery.datepick-no.js | 3 ++- 
.../Scripts/jquery/datepick/jquery.datepick.js | 3 ++- 
3 files changed, 6 insertions(+), 3 deletions(-) 
C:\source\Oti>git status 
# On branch master 
# Untracked files: 
# (use "git add <file>..." to include in what will be committed) 
# 
# app/Project.Web/Scripts/jquery/datePick/jquery.datepick-en.js 
# app/Project.Web/Scripts/jquery/datePick/jquery.datepick-no.js 
# app/Project.Web/Scripts/jquery/datePick/jquery.datepick.js 
nothing added to commit but untracked files present (use "git add" to track)

The easy workaround was just to rename the folder in TFS, and then do a new git tfs pull, but it took me quite some time to figure this one out.


Bringing my git-ignore settings with me

Since I’m working a lot of different places, and on quite a few different computers, I need to reconfigure my git-ignore settings every now and then. To manage my settings, I’ve put my git excludes in my Dropbox folder. This gives med the added advantage that all ignore settings are automatically syncronized between computers.

This is the file I have in Dropbox:


bin/
obj/
*.user
*.suo
_ReSharper.*/

And this is how git status looks like if I don’t use the ingore file:

Git notifies me that the Visual Studio build output and local settings are in the repository but are untracked. As my solutions grow, this list can grow to be very big.

I run this statement in git bash, pointing to my dropbox folder on my D: drive. This should work from Windows Command Line too, but then you need to use the Windows path

git config --global core.excludesfile /d/Dropbox/git/excludes

Note that it’s important to use the –global flag to make it valid for all local repositories, as this makes the command store the setting in the .gitconfig in your HOME folder.
When I now run git status, all the local files and settings from Visual Studio is now ignored:


Google+

Warning: this may seem like advertising!

I’ve been hooked on Google+. Probably somewhat because of my geeky nature, but I love how often sharing on G+ turns into conversations. I also love the photo sharing functions with great image viewing functions and image details. Look at this example album: https://plus.google.com/photos/112163012415386550166/albums/5479744893742196977, and remember to click on Actions -> Details under the picture so you can see both the map of the location and the camera details.

I also like how easy I can share things from my phone. The fact that Google+ uses Picasa for picture sharing is an extra plus, I’ve used it for years and would never put an image on Facebook because of their shady privacy policy.

I believe that the worst hype is over, but if you still haven’t gotten an inviation, here is one for you:

https://plus.google.com/_/notifications/ngemlink?path=%2F%3Fgpinv%3DQzg7ugB0SDY%3ATLC7AN5MlTo


An adventure in XCode and Cocoa

Since I haven’t learned a new language in a while, I wanted to try something new. Next stop Cocoa Mac and XCode.

It took quite a while to figure out how the Interface Builder and XCode worked together, but I’ll try to give a quick explanation:
First I created a new Application, and XCode created a XIB-file for me. This was called MainMenu.xib and contained both a system menu and a view. The XIB could be opened in Interface Builder, and I could draw the UI.

I then created a Cocoa class that inherited from NSView. In this class I implemented my properties and methods, which is called Outlets and Actions. Using the correct types is important for the Interface Builder to work when connecting code and UI together.
HelloWorldView.h

#import <Cocoa/Cocoa.h>
@interface HelloWorldView : NSView {
	IBOutlet NSTextField *words;
}
- (IBAction)sayHello:(id)sender;
@end

HelloWorldView.m

#import "HelloWorldView.h"
@implementation HelloWorldView
- (IBAction) sayHello:(id) sender{
	
	NSLog(@"buttonClicked");
	
	[words setStringValue:@"Hello, world"];
	[words setNeedsDisplay:YES];
}
@end

 

Then I hooked this class up to the View using Interface Builder.

Finally I hooked the text fields to the properties and the Buttons to the methods.
IB Bindings
Then I ended up with a working Cocoa mac app


Using my Squeezebox Remote for traffic information

I have a Squeezebox Duet, which is great for playing music. But I knew that the remote control was an embedded system running Linux. It’s sitting in it’s charger right next to me during breakfast, and I’ve been thinking about whether it would be possible to use it to check when my bus is coming. My bus is running along a road with heavy traffic, and it can be quite delayed during rush hours in the morning. And since the local traffic information agency is supplying free real time public transport information, I decided to give it a go.

The result

This is how the application looks right now. It’s currently in a state where it’s usable for me.

imageimageimage

If you have a squeezebox and are really bold, the applet can be dowloaded directly from the remote by adding https://github.com/downloads/perfp/TrafikantenSqueezebox/applets.xml to your squeezebox plugin settings (and remember to enable 3. party plugins)

Also, if you wan’t to check out the source, it’s available on https://github.com/perfp/TrafikantenSqueezebox

 

A few technical notes

The Squeezebox runtime environment is called jive and can be programmed in Lua. Lua is a really simple scripting language with a few interesting features, like first-class functions, dynamic typing, garbage collection and closures. I also uses one specific structure for all state, the table, which is more or less a hash table.

After playing a bit with Lua, I started looking at creating Applets for Squeezebox. At first this seemed like a simple task, since Logitech has been kind enough to supply both development guide in their wiki and SqueezePlay, a Windows/Linux/Mac version of the remote control software.

But the documentation is really poor. And they are using a patched version of the interpreter that uses a different syntax from the standard Lua parser. This means that you cannot use the lua parser to unit test your functions.

Another issue is that there is no apparent way to address the file system to reference modules. This is a problem because the relative file structure in squeezeplay on windows is different from the actual hardware, so relative references won’t work.

There is no date/time functions available in the runtime, and the only decent library I could find did not work on the squeezebox, unfortunately.

I still had a lot of fun exploring this platform and learning a new language.


Følg

Få nye innlegg levert til din innboks.

Bli med 262 andre følgere