Unable to unit test a class which calls an API - unit-testing

I have the following two classes -
Service class
#Service
public class ProfileInfoCacheService {
public ProfileInfoResponse getProfileInfo(String uuid) {
ProfileInfoResponse response = getUserInfoFromIdentity(uuid);
return response;
}
public ProfileInfoResponse getUserInfoFromIdentity(String identity) {
LinkedHashMap<String, List<UserInfo>> profileInfo = userService.getUserInfoFromIdentity(identityList);
return profcache.getProfileInfo();
}
And component
#Component
public class UserInfoServiceImpl implements UserInfoService {
#SuppressWarnings("unchecked")
#Override
public LinkedHashMap<String, List<UserInfo>> getUserInfoFromIdentity(List<String> identityList) {
//Calls an API and returns data in LinkedHashMap.
}
Now, here is my test case file. Please bear with me as I am still new at it.
package com.citruspay.prepaid;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
//class file imports
import org.mockito.runners.MockitoJUnitRunner;
#RunWith(MockitoJUnitRunner.class)
public class ProfileInfoCacheServiceTest {
private PrepaidAccount account;
private ProfileInfoCacheService pics;
#Before
public void setUp() throws Exception {
account = new PrepaidAccount("8588844251");
//pics = new ProfileInfoCacheService();
ProfileInfoCacheService pics = mock(ProfileInfoCacheService.class);
}
#Test
public void testConstructor() {
assertEquals("8588888888", account.owner());
}
#Test
public void testNumber() throws Exception {
ProfileInfoResponse response = pics.getProfileInfo("7266704751953077361"); //pics is null here
assertEquals("", response.getEmail() );
assertEquals("8588888888", response.getMobile() );
}
}
The response of getProfileInfo() call is expected to be in this format -
{
"email": "some.email#something.in",
"mobile": "8888888888",
}
Every mobile/email pair has a number (like 7266704751953077361), using which, when the API is called, it returns the same.
However, I am getting a Null Pointer exception, due to pics being null where I call pics.getProfileInfo("7266704751953077361").
Please help me correct my mistake here.
Update
Upon changing mock() to new class call, I get the ProfileInfoCacheService object but then on moving the debug to the last line of the setup() method, getting the following -
java.lang.ExceptionInInitializerError
at org.slf4j.impl.StaticLoggerBinder.<init>(StaticLoggerBinder.java:72)
at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:45)
at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124)
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:412)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)
at com.citruspay.prepaid.common.user.beans.ProfileInfoCacheService.<init>(ProfileInfoCacheService.java:42)
at com.citruspay.prepaid.ProfileInfoCacheServiceTest.setUp(ProfileInfoCacheServiceTest.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.IllegalStateException: Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the class path, preempting StackOverflowError. See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more details.
at org.slf4j.impl.Log4jLoggerFactory.<clinit>(Log4jLoggerFactory.java:54)
... 33 more
Update 2
Adding more details of ProfileInfoCacheService class -
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.exceptions.JedisException;
import com.aerospike.client.AerospikeException;
import com.aerospike.client.Key;
import com.citruspay.prepaid.common.cache.dao.ProfileInfoCacheDao;
import com.citruspay.prepaid.common.cache.entity.ProfileInfoCache;
import com.citruspay.prepaid.common.cache.factory.DaoCacheFactory;
import com.citruspay.prepaid.common.user.process.UserInfoServiceImpl;
import com.spikeify.ResultSet;
#Service
public class ProfileInfoCacheService {
#Autowired
UserInfoServiceImpl userService;
#Autowired
DaoCacheFactory<ProfileInfoCacheDao> daoCacheFactory;
#PostConstruct
public void init() {
ProfileInfoCacheDao profileInfoCacheDao = daoCacheFactory.getDaoForRead(ProfileInfoCacheDao.class);
profileInfoCacheDao.init();
}
Logger logger = LoggerFactory.getLogger(ProfileInfoCacheService.class);

Related

How to apply Interceptor(Schema validation) to a specific endpoint among multiple services deployed on server

I have two soap end points(soap services) deployed in one server. When i override the following interceptor, it is applying to both services. How to enable/disable the interceptor specific to one service. Kindly help
The interceptor code as follows.
#Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
PayloadValidatingInterceptor validatingInterceptor = new PayloadValidatingInterceptor();
validatingInterceptor.setValidateRequest(true);
validatingInterceptor.setValidateResponse(true);
validatingInterceptor.setXsdSchemaCollection(LogAnalyzerFile());
interceptors.add(validatingInterceptor);
}
Note: Its an spring boot project, using annotations.
I
package com.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.config.annotation.EnableWs;
import org.springframework.ws.config.annotation.WsConfigurationSupport;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.SmartEndpointInterceptor;
import org.springframework.ws.server.endpoint.MethodEndpoint;
import org.springframework.ws.soap.SoapBody;
import org.springframework.ws.soap.SoapHeader;
import org.springframework.ws.soap.SoapMessage;
import org.springframework.ws.transport.http.MessageDispatcherServlet;
import org.springframework.ws.wsdl.wsdl11.SimpleWsdl11Definition;
import org.springframework.ws.wsdl.wsdl11.Wsdl11Definition;
import org.springframework.xml.xsd.SimpleXsdSchema;
import org.springframework.xml.xsd.XsdSchema;
import org.xml.sax.SAXException;
import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMResult;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
#EnableWs
#Configuration
public class TestConfig extends WsConfigurationSupport implements SmartEndpointInterceptor {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
#Bean(name="testlog")
public ServletRegistrationBean testlog(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(servlet, "/File/*");
servletRegistrationBean.setName("Log");
return servletRegistrationBean;
}
#Bean(name = "testFile")
public Wsdl11Definition testFile()
{
SimpleWsdl11Definition wsdl11Definition = new SimpleWsdl11Definition();
wsdl11Definition.setWsdl(new ClassPathResource("test.wsdl"));
logger.info("test.wsdl:");
return wsdl11Definition;
}
#Bean(name = "UploadLogFile")
public XsdSchema UploadLogFile() {
return new SimpleXsdSchema(new ClassPathResource("1.xsd"));
}
#Bean(name = "ErrorInfo")
public XsdSchema ErrorInfo() {
return new SimpleXsdSchema(new ClassPathResource("2.xsd"));
}
public Resource[] getSchemas() {
List<Resource> schemaResources = new ArrayList<>();
schemaResources.add(new ClassPathResource("1.xsd"));
schemaResources.add(new ClassPathResource("2.xsd"));
return schemaResources.toArray(new Resource[schemaResources.size()]);
}
#Override
public boolean shouldIntercept(MessageContext messageContext, Object endpoint) {
if (endpoint instanceof MethodEndpoint) {
MethodEndpoint methodEndpoint = (MethodEndpoint)endpoint;
return methodEndpoint.getMethod().getDeclaringClass() == YourEndpoint.class;
}
return false;
}
private Boolean validateSchema(Source source_, MessageContext messageContext) throws Exception {
boolean errorFlag = true;
SchemaFactory _schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema _schema = _schemaFactory.newSchema(getSchemas()[0].getFile());
Validator _validator = _schema.newValidator();
DOMResult _result = new DOMResult();
try {
_validator.validate(source_, _result);
} catch (SAXException _exception) {
errorFlag = false;
SoapMessage response = (SoapMessage) messageContext.getResponse();
String faultString = StringUtils.hasLength(_exception.getMessage()) ? _exception.getMessage() : _exception.toString();
SoapBody body = response.getSoapBody();
body.addServerOrReceiverFault(faultString, Locale.US);
_exception.printStackTrace();
}
return errorFlag;
}
#Override
public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
WebServiceMessage webServiceMessageRequest = messageContext.getRequest();
SoapMessage soapMessage = (SoapMessage) webServiceMessageRequest;
SoapHeader soapHeader = soapMessage.getSoapHeader();
Source bodySource = soapMessage.getSoapBody().getPayloadSource();
return validateSchema(bodySource,messageContext);
}
#Override
public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
return true;
}
#Override
public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
return false;
}
#Override
public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) throws Exception {
}
}

