I'm developing servlets and register them into my OSGI container thanks to HttpService.
My goal is to secure all the servlets registered in my OSGI container.
I saw that I can register my Servlet with an HttpContext with my own handleSecurity method implementation to process my security.
But I'm thinking to the case where a bundle registers a servlet with the default HttpContext (with implies no security).
So my question is, is there a way to force the security of all the servlets deployed in my OSGI container once for all?
I'm going to use the Service hook feature (OSGI 4.3) in order to override the behaviour of HttpService.registerServlet. In my hook I'll force the usage of my HttContext implementation.
With this solution, any bundle that register a servlet with the HttpService will be secured by my HttpContext implementation.
The short answer is No for using the HttpService.
The longer answer, you might achieve something like this if you use the whiteboard-extender which isn't available per OSGi spec yet, but felix and pax-web do provide it.
When using the whiteboard-extender you're able to register your servlet in combination with a reference to a HttpContext (as property). Of course this HttpContext would also need to be a "customized" one but you only need to register it once and are able to reference it from your Servlets.
This is probably the closest you get to your question.
If you use the Apache Felix whiteboard extender you can register a Servlet Filter, this is a much better way to handle security since it is easy to support different strategies. The intention is that Filters and whiteboard will be supported in the next update of the Http Service: https://github.com/osgi/design/tree/master/rfcs/rfc0189
You could use hooks as suggested, but please don't. Hooks were intended for deep middleware, not for application oriented aspects. They create start/stop ordering issues, they make the system more opaque for debugging tools, in short they make your system much more complex. If you start using hooks for these purposes you will find many more use cases and they will start to interact. Stay away from them except for very core system middleware.
Related
I need to make several properties accessible from application's business layer. Those are some ids and common settings. Most of them are valid only through request-response lifespan.
This is a web application (ASP.NET Web Forms to be specific) with dependency injection set up.
Currently those properties are passed through method parameters directly to business layer's services. That works but is not very efficient since:
sometimes parameters' values need to be passed deeper obscuring the readability a bit
some properties should be lazy resolved, and this should be done only once per request
retrieving properties which are resolved by touching a database can be confusing for new developers (there is not unified way of doing this)
some services are constructed by a factory which enriches them with some config parameters
I was thinking about introducing an application context interface, with an implementation in the main project, which would be created on every request. It could be injected to the services directly making them parametrized automatically and independently (services won't need the factory anymore).
Is it how this problem should be tackled or maybe there are some other options?
One option I don't like here is that it might bond the main particle with business layer which is not a perfect example of The Clean Architecture.
Id say you solution is a very common one - inject an 'application context' into your classes. One thing I would be careful of though is making sure you are following the Integration Segregation Principle (from SOLID). Dont just start making all your classes expect an application context instance. Instead, design interfaces that split the application context up, and have your classes expect them as dependencies. Your application context will then need to implement all the interfaces.
This is the correct way to do things as it decouples your classes from implementation. Really your classes don't care if their dependency is from one giant application context, they just care about specific methods implemented by it. This will make your code more robust as you will reduce the risk of breaking something if you change the implementation of the application context later on.
Why don't you use some dependency injection container? Your global settings and parameters can be registered to it as pseudo-singletons and then you will be able to neatly request them from any point inside your application.
I have a JSF2 controller/bean/view that is invoked the standard JSF way. Now I have a need to access this logic from a legacy part of the app that knows servlets and URL params only.
I thought of creating a "loader.xhtm" view that bridges the gap between non-jsf requester and the jsf part of the app. Loader will take URL params and make the necessary JSF post to backing bean. etc. One downside of this approach is - it's one extra client/server hop, a programmatic redirect. However it is simple to implement.
But is there a more clever way? I found someone who created servlet filter and explicitly created a FacesContext, started the lifecycle and the ViewRoot. Conceptually I see what is being done, but I don't know how to put it into practice. Has anyone interfaced with JSF lifecycle directly from a servlet? Do you have a sample?
Another mention of this concept.
Ok, so the problem is:
I've got some 'order' entity, and it has 'status' property. On changing status, i wanted some other objects to be informed of this event, so i've decided to use Observer pattern. One of the observers notifies clients via email. Now i want to render Email text's from some of the twig templates. As i get from the Book, rendering templates in controllers are done with 'templating' service.
So the question as it follows: How can i access 'templating' service in my Observer class?
Specification:
I was advised, to implement my Observer as a service, but i'm not sure 'bout that. I've tried to solve this problem, and here is my options:
Use Registry. Solution that is straight and hard as rail. I guess it misses the whole point of DI and Service Container. Huge plus of this solution, is that i can access all common services from any point of my application.
To pass needed services from the context via constructor, or via setters. This is more like in Sf2 spirit. There comes another list of problems, which are not related to this question field.
Use observers as a service. I'm not really sure 'bout this option 'cos, in the book it is written, that service is a common functionality, and i don't think that observing entity with number of discrete properties is a common task.
I'm looking for a Sf2 spirit solution, which will be spread over whole project, so all answers with an explanation are appreciated.
As with any other service in a Symfony2 project, you can access it from within other classes through the dependency injector container. Basically what you would do is register your observer class as a service, and then inject the templating service into your observer service. See the docs for injecting services.
If you're not familiar with how Symfony handles dependency injection, I'd suggest reading that entire chapter of the documentation - it's very helpful. Also, if you want to find all the services that are registered for application, you can use the console command container:debug. You can also append a service name after that to see detailed info about the service.
Edit
I read your changes to the question, but still recommend going down the DI route. That is the Symfony2 spirit :) You're worried that your observer isn't common enough to be used as a service, but there's no hard rule saying "You must use this piece of code in X locations in order for it to be 'common'".
Using the DIC comes with another huge benefit - it handles other dependencies for you. Let's say the templating service has 3 services injected into itself. When using the DIC, you don't need to worry about the templating service's dependencies - they are handled for you. All you care about is telling it "inject the templating service into this other service" and Symfony takes care of all the heavy lifting.
If you're really opposed to defining your observer as a service, you can use constructor or setter injection as long as you're within a container-aware context.
I have a solution with several projects (MyApp.Data, MyApp.BLL, MyApp.Web). I register types in Global.asax file in MyApp.Web (main web application):
builder.RegisterType<SomeService1>().As<ISomeService1>().InstancePerHttpRequest();
builder.RegisterType<SomeService2>().As<ISomeService2>().InstancePerHttpRequest();
//...etc
And I wonder whether it's a bad practice to register types and their scope using attributes in the other assemblies (for example, in MyApp.BLL). See below:
[Dependency(typeof(ISomeService1), ComponentLifeStyle.Transient)]
public class SomeService1 : ISomeService1
{
//methods and properties go here
}
Using local attributes or other ways to indicate wiring for a DI Container tightly couples the service to the DI Container, so I don't think that's a good idea.
Additionally, it may constrain your future options. If, for example, you specify the lifestyle scope, you can't reuse the service with a different scope.
In general, you should compose the application in a Composition Root (global.asax), which gives you a single location with a clearly defined responsibility where all classes are composed.
That would be much more manageable and maintainable that spreading the configuration data all over your classes.
As your question implies, it makes some sense to delegate responsibility for registration to the assembly that knows what needs to be registered. For example, if you
use the SolrNet library, it provides a method that performs component registration, to encapsulate the knowledge of what needs to be registered and to spare the library's consumer from having to learn all about the library before getting started.
However, there is a potential issue with this approach. Would your registration requirements change if you used the dependent assemblies in other applications? For example, would it make sense to register something as ComponentLifeStyle.HttpRequestScoped and then use it in a non-Web application? By delegating registration to the dependency, you are coupling the dependency to its consumer's registration requirements (and to its choice of IoC container).
Autofac (I can't speak for other IoC containers) provides a way round this. It enables you to override registrations so that the most recently registered component is used when a service is resolved. This means that you can call a library's registration method and then register your own services to override the defaults.
There is another problem with your proposed attribute-based registration - it doesn't enable you to specify a lambda expression as a component creator. How would you implement a registration like this with attributes?
builder.Register(c => new A(c.Resolve<B>()));
It might be preferable to define an IRegistrar interface, and then use reflection to search all loaded assemblies for implementations and invoke them. Perhaps something like this:
public interface IRegistrar
{
void RegisterComponents();
}
I am trying to understand Jetty.
Tell me please:
When is it better to use Servlets and when Handlers?
Can I use Connectors with Servlets for "thread-per-request model"?
In Jetty, Handlers handle requests that are coming through Connectors. One of the Handlers, specifically ServletHandler, allows Jetty to (mostly) support servlets. Servlet is a portable Java EE concept, so you can design your application in a more portable way if you use servlets in Jetty. On the other hand, they are likely to bring some overhead, so you might want to implement a Handler directly that would handle requests coming via Connectors.
If you are using servlets in Jetty, you can rely on the servlet security model, on the session support, etc. If this is unnecessary for your application, you might be better off implementing a very simple handler.
One interesting observation I found when played with it. I had a jetty-based application(dropwizard.io) and here I was planning to add handler after actual(there was special use-case for it)
server.start()
using org.eclipse.jetty.servlet.ServletContextHandler.insertHandler(HandlerWrapper handler) it just throws illegalStateException: STARTED if the server already started. Because of:
public void setHandler(Handler handler) {
if (isStarted())
throw new IllegalStateException(STARTED);
//..
But in case of org.eclipse.jetty.servlet.ServletContextHandler.addServlet(ServletHolder servlet,String pathSpec) it will add your servlet to existing servlet collection and everything will work.