Skip to content

Commit

Permalink
First Version of working Auto Endpoint configuration based on WebServ…
Browse files Browse the repository at this point in the history
…iceAutoDetection.
  • Loading branch information
jonashackt committed Nov 7, 2016
1 parent 21c147f commit 3b3135e
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@
import java.util.Map;

import javax.servlet.Filter;
import javax.xml.ws.Endpoint;
import javax.xml.ws.Service;

import de.codecentric.cxf.autodetection.WebServiceAutoDetector;
import de.codecentric.cxf.common.BootStarterCxfException;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
Expand Down Expand Up @@ -39,6 +44,8 @@ public class CxfAutoConfiguration {

@Value("${cxf.servicelist.title:CXF SpringBoot Starter - service list}")
private String serviceListTitle;

private static final String PUBLISH_URL_ENDING = "/WeatherService_1.0";

@Bean
public ServletRegistrationBean cxfDispatcherServlet() {
Expand All @@ -58,14 +65,46 @@ public ServletRegistrationBean cxfDispatcherServlet() {
public SpringBus springBus() {
return new SpringBus();
}


@Bean
public Object seiImplentation() throws BootStarterCxfException {
Class serviceEndpointInterface = WebServiceAutoDetector.searchServiceEndpointInterface();
return WebServiceAutoDetector.searchAndInstantiateSeiImplementation(serviceEndpointInterface);
}

@Bean
public Endpoint endpoint() throws BootStarterCxfException {
EndpointImpl endpoint = new EndpointImpl(springBus(), seiImplentation());
// CXF JAX-WS implementation relies on the correct ServiceName as QName-Object with
// the name-Attribute´s text <wsdl:service name="Weather"> and the targetNamespace
// "http://www.codecentric.de/namespace/weatherservice/"
// Also the WSDLLocation must be set
endpoint.setServiceName(webServiceClient().getServiceName());
endpoint.setWsdlLocation(webServiceClient().getWSDLDocumentLocation().toString());
//TODO: Endpoint URL aus WSDL auslesen!
endpoint.publish(PUBLISH_URL_ENDING);
return endpoint;
}

@Bean
public Service webServiceClient() throws BootStarterCxfException {
// Needed for correct ServiceName & WSDLLocation to publish contract first incl. original WSDL
return WebServiceAutoDetector.searchAndInstantiateWebServiceClient();
}

/**
* @return the base-URL, where the WebServices are configured (eihter via property or default-value)
*/
public String getBaseUrl() {
return baseUrl;
}

/**
* @return the concrete Service URL-ending, where the WebService is configured according to your WSDL
*/
public String getServiceUrlEnding() {
return PUBLISH_URL_ENDING;
}

// Register Filter for Correlating Logmessages from the same Service-Consumer
@Bean
Expand Down
3 changes: 1 addition & 2 deletions src/test/java/de/codecentric/cxf/TestApplication.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package de.codecentric.cxf;

import de.codecentric.cxf.xmlvalidation.TestServiceXmlErrorConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
Expand All @@ -10,7 +9,7 @@
@EnableAutoConfiguration
@Import({
TestConfiguration.class,
TestServiceXmlErrorConfiguration.class
TestServiceIntegrationTestConfiguration.class
})
public class TestApplication {

Expand Down
29 changes: 0 additions & 29 deletions src/test/java/de/codecentric/cxf/TestConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,6 @@
@Configuration
public class TestConfiguration {

public static final String PUBLISH_URL_ENDING = "/WeatherService_1.0";

@Autowired
public SpringBus springBus;

@Bean
public WeatherService weatherService() {
return new TestServiceEndpoint();
}

@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus, weatherService());
// CXF JAX-WS implementation relies on the correct ServiceName as QName-Object with
// the name-Attribute´s text <wsdl:service name="Weather"> and the targetNamespace
// "http://www.codecentric.de/namespace/weatherservice/"
// Also the WSDLLocation must be set
endpoint.setServiceName(weather().getServiceName());
endpoint.setWsdlLocation(weather().getWSDLDocumentLocation().toString());
endpoint.publish(PUBLISH_URL_ENDING);
return endpoint;
}

@Bean
public Weather weather() {
// Needed for correct ServiceName & WSDLLocation to publish contract first incl. original WSDL
return new Weather();
}

// Activating XML-Schema validation with custom Fault
@Bean
public CustomFaultBuilder weatherFaultBuilder() {
Expand Down
75 changes: 71 additions & 4 deletions src/test/java/de/codecentric/cxf/TestServiceEndpoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,99 @@

import de.codecentric.namespace.weatherservice.WeatherException;
import de.codecentric.namespace.weatherservice.WeatherService;
import de.codecentric.namespace.weatherservice.datatypes.ArrayOfForecast;
import de.codecentric.namespace.weatherservice.datatypes.Forecast;
import de.codecentric.namespace.weatherservice.datatypes.POP;
import de.codecentric.namespace.weatherservice.datatypes.Temp;
import de.codecentric.namespace.weatherservice.general.ForecastRequest;
import de.codecentric.namespace.weatherservice.general.ForecastReturn;
import de.codecentric.namespace.weatherservice.general.WeatherInformationReturn;
import de.codecentric.namespace.weatherservice.general.WeatherReturn;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.time.ZonedDateTime;
import java.util.GregorianCalendar;

public class TestServiceEndpoint implements WeatherService {

private static de.codecentric.namespace.weatherservice.general.ObjectFactory objectFactoryGeneral = new de.codecentric.namespace.weatherservice.general.ObjectFactory();
private static de.codecentric.namespace.weatherservice.datatypes.ObjectFactory objectFactoryDatatypes = new de.codecentric.namespace.weatherservice.datatypes.ObjectFactory();


@Override
public WeatherInformationReturn getWeatherInformation(String zip)
throws WeatherException {
// TODO Auto-generated method stub
System.out.println("Doing something useful :)");
return null;
}

@Override
public ForecastReturn getCityForecastByZIP(ForecastRequest forecastRequest)
throws WeatherException {
// TODO Auto-generated method stub
return null;

ForecastReturn forecastReturn = objectFactoryGeneral.createForecastReturn();
forecastReturn.setCity("Weimar");
//TODO: Map more fields
forecastReturn.setState("Deutschland");
forecastReturn.setSuccess(true);
forecastReturn.setWeatherStationCity("Weimar");

forecastReturn.setForecastResult(generateForecastResult(forecastReturn.getCity()));

return forecastReturn;
}

@Override
public WeatherReturn getCityWeatherByZIP(ForecastRequest forecastRequest)
throws WeatherException {
// TODO Auto-generated method stub
System.out.println("Doing something useful :)");
return null;
}

private static ArrayOfForecast generateForecastResult(String city) {
ArrayOfForecast forecastContainer = objectFactoryDatatypes.createArrayOfForecast();
forecastContainer.getForecast().add(generateForecast(city));
return forecastContainer;
}


private static Forecast generateForecast(String city) {
Forecast forecast = objectFactoryDatatypes.createForecast();
forecast.setDate(generateCalendarFromNow());
forecast.setDesciption("Vorhersage für " + city);
forecast.setTemperatures(generateTemp());
forecast.setProbabilityOfPrecipiation(generateRegenwahrscheinlichkeit());
return forecast;
}


private static POP generateRegenwahrscheinlichkeit() {
POP pop = objectFactoryDatatypes.createPOP();
pop.setDaytime("22%");
pop.setNighttime("5000%");
return pop;
}


private static Temp generateTemp() {
Temp temp = objectFactoryDatatypes.createTemp();
temp.setDaytimeHigh("90°");
temp.setMorningLow("0°");
return temp;
}


private static XMLGregorianCalendar generateCalendarFromNow() {
GregorianCalendar gregCal = GregorianCalendar.from(ZonedDateTime.now());
XMLGregorianCalendar xmlGregCal = null;
try {
xmlGregCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(gregCal);
} catch (DatatypeConfigurationException exception) {
//LOG.calenderMappingNotWorking(exception);
}
return xmlGregCal;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package de.codecentric.cxf.xmlvalidation;
package de.codecentric.cxf;

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -13,7 +14,18 @@

@Configuration
@Import(TestConfiguration.class)
public class TestServiceXmlErrorConfiguration {
public class TestServiceIntegrationTestConfiguration {

/*
* CXF JaxWs Client
*/
@Bean
public WeatherService weatherServiceClient() {
JaxWsProxyFactoryBean jaxWsFactory = new JaxWsProxyFactoryBean();
jaxWsFactory.setServiceClass(WeatherService.class);
jaxWsFactory.setAddress(buildUrl());
return (WeatherService) jaxWsFactory.create();
}

@Bean
public SoapRawClient soapRawClient() throws BootStarterCxfException {
Expand All @@ -23,7 +35,7 @@ public SoapRawClient soapRawClient() throws BootStarterCxfException {

private String buildUrl() {
// return something like http://localhost:8084/soap-api/WeatherSoapService
return "http://localhost:8087" + cxfAutoConfiguration.getBaseUrl() + TestConfiguration.PUBLISH_URL_ENDING;
return "http://localhost:8087" + cxfAutoConfiguration.getBaseUrl() + cxfAutoConfiguration.getServiceUrlEnding();
}

@Autowired
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,5 @@ public void isWebServiceClientSuccessfullyFoundAndInstantiated() throws BootStar
QName serviceNameQName = webServiceClient.getServiceName();
assertThat(serviceNameQName.getLocalPart(), is(equalTo("Weather")));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package de.codecentric.cxf.endpoint;


import de.codecentric.cxf.TestApplication;
import de.codecentric.cxf.common.BootStarterCxfException;
import de.codecentric.cxf.common.XmlUtils;
import de.codecentric.namespace.weatherservice.WeatherException;
import de.codecentric.namespace.weatherservice.WeatherService;
import de.codecentric.namespace.weatherservice.general.ForecastReturn;
import de.codecentric.namespace.weatherservice.general.GetCityForecastByZIP;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.Resource;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

@RunWith(SpringRunner.class)
@SpringBootTest(
classes = TestApplication.class,
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
properties = { "server.port:8087" }
)
public class WeatherServiceEndpointIntegrationTest {

@Autowired
private WeatherService weatherServiceClient;

@Value(value="classpath:requests/GetCityForecastByZIPTest.xml")
private Resource GetCityForecastByZIPTestXml;

@Test
public void isEndpointCorrectlyAutoDetectedAndConfigured() throws WeatherException, BootStarterCxfException, IOException {
// Given
GetCityForecastByZIP getCityForecastByZIP = XmlUtils.readSoapMessageFromStreamAndUnmarshallBody2Object(
GetCityForecastByZIPTestXml.getInputStream(), GetCityForecastByZIP.class);

// When
ForecastReturn forecastReturn = weatherServiceClient.getCityForecastByZIP(getCityForecastByZIP.getForecastRequest());

// Then
assertNotNull(forecastReturn);
assertEquals("Weimar", forecastReturn.getCity());
assertEquals("22%", forecastReturn.getForecastResult().getForecast().get(0).getProbabilityOfPrecipiation().getDaytime());
}
}

0 comments on commit 3b3135e

Please sign in to comment.