OpenRasta - Pass parameters to custom Codec - openrasta

I've created a new custom JSON codec for OpenRasta which works fine.
I need to pass arguments to the codec's write method when the handler is executed but cannot find any documentation on how to do it.
I notice in the implemented WriteTo method, there is a string[] codecParameters parameter, however no idea how to pass them in.
Anyone come accross this problem before? Thanks

the codec parameters are per-request. They're intended to be used together with (for example) the PathSegmentAsParameterUriDecorator.
For example, if you enable that decorator, the path /resource;segment will be treated as /resource by openrasta, and a parameter will be created with the "segment" value, and passed to the codec.
If you wish to pass information to the codec from the handler, there's nothing there, as architecturally it goes against the design of OpenRasta, which specifically prevents handlers and codecs from talking to each others.
If you wish to pass configuration data to your codec, you use the Configuration property from the ICodec interface, which will be filled with whatever object you have provided at configuration time.
You provide the configuration object either through the paramter in the .TranscodedBy(object configuration) method, or if you do custom registration using the configuration metamodel, bu adding the configuration to your Configuration property on CodecModel (which incidently is used in the ResourceModel object created by the fluent API).
Do you have a specific scenario I can help with?

Related

How to trigger an action on completion/change of a type's property?

I have the following type in my grammar:
TestSuite:
'TestSuite:' name = ID
'Type:' type = SuiteType;
enum SuiteType:
INTERNAL='1' | EXTERNAL='2';
I would like to read an xml file whenever the property gets a (new) value since I use the contents of that xml file for validation and content completion. Depending on the value of the property, the xml that will be read will be different.
How would you trigger an action that would read the value of a property of a type from the runtime environment's DSL instance?
You could maybe try adding an EMF Adapter to all TestSuite instances such that upon a Notification that changes your 'type' feature to a particular value, the XML file of your choice is read and acted upon.
this blog post seems to do the trick: at the end of the linking phase, an Adapter (this is EMF vocabulary, basically a Listener) can be registered for your TestSuite instances.
Then in your Adapter implementation, you can filter whether you need to react using the methods of Notification such as getFeature().
Since you mention you want to do this for content completion and validation, you may need to do all of this in the scoping / validation phases of Xtext. You will probably have a bit of "lag" upon hitting ctrl+space for auto-completion if your IDE needs to find and parse your XML file, but that's to be expected I guess...

When to explicitly close ResourceResolver in Sling

I've read on this blog about how to use resourceResolver properly. The author quotes
If you open a JCR session of a Sling ResourceResolver, you are also
responsible for closing it. On the other hand: If you get passed a
ResourceResolver or a Session object, do not call logout() or close()
on it.
I'm not able to grasp this concept, may be because of no code example in this case.
From what i know, i can get a ResourceResolver object via either request.getResourceResolver() in servlets, using #Reference SCR annotation in OSGi components, jsp's implicit resourceResolver object, using sling.getService() in jsp, and also via adapting to ResourceResolver object.
In all the ways of getting resourceResolver object, which ones should i close myself and what is the session associated with each of these objects ?
Think of it like a File resource.
if you open it, you are responsible for closing it
if you use a reference to the File, then it is not your responsibility to close it
Therefore, your code should open & close in the same scope.
If you obtain a resourceResolver FROM a resource, you did not open the resolver and you do not need to close it.
In the example from the blog, they generate a session from session = repo.loginAdministrative() (Repository no longer has this method); thus is responsible for calling session.logout() in the same scope (using the finally {...} block).

Typhoon: Injecting run-time arguments into a singleton

