I was wondering: how does one go about configuring WAS if they want to store some confidential information that is not datasource, JMS or Mail related? I'm looking more for an adhoc JNDI resource (a few Strings) that can be queried at runtime to get both a username and password for a vendor system I need to connect to.
Not being uber familiar with WAS, I'm sort of lost. In Tomcat it was a breeze. In WAS, I think I'm missing a few concepts, I'm sure it's possible though.
WAS JNDI is open to extension using your own URL provider class. The examplehere uses the capability to point to property files, but presumably you could instead create a provider that obtained data from a database (or whatever repository you are required to use) instead of a property file.
You can define your own JNDI entries.
Under Environment -> Naming -> Name Space Bindings you can create String binding type, and assign a key and value which can be looked up by the applications.
Is this what you are after?
Manglu
Related
We are working on a spring boot library to generate and validate OTP. It uses database to store the OTP.
We are using Spring Data JPA for Database operations, as it will be easy to handle multiple database systems according to the project.
Now we have ran in to a problem, most of our projects uses Oracle with a single database.
When using the the same lib in multiple projects there is a name conflict.
So we want the name of the OTP table to be configurable using a property file.
We tried #Table(name = "${otp-table-name}") But its not working.
We did a lots of research and found out the hibernate naming strategy configuration can help.
But we dont want to use lots of configuration in our library as we need the library to be easily usable in the projects.
Can someone help us on this aspect.
Thanks in advance.
You can dynamically determine the actual DataSource based on the current context, use Spring's AbstractRoutingDataSource class. You could write your own version of this class and configure it to use a different data source based on the property file.
This allows you to switch between databases or schema without having to change the code in your library.
See: https://www.baeldung.com/spring-abstract-routing-data-source
Using a NamingStrategy is good approach.
You could let it delegate to an existing NamingStrategy and add a prefix.
Use a library specific default for the prefix, but also allow users of your library specify an alternative prefix.
This way your library can be used without extra configuration, but can also handle the case of multiple applications using it in the same database schema.
Of course this might involve the risk of someone using the default prefix without realizing that, that is already used.
It is not clear what the consequences of that scenario are.
If the consequences are really bad you should drop the default value and require that a project specific prefix is used.
When no prefix is specified throw an exception with an instructional error message telling the user, i.e. the developer how to pick a prefix and where to put it.
WSO2 Identity Server 5.0.0 (and some patches ;))
It does not appear that custom JDBC user store managers (child of JDBCUserStoreManager) use a JDBC pool. I'm noticing that I can end up session closed errors and sql exceptions whereas the Identity Server itself is still operating OK with its separate database connection (a configured pool).
So I guess I have two questions about this:
Somewhere up the chain, is there a JDBC pool for the JDBCUserStoreManager? If so, are there means to configure that guy more robustly?
Can I create another JDBC datasource in master-datasources.xml which my custom JDBC user store manage could reference?
Instead of using your own datasources/connections, you can import Carbon Datasources and use those (they come with inbuilt pooling and no need to worry about any configurations etc). You can either access these programmatically by directly calling ndatasource component or access them via JNDI.
To access them directly from ndatasource component:
The dependency:
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.ndatasource.core</artifactId>
<version>add_correct_version_here</version>
</dependency>
(You can check repository/components/plugins to find out the correct version for above dependency)
You can inject DataSourceService as in this code (the #scr.reference tag refers to the service you need to inject, this uses maven scr plugin to parse these dependencies when building the bundle).
Note that when you follow this approach you'll have to build the jar as an OSGi bundle as it uses declarative services (and have to place it in repository/components/dropins). Otherwise the dependencies won't be injected at runtime.
Next, you can access all the data sources as:
List<CarbonDataSource> dataSources = dataSourceService.getAllDataSources();
Rajeev's answer was really insightful and helped with investigating and evaluating what I should do. But, I didn't end up using that route. :)
I ended up looking through the Identity Server and Carbon source code and found out that the JDBCUserStoreManager does end up creating a JDBC pool configured by the properties you set for that manager. I had a class called CustomUserStoreConstants for my custom user store manager which had setMandatoryProperty called by default to set:
JDBCRealmConstants.DRIVER_NAME
JDBCRealmConstants.URL
JDBCRealmConstants.USER_NAME
JDBCRealmConstants.PASSWORD
So the pool was configured with these values, BUT that was it...nothing else. So no wonder it wasn't surviving the night!
It turned out that the code setting this up, if it found a value for the JDBCRealmConstants.DATASOURCE in the config params, it would just load up that datasource and ignore any other params set. Seeing that, I got rid of those 4 params listed above and forced my custom user store to only allow having a DATASOURCE and I set it in code with the default JNDI name that I would name that datasource always. With that, I was able to configure my JDBC pool for this datasource with all params such as testOnBorrow, validationQuery, validationInterval, etc in master-datasources.xml. Now the only thing that would ever need to change is the datasource's configuration in that file.
The other reason I went with the datasource in the master-datasources.xml is that I didn't have to decided in my custom user store's code which parameters I would want to have or not have and just manage it all in the xml file easily. This really has advantages with portability of configs and IT involvement for deployments and debugging. I already have other datasources in this file for the IS deployment.
All said, my user store is now living through the night and weekends. :)
I want to open access to a database using JDBC protocol, so that many people in the company can access it.
The JDBC connection string would look like jdbc:sqlserver://[serverName[\instanceName][:portNumber].
I'm wondering if there is a way to have a layer of abstraction between the client and the server. Let me explain...
For example, using REST services, we can tell people to use a URL that looks like https://servername/path/to/resource/123, which we can url-rewrite to https://my-server/my-path/resource?id=123. Implementation, location, complexity is hidden from the user, and anything can be changed transparently.
Is there something similar we can do with JDBC ? For example, can I redirect jdbc://[serverName[\instanceName][:portNumber] to jdbc:sqlserver://[my--server[\my-instance][:my-port] ?
Thanks for your help !
We can't rewrite JDBC url.
But you can use JNDI (Javax Naming Directory Interface). You must configure JNDI data source first, ex: in tomcat 6.0
Then you can use this JNDI in your application
We're using Jasypt to encrypt some config properties (database passwords) but since the decryption key is stored on each environment's file system we have to do some manual #Bean configuration to load the password from the file then overlay loading properties with an EncryptablePropertiesPropertySource.
Because it is so manual we've had to run this code in #PostConstruct of the WebApplicationConfig class and (although this hasn't happened yet) it runs the risk of loading these after the datasource bean is configured with calls to the Environment - giving null pointer exception. #Lazy loading would be an option but obviously this means we'd then be working with fragile config which we'd like to avoid.
Ultimately we want to be able to use the default classpath:application.properties so don't want to affect existing (default) setup, but we do want to be able to use an encryptable property source as a complete replacement to the Spring one, and to have Spring load the decryption code from a file before anything else happens. Is there a way to tighter integrate loading encryptable properties earlier in the application startup and configuration?
I'm "tailoring down" my previous answer since it got deleted because it was duplicate from a different question:
This library does exactly what you need jasypt-spring-boot which is basically to allow you use the #PropertySource annotation to define your properties the same way you're use to. You just have to add an extra annotation (#EnableEncryptableProperties) to your configuration file.
It is not only limited to that, every PropertySource present in Environment will be converted to EncryptablePropertySourceWrapper, a custom wrapper that checks when a property is encrypted and decrypts it on access.
The link Dave provided in the comments section unfortunately points to nothing now, but navigating from its root I got to the following example project:
https://github.com/spring-cloud-samples/configserver (also written mostly by Dave, of course)
I think it serves as a great example for what was discussed in the comments until now.
Also, for future reference (maybe it will be done at some point), there's a Spring Framework Jira ticket for the feature of using encrypted properties: https://jira.spring.io/browse/SPR-12420
For a team of developers it is essential that everybody sets up and configures the application server. In our case we are using websphere 8.5.
I'm looking for an easy way to do this. Normally you do it using the profile management tool located in WAS_HOME/bin/ProfileManagement and this tool works quiet well. But after the installation of the websphere server one still needs to configure the server profile - creating datasources, JMS queues, buses, variables and so on. So I thought it would be nice if there is a way to apply these configurations to an existing profile.
My first try was to just configure one profile and then make a configuration backup using
%WAS_HOME%/bin/backupConfig.bat
But the configuration contains e.g. the hostname and other host dependent configurations. So the backupConfig.bat tool is not what I'm looking for.
The next thought that came in my mind is that I might could create a special profileTemplate. So that others can use the profile management tool and use this template. But the template structure does not seem to be made for customization. A lot of files and nearly no documentation can be found of how to create an own profile template.
So I came across the augment templates. These template are used (as the name implies) to add specific configuration to an existing profile. I found a lot of documentation of how to apply an augmentation to an existing profile but no documentation of how to create an augmentation.
At last I think that there must be some way of exporting websphere datasource, buses, jms etc. configuration and apply them to other profiles, because in very big installations the operations team must have this ability.
I know that I can add container-specific descriptors to the EAR. E.g. META-INF/ibmconfig/cells/defaultCell/applications/defaultApp/resources.xml. But I don't want to build environment specific EAR files, because it couples our builds to the infrastructure and thus we have to build and redeploy when ever operations changes the infrastructure, e.g. hostnames, IPs, passwords.
Does anyone know how to manage the distribution of datasource, buses, jms, etc. to multiple websphere installations?
In addition to wsadmin scripts - which are very good for these kind of tasks, I'd suggest Properties-based configuration. It might be more useful for you, since it allows to export many configuration objects at one time and then apply it to different environments. It is also might a bit easier, since you work on plain text files instead of jython scripts.
Properties file based configuration enables you to:
Extract data out of the configuration repository to create properties
files.
Update a properties file to manipulate the configuration, as
needed.
Apply the updated data in the properties file to a target
configuration repository.
See more details here:
Properties-based configuration
Infocenter documentation
Education assistant
I suggest you to use wsadmin shell scripting and create a script for resource creation. A bonus is that you can run it directly from RAD (right click Run As->Administrative Script).
Here is the complete example written in Jython for JDBC resource creation along with JAAS login information (note: I'm using Oracle Database, your setup could be different depending on database you are using):
cell=AdminConfig.showAttribute(AdminConfig.list("Cell"), "name")
node=AdminConfig.showAttribute(AdminConfig.list("Node"), "name")
#Add JAAS credentials
print "Adding JAAS credentials"
security = AdminConfig.getid('/Cell:'+cell+'/Security:/')
alias = ['alias', node+'/dbUser']
userid = ['userId', 'DBUSER']
password = ['password', 'PASSWORD']
jaasAttrs = [alias, userid, password]
AdminConfig.create('JAASAuthData', security, jaasAttrs)
AdminConfig.save()
#Add JDBC jar path
print "Adding JDBC jar path"
AdminTask.setVariable('[-variableName ORACLE_JDBC_DRIVER_PATH -variableValue ${WAS_INSTALL_ROOT}/lib/ext -scope Cell='+cell+',Node='+node+']')
AdminConfig.save()
#JDBC Provider print "Adding JDBC Provider"
AdminTask.createJDBCProvider('[-scope Node='+node+',Server=server1 -databaseType Oracle -providerType "Oracle JDBC Driver" -implementationType "Connection pool data source" -name "Oracle JDBC Driver" -description "Oracle JDBC Driver-compliant Provider." -classpath ${ORACLE_JDBC_DRIVER_PATH}/ojdbc6.jar]')
AdminConfig.save()
#JDBC Datasources print "Creating Datasource"
AdminJDBC.createDataSourceAtScope("Node="+node+",Server=server1", "Oracle JDBC Driver", "test", "jdbc/test", "com.ibm.websphere.rsadapter.Oracle11gDataStoreHelper", "jdbc:oracle:thin:#10.0.0.1:1521:TEST", [['componentManagedAuthenticationAlias', node+'/test'], ['containerManagedPersistence', 'true']])
AdminConfig.save()
I just remebered the wsadmin tool and guess it is the best way to implement my requirements.
Fortunately IBM provides sample scripts that show you how to create datasources or modify them using jython or jacl scripts.
An example of how to create datasources can be found for example in the Administration scripts (1-12) -- Jython version (file ex7.py in the zip)
Hope this helps others who have the same or similay question.