Cas 5 : How to configure Jpa Ticket Registry with jndi datasource ?

857 views
Skip to first unread message

Gokhan Mansuroglu

unread,
Dec 26, 2016, 7:38:25 AM12/26/16
to CAS Community
Hello,

I am trying to configure jpa ticket registry. Firstly I added the following dependency :

        <dependency>
           
<groupId>org.apereo.cas</groupId>
           
<artifactId>cas-server-support-jpa-ticket-registry</artifactId>
           
<version>${cas.version}</version>
       
</dependency>



Then I checked the documentation at https://apereo.github.io/cas/5.0.x/installation/JPA-Ticket-Registry.html. Since I don't want to use the pooled connection and prefer a predefined jndi datasource, the configuration parameters seem to be useless. I need to define the datasource. First I tried to declare an alias in deployerConfigContext.xml :

<alias name="myDS" alias="dataSourceTicket" />

But I get the following error at startup :
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ticketEntityManagerFactory' defined in class path resource [org/apereo/cas/config/JpaTicketRegistryConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'ticketEntityManagerFactory' threw exception; nested exception is java.lang.ClassCastException: org.springframework.jndi.JndiObjectFactoryBean$$EnhancerBySpringCGLIB$$ceb3620f cannot be cast to javax.sql.DataSource




Then tried another solution :

<bean id="dataSourceTicket" class="com.zaxxer.hikari.HikariDataSource" p:dataSource-ref="myDS"/>

and get the following error :

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method init xxx.myDao required a single bean, but 2 were found:
   
- dataSourceTicket: defined in class path resource [deployerConfigContext.xml]
   
- myDS: defined in class path resource [myApplicationContext.xml]


Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed


What do you suggest me, how I can solve this issue ?

Thanks.

Adrian Chong

unread,
Dec 29, 2016, 3:40:55 AM12/29/16
to CAS Community
Your data source bean loading is not really a JNDI lookup. The JNDI look up should be like this (Here i assume you have done the JNDI DS setup in app server):

<jee:jndi-lookup id="dataSource"
    jndi-name="jdbc/casDs"
    cache="true"
    resource-ref="true"
    lookup-on-startup="false"
    proxy-interface="javax.sql.DataSource"/>

So we have defined a data source with name "dataSource". But, the jpa ticket registry and service registry needs DS with names dataSourceTicket and dataSourceService. So we define alias like this:

<alias name="dataSource" alias="dataSourceTicket"/>
<alias name="dataSource" alias="dataSourceService"/>

So the default data source names of them can be overriden.

Jose Antonio Sánchez Pujante

unread,
Mar 15, 2017, 9:39:14 AM3/15/17
to CAS Community
Hola,
la solución anterior no me ha funcionado por la configuración de mi CAS 5, por lo tanto he implementado unos cambios que funcionan que paso a detallar:

** etc/cas/localconfig.properties

#Para autenticar el usuario:
cas.authn.jdbc.query[0].jndiName=jdbc/misusuarios
#cas.authn.jdbc.query[0].user=ANULADO
#cas.authn.jdbc.query[0].password=ANULADO

#Para los tickets:
cas.ticket.registry.jpa.jndiName=jdbc/mistickets
#cas.ticket.registry.jpa.user=ANULADO
#cas.ticket.registry.jpa.password=ANULADO

** src\main\java\es\pruebas\util\JNDIConnectionManager.java  (Crear nueva clase)

package es.xxxx.xxx;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Clase para gestionar para permitir la conexión con JNDI, de forma que indicando
 * la conexión en el server.xml del TOMCAT puedan ser usadas por la aplicación de CAS.
 */
public class JNDIConnectionManager {
private static final Logger LOGGER = LoggerFactory.getLogger(JNDIConnectionManager.class);

public static DataSource getDatasource(String jndiName){
    DataSource dataSource = null;
        Context initContext;
try {
initContext = new InitialContext();
       Context envContext  = (Context)initContext.lookup("java:/comp/env");
       dataSource = (DataSource)envContext.lookup(jndiName);
       LOGGER.info("Obtenida conexión JNDI " + jndiName);
} catch (Exception ex) {
LOGGER.error("No se pudo obtener conexión JNDI " + jndiName, ex);
}
return dataSource;
}
}