Mockito not injecting repository mocks

I am trying to write tests for spring boot application which has repositories.
My test class looks like this:
package se.volvo.spp.controller.spp;
import com.datastax.driver.core.utils.UUIDs;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.*;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.data.cassandra.repository.MapId;
import org.springframework.data.cassandra.repository.support.BasicMapId;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import se.volvo.spp.BaseTest;
import se.volvo.spp.config.JacksonConfig;
import se.volvo.spp.dao.cassandra.*;
import se.volvo.spp.dto.ServiceAgentDTO;
import se.volvo.spp.exception.NotFoundException;
import se.volvo.spp.repository.AssignmentRepository;
import se.volvo.spp.repository.ServiceAgentRepository;
import se.volvo.spp.service.impl.ServiceAgentService;
import javax.inject.Inject;
import java.util.*;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
public class ServiceAgentControllerTest extends BaseTest {
#Autowired
private MockMvc mockMvc;
#Mock
ServiceProviderDAO serviceProviderDAO;
#Mock
ServiceTypeDAO serviceTypeDAO;
#Mock
ServiceDefinitionDAO serviceDefinitionDAO;
#Mock
ServiceAgentDAO serviceAgentDAO;
#Mock
AssignmentDAO assignmentDAO;
#Mock
ServiceAgentRepository serviceAgentRepository;
#Mock
AssignmentRepository assignmentRepository;
#InjectMocks
ServiceAgentService serviceAgentService;
#Before
public void setUp() {
serviceAgentDAO.setId(UUID.fromString("e5cec1dc-422b-11e8-842f-0ed5f89f718b"));
serviceAgentDAO.setContactEmail("joe.smith#arwe.com");
serviceAgentDAO.setContactTelephone("0735333333");
serviceAgentDAO.setEnabled(true);
serviceAgentDAO.setFirstNames("Joe");
serviceAgentDAO.setLastName("Smith");
serviceAgentDAO.setServiceDefinitionIds(Arrays.asList(UUID.fromString("9a9cb34a-4221-11e8-842f-0ed5f89f718b")));
assignmentDAO.setId(UUID.fromString("69f7cd9c-423f-11e8-842f-0ed5f89f718b"));
assignmentDAO.setCustomerId(UUID.fromString("7b479d52-423f-11e8-842f-0ed5f89f718b"));
assignmentDAO.setCustomerName("John Gill");
assignmentDAO.setServiceAgentId(UUID.fromString("e5cec1dc-422b-11e8-842f-0ed5f89f718b"));
assignmentDAO.setServiceDefinitionId(UUID.fromString("9a9cb34a-4221-11e8-842f-0ed5f89f718b"));
assignmentDAO.setServiceSlotId(UUID.fromString("a7ff6543-4236-11e8-8706-313df4405fc7"));
assignmentDAO.setVehicle("WIN898987686");
/*when(serviceAgentRepository.findOne(BasicMapId.id("id", Mockito.any(UUID.class)))).thenAnswer(new Answer() {
#Override
public ServiceAgentDAO answer(InvocationOnMock invocationOnMock) throws Throwable {
System.out.println("ARGUMENT IS OUTSIDE :: "+(String)invocationOnMock.getArguments()[0]);
if(((String)invocationOnMock.getArguments()[0]).equals(UUID.fromString("e5cec1dc-422b-11e8-842f-0ed5f89f718b"))) {
System.out.println("ARGUMENT IS :: "+invocationOnMock.getArguments()[0]);
return serviceAgentDAO;
}
else
throw new NotFoundException("The Service Agent ID does not exist!");
}
}
);*/
//when(serviceAgentRepository.findOne(BasicMapId.id("id", AdditionalMatchers.not(Matchers.eq(UUID.fromString("e5cec1dc-422b-11e8-842f-0ed5f89f718b")))))).thenThrow (new NotFoundException("The ServiceAgent with that ID does not exist!"));
when(serviceAgentRepository.findOne(BasicMapId.id("id", UUID.class))).thenReturn (serviceAgentDAO);
List<AssignmentDAO> assignmentDAOList = Arrays.asList(assignmentDAO);
when(assignmentRepository.findByServiceAgentId(UUID.fromString("e5cec1dc-422b-11e8-842f-0ed5f89f718b"))).thenReturn(assignmentDAOList);
assignmentDAO.setServiceAgentId(null);
when(assignmentRepository.save(Mockito.any(AssignmentDAO.class))).thenReturn(assignmentDAO);
serviceAgentDAO.setEnabled(false);
when(serviceAgentRepository.save(Mockito.any(ServiceAgentDAO.class))).thenReturn(serviceAgentDAO);
}
#Test
public void testServiceAgentNotFound() throws Exception {
ObjectMapper objectMapper = JacksonConfig.createMapper();
ServiceAgentDTO serviceAgentDTO = new ServiceAgentDTO();
serviceAgentDTO.setEnabled(false);
this.mockMvc.perform(patch("/serviceagent/" + UUIDs.timeBased())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(serviceAgentDTO))).andDo(print())
.andExpect(status().isNotFound());
}
#Test
public void testServiceAgentIDNotAllowedInRequest() throws Exception {
ObjectMapper objectMapper = JacksonConfig.createMapper();
ServiceAgentDTO serviceAgentDTO = new ServiceAgentDTO();
serviceAgentDTO.setId(UUIDs.timeBased());
serviceAgentDTO.setEnabled(false);
this.mockMvc.perform(patch("/serviceagent/" + UUIDs.timeBased())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(serviceAgentDTO))).andDo(print())
.andExpect(status().isBadRequest());
}
/*
test to verify if the agent is disabled, then the agent is removed on his assignments as well
*/
#Test
public void testServiceAgentDisabledFromEnabled() throws Exception {
ObjectMapper objectMapper = JacksonConfig.createMapper();
// add a service provider
serviceProviderDAO.setId(UUID.fromString("8890e560-4170-11e8-a465-3f3e0c8fed10"));
serviceProviderDAO.setContactAddress("Torsgatan 190");
serviceProviderDAO.setContactTelephone("073q12345678");
serviceProviderDAO.setEnabled(true);
serviceProviderDAO.setName("Cleany Car");
// add a service type
serviceTypeDAO.setId(UUID.fromString("e3e0c006-4220-11e8-842f-0ed5f89f718b"));
serviceTypeDAO.setEnabled(true);
serviceTypeDAO.setName("Refuel Benzene 95");
serviceTypeDAO.setParentServiceTypeId(UUID.fromString("c1ecdf7a-4220-11e8-842f-0ed5f89f718b"));
serviceTypeDAO.setScopes(Arrays.asList("UNLOCK", "LOCK"));
// add service definition
serviceDefinitionDAO.setId(UUID.fromString("9a9cb34a-4221-11e8-842f-0ed5f89f718b"));
serviceDefinitionDAO.setEnabled(true);
serviceDefinitionDAO.setGeographicAvailability(null);
serviceDefinitionDAO.setLeadTimesInHours(24);
serviceDefinitionDAO.setMaxAdvanceTimeInDays(7);
Map<Integer, String> operatingWeekMap = new HashMap<>();
operatingWeekMap.put(1, "10:00&17:00");
operatingWeekMap.put(2, "09:00&17:00");
operatingWeekMap.put(3, "09:00&17:00");
operatingWeekMap.put(4, "09:00&17:00");
operatingWeekMap.put(5, "09:00&17:00");
operatingWeekMap.put(6, "11:00&17:00");
operatingWeekMap.put(7, "09:00&17:00");
serviceDefinitionDAO.setOperatingWeek(operatingWeekMap);
serviceDefinitionDAO.setServiceProviderId(UUID.fromString("8890e560-4170-11e8-a465-3f3e0c8fed10"));
serviceDefinitionDAO.setServiceSlotDurationInMinutes(60);
serviceDefinitionDAO.setServiceTypeId(UUID.fromString("e3e0c006-4220-11e8-842f-0ed5f89f718b"));
serviceDefinitionDAO.setTimeZoneId("Europe/London");
// we do not populate service slot as of now, since we just need to disable agent!
ServiceAgentDTO serviceAgentDTO = new ServiceAgentDTO();
serviceAgentDTO.setEnabled(false);
this.mockMvc.perform(patch("/serviceagent/" + UUID.fromString("e5cec1dc-422b-11e8-842f-0ed5f89f718b"))
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(serviceAgentDTO))).andDo(print())
.andExpect(status().isOk());
}
}
The ServiceAgentService class has the constructor injection already for the repositories.
For some reason my mocked repositories in the setup() method do not take effect.
Also, the BaseTest class looks like below
package se.volvo.spp;
import org.junit.Ignore;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = Application.class)
#AutoConfigureMockMvc
#ActiveProfiles("dev")
#Ignore
public class BaseTest {
}
Any help is highly appreciated!

