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

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 {
}
}

Related

Getting java.lang.IllegalStateException while mocking java.util.Properties using easymock

I am using easymock framework to write UT's. I have one class which uses java.util.Properties in public function. Below is sample code:
public URI generateSASURI() throws CloudStorageException, DataProcessingException {
final String token = "token";
try {
return new URI(URIUtils.getAssetURI(azureStorageProperties.getProperty(StorageConstant.STORAGE_ACCOUNT_NAME)
, cloudBlob).toString() + "?" + token);
} catch (URISyntaxException e) {
throw new DataProcessingException("Error while creating SAS URL " + e.getMessage(), e);
}
}
where azureStorageProperties is instance of java.util.Properties, which is created as bean and injected in class.
Now while writing unit test case , i am trying to mock Properties azureStorageProperties, i am getting below error:
Unable to evaluate the expression Method threw 'java.lang.IllegalStateException' exception.
Below is ss:
Below is class to be tested:
package com.company.ops.azure.storage;
import com.company.ops.azure.storage.constants.StorageConstant;
import com.company.ops.azure.storage.dto.CloudBlob;
import com.company.ops.cloudopsfacade.dto.SignedUrlDTO;
import com.company.ops.cloudopsfacade.exception.storage.CloudStorageException;
import com.company.ops.cloudopsfacade.exception.storage.DataProcessingException;
import com.company.ops.azure.storage.util.URIUtils;
import com.company.ops.cloudopsfacade.storage.ICloudStorageClient;
import com.microsoft.azure.storage.blob.CloudBlobClient;
import com.microsoft.azure.storage.blob.SharedAccessBlobHeaders;
import com.microsoft.azure.storage.blob.SharedAccessBlobPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.EnumSet;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
public class StorageClient implements ICloudStorageClient {
private static final Logger LOG = LoggerFactory.getLogger(StorageClient.class);
#Inject
private CloudBlobClient cloudBlobClient;
#Inject
Properties azureStorageProperties;
#Inject
private SASTokenGenerator sasTokenGenerator;
private long sasUrlDuration;
private Optional<String> sasUrlDurationKey;
public StorageClient() {
sasUrlDurationKey = Optional.ofNullable(System.getenv(StorageConstant.SAS_URL_DURATION_KEY));
if (sasUrlDurationKey.isPresent()) {
try {
sasUrlDuration = Integer.parseInt(sasUrlDurationKey.get());
} catch(NumberFormatException ex) {
LOG.debug("sasURLDurationKey invalid" + ex.getMessage());
sasUrlDuration = StorageConstant.DEFAULT_SAS_URL_DURATION;
}
} else {
sasUrlDuration = StorageConstant.DEFAULT_SAS_URL_DURATION;
}
}
//NOTE: This constructor is just created for test case. As #Mock of final class is NOT supported in easymock
public StorageClient(long sasUrlDuration, CloudBlobClient cloudBlobClient) {
this.sasUrlDuration = sasUrlDuration;
this.cloudBlobClient = cloudBlobClient;
}
/**
*
* #param containerName
* #param blob
* #param expiryTime
* #return {#link URI}
* #throws CloudStorageException
* #throws DataProcessingException
*/
private URI generateSASURI(String containerName,
String blob, Long expiryTime) throws CloudStorageException, DataProcessingException {
CloudBlob cloudBlob = new CloudBlob(Optional.ofNullable(containerName)
.orElseThrow(() -> new CloudStorageException("container name is null")),
Optional.ofNullable(blob).orElseThrow(() -> new CloudStorageException("blob name is null")));
//#TODO: Need to check permissions: Currently create and write assigned
final Set<SharedAccessBlobPermissions> permissions = EnumSet.of(SharedAccessBlobPermissions.WRITE, SharedAccessBlobPermissions.CREATE);
final SharedAccessBlobHeaders contentHeaders = new SharedAccessBlobHeaders();
//in case if duration need to set manually via api
if (Optional.ofNullable(expiryTime).isPresent()) {
sasUrlDuration = expiryTime;
}
sasTokenGenerator.sasTokenGeneratorInitializer(
cloudBlobClient,
cloudBlob,
permissions,
sasUrlDuration,
contentHeaders);
final String token = sasTokenGenerator.getToken();
try {
return new URI(URIUtils.getAssetURI(azureStorageProperties.getProperty(StorageConstant.STORAGE_ACCOUNT_NAME)
, cloudBlob).toString() + "?" + token);
} catch (URISyntaxException e) {
throw new DataProcessingException("Error while creating SAS URL " + e.getMessage(), e);
}
}
/**
*
* #param containerName
* #param blob
* #param expiryTime
* #return {#link URI}
* #throws CloudStorageException
* #throws DataProcessingException
*/
#Override
public SignedUrlDTO generateSignedUrl(String containerName, String blob, Long expiryTime)
throws CloudStorageException, DataProcessingException, MalformedURLException {
try {
URI uri = generateSASURI(containerName, blob, expiryTime);
SignedUrlDTO signedUrlDTO = new SignedUrlDTO();
signedUrlDTO.setSignedURL(uri.toURL());
return signedUrlDTO;
} catch (DataProcessingException ex) {
LOG.error(ex.getMessage());
throw ex;
} catch (CloudStorageException ex) {
LOG.error(ex.getMessage());
throw ex;
} catch (MalformedURLException e) {
LOG.error("Unable to get URL");
throw e;
}
}
}
Below is complete code for UT
package com.company.ops.azure.storage;
import com.company.ops.azure.constants.AzureConstants;
import com.company.ops.azure.storage.constants.StorageConstant;
import com.company.ops.azure.storage.util.URIUtils;
import com.company.ops.cloudopsfacade.dto.SignedUrlDTO;
import com.company.ops.cloudopsfacade.exception.storage.CloudStorageException;
import com.company.ops.cloudopsfacade.exception.storage.DataProcessingException;
import com.microsoft.azure.storage.StorageCredentials;
import com.microsoft.azure.storage.StorageCredentialsAccountAndKey;
import com.microsoft.azure.storage.blob.CloudBlobClient;
import org.easymock.*;
import static org.easymock.EasyMock.*;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import javax.inject.Inject;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.Properties;
#RunWith(EasyMockRunner.class)
public class StorageClientTest extends EasyMockSupport {
private CloudBlobClient cloudBlobClient;
#Mock
private SASTokenGenerator sasTokenGenerator;
#Mock
private Properties azureStorageProperties;
#Mock
private StorageClient storageClient; /*= /*new StorageClient(StorageConstant.DEFAULT_SAS_URL_DURATION,
cloudBlobClient, azureStorageProperties);*/
#Before
public void setup() throws URISyntaxException {
resetAll();
}
#After
public void tearDown() {
verifyAll();
}
#Test
public void testGenerateSASURI() throws MalformedURLException, CloudStorageException, DataProcessingException {
String containerName = "myprojectlocal";
String blob = "testfile";
Long expiryTime = 1000L;
/*Properties azureStorageProperties = EasyMock.createMockBuilder(Properties.class)
.addMockedMethod("getProperty", String.class).createMock();*/
//azureStorageProperties = new Properties();
// azureStorageProperties.setProperty(StorageConstant.STORAGE_ACCOUNT_NAME, "storage-account-name");
expect(azureStorageProperties.getProperty(StorageConstant.STORAGE_ACCOUNT_NAME)).andReturn("storage-account-name");
expect(sasTokenGenerator.getToken()).andReturn("token");
sasTokenGenerator.sasTokenGeneratorInitializer(anyObject(CloudBlobClient.class),
anyObject(),
anyObject(),
anyLong(),
anyObject());
expectLastCall();
//azureStorageProperties.getProperty(anyString()); //.andReturn("storage-account-name");
//expectLastCall();
//expect(azureStorageProperties.getProperty(StorageConstant.STORAGE_ACCOUNT_NAME)).andReturn("storage-account-name");
replayAll();
SignedUrlDTO signedUrlDTO = storageClient.generateSignedUrl(containerName, blob, expiryTime);
Assert.assertNotNull(signedUrlDTO);
}
private CloudBlobClient getCloudBlobClient() {
final StorageCredentials credentials = new StorageCredentialsAccountAndKey(TestConstants.STORAGE_ACCOUNT_NAME,
TestConstants.STORAGE_ACCOUNT_KEY);
try {
return new CloudBlobClient(URIUtils.getStorageAccountURI(TestConstants.STORAGE_ACCOUNT_NAME), credentials);
} catch (URISyntaxException e) {}
return null;
}
}

