DEV Community

Query Filter
Query Filter

Posted on

docker-184

package com.citigroup.get.quantum.config.v2.internal.soap;

import com.citigroup.get.quantum.config.v2.ConfigRuntimeException;
import com.citigroup.get.quantum.config.v2.internal.ServiceEndPointDescription;
import com.citigroup.get.quantum.util.loadbalance.LoadBalancerRequestHandlerAdapter;
import com.citigroup.get.quantum.util.loadbalance.Request;
import com.citigroup.get.quantum.util.loadbalance.RequestCannotBeHandledException;
import com.citigroup.get.quantum.util.loadbalance.Response;
import org.apache.log4j.Logger;

import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.Objects;

/**
 * <h2>SOAPEndpointLoadBalancerHandlerImpl</h2>
 *
 * <p>Concrete load balancer request handler implementation designed to manage,<br>
 * initialize, and route downstream endpoint traffic vectors across active<br>
 * SOAP web service ports.</p>
 *
 * <p><b>Architectural Context &amp; Concurrency:</b><br>
 * Modernized to run safely within <b>Java 21</b> and <b>Spring 6.1</b> baseline<br>
 * infrastructures. This handler dynamically maps physical remote target URLs<br>
 * onto the underlying runtime JAX-WS client execution contexts using explicit<br>
 * {@link BindingProvider} context mutation. To coordinate request processing<br>
 * securely when executed by asynchronous workers running on Java 21 Virtual<br>
 * Threads, data distribution vectors leverage localized synchronizations to<br>
 * prevent state contamination across shared balancer pools.</p>
 *
 * <p>The class exposes the following public API processing vectors:<br>
 * <ul>
 * <li>{@code init(ServiceEndPointDescription serviceDescription)}: Initializes<br>
 * underlying connection ports, builds the target WSDL URL, maps the schema<br>
 * namespace, and binds the web service client to the proxy context layer.</li>
 * <li>{@code handleRequest(Request request, Response response)}: Intercepts,<br>
 * tracks, and appends the pre-bound client proxy instance and logical service<br>
 * ID into the mutable outgoing load balancer response context.</li>
 * </ul>
 *
 * @since CPLS Migration 2.0 (Java 21 / Spring 6.1 Baseline)
 * @see LoadBalancerRequestHandlerAdapter
 * @see BindingProvider
 * @see ConfigurationRetrievalServicePortType
 */
public class SOAPEndpointLoadBalancerHandlerImpl 
    extends LoadBalancerRequestHandlerAdapter {

    static final String CONFIG_RETRIEVAL_MGR_PARAM_NAME = 
        "configRetrievalMgr";

    static final String SERVICE_NAME_PARAM_NAME = 
        "serviceName";

    private ConfigurationRetrievalServicePortType configRetrievalMgr;
    private Logger logger;

    SOAPEndpointLoadBalancerHandlerImpl(
        ServiceEndPointDescription serviceDescription) {
        this.init(serviceDescription);
    }

    public void init(ServiceEndPointDescription serviceDescription) {
        this.logger = Logger.getLogger(this.getClass());
        super.init(serviceDescription.getNames(), null);
        String wsdlLocation = serviceDescription.getURL() + "?wsdl";
        URL url;

        try {
            url = new URL(wsdlLocation);
        } catch (MalformedURLException e) {
            throw new ConfigRuntimeException(
                wsdlLocation + " is not a valid URL", e);
        }

        QName namespace = new QName(
            "http://internal.soap.server.service.config.quantum.get.citi.com", 
            "ConfigurationRetrievalService"
        );

        this.configRetrievalMgr = (new ConfigurationRetrievalService(
            url, namespace)).getConfigurationRetrievalServiceSOAP11PortHttp();

        try {
            if (this.configRetrievalMgr instanceof BindingProvider bp) {
                Map<String, Object> requestContext = bp.getRequestContext();
                String serviceURL = serviceDescription.getURL();

                Objects.requireNonNull(this.logger).info(
                    "Creating loadbalancer and setting binding to end-point[" 
                    + serviceURL + "]"
                );

                requestContext.put(
                    BindingProvider.ENDPOINT_ADDRESS_PROPERTY, 
                    serviceURL
                );
            } else {
                throw new ConfigRuntimeException(
                    "WebService client port does not implement BindingProvider"
                );
            }
        } catch (Exception e) {
            String msg = "Could NOT retrieve request context so we " 
                + "cannot dynamically set web service URL!!";
            Objects.requireNonNull(this.logger).warn(msg, e);
            throw new ConfigRuntimeException(msg, e);
        }
    }

    public synchronized void handleRequest(Request request, Response response) 
        throws RequestCannotBeHandledException {

        this.logger.debug(
            "Returning service binding with name: " + super.ID + " "
        );

        response.addParameter(
            CONFIG_RETRIEVAL_MGR_PARAM_NAME, 
            this.configRetrievalMgr
        );

        response.addParameter(
            SERVICE_NAME_PARAM_NAME, 
            super.ID
        );
    }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)