One project with multiple angular app architecture - java

I need to develop a new project that will contain several AngularJS application and I have a questions about the project architecture.
The solution will behave 5 webapp (for the moment) and the customer can choose the modules he wishes. These applications will be available only on its networks.
I thought two solution
First solution: develop 5 war (easy to deploy war according customer needs)
Second solution: make a unique war (and configure in database which applications will be available)
Regarding the first solution:
I wanted to create a maven module for each webapp + a "core" module that will be included in each webapp module and will contain spring configuration (which is 95% identical between each webapp), entities, dao and some shared services. Do you see any problems to proceed this way?
Concerning the second solution
In fact I do not even know how to do it yet but I think it's doable (maybe with a http filter ?)
So what is the best solution knowing I privilege maintainability over performance?

Basically what you may meed is a project with front-end layer, service layer and DAO layer.
Prepare three of them as separate maven projects and then add them as maven dependencies or create an appropriate package structure in a single project.
In front-end, instead of using 5 different projects you can use a single project with a switching page. from the switching page you can direct requests to corresponding app you want with the aid of spring configured mvc-dispatcher.
folder structure for front-end in my suggestion would be looks like as in below,
-webapp
|_web-inf
|_pages
|_app
|_project A
|_project B
|_scripts
|_projects B's sub module A
|_projects B's sub module B
|_controllers
|_factories
|_model
|_services
|_views
|_projects B's sub module C
|_projects B's sub module D
|_projects B's sub module E
|_project C
|_project D
|_project E
You can map your resources in you application using mvc-dispatcher as below,
<mvc:resources mapping="/projectA/scripts/**" location="/WEB-INF/pages/app/projectA/scripts/"/>
<mvc:resources mapping="/projectB/scripts/**" location="/WEB-INF/pages/app/projectB/scripts/"/>
<mvc:resources mapping="/projectC/scripts/**" location="/WEB-INF/pages/app/projectC/scripts/"/>
<mvc:resources mapping="/projectD/scripts/**" location="/WEB-INF/pages/app/projectD/scripts/"/>
<mvc:resources mapping="/projectE/scripts/**" location="/WEB-INF/pages/app/projectE/scripts/"/>
Hope this would be helpful

Related

Can I have multiple data sources in spring without specifying the primary one?