Extract SOAP custom header information

I want to read request header from SOAP incoming request in my Java code for some authorization purpose. I found few work-arounds like using SOAPHandlers and . Code as below :
`package com.cerillion.ccs.framework;
import java.util.HashSet;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import org.apache.log4j.Logger;
public class ApiSoapHandler implements SOAPHandler<SOAPMessageContext> {
private static final Logger logger = Logger.getLogger(ApiSoapHandler.class.getName());
#Override
public void close(MessageContext arg0) {
// TODO Auto-generated method stub
}
#Override
public boolean handleFault(SOAPMessageContext context) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean handleMessage(SOAPMessageContext context) {
logger.debug("Inside ApiSoapHandler");
try {
SOAPMessage message = context.getMessage();
SOAPHeader header = message.getSOAPHeader();
message.saveChanges();
} catch (SOAPException e) {
logger.error("Error occurred while adding credentials to SOAP header.",
e);
}
return true;
}
#Override
public Set<QName> getHeaders() {
/* QName securityTokenHeader = new QName("urn:com.intertech.secty", "token");
//new QName(“urn:com.intertech.secty”,“username”);
HashSet<QName> headers = new HashSet<QName>();
headers.add(securityTokenHeader);
return headers;*/
return null;
} }`
I ma really curious about to have some other simple alternative rather than writing entire handler just for fetching custom header tag. Is this the only way to read SOAP request header ? Any leads are really appreciated

