Can I use both the JAX-RS and RAML extensions in Restlet in the same application? - jax-rs

I am preparing a ReSTful service which I would like to have documented using RAML (and perhaps Swagger as well), but it seems that I cannot implement both JAX-RS and RAML in the same application at the same time.
I have created an Application class for JAX-RS as follows:
public class Application extends javax.ws.rs.core.Application {
#Override
public Set<Class<?>> getClasses() {
// Use the reflections library to scan the current package tree for
// classes annotated with javax.ws.rs.Path and add them to the JAX-RS
// application
Reflections reflections = new Reflections(this.getClass().getPackage().getName());
return reflections.getTypesAnnotatedWith(Path.class);
}
}
I attach the JAX-RS Application object as follows:
Component component = new Component();
Server server = new Server(Protocol.HTTP, PORT);
component.getServers().add(server);
JaxRsApplication jaxRsApplication = new JaxRsApplication(component.getContext().createChildContext());
jaxRsApplication.add(new Application());
jaxRsApplication.setObjectFactory(objectFactory);
component.getDefaultHost().attach("/rest", jaxRsApplication);
And I would also like to implement the RAML extension, but it looks like it is tied to the Restlet Router and having it's own Application class. Is there a way to combine the two?

Indeed the RAML extension of Restlet isn't designed to be used within JAXRS application. That said you can define a resource that provide the RAML content based on classes ApplicationIntrospector of Restlet and RamlEmitter of RAML parser, as described below:
public class RamlResource {
private Definition definition;
#Path("/raml")
#GET
public String getRaml() {
return new RamlEmitter().dump(RamlTranslator
.getRaml(getDefinition()));
}
private synchronized Definition getDefinition() {
if (definition == null) {
synchronized (RamlResource.class) {
definition = ApplicationIntrospector.getDefinition(
Application.getCurrent(),
new Reference("/"), null, false);
}
}
return definition;
}
}
It's the way the RAML extension of Restlet works. You could also use such an approach for Swagger but be careful since Swagger 1.2 requires several resources (a main and several sub ones with each categories). It's not the case anymore for Swagger 2.
You can notice that there is a JAX-RS support for Swagger in the extension org.restlet.ext.swagger.
----- Edited
Perhaps can you make a try with this class that corresponds to a port of the class JaxRsApplicationSwaggerSpecificationRestlet to RAML. It's based on the class JaxRsIntrospector which seems relevant for JAX-RS application:
public class JaxRsApplicationRamlSpecificationRestlet extends Restlet {
private Application application;
private String basePath;
private Reference baseRef;
private Definition definition;
public JaxRsApplicationRamlSpecificationRestlet(Application application) {
this(null, application);
}
public JaxRsApplicationRamlSpecificationRestlet(Context context, Application application) {
super(context);
this.application = application;
}
public void attach(Router router) {
attach(router, "/api-docs");
}
public void attach(Router router, String path) {
router.attach(path, this);
router.attach(path + "/{resource}", this);
}
public Representation getApiDeclaration() {
Raml raml = RamlTranslator.getRaml(
getDefinition());
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
try {
return new StringRepresentation(
mapper.writeValueAsString(raml),
MediaType.APPLICATION_YAML);
} catch (Exception ex) {
return new StringRepresentation("error");
}
}
public String getBasePath() {
return basePath;
}
private synchronized Definition getDefinition() {
if (definition == null) {
synchronized (JaxRsApplicationRamlSpecificationRestlet.class) {
definition = JaxRsIntrospector.getDefinition(application,
baseRef, false);
}
}
return definition;
}
#Override
public void handle(Request request, Response response) {
super.handle(request, response);
if (Method.GET.equals(request.getMethod())) {
response.setEntity(getApiDeclaration());
} else {
response.setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED);
}
}
public void setApiInboundRoot(Application application) {
this.application = application;
}
public void setApplication(Application application) {
this.application = application;
}
public void setBasePath(String basePath) {
this.basePath = basePath;
// Process basepath and check validity
this.baseRef = basePath != null ? new Reference(basePath) : null;
}
}
You can use this class like this:
JaxRsApplication application
= new JaxRsApplication(component.getContext());
MyApplication app = new MyApplication();
application.add(app);
new JaxRsApplicationRamlSpecificationRestlet(app);
(...)
There is no need for a dedicated resource. Please note that this code is a bit experimental ;-) I could propose it back for a contribution for the extension raml in Restlet...
Hope it helps you,
Thierry

