Sonntag, 29. September 2013

Tangram 0.8 Release - Mehr Dynamik bitte

Es wurde langsam Zeit für ein neues Tag auf dem Tangram Repository. Die Änderungen gegenüber der letzten Version sind doch umfangreich und viele Anwendungen, die Tangram nutzen - und dringend Version 0.8 brauchen, sollten wieder eine Stabile Basis bekommen.
Die aktuelle Fassung auch von den Beispielen gibt es als Code wie immer bei github und die Dependencies bezieht man aus dem amor.

Was gibt's neues?

Version 0.8 beschäftigt sich viel mit Dynamik. Dazu bedurfte es eines Erheblichen Tunings - insbesondere auf der Google App Engine - allgemein für die Nutzung in der Cloud. Aber etwas anderes kommt unter der Überschrift Dynamik ja auch nicht in Frage.
Zu den umfangreicheren Caching Techniken ebenfalls mit Zielgebiet Cloud werde ich hier noch einen separaten Beitrag veröffentlichen.
Mit Version 0.8 ist die Programmierung von Tangram-Anwendungen nun endgültig in die Datenbank gewandert und wird dort mit Apache Velocity und Groovy umgesetzt, wobei einige Schwächen und Fehler bereinigt wurden.
Dabei sind nun neben den bekannten URLs auch Benutzeraktionen auf der Weboberfläche mit (in den sogenannten Shims) Groovy umsetzbar.
Das dynamische Zusammenstellen der Inhalte auf der Site ist nun ausreichend performant, in der API vollständig und ebenfalls mit Groovy handhabbar.
Um das alles benutzbar zu halten wurde der Editor - eigentlich nur ein Stiefkind in Tangram - in wichtigen Details verbessert und in den Abläufen einfacher gestaltet.
Technisch wurde die RDBMS Umsetzung vom Proof of Concept neben der Google App Engine zu der Hauptumsetzung und das System um die Anbindung MongoDB erweitert. Dabei wurde der JDO-Layer von den historischen Altlasten früher Google App Engine Zeiten befreit und auf API-Level 3.0 gehoben.
Natürlich sind alle genutzen Komponenten auf aktuelle Versionen umgestellt und auch das Buildsystem mit Gradle - jetzt in Version 1.8 - konsistent weiterentwickelt.

Neuer Standard-Startpunkt

Wer nun eine neue Web-Idee ausprobieren möchte und kein Geld in die Hand nehmen will, nimmt nicht mehr die Tangram und die Google App Engine und den Google Apps sondern Tangram und Cloudbees - ggf. mit MongoDB als Backend, an dieser Stelle sogar mit integrieten git-SCM und Continous-Integration-Server über Jenkins.
Auch hier gilt: Wenn die Idee fliegt, besteht ein professionelles Angebot für eine kommerzielle Nutzung der Plattform.
Ersatz für die Google Apps, die wir in der Vergangenheit für den Rest des Auftrittes wie Mails, Calender, Dokumentablage etc. genutzt haben, findet man bei zoho.

Freitag, 27. September 2013

CoreMedia Blueprint für Solaris