Asynchronous JAX-WS webservice using apache CXF and WS-Adressing, property JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY not initiated

I've problem with initiation of JAXWSProperties in MessageContext of example webservice described on following blog
There is the helper class initiating HeaderList object in getHeaders() method:
import com.sun.xml.internal.ws.api.SOAPVersion;
import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
import com.sun.xml.internal.ws.api.message.HeaderList;
import com.sun.xml.internal.ws.api.message.Headers;
import com.sun.xml.internal.ws.developer.JAXWSProperties;
import com.sun.xml.internal.ws.developer.WSBindingProvider;
import javax.xml.ws.EndpointReference;
import javax.xml.ws.Service;
import javax.xml.ws.WebServiceContext;
public final class CorrelationHelper<S extends Service> {
private WebServiceContext wsc;
private S service;
public CorrelationHelper(S service, WebServiceContext wsc) {
this.service = service;
this.wsc = wsc;
}
private HeaderList getHeaders() {
return (HeaderList)wsc.getMessageContext().get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY);
}
public <P> P getCorrelatedPort(Class<P> portType) {
P port = service.getPort(getReplyTo(), portType);
((WSBindingProvider)port).setOutboundHeaders(Headers.create(AddressingVersion.W3C.relatesToTag,
getMessageId()));
return port;
}
private EndpointReference getReplyTo() {
return getHeaders().getReplyTo(AddressingVersion.W3C,
SOAPVersion.SOAP_11).toSpec();
}
private String getMessageId() {
return getHeaders().getMessageID(AddressingVersion.W3C,
SOAPVersion.SOAP_11);
}
}
this helper is called from service implementation as:
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.jws.HandlerChain;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.soap.Addressing;
import dev.home.examples.jobprocessor.client.JobProcessorNotify;
import dev.home.examples.jobprocessor.client.JobProcessorNotify_Service;
import dev.home.examples.jobprocessor.client.JobReplyType;
import dev.home.examples.jobprocessor.handlers.CorrelationHelper;
import dev.home.examples.jobprocessor.types.JobType;
#WebService(serviceName = "JobProcessor",
targetNamespace = "http://examples.home.dev/jobprocessor",
portName = "jobProcessor",
endpointInterface = "dev.home.examples.jobprocessor.ws.JobProcessor")
#HandlerChain(file = "JobProcessor-HandlerChain.xml")
#Addressing(required = true)
public class JobProcessorImpl {
//...
public void processJob(JobType job) {
// do processing
int seconds = doJob();
// prepare reply message
JobReplyType jobReply = new JobReplyType();
jobReply.setJobId(job.getJobId());
jobReply.setResult(String.format("Job payload %s processed in %d seconds!",
job.getPayload(), seconds));
// do correlation and perform the callback
JobProcessorNotify jobProcessorNotify =
correlationHelper.getCorrelatedPort(JobProcessorNotify.class);
jobProcessorNotify.replyFinishedJob(jobReply);
}
}
HeaderList is not initiated during getReplyTo() and than is returned as null:
(HeaderList)wsc.getMessageContext().get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY)
Caused by: java.lang.NullPointerException
at dev.home.examples.jobprocessor.handlers.CorrelationHelper.getReplyTo(CorrelationHelper.java:67)
at dev.home.examples.jobprocessor.handlers.CorrelationHelper.getCorrelatedPort(CorrelationHelper.java:56)
at dev.home.examples.jobprocessor.ws.JobProcessorImpl.processJob(JobProcessorImpl.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:180)
at org.apache.cxf.jaxws.JAXWSMethodInvoker.performInvocation(JAXWSMethodInvoker.java:66)
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)
... 17 more
although the SOAP data Header contains all data:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="http://examples.home.dev/jobprocessor/types">
<soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"><wsa:Action>http://examples.home.dev/jobprocessor/processJob</wsa:Action><wsa:ReplyTo><wsa:Address>http://CZ407032:8088/mockJobProcessorNotify</wsa:Address></wsa:ReplyTo><wsa:MessageID>uuid:96dd09e2-c448-47c0-902f-7eb95421e232</wsa:MessageID><wsa:To>http://CZ407032:8088/JobProcessor</wsa:To></soapenv:Header>
<soapenv:Body>
...
</soapenv:Body></soapenv:Envelope>
You are using the property INBOUND_HEADER_LIST_PROPERTY. Reading JAX-WS documentation, shows an unpleasant warning
THIS PROPERTY IS EXPERIMENTAL AND IS SUBJECT TO CHANGE WITHOUT NOTICE IN FUTURE.
HeaderList and JAXWSProperties are classes in com.sun.xml.internal.ws.* package. Do you really want to use this? The blog is dated in 2012, may be the behaviour has changed
Check if this simple code return a not null object (after injecting messageContext as #Resource in your service)
HeaderList hl = (HeaderList) messageContext.get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY);

