mstaender
I'm new here

Modulentwicklung: Service-Konfiguration erstellen

Jump to solution

Hi,

gestern habe ich mich endlich der Konfiguration zu gewendet und nach kurzer Recherche das Beispiel namens "Service" als Grundlage genommen. Ich habe also wie im beispiel meinen kleinen Service erstellt und definiert, eine Konfiguration erstellt und nach fast einem Tag (wtf) lief es dann auch endlich.

Ich habe jetzt einen Service mit einer Configurable welche auf eine Property-Datei zugreift die analog zum Beispiel im Modul-Config-Verzeichnis liegt.

Probleme und Fragen dazu:

  1. Das UI: Das UI hat mich echt Sunden und graue Haare gekostet. Zunächst: Ja super, UI vom Beispiel läuft, also habe ich es angepasst. Resultat: Config-Fenster zu klein. Als Swing-Fucks also hier und da rumexperimentiert, das Modul immer wieder redeployed, den Service mal aktiviert, deaktiviert: keinerlei Änderungen. Irgendwann las ich dann, das man den Server manchmal (???) neu starten muss, gesagt getan. Da ich zu der Zeit versucht habe die Position des im Beispiel "masterFrame" genannten Objektes zu setzen springt auf einmal das Fenster vom ServerMonitor im Hintergrund oben rechts ins Eck und wirk kleiner Smiley Wink
    Dann hatte ich andauernd Proxyexceptions (ich benutze gar keine Proxyklassen, bei getProxyClass gebe ich null zurück)... okay, ich musste also jedesmal den Server neu starten wenn ich testen wollte ob das mit dem UI jetzt klappte oder ein neues Element hinzugefügt hatte. Dann musste ich ihn auch ohne UI Ändeurngen neustarten wegen Proxyfehlern.
    Frage: gibt es hier einen Ausweg das UI zu aktualisieren? Ich will nicht jedesmal wenn ich das Modul mit dem Service neu deploye den Server neu starten und dann wieder den SiteArchitect starten, den ServerManager usw.
  2. Lange hing ich auch am Problem: Wie bite erstelle ich die Config-Datei?
    1. Im Beispiel liegt diese einfach im SRC-Root, also legte ich meine zunächst auch dort hin. -> Sie wurde nach dem Deployment nicht gefunden. Also legte ich sie ins Resource-Folder. Sie wurde nicht gefunden. Dann versuchte ich rauszufinden ob sie im FSM irgendwo speziell liegen muss aber konnte bisher nichts finden (da gibt es doch sicher etwas und ich habe es nur übersehen). Wo muss ich diese Properties-Datei ablegen, damit diese am Ende in die Modulkonfiguration kopiert wird bei Modulinstallation? Wenn es geht: ich hoffe sie wird nicht überschrieben sondern nur erstellt, wenn es noch keine gibt?
    2. Als ich es nicht hinbekam dachte ich "naja dann erstellst du die Datei programmatisch".

      _configFile = _environment.getConfDir().obtain(MODULE_CONFIG_FILE);

      if (!_configFile.exists()) {

          // TODO: how to create the config file?
      }

      Bei dem TODO ist es am Ende geblieben, da ich ind er API keine Möglichkeit fand diese Datei zu erstellen. Habe ich (auch) das übersehen oder ist das ein Sicherheits-Feature? Ich wundere mich, da ich die Dtaei löschen kann aber ich kann keine erstellen?

Danke schonmal für die Hilfe,

Marcus

0 Kudos
1 Solution

Accepted Solutions

Hallo Marcus,

Du kannst auch bei nicht existierendem File das FileHandle holen und darauf dann einfach FileHandle#save(InputStream in) aufrufen. Du musst Dir halt den InputStream passend erzeugen (ByteArrayInputStream o.ä.).

Zum Thema initial anlegen: Hierfür kannst Du im Modul die Methode installed() und/oder updated() nutzen und hier die Datei selber anlegen.

Eine Variante ist, eine default-Config als resource mit ins Modul zu legen und in der module.xml zu deklarieren (dann landet sie auch auf dem Server bzw. im Service-Config-Ordner in FS):

<service>

    <name>SERVICE_NAME</name>

   <class>SERVICE_CLASS</class>

    <configurable>SERVICE_CONFIG_CLASS</configurable>

    <resources>

         <resource>default-config.properties</resource>

    </resources>

</service>

Beim Lesen der config schaust Du dann zuerst, ob es das "echte" config gibt (obtain auf config.properties). Wenn es nicht existiert (!configFile.exist()) liest Du aus der Default-Config. Geschrieben wird immer in die "echte" config.properties.

Vorteil dieser Variante: Du musst die Standard-Config nicht programmatisch erzeugen und trotzdem wird eine ggf. bereits vorhandene config beim Modul-Update nicht "überbügelt".

Viele Grüße

Michael

View solution in original post

0 Kudos
8 Replies
mbergmann
Crownpeak employee

Hallo Marcus,

allgemein zum Thema Configurable: Für EINFACHE Dinge habe ich mal eine kleine Lib "GenericConfig" gebaut. Damit kannst Du Textfelder und Checkboxen benutzen.

Wichtig im Umfeld eines FS-Services: Hier solltest Du dann unbedingt zwei Jars erzeugen (siehe DTA), damit die GenericConfig nicht im Server-Scope liegt.

Vielleicht hilft das ja zumindest der ganzen Swing-Implementierung aus dem Weg zu gehen 😉

Viele Grüße

