Donnerstag, 3. Oktober 2013

Wolkig aber sonnig

Bereits im Sommer konnte ich hier verkünden, daß ein Tangram Deployment in der Wolke bei den Bienen von CloudBees ohne weiteres - und ohne weitere Änderungen möglich - und sehr einfach ist.
Dabei sind die 5MB, die dort bei MySQL Instanzen kostefrei zur Verfügung gestellt werden jedoch auch für einen Playground, z.B. auf Basis des RDBMS Beispiels, sehr eingeschränkt. Beim Versuch, diese Grenze zu erweitern, stieß ich in den Services bei CloudBees auf die MongoDB, die man mir ja schon lange an's Herz gelegt hat - z.B. im CoreMedia Kontext. Schade nur, daß Tangram ja keine MongoDB unterstützt... Außerdem war die Beschreibung, die damals gegeben wurde zwar vollständig, aber für eine vollen Integration der Möglichkeiten der CloudBees Plattform sehr knapp.

MongoDB für Tangram

Das Fehlen der MongoDB-Unterstützung ließ sich mit wenigen Handgriffen beseitigen, sodaß es nun ein entsprechendes Modul gibt. Lerneffekt dabei: Die separaten RDBMS und MongoDB Layer oberhalb von JDO sind eventuell nicht nötig, und man könnte die Entscheidung der konkrekten Anbindung auf die Konfiguration auslagern. Ich lege mich damit nur auf die datanucleus dataaccess Plattform fest und verschiebe alle weiteren Fragen auf diese Ebene. Bevor ich aber soweit gehen will, sollte ich evtl. noch ein paar kleinere Ecken bei der Behandlung von strukturierten Texten und Blobs angehen.

Keine Beispielanwendung

Die Minimalversion aus dem Sommer sollte nun anhand etwas realistischerer Szenarien erweitert werden. Im Moment haben wir statt einer weiteren Beispielanwendung erst einmal unsere eigene (sehr kleine) Website, die in diesem Fall sogar eine Webseite ist - und das mit Absicht - auf CloudBees, MongoDB und Tangram umgezogen.
Dabei wird außer CloudBees nichts weiter als die lokale Entwicklungsumgebung genutzt und gegebenenfalls ein separater GIT-Client.
Nur die eingegebauten, privaten Maven-Repositories blieben bisher außen vor, und wir haben das Release 0.8 beschleunigt und gleich auf Tangrams amor abgelegt.
Die Tatsache, daß man bei CloudBees registriert sein muß, kann man hier voraussetzen und die unterschiedliche Optionen dabei ignorieren wir hier. Man muß allerdings damit rechnen, ab und zu drollige Support-Mails zu bekommen, die einen dazu animieren sollen, sich mehr mit der Plattform zu beschäftigen oder die Hilfe anbieten, wenn das CRM-System das Gefühl bekommt, das wäre notwendig.

Schritt für Schritt

Alle weiteren Schritte, bis die Site mit der neuen Technik aktiv war, finden sich nun hier in Bild und Text. Der grobe Ablauf ist:
1. Anwendung erstellen
2. Datenbank erstellen
3. GIT-Repository erstellen
4. Anwendung lokal erstellen
5. Jenkins Build erstellen
6. Anwendung einchecken
7. Konfiguration abstimmen
Für die Einrichtung einer Anwendung beschäftigt man sich zunächst mit dem run@cloud Bereich.

Bereich Applications

Von der Home-Page aus wählen wir Apps aus und erstellen eine Anwendung für Java/JVM.

Dialog Create abApplication 
 
Für den Moment muß in der Anwendung nichts weiter konfiguriert werden. Viele Texte beschreiben hier auch nur die Optionen, die man nun für die Entwicklung hat. Später kann man hier seine Domain (unten) aufschalten. Dafür muß man natürlich nicht nur hier den Domain-Namen angeben, sondern auch entsprechend seinen DNS mit einem weiteren CNAME konfigurieren.

Seite Manage Application

Für die Datenbanken hat man mehrere Optionen. Zum einen findet sich unter DBs MySQL. Dort kann man eine MySQL Datenbank anlegen und verwalten.

 Dialog Create MySQL Database

Seite Manage Database

Eine MySQL Datenbank sollte man mit dem Kommandozeilenwerkzeug bees mit der Anwendung verbinden. Alternativ kann man natürlich immer den Datenbankzugang direkt in der Anwendung einstellen, wie es auch Tangram-RDBMS erlaubt. Durch die Verbindung löst man die konkreten Einstellungen zur Datenbank von der Anwendung und verlagert sie in die Systembetreuung - keine schlechte Idee.

bees app:bind -db <DBNAME> -a <APPID> -as tangramdb

Zum anderen gibt es MongoDB, die man als Service im entsprechenden Bereich findet und sich gegebenenfalls erst abonnieren muß. Unter dem MongoDB Service legt man sich eine neue Datenbank an.

Bereich Services

Für die weiteren Schritte hier haben wir MongoDB gewählt. Jetzt wird es Zeit, die Anwendung vorzubereiten. Dazu legt man sich ein GIT Repository an und davon einen lokalen Clone auf dem Entwicklungsrechner.

 Bereich Repositories

