We have a Seam 2 based web application with the usual user login and a couple of views which have handler classes interacting with a local database and a web service.
Now, we need to implement customer specific differences - so the use cases are basically the same, but for example customer A wants a couple more fields on the form, customer B a different web service call and customer C another role with different access rights.
I know my question isn't very specific - but I'm looking for general ideas how to handle such a scenario without having to maintain different separate versions of the application or having lots of ifs in the XHTML or the java code for getting different behaviour.
So since this is I guess a common scenario - how do you handle it?
Fields
If the business case is the same and the fields don't influence it directly you might just opt-in for a user- or companysetting. So just a checkbox which modifies the layout. Hard thing which you should be aware of is validation of required fields. Since that might differ between your customers.
A step further you could go for flexible fields and all that kind of things but that will get quite complex directly. If you don't need to don't go there.
ACL
The ACL could be just made flexible enough to support different settings per customer, that shouldn't be a big issue.
Webservice
The other webservice: If it is another webservice but it gives the same info back you could just implement an interface. That way you could flexibly switch per customer. The nice thing is that your application get unaware of which webservice it actually is but it understands the interface. More on this: decoupling is the keyword.
This also generates a well testable piece of software which allows you to develop in the future further without much hassle.
Know when to stop
If it gets too far with customization understand where to stop. Don't get into too many difficulties, when a customer want a customer piece of software it should become one at some point in time. See also: http://gettingreal.37signals.com/ch05_Start_With_No.php which is quite relevant, you can't satisfy everyone with a standard piece of software. There will be lots of hidden costs: http://gettingreal.37signals.com/ch05_Hidden_Costs.php
Think that gives a well overview. If you need more details maybe separate this question because each of the three questions has it's own issues.
This is a very common problem in software development without a clear answer, so the best answers you will find will end up being advice.
The dirty little secret that we know is that unless you are selling software in a box on a shelf at Staples, then you are probably just providing the illusion of a product that cloaks truly custom software.
Because ultimately when developing business applications, all of your customers want custom built software, but they want to believe they are purchasing a product. It is simply human psychology, when we buy a product we tend to not only feel like we got a better deal but that we will be more forgiving of slight flaws or annoyances. When buying something custom made we immediately tend to feel like we are overpaying for a luxury, so if everything doesn't turn out exactly as I want it, it will be unacceptable.
The best way I have found to handle this is to have a person in your company with the strong authority of being a Product Owner. This person will be the Alpha and the Omega on every feature and change that goes into your software. It is the Product Owner's job to mitigate the disparate and sometimes completely opposing customer requests into a single set of software requirements and features that will make the majority of customers happy the majority of the time.
Simply by the way your question is worded you are already approaching the problem incorrectly by wondering how to technically deal with your different customer requests. The only customer you should care about as a developer is the Product Owner, whose job it is to tell you what custom features, settings, flags, resource bundles and forms should be included and how to flip different features on or off to satisfy the companies customer needs.
Related
I am a newbie with the rules engine, so bear with me if this question is very basic. All the tutorials for rules engines have been saying that you can move your business logic outside your code and get it updated by BAs/ end users instead of putting it inside Java code.
I have the following questions
But why can't we write our code to read values from property files and do the same thing?
Also, the rules files seem to have a syntax which is not simply one-liners, compared to .properties files.
Does putting these rules in Rule engine make the code/app work without requiring an app server restart?
3a. If it does NOT, then how can we achieve it?
Had been doing some reading the last few days and I think (it is IMHO), the capacity for allowing business rules to be updated using simple spreadsheets, gives Rules Engines the edge over property files. I can make property files as highly configurable as possible using multiple properties and instructions for modifying rules as comments under each property.
But in a scenario where the business user is able to directly configure the application to apply values based on a "decision table" in a spreadsheet, then that solution will be more desirable.
If any other (budding) developer looking for justification on the for the need of Rule Engines is convinced with this answer, please leave a thumbs up!
If there's a change in logic, you'll change the properties file and deploy the whole project again. Whereas, if you maintain it using BRMS, you can change & test individually on the BRMS only without needing to deploy the whole project again. Once the testing is done and you finally want to deploy the new rule in place, then also, no need to deploy the whole project in production. If you've exposed your rule as API using KIE Server, redeploying just the KIE server would do.
One can write decision tables in such a way that all the logic is contained in the top rows. Then the developer can lock & hide those top rows and then give it to BA. Now BA doesn't see any logic but knows how to maintain the file. Also, not all logics should be written as decision tables.
As I mentioned above, one can deploy each and every rule as a separate rest API and hence is deployable independent of the rest.
In the end, I'd say the main reason we use Redhat BRMS is, as they mention in their documentation,:
Agility: No need to involve developers for a change request. BA's themselves can change the logic.
Visibility: What you see (in the excel) is what you get.
Consistency: Rules are evaluated the same way every time.
Rules engines are not always the answer. However, they provide, in theory, the advantage that the engine can perform complex processing on a simple rule expression and return a result. Other advantages are visibility to the rules and less code.
Answers to your questions.
You can. In simple cases,using property files makes sense.
Rules need to sufficiently complex to cover the business issues they validate. A good rules engine uses a syntax that is readable, even if it is complicated.
In theory, the rules server could run independently of the app server. In large companies, that is normal. The rules server could allow updates without a restart, or it could be restarted (rippled, if there are multiple instances,) without affecting the app server.
Rules engine comes into picture when business users of company want to set certain rules and drive application based on execution results / outcome decisions of rules set. One of examples of such company could be a Law firm or Insurance company where lawyers set rules to drive the quotes calculation for a insurance & rules are subjected to change over period of time. Property file is developer area where business user may not be proficient to make changes. Having separate rules engine tracks the rules and make a business user and a developer work together automating the business seamlessly which could be difficult with properties file.
Rule files syntax is way to convert business rules (verbal) to coding instructions which are executable. Thats where the syntax comes into picture. That way rules engine provide data abstraction to business entities and their relationships.
Integration with rules engine may be done with some broker or a web service or whatever, based on that, server app need rules client jars to make call against. So its matter of deployment and how server picks up changes / hot deploys if rules client jar is updated.
Rules engines are just algorithms for organizing many rules. See the Rete Algorithm.
Basically, it all comes down to complexity. If you have a few simple rules, of course you can use a .properties file. But imagine if some of your rules are 'chained' - one rule affects some other property, which triggers some other rule, which changes another property... you'd have to scan every rule, every change. For thousands of rules, it would take forever. Hence a 'rules engine'.
There are many articles on why you should or shouldn't use a rule engine. Here is one good example.
https://martinfowler.com/bliki/RulesEngine.html
Our framework is Grails. Say domain.com contains an application and currently used by some client. If we want to allow another client with the same functionality but providing a separation for the data of two clients, so that they can't mix both, how to do this? And whenever we want to add n clients to this application, what is the best method to be followed, so that with less / no configuration we can share the common war file for these clients by separating the db.
How the real time web development handle these type of situations?
And, one more point is how to provide client1.domain.com works for client1 and client2.domain.com works for client2. How to make the war file (in Java / Grails) to work like this? Otherwise we have to programmatically control the clients with in the project for every feature to be allowed or unnecessarily maintain separate war file for each client, which will be a waste of resources.
You're describing multitenancy - create one table for N 'tenants' instead of N identical (or nearly) tables, but partition it with a tenant_id column, and use that to filter results in SQL WHERE clauses.
For example the generated code for findByUsername would be something like select * from person where username='foo' and tenant_id=3' - the same code as a regular call but with the tenant_id column to restrict within that tenant's data.
Note that previously simple things like unique constraints are now harder because you would want to restrict uniqueness within a tenant, but allow a value to be reused across tenants. In this case changing the unique constraint to be on the combo of username and tenant_id works and does the heavy lifting in the database.
For a while there were several related plugins, but they relied on tweaking internal APIs and some features broke in newer Hibernate versions. But I believe that http://grails.org/plugin/multi-tenant-single-db is active; it was updated over a year ago, but it is being used. Contact the authors if it looks like it'll be what you need to be sure it's active. Note that this can only work with Hibernate 3.x.
Hibernate 4 added support for multitenancy, but I haven't heard much about its use in Grails (which is expected, since it's not that common a requirement). It's not well documented, but this bug report highlights some of the potential pitfalls and should still be a working example (the test app is still on GitHub): https://jira.grails.org/browse/GPHIB-6.
I'd like to ensure that this is working and continues to work, so please let me know via email if you have issues later. It's a great feature and having it in Hibernate core makes things a lot easier for us. But we need to make it easy to use and well-documented, and that will happen a lot faster when it's being used in a real project.
I am a S/W developer working on a Java web application.
I have very limited knowledge of Java and want to understand my application architecture from a very high level in simple terms. Being a developer, I do not completely understand the big picture.
Can anyone help me understand this?
Each layer represents a place where some problems are solved is similar way, often using some particular libraries or frameworks. In trying to understand this work your way down through the layers. BUT, note that each layer hides the details underneath, you don't need to understand the details of lower layers in order to understand one layer.
So the Struts piece is dealing with the User-Interface related issues of understanding user requests choosing some business logic to invoke and choosing how to display the results back to the user. It doesn't concern itself with how the business logic works, that's the job of the next layer down.
By Business Logic I mean the Java (or other language) code that expresses the realities of a the customer's business. For example in a retail application we might need to work out discounts for particular volumes of orders. So the UI layer wants to display the price for a customer's order. It doesn't have any discount logic itself, instead it says to the business logic layer "Customer X is order N widgets and M zettuls, when can we supply and how much shall we charge" and the business logic figures out the pricing for this customer, which might depend on all sorts of things such as the status of the customer, the number things we have in stock, the size of the order and so on. The UI just gets an answer £450, to be delivered 16th September, and displays it.
That leads to questions such as "why separate the business logic to its own layer?" There are several possible reasons:
The business logic might be used by some completely different UI as well
It pre-exists, from some older system
Our brains are too small to think about UI and Business Logic at the same time
We have different teams working on UI and BL - different skills are needed
This same way of thinking follows down the layers. Th important thing when thinking about each layer is to try to focus on the role of the layer and treat the other layers as black-boxes. Our brains tend to be too small to think about the whole thing at the same time. I can almost feel myself changing mode as I shift between the layers - take off my UI head, put on my persistence head.
There's plenty of material "out there" about each layer. Suggest you start by reading up about one of them and ask specific questions if you get stuck.
Looks like a standard "enterprisy" application to me.
Interface
This app. is primarily intended to be used via web browsers by humans. This interface or UI layer (in a broad sense) is build using the MVC framework Struts. If you don't know MVC, then it's a good idea to read up on this term.
The app. also exposes web service interface, which is intended to be used by non-humans (other applications or scripts).
So, 2 kinds of interface is provided.
Business logic
Request coming from the 2 interfaces noted above, ultimately talk to the lower half (App. tier) to get some real job done. The actual process (calculating stuff, storing stuff and what not) happens here. Note also that this tier also talks to external systems (via Service Gateway) in order to complete the requests.
The reason they separated the system like this can vary. If it's a very simple, small app. then it doesn't pay off to have these abstractions, so it's probably a quite complex system. Maybe the app. tier is some legacy app. and they wanted to put some better UI on top of it. Maybe the app. tier and the web tier happened to use different technology stack. Or perhaps the app. tier is used by many other external systems. It also makes updating each services/replacing each services etc. easier, so maybe they are anticipating that. Anyways, it looks like a very common SOA type of design.
Not sure what else you might want to know. I see that the designer intends to use distributed cache in both tiers. All in all, it's a very common type of system integration diagram.
App Tier - Where the basic application logic resides (think of a basic console-only program).
Database - MySQL, Oracle... server
DOs - Short for Domain Objects. If anemic usually limited to getters/setters and can be synonymous with Entities (#Entity).
Data Access Objects - Objects using DAO pattern to fetch domain objects from the database. Could be considered equivalent as DAL (Data Access Layer) although this might not fit here. Usually uses a persistence/mapping framework such as Hibernate or iBatis.
Domain Model - Where Domain (domain being what has been studied/analyzed from requirements) Classes are packaged and associated (one-to-one, many-to-one, ...). Sometimes there are even composited in other container classes.
Core Application Services - Groups Services classes which could be equated to the Business Logic Layer (BLL). Biz services handle the Domain Model, Application Services are relative to the Application (methods don't manipulated Domain) and not sure what System Services are supposed to do. I'm also not sure what the distinction between Core and the Application Service block is.
Facade/Interface - This is where all the communication is done with other Tiers. It helps to fully understand interfaces and the Facade pattern.
TOs: Transfer Objects. Related to Domain Objects and used for transferring as the name implies.
Web Tier - All the logic added to make the application accessible from the Web.
Business Delegate: Block using delegation pattern? Here it apparently plays the middle man between Application facade and the Presentation Tier using TOs.
Model: Notion relative to the MVC pattern and variants. With JSF I know that beans are usually linked to JSPs. This model is to be distinguished from the Domain Model. It is created for the purposes of presentation and might contain information that has nothing to do with the data being manipulated in the application tier and is specific to the web tier.
View: Notion relative to the MVC pattern and variants. JSPs represent individual pages and use their own markup.
Session: Look up theory on sessions (necessary as HTTP is stateless).
ApplicationContext: Groups instances/settings that can be pulled into from anywhere. Often associated in the Java world with the Spring framework. To not be confused with UglyGlobalVar/singletons.
Front controller: Could be considered as equivalent to Controller of MVC although the Front Controller pattern appears to be more specific. Servlets are considered as controllers as they handle communication (GET, POST...) and coordinate the model/view. Not familiar with Struts but imagine that the framework implements classes to represent user actions.
Presentation Tier: Simply all of the logic used for outside presentation.
Filters: Can be used to filter requests, for example to redirect a request to a login page.
Feel free to add/correct this description.
I have several classes that were generated from a WSDL and I need to write 2 small applications that read some input data, call the webservice and write the responses.
Right now I created a bunch of very simple wrapper classes that take the data from the objects returned by the webservice call. I created a wrapper around the webservice proxy that returns my own classes instead of the generated types. What I try to aim for is a decoupled model, that will not reveal any of the generated classes to my simple applications.
But I think I may overengineer the whole thing. For now the 2 small applications will be almost the same size as the model classes and wrappers, but I am sure there will be more requirements coming up later and I want to be flexible.
Should I hide the generated classes (and think about this part as a Data Access Layer) or should I go with the generated classes for the first version?
We are talking in generals here, so I will respond in kind. Unless you have specific requirements that you are building to, don't engineer for the future too much, other than choosing frameworks and methodologies that can be flexible for the future. The thing is, if you engineer for the future now, you don't even have the requirements nailed down so you are working on guesses and worries. See the "You Ain't Going to Need It" principle.
Now for the question of wether you need the Data Access Layer now: if you find that you have a layer that does nothing but translate between two other layers, you don't need it. If, on the other hand, there are a set of tasks that if handled in a layer that will make other layers more concise and clear, hopefully all while reducing redundancy, go for it.
we have a J2EE app on which we're still working. It runs on Oracle DB. and the business tier is coded with EJB 2.0 with a rich client interface.
now, the application is going to be deployed on multiple sites. and each site will be creating new items (new contracts, etc.).
what we want to realize is to duplicate all new items added to a central location DB using same DB schema as local ones.
what do you think is the most effective way to accomplish this ?
I've thought about serializing all new items created and sending them to the remote site for integration through Java Message Service queue. is that approach good ?
and there's also going to be some changes to be replicated back to the satellites.
I would say that a synchronous relationship with the centre introduces coupling that you don't want. Hence your asynch idea seems pretty good to me. You presumably have some location-dependent identifier in the records so that new contracts creations in the different locations will not clash and you accept some latency in the replication to the centre.
So the simple case is that just use JMS messages from each location to the centre.
The nice thing about this appraoch is that the satelites don't even need to know about the database structure in the centre, it can be designed completely idepedently.
Things get more interesting if you also need to replicate changes back from the centre to the satelites. The big question is whether we might get conflicts between changes at the centre and changes at the satelite.
Simple case: Any data item has one "home". For example the originating satelite is the place where changes are made. Or after creation the centre is the only place ti make changes. In which case we can treat the centre as the "Hub", it can propogate changes out to the satelites. Simple JMS will do just fine for that.
Slightly harder case: Changes can be made anywhere, but only in one place at a time. Hence we can introduce somne kind if locking scheme. I would tend to have the Centre as the owner and use synchrnous web services to lock and update the data. Now we are coupled, but that necessary if we are to have a definitive owner.
Quite complex case: Anyone can changes anything anywhere without locking. It's kind of an "Act First, Apologise Later" approach. We take the optimistic approach that changes won't clash. We can send the changes for approval to the centre and the centre can either use an optimistic locking or merge non-conflicting changes approach. I would tend to do this by queueing changes a the originator, but actually processing them by synchronous calls. So decoupling the specification of change from the availability of the centre. Some more sophisticated Databases have diff/merge capabilities that may help with this.
Big questions are the extent to which you want to be coupled to the availability of the centre and the likelihood of conflicting changes. Quite often cunning application design can greatly reduce the likelihood of conflict.