I am trying to use in jBPM users from existing ASP .NET MVC Web Site.
As I understand from docs and this forum topics (first, second) best solution would be implementing of UserGroupInfoProducer that will call external service. But due lacking of experience with java I faced with several problems.
First approach: Create project with required implementation, deploy it and config jBMP to use it.
Problem was in implement interfaces that declared in another project, I've tried to add maven dependencies but after failing with some classes I've just added reference to required jar.
Deploy it on jboss like war failed, deploying like jar succeeded but server did not find UserGroupInfoProducer and other implemented interfaces.
Another problem in changing config of jbmp-console. Only way that I've found for that is modify archive directly, but I don't this it's right solution.
Second approach: Create own package of jBPM with required classes.
Problem here that I don't know what repository use for this and how to build version for my server.
As I understand from this link I need to use jbmp-console-ng, only maven task for creating war package that I found was in jbpm-console-ng-showcase I've tried to run it (release 6.2.0 Final) on:
On Windows: failed to execute because of maven error about long path, after migrating project to gradle and excluding dependencies on jmxtools-1.2.1.jar and jmxri-1.2.1.jar it created war but jboss failed to start service.
On Mac and Ubuntu using virtual box: it required to downgrade java to 1.6 and built war after this, but it failed to deploy due duplication of some classes.
As I understand you need to build diferently for each version of server but I don't know how to do this.
Third approach: Create come simulation of supported authorization ways. As I understand jBMP support LDAP, JAAS, database and file. Database and files will require duplicating users so I researched about simulating LDAP or JAAS (preferably using C#) but did not find any acceptable way.
I will be very grateful for any advise which of this approach may work or some other suggestions. Especially about building war of jbmp-console.
version used:
jBPM(6.2.0 Final), jBoss(Wildfly 8.1.0 Final), Java(1.8.0.73), Ant(1.9.6), Gradle(2.11), Intellij IDEA (15.0.3).
After a few weeks of try and error approach I have finally managed to provide fully custom authorization module for JBPM suite ( kid-wb, server and dashbuilder ) in our application. It wasn't easy and required some magic - overwriting two classes won't do it :)
My requirements was quite complex and final solution consist of kie-wb, server, dashbuiler and external authentication which provide by REST Web Service response users with roles based on token passed in session. Another thing that you have to keep in mind is that kie-wb and server are communicating through BASIC authentication - if you want to use server also you have to provide two possible methods of authentication. I won't be able to publish here any code, because it is not an open source project, but I will try to help the best I can.
If you are using WildFly as you are saying above, what you should look at is Undertow Servlet Extension
Overwriting handleDeployment method allow you to write your own IdentityManager( if you need one ) and register your custom AuthenticationMechanism.
To implement your own AuthenticationMechanism you should look at this project Custom Spnego Auth for WildFly
My solution was based on mentioned above project - you don't have to implement every class - in my case writing my own class implementing AuthenticationMechanism was sufficient to get custom authentication working in kie-wb ( not for server though).
So if you already have overwritten Servlet Extension ( and registered by putting file io.undertow.servlet.ServletExtension containing your custom servlet extension class name inside /WEB-INF/classes/META-INF/services/ path of .war file ) and implemented custom AuthenticationMechanism next thing you should do is write class implementing org.jboss.security.auth.spi.LoginModule interface. If you don't want to implement this interface all by yourself you can just extend one of already implemented classes from WildFly - for example UsernamePasswordLoginModule or other.
To let WildFly know that we are using non-standard Login module we have to modify standalone-full.xml as follows:
<subsystem xmlns="urn:jboss:domain:security:1.2">
<security-domains>
<security-domain name="other" cache-type="default">
<authentication>
<login-module code="com.package.CustomAuth" flag="required">
</login-module>
</authentication>
</security-domain>
</security-domains>
</subsystem>
and then...we are almost done :) One thing left to do is to modify deployment descriptor inside .war file. We have to change web.xml inside /WEB-INF dir as follows:
<login-config>
<auth-method>BASIC?silent=true,CUSTOM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/login_failed.jsp</form-error-page>
</form-login-config>
</login-config>
CUSTOM is name of your authentication mechanism that was registered inside class implementing Servlet Extension class.
Above instruction does not cover kie-wb <-> kie server communication. This matter was more complex and required a few workarounds. As I said before I won't be able to provide full solution with more detailed examples, but feel free to ask me anything refering this case.
Related
I am currently in the process of designing a .net logging library that could potentially be used across different solutions in our organisation as a nuget package. However, I also want to make sure that we do semantic logging so that the logs are still structured.
Example -
CustomEventSource.Log.OrderProcessingFailed(order.OrderNumber, order.ItemCount);
Given that I am creating a shared service that is application agnostic, it shouldn't be tightly coupled to the application. Here is an example flow.
Developer creates application and downloads logging package
Developer creates EventsIds (e.g. OrderProcessingFailed), categories, keywords etc... specific to
their application
Developer creates instance of logging component
passing details like machine name, event source name.
Developer
creates logs using logging instance passing details created in step
2 AND an array of name value parameters that are relevant (e.g OrderNumber: 1234, ItemCount: 3).
Logging library writes the events in ETW.
External listeners captures the events.
Has anyone seen a solution resembling above? My question is more on how to implement step 2 above. I don't want EventId to be free text but it should be something that the client is "forced" to implement similar to how an interface gives you an idea of how to implement what is required.
I know my question is a bit vague at this point so clarifications are welcome.
We are developing multiple applications for the same company.
The applications are distinct (so not suitable for a multi-tennant app) but there will be lots of shared models, a couple of shared controllers and ideally some shared views.
It is the first time I have had to do this, and wonder if I am approaching it correctly. Here is my plan:
Create a DB for the shared stuff, and another (per application) for application specific stuff
Each application will have 2 connections in web config
Create a DLL from the shared models and controllers. Put this in the /bin directory and reference it in the project. I want this to approximate the way a nuget package might work, and reference the
For each app create a SharedApplicationDBContext and a LocalApplicationDBContext, each accessing the respective DB.
Questions
Are the above steps the right ones to be taking?
Is there any way to include cshtml Views in a DLL?
Is it ok to include the Users controller / models in the DLL?
Are there any gotchas I should be aware of when sharing code like this over mutliple apps?
I know SO likes specific questions, and this is a bit vague, but I'm a bit out of my depth here and looking for some general guidance as to the right approach to take.
You've got the general idea, but it needs some tweaking:
Don't fool around with DLLs. If the projects exist in the same solution, then you might as well keep your class library there as well. In which case, you can just do a straight project reference. If you're dealing with multiple solutions then you package your class library as a nuget package and actually install it in each project. Creating a nuget package is easy enough, and you can either install from a local/network path or you can set up your own private nuget repo. This makes it stupidly easy to share resources, and you get the ability to publish updates and see at a glance which projects are running which versions of your class library.
Each app should only have the context that relates to its individual database. The shared database can also use a shared context, which would be contained in your class library. You should also house all your migrations related to this shared context in the same class library.
You can include views in a class library, but not as cshtml. They have to be compiled into the class library. You'll need RazorGenerator to accomplish this.
It's 100% okay to include the models related to users in your shared library. However, the controller is trickier. Unless you set up an SSO server that will alone be responsible for handling all authentication (a non-trivial task to say the least), each application will need it's own controller for authentication tasks. If all of the sites will reside on the same domain or subdomains thereof, you can easily share the auth cookie between them. However, if they will reside on entirely different domains, you can still share the same "users", by virtue of using the same database for each, but each site will require a separate login process (logging in at one does not log you in at another, even though the same credentials would work for both). The only way around that is, again, SSO.
For what concerns the views, you can include them in a DLL, please read here
For the models it's ok to have them in a different project.
For the controllers you can do it but you must let MVC know where the controllers will be located and you can do it by writing a custom ControllerFactory, please read more here.
I am working on a multi-tenant MVC4 web portal that is meant to host dynamically generated MVC4 applications.
Use case: The client uses the web portal to upload a xml specification. The specification gets passed to a web service that generates an mvc4 application, compiles it and returns a zip file to the portal containing the views, css, javascript and a dll(compiled c# code). Then, the portal unzips the received zip file and places it's contents in a folder (Modules) inside the portal itself. Then the client can browse the newly 'deployed' application. Many versions of the same application can be deployed and I am planning to use different Namespaces for each deployment. Note: The generated modules have some dependencies that will be injected by the web portal using a DI injector (was thinking of using ninject)
I have done a lot of research on how to build a modular MVC application. I've looked at MVC Areas, done some research on MEF, DI frameworks, looked at nopCommerce and orchard code. One thing that I cannot seem to find an answer to is how to add the Modules at runtime without requiring an AppDomain restart? Also, is there an easy way to register routes for each of these modules at runtime?
I am trying to avoid app restarts because there may be other people using the portal/deployed modules while others are uploading new specifications.
Did you have a look on this (just very slightly outdated) Tutorial? It won't solve the problem of re-scanning the Modules, but the introduced PluginAreaBootstrapper class seems to be a good start. Maybe you would be able to run the PluginAreaBootstrapper's Init() method upon a specific Event in your System (let's call it OnNewModuleDeployed).
I've been struggling to do this in a way that fulfills all of my requirements.
Here is what we have in our library:
Base classes for controllers and services
Business objects (stores, departments, etc)
Common Partial Views (Login, Error, etc)
Base class for HttpApplication
General common code (read an INI file, create a db conn, etc)
The one requirement that has been giving me trouble is as follows:
Lives in one place on a server. (i.e. copy local = false)
This breaks because:
The DLL containing the HttpApplication class must be in the same directory as the web apps dll to launch. I haven't found a way around that. I'm ok with duplicating this code in every app, but would rather not.
The shared views don't like to work if I use Assembly.LoadFrom() to load the dll from the shared location. (I've been using this method to precompile my views)
Any namespace shortcuts in web.config break at runtime with compilation errors because the web.config is parsed before the assembly is loaded.
My question to you folks is how do you handle your common code in a similar environment?
The GAC seems to be more trouble than its worth, and we want all of our apps to be using the same code, and not have multiple apps on multiple versions and have to maintain all of that. Are there design patters/best practices that can guide us in this regard?
Also, as a bonus, if you can solve any of the problems above, that would be great, too.
Thanks!
Edit: I guess a question that follows is whether or not we should even have a directory with the common dll(s) on the server, or if they should only be deployed as projects are deployed/updated?
Firstly, you will want to separate out what you're trying to achieve. Don't create 1 library that does everything or you will have a Big Ball of Mud. Don't be afraid to create several maintainable libraries to achieve what you're after. Is there a specific reason it needs to be stored in one location?
For example, several of the items you mention are MVC or web specific. If you have items that can be reused by MVC, create a class library that contains MVC base classes you inherit and reference them in your project. Use the single responsibility principle as much as possible.
Regarding the other items you mentioned, like database connectivity, if it's reusable, abstract it out in a data access class library and reference it. Other simple operations like reading an ini file or creating a file, create another library and abstract it to easy to use methods.
I prefer to copy the library dlls locally. You never know when you will need to make changes to the library, but you don't want all of your projects to stop compiling. When you're ready to implement a new version of the library, copy the dll in and recompile.
Not sure why all the hate towards the gac. It was designed to handle this specific problem. Install your common dlls to the gac and all apps can see them. Need to deploy a new one, just re-install it in one place.
I'm fairly decent with MVC3 and enjoy creating my sites with it, however, I am yet to think up and implement a decent method of a "plugin" system.
Basically, I aim to have a generic "blog-type" CMS which I can distribute across my sites, but with the option to have certain things as plugins.
For example:
Generic build:
User area
Basic blog/news editing
Plugins: (May be needed for one or two sites, but not all)
Chatroom plugin
Stats
and so on...
Currently I would just make it all and disable things through a config file, however it would be nice if i could just drop a folder into my FTP and have an MVC page which automatically picks it up!
I assume I would have to start with scanning the directory "/plugins" and picking up a "plugin.config" (Or similar) file which would contain the basic details.
But how would I get my main system to pick these things up and actually use them?!
You may be able to do this using MVC Areas, here are some links about them:
ASP.NET MVC 2 Areas
ASP.NET MVC Areas: Are they important to a large application?
https://stackoverflow.com/questions/462458/asp-net-mvc-areas-are-they-important-to-a-large-application
Try assembly scanning with StructureMap dependency injection.
Read this great tutorial: ASP.NET MVC2 Plugin Architecture Tutorial
It help me create a plugin architecture with MVC3.
Areas solve the problem for you providing you have everything in the original project/assembly. You could write your plugin system to allow the plugins to register their own areas, or alternatively you could register some new view search paths in a custom Razor view engine.
I chose the latter for a recent OS project I wrote called Spruce, which uses a whole plugin architecture you might find useful as a reference.
You can scan all the assemblies in the bin directory on startup to check for plugins, via reflection. You usually check for types that implement an interface or inherit from a class, and use these along side an IoC container such as TinyIoc, NInject, StructureMap or Unity. I'd recommend TinyIoC which is used by NancyFX.