You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by pe...@apache.org on 2021/01/14 03:19:08 UTC

[pulsar] 02/03: [feature][pulsar-broker-common]Move additional servlet module to pulsar broker common module (#9164)

This is an automated email from the ASF dual-hosted git repository.

penghui pushed a commit to branch branch-2.7
in repository https://gitbox.apache.org/repos/asf/pulsar.git

commit 601ce89d3ad48419190063930528b82b5393fa89
Author: Guangning E <gu...@apache.org>
AuthorDate: Wed Jan 13 17:12:42 2021 +0800

    [feature][pulsar-broker-common]Move additional servlet module to pulsar broker common module (#9164)
    
    * Currently, after merging this or https://github.com/apache/pulsar/pull/8067, the pulsar-proxy module already supports loading custom web routes, which is also needed in the `pulsar-broker` and `pulsar-function` modules, so consider moving this functionality to the `pulsar-broker-common` module as a generic module.
    
    * Update the class name to remove the proxy prefix
    * Move to the module
    
    How to use this generic module
    
    1. add configuration `additionalServletDirectory` and `additionalServlets` to the configuration file
    2. Call the following code
    
    ```
              Collection<AdditionalServletWithClassLoader> additionalServletCollection =
                        service.getProxyAdditionalServlets().getServlets().values();
                for (AdditionalServletWithClassLoader servletWithClassLoader : additionalServletCollection) {
                    servletWithClassLoader.loadConfig(config);
                    server.addServlet(servletWithClassLoader.getBasePath(), servletWithClassLoader.getServletHolder(),
                            Collections.emptyList(), config.isAuthenticationEnabled());
                    log.info("proxy add additional servlet basePath {} ", servletWithClassLoader.getBasePath());
                }
    ```
    
    (cherry picked from commit 118d64e257eb9dc2961146c1418486623a929a53)
---
 .../web/plugin/servlet/AdditionalServlet.java      |  12 +--
 .../servlet/AdditionalServletDefinition.java       |  10 +-
 .../servlet/AdditionalServletDefinitions.java      |   8 +-
 .../plugin/servlet/AdditionalServletMetadata.java  |  10 +-
 .../web/plugin/servlet/AdditionalServletUtils.java |  84 +++++++--------
 .../servlet/AdditionalServletWithClassLoader.java  |  16 ++-
 .../web/plugin/servlet/AdditionalServlets.java     | 118 +++++++++++++++++++++
 .../broker/web}/plugin/servlet/package-info.java   |   2 +-
 .../plugin/servlet/AdditionalServletUtilsTest.java |  56 +++++-----
 .../AdditionalServletWithClassLoaderTest.java      |  12 +--
 .../web/plugin/servlet/MockAdditionalServlet.java  |  10 +-
 .../pulsar/proxy/server/ProxyConfiguration.java    |  14 +++
 .../apache/pulsar/proxy/server/ProxyService.java   |   6 +-
 .../pulsar/proxy/server/ProxyServiceStarter.java   |   6 +-
 .../plugin/servlet/ProxyAdditionalServlets.java    |  89 ----------------
 .../proxy/server/ProxyAdditionalServletTest.java   |  14 +--
 16 files changed, 250 insertions(+), 217 deletions(-)

diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServlet.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServlet.java
similarity index 82%
rename from pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServlet.java
rename to pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServlet.java
index 7319fb4..07b8e6a 100644
--- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServlet.java
+++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServlet.java
@@ -16,24 +16,24 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.pulsar.proxy.server.plugin.servlet;
+package org.apache.pulsar.broker.web.plugin.servlet;
 
 import com.google.common.annotations.Beta;
-import org.apache.pulsar.proxy.server.ProxyConfiguration;
+import org.apache.pulsar.common.configuration.PulsarConfiguration;
 import org.eclipse.jetty.servlet.ServletHolder;
 
 /**
- * The additional servlet interface for support additional servlet on Pulsar proxy.
+ * The additional servlet interface for support additional servlet.
  */
 @Beta
-public interface ProxyAdditionalServlet extends AutoCloseable {
+public interface AdditionalServlet extends AutoCloseable {
 
     /**
      * load plugin config
      *
-     * @param proxyConfiguration
+     * @param pulsarConfiguration
      */
-    void loadConfig(ProxyConfiguration proxyConfiguration);
+    void loadConfig(PulsarConfiguration pulsarConfiguration);
 
     /**
      * Get the base path of prometheus metrics
diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServletDefinition.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletDefinition.java
similarity index 79%
rename from pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServletDefinition.java
rename to pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletDefinition.java
index 7019e52..b8c4074 100644
--- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServletDefinition.java
+++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletDefinition.java
@@ -16,24 +16,24 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.pulsar.proxy.server.plugin.servlet;
+package org.apache.pulsar.broker.web.plugin.servlet;
 
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
 /**
- * Metadata information about a proxy additional servlet.
+ * Metadata information about an additional servlet.
  */
 @Data
 @NoArgsConstructor
-public class ProxyAdditionalServletDefinition {
+public class AdditionalServletDefinition {
     /**
-     * The name of the proxy additional servlet.
+     * The name of the additional servlet.
      */
     private String name;
 
     /**
-     * The description of the proxy additional servlet to be used for user help.
+     * The description of the additional servlet to be used for user help.
      */
     private String description;
 
diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServletDefinitions.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletDefinitions.java
similarity index 79%
rename from pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServletDefinitions.java
rename to pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletDefinitions.java
index 4b73cf1..b018c4a 100644
--- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServletDefinitions.java
+++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletDefinitions.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.pulsar.proxy.server.plugin.servlet;
+package org.apache.pulsar.broker.web.plugin.servlet;
 
 import java.util.Map;
 import java.util.TreeMap;
@@ -24,11 +24,11 @@ import lombok.Data;
 import lombok.experimental.Accessors;
 
 /**
- * The collection of proxy additional servlet definition.
+ * The collection of additional servlet definition.
  */
 @Data
 @Accessors(fluent = true)
-public class ProxyAdditionalServletDefinitions {
+public class AdditionalServletDefinitions {
 
-    private final Map<String, ProxyAdditionalServletMetadata> servlets = new TreeMap<>();
+    private final Map<String, AdditionalServletMetadata> servlets = new TreeMap<>();
 }
diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServletMetadata.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletMetadata.java
similarity index 80%
rename from pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServletMetadata.java
rename to pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletMetadata.java
index a62adc3..f689cc0 100644
--- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServletMetadata.java
+++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletMetadata.java
@@ -16,23 +16,23 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.pulsar.proxy.server.plugin.servlet;
+package org.apache.pulsar.broker.web.plugin.servlet;
 
 import java.nio.file.Path;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
 /**
- * The metadata of proxy additional servlet
+ * The metadata of additional servlet
  */
 @Data
 @NoArgsConstructor
-public class ProxyAdditionalServletMetadata {
+public class AdditionalServletMetadata {
 
     /**
-     * The definition of the proxy additional servlet.
+     * The definition of the additional servlet.
      */
-    private ProxyAdditionalServletDefinition definition;
+    private AdditionalServletDefinition definition;
 
     /**
      * The path to the additional servlet package.
diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServletUtils.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletUtils.java
similarity index 53%
rename from pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServletUtils.java
rename to pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletUtils.java
index 69d372d..ff895a2 100644
--- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServletUtils.java
+++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletUtils.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.pulsar.proxy.server.plugin.servlet;
+package org.apache.pulsar.broker.web.plugin.servlet;
 
 import java.io.File;
 import java.io.IOException;
@@ -34,76 +34,76 @@ import org.apache.pulsar.common.util.ObjectMapperFactory;
 import static com.google.common.base.Preconditions.checkArgument;
 
 /**
- * Util class to search and load {@link ProxyAdditionalServlets}.
+ * Util class to search and load {@link AdditionalServlets}.
  */
 @UtilityClass
 @Slf4j
-public class ProxyAdditionalServletUtils {
+public class AdditionalServletUtils {
 
-    public final String PROXY_ADDITIONAL_SERVLET_FILE = "proxy_additional_servlet.yml";
+    public final String ADDITIONAL_SERVLET_FILE = "additional_servlet.yml";
 
     /**
-     * Retrieve the proxy additional servlet definition from the provided nar package.
+     * Retrieve the additional servlet definition from the provided nar package.
      *
-     * @param narPath the path to the proxy additional servlet NAR package
-     * @return the proxy additional servlet definition
-     * @throws IOException when fail to load the proxy additional servlet or get the definition
+     * @param narPath the path to the additional servlet NAR package
+     * @return the additional servlet definition
+     * @throws IOException when fail to load the additional servlet or get the definition
      */
-    public ProxyAdditionalServletDefinition getProxyAdditionalServletDefinition(
+    public AdditionalServletDefinition getAdditionalServletDefinition(
             String narPath, String narExtractionDirectory) throws IOException {
 
         try (NarClassLoader ncl = NarClassLoader.getFromArchive(
                 new File(narPath), Collections.emptySet(), narExtractionDirectory)) {
-            return getProxyAdditionalServletDefinition(ncl);
+            return getAdditionalServletDefinition(ncl);
         }
     }
 
-    private ProxyAdditionalServletDefinition getProxyAdditionalServletDefinition(NarClassLoader ncl) throws IOException {
-        String configStr = ncl.getServiceDefinition(PROXY_ADDITIONAL_SERVLET_FILE);
+    private AdditionalServletDefinition getAdditionalServletDefinition(NarClassLoader ncl) throws IOException {
+        String configStr = ncl.getServiceDefinition(ADDITIONAL_SERVLET_FILE);
         return ObjectMapperFactory.getThreadLocalYaml().readValue(
-                configStr, ProxyAdditionalServletDefinition.class
+                configStr, AdditionalServletDefinition.class
         );
     }
 
     /**
-     * Search and load the available proxy additional servlets.
+     * Search and load the available additional servlets.
      *
-     * @param additionalServletDirectory the directory where all the proxy additional servlets are stored
-     * @return a collection of proxy additional servlet definitions
-     * @throws IOException when fail to load the available proxy additional servlets from the provided directory.
+     * @param additionalServletDirectory the directory where all the additional servlets are stored
+     * @return a collection of additional servlet definitions
+     * @throws IOException when fail to load the available additional servlets from the provided directory.
      */
-    public ProxyAdditionalServletDefinitions searchForServlets(String additionalServletDirectory,
-                                                               String narExtractionDirectory) throws IOException {
+    public AdditionalServletDefinitions searchForServlets(String additionalServletDirectory,
+                                                          String narExtractionDirectory) throws IOException {
         Path path = Paths.get(additionalServletDirectory).toAbsolutePath();
-        log.info("Searching for proxy additional servlets in {}", path);
+        log.info("Searching for additional servlets in {}", path);
 
-        ProxyAdditionalServletDefinitions servletDefinitions = new ProxyAdditionalServletDefinitions();
+        AdditionalServletDefinitions servletDefinitions = new AdditionalServletDefinitions();
         if (!path.toFile().exists()) {
-            log.warn("Pulsar proxy additional servlets directory not found");
+            log.warn("Pulsar additional servlets directory not found");
             return servletDefinitions;
         }
 
         try (DirectoryStream<Path> stream = Files.newDirectoryStream(path, "*.nar")) {
             for (Path archive : stream) {
                 try {
-                    ProxyAdditionalServletDefinition def =
-                            ProxyAdditionalServletUtils.getProxyAdditionalServletDefinition(
+                    AdditionalServletDefinition def =
+                            AdditionalServletUtils.getAdditionalServletDefinition(
                                     archive.toString(), narExtractionDirectory);
-                    log.info("Found proxy additional servlet from {} : {}", archive, def);
+                    log.info("Found additional servlet from {} : {}", archive, def);
 
                     checkArgument(StringUtils.isNotBlank(def.getName()));
                     checkArgument(StringUtils.isNotBlank(def.getAdditionalServletClass()));
 
-                    ProxyAdditionalServletMetadata metadata = new ProxyAdditionalServletMetadata();
+                    AdditionalServletMetadata metadata = new AdditionalServletMetadata();
                     metadata.setDefinition(def);
                     metadata.setArchivePath(archive);
 
                     servletDefinitions.servlets().put(def.getName(), metadata);
                 } catch (Throwable t) {
-                    log.warn("Failed to load proxy additional servlet from {}."
-                            + " It is OK however if you want to use this proxy additional servlet,"
-                            + " please make sure you put the correct proxy additional servlet NAR"
-                            + " package in the proxy additional servlets directory.", archive, t);
+                    log.warn("Failed to load additional servlet from {}."
+                            + " It is OK however if you want to use this additional servlet,"
+                            + " please make sure you put the correct additional servlet NAR"
+                            + " package in the additional servlets directory.", archive, t);
                 }
             }
         }
@@ -112,33 +112,33 @@ public class ProxyAdditionalServletUtils {
     }
 
     /**
-     * Load the proxy additional servlets according to the additional servlet definition.
+     * Load the additional servlets according to the additional servlet definition.
      *
-     * @param metadata the proxy additional servlet definition.
+     * @param metadata the additional servlet definition.
      */
-    public ProxyAdditionalServletWithClassLoader load(
-            ProxyAdditionalServletMetadata metadata, String narExtractionDirectory) throws IOException {
+    public AdditionalServletWithClassLoader load(
+            AdditionalServletMetadata metadata, String narExtractionDirectory) throws IOException {
 
         NarClassLoader ncl = NarClassLoader.getFromArchive(
                 metadata.getArchivePath().toAbsolutePath().toFile(),
                 Collections.emptySet(),
-                ProxyAdditionalServlet.class.getClassLoader(), narExtractionDirectory);
+                AdditionalServlet.class.getClassLoader(), narExtractionDirectory);
 
-        ProxyAdditionalServletDefinition def = getProxyAdditionalServletDefinition(ncl);
+        AdditionalServletDefinition def = getAdditionalServletDefinition(ncl);
         if (StringUtils.isBlank(def.getAdditionalServletClass())) {
-            throw new IOException("Proxy additional servlets `" + def.getName() + "` does NOT provide a proxy"
-                    + " additional servlets implementation");
+            throw new IOException("Additional servlets `" + def.getName() + "` does NOT provide an "
+                    + "additional servlets implementation");
         }
 
         try {
             Class additionalServletClass = ncl.loadClass(def.getAdditionalServletClass());
             Object additionalServlet = additionalServletClass.newInstance();
-            if (!(additionalServlet instanceof ProxyAdditionalServlet)) {
+            if (!(additionalServlet instanceof AdditionalServlet)) {
                 throw new IOException("Class " + def.getAdditionalServletClass()
-                        + " does not implement proxy additional servlet interface");
+                        + " does not implement additional servlet interface");
             }
-            ProxyAdditionalServlet servlet = (ProxyAdditionalServlet) additionalServlet;
-            return new ProxyAdditionalServletWithClassLoader(servlet, ncl);
+            AdditionalServlet servlet = (AdditionalServlet) additionalServlet;
+            return new AdditionalServletWithClassLoader(servlet, ncl);
         } catch (Throwable t) {
             rethrowIOException(t);
             return null;
diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServletWithClassLoader.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletWithClassLoader.java
similarity index 74%
rename from pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServletWithClassLoader.java
rename to pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletWithClassLoader.java
index 706320c..06a51c8 100644
--- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServletWithClassLoader.java
+++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletWithClassLoader.java
@@ -16,32 +16,30 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.pulsar.proxy.server.plugin.servlet;
+package org.apache.pulsar.broker.web.plugin.servlet;
 
 import java.io.IOException;
 import lombok.Data;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.pulsar.broker.ServiceConfiguration;
+import org.apache.pulsar.common.configuration.PulsarConfiguration;
 import org.apache.pulsar.common.nar.NarClassLoader;
-import org.apache.pulsar.proxy.server.ProxyConfiguration;
-import org.apache.pulsar.proxy.server.plugin.servlet.ProxyAdditionalServlet;
 import org.eclipse.jetty.servlet.ServletHolder;
 
 /**
- * A proxy additional servlet with it's classloader.
+ * An additional servlet with it's classloader.
  */
 @Slf4j
 @Data
 @RequiredArgsConstructor
-public class ProxyAdditionalServletWithClassLoader implements ProxyAdditionalServlet {
+public class AdditionalServletWithClassLoader implements AdditionalServlet {
 
-    private final ProxyAdditionalServlet servlet;
+    private final AdditionalServlet servlet;
     private final NarClassLoader classLoader;
 
     @Override
-    public void loadConfig(ProxyConfiguration proxyConfiguration) {
-        servlet.loadConfig(proxyConfiguration);
+    public void loadConfig(PulsarConfiguration pulsarConfiguration) {
+        servlet.loadConfig(pulsarConfiguration);
     }
 
     @Override
diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServlets.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServlets.java
new file mode 100644
index 0000000..2451cf5
--- /dev/null
+++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServlets.java
@@ -0,0 +1,118 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pulsar.broker.web.plugin.servlet;
+
+import com.google.common.collect.ImmutableMap;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.pulsar.common.configuration.PulsarConfiguration;
+
+/**
+ * A collection of loaded additional servlets.
+ */
+@Slf4j
+public class AdditionalServlets implements AutoCloseable {
+
+    private static final String ADDITIONAL_SERVLET_DIRECTORY = "additionalServletDirectory";
+
+    private static final String ADDITIONAL_SERVLETS = "additionalServlets";
+
+    private static final String NAR_EXTRACTION_DIRECTORY = "narExtractionDirectory";
+
+    @Deprecated
+    private static final String PROXY_ADDITIONAL_SERVLET_DIRECTORY = "proxyAdditionalServletDirectory";
+
+    @Deprecated
+    private static final String PROXY_ADDITIONAL_SERVLETS = "proxyAdditionalServlets";
+
+    @Getter
+    private final Map<String, AdditionalServletWithClassLoader> servlets;
+
+    public AdditionalServlets(Map<String, AdditionalServletWithClassLoader> servlets) {
+        this.servlets = servlets;
+    }
+
+    /**
+     * Load the additional servlet for the given <tt>servlet name</tt> list.
+     *
+     * @param conf the pulsar service configuration
+     * @return the collection of additional servlet
+     */
+    public static AdditionalServlets load(PulsarConfiguration conf) throws IOException {
+        String additionalServletDirectory = conf.getProperties().getProperty(ADDITIONAL_SERVLET_DIRECTORY);
+        if (additionalServletDirectory == null) {
+            // Compatible with the current proxy configuration
+            additionalServletDirectory = conf.getProperties().getProperty(PROXY_ADDITIONAL_SERVLET_DIRECTORY);
+        }
+
+        String additionalServlets = conf.getProperties().getProperty(ADDITIONAL_SERVLETS);
+        if (additionalServlets == null) {
+            additionalServlets = conf.getProperties().getProperty(PROXY_ADDITIONAL_SERVLETS);
+        }
+        if (additionalServletDirectory == null || additionalServlets == null) {
+            return null;
+        }
+
+        AdditionalServletDefinitions definitions =
+                AdditionalServletUtils.searchForServlets(additionalServletDirectory
+                        , null);
+        ImmutableMap.Builder<String, AdditionalServletWithClassLoader> builder = ImmutableMap.builder();
+
+        List<String> additionalServletsList = Arrays.asList(additionalServlets.split(","));
+        additionalServletsList.forEach(servletName -> {
+
+            AdditionalServletMetadata definition = definitions.servlets().get(servletName);
+            if (null == definition) {
+                throw new RuntimeException("No additional servlet is found for name `" + servletName
+                        + "`. Available additional servlet are : " + definitions.servlets());
+            }
+
+            AdditionalServletWithClassLoader servletWithClassLoader;
+            try {
+                servletWithClassLoader = AdditionalServletUtils.load(definition,
+                        conf.getProperties().getProperty(NAR_EXTRACTION_DIRECTORY));
+                if (servletWithClassLoader != null) {
+                    builder.put(servletName, servletWithClassLoader);
+                }
+                log.info("Successfully loaded additional servlet for name `{}`", servletName);
+            } catch (IOException e) {
+                log.error("Failed to load the additional servlet for name `" + servletName + "`", e);
+                throw new RuntimeException("Failed to load the additional servlet for name `" + servletName + "`");
+            }
+        });
+
+        Map<String, AdditionalServletWithClassLoader> servlets = builder.build();
+        if (servlets != null && !servlets.isEmpty()) {
+            return new AdditionalServlets(servlets);
+        }
+
+        return null;
+    }
+
+    @Override
+    public void close() {
+        servlets.values().forEach(AdditionalServletWithClassLoader::close);
+    }
+}
diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/package-info.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/package-info.java
similarity index 94%
rename from pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/package-info.java
rename to pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/package-info.java
index bd0517a..2807dc4 100644
--- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/package-info.java
+++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/plugin/servlet/package-info.java
@@ -20,4 +20,4 @@
 /**
  * Pulsar proxy servlet plugin.
  */
-package org.apache.pulsar.proxy.server.plugin.servlet;
\ No newline at end of file
+package org.apache.pulsar.broker.web.plugin.servlet;
\ No newline at end of file
diff --git a/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/plugin/ProxyAdditionalServletUtilsTest.java b/pulsar-broker-common/src/test/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletUtilsTest.java
similarity index 63%
rename from pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/plugin/ProxyAdditionalServletUtilsTest.java
rename to pulsar-broker-common/src/test/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletUtilsTest.java
index 7099b3b..bade954 100644
--- a/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/plugin/ProxyAdditionalServletUtilsTest.java
+++ b/pulsar-broker-common/src/test/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletUtilsTest.java
@@ -16,20 +16,14 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.pulsar.proxy.server.plugin;
+package org.apache.pulsar.broker.web.plugin.servlet;
 
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Paths;
 import java.util.Set;
-import org.apache.pulsar.broker.intercept.*;
 import org.apache.pulsar.common.nar.NarClassLoader;
 import org.apache.pulsar.common.util.ObjectMapperFactory;
-import org.apache.pulsar.proxy.server.plugin.servlet.ProxyAdditionalServlet;
-import org.apache.pulsar.proxy.server.plugin.servlet.ProxyAdditionalServletDefinition;
-import org.apache.pulsar.proxy.server.plugin.servlet.ProxyAdditionalServletMetadata;
-import org.apache.pulsar.proxy.server.plugin.servlet.ProxyAdditionalServletUtils;
-import org.apache.pulsar.proxy.server.plugin.servlet.ProxyAdditionalServletWithClassLoader;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PowerMockIgnore;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -45,10 +39,10 @@ import static org.testng.AssertJUnit.assertSame;
 import static org.testng.AssertJUnit.assertTrue;
 
 @PrepareForTest({
-        BrokerInterceptorUtils.class, NarClassLoader.class
+        NarClassLoader.class
 })
 @PowerMockIgnore({"org.apache.logging.log4j.*"})
-public class ProxyAdditionalServletUtilsTest {
+public class AdditionalServletUtilsTest {
 
     // Necessary to make PowerMockito.mockStatic work with TestNG.
     @ObjectFactory
@@ -57,22 +51,22 @@ public class ProxyAdditionalServletUtilsTest {
     }
 
     @Test
-    public void testLoadProxyEventListener() throws Exception {
-        ProxyAdditionalServletDefinition def = new ProxyAdditionalServletDefinition();
-        def.setAdditionalServletClass(MockProxyAdditionalServlet.class.getName());
+    public void testLoadEventListener() throws Exception {
+        AdditionalServletDefinition def = new AdditionalServletDefinition();
+        def.setAdditionalServletClass(MockAdditionalServlet.class.getName());
         def.setDescription("test-proxy-listener");
 
         String archivePath = "/path/to/proxy/listener/nar";
 
-        ProxyAdditionalServletMetadata metadata = new ProxyAdditionalServletMetadata();
+        AdditionalServletMetadata metadata = new AdditionalServletMetadata();
         metadata.setDefinition(def);
         metadata.setArchivePath(Paths.get(archivePath));
 
         NarClassLoader mockLoader = mock(NarClassLoader.class);
-        when(mockLoader.getServiceDefinition(eq(ProxyAdditionalServletUtils.PROXY_ADDITIONAL_SERVLET_FILE)))
+        when(mockLoader.getServiceDefinition(eq(AdditionalServletUtils.ADDITIONAL_SERVLET_FILE)))
                 .thenReturn(ObjectMapperFactory.getThreadLocalYaml().writeValueAsString(def));
-        Class listenerClass = MockProxyAdditionalServlet.class;
-        when(mockLoader.loadClass(eq(MockProxyAdditionalServlet.class.getName())))
+        Class listenerClass = MockAdditionalServlet.class;
+        when(mockLoader.loadClass(eq(MockAdditionalServlet.class.getName())))
                 .thenReturn(listenerClass);
 
         PowerMockito.mockStatic(NarClassLoader.class);
@@ -83,29 +77,29 @@ public class ProxyAdditionalServletUtilsTest {
                 any(String.class)
         )).thenReturn(mockLoader);
 
-        ProxyAdditionalServletWithClassLoader returnedPhWithCL = ProxyAdditionalServletUtils.load(metadata, "");
-        ProxyAdditionalServlet returnedPh = returnedPhWithCL.getServlet();
+        AdditionalServletWithClassLoader returnedPhWithCL = AdditionalServletUtils.load(metadata, "");
+        AdditionalServlet returnedPh = returnedPhWithCL.getServlet();
 
         assertSame(mockLoader, returnedPhWithCL.getClassLoader());
-        assertTrue(returnedPh instanceof MockProxyAdditionalServlet);
+        assertTrue(returnedPh instanceof MockAdditionalServlet);
     }
 
     @Test(expectedExceptions = IOException.class)
-    public void testLoadProxyEventListenerWithBlankListerClass() throws Exception {
-        ProxyAdditionalServletDefinition def = new ProxyAdditionalServletDefinition();
+    public void testLoadEventListenerWithBlankListerClass() throws Exception {
+        AdditionalServletDefinition def = new AdditionalServletDefinition();
         def.setDescription("test-proxy-listener");
 
         String archivePath = "/path/to/proxy/listener/nar";
 
-        ProxyAdditionalServletMetadata metadata = new ProxyAdditionalServletMetadata();
+        AdditionalServletMetadata metadata = new AdditionalServletMetadata();
         metadata.setDefinition(def);
         metadata.setArchivePath(Paths.get(archivePath));
 
         NarClassLoader mockLoader = mock(NarClassLoader.class);
-        when(mockLoader.getServiceDefinition(eq(ProxyAdditionalServletUtils.PROXY_ADDITIONAL_SERVLET_FILE)))
+        when(mockLoader.getServiceDefinition(eq(AdditionalServletUtils.ADDITIONAL_SERVLET_FILE)))
                 .thenReturn(ObjectMapperFactory.getThreadLocalYaml().writeValueAsString(def));
-        Class listenerClass = MockProxyAdditionalServlet.class;
-        when(mockLoader.loadClass(eq(MockProxyAdditionalServlet.class.getName())))
+        Class listenerClass = MockAdditionalServlet.class;
+        when(mockLoader.loadClass(eq(MockAdditionalServlet.class.getName())))
                 .thenReturn(listenerClass);
 
         PowerMockito.mockStatic(NarClassLoader.class);
@@ -116,23 +110,23 @@ public class ProxyAdditionalServletUtilsTest {
                 any(String.class)
         )).thenReturn(mockLoader);
 
-        ProxyAdditionalServletUtils.load(metadata, "");
+        AdditionalServletUtils.load(metadata, "");
     }
 
     @Test(expectedExceptions = IOException.class)
-    public void testLoadProxyEventListenerWithWrongListerClass() throws Exception {
-        ProxyAdditionalServletDefinition def = new ProxyAdditionalServletDefinition();
+    public void testLoadEventListenerWithWrongListerClass() throws Exception {
+        AdditionalServletDefinition def = new AdditionalServletDefinition();
         def.setAdditionalServletClass(Runnable.class.getName());
         def.setDescription("test-proxy-listener");
 
         String archivePath = "/path/to/proxy/listener/nar";
 
-        ProxyAdditionalServletMetadata metadata = new ProxyAdditionalServletMetadata();
+        AdditionalServletMetadata metadata = new AdditionalServletMetadata();
         metadata.setDefinition(def);
         metadata.setArchivePath(Paths.get(archivePath));
 
         NarClassLoader mockLoader = mock(NarClassLoader.class);
-        when(mockLoader.getServiceDefinition(eq(ProxyAdditionalServletUtils.PROXY_ADDITIONAL_SERVLET_FILE)))
+        when(mockLoader.getServiceDefinition(eq(AdditionalServletUtils.ADDITIONAL_SERVLET_FILE)))
                 .thenReturn(ObjectMapperFactory.getThreadLocalYaml().writeValueAsString(def));
         Class listenerClass = Runnable.class;
         when(mockLoader.loadClass(eq(Runnable.class.getName())))
@@ -146,6 +140,6 @@ public class ProxyAdditionalServletUtilsTest {
                 any(String.class)
         )).thenReturn(mockLoader);
 
-        ProxyAdditionalServletUtils.load(metadata, "");
+        AdditionalServletUtils.load(metadata, "");
     }
 }
diff --git a/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/plugin/ProxyAdditionalServletWithClassLoaderTest.java b/pulsar-broker-common/src/test/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletWithClassLoaderTest.java
similarity index 71%
rename from pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/plugin/ProxyAdditionalServletWithClassLoaderTest.java
rename to pulsar-broker-common/src/test/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletWithClassLoaderTest.java
index d7206ad..9811900 100644
--- a/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/plugin/ProxyAdditionalServletWithClassLoaderTest.java
+++ b/pulsar-broker-common/src/test/java/org/apache/pulsar/broker/web/plugin/servlet/AdditionalServletWithClassLoaderTest.java
@@ -16,26 +16,24 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.pulsar.proxy.server.plugin;
+package org.apache.pulsar.broker.web.plugin.servlet;
 
 import org.apache.pulsar.common.nar.NarClassLoader;
-import org.apache.pulsar.proxy.server.plugin.servlet.ProxyAdditionalServlet;
-import org.apache.pulsar.proxy.server.plugin.servlet.ProxyAdditionalServletWithClassLoader;
 import org.testng.annotations.Test;
 
 import static org.mockito.Mockito.*;
 import static org.testng.Assert.assertEquals;
 
 /**
- * Unit test {@link ProxyAdditionalServletWithClassLoader}.
+ * Unit test {@link AdditionalServletWithClassLoader}.
  */
-public class ProxyAdditionalServletWithClassLoaderTest {
+public class AdditionalServletWithClassLoaderTest {
 
     @Test
     public void testWrapper() throws Exception {
-        ProxyAdditionalServlet servlet = mock(ProxyAdditionalServlet.class);
+        AdditionalServlet servlet = mock(AdditionalServlet.class);
         NarClassLoader loader = mock(NarClassLoader.class);
-        ProxyAdditionalServletWithClassLoader wrapper = new ProxyAdditionalServletWithClassLoader(servlet, loader);
+        AdditionalServletWithClassLoader wrapper = new AdditionalServletWithClassLoader(servlet, loader);
 
         String basePath = "metrics/pulsar";
 
diff --git a/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/plugin/MockProxyAdditionalServlet.java b/pulsar-broker-common/src/test/java/org/apache/pulsar/broker/web/plugin/servlet/MockAdditionalServlet.java
similarity index 77%
rename from pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/plugin/MockProxyAdditionalServlet.java
rename to pulsar-broker-common/src/test/java/org/apache/pulsar/broker/web/plugin/servlet/MockAdditionalServlet.java
index f677f02..05b955c 100644
--- a/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/plugin/MockProxyAdditionalServlet.java
+++ b/pulsar-broker-common/src/test/java/org/apache/pulsar/broker/web/plugin/servlet/MockAdditionalServlet.java
@@ -16,16 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.pulsar.proxy.server.plugin;
+package org.apache.pulsar.broker.web.plugin.servlet;
 
-import org.apache.pulsar.proxy.server.ProxyConfiguration;
-import org.apache.pulsar.proxy.server.plugin.servlet.ProxyAdditionalServlet;
+import org.apache.pulsar.common.configuration.PulsarConfiguration;
+import org.apache.pulsar.broker.web.plugin.servlet.AdditionalServlet;
 import org.eclipse.jetty.servlet.ServletHolder;
 
-public class MockProxyAdditionalServlet implements ProxyAdditionalServlet {
+public class MockAdditionalServlet implements AdditionalServlet {
 
     @Override
-    public void loadConfig(ProxyConfiguration proxyConfiguration) {
+    public void loadConfig(PulsarConfiguration pulsarConfiguration) {
 
     }
 
diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyConfiguration.java b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyConfiguration.java
index 52a34a0..3847f82 100644
--- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyConfiguration.java
+++ b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyConfiguration.java
@@ -487,6 +487,7 @@ public class ProxyConfiguration implements PulsarConfiguration {
     )
     private int httpNumThreads = Math.max(8, 2 * Runtime.getRuntime().availableProcessors());
 
+    @Deprecated
     @FieldContext(
             category = CATEGORY_PLUGIN,
             doc = "The directory to locate proxy additional servlet"
@@ -495,11 +496,24 @@ public class ProxyConfiguration implements PulsarConfiguration {
 
     @FieldContext(
             category = CATEGORY_PLUGIN,
+            doc = "The directory to locate proxy additional servlet"
+    )
+    private String additionalServletDirectory = "./proxyAdditionalServlet";
+
+    @Deprecated
+    @FieldContext(
+            category = CATEGORY_PLUGIN,
             doc = "List of proxy additional servlet to load, which is a list of proxy additional servlet names"
     )
     private Set<String> proxyAdditionalServlets = Sets.newTreeSet();
 
     @FieldContext(
+            category = CATEGORY_PLUGIN,
+            doc = "List of proxy additional servlet to load, which is a list of proxy additional servlet names"
+    )
+    private Set<String> additionalServlets = Sets.newTreeSet();
+
+    @FieldContext(
             category =  CATEGORY_HTTP,
             doc = "Enable the enforcement of limits on the incoming HTTP requests"
         )
diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyService.java b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyService.java
index 34ec40b..58ba3cf 100644
--- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyService.java
+++ b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyService.java
@@ -51,7 +51,7 @@ import org.apache.pulsar.broker.cache.ConfigurationCacheService;
 import org.apache.pulsar.common.allocator.PulsarByteBufAllocator;
 import org.apache.pulsar.common.configuration.PulsarConfigurationLoader;
 import org.apache.pulsar.common.util.netty.EventLoopUtil;
-import org.apache.pulsar.proxy.server.plugin.servlet.ProxyAdditionalServlets;
+import org.apache.pulsar.broker.web.plugin.servlet.AdditionalServlets;
 import org.apache.pulsar.proxy.stats.TopicStats;
 import org.apache.pulsar.zookeeper.ZooKeeperClientFactory;
 import org.apache.pulsar.zookeeper.ZookeeperClientFactoryImpl;
@@ -118,7 +118,7 @@ public class ProxyService implements Closeable {
     @Getter
     private final Map<String, TopicStats> topicStats;
     @Getter
-    private ProxyAdditionalServlets proxyAdditionalServlets;
+    private AdditionalServlets proxyAdditionalServlets;
 
     public ProxyService(ProxyConfiguration proxyConfig,
                         AuthenticationService authenticationService) throws IOException {
@@ -152,7 +152,7 @@ public class ProxyService implements Closeable {
                 stats.calculate();
             });
         }, 60, TimeUnit.SECONDS);
-        this.proxyAdditionalServlets = ProxyAdditionalServlets.load(proxyConfig);
+        this.proxyAdditionalServlets = AdditionalServlets.load(proxyConfig);
     }
 
     public void start() throws Exception {
diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyServiceStarter.java b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyServiceStarter.java
index c1178b0..3e79fe2 100644
--- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyServiceStarter.java
+++ b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyServiceStarter.java
@@ -28,7 +28,7 @@ import static org.slf4j.bridge.SLF4JBridgeHandler.removeHandlersForRootLogger;
 import org.apache.pulsar.broker.PulsarServerException;
 import org.apache.pulsar.broker.authentication.AuthenticationService;
 import org.apache.pulsar.common.configuration.PulsarConfigurationLoader;
-import org.apache.pulsar.proxy.server.plugin.servlet.ProxyAdditionalServletWithClassLoader;
+import org.apache.pulsar.broker.web.plugin.servlet.AdditionalServletWithClassLoader;
 import org.apache.pulsar.websocket.WebSocketConsumerServlet;
 import org.apache.pulsar.websocket.WebSocketProducerServlet;
 import org.apache.pulsar.websocket.WebSocketReaderServlet;
@@ -211,9 +211,9 @@ public class ProxyServiceStarter {
 
         // add proxy additional servlets
         if (service != null && service.getProxyAdditionalServlets() != null) {
-            Collection<ProxyAdditionalServletWithClassLoader> additionalServletCollection =
+            Collection<AdditionalServletWithClassLoader> additionalServletCollection =
                     service.getProxyAdditionalServlets().getServlets().values();
-            for (ProxyAdditionalServletWithClassLoader servletWithClassLoader : additionalServletCollection) {
+            for (AdditionalServletWithClassLoader servletWithClassLoader : additionalServletCollection) {
                 servletWithClassLoader.loadConfig(config);
                 server.addServlet(servletWithClassLoader.getBasePath(), servletWithClassLoader.getServletHolder(),
                         Collections.emptyList(), config.isAuthenticationEnabled());
diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServlets.java b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServlets.java
deleted file mode 100644
index 07ef85d..0000000
--- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/plugin/servlet/ProxyAdditionalServlets.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.pulsar.proxy.server.plugin.servlet;
-
-import com.google.common.collect.ImmutableMap;
-
-import java.io.IOException;
-import java.util.Map;
-
-import lombok.Getter;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.pulsar.proxy.server.ProxyConfiguration;
-
-/**
- * A collection of loaded proxy additional servlets.
- */
-@Slf4j
-public class ProxyAdditionalServlets implements AutoCloseable {
-
-    @Getter
-    private final Map<String, ProxyAdditionalServletWithClassLoader> servlets;
-
-    public ProxyAdditionalServlets(Map<String, ProxyAdditionalServletWithClassLoader> servlets) {
-        this.servlets = servlets;
-    }
-
-    /**
-     * Load the proxy additional servlet for the given <tt>servlet name</tt> list.
-     *
-     * @param conf the pulsar proxy service configuration
-     * @return the collection of proxy additional servlet
-     */
-    public static ProxyAdditionalServlets load(ProxyConfiguration conf) throws IOException {
-        ProxyAdditionalServletDefinitions definitions =
-                ProxyAdditionalServletUtils.searchForServlets(
-                        conf.getProxyAdditionalServletDirectory(), null);
-
-        ImmutableMap.Builder<String, ProxyAdditionalServletWithClassLoader> builder = ImmutableMap.builder();
-
-        conf.getProxyAdditionalServlets().forEach(servletName -> {
-
-            ProxyAdditionalServletMetadata definition = definitions.servlets().get(servletName);
-            if (null == definition) {
-                throw new RuntimeException("No proxy additional servlet is found for name `" + servletName
-                        + "`. Available proxy additional servlet are : " + definitions.servlets());
-            }
-
-            ProxyAdditionalServletWithClassLoader servletWithClassLoader;
-            try {
-                servletWithClassLoader = ProxyAdditionalServletUtils.load(definition, conf.getNarExtractionDirectory());
-                if (servletWithClassLoader != null) {
-                    builder.put(servletName, servletWithClassLoader);
-                }
-                log.info("Successfully loaded proxy additional servlet for name `{}`", servletName);
-            } catch (IOException e) {
-                log.error("Failed to load the proxy additional servlet for name `" + servletName + "`", e);
-                throw new RuntimeException("Failed to load the proxy additional servlet for name `" + servletName + "`");
-            }
-        });
-
-        Map<String, ProxyAdditionalServletWithClassLoader> servlets = builder.build();
-        if (servlets != null && !servlets.isEmpty()) {
-            return new ProxyAdditionalServlets(servlets);
-        }
-
-        return null;
-    }
-
-    @Override
-    public void close() {
-        servlets.values().forEach(ProxyAdditionalServletWithClassLoader::close);
-    }
-}
diff --git a/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/ProxyAdditionalServletTest.java b/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/ProxyAdditionalServletTest.java
index a754c7f..ad28ebe 100644
--- a/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/ProxyAdditionalServletTest.java
+++ b/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/ProxyAdditionalServletTest.java
@@ -26,9 +26,9 @@ import org.apache.commons.lang3.RandomUtils;
 import org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest;
 import org.apache.pulsar.broker.authentication.AuthenticationService;
 import org.apache.pulsar.common.configuration.PulsarConfigurationLoader;
-import org.apache.pulsar.proxy.server.plugin.servlet.ProxyAdditionalServletWithClassLoader;
-import org.apache.pulsar.proxy.server.plugin.servlet.ProxyAdditionalServlets;
-import org.apache.pulsar.proxy.server.plugin.servlet.ProxyAdditionalServlet;
+import org.apache.pulsar.broker.web.plugin.servlet.AdditionalServletWithClassLoader;
+import org.apache.pulsar.broker.web.plugin.servlet.AdditionalServlets;
+import org.apache.pulsar.broker.web.plugin.servlet.AdditionalServlet;
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.servlet.ServletHolder;
 import org.mockito.Mockito;
@@ -157,13 +157,13 @@ public class ProxyAdditionalServletTest extends MockedPulsarServiceBaseTest {
             }
         };
 
-        ProxyAdditionalServlet proxyAdditionalServlet = Mockito.mock(ProxyAdditionalServlet.class);
+        AdditionalServlet proxyAdditionalServlet = Mockito.mock(AdditionalServlet.class);
         Mockito.when(proxyAdditionalServlet.getBasePath()).thenReturn(BASE_PATH);
         Mockito.when(proxyAdditionalServlet.getServletHolder()).thenReturn(new ServletHolder(servlet));
 
-        ProxyAdditionalServlets proxyAdditionalServlets = Mockito.mock(ProxyAdditionalServlets.class);
-        Map<String, ProxyAdditionalServletWithClassLoader> map = new HashMap<>();
-        map.put("prometheus-proxy-servlet", new ProxyAdditionalServletWithClassLoader(proxyAdditionalServlet, null));
+        AdditionalServlets proxyAdditionalServlets = Mockito.mock(AdditionalServlets.class);
+        Map<String, AdditionalServletWithClassLoader> map = new HashMap<>();
+        map.put("prometheus-proxy-servlet", new AdditionalServletWithClassLoader(proxyAdditionalServlet, null));
         Mockito.when(proxyAdditionalServlets.getServlets()).thenReturn(map);
 
         Mockito.when(proxyService.getProxyAdditionalServlets()).thenReturn(proxyAdditionalServlets);