Related

Define class dynamically with Service Locator - Asp.Net Core

I am working with Asp.Net Core application. I have two classes namely Online and Offline. I have created interface and defined the methods in these two classes. Based on the need I have to connect to anyone of these two classes.
Previously when I worked in Asp.Net MVC, I have used unity container and Service Locator to specify the class name in XML file for invoking the class dynamically (between online and offline).
Now I want to implement the same with Asp.Net core. But I am not sure how to specify the class name outside for method invocation. Kindly help.
Thanks
In .net core dependency injection is in built. You don't need unity or any other any more.
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-5.0
You can achieve what you want by using a little tweak.
//// classes
public interface IFileUploadContentProcess
{
IEnumerable<StoreOrder> ProcessUploads(IFormFile file);
}
public class ProcessExcelFiles : IFileUploadContentProcess
{
public IEnumerable<StoreOrder> ProcessUploads(IFormFile file)
{
throw new NotImplementedException();
}
}
public class ProcessCsvFiles : IFileUploadContentProcess
{
public IEnumerable<StoreOrder> ProcessUploads(IFormFile file)
{
throw new NotImplementedException();
}
}
//// register it
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddTransient<IStoreOrderService, StoreOrderService>();
services.AddTransient<ProcessExcelFiles>();
services.AddTransient<ProcessCsvFiles>();
// Add resolvers for different sources here
services.AddTransient<Func<string, IFileUploadContentProcess>>(serviceProvider => key =>
{
return key switch
{
"xlsx" => serviceProvider.GetService<ProcessExcelFiles>(),
_ => serviceProvider.GetService<ProcessCsvFiles>(),
};
});
}
//use it
public class StoreOrderService : IStoreOrderService
{
private readonly Func<string, IFileUploadContentProcess> _fileUploadContentProcess;
public StoreOrderService(Func<string, IFileUploadContentProcess> fileUploadContentProcess)
{
_fileUploadContentProcess = fileUploadContentProcess;
}
public async Task<IEnumerable<StoreOrder>> UploadStoreOrdersAsync(IFormFile file)
{
//// passing csv to process csv type(default), if xlsx, pass xlsx
var records = _fileUploadContentProcess("csv").ProcessUploads(file);
return records;
}
}
After lot of brainstroming, I found the below solution
Create a class for ServiceLocator
public class ServiceLocator
{
private ServiceProvider _currentServiceProvider;
private static ServiceProvider _serviceProvider;
public ServiceLocator(ServiceProvider currentServiceProvider)
{
_currentServiceProvider = currentServiceProvider;
}
public static ServiceLocator Current
{
get
{
return new ServiceLocator(_serviceProvider);
}
}
public static void SetLocatorProvider(ServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public object GetInstance(Type serviceType)
{
return _currentServiceProvider.GetService(serviceType);
}
public TService GetInstance<TService>()
{
return _currentServiceProvider.GetService<TService>();
}
}
Step 2: Create interface and inherit in the classes and define the interface methods
Step 3: Define class name in appSettings.json and read the values in startup.cs
public void ConfigureServices(IServiceCollection services)
{
//reading from appSettings.json
string strClassName = Configuration["DependencyInjection:className"];
if (strClassName == "OnlineData")
services.AddTransient<<<InterfaceName>>, <<OnlineClassName>>>();
if (strClassName == "OfflineData")
services.AddTransient<<<InterfaceName>>, <<OfflineClassName>>>();
}
Step 4: Create object for the dynamic class inside controller/action method
InterfaceNamemyService = ServiceLocator.Current.GetInstance<>();

Unable to set WriteTimeout on reactor-netty version 0.9.10

I have written a Reactive API using Spring WebFlux version 2.3.0.RELEASE having reactor-netty version 0.9.10. As part of the API's SLA, I want to timeout the request if the Server takes more than the stipulated configured WriteTimeout.
Sharing the code snipped below where I have implemented a customizer for NettyReactiveWebServerFactory.
#Bean
public WebServerFactoryCustomizer serverFactoryCustomizer() {
return new NettyTimeoutCustomizer();
}
class NettyTimeoutCustomizer implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> {
#Override
public void customize(NettyReactiveWebServerFactory factory) {
int connectionTimeout = 1000;
int writeTimeout = 1;
factory.addServerCustomizers(server -> server.tcpConfiguration(tcp ->
tcp.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectionTimeout)
.doOnConnection(connection ->
connection.addHandlerLast(new WriteTimeoutHandler(writeTimeout)))));
}
}
In spite of the Customizer, the WriteTimeout is Not Working for the API.
Instead of defining a WebServerFactoryCustomizer bean, create a bean of NettyReactiveWebServerFactory to override Spring's auto-configuration.
#Bean
public NettyReactiveWebServerFactory nettyReactiveWebServerFactory() {
NettyReactiveWebServerFactory webServerFactory = new NettyReactiveWebServerFactory();
webServerFactory.addServerCustomizers(new MyCustomizer());
return webServerFactory;
}
Now the MyCustomizer will look something like this:
public class MyCustomizer implements NettyServerCustomizer {
#Override
public HttpServer apply(HttpServer httpServer) {
return httpServer.tcpConfiguration(tcpServer -> tcpServer.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000)
.bootstrap(serverBootstrap -> serverBootstrap.childHandler(new ChannelInitializer<Channel>() {
#Override
protected void initChannel(Channel channel) throws Exception {
channel.pipeline().addLast("writeTimeoutHandler", new WriteTimeoutHandler(1));
}
}))
);
}
}
This is the way suggested in the official API doc