I'm trying to figure out how to inject run-time arguments into a singleton when it is created, and then have those arguments just be remembered from then on. I'm not sure if the interface for run-time arguments can support this, though. Say, for example, I have a Client object that requires a token, and has the following initializer:
+ (instancetype)initWithToken:(NSString *)token;
The token is obtained at runtime from the server and is different for every user, so I can't simply put the NSString in the definition. So I create the following method on my Typhoon assembly:
- (Client *)clientWithToken:(NSString *)token;
However, in the future (when I'm injecting this client into other classes), I won't have the token on hand to call this method with. So I would like to just be able to inject [self client], for example. Since the client is a singleton and has already been created, the token isn't necessary, anyway.
However, I can't seem to find a way to do this. Obviously, defining a separate method called client would just return a different client. Can I just call clientWithToken:nil and the argument will be ignored if the client already exists? Perhaps traversing the assembly's singletons array would work, but that is obviously very inelegant.
I have considered injecting by type (so I don't need a method to call), but I have multiple different clients of the same type, so I need to be explicit about which client to inject. Of course, there is also the option of removing this parameter from the initializer, and instead setting it as a property from outside the assembly; however this pattern is used throughout our application, so I would like to avoid rewriting that much code.
Thank you.
Reviewing the Typhoon User Guide's 'When to Use Runtime Arguments' shows that this scenario isn't really a good match. Runtime arguments are great when we have a top-level component that mixes some static dependencies with information that is known later - thus avoiding the creation of a custom 'factory' class. Its not possible to use them in the way described.
Instead consider the following suggestions:
Inject a shared context class
Create a mutable Session model object and register it with Typhoon. Update the state on this model when you have a token. Inject this into the clients, which will use this session information when making connections.
Aspect Hook
Hook your clients so that before a method is invoked the token information is available. This could be done by:
Using an Aspects library like this one.
Define a Protocol for the clients and wrap the base implementation in one that is security aware.

OpenRasta: Can I use a generic handler for versioning resources gracefully?

We have an OpenRasta service, and we'd like to use media types to version our resources. We'll have a different set of DTOs for each new version, distinguishable by namespace. For each version of the DTOs, we have a corresponding media type.
So DTOs will be mapped to media types like this:
Namespace.Dto.V1.MyResource -> application/vnd.Namespace.Dto.V1.MyResource+json
Namespace.Dto.V2.MyResource -> application/vnd.Namespace.Dto.V2.MyResource+json
The repository implementation will be specific to the version of the DTOs, but the interface is generic. I would like my handler and codec to be generic as well, so I don't need to copy/paste them for each version of the DTOs. So I want my routes to look like this:
ResourceSpace.Has.ResourcesOfType<V1.MyResource>()
.AtUri("MyResource/{resourceID}")
.HandledBy<MyResourceHandler<Dto.V1.MyResource>>()
.TranscodedBy<MyResourceCodec<Dto.V1.MyResource>>()
.ForMediaType(mediaTypeMapper.GetMediaType(typeof(Dto.V1.MyResource)));
//V2 of DTOs
ResourceSpace.Has.ResourcesOfType<V2.MyResource>()
.AtUri("MyResource/{resourceID}")
.HandledBy<MyResourceHandler<Dto.V2.MyResource>>()
.TranscodedBy<MyResourceCodec<Dto.V2.MyResource>>()
.ForMediaType(mediaTypeMapper.GetMediaType(typeof(Dto.V2.MyResource)));
Should this work? Right now, it appears that my service is handling requests with MyResourceHandler<Dto.V1.MyResource> regardless of the Accept header on a GET request, for example.
Any thoughts? We could change our scheme to use URIs like /v1/MyResource/ instead of using the accept header, but it would be great to get this working.
EDIT:
I should add that part of the reason we are using media types for versioning is because this is a service for internal use, not meant to be accessible on the public web.
You're registering two resource types on the same URI, only one will get selected, there's no way to do the distinction at request time.
I don't think versioning in URIs or media types is a good idea on the web. That said, for what you want (different mediatypes), then use the same resource type and use your codec to fill-in the same type from the incoming / outgoing data. That's teh responsibility of a codec in OR, making the junction between a DTO and a media type format.
On incoming requests, we need to know what resource type you want based on the URI. If you have two different types it ought to be different resources. that said if you do the following that'll work too:
ResourceSpace.Has.ResourcesNamed("myResource").AtUri("/myResource").HandledBy<ResourceV1Handler>().And.HandledBy<ResourceV2Handler>();
ResourceSpace.Has.ResourcesOfType<MyV1Resource>().WithoutUri.TranscodedBy<V1Codec>();
ResourceSpace.Has.ResourcesOfType<MyV2Resource>().WithoutUri.TranscodedBy<V2Codec>();
you can then write
public class handler {
public object Post(MyV1Resource resource) {}
public object Post(MyV2Resource resource) {}
}
and that'll work. What you won't be able to do is implement the get in that way, as OR assumes one resource type == one URI in most instances.
As for generics, if you use an IoC container, you can register your handlers in a generic fashion (aka register typeof(IHandler<>) with typeof(Handler<>)). This means any IHandler will get resolved to Handler. You can then simply register HandledBy>() in your registration and you're done. Same applies to codecs (but then again, codecs in OR are there to deal with media type issues, not just as serialization mechanisms, as serialization in itself is evil for the web and should be used seldomly).

Finding target of LinFu proxy object

This is pretty much a duplicate question but instead of using Castle Dynamic Proxy I'm using LinFu Getting underlying type of a proxy object
I'm using automapper to create proxies of interfaces that I'm sending to my viewmodel in Asp.net MVC. My problem is from what I can tell that MVC's default MetadataProvider find the properties and metadata by calling .GetType() on the model.
So what happens is EditorFor() and DisplayFor() templates don't generate any fields. What I need to do is find the proxy target type and then generate my templates. I know I can just parse the name and use GetType( "thename" ) but was wondering if there was an easy way.
LinFu.DynamicProxy doesn't directly expose the underlying object of a proxy. It simply redirects each method call to an IInterceptor implementation instance. In order to access the underlying object, you'll have to figure out whether or not the current interceptor instance actually has a target class instance, or not.
If you're working with AutoMapper, AFAIK, they use LinFu.DynamicObject to do a lot of the duck taping, and calling GetType() on a dynamic type generated by LinFu.DynamicObject won't even get you the actual type in your domain model--it will just get you an object that has been literally duck-taped together by LinFu itself.
get latest AutoMapper - it uses Castle Dynamic Proxy, and you already know how to get this from there :)

Resources