Hier hinein kopiert man sich das MongoDB Beispiel (oder das RDBMS-Beispiel). 
Unter CloudBees ist eine Sache anders als in allen anderen bisher probierten Plattformen: Es gibt ein Problem mit den Bibliotheken, die als „provided“ angesehen werden. Also fügen wir sie explizit über die build.gradle hinzu.

configurations {
  libs
  webapp
  // add this:
  reallyNeeded
}
...
dependencies {
  webapp "tangram:tangram-mongo:$tangram_version:war@war"
 
  compile "tangram:tangram-mongo:$tangram_version"
 
  providedCompile "javax.servlet:servlet-api:$servlet_spec"
  providedCompile "javax.servlet:jsp-api:$jsp_spec"
 
  // add this:
  reallyNeeded "org.ow2.asm:asm:4.0"
 
  testCompile "junit:junit:$junit_version"

  providedCompile "org.apache.ant:ant:1.8.4"
  providedCompile "org.datanucleus:datanucleus-enhancer:$datanucleus_enhancer_version"
}
...
war {
  // change this:
  classpath = jar.outputs.files
  + configurations.runtime
  - configurations.providedRuntime
  + configurations.reallyNeeded
  excludes = [ "classes/**" ]
}

Für MongoDB kann man nicht den eleganten Weg über eine Verbindung der Datenbank in der Konfiguration gehen und trägt den konkreten Zugang im Code in src/main/resources/jdoconfig.xml ein. Aus der Konfiguration der MongoDB Datenbank extrahiert man die notwendigen Informationen für Benutzernnamen, Kennwort und Zugangs-URL. 

 Seite Manage MongoDB

Unter Show Config findet man eine Zeichenkette der Form 

mongodb://<username>:<password>@<host>:<port>/<database> 

Diesen Text muß man entsprechend zerlegen, um die Teile für den Zugang für die Datei src/main/resources/jdoconfig.xml passend einfügen zu können.

<?xml version="1.0" encoding="utf-8"?>
<jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig">

<persistence-manager-factory name="transactions-optional">
  <property name="javax.jdo.PersistenceManagerFactoryClass"    
            value="org.datanucleus.api.jdo.JDOPersistenceManagerFactory"/>

  <!-- jndi datasource for mongodb -->
  <property name="datanucleus.ConnectionURL" value="mongodb:host:port/database" />
  <property name="datanucleus.ConnectionUserName" value="username" />
  <property name="datanucleus.ConnectionPassword" value="password" />

  <property name="datanucleus.autoCreateSchema" value="true" />
  <property name="datanucleus.validateTables" value="true" />
  <property name="datanucleus.manageRelationships" value="true" />
  <property name="datanucleus.validateConstraints" value="true" />
</persistence-manager-factory>

</jdoconfig>
 
Für den ersten Schritt ist ein erweitertes Logging in src/main/webapp/WEB-INF/log4j.properties hilfreich.

# Daily rolling file appender
log4j.appender.file=org.apache.log4j.ConsoleAppender
# log4j.appender.file.File=build/tangram.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout

Bevor wir das Ergebnis nur in das GIT-Repository pushen, legen wir uns lieber gleich vorher einen Job im Jenkins Continous-Integration Server an, der auf unseren Push mit dem ersten Deployment-Versuch reagieren kann.


Bereich Builds

Wir legen also eine Freestyle Job in Jenkins an.

 Seite Neuen Job Anlegen

Diesen neuen Job konfigurieren wir dann. Zunächst wählt man unter Source-Code Management git aus und fügt die ssh-basierte Zugangs-URL ein.

 Seite Job konfigurieren

Im Buildverfahren sind zwei Schritte nötig, die über Build-Schritt hinzufügen... eingefügt werden können: Invoke Gradle Script und Deploy applications. In beiden Schritte kann die weitgehend leere Basiskonfiguration beibehalten werden.

Seite Job konfigurieren - Buildverfahren

Alle weiteren Anpassungen und Entwicklungen sind jetzt nur noch dem konkreten Bedarf und nicht mehr der Technik geschuldet.
Nun wird jedesmal, wenn man das GIT-Repository pusht ein Build im Jenkins angestoßen und die aktuelle Version versucht zu bauen und zu deployen.
Im Erfolgsfall kann man dann sein Logging tunen und eine eigene Domain aufschalten.

Sicherheitsfragen

Sicherheitsbedenken? In diesem Fall ist ein ohnehin veröffentlichtes Framework mit nichts weiter als der Beispielanwendung - ebenfalls öffentlich zugänglich - und ein paar eigenen Templates für ohnehin öffentlich zugänglichen Inhalt zu sehen. Dies ist nicht die Stelle, an der uns die Cloud Sorgen machen kann, aber die Cloudbees Plattform nimmt uns die Betreuung aller Komponenten von der Entwicklung bis zum produktiven System ab. Physische eigene zu wartende Rechner finden sich nur noch im Form der Entwicklermaschinen. Alles andere kann abgegeben werden. Die eingesetzte Technik erlaubt es uns aber, jeden Schritt auch anders umzusetzen.

Keine Kommentare:

Kommentar veröffentlichen