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.
Das Entstehungs-Blog zu "Tangram". Einer Zusammenstellung von kleinere und größere Bausteinen, um schlank und elegant Ideen in's Web zu bringen. Es ist eine modulare Sammlung, um klein anzufangen ohne sich den Weg zur großen Webpräsenz zu verbauen. Außerdem ist das Ziel, vorhandene Räder nicht neu zu erfinden, sondern eher Versatzstücke zu integrieren, um ein schönes Gesamtbild zu erstellen. - Daher ja auch der Name.
Freitag, 27. September 2013
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.
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.
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.
Labels:
Foto,
GAE,
Google App Engine,
Google Apps,
Natur,
Tangram,
Tangram CMS
Montag, 8. Juli 2013
Mehr Auswahl für die Plattform - Tangram auf Cloudbees
Wie es aussieht, läuft Tangram sehr einfach auch auf der Infrastruktur von Cloudbees. Im Gegensatz zu der Google App Engine benötigt man bei dieser Variante keine spezielle Anpassung, es müssen nur die vorhandenen Konfigurationsparameter passend eingestellt werden:
Eine solche Datenbank könnte man natürlich nun direkt in die Tangram-Anwendung hineinkonfigurieren. Dann könnte man den folgenden Schritt überspringen und direkt die Anwendung mit Schritt 4 deployen. Server, Port, Schemaname und Benutzername sind ja aus dem GUI bekannt und können einfach in die jdoconfig.xml übernommen werden. Wir gehen hier jedoch über einen Zwischenschritt vor.
examples\rdbms-example>bees app:bind -db <DBNAME> -a <APPID> -as tangramdb
Im Tangram rdbms example lautet die jdoconfig.xml dann
<?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"/>
<property name="datanucleus.ConnectionFactoryName"
value="java:comp/env/jdbc/tangramdb" />
<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>
Statt der "normalen" Verbindungsparameter findet sich hier also nur eine Zeile mit dem Eigenschaftsnamen "datanucleus.ConnectionFactotyName". Die anderen Parameter entsprechen den Einstellungen, die im Zusammenhang mit Tangram immer verwendet werden.
examples\rdbms-example>bees app:deploy build\libs\rdbms-example.war
-a <account>/<appid>
http://<appid>.<account.>.cloudbees.net/s/list?cms.editor.class.name=org.tangram.rdbms.solution.RootTopic
führt einen nun auf nach dem Login an den einfachen Tangram Editor - und es kann losgehen, mit dem Anlagen von Codes und (im Beispiel) Topics und anderen Objekten,
1. Anlegen einer neuen Anwendung
Entweder über die Web-Schnittstelle oder die Kommandozeile legt man eine neue Anwendung an.2. Erstellen einer Datenbank
Unter Cloudbees kann man MySQL Datenbanken anlegen und benutzen.Eine solche Datenbank könnte man natürlich nun direkt in die Tangram-Anwendung hineinkonfigurieren. Dann könnte man den folgenden Schritt überspringen und direkt die Anwendung mit Schritt 4 deployen. Server, Port, Schemaname und Benutzername sind ja aus dem GUI bekannt und können einfach in die jdoconfig.xml übernommen werden. Wir gehen hier jedoch über einen Zwischenschritt vor.
3. Verbinden der Datenbank als Datasource
Die Verbindung der Datenbank mit einem Namen, der über JNDI erreichbar ist, kann nur über die Kommandozeile erledigt werden:examples\rdbms-example>bees app:bind -db <DBNAME> -a <APPID> -as tangramdb
Im Tangram rdbms example lautet die jdoconfig.xml dann
<?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"/>
<property name="datanucleus.ConnectionFactoryName"
value="java:comp/env/jdbc/tangramdb" />
<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>
Statt der "normalen" Verbindungsparameter findet sich hier also nur eine Zeile mit dem Eigenschaftsnamen "datanucleus.ConnectionFactotyName". Die anderen Parameter entsprechen den Einstellungen, die im Zusammenhang mit Tangram immer verwendet werden.
4. Deployen
Entweder benutzt man wieder das GUI und deployed das Web-Archiv unter build\libs\rdbms-example.war oder erledigt dies über die Kommandozeile (BEES_HOME muß gesetzt sein und das Cloudbees SDK im Pfad erreichbar):examples\rdbms-example>bees app:deploy build\libs\rdbms-example.war
-a <account>/<appid>
5. Benutzen
Das war's dann auch:http://<appid>.<account.>.cloudbees.net/s/list?cms.editor.class.name=org.tangram.rdbms.solution.RootTopic
führt einen nun auf nach dem Login an den einfachen Tangram Editor - und es kann losgehen, mit dem Anlagen von Codes und (im Beispiel) Topics und anderen Objekten,
Labels:
Cloudbees,
CMS,
Datanucleus,
Datasource,
Java,
JDO,
JNDI,
PaaS,
Tangram
Mittwoch, 9. Januar 2013
JDO 3.0 in der Google App Engine
Es ist nicht gerade ganz neu, aber ich habe es nun einmal bis jetzt aufgeschoben, meine Google App Engine nutzenden Anwendungen auf JDO 3 zu heben, obwohl das ja nun angeblich möglich ist.
Das wichtigste dabei wären die "unowned relationsships" (was ein Wort-Ungetüm), da sie der Grund sind, daß wir bisher keine referenzielle Integrität auf Datenebene haben und diese merkwürdigen Umwege über die IDs als Strings in in den Datenfeldern nutzen müssen. In Tangram gibt es da einen Haufen Methoden (getIds, getContent(), getContents()), die einem das Leben einfach machen, aber eigentlich sollte das alle ersatzlos gestrichen werden.
Google beschreibt die Umstellung als manuellen Weg, die Anwendung zu modifizieren.
An andere Stelle kursieren immer wieder Anleitetungen, wie man das mit dem Eclipse Plugin für die Google App Engine bewerkstelligen soll. Nur genau dieses Plugin nutze ich natürlich in einem Projekt nicht, das ich auch anderen Menschen zur Verfügung stellen will, da dort mein Anspruch ist, daß man einfach ein Build-Systam hat, das alles genauso zusammenbaut wie ich bei mir.
Mit einer IDE habe ich so etwas noch nie erreicht, also bleibe ich nach make, ant, maven nun bei gradle und will hier einmal für mich und andere Aufzählen, was man zu Umstellung machen muß:
Schritt eins ist, die Abhängigkeit der JDO API zu ändern. In Gradle-Notation wird
javax.jdo:jdo2-api:2.3-eb zu
javax.jdo:jdo2-api:3.0.1
(Die letzten Maven-Nutzer werde das auch lesen können)
Und dann brauch noch die jdoconfig.xml ein paar kleinere Anpassungen:
<property name="javax.jdo.PersistenceManagerFactoryClass"
value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/>
wird zu
<property name="javax.jdo.PersistenceManagerFactoryClass"
value="org.datanucleus.api.jdo.JDOPersistenceManagerFactory"/>
Außerdem kommen noch zwei kleine Zeile dazu
value="org.datanucleus.api.jdo.JDOPersistenceManagerFactory"/>
Außerdem kommen noch zwei kleine Zeile dazu
<property name="datanucleus.appengine.query.inMemoryWhenUnsupported" value="true"/>
<property name="datanucleus.appengine.relationDefault" value="unowned"/>
Die obere Zeile ergibt sich aus den geänderten Paketen für die aktuelle datanucleus Version und die beiden anderen Zeilen versuchen, die performance zu erhöhen und die "unowned relationsships" als default zu setzen, wie es auch bei allen anderen Stores außer der Appengine der Falle ist.
Wenn man das getan hat, funktioniert bis auf die paar Semantik-Änderungen alles wie gehabt und man kann beginnen die Model-Klassen umzuschreiben.
Google beschreibt, daß auch noch die JPA-Anbindung in datanucleus hinzugefügt werden sollte, aber die nutzen ich nicht und so entsteht die Abhängigkeit nicht. Desweitere fehlt noch geronimo-jpa_2.0_spec-1.0, was aber für JDO wieder keine Rolle spielen sollte..
Aus
package org.tangram.gae.solution;
import java.util.List;
import org.tangram.jdo.JdoContent
import javax.jdo.annotations.PersistenceCapable;
@PersistenceCapable
public class Container extends JdoContent {
private List<String> contentIds;
public List<Topic> getContents() {
return getContents(Topic.class, contentIds);
}
public void setContents(List<Topic> contents) {
contentIds = getIds(contents);
}
} // Containerwird dann das deutlich lesbarere
package org.tangram.rdbms.solution;
import java.util.List;
import javax.jdo.annotations.PersistenceCapable;
@PersistenceCapable
public class Container extends Linkable {
import java.util.List;
import javax.jdo.annotations.PersistenceCapable;
@PersistenceCapable
public class Container extends Linkable {
@Unowned
private List<Topic> contents;
public List<Topic> getContents() {
return contents;
}
public void setContents(List<Topic> contents) {
this.contents = contents;
}
} // Container
wie wir es schon in der rdbms Variante nutzen. Endlich...
private List<Topic> contents;
public List<Topic> getContents() {
return contents;
}
public void setContents(List<Topic> contents) {
this.contents = contents;
}
} // Container
wie wir es schon in der rdbms Variante nutzen. Endlich...
(Daß ich dabei Probleme in der rdbms-Variante entdecken mußte steht auf einem anderen Blatt und damit in einem späteres Posting ;-) )
Labels:
Google App Engine,
Java,
JDO 2.3,
JDO 3.0,
Tangram CMS
Samstag, 22. Dezember 2012
Das war nicht gut
Neulich habe ich hier mal einen Workaround mit Gradle für das Classpath-Problem mit dem YUI-Compressor beschrieben.
Dieser Workaround funktioniert solange sehr gut, wie man in den Web-Archiv-Artefakten alle Java-Bibliotheken mitschleppt und dann beim Kopieren daraus auswählen und umbenennen kann.
Genau das habe ich gestern mit der Version 0.7 von Tangram aber endlich eingedämmt, da man jede Menge Code und damit Daten ständig von A nach B schiebt. Man kann eigentlich all die JAR-Dateien einfach weglassen. Sie kommen automatisch durch die Abhängigkeiten der restlichen Codes wieder rein. Alle JARs? Ein kleines, problematisches Archiv leider nicht: der YUI-Compressor. - Also habe ich die Mimik mal wieder umgebaut.
Dazu basteln wir uns eine weitere Configuration, wie das für die Google App Engine schon für das enhancen der JDO-Klassen notwendig war:
configurations { .
.
. yui
}
Mit dieser Konfiguration belegen wir nur den YUI-Compressor:
dependencies {
.
.
. providedCompile "com.yahoo.platform.yui:yuicompressor:$yui_version"
configurations { .
.
. yui
}
Mit dieser Konfiguration belegen wir nur den YUI-Compressor:
dependencies {
.
.
. providedCompile "com.yahoo.platform.yui:yuicompressor:$yui_version"
yui "com.yahoo.platform.yui:yuicompressor:$yui_version"
.
.
.}
Er wird also aus den Abhängigkeiten entfernt und nur in der Konfiguration genutzt. Und die Elemente dieser Konfiguration können wir nun wieder beim Kopieren umbenennen, wen man das abschließende into('') etwas tuned.
war.doFirst {
.
.
. for (f in configurations.yui.files) {
copy {
from f.absolutePath
into "$buildDir/target/WEB-INF/lib"
rename 'yui', 'aaa-yui'
}
}
into ('') {
from "$buildDir/target"
exclude 'WEB-INF/lib/tangram-**'
}
.
.
.}
Er wird also aus den Abhängigkeiten entfernt und nur in der Konfiguration genutzt. Und die Elemente dieser Konfiguration können wir nun wieder beim Kopieren umbenennen, wen man das abschließende into('') etwas tuned.
war.doFirst {
.
.
. for (f in configurations.yui.files) {
copy {
from f.absolutePath
into "$buildDir/target/WEB-INF/lib"
rename 'yui', 'aaa-yui'
}
}
into ('') {
from "$buildDir/target"
exclude 'WEB-INF/lib/tangram-**'
}
}
Und damit wäre dieser Bereich auch wieder heil und kann wieder als Vorlage für entsprechende Fälle mit dem YUI-Compressor und Gradle dienen.
Und damit wäre dieser Bereich auch wieder heil und kann wieder als Vorlage für entsprechende Fälle mit dem YUI-Compressor und Gradle dienen.
Labels:
Compressor,
CSS,
Google App Engine,
Gradle,
Java,
JavaScript,
Minify,
Tangram,
YUI
Freitag, 21. Dezember 2012
Artefakte mit viel Liebe
Es liegt ganz sicherlich an mir, daß ich zwar nun für fast alles, was man so zu Entwicklung und Betrieb braucht, dienste in der "Cloud" gefunden habe, aber das Bereitstellen von Bibliotheken via Maven Repository noch nicht hingebekommen habe.
Aber im Grunde - so von der lesenden Seite - sind das ja nur Verzeichnisstrukturen mit einigen festgtelegten Dateien darin, die man per HTTP zugreifen kann. - Und das solle ist: Alle Daten dazu habe ich ja schon lokal auf der Platte, wenn ich meinen Build - bei mir ja immer mit Gradle - abgeschlossen habe.
Bis ich also verstanden habe, wie ich meine Projekte in den Prozeß in die Zentralen Maven Repositories einkippe, habe ich eher mal eben heute für die Zeit bis dahin ein Ad-hoc Maven Object Repository mit dem Tangram - in Version für die Google App Engine - geschrieben und es deshalb amor genannt.
Was mußte man dafür tun? Es gibt nur ein Datenmodell: Das Artefakt, wie es im Repository zugänglich gemacht werden soll. Der Rest ist URL-Format und eine kleine Listing-Seite - und damit sind das nur noch Dinge, die man dynamisch im Tangram mal schnell hinzufügen kann. Der Code findet sich auf github - mit Datenbank Abzug diesmal.
Die Beispiel-Site ist nun das Repository auf dem ich das aktuelle Tangram 0.7 zur Verfügung stelle: http://my-amor.appspot.com/
Labels:
Google App Engine,
Gradle,
Maven,
Repository,
Tangram
Abonnieren
Posts (Atom)