Evtl. kennt das noch der ein oder andere: Wenn man den ganzen Tag auf einen dieser alten grünen Monochrommonitore geschaut hat, sieht man abends einen rosa Augenhintergrund. - In unserem Projekt hier ist es gerade sehr ähnlich - nur andersherum.
Und so müssen die neuen Dinge von CoreMedia, die richtig Spaß machen und gut zu handhaben sind (natürlich nicht ohne Einarbeitung), auch ein wenig Altlast tragen, denn einige Dinge sollen so bleiben, wie sie seit viele Jahren bewährt laufen.
Z.B. sind die Server immernoch Sparc Maschinen mit Oracle Solaris. Und der der Kunde erwartet, daß das einfach so funktioniert, da es ja auch im Handbuch steht.
Der CoreMedia Blueprint und sein kleiner Bruder verlassen sich aber darauf, daß die damit erstellten Pakete auf einer bestimmten Sorte Linux laufen (eine Frage von LSB, BSD, POSIX usw.). Also haben wir da doch mit einer gewissen Lernkurve Punkte entdeckt, an denen man Änderungen einbauen muß. Die Projektlösung war dabei doch recht speziell, umfangreich - und hatte mehr Klippen zu umschiffen als für eine Blueprint nötig.
Daher wollte ich nun auf Basis des reinen Blueprint Workspaces noch einmal eine saubere, schlanke Neu-Umsetzung durchführen. Bereits bei den Spielereien mit Debian/Ubutunu habe ich gesehen, wie sich einige Skripte doch auf Details verlassen, die nicht einmal unter allen Linux-Distributionen so sind. Bei Solaris war mir aus Jahrzehntelanger Erfahrung klar, daß selbst bei gleicher Shell einige System-Tools sich nicht so verhalten, wie ihre meist erweiterten GNU-Freunde. - Und das ist auch hier wieder relevant.
Der große Skripte-Zoo im CoreMedia Blueprint ist aber gerade ein wichtiger Teil für den Weg vom Entwickler-Rechner in die Produktion. Diese Zusammenstellung wollte ich möglichst minimal anpassen und mit einer Solaris Paketierung zusammenführen.
Schritt eins dabei war natürlich die Herstellung der Pakete selbst. Wegen schlechter Erfahrungen mit entsprechenden Maven-Plugins, die auch seit Jahren nicht mehr gewartet werden und das Alpha-Stadium nicht verlassen haben, kam diesmal der Einsatz der System-Tools auf die Tagesordnung. Solaris-Pakete lassen sich damit auch nur unter Solaris erstellen, sorry.
Dabei integriert mal die Skripte aus dem Workspace oder verpackt. D.h. man holt sich die preinstall.sh und portuninstall.sh als preinstall und postuninstall in das Paket während man die postinstall.sh und preuninstall einfach verpacken kann:
  # postinstall
  if [ -f ${INSTALL_ROOT}/${APPLICATION_NAME}/INSTALL/postinstall.sh ] ; then
    ${INSTALL_ROOT}/${APPLICATION_NAME}/INSTALL/postinstall.sh 1
  fi


Im Gegensatz zu Linux Varianten kennt hier Solaris anscheinend keine Parameter an diese Skripte. Preinstall und Postuninstall sind also schon einmal anzupassen, da vor dem Installieren und nach dem Entfernen ein Wrapper in's Leere greifen würde:
  #!/bin/bash
  set -e
  # $1 == 1 --> initial installation
  # $1 == 2 --> upgrade
  SELECTOR=$1

  # Solaris
  if [ -z $SELECTOR ] ; then
    SELECTOR=1
  fi

  if [ $SELECTOR -eq 1 ] ; then
    ...
  (preinstall.sh)Die Solaris Paketierung stellt man auch gerne wieder generisch als Maven Modul unter packages/ bereit und legt sich hierin Prototypen für die Paketbeschreibung inklusive der Skripte und ein Ant-Script zu Steuerung der Paketierung bereit:
  PKG=${APPLICATION_NAME}
  NAME=${APPLICATION_NAME}
  DESC="CoreMedia 7 Component - ${APPLICATION_NAME}"
  VERSION=${project.version}
  BASEDIR=${INSTALL_ROOT}
  PSTAMP=${timestamp}
  CATEGORY=application
  ARCH=sparc
  CLASSES=none
  VENDOR="CoreMedia AG"
  HOTLINE="+49-40-325587-777"
  EMAIL="support@coremedia.com"
  ISTATES=S s 1 2 3
  RSTATES=S s 1 2 3

  pkginfo

  i pkginfo
  i preinstall=preinstall
  i postinstall=postinstall
  i preremove=preuninstall
  ! postremove=postuninstall
  !include generated-prototype

  prototype

