Questions & Answers

SOLVED
SebastianStieme
Returning Observer

Data Access Plugin Zugriff auf externe System z. B. via REST

Jump to solution

Hallo,

ich/wir sind gerade dabei ein Data Access Plugin zu entwickeln. Dieses soll Daten via REST von einem Server X abfragen und dann eben in FirstSpirit fรผr den Redakteur, aber dann natรผrlich auch die Generierung spรผlen.

Das Problem was ich nun aber habe, ist dass das DAP die Daten vom Client aus abrufen will. Der Plan wรคre ja aber das der REST Call vom FirstSpirit-Server aus geht.

Der Server X, also das externe System ist nรคmlich nur vom FirstSpirit-Server aus erreichbar.

Wie stelle ich das am besten an?

Das ist DAP ist und bleibt vermutlich immer ein Client-Modul? Das geht vermutlich auch nicht anders?

Muss ich jetzt irgendwie noch einen zusรคtzlichen Server-Service schreiben? Sprich dann wรคre die Kommunikation vom Server X an den Server-Service an das DAP?

Und wenn ja, wie mache ich das grob?

Baue ich ein komplett separates FirstSpirit Modul fรผr den Server-Service? Oder packe ich alles zusammen und muss dann "nur" die module.xml erweitern?

Uns fehlt es hier leider so ein wenig an der Grundidee, wie das eigentlich funktionieren soll.

Hier ggf. noch ein paar Infos zum aktuellen Stand:

in der DataStream Klasse frage ich dann via

HttpRequest request = HttpRequest.newBuilder()

.uri(URI.create("http://localhost:8081/api/agendas"))

.GET()

.build();

die externe Schnittstelle ab.

vielen Dank und GruรŸ

Sebastian

1 Solution

Accepted Solutions
bIT_sosswald
Returning Responder

Hallo Sebastian,

nach einem kurzen Blick in die Module-XML sieht es so aus, als ob du nur eine Library bzw. eine Pulic-Komponente hast. Diese werden um es plakativ auszudrรผcken "da ausgefรผhrt wo sie aufgerufen werden". - Das geht aus der Doku IMHO nicht wirklich bzw. zumindest nicht klar hervor. Ich musste das auch auf die harte Tour lernen und habe die gleiche Erfahrung gemacht wie du.

Die einfachste Lรถsung ist vermutlich, dass du die Logik der externen Anbindung in eine Service-Komponente auslagerst. Das DAP wรผrde dann den FS-Service รผber einen entsprechenden Broker holen und von diesem Daten abfragen. Der Service wiederum lรคuft eben als "zentraler Service" auf dem FS-Server, fรผhrt von dort den Zugriff auf das externe System durch und liefert die Daten an das DAP, welches im z.B. im Client lรคuft, zurรผck.

So lรถse ich zumindest immer meine Anforderungen, wenn ich mรถchte, dass eine Operation zwingend vom FS-Server und nicht aus dem Client ausgefรผhrt wird.

Um auf deine Fragen einzugehen:

  • Ja, der Client hat ja die Hoheit รผber die Aktionen des Users z.B. was der User wann in das Suchfeld des DAP eingibt etc. und muss somit steuern wann das DAP ANfragen startet und wie die Ergebnisse im CLient dargestellt werden. - Von daher macht es durchaus Sinn, dass das DAP im Client lรคuft.
  • Ja, ich wรผrde einen separaten Service schreiben, der die Kommunikation mit dem Drittsystem รผbernimmt.
  • Ich wรผrde dazu KEIN eigenes Modul schreiben, sondern den Service mit in dein DAP-Modul packen. (Gehรถrt fachlich ja zusammen.)
  • Ja, wenn du den Service in deinem Modul hast und die module.xml entsprechend erweiterst wird der Service direkt beim Installieren des Moduls gestartet und du kannst ihn in deinem DAP verwenden.

Beste GrรผรŸe

Sandro

View solution in original post

0 Kudos
6 Replies
bIT_sosswald
Returning Responder

Hallo Sebastian,

nach einem kurzen Blick in die Module-XML sieht es so aus, als ob du nur eine Library bzw. eine Pulic-Komponente hast. Diese werden um es plakativ auszudrรผcken "da ausgefรผhrt wo sie aufgerufen werden". - Das geht aus der Doku IMHO nicht wirklich bzw. zumindest nicht klar hervor. Ich musste das auch auf die harte Tour lernen und habe die gleiche Erfahrung gemacht wie du.

Die einfachste Lรถsung ist vermutlich, dass du die Logik der externen Anbindung in eine Service-Komponente auslagerst. Das DAP wรผrde dann den FS-Service รผber einen entsprechenden Broker holen und von diesem Daten abfragen. Der Service wiederum lรคuft eben als "zentraler Service" auf dem FS-Server, fรผhrt von dort den Zugriff auf das externe System durch und liefert die Daten an das DAP, welches im z.B. im Client lรคuft, zurรผck.