Pass data from android service to ContentPage in Xamarin Form based application

I am having one Application based on XamarinForms.
One background service I have created in Android project and that service would like to send data to ContentPage(which is in PCL) which is displayed to user.
How could I pass data to ContentPage(From xx.Droid project to PCL)?
One solution is:
To Create class in PCL with static variable(e.g. var TEMP_VAR), which will be accessed from xxx.Droid project.
Update value of that static variable(TEMP_VAR) from the service class from the xxx.Droid project.
Need to create Notifier on that static variable(TEMP_VAR)
Update the content page using MessageCenter Mechanism if require.
If there is any better solution, could you please provide me?
This can be achieved using the concept of C#
Dependency service
Event
Need to have 4 classes for such an implementation:
Interface in PCL(e.g. CurrentLocationService.cs) with event handlers defined in it.
namespace NAMESPACE
{
public interface CurrentLocationService
{
void start();
event EventHandler<PositionEventArgs> positionChanged;
}
}
Implementation of interface of PCL in xxx.Droid project (e.g. CurrentLocationService_Android.cs) using Dependency service
class CurrentLocationService_Android : CurrentLocationService
{
public static CurrentLocationService_Android mySelf;
public event EventHandler<PositionEventArgs> positionChanged;
public void start()
{
mySelf = this;
Forms.Context.StartService(new Intent(Forms.Context, typeof(MyService)));
}
public void receivedNewPosition(CustomPosition pos)
{
positionChanged(this, new PositionEventArgs(pos));
}
}
ContentPage in PCL - which will have object of implementation of interface.
Object can be obtained by
public CurrentLocationService LocationService
{
get
{
if(currentLocationService == null)
{
currentLocationService = DependencyService.Get<CurrentLocationService>();
currentLocationService.positionChanged += OnPositionChange;
}
return currentLocationService;
}
}
private void OnPositionChange(object sender, PositionEventArgs e)
{
Debug.WriteLine("Got the update in ContentPage from service ");
}
Background service in xxx.Droid project. This service will have reference of implementation of dependency service CurrentLocationService.cs
[Service]
public class MyService : Service
{
public string TAG = "MyService";
public override IBinder OnBind(Intent intent)
{
throw new NotImplementedException();
}
public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId)
{
Log.Debug(TAG, TAG + " started");
doWork();
return StartCommandResult.Sticky;
}
public void doWork()
{
var t = new Thread(
() =>
{
Log.Debug(TAG, "Doing work");
Thread.Sleep(10000);
Log.Debug(TAG, "Work completed");
if(CurrentLocationService_Android.mySelf != null)
{
CustomPosition pos = new CustomPosition();
pos.update = "Finally value is updated";
CurrentLocationService_Android.mySelf.receivedNewPosition(pos);
}
StopSelf();
});
t.Start();
}
}
Note : PositionEventArgs class need to be created as per usage to pass on data between service and ContentPage.
This works for me like charm.
Hope so this would be helpful to you.

SignalR, WebAPI and MVC sharing the same dependency resolver kernel

