How to use a #FeignClient to map a HAL JSON _embedded collection - spring-data-rest

We're trying to use a spring-cloud #FeignClient to call the HAL-JSON REST API of a microservice from another microservice. The service is implemented with Spring Data Rest, Spring Boot 1.4, with Hateoas enabled by default.
Using a dedicated DTO on the client side, all the simple properties are properly mapped, but the HAL-specific _embedded collection is ignored.
As taken primarly from this post, we implemented a custom Feign Decoder with a corresponding ObjectMapper, using the often mentioned Jackson2HalModule, but this still does not solve our issue.
You can reproduce the issue with this sample project, where the problem is described in more detail.
We appreciate any help or hints on this problem! Thanks in advance

I think the key to understanding how to deserialize this is that your Customer is the Resources class that is embedding the relations. So you need to deserialize it as Resources in order for the HalResourcesDeserializer to pick it up.
I got it to work this way.
#Getter
#Setter
public class Customer extends Resources<Resource<Relation>> {
public static enum Type {
PERSON, INSTITUTION
}
private String displayName;
private Integer rating;
private Type type;
public Collection<Resource<Relation>> getRelations() {
return this.getContent();
}
}
This still looks a little odd and I am not sure if this is the best solution.

I know I am responding to an old question, but in my experience, I had to add #EnableHyperMediaSupport to my main/any configuration class to resolve this issue. You can try that and verify if it works for you.

Related

Injecting Managed Bean into Webservice

I'm trying to inject a Managed Bean within a Webservice but the injected Bean is allways null. Does anybody knows why and if so could you provide some hints or a workaround?
#WebService(targetNamespace = "http://impl.soap.valueservice.drivelog.com/", endpointInterface = "com.drivelog.valueservice.soap.impl.ValueService", portName = "ValueServiceImplPort", serviceName = "ValueServiceImplService")
public class ValueServiceImpl implements ValueService {
#Inject
private ValueServiceFacade valueBean;
...
}
#ManagedBean
public class ValueServiceFacadeImpl implements ValueServiceFacade {
...
}
This is really embarrassing.
According to this blog post (https://weblogs.java.net/blog/jitu/archive/2010/02/19/jax-ws-cdi-java-ee-6-0) and this post (https://blogs.oracle.com/arungupta/entry/totd_124_using_cdi_jpa), this should work but I can't make it work using TomEE here.
There is also some discussion about JSRs here (https://bugzilla.redhat.com/show_bug.cgi?id=1001610) but I can't really tell you why it does not work.
For TomEE (openEJB) all I could find was a lot of issues closed (related to https://issues.apache.org/jira/browse/OPENEJB-1592) with a scary comment "All done for certification", and maybe, the JEE Web Profile does not need to make these work together, while Geronimo, that implements the full EJB Profile, may need to work with this.
Please also see Java EE 6 WebService and CDI injection
So I can't really answer this. At the same time, I'll ask you to provide us some more information about what container you're using, so we can help you better.
For TomEE, a working approach considering #Inject in a web-resource is providing a method that #Produces an entity with that interface.
For your example, this could be small factory:
public class ValueServiceFactory {
#Produces
public ValueServiceFacade getValueService() {
return new ValueServiceFacadeImpl();
}
}

Named binding - MVC3

I'm trying to register to implementations of same interface using named instances
kernel.Bind<IRepository>().To<CachedRepository>().InSingletonScope();
kernel.Bind<IRepository>().To<DbRepository>().InSingletonScope().Named("db");
the idea, is that if I not specify the name then the CachedRepository gets created, if I need a DB oriented one then I'd use the Named attribute, but this miserable fails when a simple object would get created
public class TripManagerController : Controller
{
[Inject]
public IRepository Repository { get; set; } // default Cached repo must be created
public TripManagerController()
{
ViewBag.LogedEmail = "test#test.com";
}
}
the error is
Error activating IRepository More than one matching bindings are
available. Activation path: 2) Injection of dependency IRepository
into parameter repository of constructor of type TripManagerController
1) Request for TripManagerController
Suggestions: 1) Ensure that you have defined a binding for
IRepository only once.
Is there a way to achieve what I want without creating a new interface for BD oriented repositories?
Thx
The [Named] attribute as shown in the wiki should work.
BTW stay away from anything other than ctor injection!
It would seem you cannot do what you're trying, I've just come across the same issue and as well as finding your question I also found this one where the author of Ninject Remo Gloor replied.
https://stackoverflow.com/a/4051391/495964
While Remo didn't explicitly say it couldn't be done his answer was to name both bindings (or use custom attribute binding, amounting the same thing).

How to properly construct dependent objects manually?