So lรถse ich zumindest immer meine Anforderungen, wenn ich mรถchte, dass eine Operation zwingend vom FS-Server und nicht aus dem Client ausgefรผhrt wird.

Um auf deine Fragen einzugehen:

  • Ja, der Client hat ja die Hoheit รผber die Aktionen des Users z.B. was der User wann in das Suchfeld des DAP eingibt etc. und muss somit steuern wann das DAP ANfragen startet und wie die Ergebnisse im CLient dargestellt werden. - Von daher macht es durchaus Sinn, dass das DAP im Client lรคuft.
  • Ja, ich wรผrde einen separaten Service schreiben, der die Kommunikation mit dem Drittsystem รผbernimmt.
  • Ich wรผrde dazu KEIN eigenes Modul schreiben, sondern den Service mit in dein DAP-Modul packen. (Gehรถrt fachlich ja zusammen.)
  • Ja, wenn du den Service in deinem Modul hast und die module.xml entsprechend erweiterst wird der Service direkt beim Installieren des Moduls gestartet und du kannst ihn in deinem DAP verwenden.

Beste GrรผรŸe

Sandro

0 Kudos

Danke fรผr die Antwort.

Ja, so รคhnlich versuche ich es aktuell auch schon zu lรถsen. Habe nun aber das nรคchste Problem, dass ich eine ClassCastException erhalte, wenn ich aus dem Client versuche, den ServerService aufzurufen.

Ich versuche mal so viele Infos wie mรถglich hier darzustellen. Bzw. zu schildern wie ich aktuell vorgehe.

Ich habe zum einen den ExternalAgendaService. Das soll dann der Service sein, der auf dem FS Server als Dienst lรคuft und dann die Kommunikation zum externen REST-Server รผbernimmt. Aktuell wรคre ich mit einem "Hello World" aber schon mal zufrieden ; ) Sie Screenshot im Anhang scheint der auch als Dienst auf dem Server zu laufen.

Das Problem, welches ich nun aber habe ist, wie ich den Service aus meinem DAP ansprechen kann.

Das ExternalAgendaDataAccessPlugin ist aktuell ein separates Modul. Ich habe die JAR vom ExternalAgendaService hier in den lib Ordner kopiert, so dass ich das dann via mvn dependency im Modul nutzen und bauen kann. Das kopieren dieser JAR in die FSM funktioniert noch nicht, das mach ich aktuell hรคndisch. HeiรŸt also ich kopiere aktuell die ExternalAgendaService.jar hรคndisch in die FSM vom ExternalAgendaDataAccessPlugin.

Dann versuche ich im ExternalAgendaDataAccessPlugin den Service wie folgt anzusprechen:

ExternalAgendaServiceProxy proxy = (ExternalAgendaServiceProxy) context.requireSpecialist(ServicesBroker.TYPE).getService(ExternalAgendaService.class);

erhalte dann aber leider die folgende Fehlermeldung im FS SiteArchitect ๐Ÿ˜•

WARN  29.11.2021 09:59:02.428 (de.espirit.firstspirit.server.io.AbstractServiceLocator): incompatible class loaders? CachingRemoteModuleClassLoader-120{mode=ISOLATED, module=LMWL FS Solr External Agenda Data Access Plugin, parent=ClientCombinedClassLoader-105{Global Isolated, 20 classloaders, parent=jdk.internal.loader.ClassLoaders$AppClassLoader@2145433b}} / CachingRemoteModuleClassLoader-146{mode=LEGACY, module=LMWL FS Solr External Agenda Service, parent=ClientCombinedClassLoader-107{Global Legacy, 20 classloaders, parent=UnifyingClassLoader-106{3 classLoaders, parent=jdk.internal.loader.ClassLoaders$AppClassLoader@2145433b}}}

ERROR 29.11.2021 09:59:02.432 (de.espirit.common.base.control.AbstractActionProcessor): [JC_Main]Handle failed [ActionEvent[AE@pluginsAccessible,null]@792732213]!

FSVersion=5.2.210809.79900#5284;JDK=11.0.11 64bit AdoptOpenJDK;OS=Windows 10 10.0 amd64;Date=29.11.2021 09:59:02 (I)

java.lang.ClassCastException: Cannot cast de.lmwl.ExternalAgendaServiceProxy to de.lmwl.ExternalAgendaService

at java.base/java.lang.Class.cast(Unknown Source)

at de.espirit.firstspirit.server.io.AbstractServiceLocator.getService(AbstractServiceLocator.java:106)

