Quantcast
Channel: Communardo Techblog » plugins
Viewing all articles
Browse latest Browse all 8

Jobs und Trigger in Crowd verwenden

$
0
0

Probleme

Keine konfigurierbaren Module

Standardmäßig gibt es für Atlassian Crowd keine Möglichkeit Scheduler, Jobs oder Trigger Module über die Konfigurationsdatei atlassian-plugin.xml zu definieren.

In Atlassian Confluence können Jobs und die zugehörigen Trigger bequem über die atlassian-plugin.xml konfiguriert werden.
siehe http://confluence.atlassian.com/display/CONFDEV/Job+Module und http://confluence.atlassian.com/display/CONFDEV/Trigger+Module

Crowd Scheduler in Plugins nicht verfügbar

Atlassian Crowd verwendet einen Scheduler, welcher die Jobs TokenRepeaterJob und LicenseResourceJob verwaltet. Generell besteht die Möglichkeit Komponenten in der Datei atlassian-plugin.xml mittels component-import zu importieren. Dies ist allerdings nur möglich, wenn die Komponenten in Spring mit dem Attribut

plugin:available=<span>"<span>true</span>"</span>

versehen ist. Der Scheduler besitzt leider dieses Attribut nicht, sodass die Verwendung innerhalb eines Plugins nicht möglich ist.

Lösung

Zusammenfassung

Die Nutzung des ServiceAccessLayers, kurz SAL, ermöglicht es Jobs und Trigger zu implementieren. Die Entwickler von Atlassian stellen dafür eine Bibliothek sal-api-X.X.X.jar zur verfügung.

Schritt für Schritt

Die folgenden Schritte erläutern das Implementieren von Jobs und Triggern.

zusätzliche Dependency

Damit das Plugin die SAL-Klassen nutzen kann muss die Bibliothek als Abhängigkeit in die pom.xml ergänzt werden.

<dependency>
   <groupId>com.atlassian.sal</groupId>
   <artifactId>sal-api</artifactId>
   <version>2.0.17</version>
   <scope>provided</scope>
</dependency>

Definition des Schedulers

Damit die Jobs auch nach den definierten Trigger-Zeiten ausgeführt werden, muss ein Scheduler verwendet werden. Diesen kann leicht in der atlassian-plugin.xml konfiguriert werden.

<component-<span>import</span> key=<span>"pluginScheduler"</span>>
   <description>SAL Scheduler</description>
   <<span>interface</span>>com.atlassian.sal.api.scheduling.PluginScheduler</<span>interface</span>>
</component-<span>import</span>>

Job erstellen

Die neue Job-Klasse muss das Interface com.atlassian.sal.api.scheduling.PluginJob implementieren.

<span>public</span> class MyJob <span>implements</span> PluginJob {

	<span>public</span> void execute(Map<<span>String</span>, <span>Object</span>> jobDataMap) {

		TransactionTemplate tt = (TransactionTemplate) jobDataMap.get(<span>"transactionTemplate"</span>);

		tt.execute(<span>new</span> TransactionCallback() {

			<span>public</span> <span>Object</span> doInTransaction() {

				perform();

				<span>return</span> 0;
			}

		});
	}

	<span>protected</span> void perform() {

	}

}

Innerhalb der Methode execute muss die Logik des Jobs definiert sein. Sollte es notwendig sein, dass Manager verwendet werden, die transaktionssichere Aufrufe beinhalten (wie z.B. Datenbank-Zugriffe via Hibernate), muss die Logik innerhalb der execute Methode der TransactionTemplate-Instanz liegen. (siehe obriges Code-Beispiele)

Manager Implementierung für Job-Registrierung

Als nächtes muss der Job für den Scheduler registriert werden, sodass er je nach Definition zyklisch ausgeführt werden kann. Dies wird durch eine neue Service-Klasse (oder Manager-Klasse) übernommen.

<span>public</span> class MyService <span>implements</span> IMyService, LifecycleAware {

	<span>private</span> <span>static</span> <span>final</span> Logger LOG = Logger.getLogger(MyService.class);

	<span>private</span> <span>static</span> <span>final</span> <span>String</span> JOB_NAME = MyTrigger.class.getName() + <span>":job"</span>;

	<span>// 24h in mili-seconds
</span>	<span>private</span> <span>static</span> <span>final</span> <span>long</span> INTERVAL = 86400000L;

	<span>private</span> PluginScheduler pluginScheduler; <span>// provided by SAL
</span>
	<span>private</span> TransactionTemplate transactionTemplate;

	<span>// use a constructor <span>for</span> injection
</span>	<span>public</span> PasswordReminderTrigger(PluginScheduler pluginScheduler, TransactionTemplate transactionTemplate) {

		<span>this</span>.pluginScheduler = pluginScheduler;
		<span>this</span>.transactionTemplate = transactionTemplate;
	}

	<span>public</span> void onStart() {
		reschedule(INTERVAL);
	}

	@SuppressWarnings(<span>"serial"</span>)
	<span>public</span> void reschedule(<span>long</span> interval) {

	...
	
	}
}

Zusätzlich sind noch folgende Anpassungen in der atlassian-plugin.xml zu treffen.

<component key=<span>"schedulerComponent"</span> class=<span>"my.path.plugins.myproject.services.MyService"</span>
	system=<span>"<span>true</span>"</span> <span>public</span>=<span>"<span>true</span>"</span>>
       <<span>interface</span>>com.atlassian.sal.api.lifecycle.LifecycleAware</<span>interface</span>>
       <<span>interface</span>>my.path.plugins.myproject.services.IMyService</<span>interface</span>>
</component>
Wichtig
Das Interface LifecycleAware sorgt dafür, dass bei der Registrierung der Service-Klasse der Job im Scheduler registriert wird.

Info
Das Interface definiert lediglich die reschedule-Methode.
<span>public</span> <span>interface</span> IMyService {
	
  <span>public</span> void reschedule(<span>long</span> interval);
  
}

Registrieren des Jobs für den Schedulers

In der Methode reschedule muss der folgende Quellcode eingetragen und an die eigenen Bedürfnisse angepasst werden.

pluginScheduler.scheduleJob(JOB_NAME,
	MyJob.class,
	<span>new</span> HashMap<<span>String</span>, <span>Object</span>>() {
		{
			put(<span>"transactionTemplate"</span>, transactionTemplate);
			...
		}
	},
	startDate,
	interval
);

Der HashMap Parameter dient als Übergabeparameter für die execute-Methode des Jobs. Das startDate muss als java.util.Date festgelegt werden. Des Weiteren ist der Interval in Millisekunden anzugeben.

TransactionTemplate

Innerhalb eines Jobs ist es leider nicht möglich transaktionssichere Funktionen, wie Hibernate Zugriffe auszuführen. Es gibt allerdings einen Mechanismus, mit dem es trotzdem möglich. Zu diesem Zweck wird die Klasse TransactionTemplate verwendet.

Damit die Spring Injection auch hier greifen kann, muss das TransactionTemplate in der atlassian-plugin.xml konfiguriert werden.

<component-<span>import</span> name=<span>"SAL Transaction Template"</span> key=<span>"transactionTemplate"</span>>
   <<span>interface</span>>com.atlassian.sal.api.transaction.TransactionTemplate</<span>interface</span>>
</component-<span>import</span>>

The post Jobs und Trigger in Crowd verwenden appeared first on Communardo Techblog.


Viewing all articles
Browse latest Browse all 8