A message body writer for Java type was not found

I am receiving following exception:
ClientHandlerException: A message body writer for Java type,
class com.company.testing.repo.model.Privilege,
and MIME media type,
application/octet-stream, was not found
Privilege is an ENUM class:
public enum Privilege {
READ,
WRITE;
}
Resource entry is this:
#Path("repoPrivs")
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
Response getGroups(Privilege privilege);
my client code is this:
#Override
public List<MyGroup> getGroups(Privilege privilege) {
IWebParamaterProvider provider = WebParamaterFactory.create("repo-mapping/repoPrivs", //$NON-NLS-1$
SecureAction.READ, webProxy);
provider = provider.setType(MediaType.APPLICATION_JSON);
provider = provider.setAccept(MediaType.APPLICATION_JSON);
List<MyGroup> groups = null;
groups = webProxy.post(provider, new GenericTypeFactory<MyGroup>(), MyGroup.class, privilege);
return groups;
}
Override
public final <T> List<T> post(IWebParamaterProvider provider, GenericTypeFactory<T> genericsFactory,
Class<T> clazz, Object requestEntity){
WebResource resource = ((IWebResourceProvider) provider).getWebResource();
TRACER.trace("POST: " + resource.getURI().toString()); //$NON-NLS-1$
return resource.post(genericsFactory.create(clazz), requestEntity);
}
public GenericType<List<T>> create(final Class<T> clazz) {
ParameterizedType genericType = new ParameterizedType() {
#Override
public Type[] getActualTypeArguments() {
return new Type[] { clazz };
}
#Override
public Type getOwnerType() {
return List.class;
}
#Override
public Type getRawType() {
return List.class;
}
};
return new GenericType<List<T>>(genericType) {
};
}
What is that I am missing
It is very important to provide complete minimal example so other people can help you.
Below you have Jersey 2 and Jersey 1 example and both of them uses in memory test container. Make sure to get the all the required dependencies based on the version.
Jersey 2
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory;
import org.glassfish.jersey.test.spi.TestContainerFactory;
import org.junit.Test;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.junit.Assert.*;
public class JerseyVersion2Test extends JerseyTest {
#Path("hello")
public static class HelloResource {
#POST
#Produces(APPLICATION_JSON)
#Consumes(APPLICATION_JSON)
public List<MyGroup> doPost(Privilege privilege) {
List<MyGroup> myGroups = new ArrayList<>();
MyGroup myGroup = new MyGroup();
myGroup.name = "jersey";
myGroup.version = 2;
myGroups.add(myGroup);
return myGroups;
}
}
#Override
protected Application configure() {
return new ResourceConfig(HelloResource.class);
}
#Override
protected TestContainerFactory getTestContainerFactory() {
return new InMemoryTestContainerFactory();
}
#Test
public void testPost() {
List<MyGroup> myGroups = getGroups();
assertEquals(1, myGroups.size());
}
public enum Privilege {
READ,
WRITE;
}
public List<MyGroup> getGroups() {
List<MyGroup> groups = target("hello").request().
accept(MediaType.APPLICATION_JSON).
post(Entity.json(Privilege.READ)).
readEntity(new GenericTypeFactory<MyGroup>().create(MyGroup.class));
return groups;
}
#JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public static class MyGroup {
private String name;
private double version;
}
public class GenericTypeFactory<T> {
public GenericType<List<T>> create(final Class<T> clazz) {
ParameterizedType genericType = new ParameterizedType() {
#Override
public Type[] getActualTypeArguments() {
return new Type[]{clazz};
}
#Override
public Type getOwnerType() {
return List.class;
}
#Override
public Type getRawType() {
return List.class;
}
};
return new GenericType<List<T>>(genericType) {
};
}
}
}
Jersey 1
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.test.framework.AppDescriptor;
import com.sun.jersey.test.framework.JerseyTest;
import com.sun.jersey.test.framework.LowLevelAppDescriptor;
import com.sun.jersey.test.framework.spi.container.TestContainerFactory;
import com.sun.jersey.test.framework.spi.container.inmemory.InMemoryTestContainerFactory;
import org.junit.Test;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.junit.Assert.assertEquals;
public class JerseyVersion1Test extends JerseyTest {
#Path("hello")
public static class HelloResource {
#POST
#Produces(APPLICATION_JSON)
#Consumes(APPLICATION_JSON)
public List<MyGroup> doPost(Privilege privilege) {
List<MyGroup> myGroups = new ArrayList<>();
MyGroup myGroup = new MyGroup();
myGroup.name = "jersey";
myGroup.version = 1.12;
myGroups.add(myGroup);
return myGroups;
}
}
#Override
protected AppDescriptor configure() {
return new LowLevelAppDescriptor.Builder(HelloResource.class).build();
}
#Override
protected TestContainerFactory getTestContainerFactory() {
return new InMemoryTestContainerFactory();
}
#Test
public void testPost() {
List<MyGroup> myGroups = getGroups();
assertEquals(1, myGroups.size());
}
public enum Privilege {
READ,
WRITE;
}
public List<MyGroup> getGroups() {
WebResource webResource = resource();
List<MyGroup> groups = webResource.path("hello").
accept(MediaType.APPLICATION_JSON).
type(MediaType.APPLICATION_JSON).
post(new GenericTypeFactory<MyGroup>().create(MyGroup.class), Privilege.READ);
return groups;
}
#JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public static class MyGroup {
private String name;
private double version;
}
public class GenericTypeFactory<T> {
public GenericType<List<T>> create(final Class<T> clazz) {
ParameterizedType genericType = new ParameterizedType() {
#Override
public Type[] getActualTypeArguments() {
return new Type[]{clazz};
}
#Override
public Type getOwnerType() {
return List.class;
}
#Override
public Type getRawType() {
return List.class;
}
};
return new GenericType<List<T>>(genericType) {
};
}
}
}
javax.xml.bind.annotation.XmlRootElement
Java doc:
The #XmlRootElement annotation can be used with the following program
elements:
a top level class
an enum type
[...]
When a top level class or an enum type is annotated with the #XmlRootElement annotation, then its value is represented as XML element in an XML document.
in your case it is clear that Jersey unable to unmarshall the incoming JSON payload to your object, thus the exception
A message body writer for Java type, class com.company.testing.repo.model.Privilege
annotating your Enum (Privilege) with #XmlRootElement should solve the issue.
#XmlRootElement
public enum Privilege {
READ,
WRITE;
}

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.

