Skip to content

Commit 54049f1

Browse files
committed
[ZEPPELIN-6340] Add ZeppelinEventBus and update NotebookServer to handle NoteRemovedEvent
# Conflicts: # zeppelin-server/src/test/java/org/apache/zeppelin/service/NotebookServiceTest.java
1 parent 78161e3 commit 54049f1

20 files changed

Lines changed: 499 additions & 27 deletions

conf/zeppelin-site.xml.template

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,4 +840,10 @@
840840
<description>fields to be excluded from being saved in note files, with Paragraph prefix mean the fields in Paragraph, e.g. Paragraph.results</description>
841841
</property>
842842

843+
<property>
844+
<name>zeppelin.eventbus.enabled</name>
845+
<value>false</value>
846+
<description>Enables the new event-driven architecture using an in-process EventBus</description>
847+
</property>
848+
843849
</configuration>

zeppelin-server/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@
9797
<artifactId>jakarta.inject-api</artifactId>
9898
</dependency>
9999

100+
<dependency>
101+
<groupId>io.reactivex.rxjava3</groupId>
102+
<artifactId>rxjava</artifactId>
103+
<version>3.1.12</version>
104+
</dependency>
105+
100106
<dependency>
101107
<groupId>commons-io</groupId>
102108
<artifactId>commons-io</artifactId>

zeppelin-server/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,8 @@ public boolean isPrometheusMetricEnabled() {
941941
return getBoolean(ConfVars.ZEPPELIN_METRIC_ENABLE_PROMETHEUS);
942942
}
943943

