How to register Autofac component per http request in web.config? - web-config

In MVC3 application I have my custom implementation of IPrincipal.
I want to register it in web.config and then inject it to constructors by Autofac.
Autofac XML-configuration has attribute "instance-scope" but it does not support "per-http-request".
Any ideas how can I register component per http scope in web.config?
I already tried different combinations of per-dependency, single-instance or per-lifetime-scope with ownership external but results are very buggy.

As Nicholas Blumhardt from Autofac team told me per-lifetime-scope should be used.
When running under ASP.NET it is equivalent to per-HTTP-request in practical terms.

As far as I can see from the source, registering per http request in XML configuration is not supported. As you mention, only the three instance-scope values (per-dependency, single-instance and per-lifetime-scope) are allowed.
Also, looking at how per-http-request scoping works, it uses the InstancePerMatchingLifetimeScope registration call with a httpRequest key. Again, there is no XML config way of configuring a "matching-lifetime-scope".
The way to go is configuration through code.

Related

Workday Studio - request with HTTP out to vendor API receiving error with: No bean named 'http-token-auth' is defined

I have a Workday studio integration to send a GET request to a vendor's API using an HTTP component, but I'm receiving the error below. The vendor doesn't have a username/password to connect. I have to connect using a token. Does anyone know how to make this work from Studio to GET data?
Reason: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'http-token-auth' is defined
I have sent the request in many different ways: hard coding the URL with the token, setting headers with the token. Below are my different attempts.
I’m not sure what Http authorization this is supposed to use. There is no username/password, just a token and a URL to post using CURL. Below is what studio looks like with the HTTP properties.
Below is what is set on the Header.
Also, I'm able to GET data using SoapUI. Below is a snip of the request in SoapUI.
Below is the JSON raw request in SoapUI that is successful in getting data from the API.
Any help is much appreciated!!
Thank you, -Remo
To preface; I'm not familiar with Workday Studio, and there don't seem to be any public docs, so there may be some nuance here that this answer misses.
Summary
Workday, your code, or possibly some library being used is referencing a bean (see Spring docs: Core Technologies) that does not exist or can not be found.
If you're not writing any Java code whatsoever here, it's almost certainly either a configuration issue or bug in Workday Studio. Below are some observations based on the information you've provided. But first, a wild guess.
Wild Guess
It seems likely that Workday is handling this a little differently than cURL or SoapUI. cURL and SoapUI are doing something like the following:
Send GET request to URL with params, and include API key in header
Server sends desired response
However, it sounds like Workday is doing something more like:
Send GET request assuming a pre-auth scenario, using challenge-type: 'token'
Server responds with the correct auth-type that its framework (presumably Rails) uses for tokens; 'http-token-auth'
Workday (wrongly) assumes that the server is using the Spring framework, and tries to load the correct auth-type bean based on that response
Spring framework barfs because there's no such bean
I imagine there's some way to get Workday to play nicely with a standard REST API, and just supply the API key to the vendor's server as it expects, rather than trying to do a challenge/response.
If this isn't it, there are some more weedy possibilities below.
Odd Bean Name
The bean name specified in the error is http-token-auth, which is in kebab-case. The convention for naming beans is (lower-) camelCase, so wherever that's specified may have just used the wrong casing.
This could be in the Workday Studio configuration, the XML config file, or some custom code you've written, if any.
Configuration
If the bean name is correct, then there's likely some other configuration issue. Spring can implicitly detect candidate components by scanning the classpath (see Spring docs: Classpath scanning and managed components) or loading it from the project XML. The issue could be:
The build path is wrong (see this answer by esaj if you're unfamiliar)
The classpath is wrong, so Spring just doesn't see it. This seems like a Workday-specific config in this case.
The bean is in the project XML, but nested. In that case, it'd only be accessible to the enclosing bean. One solution to this is to activate the corresponding profile.
A packaging issue; if the bean isn't being included in the resulting deployed jar, then there will be issues. This solution by dawrutowicz should apply in a number of cases.
Project configuration; all the settings in your screenshots look exactly correct and should work fine, so there might be something hidden in your project settings
Bug in Workday Studio
This seems somewhat less likely, but is always a possibility. If you haven't written any Java code whatsoever, then there's something either in the Workday code that's serving up this unexpected 'http-token-auth' or inappropriately accepting it from somewhere else and trying to load up a bean using it.
Final Thoughts
Since you're trying to work with a vendor's API, I'd strongly recommend you try to collaborate with one of the engineers there. Guaranteed, they have at least one engineer who has dealt with complicated integration issues before. They'll have more details about their API, and might be able to give you more direct input on any configuration/code you'd be able to share.
I had an identical error message reported when sending a Rest POST request to a 3rd party web service from Workday Studio using Bearer authentication.
The resolution was to set the header output type to "message" instead of a "rootpart". It is not a bug in Workday Studio.
Workday Studio set header output type setting
Regards,
Shiraz

Best practices for REST API that access multiple environments

When writing a RESTful API that needs to access different environments such as a lab/test database and a production database, what's the best practices around setting up the API?
Should there be a #PathParam?:
/employee/{emp_id}/{environment}
/{environment}/employee/{emp_id}/
Should there be a #QueryParam?:
/employee/{emp_id}/?environment="test"
/employee/{emp_id}/?environment="prod"
Should there be a field in the payload?:
{"emp_id":"123","environment":"test"}
{"emp_id":"123","environment":"production"}
In fact I see two ways to handle this. The reason to use one or the other corresponds to what is the most convenient to implement in your RESTful application.
Using a path parameter
With this approach, it should be a path parameter at the very beginning of the resource path. So URL would be like this: /{environment}/employee/{emp_id}. Such approach is convenient if you have several applications deployed under different root paths. For example:
/test: application packaged with the configuration for the test environment
/prod: application packaged with the configuration for the production
In this case, applications for each environment are isolated.
Using a custom header
You could also a custom header to specify on which environment to route. Github uses something like that to select the version of the API to use. See this link: https://developer.github.com/v3/#current-version. It's not exactly the same thing but you could have something like that:
GET /employee/{emp_id}
x-env: test
A reverse proxy could handle this header and route the request to the right environment.
I'm not convinced by the approach within the payload since an field environment isn't actually a part of the representation for element resource employee. Regarding the query parameter approach, it's similar since such parameters apply to the request on the resource.
Hope it helps you,

GETting plain content in presence of JAX-RS

I have a project which is basically an Apache Wicket web app, but it also has 3 REST services. I'd like to keep these two different technologies together in one application, as they share quite a lot of classes. Also, I'd like them to share the same JPA instance, as they operate on the same database.
The problem I'm facing is that, as soon as any JAX-RS path is specified, all URLs sent to the application appear to be handled by JAX-RS, even if the REST paths specified don't justify this. Concretely:
#PATH("service")
public class ServiceClassA
#PATH("s1")
public String someMethod...
#PATH("service")
public class ServiceClassB
...
Please note that thereby all defined services have a URI starting "MyAppName/service/...".
The Wicket classes are unaffected by this, as probably the Wicket filter runs before JAX-RS has a chance to grab the URL. But plain resources like css files get in the hands of JAX-RS, resulting in a
No root resource matching request path browser/xxx.css has been found, Relative Path: /browser/xxx.css.
The JAX-RS endpoints contain, in addition to those for the service methods shown above, a general one:
REST Application: http://localhost:8080/MyAppName/ -> org.apache.openejb.server.rest.InternalApplication
As soon as I remove all #PATH annotations, my css is served normally. So I suspect that the endpoint just shown is automatically generated and causes any URI of my app to be handled by the REST framework, even if no path was defined for it. So what I basically need is to tell JAX-RS to ignore
either all URIs not starting with "MyAppName/service",
or all URIs starting with "MyAppName/browser",
or to redirect all URIs it can't handle to the standard Web Server mechanism.
I experimented and googled for possible configuration options quite a lot, but still I didn't find anything suitable for such a simple requirement. I'd appreciate any hints.
BTW, my web.xml is plain vanilla. It contains the wicket filter, mapped to /*, and nothing else, in particular no filtering or servlet for JAX-RS. The server is TomEE-plus 1.6.0.2, and the JAX-RS libraries are the ones shipped with TomEE.
JAX-RS is a servlet so without binding it to a sub context of your app it conflicts with resources. You can provide an Application with #Application("subcontext").
Note: TomEE supports exclusion of some static resources but the configuration is explicit in openejb-jar (https://issues.apache.org/jira/browse/TOMEE-728) so first solution is easier.

GWT: add-linker (cross-site) doens't work with Server code!

I am trying to do some cross-site in GWT.
According to GWT:Same Origin Policy I've added to the module xml file.
It is working okey as long as I am not calling any GWT remote service (using GWT-RPC), but when I try to call any remote service, I got no response!
Any one know how to fix cross-site issue in GWT with GWT remote services?
Thanks in advance!
Steve's answer is correct, however there is one other option you can consider which is the best approach if you want to require authentication for server interaction without using OAUTH. The main point is that the cross-site linker doesn't bypass the SOP, but allows you to host the index.html on a different site than the JS code so that you can have the JS code and servlets on one server and load them from another. To get around the SOP you can use a method called JSON with padding or JSONP. Essentially what it does is use a script tag to inject a foreign request into the environment by wrapping the requested data in a callback. To do this you can use one of many server-side implementations such as Jersey. GWT 2 includes a JsonpRequestBuilder object which does all the client-side work for you and can be used in the same way as RequestBuilder. See this article for a tutorial.
If you want to access some other server (example.com) from your GWT app, then you'll have to do an RPC to your server, and in your server-side code, you'll have to make another HTTP call to the example.com page you're looking for.
The page you linked to regarding cross-site linking outlines that adding <add-linker name="xs"/> to the module file allows you to split your hosting between 2 servers:
One server for static files (all GWT produced html and js files, and all images)
One server for dynamic calls (all your RPCs go here, and your index.html home page must be here)

General question, what do you want from a web framework?

In a MVC application, what are some of the components that make up the application. What tools and functionality is missing that you would like to have. Regardless of the server-side language, what would you want?
I see a lot in my code where I code some much functionality that it seems should already be there. I looked at Google web toolkit and they seem to get it right. Widgets are widgets and you simply add them to your application.
For example. I work with J2EE apps but in other languages, the components are the same.
Controller Objects
Controller handlers, defined by methods in the controller objects.
Configuration files defining the URL mapping and settings.
Template server page files (e.g. JSP/ASP files).
Configuration files defining O/RM mapping between application objects and the database.
Configuration files defining the database connection properties.
JavaScript libraries (e.g. jQuery)
Logging configuration files
Resource message bundle files
Validation configuration files or code
Middleware components and objects (EJB configurations, JMS/Messaging configurations, etc).
Credit Card or other middleware connectivity APIs and libraries.
Anything else you can think of?
Built-in Unit Testing Component
I think one thing you're missing from that very exhaustive list is the automatic binding of request properties to form objects, and the saving of these objects to the session where appropriate. Form objects here being the object on the server that represents the current state of the HTML-based for displayed to the user.
I think scaffolding and automatic admin interfaces are very nice features too, that I dont want to miss ;)
You've made the assumption that all MVC applications are websites. MVC is widely used for more than just web apps so things like URL mappers, template server pages and "Server side" languages are not associated with the MVC pattern, so much as a particular implementation and adaptation of the MVC for use in web apps.