Working with multiple services/controllers in spring - java

I'm working with spring in java and I'm trying to create a rest-API for my program. I have 3 entities to manage so I also have 3 DAO classes.
my problem is that I have 2 types of users (player and admin). every one of them has different operations he can do on each of the entities/tables.
My question is what is the best way to implement these requirements.
should I have 3 services and 3 controllers for (one for each of my entities/tables) or should I create 2 services and 2 controllers (one for each type of users) Or maybe there is a better way than what I suggested?
EDIT:
Another thing that may be important is that I need to verify the data in the service, the verification process checks for connections in tables so in each service, I will also need to have Dao objects for different entities (For Example checking if a new action has an element on which the action occurred.

It sounds like you are probably going to have different functionality for the different types of user. It's kind of the point that admins can do things that players can't do. So there are going to be separate admin-specific service methods, the controllers used by the players don't need to have admin services wired into them.
Also it's the nature of transactions that they usually are not specific to an entity, usually you have different entities you want to deal with in the same transaction. If so then having a different service for each entity probably doesn't make sense.
On the controller level, use Spring Security to enforce who can call what endpoint. I would organize the controller endpoints into classes depending on what shared enough things in common, but how you break it up is not a huge deal.
For services, I would have one service implementing logic for normal players, and one service implementing administrator functionality. If there is a lot of code for either of these then I would think about breaking it up into separate services, keeping the distinction between services containing methods for normal players vs. for admins.

You can look into method level security with Spring Security. Baeldung has quite a nice guide about that topic.
You basically annotate certain controller methods and then access to them is denied for users that do not fulfil the conditions of the annotation.
E. g. Thymeleaf offers integration with Spring Security too, so you can make buttons unavailable in your HTML when the user does not have a certain privilege

Related

Understand application architecture

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.

Multi tenancy support in Java EE 6

I have an existing Java EE 6 application (deployed in Glassfish v 3.1) and want to support multiple tenants. Technologies/APIs I'm currently using in my app are
EJB (including the EJB timer service)
JPA 2.0 (EclipseLink)
JSF 2.0
JMS
JAX-RS
I plan to use CDI as well
As far as I know, adding multi-tenancy support affects only the persistence layer. My question: Has anybody done this before? What are the steps to convert the application? Will this affect other layers other than persistence?
There will be a high number of tenants, therefore, all data will reside in the same DB schema.
Persistence Layer
Start with the persistence layer. Roll upwards through your architecture once you have that done.
The Schema that you are proposing would have an ID that identifies the tenant (eg. TenantId). Each table would have this ID. In all of your queries you would have to ensure that the TenantId matches the logged in User's TenantId.
The difficulty with this is that it is a very manual process.
If you go with Hibernate as your JPA provider then there are some tools that will help with this; namely Hibernate Filters.
These are commonly used to restrict access on multi-tenant Schemas (see here and here for some more)
I haven't used EclipseLink but it does look like it has good support for Multi-Tenancy as well. The DiscriminatorColumn looks like a very similar concept to Hibernate Filters.
Service Layer
I assume that you're using JAX-RS and JMS for a Service Layer. If so then you will also need to think about how you are going to pass the tenantId around and authenticate your Tenants. How are you going to prevent one tenant from accessing the REST service of another? Same thing for JMS.
UI Layer
You are going to have to hook up your login in your UI to a Bean (Hibernate or Eclipselink) that sets the TenantId for the Filter/Discriminator.
Tell us about the number and the degree of separation and customization necessary for different tenants.
If you have a small number of tenants, I would propose to create a customizable "white-label" product. This gives you the opportunity to create some specific things for one tenant without overcomplexing matters. Plus, separating the applications per tenant helps you in maintenance. We did this for a product with a handful of different tenants.
If you have many tenants, this is of course no longer practical. We did a generic version of the same product. All we did then was distinguish tenants by id after login, thus separating the data from others. But still, there was nothing to do in terms of changing the application or a layer within, the id was all what was needed to separate the data and the workflow is automatically separated by having different instances of beans or other managed objects.
There's several ways you can go with this, depending on the level of separation you want to achieve and how many concurrent tenants you want to support. At one extreme, you can create a new schema for each tenant and therefore ensure database-level isolation of data. For most practical purposes it's usually sufficient to have a logical partitioning of your data by assigning a tenant_id to every entity in your domain model and maintaining foreign-key constraints. Of course this means you'll probably want to always pass in your current session's tenant_id to every query / finder method so that it can restrict the data set based on that. You'll want to make sure that users cannot access another tenant's data by entering a tenant id (or a entity id) that does not belong to them in url.
Go message oriented.
If you choose messaging as the strategic approach and refactor (if necessary) business logic around JMS, then other options remain viable and locally applicable.
With this approach, you pay a specific fixed cost (refactor) in your existing (single tenant) system. You then can apply approaches of various degrees of complexity, ranging from simple sharding (#Geziefer's id based association) to a full blown shared-core-schema + extended-tenant-specific-schemas approach, without impacting system architecture and additional refactoring.
You will further have orthogonal control over your system data flows via the messaging layer (applying routers, filters, special processing paths, etc.)
[edit per request]
There is nothing per se in M.T. that explicitly suggests message orientation. But as a general problem, we are looking at widening interfaces, and enriched data flows. Per an API based approach, you would need to carefully inject the appropriate the tenant discriminant in all required interfaces (e.g. methods). A message based (or alternatively a context based API approach) allows for a normative (stable) interface (e.g. message.send()) and at the same allows for explicit specialized data flows. If switching to a message based backbone is not on the table, you are strongly suggested to consider injecting a uniform context (e.g. "RequestContext") param in your APIs. This single extension should cover all your future specialization needs.

spring mvc dao and service bean mapping

I am new to Spring and hibernate.
I am trying to learn the best practices and design methodoligies in j2ee apps.
I have a managed to create a basic spring mvc web app. now lookin for that
- how should i map my service beans to dao beans or should just use dao beans only.
- Is there any need to make DAO classes singleton
- If i use same dao bean for the jsp, then e.g. onSubmit if I have to enter data on multiple tables (dao beans) then how would I do that.
1 service bean to more than 1 dao beans??
and any refrence material on designing good web app using spring hibernate would appreciated ;)
thanks
You must use service bean. service logic should be there only.
DAO should only for DB related operation.
Now you can inject multiple DAO in your service bean.
FWIW - I just went through a similar learning process on Spring. The good news is, there are a lot of examples out on google; the bad news is, there are not a lot of "complete" examples that are good for rookies (also if you are going to target v3 Spring, there is a lot of pre-v3 stuff out there that can be confusing based on the new baseline). What worked for me was the following: started with the sample applications on the SpringSource site (http://www.springsource.org/documentation). Between their handful of examples, there are just about all the pieces you will need, at least in minimal form. When I found something in those examples that I needed, I googled based on similar terms (some of the # annotations etc) to find more complete information/better examples on that given topic. Many of those searches led me back to this site, which is why I started frequenting here - lots of good questions already answered. I guess this isn't an overly insightful answer, but this process got me up and working through the basics in a fairly quick amount of time.
DAO layer and service layer are different entities:
DAO is responsible for getting and putting single objects from\to DB. For example, get User(id, name, lastname) from DB.
Service layer is responsible for your business logic. It can use several DAO objects for making one action. For example, send message from one user to another and save it in sent folder of first user and in inbox of recipient.
A service is about presenting a facade to the user that exposes business functions that the user can take. Basically, if you have a set of low-level use cases, the methods on the service would line up with individual user actions. Services are transactional, generally if the user does something we want all the consequences of that action to be committed together. The separation between controller and service means we have one place to put webapp-specific functionality, like getting request parameters, doing validation, and choosing where to forward or redirect to, and a separate place to put the business logic, stuff that doesn't depend on webapp apis and is about what objects get updated with what values and get persisted using which data access objects.
I see a lot of cases where people seem to think they need one service for each dao. I think their assumption is that because Data Access Objects and Controllers and Models are fairly mechanical about how they're defined, services must be the same way, and they construct them with no regard for the use cases that are being implemented. What happens is, in addition to having a lot of useless service boilerplate code, all the business logic ends up in the controller jumbled up with the web-specific code, and the controllers become big and unmanageable. If your application is very simple you can get by with this for a while, but it is disorganized, it's hard to test, and it's generally a bad idea. Separation of concerns, keeping infrastructure code in one place and business code in another, is what we should be aiming for, and using services properly is very helpful in getting there.

Should I duplicate validation in my MVC layer and Service layer?

I'm feeling a little conflicted at the moment. I have a web application using Stripes for an MVC framework and Spring/Hibernate for the back-end. I have an account registration method in my MVC layer which requires the following validation:
Username is not already taken
The provided email address is not already associated with another account
I have a validation method in Stripes (MVC layer) that checks these two cases but was wondering whether my service layer should duplicate these checks? If the service layer interface was exposed as a web service then I think the validation would be a good idea, but if it's only used in the context of a web application is it required?
Edit: I'm not intending to duplicate the validation code - I mean duplicating the validation method calls in two places.
I see my options as:
Duplicate the validation calls in both MVC and service layer
Only perform this validation in the MVC layer
Only perform this validation in the service layer.
What's best practice here? I'm looking for advice/opinions on which option I should go with and why.
Note that there are simple validation checks on the input fields of the registration form (like checking for blanks) and that I think these should be handled by the MVC validation only; I'm only concerned about more complex validations.
Don't duplicate code. Use JSR303 Bean Validation so you can use the same validation logic in all layers of your app.
Hibernate Validator (a separate project from the Hibernate ORM stuff) provides the reference implementation of this interface. It is dead simple to use, you can get started with it very quickly.
In my opinion you should diferenciate two kinds of validations:
The Format data validation: Which should be validated in the presentation layer (MVC in your case). Normally both in the client and the server side
The Bussines data validation: Which should be validated in the service layer
In your case your validations are related to business rules, so I will put them only in the service layer.
In addition, if you duplicate your validations in both layers you will be making the same queries twice, slowing down the performance of your application.
Annie,
Good question, I have asked myself the same in many occasions. Here's what I ended up with (until now).
The purest (but tedious) approach is to invoke the validation logic in both layers.
the pragmatic approach could be to only invoke it in web-land (e.g. your controllers).
I think there is no answer that ends all discussion. I think that it depends on the context of your project. If the project-size is modest (in terms of people and size of codebase) and you are confident that not a whole lot of code will be developed by others that invoke your service API (to an extent that you will not be able to oversee), then doing the validation in the web-layer only may well suffice.
However, if you expect many clients you may need a higher-level security. When I say security here, I refer to it as the level of consistency-guarantees that you need.
If that level is high, there is no way around it: you will have to do it in both the service (for security) and the web layer (mostly to be able to provide end-users with an acceptable experience).
So the key driver here is security and how much of it you really need. If you need a lot, you go for the 'purist' approach. If your application doesn't exactly make decisions that concern matters of life and death, you go for the pragmatic approach.
Ideally, do the validation in both layers, since your service layer may be used with a client other than the current mvc layer
Reuse the validation mechanism at both places (Bean validation, for example)

Stateless EJBs: Finding the balance between performance and security

I have a JSF web client and a Java client that both use the same stateless EJB layer for their application logic. I'm unsure of how to balance the need for performance (limiting the amount of data that is transported between the presentation and application layers) with security (in the sense of ensuring all decisions are made based on up to date data).
I understand that this is a subjective topic, so perhaps I can make it more objective with concrete examples:
Do I only send the username to the EJBs, and then load the User entity on each and every EJB call, or do I send the User entity from the presentation layers?
If I need more information than just the User entity (let's say I need to load an additional entity on each EJB call), do I send the username and the other entity's key and load both the entities in the application layer, or do I send both entites from the presentation layers?
What about if I need even more information for certain EJB calls (>= 3 entities)?
When does it make sense to send the actual entity instead of just its key, or is the answer never, always reload on the application layer side? Should I be worried about performance? I've heard that Hibernate (which I'm using) employs intelligent caching meaning the User entity probably won't be reloaded from the DB every time? What if my EJB methods have a very small granularity and frontend actions might sometimes cause 3 or more EJB methods to be called, with each needing to load the User entity?
A final related question: I intend on using the JAAS principal to store the username which is loaded by the EJBs. What if my Remote facade EJBs call a bunch of Local stateless EJBs that also require the user information, do I still use the JAAS principal and load the User entity in each of them as well or is there a better way?
You should consider stateful EJBs, since it sounds like the clients need non-trivial state to answer a series of requests concerning the same state from one user. That said, stateful EJBs are kind of a bear to write and configure properly.
As a matter of design, I would not have the clients send user information to the business logic layer. One, it just punts the problem over to the client, no? to load, store and send this info? also it makes me nervous from a security perspective, to let a presumably less-secure client tier feed sensitive user data to a more-secure backend-tier which then trusts and uses that info.
But, really, I think you mentioned the best approach already: Hibernate's lazy loading. You just interact with the object and let it load data on demand. To work well with Hibernate in this regard, the User object should be small, so that loading it is fairly quick, and push all the big, heavy info into child objects or other entities. Then it doesn't matter if you have to load User a lot; it's just a bit of a 'pointer' to other info.
I don't think it changes things if you use JAAS, no. Although I might say, for what I imagine your purposes are, JAAS may or may not be worthwhile. In the time it takes you to integrate, write permissions, use those permissions, deal with consequences of the SecurityManager, etc. you probably could have just written a simple permissions framework for yourself anyhow.
if you make just one EJB, make stateless session. personally i found it humbug empty interfaces

Categories

Resources