class PathPrefixServiceHandler implements MiddlewareHandler {
    static Logger logger = LoggerFactory.getLogger(PathPrefixServiceHandler.class);
    protected volatile HttpHandler next;
    protected static PathPrefixServiceConfig config;

    public PathPrefixServiceHandler() {
        logger.info("PathServiceHandler is constructed");
        config = PathPrefixServiceConfig.load();
    }

    @Override
    public void handleRequest(final HttpServerExchange exchange) throws Exception {
        logger.debug("PathPrefixServiceHandler.handleRequest starts.");
        pathPrefixService(exchange);
        logger.debug("PathPrefixServiceHandler.handleRequest ends.");
        Handler.next(exchange, next);
    }

    protected void pathPrefixService(HttpServerExchange exchange) throws Exception {<FILL_FUNCTION_BODY>}

    @Override
    public HttpHandler getNext() {
        return next;
    }

    @Override
    public MiddlewareHandler setNext(final HttpHandler next) {
        Handlers.handlerNotNull(next);
        this.next = next;
        return this;
    }

    @Override
    public boolean isEnabled() {
        return config.isEnabled();
    }

    @Override
    public void register() {
        ModuleRegistry.registerModule(PathPrefixServiceConfig.CONFIG_NAME, PathPrefixServiceHandler.class.getName(), Config.getNoneDecryptedInstance().getJsonMapConfigNoCache(PathPrefixServiceConfig.CONFIG_NAME), null);
    }

    @Override
    public void reload() {
        config.reload();
        ModuleRegistry.registerModule(PathPrefixServiceConfig.CONFIG_NAME, PathPrefixServiceHandler.class.getName(), Config.getNoneDecryptedInstance().getJsonMapConfigNoCache(PathPrefixServiceConfig.CONFIG_NAME), null);
        if (logger.isInfoEnabled()) logger.info("PathPrefixServiceHandler is reloaded.");
    }
}

        String requestPath = exchange.getRequestURI();
        String[] serviceEntry = HandlerUtils.findServiceEntry(HandlerUtils.normalisePath(requestPath), config.getMapping());

        // if service URL is in the header, we don't need to do the service discovery with serviceId.
        HeaderValues serviceIdHeader = exchange.getRequestHeaders().get(HttpStringConstants.SERVICE_ID);
        String serviceId = serviceIdHeader != null ? serviceIdHeader.peekFirst() : null;

        if (serviceId == null && serviceEntry != null) {

            if (logger.isTraceEnabled())
                logger.trace("serviceEntry found and header is set for service_id = '{}'", serviceEntry[1]);

            exchange.getRequestHeaders().put(HttpStringConstants.SERVICE_ID, serviceEntry[1]);
        }

        if (serviceEntry != null) {
            if (logger.isTraceEnabled())
                logger.trace("serviceEntry found and endpoint is set to = '{}@{}'", serviceEntry[0], exchange.getRequestMethod().toString().toLowerCase());
            HandlerUtils.populateAuditAttachmentField(exchange, Constants.ENDPOINT_STRING, serviceEntry[0] + "@" + exchange.getRequestMethod().toString().toLowerCase());
        } else {
            if (logger.isTraceEnabled())
                logger.trace("serviceEntry is null and endpoint is set to = '{}@{}'", Constants.UNKOWN_STRING, exchange.getRequestMethod().toString().toLowerCase());
            // at this moment, we don't have a way to reliably determine the endpoint.
            HandlerUtils.populateAuditAttachmentField(exchange, Constants.ENDPOINT_STRING, Constants.UNKOWN_STRING + "@" + exchange.getRequestMethod().toString().toLowerCase());
        }
    
<no_super_class>