at de.espirit.firstspirit.server.io.AbstractServerConnection.getService(AbstractServerConnection.java:623)

at de.espirit.firstspirit.client.io.ProjectConnection.getService(ProjectConnection.java:101)

at de.espirit.firstspirit.agency.ServicesBrokerImpl.getService(ServicesBrokerImpl.java:26)

at de.lmwl.ExternalAgendaDataAccessPlugin.setUp(ExternalAgendaDataAccessPlugin.java:67)

at de.espirit.firstspirit.client.plugin.ReportPluginAgentImpl.setUpAndAppendIfTrusted(ReportPluginAgentImpl.java:64)

at de.espirit.firstspirit.client.plugin.ReportPluginAgentImpl.getReportPlugins(ReportPluginAgentImpl.java:53)

at de.espirit.firstspirit.client.ClientFrame.restoreOrganizeNavigationContext(ClientFrame.java:1126)

at de.espirit.firstspirit.client.ClientFrame.getHandle(ClientFrame.java:965)

at jdk.internal.reflect.GeneratedMethodAccessor26.invoke(Unknown Source)

at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.base/java.lang.reflect.Method.invoke(Unknown Source)

at de.espirit.common.gui.RunsInEDTProxyFactory$RunsInEDTInvocationHandler.invoke(RunsInEDTProxyFactory.java:143)

at com.sun.proxy.$Proxy4.getHandle(Unknown Source)

at de.espirit.common.base.control.AbstractActionProcessor$ActionProcessDelegate.handle(AbstractActionProcessor.java:1100)

at de.espirit.common.base.control.AbstractActionProcessor$AbstractActionProcess.handle(AbstractActionProcessor.java:1284)

at de.espirit.common.base.control.AbstractActionProcessor$InnerActionProcess.handle(AbstractActionProcessor.java:1576)

at de.espirit.common.base.control.AbstractActionProcessor$InnerActionProcess$1.onGrant(AbstractActionProcessor.java:1559)

at de.espirit.common.base.control.AbstractActionProcessor$ActionProcessDelegate.grant(AbstractActionProcessor.java:957)

at de.espirit.common.base.control.AbstractActionProcessor$AbstractActionProcess.grant(AbstractActionProcessor.java:1279)

at de.espirit.common.base.control.AbstractActionProcessor$InnerActionProcess.grant(AbstractActionProcessor.java:1556)

at de.espirit.common.base.control.AbstractActionProcessor$InnerActionProcess.start(AbstractActionProcessor.java:1551)

at de.espirit.common.base.control.AbstractActionProcessor.doProcess(AbstractActionProcessor.java:436)

at de.espirit.common.base.control.AbstractActionProcessor$2.execute(AbstractActionProcessor.java:589)

at de.espirit.common.util.ExecutorScheduler$ExecuteCommand.run(ExecutorScheduler.java:123)

at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)

at java.base/java.util.concurrent.FutureTask.run(Unknown Source)

at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at java.base/java.lang.Thread.run(Unknown Source)

Hat jemand eine Idee was ich da wohl falsch mache?

Danke und GruรŸ

Sebastian

-- Update --

ich hab ja jetzt nochmal gelesen "

  • Ich wรผrde dazu KEIN eigenes Modul schreiben, sondern den Service mit in dein DAP-Modul packen. (Gehรถrt fachlich ja zusammen.)

"

Das werde ich dann jetzt mal ausprobieren : ) - wรคre ja eh viel besser

0 Kudos

Hi Sebastian,

ganz dumme Frage: Nach der Modulinstallation den FS-Server neu gestartet?

Solche ClassCast-Exceptions kommen / kamen zumindest frรผher รถfters nach einer Modulinstallation. Aber da dann eher mit "java.lang.ClassCastException: Cannot cast com.sun.proxy.$Proxy55 to com..." also ohne konkreten Klassennamen beim Proxy.

In die Anhรคnge habe ich jetzt mal noch nicht geschaut. ๐Ÿ˜‰

Beste GrรผรŸe

Sandro

0 Kudos

ja hab ich. Das hatte ich auch schon mehrfach hier im Forum gelesen.

0 Kudos

Nun hab ich es.

Vielen Dank fรผr die Hilfe. Der Trick war also beides in ein Maven-Projekt zu bauen. Was am Ende sowieso viel besser fรผr uns ist.

Hi Sebastian,

freut mich, dass ich helfen konnte.

Klingt danach, dass da evtl. der Isolated-Mode reingegrรคtscht hat und der Service daher nicht im anderen Modul erreichbar war oder etwas รคhnliches.

Super, dass es jetzt klapp! Viel SpaรŸ beim Daten von extern laden.  

GrรผรŸe
Sandro

0 Kudos

Type a product name