How to make requests with auto-generated wsdl in Spring Boot

35 Views Asked by At

I have an integration task with some service. In this case I got some wsdl url, some .jks file and password. Nothing else. I already tested this wsdl endpoints by SoapUI and got success results (can do only with SSL settings [.jks and password]). After that I export whole wsdl from SoapUI and generated classes with plugin:

             <plugin>
                <groupId>com.sun.xml.ws</groupId>
                <artifactId>jaxws-maven-plugin</artifactId>
                <version>4.0.2</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>wsimport</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <wsdlDirectory>${project.basedir}/src/main/resources/</wsdlDirectory>
                    <wsdlFiles>
                        <wsdlFile>exported.wsdl</wsdlFile>
                    </wsdlFiles>
                    <packageName>az.atb.parking.client</packageName>
                    <sourceDestDir>
                        ${project.build.directory}/generated-sources/
                    </sourceDestDir>
                </configuration>
            </plugin>

I now that I need to do requests with my .jks and password.

So my WebServiceClient after generate looks like:

@Component
@WebServiceClient(name = "PP", targetNamespace = "PP", wsdlLocation = "https://PRIVATE_URL:PORT/?wsdl")
public class PP extends Service
{
    private static final URL PP_WSDL_LOCATION;
    private static final WebServiceException PP_EXCEPTION;
    private static final QName PP_QNAME = new QName("PP", "PP");

    static {
        URL url = null;
        WebServiceException e = null;
        try {
            url = new URL("https://PRIVATE_URL:PORT/?wsdl");
        } catch (MalformedURLException ex) {
            e = new WebServiceException(ex);
        }
        PP_WSDL_LOCATION = url;
        PP_EXCEPTION = e;
    }

    public PP() {
        super(__getWsdlLocation(), PP_QNAME);
    }

    public PP(WebServiceFeature... features) {
        super(__getWsdlLocation(), PP_QNAME, features);
    }

    public PP(URL wsdlLocation) {
        super(wsdlLocation, PP_QNAME);
    }

    public PP(URL wsdlLocation, WebServiceFeature... features) {
        super(wsdlLocation, PP_QNAME, features);
    }

    public PP(URL wsdlLocation, QName serviceName) {
        super(wsdlLocation, serviceName);
    }

    public PP(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {
        super(wsdlLocation, serviceName, features);
    }
    
    @WebEndpoint(name = "PPPort")
    public PPPort getPPPort() {
        return super.getPort(new QName("PP", "PPPort"), PPPort.class);
    }

    @WebEndpoint(name = "PPPort")
    public PPPort getPPPort(WebServiceFeature... features) {
        return super.getPort(new QName("PP", "PPPort"), PPPort.class, features);
    }

    private static URL __getWsdlLocation() {
        if (PP_EXCEPTION!= null) {
            throw PP_EXCEPTION;
        }
        return PP_WSDL_LOCATION;
    }

}

So in my @Service I tried to use this Client like:

@Service
public class ParkingClientService {

    private final PPPort client;

    public ParkingClientService(PP ppClient) {
        this.client = ppClient.getPPPort();
    }
    
    // OTHER METHODS
}

But it gives me errors like (after starting spring application):

1. org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'PP' defined in file [C:\Users\USERNAME\IdeaProjects\parking-api\target\classes\az\atb\parking\client\PP.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [az.atb.parking.client.PP]: Constructor threw exception; nested exception is jakarta.xml.ws.WebServiceException: Failed to access the WSDL at: https://PRIVATE_URL:PORT/?wsdl. It failed with: 
    PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.

2. Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [az.atb.parking.client.PP]: Constructor threw exception; nested exception is jakarta.xml.ws.WebServiceException: Failed to access the WSDL at: https://PRIVATE_URL:PORT/?wsdl. It failed with: 
    PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.

3. Caused by: jakarta.xml.ws.WebServiceException: Failed to access the WSDL at: https://PRIVATE_URL:PORT/?wsdl. It failed with: 
    PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.

4. Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

5. Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

6. Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

I tried different versions to put keystore file and password, but they not helps. ChatGPT can't help me with this question).

I tried to add:

  1. Adding truest manager:
private PPPort configurePort(PPPort port) {
    try {
        SSLContext sslContext = SSLContext.getInstance("TLS");

        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        String keystoreLocation = "C:\\Users\\USERNAME\\IdeaProjects\\parking-api\\src\\main\\resources\\keystore\\parking.jks";
        try (FileInputStream keyStoreFile = new FileInputStream(keystoreLocation)) {
            keyStore.load(keyStoreFile, "PASSWORD".toCharArray());
        }

        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, "PASSWORD".toCharArray());

        // Create a permissive TrustManager that accepts all certificates
        TrustManager[] trustManagers = {new PermissiveTrustManager()};

        sslContext.init(keyManagerFactory.getKeyManagers(), trustManagers, null);

        ((BindingProvider) port).getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", sslContext.getSocketFactory());

    } catch (Exception e) {
        e.printStackTrace(); // Handle exception appropriately in your code
    }

    return port;
}

sslContext.init(keyManagerFactory.getKeyManagers(), trustManagers, null);

sslContext.getDefaultSSLParameters().setEndpointIdentificationAlgorithm("HTTPS");

2.

System.setProperty("javax.net.ssl.keyStore", "mypath/parking.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "PASSWORD");

How can I do my requests and where and how I need to put my file.jks and password?

0

There are 0 best solutions below