<?xml version="1.0" encoding="UTF-8" ?>
<project>
  <target name="pkg">
    <copy file="${project.build.directory}/${PACKAGE_DIR}/INSTALL/preinstall.sh"
          tofile="${project.build.directory}/solaris-cooked/preinstall" 

          overwrite="true" failonerror="false" />
    <copy file="${project.build.directory}/${PACKAGE_DIR}/INSTALL/postuninstall.sh"
          tofile="${project.build.directory}/solaris-cooked/postuninstall"     

          overwrite="true" failonerror="false" />
    <exec executable="/bin/bash" failonerror="true">
        <arg value="-c" />
        <arg value="pkgproto ${project.build.directory}/${PACKAGE_DIR}=${APPLICATION_NAME}/ > ${project.build.directory}/solaris-cooked/raw-prototype" />
    </exec>
    <exec executable="/bin/bash" failonerror="true">
        <arg value="-c" />
        <arg value="sed -e s/${user.name}/${INSTALL_USER}/g ${project.build.directory}/solaris-cooked/raw-prototype | sed -e s/[a-zA-Z0-9]*$/${INSTALL_GROUP}/g | grep -v dll= | grep -v exe= | grep -v bat= > ${project.build.directory}/solaris-cooked/generated-prototype" />
    </exec>
    <exec executable="/bin/bash" failonerror="true">
      <arg value="-c"/>
      <arg value="mkdir ${project.build.directory}/pkg"/>
    </exec>
    <exec executable="/bin/bash" failonerror="true">
        <arg value="-c" />
        <arg value="pkgmk -f ${project.build.directory}/solaris-cooked/prototype -d ${project.build.directory}/pkg -o -b ./" />
    </exec>
    <exec executable="/bin/bash" failonerror="true">
        <arg value="-c" />
        <arg value="pkgtrans ${project.build.directory}/pkg ../${APPLICATION_NAME}-${project.version}.sparc.pkg ${APPLICATION_NAME}" />
    </exec>

    <exec executable="/bin/bash" failonerror="true">
      <arg value="-c" />
      <arg value="gzip -9 ${project.build.directory}/${APPLICATION_NAME}-${project.version}.sparc.pkg" />

    </exec>
  </target>
</project>

(ANT build-pkg.xml)

Wenn man diese Pakete dann installiert, fällt die Installation recht herb auf die Nase. Unter Solaris funktioniert das automatische Anlege der Benutzer doch etwas anders und hat keine impliziten Randbedingungen wie bei Linux.
   # Add the "@INSTALL_USER@" user
  # This will fail on Solaris
  /usr/sbin/useradd -c "system user to run coremedia services and applications" \

       -s /bin/bash -m -d @INSTALL_ROOT@ -r @INSTALL_USER@ 2> /dev/null || :
  # For Solaris create group manually
  /usr/sbin/groupadd @INSTALL_GROUP@ 2> /dev/null || :
  # So try it again without -r parameter but group (s.a.) instead
  /usr/sbin/useradd -c "system user to run coremedia services and applications" \

       -s /bin/bash -m -d @INSTALL_ROOT@ \
       -g @INSTALL_GROUP@ @INSTALL_USER@ 2> /dev/null || :
(postinstall.sh)
Wenn man jetzt noch das mktemp in reconfigure.sh umformuliert kommt man schon sehr viel weiter. Und nach einer Anpassung der Service-Integration in /etc/init.d ist man sehr nahe am Ziel.
  # Register as service if possible
  if [ -x /sbin/chkconfig ] ; then
    logger -p syslog.info -t coremedia/rpm \

           -s "Enabling the service @APPLICATION_NAME@, ..."
    chkconfig @APPLICATION_NAME@ on
  else
    echo "To start call \"/etc/init.d/@APPLICATION_NAME@ start\""
  fi
  (z.B. postinstall.sh)

Auch hier wieder ist zur (etwas) besseren Lesbarkeit einiges ausgelassen. Die volle GIT-Patch-Sequence gibt's gerne auf Anfrage.

Montag, 23. September 2013

CoreMedia 7 Blueprint als Debian/Ubuntu Pakete