I'm using Ninject.Web.Common and I really like Ninject so far. I'm not used to dependency injection yet so I've got a pretty lame question I can't however google and answer to so far.
Suppose I have a Message Handler which depends on my IUnitOfWork implementation. I need to construct an instance of my handler to add it to Web API config. I've managed to achieve this using the following code:
var resolver = GlobalConfiguration.Configuration.DependencyResolver;
config.MessageHandlers.Add((myproject.Filters.ApiAuthHandler)resolver.GetService(typeof(myproject.Filters.ApiAuthHandler)));
I really dislike typing this kind of stuff so I'm wondering if I'm doing it right. What's the common way of constructing dependent objects manually?
Well I use dependency injection in real world projects only half a year ago, so I'm a pretty new to this stuff. I would really recommend the Dependency Injection in .NET book, where all the concepts are described pretty well and I learned a lot from it.
So far for me what worked the best is overwriting the default controller factory like this:
public class NinjectControllerFactory : DefaultControllerFactory
{
private IKernel _kernel;
public NinjectControllerFactory()
{
_kernel= new StandardKernel();
ConfigureBindings();
}
protected override IController GetControllerInstance(RequestContext requestContext,
Type controllerType)
{
return controllerType == null
? null
: (IController)_kernel.Get(controllerType);
}
private void ConfigureBindings()
{
_kernel.Bind<IUnitOfWork>().To<MessageHandler>();
}
}
And in the Global.asax in the Application_Start function you just have to add this line:
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
This approach is called the composition root pattern and considered the "good" way for dependency injection.
What I would recommend as well that if you have multiple endpoints like services and other workers as well you should create an Application.CompositionRoot project and handle there the different binding configuration for the different endpoints for your application.

WCF - contracts versioning (by example)

This should be easy for someone familiar with the best practices of versioning service/data contracts. I want to make sure that I will use this versioning in the correct way.
So, let's say we have a service contract:
[ServiceContract(Namespace="http://api.x.com/Svc1")]
public interface IService1
{
[OperationContract(Name = "AddCustomer")]
bool AddCustomer(DTOCustomer1 customer);
}
and data contract:
[DataContract(Name="Customer", Namespace="http://api.x.com/Svc1/2011/01/DTO")]
public class DTOCustomer1
{
[DataMember(Name="Name")]
public string Name { ... }
}
if I really need to change the latter into something else: (the following is just example)
[DataContract(Name="Customer", Namespace="http://api.x.com/Svc1/2012/01/DTO")]
public class DTOCustomer2
{
[DataMember(Name="Name")]
public string Name { ... }
[DataMember(Name="Address")]
public DTOAddress Address { ... }
}
...then how shall I use DTOCustomer2 instead of DTOCustomer1 from the service so that old and new clients will be compliant? What is recommended in this case? Will my service contract change? AFAIK I won't need to change the service contract. How will the service contract look like? Do I need a new endpoint? Do I need a new operation contract making use of the new data contract?
EDIT1:
Simply changing
bool AddCustomer(DTOCustomer1 customer);
into
bool AddCustomer(DTOCustomer2 customer);
will do?
EDIT2:
Answer to EDIT1 is No, since DTOCustomer2 has different namespace, but it might work if it has the same namespace. Still I don't know what is the best thing here and expect somebody to come up with a good answer.
Thank you in advance!
I ended up answering to this question with the help of another question here: WCF - handle versioning
Please find some useful links that describe the best practise for Data contract versioning.
Best Practices: Data Contract Versioning
Data Contract Versioning
The 2nd link describes on how you handle when you want to add or removed attributes of your data contract and few other scenarios.
Hope that helps.

Error trying to implement Code First (CTP 5) in WCF Data Service

I am trying to implement Code First (CTP 5) in my WCF Data Service (OData). Its a simple scenario, but I get a HTTP 500 Internal Server Error with no much details. I put this on Data Service to show fault error details.
[System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)]
However I still don't see what is going wrong.
In Constructor of my DbContext implementation I am calling base class with Connection string like below.
public MyContext() : base("MyConnection")
{
}
And I have a simple member in it like this.
public DbSet<MyData> MyData{ get; set; }
I implemented the members of MyData class as needed.
All I get in browser is 500 Internal server error without any further details.
What could wrong with my implementation?
After some research, trial and error I found the issue. Putting it here to help others landing in this situation. One of the objects in my Model is being treated as a Complex Type and I am referring to it in another POCO object in my Model as a Collection, which apparently is not supported by EF Code First (which makes sense). This links helped me understand it better.
[Complex Types]
http://weblogs.asp.net/manavi/archive/2010/12/11/entity-association-mapping-with-code-first-part-1-one-to-one-associations.aspx
[Conventions in CodeFirst]http://blogs.msdn.com/b/efdesign/archive/2010/06/01/conventions-for-code-first.aspx
Please be aware that there could be many such instances of 500 which is causd due to improper modellign of Objects. Make sure to verify the Conventions and how Code First works in background to understand thee relationships.