/*
 * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     James Sutherland - initial API and implementation
package org.eclipse.persistence.testing.tests.ucp;

import java.sql.SQLException;

import oracle.ucp.jdbc.PoolDataSource;
import oracle.ucp.jdbc.PoolDataSourceFactory;

import org.eclipse.persistence.sessions.JNDIConnector;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.server.Server;
import org.eclipse.persistence.testing.framework.TestErrorException;
import org.eclipse.persistence.testing.tests.unitofwork.UnitOfWorkClientSessionTestModel;


/**
 * This model is used to test Oracle UCP.
 * To test a RAC, URL should be a composite like:
 * "@(DESCRIPTION=(LOAD_BALANCE=on) (ADDRESS=(PROTOCOL=TCP)(HOST=host1) (PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=host2) (PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=service)))"
 *
 */
public class UCPUnitOfWorkTests extends UnitOfWorkClientSessionTestModel {

    @Override
    public Server buildServerSession() {
        try {
            PoolDataSourceFactory factory = new oracle.ucp.jdbc.PoolDataSourceFactory();
            PoolDataSource dataSource = factory.getPoolDataSource();
            //dataSource.setONSConfiguration("nodes=adcdbc01-r.us.oracle.com:6200");
            dataSource.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
            dataSource.setURL(getSession().getLogin().getConnectionString());
            dataSource.setUser(getSession().getLogin().getUserName());
            dataSource.setPassword(getSession().getLogin().getPassword());
            dataSource.setInitialPoolSize(1);
            dataSource.setMinPoolSize(1);
            dataSource.setMaxPoolSize(10);
            dataSource.setFastConnectionFailoverEnabled(true);
            Project project = getSession().getProject().clone();
            project.setLogin(project.getLogin().clone());
            project.getLogin().setConnector(new JNDIConnector(dataSource));
            project.getLogin().setUsesExternalConnectionPooling(true);
            Server server = project.createServerSession();
            server.setSessionLog(getSession().getSessionLog());
            server.login();
            return server;
        } catch (SQLException error) {
            throw new TestErrorException("UCP failed to initialize.", error);
        }
    }
}
