Skip to content

Commit f5db45a

Browse files
authored
HDDS-14005. EventNotification: EventNotification: add the plugin framework (#10095)
1 parent a62fa97 commit f5db45a

7 files changed

Lines changed: 428 additions & 0 deletions

File tree

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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.hadoop.ozone.om.eventlistener;
19+
20+
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
21+
22+
/**
23+
* Interface for event listener plugin implementations.
24+
*/
25+
public interface OMEventListener {
26+
27+
void initialize(OzoneConfiguration conf, OMEventListenerPluginContext pluginContext);
28+
29+
void start();
30+
31+
void shutdown();
32+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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.hadoop.ozone.om.eventlistener;
19+
20+
/**
21+
* A narrow set of functionality we are ok with exposing to plugin
22+
* implementations.
23+
*/
24+
public interface OMEventListenerPluginContext {
25+
26+
}
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+
/**
19+
* This package contains classes for the OM Event Listener implementation.
20+
*/
21+
package org.apache.hadoop.ozone.om.eventlistener;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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.hadoop.ozone.om.eventlistener;
19+
20+
import org.apache.hadoop.ozone.om.OzoneManager;
21+
22+
/**
23+
* A narrow set of functionality we are ok with exposing to plugin
24+
* implementations.
25+
*/
26+
public final class OMEventListenerPluginContextImpl implements OMEventListenerPluginContext {
27+
private final OzoneManager ozoneManager; // NOPMD: unused. will be used soon
28+
29+
public OMEventListenerPluginContextImpl(OzoneManager ozoneManager) {
30+
this.ozoneManager = ozoneManager;
31+
}
32+
33+
// TODO: fill this out with capabilities we would like to expose to
34+
// plugin implementations.
35+
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
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.hadoop.ozone.om.eventlistener;
19+
20+
import java.util.ArrayList;
21+
import java.util.List;
22+
import java.util.Map;
23+
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
24+
import org.apache.hadoop.ozone.OzoneIllegalArgumentException;
25+
import org.apache.hadoop.ozone.om.OzoneManager;
26+
import org.slf4j.Logger;
27+
import org.slf4j.LoggerFactory;
28+
29+
/**
30+
* This is a manager for plugins which implement OMEventListener which
31+
* manages the lifecycle of constructing starting/stopping configured
32+
* plugins.
33+
*/
34+
public class OMEventListenerPluginManager {
35+
public static final Logger LOG = LoggerFactory.getLogger(OMEventListenerPluginManager.class);
36+
37+
public static final String PLUGIN_DEST_BASE = "ozone.om.plugin.destination.";
38+
39+
private final List<OMEventListener> plugins;
40+
41+
public OMEventListenerPluginManager(OzoneManager ozoneManager, OzoneConfiguration conf) {
42+
this.plugins = loadAll(ozoneManager, conf);
43+
}
44+
45+
public List<OMEventListener> getLoaded() {
46+
return plugins;
47+
}
48+
49+
public void startAll() {
50+
for (OMEventListener plugin : plugins) {
51+
try {
52+
plugin.start();
53+
} catch (Exception ex) {
54+
LOG.error("Failed to start event listener plugin {}",
55+
plugin.getClass().getName(), ex);
56+
}
57+
}
58+
}
59+
60+
public void shutdownAll() {
61+
for (OMEventListener plugin : plugins) {
62+
try {
63+
plugin.shutdown();
64+
} catch (Exception ex) {
65+
LOG.error("Failed to shut down event listener plugin {}",
66+
plugin.getClass().getName(), ex);
67+
}
68+
}
69+
}
70+
71+
// Configuration is based on ranger plugins
72+
//
73+
// For example, a plugin named FooPlugin would be configured via
74+
// OzoneConfiguration properties as follows:
75+
//
76+
// conf.set("ozone.om.plugin.destination.foo", "enabled");
77+
// conf.set("ozone.om.plugin.destination.foo.classname", "org.apache.hadoop.ozone.om.eventlistener.FooPlugin");
78+
//
79+
static List<OMEventListener> loadAll(OzoneManager ozoneManager, OzoneConfiguration conf) {
80+
List<OMEventListener> plugins = new ArrayList<>();
81+
82+
Map<String, String> props = conf.getPropsMatchPrefixAndTrimPrefix(PLUGIN_DEST_BASE);
83+
List<String> destNameList = new ArrayList<>();
84+
for (Map.Entry<String, String> entry : props.entrySet()) {
85+
String destName = entry.getKey();
86+
String value = entry.getValue();
87+
LOG.info("Found event listener plugin with name={} and value={}", destName, value);
88+
89+
if (value.equalsIgnoreCase("enabled")) {
90+
destNameList.add(destName);
91+
LOG.info("Event listener plugin {}{} is set to {}", PLUGIN_DEST_BASE, destName, value);
92+
}
93+
}
94+
95+
OMEventListenerPluginContext pluginContext = new OMEventListenerPluginContextImpl(ozoneManager);
96+
97+
for (String destName : destNameList) {
98+
try {
99+
Class<? extends OMEventListener> cls = resolvePluginClass(conf, destName);
100+
LOG.info("Event listener plugin class is {}", cls);
101+
102+
OMEventListener impl = cls.getDeclaredConstructor().newInstance();
103+
impl.initialize(conf, pluginContext);
104+
105+
plugins.add(impl);
106+
} catch (ReflectiveOperationException ex) {
107+
LOG.error("Can't make instance of event listener plugin {}{}", PLUGIN_DEST_BASE, destName, ex);
108+
} catch (Exception ex) {
109+
LOG.error("Failed to initialize event listener plugin {}{}", PLUGIN_DEST_BASE, destName, ex);
110+
}
111+
}
112+
113+
return plugins;
114+
}
115+
116+
private static Class<? extends OMEventListener> resolvePluginClass(OzoneConfiguration conf,
117+
String destName) {
118+
String classnameProp = PLUGIN_DEST_BASE + destName + ".classname";
119+
LOG.info("Getting classname for {} with property {}", destName, classnameProp);
120+
Class<? extends OMEventListener> cls = conf.getClass(classnameProp, null, OMEventListener.class);
121+
if (null == cls) {
122+
throw new OzoneIllegalArgumentException(String.format(
123+
"Unable to load plugin %s, classname property %s is missing or does not implement OMEventListener",
124+
destName, classnameProp));
125+
}
126+
return cls;
127+
}
128+
}
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+
/**
19+
* This package contains classes for the OM Event Listener implementation.
20+
*/
21+
package org.apache.hadoop.ozone.om.eventlistener;

0 commit comments

Comments
 (0)