How do I write a ExtensionFunctionDefinition in saxon 9.5?

The example usage of ExtensionFunctionDefinition from the saxon documentation does not compile with Saxon version 9.5.1-6
The error I get is:
java: <anonymous ShiftLeft$1> is not abstract and does not override abstract method call(net.sf.saxon.expr.XPathContext,net.sf.saxon.om.Sequence[]) in net.sf.saxon.lib.ExtensionFunctionCall
How do I make this code compile in Saxon 9.5?
private static class ShiftLeft extends ExtensionFunctionDefinition {
#Override
public StructuredQName getFunctionQName() {
return new StructuredQName("eg", "http://example.com/saxon-extension", "shift-left");
}
#Override
public SequenceType[] getArgumentTypes() {
return new SequenceType[] {SequenceType.SINGLE_INTEGER, SequenceType.SINGLE_INTEGER};
}
#Override
public SequenceType getResultType(SequenceType[] suppliedArgumentTypes) {
return SequenceType.SINGLE_INTEGER;
}
#Override
public ExtensionFunctionCall makeCallExpression() {
return new ExtensionFunctionCall() {
public SequenceIterator call(SequenceIterator[] arguments, XPathContext context) throws XPathException {
long v0 = ((IntegerValue)arguments[0].next()).longValue();
long v1 = ((IntegerValue)arguments[1].next()).longValue();
long result = v0<<v1;
return Value.asIterator(Int64Value.makeIntegerValue(result));
}
};
}
}
import com.saxonica.config.EnterpriseTransformerFactory;
import com.saxonica.config.ProfessionalConfiguration;
import com.saxonica.objectweb.asm.tree.analysis.Value;
import net.sf.saxon.expr.XPathContext;
import net.sf.saxon.lib.ExtensionFunctionCall;
import net.sf.saxon.lib.ExtensionFunctionDefinition;
import net.sf.saxon.om.Sequence;
import net.sf.saxon.om.SequenceIterator;
import net.sf.saxon.om.StructuredQName;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.value.Int64Value;
import net.sf.saxon.value.IntegerValue;
import net.sf.saxon.value.SequenceType;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.StringWriter;
class ShiftLeft extends ExtensionFunctionDefinition {
#Override
public StructuredQName getFunctionQName() {
return new StructuredQName("eg", "http://example.com/saxon-extension", "shift-left");
}
#Override
public SequenceType[] getArgumentTypes() {
return new SequenceType[]{SequenceType.SINGLE_INTEGER, SequenceType.SINGLE_INTEGER};
}
#Override
public SequenceType getResultType(SequenceType[] suppliedArgumentTypes) {
return SequenceType.SINGLE_INTEGER;
}
#Override
public ExtensionFunctionCall makeCallExpression() {
return new ExtensionFunctionCall() {
#Override
public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException {
long v0 = ((IntegerValue)arguments[0]).longValue();
long v1 = ((IntegerValue)arguments[1]).longValue();
long result = v0<<v1;
return Int64Value.makeIntegerValue(result);
}
};
}
}