944+
public boolean isEventBusEnabled() { return getBoolean(ConfVars.ZEPPELIN_EVENTBUS_ENABLED); }
945+
944946
public DEFAULT_UI getDefaultUi() {
945947
return DEFAULT_UI.valueOf(getString(ConfVars.ZEPPELIN_DEFAULT_UI).toUpperCase());
946948
}
@@ -1187,7 +1189,8 @@ public enum ConfVars {
11871189
ZEPPELIN_SPARK_ONLY_YARN_CLUSTER("zeppelin.spark.only_yarn_cluster", false),
11881190
ZEPPELIN_SESSION_CHECK_INTERVAL("zeppelin.session.check_interval", 60 * 10 * 1000),
11891191
ZEPPELIN_NOTE_CACHE_THRESHOLD("zeppelin.note.cache.threshold", 50),
1190-
ZEPPELIN_NOTE_FILE_EXCLUDE_FIELDS("zeppelin.note.file.exclude.fields", "");
1192+
ZEPPELIN_NOTE_FILE_EXCLUDE_FIELDS("zeppelin.note.file.exclude.fields", ""),
1193+
ZEPPELIN_EVENTBUS_ENABLED("zeppelin.eventbus.enabled", false);
11911194

11921195
private String varName;
11931196
private Class<?> varClass;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.zeppelin.eventbus;
19+
20+
import io.reactivex.rxjava3.core.Observable;
21+
22+
public interface EventBus {
23+
24+
void post(ZeppelinEvent event);
25+
26+
<T extends ZeppelinEvent> Observable<T> observe(Class<T> eventType);
27+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.zeppelin.eventbus;
19+
20+
import io.reactivex.rxjava3.core.Observable;
21+
import jakarta.inject.Inject;
22+
import org.slf4j.Logger;
23+
import org.slf4j.LoggerFactory;
24+
25+
public class NoOpEventBus implements EventBus {
26+
27+
private static final Logger LOGGER = LoggerFactory.getLogger(NoOpEventBus.class);
28+
29+
@Inject
30+
public NoOpEventBus() {
31+
LOGGER.info("Starting NoOpEventBus");
32+
}
33+
34+
@Override
35+
public void post(ZeppelinEvent event) {
36+
LOGGER.debug("Posting event: {}", event.getClass().getName());
37+
}
38+
39+
@Override
40+
public <T extends ZeppelinEvent> Observable<T> observe(Class<T> eventType) {
41+
return Observable.empty();
42+
}
43+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.zeppelin.eventbus;
19+
20+
import org.apache.zeppelin.notebook.Note;
21+
import org.apache.zeppelin.user.AuthenticationInfo;
22+
23+
public interface NoteEvent extends ZeppelinEvent {
24+
25+
Note getNote();
26+
27+
AuthenticationInfo getSubject();
28+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.zeppelin.eventbus;
19+
20+
import org.apache.zeppelin.notebook.Note;
21+
import org.apache.zeppelin.user.AuthenticationInfo;
22+
23+
public class NoteRemovedEvent implements NoteEvent {
24+
25+
private final Note note;
26+
27+
private final AuthenticationInfo subject;
28+
29+
public NoteRemovedEvent(Note note, AuthenticationInfo subject) {
30+
this.note = note;
31+
this.subject = subject;
32+
}
33+
34+
@Override
35+
public Note getNote() {
36+
return this.note;
37+
}
38+
39+
@Override
40+
public AuthenticationInfo getSubject() {
41+
return subject;
42+
}
43+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.zeppelin.eventbus;
19+
20+
public interface ZeppelinEvent {
21+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.zeppelin.eventbus;
19+
20+
import io.reactivex.rxjava3.core.Observable;
21+
import io.reactivex.rxjava3.subjects.PublishSubject;
22+
import io.reactivex.rxjava3.subjects.Subject;
23+
import jakarta.inject.Inject;
24+
import org.slf4j.Logger;
25+
import org.slf4j.LoggerFactory;
26+
27+
public class ZeppelinEventBus implements EventBus {
28+
29+
private static final Logger LOGGER = LoggerFactory.getLogger(ZeppelinEventBus.class);
30+
31+
private final Subject<ZeppelinEvent> eventBus;
32+
33+
@Inject
34+
public ZeppelinEventBus() {
35+
LOGGER.info("Starting ZeppelinEventBus");
36+
37+
eventBus = PublishSubject.<ZeppelinEvent>create().toSerialized();
38+
}
39+
40+
@Override
41+
public void post(ZeppelinEvent event) {
42+
LOGGER.debug("Posting event: {}", event.getClass().getName());
43+
44+
eventBus.onNext(event);
45+
}
46+
47+
@Override
48+
public <T extends ZeppelinEvent> Observable<T> observe(Class<T> eventType) {
49+
LOGGER.debug("Observing event: {}", eventType.getName());
50+
51+
return eventBus.ofType(eventType);
52+
}
53+
}

zeppelin-server/src/main/java/org/apache/zeppelin/notebook/Notebook.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
4545
import org.apache.zeppelin.display.AngularObject;
4646
import org.apache.zeppelin.display.AngularObjectRegistry;
47+
import org.apache.zeppelin.eventbus.EventBus;
48+
import org.apache.zeppelin.eventbus.NoteRemovedEvent;
4749
import org.apache.zeppelin.interpreter.Interpreter;
4850
import org.apache.zeppelin.interpreter.InterpreterFactory;
4951
import org.apache.zeppelin.interpreter.InterpreterGroup;
@@ -86,11 +88,13 @@ public class Notebook {
8688
private Credentials credentials;
8789
private final List<Consumer<String>> initConsumers;
8890
private ExecutorService initExecutor;
91+
private EventBus eventBus;
8992

9093
/**
9194
* Main constructor \w manual Dependency Injection
9295
*
9396
* @throws IOException
97+
*
9498
* @throws SchedulerException
9599
*/
96100
public Notebook(
@@ -100,8 +104,8 @@ public Notebook(
100104
NoteManager noteManager,
101105
InterpreterFactory replFactory,
102106
InterpreterSettingManager interpreterSettingManager,
103-
Credentials credentials)
104-
{
107+
Credentials credentials,
108+
EventBus eventBus) {
105109
this.zConf = zConf;
106110
this.authorizationService = authorizationService;
107111
this.noteManager = noteManager;
@@ -111,6 +115,7 @@ public Notebook(
111115
// TODO(zjffdu) cycle refer, not a good solution
112116
this.interpreterSettingManager.setNotebook(this);
113117
this.credentials = credentials;
118+
this.eventBus = eventBus;
114119
addNotebookEventListener(this.interpreterSettingManager);
115120
initConsumers = new LinkedList<>();
116121
}
@@ -221,7 +226,8 @@ public Notebook(
221226
InterpreterFactory replFactory,
222227
InterpreterSettingManager interpreterSettingManager,
223228
Credentials credentials,
224-
NoteEventListener noteEventListener)
229+
NoteEventListener noteEventListener,
230+
EventBus eventBus)
225231
throws IOException {
226232
this(
227233
zConf,
@@ -230,7 +236,8 @@ public Notebook(
230236
noteManager,
231237
replFactory,
232238
interpreterSettingManager,
233-
credentials);
239+
credentials,
240+
eventBus);
234241
if (null != noteEventListener) {
235242
addNotebookEventListener(noteEventListener);
236243
}
@@ -432,7 +439,11 @@ private void removeNote(Note note, AuthenticationInfo subject) throws IOExceptio
432439
note.setRemoved(true);
433440
noteManager.removeNote(note.getId(), subject);
434441
authorizationService.removeNoteAuth(note.getId());
442+
435443
fireNoteRemoveEvent(note, subject);
444+
if (zConf.isEventBusEnabled()) {
445+
eventBus.post(new NoteRemovedEvent(note, subject));
446+
}
436447
}
437448

438449
public void removeCorruptedNote(String noteId, AuthenticationInfo subject) throws IOException {
@@ -564,6 +575,9 @@ public void removeFolder(String folderPath, AuthenticationInfo subject) throws I
564575
note.setRemoved(true);
565576
authorizationService.removeNoteAuth(note.getId());
566577
fireNoteRemoveEvent(note, subject);
578+
if (zConf.isEventBusEnabled()) {
579+
eventBus.post(new NoteRemovedEvent(note, subject));
580+
}
567581
}
568582
return null;
569583
});
@@ -843,6 +857,7 @@ private void fireNoteUpdateEvent(Note note, AuthenticationInfo subject) {
843857
}
844858
}
845859

860+
846861
private void fireNoteRemoveEvent(Note note, AuthenticationInfo subject) {
847862
for (NoteEventListener listener : noteEventListeners) {
848863
listener.onNoteRemove(note, subject);

0 commit comments

Comments
 (0)