The situation is as follows.
I have a microservice that imports a module. I want that module to be reusable by other microservices and to have it's own data source.
I managed to do this by manually configuring the data source in the module (in a #Config glass), but if I want to import the module, I also have to manually configure my data source in each micro service and specify that it's the primary one.
Is there any way to only configure the module's data base and to let spring do it's automatic config inside the microservices? Thanks, any help is appreaciated.

Multi module Spring Boot project with different context paths

As the title says, I'm trying to create a multi module Spring Boot project that has different context paths for each module.
Let's say I have a bunch of core functionality in one module, and let's call it 'core'. This includes defining entities, DAOs and common functionality. I'd like to add two more modules, (for instance 'frontend' and 'admin'), and I'd like that those two modules could run independently from each other (both depending on 'core'). But I'd also like to have the possibility to run them together, and access frontend when the path is '/' and admin when the path is '/admin', which is the part I'm struggling to achieve.
What I've done so far:
I'm using Gradle. I've created a parent module at root level. This parent module contains the just the main method for Spring Boot to init, and depends on both 'frontend' and 'admin' (both which, in turn, depend on 'core'). I've created a Controller on each of these two modules, and if the path is different they work fine. But still, they work as they belong to the same application, and both are mapped to the same context path. I want to be able to map "/login" on each module and let Spring decide where to execute based on context path ("localhost:8080/login" should be mapped to 'frontend' module Controller, "localhost:8080/admin/login" should be mapped to 'admin' module Controller).
Just to clarify, if the approach I'm using is not the best for what I'm trying to achieve, I'm happy to change it.

Are there any disadvantages in WAR packaging over EAR packaging?

I have a general architectural question about the advantage and disadvantage of EAR packaging in a Java EE application.
I have a Java EE business application deployed in multiple server environments. The application consists of the following main modules:
EJBs with business logic
Web-UI
REST API
Without consideration of the further details of the different modules currently I package these modules into an EAR to be deployed on a Application Server like GlassFish or WildFly:
my.ear
/
+- META-INF/
| |- application.xml
|- my_ejb_module.jar
|- my_web_module.war
|- my_restservice.war
As in these days WebService and Microservice architecture is discussed more and more often, I wonder if this kind of packaging is a little bit outdated?
As I started the project for several years, this packaging seems to be the best solution, because the EJB module containing the business logic is shared across both web modules.
But when I today look at self-contained microservices I wonder if it would't be better to split the application into two deployable web modules where each of them contains the EJB module:
web-ui.war
/
+- WEB-INF/lib
| |- my_ejb_module.jar
|- my_web_module.war
restservice.war
/
+- WEB-INF/lib
| |- my_ejb_module.jar
|- my_restservice.war
In this setup I would be able to deploy the REST API on a separate machine. So it looks like the approach has no disadvantage against the EAR packaging.
It this true? My question goes in the direction of transactions. Is there any advantage if two web modules sharing the same EJB module in an EAR packaging? Or did the second approach where both web modules contain the same EJB module provide the same functionality concerning transaction handling and concurrency? Especially when both Web modules are deployed on the same application server.
The only disadvantage I can see so far is, that my EJB module can not contain Java EE TimerServices or MessageDriven EJBs as these kinds of EJBs are not supported when deployed in a war module. But this would be acceptable in my case.
I try to answer my question by myself:
After making some test deployments I came to the conclusion, that in my case a split is not possible. The reason is, that my ejb-module contains JPA entity beans. If I deploy two web modules containing the same entity beans that will break any JPA caching concepts. A separation would only be possible if both web modules using the same REST service to access the JPA entity beans.
So my example deployment should look like this
web-ui.war
/
|- my_web_module.war
restservice.war
/
+- WEB-INF/lib
| |- my_ejb_module.jar
|- my_restservice.war
where the restservice.war is the main module containging business logic and the database layer (JPA entity beans) and also publishing a open REST API.
The web-ui.war only contains a web application which interacts via the REST API from the restservice.war.
But bundling the ejb module in both web modules is a bad practice. EAR packaging make sense in case to bundle all modules together and provides the advantage that all client modules (war modules) can access the same EJB module transparent and in a transaction save way.
So a EJB module containing JPA entity beans should only be deployed once and not bundled into multiple deployment units.
The only disadvantage I see in ear packaging is that sometimes ears are some kind of monoliths. To simplify your architecture
you can get rid of ear packaging and decompose those monoliths, if you are using full profile app server, then you can deploy ejb-jar alone as a jar file, and call EJBs from the web modules.
You can create a loosely coupled architecture using JNDI lookup:
ExampleEJB exampleEJB;
...
private ExampleEJB getExampleEJB() {
if (this.exampleEJB == null) {
InitialContext ic = new InitialContext();
this.exampleEJB = (ExampleEJB)ic.lookup("ExampleEJB#com.example.ExampleEJB");
}
return this.exampleEJB
}
Or a tight coupled one using CDI via annotations:
...
#EJB(mappedName="ExampleEJB")
ExampleEJB exampleEJB;
...
JNDI lookup has no restrictions, you can use it in any class. In javaee 6 annotations only works in container managed components (classes annotated with #WebService, #Stateless, #Statefull, etc).

JPA EntityListener and persistence archive

we've a persistence archive containing only Entities and the persistence.xml. And we've an ejb module containing the ejb stuff.
Now for a specific use case we need to add an EntityListener which has access to some EJBs in the service layer.
The ejb module depends on the persistence module. However to declare the listener in the Entity the persistence module needs to know about the class in the ejb module. A cyclic dependency is not possible and having a third module containing only the JPA listener leads to cyclic dependencies as well.
So the only option I see is to merge the ejb module and the persistence archive into a single module. However that way we loose the flexibility to use the persistence archive in another application to connect to the remote interfaces without carrying the whole ejb jar's content.
Any ideas on how to solve this and stay modular (separate ejb and persistence modules?).
We're talking about a JEE7 application.
You could move the persistence.xml from your JPA project to your EJB project and then use the <jar-file>packedEntity.jar</jar-file> XML element. Check this answer.
One idea is to use your Source-Control-Management (git/svn/cvs) to import the entity package in your EJB project (+the persistence.xml file). This way, you have more flexibility on what/how you define them.
In SVN you have svn:externals. For git check out this answer.

How to combine Yeoman scaffolding with existing Java directory structure

In my existing web project the directory structure for the served html content while development with jetty is "myProject/src/main/webapp/"
Now, I want to integrate an angularjs project here.
I've played a little bit with Yeoman.
If I'm scaffolding with yeoman, I'm wondering how I can integrate it into our existing dev and deployment structure.
I suppose to use the main folder "myProject" to run yeoman scaffolding would be fine. Then I would get a "myProject/app/" diretory for all my frontend stuff. Should I instruct somehow (how?) my jetty server to use ".../src/main/webapp/" as an alias for the new app directory?
We use jetty mainly as a proxy for requesting the backend. Is there also a way to do a live reload similar to "yeoman server" in combination with jetty?
Take a look at my answer on how to do Django-Yeoman integration.
Architectural concepts will be the same, even external articles (definitely must-reads) are Java-based.
In short:
Use yeoman-maven-plugin. If you are on Gradle that's still ok. Even better, since you will have better control over which grunt tasks are being invoked.
Your project structure should resemble this:
pom.xml
src/
main/
java/
...
resources/
...
webapp/
WEB-INF/
yo/
dist/
<<the rest of the Yeoman-generated stuff>>
Yeoman generators, including the one initialising the frontend part, should be invoked exclusively from yo directory.
The plugin takes care for copying production-ready yo/dist to WEB-INF.
All you have to do is to serve the latter as a static resource.
Config for Spring MVC (dispatcher servlet):
<!--Yeoman static content-->
<mvc:resources location="WEB-INF/yo/" mapping="/**"/>
One should aim for similar config when using other technologies, like Jetty, or pure Servlet config.
The rest, particularly dev setup, is described in referenced answer.

Categories