Im trying to understand this particular issue i'm having. Using Spring OXM here to implement a Soap WS Consumer.
I'm only attaching the relevant information to explain the problem.
LoginWsConfiguration,
@Configuration
public class LoginWsConfiguration {
@Inject
private OnboardingProperties onboardingProperties;
@Bean
Jaxb2Marshaller jaxb2Marshaller() {
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
jaxb2Marshaller
.setPackagesToScan("org.openiam.ws.login.api_3_2_6");
try {
jaxb2Marshaller.afterPropertiesSet();
}
catch (Exception ex) {
throw new BeanCreationException(ex.getMessage(), ex);
}
return jaxb2Marshaller;
}
@Bean
public WebServiceTemplate webServiceTemplate(Jaxb2Marshaller jaxb2Marshaller) {
WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
webServiceTemplate.setMarshaller(jaxb2Marshaller);
webServiceTemplate.setUnmarshaller(jaxb2Marshaller);
webServiceTemplate.setDefaultUri(onboardingProperties.getIAM().getEndpoint().getLogin());
return webServiceTemplate;
}
And the LoginClient client is implemented as,
@Component
public class LoginClient {
private static final Logger log = LoggerFactory.getLogger(IAMLoginClient.class);
@Autowired
private LoginMapper loginMapper;
@Inject
private OnboardingProperties onboardingProperties;
private WebServiceTemplate webServiceTemplate;
@Autowired
public LoginClient(WebServiceTemplate webServiceTemplate) {
this.webServiceTemplate = webServiceTemplate;
}
public LoginClient() {
}
public Optional getLoginByUserId(final String userId) {
ObjectFactory factory = new ObjectFactory();
GetLoginByUser req = factory.createGetLoginByUser();
req.setUserId(userId);
GetLoginByUserResponse resp = (GetLoginByUserResponse)webServiceTemplate.marshalSendAndReceive(req);
if (resp != null && resp.getReturn() != null && resp.getReturn().getStatus() == org.openiam.ws.login.api_3_2_6.ResponseStatus.SUCCESS) {
List<Login> foundLogins = resp.getReturn().getPrincipalLists();
Login foundLogin = foundLogins.stream()
.filter(login -> login.getManagedSysId().equals(Constants.IAM_DEFAULT_MANAGED_SYS_ID))
.findFirst()
.orElse(null);
return Optional.ofNullable((foundLogin != null) ? this.loginMapper.mapIAMLogin(foundLogin) : null);
}
return Optional.empty();
}
For completeness, GetLoginByUser,
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getLoginByUser", propOrder = {
"userId"
})
@XmlRootElement(name = "getLoginByUser")
public class GetLoginByUser {
protected String userId;
/**
* Gets the value of the userId property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getUserId() {
return userId;
}
/**
* Sets the value of the userId property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setUserId(String value) {
this.userId = value;
}
}
GetLoginByUserResponse,
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getLoginByUserResponse", propOrder = {
"_return"
})
@XmlRootElement(name = "getLoginByUserResponse")
public class GetLoginByUserResponse {
@XmlElement(name = "return")
protected LoginListResponse _return;
/**
* Gets the value of the return property.
*
* @return
* possible object is
* {@link LoginListResponse }
*
*/
public LoginListResponse getReturn() {
return _return;
}
/**
* Sets the value of the return property.
*
* @param value
* allowed object is
* {@link LoginListResponse }
*
*/
public void setReturn(LoginListResponse value) {
this._return = value;
}
}
However, when I try to,
@Autowired
private UserClient iamUserClient;
@Autowired
private LoginClient iamLoginClient;
Optional<IAMUser> userFromIAM = iamUserClient.getUserByPrincipal(lowercaseLogin);
IAMUser userIAM = userFromIAM.
orElseThrow(() -> new UsernameNotFoundException("User " + lowercaseLogin + " was not found in IAM"));
if (userIAM.getStatus() != IAMUserStatus.ACTIVE || userIAM.getAccountStatus() != null) {
throw new UserNotActivatedException("User " + lowercaseLogin + " is not active");
}
Optional<IAMLogin> loginFromIAM = iamLoginClient.getLoginByUserId(userIAM.getId());
I get the error,
org.springframework.oxm.UncategorizedMappingException: Unknown JAXB exception; nested exception is javax.xml.bind.JAXBException: class org.openiam.ws.login.api_3_2_6.GetLoginByUser nor any of its super class is known to this context.
at org.springframework.oxm.jaxb.Jaxb2Marshaller.convertJaxbException(Jaxb2Marshaller.java:915)
at org.springframework.oxm.jaxb.Jaxb2Marshaller.marshal(Jaxb2Marshaller.java:684)
at org.springframework.ws.support.MarshallingUtils.marshal(MarshallingUtils.java:81)
at org.springframework.ws.client.core.WebServiceTemplate$2.doWithMessage(WebServiceTemplate.java:399)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:590)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:383)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:373)
at com.orchestral.dsm.onboarding.iam.ws.login.LoginClient.getLoginByUserId(LoginClient.java:77)
at com.orchestral.dsm.onboarding.security.IAMUserDetailsService.loadUserByUsername(IAMUserDetailsService.java:45)
From what I can see it doesn't fail when marshalling in getUserByPrincipal (UserClient) but fails on getLoginByUserId (LoginClient).
This was due to the fact that both,
were conflicting with each other. Having individual
jaxb2Marshallerand passing that toWebServiceTemplatefixed the issue.So LoginWsConfiguration updated to,