Currently I've a JHipster 3.3 monolithic application and I would like to migrate to microservices architecture. I've already created the registry, the gateway and the uaa service. Now I need to migrate the core business of my application into a microservice. Is there a facility to perform it? Can I make it automatically?
You could either convert your monolith into a service, or re-generate it from your entity definitions.
First approach requires a good understanding about Spring Cloud, you'd start by annotating your app with #EnableEurekaClient, add missing depdendencies on Spring cloud to your pom.xml, add missing properties to your application*.yml, create bootstrap*-yml files. Then you would move your client part to your gateway. This is not easy especially if you're new to spring cloud.
Second approach requires you to generate a microservices app with same options as your monolith, then copy to it your .jhipster folder which contains your entity definitions and re-generate them running yo jhipster:entity <entityName> for each entity in same order as you created them initially and then generate htem also on gateway for generating the client part.
You should also take time to think about why you're migrating, if you turn your monolith app into a single service then it might be a bad idea as you'll only add complexity, it makes sense only if you are planning to add more services and/or split your monolith into several services. There is a good free ebook and video at O'Reilly: "Microservices AntiPatterns and Pitfalls"
For start I want also to subscribe to the last part of the answer of Gaƫl:
think about why you're migrating?
Personally I am at the moment in a migration process. I start in 2015 a JHipster monolith app (at that time that was the only option :) ) which I still develop and add new features. For my monolith I decide to migrate to microservice because we gone increase the team and want to go with a DDD in the future. I must admit that there is some overhead at the begin and the learning curve is quite steep but in the end the results are very rewarding especially if you believe in CI (y)
This is how I migrate my monolith:
be sure that you have all your sources commited and sync with your VSC (I use git as DVCS)
without any changes just run the jhipster generator and overwrite all the old sources
make a git diff to have an overview of the files that are generated from jhipster and which you have modified
if you have not changed the format of the files that jhipster generates it should be just some files in webapp folder and configuration file
if you have differences only because of formatting I will recommend to check the code and then update your base code of your monolith app
the target is to have a few as possible differences when regenerating the the monolith app with the jhipster generator (is better to have fewer files to check when migrating to microservices)
at this moment I imply that you are on clean workspace (i.e. all your changes are sync with the VCS) and if you will run a yo jhipster you will have as few as possible file to recheck manually
in the root folder of the app there is a .yo-rc.json file
in that file you should change the applicationType from monolith to getaway and authenticationType from what you have to jwt e.g.
.yo-rc.json
"jhipsterVersion": "3.5.1",
"serverPort": "8080",
"applicationType": "gateway",
"jhiPrefix": "jhi",
after merging the new generated files you should have now the gateway of the microservice (it can be that you need to delete some classes depending on which authenticationType your monolith use to have)
personally I am working now on moving some of the responsibilities(all the staff that the old monolith did) which exist in the gateway to migrate to sand alone microservices
the migration of the services mentioned in 6.1 is something that goes parallel with adding new features to the app and those will be added as new microservices
My recommendation is to go in small steps/increments and it will be nice if you have a CI so that you can have asap also a feedback about your migration ;)
Good luck.
Cheers, duderoot
Related
I have some tiered ABP.IO application template project deployment questions - but they may be ASP.NET Core deployment questions.
Background
I'm a bit confused as to whether I need to create appsettings.Production.json files to mirror the appsettings.json files in my class library projects (MyProduct.Application, MyProduct.Application.Contracts, etc.) AND my four ASP.NET projects (MyProduct.HttpApi.Host, MyProduct.IdentityServer, MyProduct.Web, and MyProduct.Web.Public) OR whether I just need to create them for ONLY the four ASP.NET projects and make sure that the settings that are in the class library projects are represented in the ones for the ASP.NET projects.
Questions
Should I create appsettings.Production.json files in my class
library/DLL projects?
If yes to 1, will the launchSettings.json file be the right place to
ensure that the libraries are built with the production
configuration?
If yes to 2, are there any considerations when deploying to
production? I know I need to use an environment variable on the
server.
If no to 1 or 2, how do I build my libraries to use the production
configuration?
Is it possible to replace the client secrets wherever they may
appear? It would seem like it would be necessary but there's no help
on this in the documentation. Are there any considerations toward
doing this? Is a simple search and replace of all the default
secrets sufficient or are there code changes necessary?
Is it possible to replace all references to localhost with the FQDN
of the respective site (Host/API, IdentityServer, Web, Web.Public)?
The application template would require this, correct? I am doing an
IIS deployment currently - not a Docker or Kubernetes deployment.
What else am I missing?
Thanks for taking the time to comment. If you have a resource to share with me, please do. I cannot find a deployment guide or checklist on the ABP Framework site, ABP Commercial site, Community Forum, or Discord channel.
UPDATE
I have been through these two resources and I am a lot more educated about configuration in ASP.NET Core but I still cannot find the answer to my question about configuring class libraries in production. 1 - https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-6.0 2 - https://learn.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-6.0
FINAL UPDATE
Eventually I just had to figure things out but Omer's answers make a lot of sense in hindsight.
My solution was to add the appsettings.Production.json files to each of the deployable projects as suggested below. You can read Omer's answer for details. I pretty much did everything that Omer suggested but I had not thought about the one shot seeding of the Identity Server database tables. That was truly helpful. My final hurdle was figuring out a way to perform DB Migrations on my local DB instance and my remote servers with just a click.
Through various posts, I eventually figured out that I could use the Launch Profile editor buried under the Debug section of the DbMigrator project properties, to create myself two Launch Profiles. I have one for local development and one for production - although through this mechanism, I don't see why you couldn't create one for each part of your staging pipeline.
It should be noted that I deleted the default profile which was named using the project name/namespace.
Here is the Launch Profile editor screen for the Development profile:
And here is the Launch Profile editor screen for the Production profile:
Of primary importance is the ASPNETCORE_ENVIRONMENT=Development environment variable in development and the ASPNETCORE_ENVIRONMENT=Production environment variable in production.
Exiting the editor produces the Properties folder and the contained
launchSettings.json file.
You could create this folder and file yourself without going through the editor. Here is the text of that file:
{
"profiles": {
"EnvironmentConfiguration.Cli (Development)": {
"commandName": "Project",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"EnvironmentConfiguration.Cli (Production)": {
"commandName": "Project",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
}
}
}
}
Now when I want to run a schema migration, I can simply select the DbMigrator project as the startup project...
...and I will have two launch profiles in my debug menu:
Does anyone know of a better way?
I am using ABP with Blazor Wasm and IdentityServer is not seperated. So I am publishing only .Host and .Blazor projects.
No, you only need them for published projects (.Host, .Web, .Blazor etc)
Should I create appsettings.Production.json files in my class
library/DLL projects?
Libraries are not standalone projects. They are used by other projects (By .Host project or they can be used by another library project) So, they will take these configuration settings from live application (.Host, .Web, .Blazor etc)
If no to 1 or 2, how do I build my libraries to use the production
configuration?
These keys are using by IdentityServer and I think they are seeded to Database on initial migration. If you want to change them, you need to change them from appsettings.json files and change value in database also. By the way, it is encrypted and you need to change value in DB with new encrypted value. (https://support.abp.io/QA/Questions/441/About-changing-client-secrets)
Is it possible to replace the client secrets wherever they may
appear? It would seem like it would be necessary but there's no help on this in the documentation. Are there any considerations toward doing this? Is a simple search and replace of all the default secrets sufficient or are there code changes necessary?
Change "localhost" values to your FQDN in all appsettings.json files. Also there should be some changes in database for IdentityServer. Because in the initial migration, it is written on DB.
[dbo].[IdentityServerClientCorsOrigins].[Origin]
[dbo].[IdentityServerClientPostLogoutRedirectUris].[PostLogoutRedirectUri] [dbo].[IdentityServerClientRedirectUris].[RedirectUri]
Is it possible to replace all references to localhost with the FQDN
of the respective site (Host/API, IdentityServer, Web, Web.Public)?
The application template would require this, correct? I am doing an
IIS deployment currently - not a Docker or Kubernetes deployment.
Do not forget to install SSL. If you are using Cloudflare disable SSL from Cloudflare (If you have also in server) Because it may conflict.
Another important thing is to remove Webdav if you are using IIS. Because Webdav occurs error for put request. (https://stackoverflow.com/a/59235862/2178028)
Also, I dont know why but for the first publish of Blazor projects, it gives 403 error for .dll files in ISS. Then I follow this link (https://www.eugenechiang.com/2021/12/12/failed-to-find-a-valid-digest-in-the-integrity-attribute-for-resource-in-blazor-app/) and problem is solved.
What else am I missing?
actually configuration of development mode different from production mode so to handle this you must use appsetting.production.json
answer for first question is no, because all projects use ui project settings by dependency injection
I am using KeyCloak as my user management tool, and love it.
The data of Keycloak is stored for me on a Postgres database. Over time, more clients are being registered, and other alterations to the realms may be done. My question is: How do I properly keep track of that, and propagate automatically changes between my different environments? For databases, I use liquibase for a purpose like this. I couldn't find anything similar for the Keycloak case.
So, I wanted to ask: How are you folks out there handling this? What am I missing?
It depends on how you're doing the management of those changes. There are generally two approaches:
Using the Keycloak admin console
Using the Keycloak CLI
If you're applying your changes via the admin console, then you can either rely on the database backup or setup a scheduled pipeline in your CI tool to make an export of the Keycloak realm into a file and archive it somewhere.
In case you're using the second approach, then you can have a git repository containing all the Keycloak CLI scripts that you run on your server (e.g. to add a client, to update a realm config, etc.). In that case, you can have them reviewed, versioned and then run as part of an automated pipeline. This will also allow you to run a script on different environments. But of course it comes with a price which is to write a script for every single task that you can typically do in admin console with a couple of clicks.
How is the worklightserverhost attribute on the app-builder task used? This is important as when deploying an tested application into a production environment, you normally wouldn't do a new build (as this could introduce regression problems). However, the fact that this is a mandatory property and contains in this scenario the test server URL and context - does it force you then to do a new build for the production environment?
Yes, a re-build for each environment does seem to be the usual approach. While we might prefer a "build once, promote through the stages" pattern, I think by careful use of tagging in your source repository you can get pretty good defence against regression.
Alternatively, I think with care you could set up your network so that the app is built once directing to, say,
myco.mobile.hostv21
you could then have that resolve to the different stages as appropriate.
Currently I am using ms-deploy to build and deploy on several machines using team-city. In my current scenario, I need to build, package and deploy on Dev. After this I need to deploy this package on test and Live servers (which are on different domain. I understand how we do it but problem is Web transformation only occurs for test and live configs if we build a package. It means if I want to use the same package that is created for Dev cannot be used, as web transformation only occurred for Dev web config. Also know that we can change web config when un-packaging but that parameters are very limited. We have a lot of changes not just the connection string or db changes.
Another solution is to add another step to build packages for test and live as part of Dev deployment but then it means a lot of copying on remote servers, once for test and once for live which is a lot of time consuming due to different domains.
Can you please guide what is the best solution in this scenario. So I can use team-city to publish to Dev and test and live using same package and different web configs in one go.
To configure items at deployment time which are not automatically created for you. You can add a file named parameters.xml to your project and extend what you want to make available at deployment time.
Here's some documentation on the approach Using Deployment Parameters for Web.Config File Settings.
I have two Rails 3 applications that will share portions of the same database through an internally developed gem. This is an internal project where we will always have full control over both applications. One application is bare metal administration (dev facing, potentially unstable) and another is the content publishing system (user facing, production). Its not practical nor desirable to meld the applications.
I've already seen Rails - Shared Database Tables between two apps
My proposed solution is to git submodule and share the /db directory of both applications.
I want to know if this is a valid approach, and if so are there any pitfalls I'm setting myself up for? If this isn't valid what is a good alternative? (The goal here is to remain as simple as possible, no interprocess APIs.)
I have used this approach and it does work. If you are using capistrano for deployment enable submodule deployment like this
set :git_enable_submodules, 1
You have to be careful not to forget to sync the /db folder, before you start creating migrations, they are created with a timestamp and you can end up with the wrong sequence of migrations.