HTTP GET request with proper content-type is not hitting the expected service method

I have 2 restful service method getCustomerJson and getCustomerXML in a class CustomerResource where i am using jersey API for Restful Webservices. All the parameters of the 2 methods are same except one produces xml and other produces json.
When i am using the a HTTP GET request with header Content-Type="application/json" it always invokes the getCustomerXML method which returns xml.
Can someone explain me how jersey works in this kind of situation ?
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import domain.Customer;
#Path("/customers")
public class CustomerResource {
private static Map<Integer, Customer> customerDB = new ConcurrentHashMap<Integer, Customer>();
private static AtomicInteger idCounter = new AtomicInteger();
// Constructor
public CustomerResource() {
}
#GET
#Produces(MediaType.TEXT_PLAIN)
public String sayHello() {
return "Hello Kundan !!!";
}
#GET
#Path("{id}")
#Produces("application/xml")
public Customer getCustomerXML(#PathParam("id") int id, #Context HttpHeaders header) {
final Customer customer = customerDB.get(id);
List<String> contentList = header.getRequestHeader("Content-Type");
List<String> languageList = header.getRequestHeader("Accept-Language");
List<String> compressionFormatList = header.getRequestHeader("Content-Type");
if (customer == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return customer;
}
#GET
#Path("{id}")
#Produces("application/json")
public Customer getCustomerJson(#PathParam("id") int id) {
final Customer customer = customerDB.get(id);
if (customer == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return customer;
}
#POST
#Consumes("application/xml")
public Response createCustomer(Customer customer) {
customer.setId(idCounter.incrementAndGet());
customerDB.put(customer.getId(), customer);
System.out.println("Created customer " + customer.getId());
return Response.created(URI.create("/customers/" + customer.getId())).build();
}
#PUT
#Path("{id}")
#Consumes("application/xml")
public void updateCustomer(#PathParam("id") int id, Customer customer) {
Customer current = customerDB.get(id);
if (current == null)
throw new WebApplicationException(Response.Status.NOT_FOUND);
current.setFirstName(customer.getFirstName());
current.setLastName(customer.getLastName());
current.setStreet(customer.getStreet());
current.setCity(customer.getCity());
current.setState(customer.getState());
current.setZip(customer.getZip());
current.setCountry(customer.getCountry());
}
#DELETE
#Path("{id}")
public void deleteCustomer(#PathParam("id") int id) {
customerDB.remove(id);
System.out.println("Deleted !");
}
}
Use Accept: application/json. Accept tells the server what type you want back. Content-Type if for the type of data you are sending to the server, like with a POST request.

Extand Netbeans RESTful Webservice

i did this tutorial http://netbeans.org/kb/docs/websvc/rest.html to create a restful webservice with my mysql db.
the basic things works fine, but now i want to extend the service functionality. how can i add additional parameters to the GET service ?
i tried this
but as a result I have all cities.
when I add the parameter countryCode links the service becomes
http://localhost:8080/Data/resources/converter.city/?
countryCode=TUR×tamp=1323114935089
This is my code
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package service;
import converter.City;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
/**
*
* #author mehdi
*/
#Stateless
#Path("converter.city")
public class CityFacadeREST extends AbstractFacade<City> {
#PersistenceContext(unitName = "DataPU")
private EntityManager em;
public CityFacadeREST() {
super(City.class);
}
#POST
#Override
#Consumes({"application/xml", "application/json"})
public void create(City entity) {
super.create(entity);
}
#PUT
#Override
#Consumes({"application/xml", "application/json"})
public void edit(City entity) {
super.edit(entity);
}
#DELETE
#Path("{id}")
public void remove(#PathParam("id") Integer id) {
super.remove(super.find(id));
}
#GET
#Path("{id}")
#Produces({"application/xml", "application/json"})
public City find(#PathParam("id") Integer id) {
return super.find(id);
}
#GET
#Override
#Produces({"application/xml", "application/json"})
public List<City> findAll() {
return super.findAll();
}
#GET
#Path("{from}/{to}")
#Produces({"application/xml", "application/json"})
public List<City> findRange(#PathParam("from") Integer from, #PathParam("to") Integer to) {
return super.findRange(new int[]{from, to});
}
#GET
#Path("count")
#Produces("text/plain")
public String countREST() {
return String.valueOf(super.count());
}
#java.lang.Override
protected EntityManager getEntityManager() {
return em;
}
}
You will have to update the annotations in your Java resource class to accept the additional parameter(s). Have you looked at the annotation support for query parameters in JAX-RS?