Play Framework how to set jdbc properties after startup - scala

In my play application the database settings are not known before startup of the application. I have to read them from an environment variable after automatic deployment and start of the application.
The platform the app is deployed on is cloudfoundry. And there is a environment variable called VCAP_SERVICES (that is a json string). Here are all services listed e.g. the database service including the credentials
Is there a prefered way to do so? In means of still being able to use stuff like:
DataSource ds = DB.getDatasource();

Related

How to configure Quarkus Dev Services besides prod config?

I want to use dev services to start postgres db on local application startup (quarkus profile = local).
Dev services are active in test and dev mode, so by not defining quarkus.datasource.jdbc.url it is actually working already with following config:
quarkus.datasource.db-kind=postgresql
quarkus.datasource.devservices.port=5432
quarkus.datasource.username=postgres
quarkus.datasource.password=postgres
However, I don't know how to configure this besides a prod configuration which has a quarkus.datasource.jdbc.url defined e.g.
%local.quarkus.datasource.devservices.enabled=true
%local.quarkus.datasource.db-kind=postgresql
%local.quarkus.datasource.devservices.port=5432
%local.quarkus.datasource.username=postgres
%local.quarkus.datasource.password=postgres
quarkus.datasource.db-kind=postgresql
quarkus.datasource.jdbc.url=jdbc:postgresql://myProdDB.com:5432/mydb
If I start the application with quarkus profile = local, instead of spinning up postgres on docker, quarkus falls back to the prod property quarkus.datasource.jdbc.url which I don't want for my local dev environment.
If I prefix the prod properties with a prod profile like %prod.quarkus.datasource.jdbc.url this fallback can be prevented, however, I want to follow the convention that prod properties are default, thus not prefixed with profile.
I already tried without success to somehow set %local.quarkus.datasource.jdbc.url to an empty value to prevent fallback to quarkus.datasource.jdbc.url:
%local.quarkus.datasource.jdbc.url="" -> java.sql.SQLException: Driver does not support the provided URL: ""
%local.quarkus.datasource.jdbc.url=null -> java.sql.SQLException: Driver does not support the provided URL: null
%local.quarkus.datasource.jdbc.url= -> io.quarkus.runtime.configuration.ConfigurationException: Model classes are defined for the default persistence unit default but configured datasource default not found: the default EntityManagerFactory will not be created. To solve this, configure the default datasource. Refer to https://quarkus.io/guides/datasource for guidance.

How Environment variable names reflect the structure of an appsettings.json

I am using ASP.NET Core 5.0 and I have a Web API app deployed to internal cloud where few settings like DB are controlled via environment variables on the host cloud. In my Startup.cs I have the below code
string projectDbConnection = Configuration.GetSection("ProjectDatabaseSettings").GetValue<string>("PROJECT_DB_CONNECTION");
string projectDbName = Configuration.GetSection("ProjectDatabaseSettings").GetValue<string>("PROJECT_DB_NAME");
Here as I understand, when running locally in IIS Express it looks for appsettings.<Environment>.json and they take precedence over appsettings.json values.
But this app is always connecting to the wrong DB when I deployed to Cloud where I mentioned the PROJECT_DB_CONNECTION & PROJECT_DB_NAME as Environment variables for the app.
To make the app read from the Environment variables I had to change the above Code in Startup.cs as
string projectDbConnection = Configuration.GetValue<string>("PROJECT_DB_CONNECTION");
string projectDbName = Configuration.GetValue<string>("PROJECT_DB_NAME");
I am unable to understand the difference between the GetSection.GetValue and just GetValue and why I should use Configuration.GetValue() to direct app to read from Env variables.
what am I missing and when should we use what?
Naming of environment variables
There is kind of a naming convention in the environment variables for nested appsettings to env vars, see naming of environment variables.
Each element in the hierarchy is separated by a double underscore.
In your case it would work if you name the env variable: ProjectDatabaseSettings__PROJECT_DB_CONNECTION.
Config Order
Regarding to Microsoft Documentation there is a order in which the config sources are checked.
ChainedConfigurationProvider : Adds an existing IConfiguration as a source. In the default configuration case, adds the host configuration and setting it as the first source for the app configuration.
appsettings.json using the JSON configuration provider.
appsettings.Environment.json using the JSON configuration provider. For example, appsettings.Production.json and appsettings.Development.json.
App secrets when the app runs in the Development environment.
Environment variables using the Environment Variables configuration provider.
Command-line arguments using the Command-line configuration provider.
The usecase
This is useful when you are developing local using appsettings.json, but run in a cluster or cloud in production where it is more convenient to use environment variables (f.e.: in kubernetes environment variables are set via config maps).

Specify postgresql database name in cloud foundry manifest.yml

