In integration testing, I use a real remote server to consume REST APIs.
What's the simplest way to provide those responses within a unit test w/o depending on external entity.
One possible approach is to build
public class TestHttpResponse implements org.apache.http.client.methods.CloseableHttpResponse
override
#Override
public StatusLine getStatusLine() {
return new StatusLine() {
#Override
public ProtocolVersion getProtocolVersion() {
return null;
}
#Override
public int getStatusCode() {
return statusCode;
}
#Override
public String getReasonPhrase() {
return reasonPhrase;
}
};
}
...
Is there a simpler and better way for mocking REST API response payloads?
I'm a fan of Mockito for this purpose:
http://www.vogella.com/tutorials/Mockito/article.html#testing-with-mock-objects
The nice part about Mockito is how you can control it's behavior dynamically.
Related
For more complex needs you can create a #Bean of type
DiscoveryClientOptionalArgs and inject ClientFilter instances into it,
all of which will be applied to the calls from the client to the
server.
this description in spring-cloud wiki
#Bean
public DiscoveryClientOptionalArgs discoveryClientOptionalArgs() {
DiscoveryClientOptionalArgs discoveryClientOptionalArgs = new DiscoveryClientOptionalArgs();
discoveryClientOptionalArgs.setAdditionalFilters(Collections.singletonList(new IpCilentFilter()));
return discoveryClientOptionalArgs;
}
public class IpCilentFilter extends ClientFilter {
#Override
public ClientResponse handle(ClientRequest clientRequest) throws ClientHandlerException {
// here How to disallow clients to connect
return getNext().handle(clientRequest);
}
}
How to disallow clients to connect?
throws ClientHandlerException useless
return null useless
what should I do?
I am trying to implement the projection with specification in Spring Data JPA via this implementation:
https://github.com/pramoth/specification-with-projection
Related classes are as follows:
Spec:
public class TopicSpec {
public static Specification<Topic> idEq(String id){
return (root, query, cb) -> cb.equal(root.get(Topic_.id),id);
}
}
Repository
#Repository
public interface TopicRepository extends JpaRepository<Topic,String>,JpaSpecificationExecutorWithProjection<Topic> {
public static interface TopicSimple{
String getId();
String getName();
}
List<TopicSimple> findById(String id);
}
Test
#Test
public void specificationWithProjection() {
Specification<Topic> where= Specifications.where(TopicSpec.idEq("Bir"));
List<Topic> all = topicRepository.findAll(where);
Assertions.assertThat(all).isNotEmpty();
}
I have this response from the Get method:
However the tests fail. Besides when I pull the github project of pramoth I can run the tests with success. Does anyone have any opinion about this issue?
The full project can be found here:
https://github.com/dengizik/projectionDemo
I have asked the same question to the developer of the project Pramoth Suwanpech, who was kind enough to check my code and give answer. My test class should've implement the test object like this:
#Before
public void init() {
Topic topic = new Topic();
topic.setId("İki");
topic.setName("Hello");
topicRepository.save(topic); }
With this setting the tests passed.
We are using zuul as API gateway in spring cloud. Now we want to extract access token from zuul for further implementation.Please provide suggestion how we want to implement. Thank you
To read the authorization header you will need to create a filter in ZUUL my thought is you will need a pre filter you can change it based on your need. Here is what you will need.
public class TestFilter extends ZuulFilter {
#Override
public boolean shouldFilter() {
return true;
}
#Override
public Object run() {
final RequestContext ctx = RequestContext.getCurrentContext();
final HttpServletRequest request = ctx.getRequest();
//Here is the authorization header being read.
final String xAuth = request.getHeader("Authorization");
//Use the below method to add anything to the request header to read downstream. if needed.
ctx.addZuulRequestHeader("abc", "abc");
return null;
}
#Override
public String filterType() {
return "pre";
}
#Override
public int filterOrder() {
return 1;
}
}
You will need a #Bean declaration for Filter in the class where you have #EnableZuulProxy
#Bean
public TestFilter testFilter() {
return new TestFilter();
}
Hope this helps.!!!
I have a bundle that provides a service.
My bundle implementation looks like this:
class ServiceImpl implements Service
{
Object value;
#Override
public void setValue(Object value)
{
this.value = value;
}
#Override
public Object getValue()
{
return value;
}
}
In my java application, I load this bundle to OSGI framework, and create TWO references to the service, in an attempt to have two objects with different values for "value".
Unfortunately, this does not seem to work. The service always returns the last value set by either objects. How can I overcome this issue?
Here's an example for the problem:
Service object1 = context.getService(reference1);
Service object2 = context.getService(reference2);
Integer one= 1;
Integer two =2;
object1.setValue(1);
object2.setValue(2);
System.out.println(object1.getValue() ); //returns 2 !!!!!!!!!!!!!!!!!!
System.out.println(object2.getValue() ); //returns 2
I used ServiceFactory but it seems not useful for my case. What should I do? Thanks.
Both BJ and Balazs offer valuable information, but no solution that works with current versions of the OSGi specification.
What you can do is register your service with a second "Factory" interface. This factory then allows you to create instances of the service. Because you probably don't want to do that manually, you can hide this logic in a ServiceTracker.
There are a few "downsides" to this approach. First of all, you need to register the service and have the instance implement both Factory and Service. Secondly, you always have to use this custom ServiceTracker to access it. If you use a dependency manager that allows you to extend its dependencies (such as Apache Felix Dependency Manager) you can easily hide all of this in a custom ServiceDependency.
Anyway, to show you that this actually works, here is a simple example:
public class Activator implements BundleActivator {
#Override
public void start(final BundleContext context) throws Exception {
context.registerService(Service.class.getName(), new FactoryImpl(), null);
ServiceTrackerCustomizer customizer = new ServiceTrackerCustomizer() {
#Override
public Object addingService(ServiceReference reference) {
Object service = context.getService(reference);
if (service instanceof Factory) {
return ((Factory) service).createInstance();
}
return service;
}
#Override
public void modifiedService(ServiceReference reference,
Object service) {
// TODO Auto-generated method stub
}
#Override
public void removedService(ServiceReference reference,
Object service) {
// TODO Auto-generated method stub
}
};
ServiceTracker st1 = new ServiceTracker(context, Service.class.getName(), customizer);
ServiceTracker st2 = new ServiceTracker(context, Service.class.getName(), customizer);
st1.open();
st2.open();
Service s1 = (Service) st1.getService();
Service s2 = (Service) st2.getService();
s1.setValue("test1");
s2.setValue("test2");
System.out.println(s1.getValue());
System.out.println(s2.getValue());
}
#Override
public void stop(BundleContext context) throws Exception {
}
static interface Factory {
public Object createInstance();
}
static class FactoryImpl extends ServiceImpl implements Factory, Service {
#Override
public Object createInstance() {
return new ServiceImpl();
}
}
static interface Service {
public void setValue(Object value);
public Object getValue();
}
static class ServiceImpl implements Service {
private Object m_value;
#Override
public void setValue(Object value) {
m_value = value;
}
#Override
public Object getValue() {
return m_value;
}
}
}
You need to wait for R6. Pre-R6, each bundle can be exposed to at most one instance of a service. Even registering a ServiceFactory will not change that since the framework will cache the service object from the ServiceFactory to return to the bundle on subsequent calls to getService.
In R6, we introduce service scopes which allows a service implementation to return multiple service objects to a bundle. Using this requires both the service provider and the service consumer to use new API added in R6.
You can play with this now as it is implemented in Eclipse Equinox Luna.
Even if you use ServiceFactory, for the same bundle the same service object will be returned.
There might be a PrototypeServiceFactory in the future as there is an RFP about it: https://github.com/osgi/design/tree/master/rfcs/rfc0195
That would fit to your needs.
Although there might be a PrototypeServiceFactory in the future, I think it is better to solve this use-case programmatically by yourself. E.g.:
Instead of creating a mutuable OSGi service (I do not think creating mutuable services is a good idea) create a factory.
On the client side you would use:
BusinessLogicFactory factory = context.getService(reference);
BusinessLogic object1 = factory.createInstance();
BusinessLogic object2 = factory.createInstance();
...
I am trying to a find a good design for the following scenario.
I have a POST rest service which will be given an array of services as data. And which should in turn be calling them one by one to aggregate results on the server and send them back to the client.
#Path("/resource1")
#Path("/resource2")
#Path("/collection")
Post data to /collection
{["serviceName": "resource1", "data":"test1"], ["serviceName":"resource2","data":"test2"]}
The reason i need the resource1 and resource2 are, because those services can be called standalone also. I want to reuse the same setup if possible.
Is there any way to do this.
I am using jersey with spring.
Not sure what these resources have in common. If the post method has the same signature for all of them, you could have an abstract class or interface they implement defining the post method and can try using ResourceContext.matchResource to do this. E.g. something like this:
public abstract class AbstractResource {
public abstract String post(Object data);
}
#Path("/resource1")
public class Resource1 extends AbstractResource {
#POST
public String post(String data) {
// do something
}
}
#Path("/collection")
public class CollectionResource {
#Context
private ResourceContext rc;
#POST
#Consumes("application/json")
public String post(List<PostRequest> postRequests) {
StringBuilder result = new StringBuilder();
for (PostRequest pr : postRequests) {
// should wrap this in try-catch
AbstractResource ar = rc.matchResource(pr.resource,
AbstractResource.class);
sb.append(ar.post(pr.data));
}
return result.toString();
}
}
#XmlRootElement
public class PostRequest {
public String resource;
public String data;
}
Hopefully you got the idea and will be able to play with it and tweak it to fit your needs.