Wiki source code of Remote Observation Module

Last modified by Thomas Mortagne on 2023/10/10 14:25

Hide last authors
Thomas Mortagne 12.1 1 {{box cssClass="floatinginfobox" title="**Contents**"}}
2 {{toc/}}
3 {{/box}}
Vincent Massol 1.1 4
5 Provides the ability to automatically send and receive events through the network.
6
7 image:rom.png
8
9 = Features =
10
11 * api to start/stop channels at runtime
12 * add custom event converter
13 * add custom network adapter implementation (default is based on JGroups)
14
15 = Quick Example =
16
17 == Start/stop channel ==
18
19 {{code language="java"}}
Vincent Massol 12.4 20 RemoteObservationManager rom = componentManager.getInstance(RemoteObservationManager.class);
Vincent Massol 1.1 21
22 // stop the channel with identifier channelid, the channel with configuration file channelid.xml
23 rom.stopChannel("channelid");
24 // start the channel with identifier channelid, the configuration file is releaded
25 rom.startChannel("channelid");
26 {{/code}}
27
Thomas Mortagne 6.1 28 = Setup =
29
30 == General configuration ==
31
32 Found in WEB-INF/xwiki.properties file
33
Thomas Mortagne 7.1 34 {{code language="properties"}}
Thomas Mortagne 6.1 35 #-# [Since 2.0M3]
36 #-# Indicate if the network distribution module is enabled or not.
37 #-# By default remote events are disabled.
38 # observation.remote.enabled = false
39
40 #-# [Since 2.0M3]
41 #-# The list of events communication channels to start when the application starts.
42 #-# By default no channel is configured.
43 #-#
44 #-# The default remote event distribution implementation is using JGroups and you'll need to drop your JGroups channel
45 #-# xml files in the WEB-INF/observation/remote/jgroups/ directory. There's a README file in that directory with more
46 #-# information.
47 #-# Example: observation.remote.channels = public, cluster
48
49 #-# [Since 2.0M4]
50 #-# The implementation of network adapter to use.
51 #-# The default is jgroups.
52 #-#
53 #-# By default obnly jgroups is provided. To add one implements NetworkAdaptor componenet interface. The identifier provided in the configuration is matched with the component role hint.
54 #-# Example: observation.remote.networkadapter = jgroups
55 {{/code}}
56
57 == JGroups ==
58
59 Currently only JGroups implementation is provided.
60
Thomas Mortagne 6.2 61 The configuration for a channel is searched in the following order:
Thomas Mortagne 12.1 62
Thomas Mortagne 6.2 63 1. WEB-INF/observation/remote/jgroups/<channel name>.xml
64 1. <channel name>.xml in the root of jgroups jar file
Thomas Mortagne 6.1 65
Thomas Mortagne 10.1 66 = Check remote event =
67
68 Remote Observation Manager is supposed to emulate local event as much as possible but in some case you actually need to do different things depending if it's a remote or local event (invalidate a cache, avvoid doing twice something on the database, etc.).
69
70 For this you can use inject the component ##org.xwiki.observation.remote.RemoteObservationManagerContex##.
71
72 {{code language="java"}}
73 import org.xwiki.observation.remote.RemoteObservationManagerContext;
74 [...]
75
76 public class MyListener implements EventListener
77 {
78 @Inject
79 private RemoteObservationManagerContext remoteObservationManagerContext;
80
81 [...]
82
83 @Override
84 public void onEvent(Event event, Object source, Object data)
85 {
86 if (this.remoteObservationManagerContext.isRemoteState()) {
87 // do something specific to remote event
88 }
89 }
90 }
91 {{/code}}
92
Thomas Mortagne 11.1 93 From Remote Observation Manager module.
94
95 {{code language="xml"}}
96 <dependency>
97 <groupId>org.xwiki.platform</groupId>
98 <artifactId>xwiki-platform-observation-remote</artifactId>
99 <version>${platform.version}</version>
100 </dependency>
101 {{/code}}
Thomas Mortagne 12.1 102
Thomas Mortagne 9.1 103 = Extends Remote Observation Manager =
Vincent Massol 1.1 104
105 Remote event manage is extendable in many ways depending of the need.
106
107 == Add custom event converter ==
108
109 Each time an event is generated locally or received from network, Remote Event Manager try to converter it to the other side. By default a support of all document events and any fully serializable event is provided but since it's possible to add any kind of local event Remote Event Manager also provide a way to provide converter for any kind of event as well.
110
Vincent Massol 12.3 111 There are two kinds of converters:
Thomas Mortagne 12.1 112
Vincent Massol 1.1 113 * the local to remote event converter: ##org.xwiki.observation.remote.converter.LocalEventConverter##
114 * the remote to local event converter: ##org.xwiki.observation.remote.converter.RemoteEventConverter##
115
116 Most of the time when adding a new event you will need to make conversion both ways. The common way to do this is by extending AbstractEventConverter which provide a default priority and implements both LocalEventConverter and RemoteEventConverter.
117
118 {{code language="java"}}
119 public class ViewEventConverter extends AbstractEventConverter
120 {
121 public int getPriority()
122 {
123 // default priority level
124 return 1000;
125 }
126
127 public boolean toRemote(LocalEventData localEvent, RemoteEventData remoteEvent)
128 {
129 if (localEvent.getEvent() instanceof ActionExecutionEvent) {
130 ActionExecutionEvent event = (ActionExecutionEvent) localEvent.getEvent();
131
132 if ("view".equals(event.getActionName())) {
133 // fill the remote event
134 remoteEvent.setEvent(event);
135 }
136
137 return true;
138 }
139
140 return false;
141 }
142
143 public boolean fromRemote(RemoteEventData remoteEvent, LocalEventData localEvent)
144 {
145 if (localEvent.getEvent() instanceof ActionExecutionEvent) {
146 ActionExecutionEvent event = (ActionExecutionEvent) localEvent.getEvent();
147
148 if ("view".equals(event.getActionName())) {
149 // fill the local event
150 localEvent.setEvent(event);
151 }
152
153 return true;
154 }
155
156 return false;
157 }
158 }
159 {{/code}}
160
161 ##toRemote## and ##fromRemote## work the same way: converter manager call them in the priority order one by one and stop when the methods return true. If the converter event data is empty it mean the event should not be sent for remote event or given to Observation Manager for local events.
162
163 This converter is a combination local event converter and remote event converter. It's possible to implement just local or just remote. For example one would want to filter some kind of events or document.
164
165 == Add custom network adaptor ==
166
167 The default implementation is based on JGroups, it possible to change just the network communication part easily by providing a new implementation of ##org.xwiki.observation.remote.NetworkAdapter## and setting the role hint of this new component as value of the property ##observation.remote.networkadapter## in the file ##xwiki.properties##.
168
169 == Provide custom JGroups listener ==
170
171 In JGroups based implementation it's possible to provide to set the Receiver to use channel by channel. This is useful for example to make a channel readonly when you want to send events in a public UDP broadcast and not do two ways clustering.
172
173 To do this implements the component interface ##org.xwiki.observation.remote.jgroups.JGroupsReceiver## and make the role hint having the same name as the channel.
174
175 {{code language="java"}}
Thomas Mortagne 12.1 176 @Component
177 @Named("public")
Vincent Massol 1.1 178 public class PublicJGroupsReceiver implements JGroupsReceiver
179 {
180 public byte[] getState()
181 {
182 return null;
183 }
184
185 public void receive(Message msg)
186 {
187 // do nothing, it's a readonly public channel
188 }
189
190 public void setState(byte[] state)
191 {
192
193 }
194
195 public void block()
196 {
197
198 }
199
200 public void suspect(Address suspectedMbr)
201 {
202
203 }
204
205 public void viewAccepted(View newView)
206 {
207
208 }
209 }
210 {{/code}}
211
212 = JGroups =
213
214 See http://www.jgroups.org and http://www.jboss.org/community/wiki/JGroups for more documentation on JGroups and its configuration files.
215
Vincent Massol 4.2 216 = Debugging =
Thomas Mortagne 3.1 217
Vincent Massol 4.1 218 There are types of logs you can enable to diagnose issues with clustering:
Thomas Mortagne 12.1 219
Vincent Massol 4.1 220 * XWiki cluster logs
221 * JGroups cluster logs
Thomas Mortagne 3.1 222
Thomas Mortagne 14.1 223 For both you'll need to edit the Log4J configuration (see [[xwiki:Documentation.AdminGuide.Logging]]).
Thomas Mortagne 3.1 224
Vincent Massol 4.1 225 To enable XWiki cluster logs, add:
226
Thomas Mortagne 3.1 227 {{code}}
228 log4j.logger.org.xwiki.observation.remote=trace
229 {{/code}}
230
Vincent Massol 4.1 231 To enable JGroups cluster logs, see the [[JGroups Logging Article>>http://community.jboss.org/wiki/JGroupsLogging]].
232
Vincent Massol 1.1 233 = Tutorial =
234
Thomas Mortagne 14.1 235 * [[How to setup a cluster of XWiki instance based on distributed events>>xwiki:Documentation.AdminGuide.DistributedEventClusterSetup]].

Get Connected