Is there a way to specify a postgresql database name to connect to in the cloud foundry manifest.yml file? I've been raking through the documentation and haven't yet found this specific information.
I'm imagining something like this:
applications:
- name: my-app
routes:
- route: my-app.mybluemix.net
services:
- postgres
dbname: database2
With that approach, a postgresql connection can be made by just the connection string provided by VCAP_SERVICES parsing modules (cfenv in the case of node).
If this is not possible, I will just set a dbname environment variable and build my own connection string.
There is nothing like that in a Cloud Foundry application manifest.yml.
The manifest.yml only takes a list of service instance names and the services with those names will be bound to your app. It does not allow you set other metadata.
https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html#services-block
I don't know if these will help, but when you cf bind-service directly there are two additional provisions you can make use of (these are not supported by manifest.yml as of me writing this):
Arbitrary bind parameters. These probably won't help unless your service broker supports them, but it's a way to pass additional info to the service broker. If your broker supported it, you could in theory say give me a database named XYZ by passing it some config this way.
Named service bindings. This provides what amounts to a second name. The intent is that you can create the service with a name of X, but your application can look for a service binding with name Y. You can use this to swap in differently named services, but still expose the same binding name to the application so it will always find the service.
If you are trying to pass in some other service instance related metadata to your application, you'd need to do it some other way. Like if you want to tell it the database name or the connection pool size, etc.. Using environment variables like you mentioned is one option. You could use a config file or cli arguments passed to your application. What you pick is probably a matter of preference/support in the library/framework you're using.
For what it's worth, most service brokers I've seen pass in and tell you a specific database name to use. If the broker said connect to db XYZ and you made your connection to myCoolDb, the connection would fail. Just wanted to mention this. Your mileage may vary.

How to change application server database in k2 blackperl application?

I have K2 blackpearl application which have 2 databases: 1 is k2 database i.e. product database and another is the application database for keeping application data. I am not aware how the application database was configured, but I want to change the application database location to some different serer.
I have already checked smartobject tester and hostserver configuration.
Any idea where i can make connection string changes for this?
If your "Application Data" contains LOB data and is used in your custom solution, you need to perform the following to change it to different server:
Backup that database
Restore it to different server
Edit configuration of Service Instance (SQL Service Instance) corresponding for that database according to that different server
configuration. Usually, it is required to change "Server Name", "Use
Native SQL Execution" and "On Different Server" properties on that
service instance. You can perform these changes using K2 Management site or
SmartObject Service Tester Tool
If your K2 application uses SQL Server as a data source then it most likely uses SQL Server Service broker for this type of integration. If you are new to K2 you have the following logical hierarchy:
Service Type
Service Broker
Service Instance
SmartObjects
Service Broker it is something that allows you to connect to external system (SQL Server in your case) and Service Instance represents instance of this system accessible to K2 (SQL Server database) based on which you can create SmartObjects - representations of objects within external system with which K2 can interact (SQL tables, stored procedures etc. in your case).
I hope from description above it is clear that your app DB connection string lives at Service Instance level. To adjust it you have to do the following:
1) Run SmartObjects Services Tester (default location: "C:\Program Files (x86)\K2 blackpearl\Bin\SmartObject Service Tester.exe")
2) Expand SQL Server Service category and select service instance corresponding to your app database. It should be clear from name (if naming conventions were followed when it was created), but if not just edit its properties - there you will see Database and Server properties corresponding to SQL database name and SQL Server name respectively.
3) Once you located right service instance just edit its properties adjusting server and database name. Here how it looks like:
If necessary refer to #Dragan Panjkov answer or documentation I mentioned above for information about additional settings you may need to adjust.
To do this you need to run the K2 setup tool - you can access it from the start menu. You just need to run through the wizard (which will be pre-populated with your existing settings), and update the K2 database settings when you get to it.

Create app instance (in service fabric cluster explorer) ignores number of instances on local machine

Using 5.1.163 version of service fabric run time.
Created a service fabric application with one stateless web api (i.e. using owin communication listener).
Modified the generated code so that listening endpoint to contain partition id/instance id/new_guid (just as is the case for stateful services). This should allow me to create another app instance so that I can have multi-tenancy at application level.
By default, Local.xml file is set to 1 instance for this service.
Deployed it to local machine by F5. Verified that it is deployed to only one instance.
Verified that service is working fine.
Navigated to local service fabric explorer and clicked on the Cluster/Application/AppType node. Clicked on 'Create app instance'.
It successfully created 2nd app instance.
However in this new instance, the service is deployed to all 5 nodes.
I was expecting it deploy the service instance only one node. Is this a bug? But only in this version of service fabric?
When you deploy a Service Fabric application using Visual Studio (or from PowerShell) you use the Deploy-FabricApplication.ps1 that is generated for your application and found in /scripts under your SF project. This script does two things (mainly):
Create/update the application type
Create a new/upgrade existing instance of the application type
The second part there is similar to what you do in the SF Explorer, except this one also considers the publisher profile file you supply. The PS-script actually reads your publisher profile xml files and extracts any parameters in there to a hashset (a dictionary) and passes that as an argument in step 2.
You can create an instance of an SF application type using the PS cmdlets (alternatively you can use FabricClient). The following command does this: New-ServiceFabricApplication. Here you have the chance to supply your own application parameters, including instance count for services in your new application instance (if you have a dynamic parameter for that in your application manifest).
So, when you use the SF explorer to create a new application instance you cannot control how that instance is created, it is always using the default parameter values as specified directly in ApplicationManifest.xml, not values you have specified in your publisher profiles (local1, local5, cloud, etc.).
To controll the creation, run New-ServiceFabricApplication with yor parameters as a hashset.