Es ist hier Off-Topic, aber es paßt gut in die Zielrichtung Entscheidungsfreiheit bei der Plattformwahl zu bekommen und dennoch einheitlich die benötigten Features zur Verfügung zu haben.
Dies ist ein Thema, das man eben nicht nur mit Tangran adressieren kann, sondern auch z.B. mit dem CoreMedia CMS.
Mehr durch einen Bedienerfehler inspiriert als mit Zielrichtung versehen, habe ich das CoreMedia 7 Blueprint mit Debian Paketbau versehen. Damit kann man - auch wenn es nicht suppported ist - das CoreMedia 7 System auch z.B. mit einem Ubuntu LTS (es sollte ja auch ein Enterprise Linux sein können, damit man bei Bedarf auch kommerziell Support einkaufen kann) einsetzen.
CoreMedia selbst bietet uns ein fertiges Setup zum Bau von RPM-Paketen für die einzelnen Komponenten, das sogar unter Windows ohne weitere Werkzeuge läuft. Das ist eine Meßlatte, die ich nicht unterschreiten wollte. Also war ich auf der Suche nach einer reinen Java-Lösung und stieß auf diese Liste: Maven plugin for building debian package.
Leider werden CoreMedia Workspaces immernoch mit Maven zu fertigen Lösungen zusammengebaut und zwei der Tools auf der Liste lassen sich nicht einfach integrieren oder benötigen wieder externe Werkzeuge auf der Unix-Kommandozeile.
Einzig jdeb brachte schnell erste Ergebnisse.
Wer das Ganze in sein Projekt eingepaßt haben möchte oder einfach den fertigen Patch gegen dan Blueprint in Version 26 haben möchte, möge sich einfach mal melden. Hier folgt jetzt die lesbare aber damit nicht Code-Zeilen-genaue Version.
Was ist zu tun?
Nachdem man in der root-POM jdeb mit Version (hier 1.0.1) bekannt gemacht hat, wendet man sich einzig dem Bereich packages im Workspace zu, wo alles zunächst ganz einfach aussieht.
Mit einer Konfiguration für alle Pakete
  <plugin>
    <artifactId>jdeb</artifactId>
    <groupId>org.vafer</groupId>
    <configuration>
      <deb>[[buildDir]]/${APPLICATION_NAME}_[[version]]_all.[[extension]]</deb>
      <controlDir>${project.build.directory}/deb</controlDir>
      <dataSet>
        <data>
          <type>template</type>
          <paths>
            <path>${INSTALL_ROOT}/${APPLICATION_NAME}</path>
          </paths>
        </data>                  

        <data>
          <src>${project.build.directory}/${APPLICATION_NAME}</src>
          <type>directory</type>
          <excludes>**/*.bat,**/*.exe,**/*.dll</excludes>
          <mapper>
            <type>perm</type>
            <user>${INSTALL_USER}</user>
            <group>${INSTALL_GROUP}</group>
            <prefix>${INSTALL_ROOT}/${APPLICATION_NAME}</prefix>
          </mapper>
        </data>
      </dataSet>
    </configuration>
  </plugin>

entstehen sehr schnell .deb Dateien, wenn man sich vorher eine Dependency auf ein ZIP erzeugt und im ${project.build.directory}/deb auspacken läßt. In dieser Dependency (hier genannt debian-packaging) braucht man mindestens ein control-File und Filtering, damit man nicht für jedes Paket ein eigenes erstellen muß.
  Package: ${APPLICATION_NAME}
  Version: ${project.version}
  Section: httpd
  Priority: optional
  Architecture: all
  Depends: ${APPLICATION_PREFIX}-tomcat-installation
  Maintainer: Main Tainer <maintainer@example.com>
  Description: CoreMedia 7 - ${APPLICATION_PREFIX} ${project.artifactId}
  Homepage: http://www.coremedia.com/

Bis diese Pakete auch nur fast auf dem Niveau der RPM-Pakete sind, ist allerdings noch ein wenig Feinarbeit notwendig.
Die Installation- und Entfernungs-Skripten, die Dateiberechtigungen und die Unterschiede zwischen dem Bereich tools, services und der tomcat-installation bringen dann noch ein wenig Arbeit, die einige Round-Trips erfordert, bis alles an seiner Stelle steht und richtig zusammenspielt.
Man sieht es schon an den data-Template oben, wo der Basis-Pfad des gesamten Paketes noch einmal explizit erwähnt werden muß. Außerdem haben Debian-Pakete andere Aufruf-Parameter für die Skripten, wo z.B. install statt 1 und upgrade statt 2 übergeben wird. Desweiteren verlassen sich die mitgelieferten Skripten von CoreMedia auch fest auf das Vorhandensein von Werkzeugen, die nun einmal nun auf jedem Linux verfügbar sind. Diese mitgelieferten Skripten werden durch Wrapper in den Pakete aufgerufen - außer natürlich dem Skript preinst (preinstall.sh), das beim Wrapper in's leere greifen würde und daher angepaßt werden mußte - in allen drei Varianten, die im Workspace existieren:
  # $1 == 1 --> initial installation
  # $1 == 2 --> upgrade
  SELECTOR=$1


  # Debian
  if [ "a$SELECTOR" = "ainstall" ] ; then
    SELECTOR=1
  fi
  if [ "a$SELECTOR" = "aupgrade" ] ; then
    SELECTOR=2
  fi

  if [ $SELECTOR -eq 1 ] ; then
    # initial installation

Am Ende der ganzen Prozedur kommt noch ein wenig Fleißarbeit: In jedem aber auch jedem Paket - das ist beim CoreMedia Application Maven Plugin letztlich nicht anders - muß nun der Paketbau als Referenz auf die übergreifenden Konfiguration eingefügt werden.
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
      <execution>
        <phase>initialize</phase>
        <goals>
          <goal>unpack</goal>
        </goals>
        <configuration>
          <artifactItems>
            <artifactItem>
              <groupId>${project.groupId}</groupId>
              <artifactId>debian-packaging</artifactId>
              <version>${project.version}</version>
              <type>zip</type>
              <outputDirectory>${project.build.directory}/deb</outputDirectory>
            </artifactItem>
          </artifactItems>
        </configuration>
      </execution>
    </executions>
  </plugin>

  ...
  <plugin>
    <artifactId>jdeb</artifactId>
    <groupId>org.vafer</groupId>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>jdeb</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

Auch hier sind natürlich wieder ein paar Schritte ausgelassen, um den Text hier noch einigermaßen lesbar zu halten.

Mittwoch, 18. September 2013

NATURINSPIRIERT.org mit Tangram

Die Meldung kommt eigentlich etwas spät, aber es gibt einmal wieder eine neue Site, die mit Tangram realisiert wurde. Das kleine Foto-Blog naturinspiriert.org ist mit dem Tangram Framework auf der Google App Engine realisiert worden.
Das ganze ist insofern technisch dennoch nicht "yet another" und "nur klein", da hier zum ersten Mal live die dynamsichen Content-Zusammenstellungen genutzt werden. Die einzelnen Rubriken der Site befüllen sich mit den passenden Artikeln von selbst. Alle anderen Projekte, die diese Feautures von Tangram 0.8 nutzen sind leider noch nicht online oder können hier nicht öffentlich erwähnt werden.
Was bei der Umsetzung aufstieß sind allerdings die Probleme mit der Google App Engine: Man darf sich nicht mehr blenden lassen von veralteten Hinweisen und Links: Ohne kostenpflichtigen Google Apps Zugang bekommt man keine eigene Domain mehr für Google App Engine Anwendungen geschaltet. Punkt. Die erwähnten Links gibt es nicht mehr. Wir haben sie in keinem Szenario aus Google App Engine Anwendungen und Google Accounts nachstellen können.Wir werden also nun weiter an den alternativen Arbeiten.
Wenn's Geld kosten darf, ist Google Apps sicherlich eine gute Lösung und Google Appengine eine sehr attraktive Plattoform. Wenn man allerdings noch nicht weiß, ob eine Lösung Geld verdient, ist es nach erfolgreichen Jahren seit 2013 nur noch zweite Wahl.