Über abapguru

Informatiker. Braucht es mehr Worte?

WCF Hosting ohne Admin Rechte

WCF bietet von Haus aus die Möglichkeit, einen Service in einem Prozess anstatt im IIS zu hosten. Dadurch ist das Hosting wesentlich flexibler, denn zum einen erfordert ein HTTP Hosting nicht zwingend die Installation des IIS, zum anderen stehen auch andere Protokolle wie TCP/IP und Named Pipes zur Vefügung.

Der einzige Haken daran ist, dass ein Prozess, der ohne Admin Rechte läuft, nicht die Rechte hat um einen Service via HTTP zu hosten. Versucht man z.B. einen Windows Service ohne diese Rechte zu starten, erhält man die Fehlermeldung:

Service cannot be started. System.ServiceModel.AddressAccessDeniedException: HTTP could not register URL http://+:7270/[ServiceName]/. Your process does not have access rights to this namespace.

Es gibt aber einen Weg, den WCF Service auch ohne Admin Rechte zu hosten. Unter Windows Vista / 7 / Server 2008 (R2) steht dafür das Tool netsh zur Verfügung. Dadurch ist es möglich, einem Benutzer oder einer Gruppe Rechte auf einen HTTP Namespace, also z.b. „http://+:7270/ServiceName“ zu geben.

Die Syntax dafür lautet

netsh http add urlacl url=http://+:80/MyUri user=DOMAIN\user

Für Windows XP oder Windows Server 2003 übernimmt das Tool httpcfg diese Aufgabe.