Michael

0 Kudos

Hi Michael,

stimmt, die "Generic Config" hattest du in der DTA erwähnt. ich hatte auch kurz überlegt ob ich da snutze aber wollte dann doch "schnell" mein eigenes kleines UI haben.

Ich habe momentan noch viele Resourcen im Server-Scope was ich jetzt versuche loszuwerden indem ich die probleme die ich damit umgangen habe jetzt löse. Daher die vielen Threads gerade Smiley Happy

Hast du eine Idee wie man die Konfigurationsdatei handhabt? Momentan muss ich sie manuell ins FS2-Modul-Config-Verzeichnis kopieren was nicht so sinnvoll ist :[

MfG Marcus

0 Kudos

Hallo Marcus,

um eine neue Datei im Konfigurationsordners deines Moduls anlegen zu können kannst du deinen Code von oben weiter benutzen.

Die fehlt nur noch der Aufruf der save Methode auf dem FileHandle Objekt.

final InputStream is = getClass().getResourceAsStream(file);

if (is != null) {

     try {

          _configFile.save(is);

     } finally {

          IoUtil.saveClose(is);

     }

}

Mit diesem Beispiel kannst du zum Beispiel eine initiale Konfigurationsdtaei erstellen und mit Inhalten aus deiner JAR / FSM befüllen.

Das Beispiel ist im übrigen aus dem Moduleentwicklerhandbuch.

Viele Grüße

Benjamin

Hallo Marcus,

Du kannst auch bei nicht existierendem File das FileHandle holen und darauf dann einfach FileHandle#save(InputStream in) aufrufen. Du musst Dir halt den InputStream passend erzeugen (ByteArrayInputStream o.ä.).

Zum Thema initial anlegen: Hierfür kannst Du im Modul die Methode installed() und/oder updated() nutzen und hier die Datei selber anlegen.

Eine Variante ist, eine default-Config als resource mit ins Modul zu legen und in der module.xml zu deklarieren (dann landet sie auch auf dem Server bzw. im Service-Config-Ordner in FS):

<service>

    <name>SERVICE_NAME</name>

   <class>SERVICE_CLASS</class>

    <configurable>SERVICE_CONFIG_CLASS</configurable>

    <resources>

         <resource>default-config.properties</resource>

    </resources>

</service>

Beim Lesen der config schaust Du dann zuerst, ob es das "echte" config gibt (obtain auf config.properties). Wenn es nicht existiert (!configFile.exist()) liest Du aus der Default-Config. Geschrieben wird immer in die "echte" config.properties.

Vorteil dieser Variante: Du musst die Standard-Config nicht programmatisch erzeugen und trotzdem wird eine ggf. bereits vorhandene config beim Modul-Update nicht "überbügelt".

Viele Grüße

Michael

0 Kudos

Hi,

danke euch erst einmal für die Antworten!

Ich hatte mir die Doku für die save()-Methode angesehen und dort steht:

If isFile() returns true, saves the stream-given content to the file.

Jetzt dachte ich, wenn exists() mir schon "false" zurück gibt wird ein nicht existierendes Objekt ja vermutlich keine File sein. In der Doku steht nichts von einem Default-Wert, es könnte ja auch ein Ordner sein...

Also gab ich mir beim Installieren des Moduls mal folgendes aus:

Logging.getLogger().logInfo("Exists ConfFile?: " + _configFile.exists(), loggerClass);

Logging.getLogger().logInfo("IsFile ConfFile?: " + _configFile.isFile(), loggerClass);

Wenn die Datei existiert: beide true. Wenn sie nicht existiert: beide false.

An dem Punkt dachte ich ich übersehe was und habe gar nicht versucht die Datei trotzdem mit save() zu erstellen weil ich shcon so viel experimentiert hatte und ind er Doku ja steht, dass save() nur geht, wenn isFile() true zurück gibt.

Siehe da, es geht aber trotzdem und handelt sich somit nur um einen kleinen Fehler in der Doku.

Danke auch für den Hinweis auf die <resources>, das habe ich offenbar missverstanden. Zusätzlich lag die default-Config im falschen "resource"-Verzeichnis.

0 Kudos

Hallo Michael,

das Thema ist zwar schon etwas älter, meine Frage passt aber glaub ich trotzdem am ehesten hier her. Ich würde nämlich gern für einen Service die GenericConfig verwenden. Mir ist nur nicht ganz klar wie ich dann am Besten an die konfigurierten Werte komme. In der PDF bei dem Modul ist der Weg über den LegacyModuleAgent beschrieben. Das scheint aber nur für ProjectAppConfigProperties zu klappen oder?

Übersehe ich etwas oder ist das einfach so, dass ich das Auslesen der Konfigurationsdatei dann noch selbst implementieren muss?

VG

Anja

0 Kudos

Hallo Anja,

im Service selber kommst du ja ganz einfach lesend an das configfile - da Du dort das Environment hast und dann über den direkten Weg env.getConfDir().obtain("configuration.properties") usw. selber die Properties-Datei einlesen kannst. Das sind ca. 2-3 Zeilen Code, darum hatte ich für den Fall keine Convenience-Methode gebaut. Falls Du die Werte woanders brauchst kannst Du dir ja entsprechende Methoden im Service definieren die die Werte raus geben.

Viele Grüße

Michael

0 Kudos

Hi Michael,

da hatte ich wohl einfach etwas umständlich gedacht. Nun klappt's, herzlichen Dank!

VG

Anja

0 Kudos