I'm attempting to use Windsor and NHibernate in a medium trust environment and I'm running up against some problems with permissions. I have read through the other questions on this but I'm using Windsor's NHibernate facility which I haven't seen discussed.
For some reason there is a dependency on the Castle.Service.Transations assembly when the container starts up. This then tries to create and instance of:
Castle.Services.Transaction.CallContextActivityManager()
A security exception is raised as CallContextActivityManager tires to use SetData in System.Runtime.Remoting.Messaging.CallContext which is only allowed if you have infrastructure permission. I'm guessing that medium trust apps don't.
Does anyone know a way around this security issue in medium trust? Should I dump the NHibernate facility and register it manually with the container?
You can get around this by registering the TLSActivityManager in the container (for type IActivityManager). The DefaultTransactionManager (used by NHibernateIntegrationFacility) will then use this ActivityManager instead of firing off a new CallContextActivityManager.
Related
I'm trying to get rid of XML in my project.
I already tried to add this:
JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
sf.setResourceClasses(CustomerService.class);
sf.setAddress("http://localhost:9000/");
sf.create();
to my Activator class, but my bundle wont start with this.
So, how usually people configuring endpoints?
(Sorry, no code, just some high level insights from my experience/projects)
I use jersey and its integration into the OSGi environment. I.e. org.glassfish.jersey.servlet.ServletContainer to which I register all jax-rs resources. This way, I can use whatever HTTP server implementation is available (for example, jetty) and configure it via the OSGi system environment properties.
For simplicity, I re-register annotated OSGi (declarative) services as singleton resources/endpoints into that ServletContainer.
Maybe, CXF has also a similar approach.
I can't seem to get the Castle Windsor Integration working for Mass Transit over RabbitMQ. Everything was working fine until I introduced Windsor into the picture. I referenced Castle.Windsor 3.2 and MassTransit.WindsorIntegration 2.9 and configured the container for use within my application. I'm registering the MassTransit Consumers via:
Container.Register(..., Types.FromThisAssembly().BasedOn<IConsumer>());
When I debug and inspect the container after this line is ran, I can see that it successfully registered all of the consumers along with all of my other components. I then have the following code to initialize and register the service bus:
var serviceBus = ServiceBusFactory.New(sbc =>
{
sbc.UseRabbitMq();
sbc.ReceiveFrom(Config.ServiceBusEndpoint);
sbc.Subscribe(sc => sc.LoadFrom(Container));
});
Container.Register(Component.For<IServiceBus>().Instance(serviceBus));
I am using the LoadFrom(IWindsorContainer container) extension method provided by MassTransit.WindsorIntegration.
All of the examples I've found so far stop here and indicate that this is all you should have to do. Unfortunately for me my Consumers are never being called and messages are just piling up in the queue (eventually timing out and going to error queue). The fact that messages are showing up in the Consumer queue at all (+ I see a single consumer bound to the queue via the RabbitMQ Admin Tool) indicates to me that the consumers are probably being subscribed properly - so I'm not sure where the problem lies.
I added NLog logging for Windsor and MassTransit but no errors are showing up in the logs. I'm not sure how I should proceed troubleshooting at this point. Any ideas?
Also, this application is currently just a console application using Topshelf for development. Ultimately it will be installed as a Windows Service. Not sure if that is relevant or not but I thought I'd mention it just in case.
UPDATE
As a test I created a very simple Consumer with a parameter-less constructor for processing a very simple test message. This Consumer is successfully called! The "real" Consumers however have dependencies that need to be injected into them via the constructor. I was hoping the Container would resolve these but apparently it's having some sort of trouble. Weird that nothing is showing up in the logs about it. Stay tuned...
Okay I figured it out. Somewhere along the way when I was adding/removing NuGet packages I somehow managed to delete a reference to a DLL (ServiceStack.Text.dll) that one of my components needed (RedisClientsManager).
I started the debugger, let all my components get registered then popped open the Immediate Window and attempted to resolve each component one by one (by calling container.Resolve<RegisteredType>()) until I found the one that threw the exception when I attempted to resolve it.
The Exception message from Windsor at that point told me exactly what the problem was. I'm a little lost as to why this wasn't being logged or why the Exception was not raised when the container itself attempted to resolve it. Anyhow, moral of the story is make sure your components resolve.
I am testing the tomcat7 clickstack for our application which has some config parameters set using the built in Config features of Cloudbees. The tomcat7 clickstack does not find them, but the standard tomcat6 container does. I have double checked them and reset them through the cloudbees sdk and they are there and correct, but are coming back as null for tomcat7.
The switch to clickstacks requires us to refactor how the servlet container gets configured so that the injection points such as cloudbees-web.xml and jvm system properties behave consistently across all the servlet container clickstacks.
Some of that refactoring has been committed but some of the work is still in my backlog... Assuming none of the other bees steal that task from my backlog before I get to it ;-)
IF I recall correctly, the parameters should be available as environment variables (sub optimal I know, but all containers should be giving this as a consistent UX for all clickstacks, eg both non-java based and java-based) and may be already available as system properties (again sub optimal, but the java container refactoring should be giving this as a consistent UX for all java based clickstacks). The consistent java servlet UX has not been committed yet but should be available soon.
I've got a class library doing all my NHibernate stuff. It also handles all the mapping using Fluent NHibernate - no mapping files to deploy.
This class library is consumed by a number of apps, including a Windows Service running on my computer. Although it works fine in all my web apps, the Windows Service gets this when it tries to use NHibernate:
An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.
at FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory()
at Kctc.NHibernate.KctcSessionFactory.get_SessionFactory() in C:\Kctc\Trunk\Kctc.NHibernate\KctcSessionFactory.cs:line 28
...more stack trace...
I have checked for an InnerException and there doesn't appear to be one. I have no idea what the PotentialReasons collection is, and Google doesn't seem to be forthcoming either.
This is my dev machine, so when I'm working on my web apps they run locally (i.e. using the web server in Visual Studio). The fact that the Windows Service and my dev web apps are running on this same machine suggest it's not to do with trust settings or what have you.
Can anyone suggest what I should try? This is one of those ones where I'm so stumped I can't even think of how to get more information about the problem.
Just a wild guess. NHibernate picks up the hibernate.cfg.xml file from the execution directory. Did you configure the execution directory of the service that it can find this file?
I've found out what the problem is. The Service did not deploy with the required NHibernate.ByteCode.LinFu.dll.
I appear to have an ongoing problem with the Visual Studio compiler not always copying indirect dependencies (i.e. dlls required by class libraries required by the app) into the output folder during the build. I should have thought of this sooner really.
Thanks for racking your brains on my behalf guys.
I bet the name of the connection string is missing from the app.config. For me that message is almost exclusively a missing connection string.
Are you targeting the same database or could it be some sort of schema mismatch between databases?
Could it be authentication issues on the service like you use windows authentication where it can't be used (or the sql authentication that doesn't work)?
It's hard to tell when there is no code, just an exception!
EDIT Are you ever using HttpContext, HostingEnvironment or anything else specific to "web"?
I have a sharp architecture project and I am making use of ApplicationServices in it as well.
There is requirement to provide a winform client that will use a wcf service. The wcf service will in turn use the ApplicationServices. I have not started working on the winform client yet but I am working on the wcf service.
Following the Northwind sample. I have created a "Wcf Service library" project and a "Wcf Service Application" project in my solution.
I am new to wcf but i know all the basics and have worked with web services alot in the past. I have following questions:-
1) I would like to know why there is a need of two projects, wcf library and wcf application?
2) I have noticed that the ITerritoriesWcfService interface in the Northwind sample inherits ICloseableAndAbortable.
public interface ITerritoriesWcfService : ICloseableAndAbortable
What is the purpose of ICloseableAndAbortable?
3) There is another class TerritoriesWcfServiceClient
public partial class TerritoriesWcfServiceClient : ClientBase<ITerritoriesWcfService>, ITerritoriesWcfService
What is the purpose of this class?
4) In the TerritoriesService.svc file, what is the purpose of Factory="SharpArch.Wcf.NHibernate.ServiceHostFactory, SharpArch.Wcf" ? Usually in a normal wcf service application, I use codebehind attribute, but since the .cs file actually resides int the wcf service library project, I would like to know what following code is doing?
<%# ServiceHost Language="C#" Debug="true"
Service="Northwind.Wcf.TerritoriesWcfService"
Factory="SharpArch.Wcf.NHibernate.ServiceHostFactory, SharpArch.Wcf" %>
Even if I remove the above Factory attribute, I can still run the service app project and test the service using WcfTestClient utility.
6) When i run my service and using WcfTestClient If I run a method twice that accesses a repository, then on the second call, I get an ObjectDisposedException.
{"Session is closed!\r\nObject name: 'ISession'."}
I believe the NHibernate Session is getting disposed after the first call. How can reinitialise for each call or should I keep it open? I would like to know the best practice?
7) Also If I run the Northwind.Wcf.Web project and click on TerritoriesService.svc
file on the Directory Listing screen, I get the following error
{"Method 'Generate' in type 'Northwind.Data.NHibernateMaps.AutoPersistenceModelGenerator' from assembly 'Northwind.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.":"Northwind.Data.NHibernateMaps.AutoPersistenceModelGenerator"}
I don't understand why is it throwing this error, when i already got the method and the Northwind.Web works fine too.
Awaiting
Nabeel
1) Strictly, you can combine the WCF library and the WCF application
in one assembly. This would mean that you would combine the contracts
and the implementations in one assembly.
If you are using svcutil.exe or Visual Studio (which uses svcutil.exe
in turn) to generate proxy classes for your client, you'd be fine
because the proxy classes are generated from discovery of your
services.
If however, you want to use your own classes for transport, which is
quite common in DTO scenarios and the like, you'd need to reference a
shared library from both the client and the server. If that shared
library would be your combined library/application assembly, the
client would get the application implementation in scope (because it
references the assembly that contains the contracts) and that's really
not something you'd want. The client needs to know as little as
possible about the server, just as much as the contracts expose --
that's what the contracts are for in the first place.
I think it is best practice to separate interfaces/contracts from
implementation anyway because it leads to better separation of
concerns. It's just that most parts of your solution don't need (and
shouldn't) know HOW something is done, just WHAT that something can
do. There are many more advantages over this, such as improved
testability.
2) Taken from the code documentation of ICloseableAndAbortable:
"When implemented by your WCF contracts, they are then interchangable
with WCF client proxies. This makes it simpler to use dependency
injection and to mock the WCF services without having to worry about
if it's a WCF client when you go to close/abort it.".
I think that says it all.
3) The client class is, like the code documentation says, a strongly
typed client proxy. It can be used by clients to talk to the server,
providing a strongly typed class that has members that correspond to
the service operations that can be called on the server.
The advantage of this class is that you don't need to use the
svcutil.exe generated proxy classes. This what they mean by not having
to configure it via WCF configuration. This allows you to ship proxy
classes to your clients so they can immediately talk to your server
instead of generating proxy classes first. It allows for more control
as well, changing the code that is generated by the proxy class is
really not something you'd want to do.
This again is a good reason to put the interfaces/contracts in a
separate assembly because you don't want to ship the service
implementation code to your clients.
4) The service host factory creates a service instance based on the
provided service type. This can come in handy if you want to put the
service code somewhere other than in the code behind file. You'd also
need it if you are using Depency Injection, you'd provide the service
contract interface as the type and the SharpArch.Wcf service host
factory resolves it to the correct implementation class type by means
of the DI framework (Castle Windsor in SA). You can think of this as a
means of getting hold of a service implementation while not caring
about where it actually is coming from.
In this case, the service will run when you remove the factory
attribute, because the default factory is able to resolve the service
type. You're bypassing on stuff like DI and session management though,
exactly that what makes SA valueable.
5) I'll have to skip this one because apparently there is no question number 5 :-)
6) As in the Northwind sample project, you are probably using the ServiceHostFactory that comes with SA. With this service host factory, each created service instance is extended by a behavior that closes the NHibernate session directly after it's called. That okay by itself but chances are that your proxy clients are not managed in a transient way by Castle Windsor. Therefore instances get reused, including the closed sessions they (still) contain. Decorate your client proxy classes with the Transient attribute (Castle.Core.TransientAttribute) and Castle Windsor will create a fresh instance every time a service call is performed.
Apparently, there is a second way to solve this but it requires modification of the S#arpArchitecture code base. See WCF connections which process more than one request fail because the nhibernate session is closed and isn't re-opened. on GitHub.
7) I'm sorry, I seriously have no idea. I might look into this later.