I have an ASP.NET MVC app with SignalR and WebAPI. The app uses Ninject for dependency injection, but apparently SignalR and WebAPI are getting different kernels, so it fails to share a singleton object that should be shared for all the application.
I can see clearly in the log how an instance is created when SignalR gets a connection request, and other when WebAPI gets a request.
I want to have the same Ninject kernel shared among these three elements, so I can have unique singletons.
This is what I have done so far:
The first thing I have done is creating a NinjectModule declaring the binding:
public class MyDependencyModule: NinjectModule
{
public override void Load()
{
var binding = Bind<MustBeSingleton>().ToSelf();
binding.OnActivation((ctx, o) =>
{
Debug.Print("Registering item " + o.GetHashCode());
HostingEnvironment.RegisterObject(o);
});
binding.OnDeactivation(o =>
{
Debug.Print("Unregistering game connection " + o.GetHashCode());
});
binding.InSingletonScope();
}
}
I have also created a wrapper for Ninject in order to plug it in WebAPI:
public class NinjectDependencyScope : IDependencyScope
{
private IResolutionRoot resolver;
internal NinjectDependencyScope(IResolutionRoot resolver)
{
this.resolver = resolver;
}
public void Dispose()
{
IDisposable disposable = resolver as IDisposable;
if (disposable != null)
disposable.Dispose();
resolver = null;
}
public object GetService(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has already been disposed");
return resolver.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has already been disposed");
return resolver.GetAll(serviceType);
}
}
public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver(IKernel kernel)
: base(kernel)
{
this.kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectDependencyScope(kernel.BeginBlock());
}
}
Also, I have created another wrapper for SignalR:
public class SignalRNinjectDependencyResolver : DefaultDependencyResolver
{
private readonly IKernel _kernel;
public SignalRNinjectDependencyResolver(IKernel kernel)
{
_kernel = kernel;
}
public override object GetService(Type serviceType)
{
return _kernel.TryGet(serviceType) ?? base.GetService(serviceType);
}
public override IEnumerable<object> GetServices(Type serviceType)
{
return _kernel.GetAll(serviceType).Concat(base.GetServices(serviceType));
}
}
Then I have created a Ninject kernel that does all the config:
public class ApplicationDependencies:StandardKernel
{
public ApplicationDependencies()
:base(new MyDependencyModule())
{
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(this);
Microsoft.AspNet.SignalR.GlobalHost.DependencyResolver = new SignalRNinjectDependencyResolver(this);
}
}
The MVC application, uses NinjectHttpApplication as base class, so I indicate the kernel that must be used this way:
public class MvcApplication : Ninject.Web.Common.NinjectHttpApplication
{
protected override Ninject.IKernel CreateKernel()
{
return new ApplicationDependencies();
}
}
Also, in the SignalR configuration I specify the Resolver:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR<MyPersistentConnection>("/updates", new ConnectionConfiguration()
{
Resolver = GlobalHost.DependencyResolver
});
}
}
(I have tried also without specifying the resolver, and it does not work either).
Any idea?
Cheers.
I found the answer in another post: Singleton Scope binding not working as intended
Rather than binding as a singleton, "ToConstant" must be used:
var binding = Bind<MustBeSingleton>().ToConstant(new MustBeSingleton());
I have created a simple demo project with ASP.NET MVC, WebAPI and SignalR using the same dependency injection context.
https://drive.google.com/file/d/0B52OsuSSsroNX0I5aWFFb1VrRm8/edit?usp=sharing
The web app, contains a single page that shows the AppDomain and GetHashCode of an object that is supposed to be unique across the three frameworks, giving a result similar to:
Dependency Test
Framework IMySingletonService instance
MVC AppDomainId:2 / HashCode:5109846
WebAPI AppDomainId:2 / HashCode:5109846
SignalR AppDomainId:2 / HashCode:5109846
Other problem was, that Ninject was disposing my singleton because was IDisposable. I don't really understand why this happens, but that is another war.
Cheers.
In order keep this 3 things working.. you should check these references out:
Web API + Ninject
http://www.peterprovost.org/blog/2012/06/19/adding-ninject-to-web-api/
SignalR + Ninject https://github.com/SignalR/SignalR/wiki/Extensibility (last part:
When using ASP.NET MVC, configure SignalR first, then ASP.NET MVC)
For the second one, I refactored a little bit, since I need the kernel for SignalR Dependency Resolver
// Route SignalR.
GlobalHost.DependencyResolver = NinjectWebCommon.GetSignalrResolver();
RouteTable.Routes.MapHubs();
I defined GetSignalrResolver inside of NinjectWebCommon like this:
public static Microsoft.AspNet.SignalR.Ninject.NinjectDependencyResolver GetSignalrResolver()
{
return new Microsoft.AspNet.SignalR.Ninject.NinjectDependencyResolver(bootstrapper.Kernel);
}
Note: There are 2 different DependencyResolver: one for Web API (1) assigned to GlobalConfiguration.Configuration.DependencyResolver and the other for SignalR (2) assigned to GlobalHost.DependencyResolver
in order to use a dependency resolver for both WebApi and SignalR you need to implement a class that looks like this:
public class NinjectDependencyResolver : Microsoft.AspNet.SignalR.DefaultDependencyResolver,
System.Web.Http.Dependencies.IDependencyResolver
{
public readonly IKernel Kernel;
public NinjectDependencyResolver(string moduleFilePattern)
: base()
{
Kernel = new StandardKernel();
Kernel.Load(moduleFilePattern);
}
public override object GetService(Type serviceType)
{
var service = Kernel.TryGet(serviceType) ?? base.GetService(serviceType);
return service;
}
public override IEnumerable<object> GetServices(Type serviceType)
{
IEnumerable<object> services = Kernel.GetAll(serviceType).ToList();
if (services.IsEmpty())
{
services = base.GetServices(serviceType) ?? services;
}
return services;
}
public System.Web.Http.Dependencies.IDependencyScope BeginScope()
{
return this;
}
public void Dispose()
{ }
}
then in your startup class you should register NinjectDependencyResolver for both WebApi and SignalR, like this:
public void Configuration(IAppBuilder app)
{
var dependencyResolver = new NinjectDependencyResolver("*.dll");
var httpConfiguration = new HttpConfiguration();
httpConfiguration.DependencyResolver = dependencyResolver;
app.UseWebApi(httpConfiguration);
var hubConfig = new HubConfiguration { Resolver = dependencyResolver };
app.MapSignalR(hubConfig);
}