** src\main\java\org\apereo\cas\configuration\model\support\jpa\AbstractJpaProperties.java   (Traerse el código fuente de CAS 5)
Modificar clase para incluir la propiedad jndiName:

public abstract class AbstractJpaProperties {
   ....
   private String jndiName = null;
   ..
/**
* @return the jndiName
*/
public String getJndiName() {
return jndiName;
}

/**
* @param jndiName the jndiName to set
*/
public void setJndiName(String jndiName) {
this.jndiName = jndiName;
}
    
}

** src\main\java\org\apereo\cas\configuration\support\Beans.java   (Traerse el código fuente de CAS 5)
Volver a implementar el método newHickariDataSource:

    public static HikariDataSource newHickariDataSource(final AbstractJpaProperties jpaProperties) {
        try {
        final HikariDataSource bean = new HikariDataSource();
       
        // Si se ha definido en el fichero de propiedades una conexión JNDI se usará ésta, 
        // de lo contrario, se realizará el sistema antiguo de conexión.
        String jndiName = jpaProperties.getJndiName();
       
        if (jndiName != null){
        //NUEVO SISTEMA CON JNDI
        LOGGER.info("newHickariDataSource para recurso JNDI " + jndiName);        
        DataSource dataSource = JNDIConnectionManager.getDatasource(jndiName);
           bean.setDataSource(dataSource);
        }else{
        //ANTIGUO SISTEMA CON USUARIO/CLAVE DESDE FICHERO DE PROPIEDADES:
        LOGGER.info("newHickariDataSource para usuario " + jpaProperties.getUser());
           bean.setDriverClassName(jpaProperties.getDriverClass());
           bean.setJdbcUrl(jpaProperties.getUrl());
           bean.setUsername(jpaProperties.getUser());
           bean.setPassword(jpaProperties.getPassword());
           bean.setMaximumPoolSize(jpaProperties.getPool().getMaxSize());
           bean.setMinimumIdle(jpaProperties.getPool().getMaxIdleTime());
           bean.setIdleTimeout(jpaProperties.getIdleTimeout());
           bean.setLeakDetectionThreshold(jpaProperties.getLeakThreshold());
           bean.setInitializationFailFast(jpaProperties.isFailFast());
           bean.setIsolateInternalQueries(jpaProperties.isIsolateInternalQueries());
           bean.setConnectionTestQuery(jpaProperties.getHealthQuery());
           bean.setAllowPoolSuspension(jpaProperties.getPool().isSuspension());
           bean.setAutoCommit(jpaProperties.isAutocommit());
           bean.setLoginTimeout(jpaProperties.getPool().getMaxWait());
           bean.setValidationTimeout(jpaProperties.getPool().getMaxWait());
            }
            return bean;
        } catch (final Exception e) {
            throw new IllegalArgumentException(e);
        }
    }


** src\main\webapp\META-INF\context.xml  

<?xml version='1.0' encoding='utf-8'?>
<Context reloadable="true">

<ResourceLink name="jdbc/misusuarios" global="jdbc/misusuarios"
type="javax.sql.DataSource" />
<ResourceLink name="jdbc/mistickets" global="jdbc/mistickets"
type="javax.sql.DataSource" />

</Context>

** [TOMCAT] server.xml  

...
 <GlobalNamingResources>
...
<Resource auth="Container" driverClassName="oracle.jdbc.OracleDriver" maxTotal="20" maxIdle="1" maxWaitMillis="-1" 
removeAbandonedOnBorrow="true" removeAbandonedOnMaintenance="true" removeAbandonedTimeout="60" type="javax.sql.DataSource" 
name="jdbc/mistickets" username="tickets" password="bbb"
url="jdbc:oracle:thin:@bddevapli.carm.es:1521:devapli"  />

<Resource auth="Container" driverClassName="oracle.jdbc.OracleDriver" maxTotal="20" maxIdle="1" maxWaitMillis="-1" 
removeAbandonedOnBorrow="true" removeAbandonedOnMaintenance="true" removeAbandonedTimeout="60" type="javax.sql.DataSource" 
name="jdbc/misusuarios" username="usuarios" password="ddd"
url="jdbc:oracle:thin:@bddevapli.carm.es:1521:devapli"  />
...
 </GlobalNamingResources>
...


Paz y bien.
Reply all
Reply to author
Forward
0 new messages