How to configure Oracle's Database Network Encryption with MyBatis? - oracle

I have a requirement to encrypt the data in transit between the web server and the database server using Mybatis as the persistence framework.
The database server is Oracle 12c Enterprise Edition Release 12.1.0.2.0 - 64bit. I am using the ojdbc7.jar driver.
I am able to establish an encrypted connection as described here... https://docs.oracle.com/database/121/DBSEG/asojbdc.htm#DBSEG9613. However, I have not been able to do so through MyBatis. I am setting the connection properties in the mybatis-config.xml file. Below are the contents of that file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC '-//mybatis.org//DTD Config 3.0//EN' 'http://mybatis.org/dtd/mybatis-3-config.dtd'>
<configuration>
<settings>
<setting name="lazyLoadingEnabled" value="false" />
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:#//<server>:<port>/<service>"/>
<property name="username" value="<username>"/>
<property name="password" value="<password>"/>
<property name="poolMaximumActiveConnections" value="20"/>
<property name="poolMaximumIdleConnections" value="10"/>
<property name="poolMaximumCheckoutTime" value="180000"/>
<property name="poolPingQuery" value="select 0 from dual"/>
<property name="poolPingEnabled" value="true"/>
<property name="poolPingConnectionsNotUsedFor" value="1800000"/>
<property name="CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_LEVEL" value="REQUIRED"/>
<property name="CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_TYPES" value="AES256"/>
</dataSource>
</environment>
</environments>
</configuration>
The last two property elements are my attempt at configuring an encrypted connection. Without them I am able to connect successfully without encryption. With the last two property elements I just get an error:
Caused by: org.apache.ibatis.exceptions.PersistenceException: ###
Error building SqlSession. ### The error may exist in SQL Mapper
Configuration ### Cause: org.apache.ibatis.builder.BuilderException:
Error parsing SQL Mapper Configuration. Cause:
org.apache.ibatis.datasource.DataSourceException: Unknown DataSource
property: CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_TYPES
Does anybody know how to solve this?

The names of the JDBC properties are not quite right. Note that they can be found in the JavaDoc under oracle.jdbc.OracleConnection. You can try these:
EDIT: as Chris explained in this comments MyBatis requires the driver's property name to be prefixed with "driver".
<property name="driver.oracle.net.encryption_client" value="REQUIRED"/>
<property name="driver.oracle.net.encryption_types_client" value="(AES256)"/>

Related

LDAP Queries are very slow on SSL (Java - SpringFramework)