Weitere Informationen liefert der Artikel Configuring Namespace Reservations (http://msdn.microsoft.com/en-us/library/ms733768.aspx)

Updating ESXi 5.0 via Command Line Tools

With vSphere 5, vihostupdate and esxupdate are not applicable for ESXi 5. We instead need to use the esxcli command to apply the updates to our ESXi 5 hosts.

  • Make sure you have ESXi Shell access on the ESXi 5 host
  • Download the patch bundle directly from the VMware Support Website (http://www.vmware.com/patchmgr/download.portal). This download will be a .zip file. Do not extract it!
  • Upload the .zip file to a datastore that is accessible on the ESXi host you wish to update. The syntax below will use /vmfs/volumes/pool01, and you may need to adjust this as necessary. Note that the .zip file is uploaded to the ESXi host via the vSphere Client.
  • Set the host to maintenance mode via the vSphere Client
  • To verify which VIBs are already installed on the ESXi 5 host, issue the following command.
    esxcli software vib list | more
  • To find out which VIBs are available in the depot (the downloaded .zip file), issue the following command.
    esxcli software sources vib list --depot=/vmfs/volumes/pool01/updates/ESXi500-201109001.zip | more
  • To update the ESXi 5 host with the VIBs included in the depot, issue the following command.
    esxcli software vib update --depot=/vmfs/volumes/pool01/updates/ESXi500-201109001.zip
  • When the update is complete, verify the information presented. If prompted, reboot the ESXi 5 host (via vSphere Client)
  • If applicable, take the ESXi 5 host out of maintenance mode using the vSphere Client

Tinnitus

So… irgendwann hat es ja so kommen müssen. Seit nun ca. drei Wochen gehöre ich offiziell in den Club der „Tinnitus geplagten“. Mehr oder weniger gut kann ich dies natürlich aktuell verkraften; andererseits sehe ich langsam ein dass ein zwölf Stunden Arbeitstag doch nicht so das Wahre ist… :-/

Alles in allem bin ich aktuell wieder einigermaßen fit (zum arbeiten – klaro 😉 ). Ich werde euch immer mal wieder auf dem laufenden halten…

Calling WCF Services from ABAP

I’m writing an ABAP application that needs to call a back end .NET web service which is written using Windows Communication Foundation. When creating a running WCF web service out of the box, ABAP could not connect to the web service.

The problem

The SAP HTTP Client returns „Cannot process the message because the content type ‘text/xml; charset=utf-8′ was not the expected type ‘application/soap+xml; charset=utf-8′.

The reason

WCF is running a newer version of web services than expected by the ABAP HTTP Client.

The solution

Change the binding type of the WCF service from „wsHttpBinding“ to „basicHttpBinding“ in „web.config„.
This ensures that your .NET web service would support clients and other services that conform to the WS-I standards.

On the ABAP side double check that the namespace and the SOAPAction are correct. If you get a message like „SOAP fault“ then your SOAP action is wrong. Believe me 😉

 

SQL Server CLR Integration

Der einfachste Weg verwalteten Code (Managed Code – .NET Runtime – CLR) und SQL Server zu „verheiraten“ ist die Entwicklungsumgebung Visual Studio (2005 – 2010) zu verwenden. Visual Studio vereinfacht die Entwicklung drastisch, z.B. durch automatisierte Deployment Prozesse. Trotzdem werden wir den Prozess hier „per Hand“ erklären. Natürlich funktioniert dieser Weg auch mit jeder beliebigen .NET Entwicklungsumgebung.

Für jedes unterstützte Stück „Managed Code“ existieren im Namespace Microsoft.SqlServer.Server entsprechende Attribute welche Methoden für den SQL Server verfügbar machen. Dies sind im folgenden:

SqlProcedure 
SqlFunction
SqlUserDefinedAggregate
SqlUserDefinedType
SqlMethod

Auf die zwei häufigsten dieser Attribute möchte ich im folgenden nun kurz eingehen.

SqlProcedure

Die am meisten verwendeten – und nützlichsten – Features in eigenen Projekten sind wahrscheinlich Stored Procedures. Da diese aber meist in T-SQL entwickelt werden lassen sich damit meist nur schwierig komplexere Aufgaben abbilden. Zum Glück lassen sich Stored Procedures auch mit C# (oder einer anderen .NET kompatiblen Sprache) entwickeln. Jedoch gibt es gewisse Voraussetzungen für das entwickeln von „Managed Stored Procedures“.

  • Die enthaltende Klasse muss public sein
  • Die entsprechende Methode muss public static sein

Das sind alle Anforderungen. Klingt doch gar nicht mal so schlimm, oder? 😉 Um das ganze noch einmal zu verdeutlichen, hier ein Beispiel:

using System;
using Microsoft.SqlServer.Server;

namespace abapguru.SqlServer {
    public class SqlServerIntegration {
        [SqlProcedure("spDoSomething")]
        public static void DoSomething() {
            // Hier passiert was...
        }
    }
}

Hier gibt es also zu „normalen“ statischen Methoden kaum unterschiede. Das SqlProcedure Attribute macht die Methode DoSomething für den SQL Server zugreifbar. Der einzige unterstützte Parameter ist ein String der einen alternativen Namen für die Stored Procedure angibt. Im Normalfall ist dieser immer gleich dem Namen der Methode.

SqlFunction

Funktionen für den SQL Server zu erstellen ist fast so einfach wie Stored Procedures, mit dem einen unterschied dass die Methode einen Rückgabewert benötigt.

using System;
using Microsoft.SqlServer.Server;

namespace abapguru.SqlServer {
    public class SqlServerIntegration {
        [SqlFunction()]
        public static int CalculateSomething(int x, int y) {
            return (x + y);
        }
    }
}

Das Attribute SqlFunction unterstützt folgende Parameter:

  • DataAccess
    Bestimmt, ob für die Berechnung auf Daten zugegriffen werden muss oder ob die Berechnung autonom durchgeführt werden kann
  • IsDeterministic
    Bestimmt, ob die Funktion immer den selben Wert zurückgibt, unabhängig vom Status des SQL Servers
  • IsPrecise
    Bestimmt, ob das Ergebnis „wissenschaftlich präzise“ ist (z.B. für mehrdimensionale Berechnungen nötig)
  • Name
    Bestimmt den Namen der Funktion innerhalb des SQL Servers

Assembly in SQL Server einbinden

Angenommen wir haben nun eine fertige Assembly. Um diese innerhalb des SQL Servers verwenden zu können musse diese nur noch installiert eingebunden werden. Dies wird über einen T-SQL Befehl bewerkstelligt.

CREATE ASSEMBLY <NAME>
FROM <PATH>

Beispiel

CREATE ASSEMBLY abapguru.SqlServer
FROM 'C:\Assemblies\abapguru.SqlServer.dll'

Ich denke die Erklärung der Syntax kann ich mir sparen – das ist jedermann logisch oder 🙂

Eine Anmerkung noch: Standardmäßig wird die Assembly mit der „Berechtigung“ installiert, nur „safe Code“ auszuführen. Die CLR Integration hat die Notation von drei verschiedenen Ausführungsberechtigungen; diese werden auf Assemblyebene gesetzt.

  • SAFE
    Nur CLR ist ausführbar. Kein Zugriff auf externe Resourcen
  • EXTERNAL
    Zugriff auf externe Daten ist erlaubt. Darunter fallen z.B. Dateisysteme, Eventlog, Netzwerk. Kein Zugriff auf „unsafe Code“ or „interop code“.
  • UNSAFE
    Keine Limitation, somit Zugriff auf alle Resourcen erlaubt

Diese Ausführungsberechtigungen können beim Importieren der Assembly mit Hilfe des WITH PERMISSION_SET Zusatzes angegeben werden.

CREATE ASSEMBLY <NAME>
FROM <PATH>
WITH PERMISSION_SET=(SAFE|EXTERNAL|UNSAFE)

Ähnlich wie alle DDL Befehle gibt es analog zu CREATE natürlich auch DROP und ALTER. Hier verweise ich allerdings auf die MSDN Dokumentation 😉

Managed Code auf T-SQL mappen

Nachdem die Assembly nun dem SQL Server bekannt ist benötigen wir nur mehr einen letzten, aber wichtigen Schritt. Die in CLR Codierten Funktionen und Stored Procedures müssen nun noch auf äquivalente T-SQL Befehle „gemappt“ werden. Dazu benötigen wir (schon wieder) einige DDL Befehle. Einige Teile davon dürften aber durchaus dem ein oder anderen bekannt sein, der schon seine Erfahrungen mit Stored Procedures gemacht hat.

CREATE PROCEDURE <NAME>
AS EXTERNAL NAME <ASSEMBLY>.<TYPE>.<METHOD>

Beispiel

CREATE PROCEDURE spDoSomething
AS EXTERNAL NAME [abapguru.SqlServer].SqlIntegration.DoSomething

Dieses kleine Stück T-SQL erstellt eine neue Stored Procedure, allerdings mit Referenz auf das Coding innerhalb unserer eigens erstellten Assembly. Nun können wir mittels EXEC die Stored Procedure aufrufen.

EXEC spDoSomething

Sollte die Stored Procedure parametrisiert sein, können die Parameter (wie gewohnt) in T-SQL spezifizert werden. Achtung! Die Signatur muss hier exakt identisch sein. Beispiel:

CREATE PROCEDURE spDoSomethingWithParams
  @NUMBER INT
AS EXTERNAL NAME [abapguru.SqlServer].SqlIntegration.DoSomethingWithParams

Ähnlich funktionerit das ganze auch mit Funktionen

CREATE FUNCTION CalculateSomething (
  @X INT,
  @Y INT
) RETURNS INT
AS EXTERNAL NAME [abapguru.SqlServer].SqlIntegration.CalculateSomething

Auch hier kann, nach absetzen des obigen Codes die Funktion über SELECT aufgerufen werden.

SELECT CalculateSomething(5, 5)

Fehler 6506 vorbeugen

Solltet Ihr den Fehler mit der Nummer 6506 (Could not find Type in Assembly) beim mappen der Funktionen und SPs bekommen, hilft mit ziemlicher sicherheit folgender Trick. Als erstes sollte sichergestellt werden dass die CLR Integration prinzipiell aktiviert ist. Wenn nicht, bitte mit folgendem Befehl aktivieren.

EXEC sp_configure 'clr enabled', 1
GO
RECONFIGURE

Wenn dieser Schritt erledigt ist und der Fehler euch immer noch nervt hilft folgendes. Aus einem (mir) unerklärlichen Grund muss der Assemblyname im Klassennamen noch einmal auftauchen. Beispiel:

Liefert den Fehler 6506

AS EXTERNAL NAME [abapguru.SqlServer].SqlIntegration.CalculateSomething

Läuft ohne Fehler durch

AS EXTERNAL NAME [abapguru.SqlServer].[abapguru.SqlServer.SqlIntegration].CalculateSomething

Geschafft!

Eine Anmerkung noch am Ende: Bitte extremste Sorgfalt beim Entwickeln von CLR Code welcher in SQL Server integriert wird. Sollte z.B. eine unbehandelte Ausnahme innerhalb des Codings auftreten kann es sein dass der SQL Server die komplette AppDomain entladen muss, was zu enormen Performanceproblemen führen kann.

Bei gelegenheit werde ich noch einen Post zum Thema Performance tippen – mal sehen wie es die Zeit zulässt.

OTRS auf Ubuntu 10.10 (Quickinstall)

Folgende Zeile nach Bash klopfen (natürlich ohne Zeilenumbruch…), OTRS laut Anleitung installieren und Spass haben 😉

Installiert Apache2 inkl. Postgre SQL und allen nötigen Perl-Modulen.

apt-get install apache2 perl postgresql postgresql-client libapache-dbi-perl
libdbd-pg-perl libdigest-md5-file-perl libcss-minifier-xs-perl
libcrypt-passwdmd5-perl libmime-base64-urlsafe-perl
libjavascript-minifier-xs-perl libnet-dns-perl
liblwp-useragent-determined-perl libgd-gd2-perl libgd-text-perl
libgd-graph-perl libpdf-api2-perl libcompress-zlib-perl
libjson-xs-perl libio-socket-ssl-perl libnet-imap-simple-ssl-perl
libnet-smtp-ssl-perl libsoap-lite-perl libtext-csv-xs-perl libnet-ldap-perl

Festplatte mal anders…

Eigentlich sind alte kaputte Festplatten sogar zum Wegwerfen noch zu schade… warum nicht als Hartziel verwenden? 🙂

Das Ergebnis des Beschusstests kann man hier bewundern. Folgende Kaliber wurden auf die Kiste abgefeuert: .45 ACP, .40 S&W, .223 REM, .22 lfB (Standard Velocity und High Velocity)

Endeffekt: .45 ACP hat das Gehäuse geknackt (Bild zwei, die Querverstrebung links vom Lager der Spindel). Bis auf die .22 lfB Standard Velocity sind alle anderen Kaliber durch das Gehäuse und die einzelnen Datenplatten durch – war ja nicht anders zu erwarten. Die leichte 22er hat es aber auch durch den Bleckdeckel geschafft. Im Bild eins die Einzelteile (die, die ich noch gefunden hab…) im Überblick 🙂

War ein Lustiger Abend mit (etwas) Abwechslung… Ach ja, noch ein herzliches Dankeschön an meine beiden „Laborassistenten“ und die freundliche Munitionsspende 😉

Intel X25-M G2 Postville

Intel X25-M G2 120 GB SSD

Intel X25-M G2 120 GB SSD

Seit genau einer Woche läuft sie im ThinkPad – die Intel SSD X25-M G2 Postville.

Unterm Strich: fantastisch! Nie wieder ohne! Obwohl (aktuell) nur 2GB Arbeitsspeicher verbaut sind ist das Notebook um einiges schneller geworden. Windows 7 bootet im Vergleich zur Platte vorher in einem drittel der Zeit. Applikationen sind sofort gestartet – wer den VMware vSphere Client kennt der weiß was „langsames starten“ bedeutet. Sogar dieser ist innerhalb von einer Sekunde gestartet. Von der Akkulaufzeit ganz zu schweigen – mit 9-Zellen Akku läuft die Kiste rund 5 Stunden.

Die 200 Teuros waren auf jeden Fall eine sinnvolle Anschaffung!

Ach ja: Benchmarks folgen in Kürze 🙂