Using one Dependency Resolver for SignalR and standard MVC controllers?

Currently I am using Unity 3.x as my IoC. I also using the Unity.MVC4 library to help manage the lifetime of my resolver. Here is what my resolver looks like:
namespace Wfm.Core.Common.Mvc.Unity
{
public class WfmDependencyResolver : UnityDependencyResolver
{
public WfmDependencyResolver(IUnityContainer container) : base(container)
{
}
private static WfmDependencyResolver _wfmGrabbrResolver;
public static WfmDependencyResolver Instance { get { return _wfmGrabbrResolver ?? (_wfmGrabbrResolver = new WfmDependencyResolver(InstanceLocator.Instance.Container)); } }
}
}
The UnityDependencyResolver comes from the Unity.MVC4 library. In my Globabl.asax.cs file I am setting the resolver like this:
DependencyResolver.SetResolver(WfmDependencyResolver.Instance);
Here is my singleton InstanceLocator class:
public class InstanceLocator
{
private static InstanceLocator _instance;
public IUnityContainer Container { get; private set; }
private InstanceLocator()
{
Container = new UnityContainer();
}
public static InstanceLocator Instance
{
get { return _instance ?? (_instance = new InstanceLocator()); }
}
public T Resolve<T>()
{
try
{
return WfmDependencyResolver.Instance.GetService<T>();
}
catch(Exception ex)
{
return default(T);
}
}
public T ResolvewithoutManager<T>()
{
try
{
return Container.Resolve<T>();
}
catch (Exception)
{
throw;
}
}
}
This obviously works well from my MVC controllers, but what would be a good solution to allow my application to resolve inside my Hub controllers along with my MVC controllers. Currently, I created a singleton class that allows me to resolve my types manually. I can specifically resolve my types inside my Hubs using my the class like this:
InstanceLocator.Instance.Resolve<ISomeInterface>();
While this works, its not ideal from a development standpoint. Reason being, I want my types to be injected and not manually instantiated. My hubs and Controllers are inside the same MVC application and I do not want to have separate them right now.
There's an entire article devoted to dependency injection in SignalR: http://www.asp.net/signalr/overview/extensibility/dependency-injection
So all you have to do is write a custom dependency resolver for SignalR which obviously will be a simple wrapper to your commonly shared Unity container.