We have a web application in Java (Spring Framework). For authentication and user management, we are using SSO with LDAP.
The LDAP context is as defined in the bean below:
<bean id="legacyLdapContext" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="ldaps://aaa.bbb.ccc.edu:636"/>
<property name="base" value="cn=Users,dc=bbb,dc=ccc,dc=edu"/>
<property name="userDn" value="user"/>
<property name="password" value="*****"/>
<property name="pooled" value="true"/>
<property name="baseEnvironmentProperties">
<map>
<entry>
<key>
<value>java.naming.security.authentication</value>
</key>
<value>simple</value>
</entry>
<entry key="java.naming.referral">
<value>ignore</value>
</entry>
</map>
</property>
</bean>
Everything works fine, but the connection/queries are very slow.
If the same configuration is changed to non ssl (`ldap://aaa.bbb.ccc.edu:389') it is lightening fast. A query that takes the non SSL context just a few seconds, takes the SSL context 7 minutes.
Is there any LDAPS related configuration missing? I have installed the certificate to JVM using the steps here http://javacolors.blogspot.in/2012/05/how-to-register-ssl-certificates-in.html .
To force the JVM to pool SSL connections, add the following line to your Apache Tomcat /bin/setenv.sh ({{setenv.bat}} for Windows) file
On Linux:
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.jndi.ldap.connect.pool.protocol='plain ssl' -Dcom.sun.jndi.ldap.connect.pool.authentication='none simple DIGEST-MD5'"
On Windows:
JAVA_OPTS=%JAVA_OPTS% -Dcom.sun.jndi.ldap.connect.pool.protocol="plain ssl" -Dcom.sun.jndi.ldap.connect.pool.authentication="none simple DIGEST-MD5"
https://confluence.atlassian.com/display/CROWDKB/Performance+problem+when+using+LDAPS

Postgresql database location for maven build tests

I have big maven project. So I run mvn clean install. But I get errors on tests. The sql connection exception. I have sql file with database for Postgresql. Should I have create database (with user and password) on localhost? So how do junit tests run? Do they need server with database on localhost?
This xml for connection database:
<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="org.postgresql.Driver" />
<property name="jdbcUrl" value="jdbc:postgresql://localhost/lion" />
<property name="user" value="osm" />
<property name="password" value="101918" />
<property name="maxPoolSize" value="100" />
<property name="minPoolSize" value="5" />
<property name="acquireIncrement" value="5" />
<property name="idleConnectionTestPeriod" value="300" />
<property name="maxStatements" value="0" />
<property name="maxIdleTime" value="100" />
</bean>
Yes, apparently you have a project with Spring integration tests connecting to real PostgreSQL database. Most likely other developers have such a database installed so it works for them. Not perfect but sometimes necessary.
That being said yes, you need to isntall PostgreSQL, create lion database and all needed tables. Moreover database user name and password are apparently hard-coded in your configuration (should they be posted here?), so you must either create the same user in your PostgreSQL server or (better) externalize jdbcUrl, username and password.
Finally consider incorporating flyway, brilliant little library that will create your database tables if you start an application on empty schema.

Cloudbees, Tomcat, and Spring: "Cannot create JDBC driver of class '' for connect URL 'null'"

I'm trying to deploy my Spring MVC webapp (Hibernate and JPA) to a Tomcat 7 ClickStack in Cloudbees, but cannot seem to configure the database connection properly. I've tried following multiple tutorials (which offer many solutions), none of which have worked. If someone could take a look at my config files below and let me know if they see anything wrong it would be greatly appreciated.
The error:
java.lang.NullPointerException
org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'
First, I bound my database to my app using the cloudbees cli so that I don't have to declare it in cloudbees-web.xml:
bees app:bind -a myapp/app -db mydatabase
application - myapp/app bound to cb-db:myapp/mydatabase as mydatabase
(I have also tried unbinding the database and defining it in cloudbees-web.xml and also in context.xml without success)
spring-data.xml:
<jee:jndi-lookup id="datasource" jndi-name="jdbc/mydatabase"
lookup-on-startup="false" proxy-interface="javax.sql.DataSource"
cache="true" resource-ref="true" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="hibernate-jpa"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
<property name="showSql" value="false"/>
<property name="generateDdl" value="true"/>
</bean>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
</bean>
web.xml:
<resource-ref>
<res-ref-name>jdbc/mydatabase</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
I have removed all references to connectors from my Maven files and all jars from the lib folder. Searching for the error message shows that it usually has to do with the driver not being found... but since the database is supplied by the container, why do I have to worry about that?
-- EDIT: Working META-INF/context.xml file --
Note that the com.cloudbees.jdbc.Driver referenced in a lot of the docs didn't work (threw a classnotfound exception), so I had to package the mysql-connector-java.jar file in the lib folder. Also, for now I just hardcoded the url, username, and password instead of setting it up to use the system properties.
<Context>
<Loader delegate="true"/>
<Resource
name="jdbc/mydatabase"
auth="Container"
type="javax.sql.DataSource"
maxActive="5"
maxIdle="2"
username="USERNAME"
maxWait="5000"
driverClassName="com.mysql.jdbc.Driver"
password="PASSWORD"
url="jdbc:mysql://MY_EC2_DB_URL:3306/mydatabase"/>
</Context>
I was facing the same issue and finally managed to "properly" configure the datasource !
I'm using a PropertyPlaceholderConfigurer as follows :
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="database" value="MYSQL" />
<property name="generateDdl" value="false" />
</bean>
<context:property-placeholder system-properties-mode="FALLBACK" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${dt4j.driver}" />
<property name="url" value="${dt4j.url}" />
<property name="username" value="${dt4j.username}" />
<property name="password" value="${dt4j.password}" />
</bean>
"FALLBACK" indicates placeholders should be resolved against any local properties and then against system properties.
Finally, I just need to add system properties (-Dprop=value) or add them in the Cloudbees deployer plugin to make it work.
There must be a better way but the main goal is achieved : the data source configuration is not hardcoded in the project !
Unfortunately at this point in time, the JNDI DB setup is not done for you in the tomcat7 stack.
When you bind the database to your app - it injects some system properties:
MYSQL_PASSWORD_MYDB
MYSQL_URL_MYDB
MYSQL_USERNAME_MYDB
(MYDB as it is the name of your db resource). You can then refer to them in your code/config.
For tomcat 7, you can put in /META-INF/context.xml into your app which will set up the JNDI data source (see http://tomcat.apache.org/tomcat-7.0-doc/jndi-datasource-examples-howto.html)

Setting V$SESSION.program property on Glassfish JDBC Connection Pool

my Java EE App is deployed on Glassfish 3.0.1, and uses a JDBC Connection Pool to Connect to an Oracle 9i database. I am using JPA to read/write data to the database, which is working fine. However, to get better reporting regarding the load this app is putting on the database, I want to set the V$SESSION.program column for use by oracle.
From various google searches (eg. http://forums.oracle.com/forums/thread.jspa?messageID=3271623) it looks like I should just be able to add this as a property, the same as you would set any other property. So I have tried this by changing the domain.xml file for Glassfish (see below), and the V$SESSION.program property is now set on the JDBC connection pool when I view it using the Glassfish Admin Console (When I start up the glassfish server, go to the admin page and browse to Resources->JDBC->Connection Pools->MyConnectionPool->Additional Properties I can see an entry for V$SESSION.program set appropriately).
However, when I query the Oracle Database for the connections (SELECT * FROM V$SESSION), they have the same V$SESSION.program as before (which is "JDBC Thin Client"), rather than the one I set in the domain.xml and which I can see as a property of the JDBC Connection Pool on the Glassfish Admin Page.
The resources section of my domain.xml is below:
<resources>
<jdbc-connection-pool pool-resize-quantity="4" max-pool-size="16" datasource-classname="oracle.jdbc.pool.OracleDataSource" res-type="javax.sql.DataSource" steady-pool-size="4" name="mydatabasename">
<property name="datasourceName" value="OracleConnectionPoolDataSource" />
<property name="databaseName" value="mydatabasename" />
<property name="password" value="mypassword" />
<property name="portNumber" value="1521" />
<property name="serverName" value="myservername" />
<property name="url" value="jdbc:oracle:thin:#myservername:1521:mydatabasename" />
<property name="user" value="myuser" />
<property name="v$session.program" value="MyGlassfishApp" />
</jdbc-connection-pool>
<jdbc-resource pool-name="mydatabasename" jndi-name="jdbc/mydatabasename" />
</resources>
And my Persistence.xml is as below (I've deleted all the <class>...</class> lines):
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="Persistence-ejb" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/mydatabasename</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.query.timeout" value="60"/>
<property name="javax.persistence.lock.timeout" value="60"/>
<property name="javax.persistence.target-server" value="SunAS9"/>
<!-- Disable caching so we always use the DB directly -->
<property name="eclipselink.cache.shared.default" value="false"/>
<property name="eclipselink.query-results-cache" value="false"/>
</properties>
</persistence-unit>
</persistence>
EDIT:
I have tried v$session.program, V$SESSION.PROGRAM and V$SESSION.program - none have worked though... I have also tried setting the V$SESSION.program property on the EntityManager, but that didn't work (I didn't really expect it to since from what I understand the EntityManager properties are only to do with the JPA layer, not the underlying connection to the Database - but I'm trying stuff out of desperation...)
I also tried using a SessionCustomizer as suggested here. The SessionCustomizer code I used is below:
public class ProgramSessionCustomizer implements SessionCustomizer {
private static Logger logger = Logger.getLogger(ProgramSessionCustomizer.class);
#Override
public void customize(Session s) throws Exception {
logger.error("ProgramSessionCustomizer setting v$session.program");
s.getDatasourceLogin().setProperty("v$session.program", "MYprogramTEST");
logger.error("ProgramSessionCustomizer has set v$session.program");
}
}
I then set the SessionCustomizer in the persistence.xml by adding the property:
<property name="eclipselink.session.customizer" value="persistence.config.ProgramSessionCustomizer"/>
I can see the log lines, so the Customizer is definitely being called. However, I don't see the program set in the database, and I don't even see it set when I browse to the JDBC connection pool properties on the Glassfish Admin Console (which, as I said above, I do see when I set the property using the glassfish domain.xml)
Again, any more suggestions would be very welcome as I'm at a loss!
I finally found out how to set this connection property in WebSphere 8 too for a XA datasource. It can be set in the WebSphere admin console:
Resources > JDBC providers > [Oracle JDBC Driver (XA)] > Data Sources > [data source name] > Custom properties
Just add there a property with a key: connectionProperties and its value: v$session.program:PUT_YOUR_NAME_HERE
This works for me using Spring. It should works for yours Java EE app as well. The idea is to set the v$session param indirectly via properties passed to connectionProperties property
<bean class="oracle.jdbc.pool.OracleDataSource" destroy-method="close">
<property name="URL" value="${configDb.url}"/>
<property name="user" value="${configDb.user}"/>
<property name="password" value ="${configDb.password}"/>
<property name="connectionCachingEnabled" value="true"/>
<property name="connectionProperties">
<value>v$session.program:PUT_YOUR_NAME_HERE</value>
</property>
</bean>

how to make connection pool in spring application using BasicDataSource

I have created the application in which I need to configure the connection pool.In which I am configuring the connection pooling in the spring_Config file. using the Basicdatasource.
but there is some problem to create the connection pool. Please tell me how to create the connection pooling in spring application using BasicDatasource.
I tried this one code in spring config ;-
bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource">
com.mysql.jdbc.Driver
jdbc:mysql:/revup?noAccessToProcedureBodies=true
jdbc:mysql://localhost:3306/revup?noAccessToProcedureBodies=true</value>-->
</value>-->
</value>-->
<property name="poolPreparedStatements">
<value>true</value>
</property>
<property name="initialSize">
<value>2</value>
</property>
<property name="maxActive">
<value>15</value>
</property>
Is there any modification of code please tell me. thanks in advance.
Here's a working example:
<bean id="dataSourceApache" class="org.apache.commons.dbcp.BasicDataSource">
<property name="url" value="jdbc:mysql://localhost:3306/coffee_shop" />
<property name="username" value="john" />
<property name="password" value="secret" />
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
</bean>
If you're using Eclipse, you should also download support for XML configuration syntax. It really helps you alot.
SpringSource Tool Suite has all the SpringSource support bundled ready for use.
Else, you can see all the fields that's possible to set in the Java documentation.

Resources