Reyfren
Reyfren

Reputation: 61

Publish JAXWS Endpoint in the same port than Spring boot

I am having issues with the implementation of JAXWS for expose the endpoint that will consume the soap message in the same port that API rest or default spring boot port.

I am using this :

Plugin for generated code from wsdl : org.codehaus.mojo>jaxws-maven-plugin-2.6

Java 11 + Spring boot 2.7.13 + jakarta.xml.ws-api-4.0.1

package net.gencat.salut.sivec.external.cases.config;

import jakarta.xml.ws.Endpoint;
import lombok.extern.slf4j.Slf4j;
import net.gencat.salut.sivec.external.cases.argo.CarregaImpl;
import net.gencat.salut.sivec.external.cases.notification.NotificationSoapImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;

@Configuration
@Slf4j
public class WebServiceConfig {


 @Bean
  public CarregaImpl carregaImpl() {        
    return new CarregaImpl();
    
 }


 @Bean
 public Endpoint publishEndpoint(final SoapProperties soapProperties,CarregaImpl carregaImpl) 
  {
    log.info("Endpoint argo published: {}",soapProperties.getUri());
    return Endpoint.publish(soapProperties.getUri(), carregaImpl);
    
  }


}

The value of getURi is this: http://localhost:8989/ws/

This is my log:

enter image description here

Solution 1 what I want

I want to know how i can to configure JAXWS Endpoint for use the same port than Spring boot if with the solution or implementation what I did , I can't use the same port because spring boot shows in runtime "port in use"

enter image description here

Solution 2: If I configure two different ports, how I have configured the endpoint to http://localhost:8989 when I deploy this microservice in Openshift and see all the port on listen

For the port 8989, it shows "localhost:8989" instead of ":::8989" what is how is shown the default spring boot port, then I have a redirect issue because unable to resolve localhost:8989 in cloud

Someone can help me?. Please any recomendation is welcome but one example would be appreciated

Upvotes: 0

Views: 143

Answers (1)

grekier
grekier

Reputation: 3726

I have an app running both rest and SOAP server on the same port. I'm using a different plugin though:

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>jaxb2-maven-plugin</artifactId>
                <version>2.5.0</version>
                <executions>
                    <execution>
                        <id>xjc</id>
                        <goals>
                            <goal>xjc</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <sources>
                        <source>${project.basedir}/src/main/resources/static</source>
                    </sources>
                </configuration>
            </plugin>

in my static folder, I have my xsd files.

After that, my configuration class is a bit different:

@EnableWs
@Configuration
class WebServiceConfig : WsConfigurerAdapter() {

    // Global URL registration
    @Bean
    fun messageDispatcherServlet(applicationContext: ApplicationContext): ServletRegistrationBean<MessageDispatcherServlet> {
        val servlet = MessageDispatcherServlet()
        servlet.setApplicationContext(applicationContext)
        servlet.isTransformWsdlLocations = true
        return ServletRegistrationBean(servlet, "/webservices/*", "/ws/*")
    }

    @Bean
    fun schema1(): XsdSchema {
        return SimpleXsdSchema(ClassPathResource("static/schema1.xsd"))
    }

    @Bean(name = ["Schema1Service"])
    fun schema1Definition(accountBalancerSchema: XsdSchema): Wsdl11Definition {
        val wsdl11Definition = NoRequestSuffixWsdl11Definition()
        wsdl11Definition.setPortTypeName("Schema1Definition")
        wsdl11Definition.setLocationUri("/webservices")
        wsdl11Definition.setTargetNamespace(Schema1Endpoint.NAMESPACE_URI)
        wsdl11Definition.setSchema(schema1)
        return wsdl11Definition
    }

    // ... with new beans for each xsd
}

This is Kotlin code but the concept is the same in Java.

Then, the endpoint looks like:

@Endpoint
class Schema1Endpoint(
// All autowired necessary
) {
    companion object {
        const val NAMESPACE_URI = "https://whatever.your.namespace.is"
    }

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "matching def from xsd")
    @ResponsePayload
    fun function1(@RequestPayload request: Function1Request): Function1Response { // Request & Response are auto generated
        // do what you need to here
        val response = Function1Response()
        // set what you need on the response
        return response
    }

    // All other functions...
}

I hope this helps.

UPDATE1: Adding the NoRequestSuffixWsdl11Definition:

package no.schibsted.dib.online.config.utils

import org.springframework.beans.factory.InitializingBean
import org.springframework.util.StringUtils
import org.springframework.ws.wsdl.wsdl11.ProviderBasedWsdl4jDefinition
import org.springframework.ws.wsdl.wsdl11.Wsdl11Definition
import org.springframework.ws.wsdl.wsdl11.provider.InliningXsdSchemaTypesProvider
import org.springframework.ws.wsdl.wsdl11.provider.SoapProvider
import org.springframework.ws.wsdl.wsdl11.provider.SuffixBasedMessagesProvider
import org.springframework.ws.wsdl.wsdl11.provider.SuffixBasedPortTypesProvider
import org.springframework.xml.xsd.XsdSchema
import javax.xml.transform.Source

class NoRequestSuffixWsdl11Definition : Wsdl11Definition, InitializingBean {
    private val typesProvider = InliningXsdSchemaTypesProvider()

    private val messagesProvider: SuffixBasedMessagesProvider = NoRequestSuffixBasedMessagesProvider()

    private val portTypesProvider: SuffixBasedPortTypesProvider = NoRequestSuffixBasedPortTypesProvider()

    private val soapProvider = SoapProvider()

    private val delegate = ProviderBasedWsdl4jDefinition()

    init {
        delegate.typesProvider = typesProvider
        delegate.messagesProvider = messagesProvider
        delegate.portTypesProvider = portTypesProvider
        delegate.bindingsProvider = soapProvider
        delegate.servicesProvider = soapProvider
    }

    fun setTargetNamespace(targetNamespace: String?) {
        delegate.targetNamespace = targetNamespace
    }

    fun setSchema(schema: XsdSchema?) {
        typesProvider.setSchema(schema)
    }

    fun setPortTypeName(portTypeName: String?) {
        portTypesProvider.portTypeName = portTypeName
    }

    fun setLocationUri(locationUri: String?) {
        soapProvider.setLocationUri(locationUri)
    }

    @Throws(Exception::class)
    override fun afterPropertiesSet() {
        if (!StringUtils.hasText(delegate.targetNamespace) && typesProvider.schemaCollection != null && typesProvider.schemaCollection.xsdSchemas.size > 0) {
            val schema = typesProvider.schemaCollection.xsdSchemas[0]
            setTargetNamespace(schema.targetNamespace)
        }
        if (StringUtils.hasText(portTypesProvider.portTypeName)) {
            soapProvider.setServiceName(portTypesProvider.portTypeName + "Service")
        }
        delegate.afterPropertiesSet()
    }

    override fun getSource(): Source? {
        return delegate.source
    }
}

Upvotes: 0

Related Questions