http://git-wip-us.apache.org/repos/asf/cxf/blob/88cde365/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProvider.java index bdce24b..209088c 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProvider.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProvider.java @@ -18,13 +18,17 @@ */ package org.apache.cxf.rs.security.oauth2.provider; +import java.util.ArrayList; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; - import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityTransaction; import javax.persistence.TypedQuery; import org.apache.cxf.helpers.CastUtils; +import org.apache.cxf.rs.security.oauth2.common.AccessTokenRegistration; import org.apache.cxf.rs.security.oauth2.common.Client; import org.apache.cxf.rs.security.oauth2.common.OAuthPermission; import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken; @@ -32,165 +36,385 @@ import org.apache.cxf.rs.security.oauth2.common.UserSubject; import org.apache.cxf.rs.security.oauth2.tokens.bearer.BearerAccessToken; import org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken; +/** + * Provides a Jpa BMT implementation for OAuthDataProvider. + * + * If your application runs in a container and if you want to use + * container managed persistence, you'll have to override + * the following methods : + * <ul> + * <li> {@link #getEntityManager()}</li> + * <li> {@link #commitIfNeeded(EntityManager)}</li> + * <li> {@link #closeIfNeeded(EntityManager)}</li> + * </ul> + */ public class JPAOAuthDataProvider extends AbstractOAuthDataProvider { - private static final String CLIENT_TABLE_NAME = Client.class.getSimpleName(); - private static final String BEARER_TOKEN_TABLE_NAME = BearerAccessToken.class.getSimpleName(); - private static final String REFRESH_TOKEN_TABLE_NAME = RefreshToken.class.getSimpleName(); - private EntityManager entityManager; - - public JPAOAuthDataProvider() { - } - + private static final String CLIENT_QUERY = "SELECT client FROM Client client" + + " INNER JOIN client.resourceOwnerSubject ros"; + + private EntityManagerFactory entityManagerFactory; + + public void setEntityManagerFactory(EntityManagerFactory emf) { + this.entityManagerFactory = emf; + } + @Override - public Client getClient(String clientId) throws OAuthServiceException { - return getEntityManager().find(Client.class, clientId); - } - - public void setClient(Client client) { - getEntityManager().getTransaction().begin(); - if (client.getResourceOwnerSubject() != null) { - UserSubject sub = getEntityManager().find(UserSubject.class, client.getResourceOwnerSubject().getLogin()); - if (sub == null) { - getEntityManager().persist(client.getResourceOwnerSubject()); - } else { - client.setResourceOwnerSubject(sub); + public Client getClient(final String clientId) throws OAuthServiceException { + return execute(new EntityManagerOperation<Client>() { + @Override + public Client execute(EntityManager em) { + return em.find(Client.class, clientId); } + }); + } + + protected <T> T execute(EntityManagerOperation<T> operation) { + EntityManager em = getEntityManager(); + T value; + try { + value = operation.execute(em); + } finally { + closeIfNeeded(em); + } + return value; + } + + protected <T> T executeInTransaction(EntityManagerOperation<T> operation) { + EntityManager em = getEntityManager(); + EntityTransaction transaction = null; + T value; + try { + transaction = beginIfNeeded(em); + value = operation.execute(em); + flushIfNeeded(em); + commitIfNeeded(em); + } catch (RuntimeException e) { + if (transaction != null) { + transaction.rollback(); + } + throw e; + } finally { + closeIfNeeded(em); } - getEntityManager().persist(client); - getEntityManager().getTransaction().commit(); + return value; + } + + public void setClient(final Client client) { + executeInTransaction(new EntityManagerOperation<Void>() { + @Override + public Void execute(EntityManager em) { + if (client.getResourceOwnerSubject() != null) { + UserSubject sub = + em.find(UserSubject.class, client.getResourceOwnerSubject().getLogin()); + if (sub == null) { + em.persist(client.getResourceOwnerSubject()); + } else { + client.setResourceOwnerSubject(sub); + } + } + boolean clientExists = em.createQuery("SELECT count(client) from Client client " + + "where client.clientId = :id", + Long.class) + .setParameter("id", client.getClientId()) + .getSingleResult() > 0 ? true : false; + if (clientExists) { + em.merge(client); + } else { + em.persist(client); + } + return null; + } + }); } - + @Override - protected void doRemoveClient(Client c) { - removeEntity(c); + protected void doRemoveClient(final Client c) { + executeInTransaction(new EntityManagerOperation<Void>() { + @Override + public Void execute(EntityManager em) { + Client clientToRemove = em.getReference(Client.class, c.getClientId()); + em.remove(clientToRemove); + return null; + } + }); } @Override - public List<Client> getClients(UserSubject resourceOwner) { - return getClientsQuery(resourceOwner).getResultList(); + public List<Client> getClients(final UserSubject resourceOwner) { + return execute(new EntityManagerOperation<List<Client>>() { + @Override + public List<Client> execute(EntityManager em) { + return getClientsQuery(resourceOwner, em).getResultList(); + } + }); } @Override - public List<ServerAccessToken> getAccessTokens(Client c, UserSubject sub) { - return CastUtils.cast(getTokensQuery(c, sub).getResultList()); + public List<ServerAccessToken> getAccessTokens(final Client c, final UserSubject sub) { + return execute(new EntityManagerOperation<List<ServerAccessToken>>() { + @Override + public List<ServerAccessToken> execute(EntityManager em) { + return CastUtils.cast(getTokensQuery(c, sub, em).getResultList()); + } + }); } @Override - public List<RefreshToken> getRefreshTokens(Client c, UserSubject sub) { - return getRefreshTokensQuery(c, sub).getResultList(); + public List<RefreshToken> getRefreshTokens(final Client c, final UserSubject sub) { + return execute(new EntityManagerOperation<List<RefreshToken>>() { + @Override + public List<RefreshToken> execute(EntityManager em) { + return getRefreshTokensQuery(c, sub, em).getResultList(); + } + }); } - + @Override - public ServerAccessToken getAccessToken(String accessToken) throws OAuthServiceException { - return getEntityManager().find(BearerAccessToken.class, accessToken); + public ServerAccessToken getAccessToken(final String accessToken) throws OAuthServiceException { + return execute(new EntityManagerOperation<ServerAccessToken>() { + @Override + public ServerAccessToken execute(EntityManager em) { + return em.find(BearerAccessToken.class, accessToken); + } + }); } + @Override - protected void doRevokeAccessToken(ServerAccessToken at) { - removeEntity(at); + protected void doRevokeAccessToken(final ServerAccessToken at) { + executeInTransaction(new EntityManagerOperation<Void>() { + @Override + public Void execute(EntityManager em) { + ServerAccessToken tokenToRemove = em.getReference(at.getClass(), at.getTokenKey()); + em.remove(tokenToRemove); + return null; + } + }); } + @Override - protected RefreshToken getRefreshToken(String refreshTokenKey) { - return getEntityManager().find(RefreshToken.class, refreshTokenKey); + protected void linkRefreshTokenToAccessToken(final RefreshToken rt, final ServerAccessToken at) { + super.linkRefreshTokenToAccessToken(rt, at); + executeInTransaction(new EntityManagerOperation<Void>() { + @Override + public Void execute(EntityManager em) { + em.merge(at); + return null; + } + }); } + @Override - protected void doRevokeRefreshToken(RefreshToken rt) { - removeEntity(rt); - } - - protected void saveAccessToken(ServerAccessToken serverToken) { - getEntityManager().getTransaction().begin(); - List<OAuthPermission> perms = new LinkedList<OAuthPermission>(); - for (OAuthPermission perm : serverToken.getScopes()) { - OAuthPermission permSaved = getEntityManager().find(OAuthPermission.class, perm.getPermission()); - if (permSaved != null) { - perms.add(permSaved); - } else { - getEntityManager().persist(perm); - perms.add(perm); + protected RefreshToken getRefreshToken(final String refreshTokenKey) { + return execute(new EntityManagerOperation<RefreshToken>() { + @Override + public RefreshToken execute(EntityManager em) { + return em.find(RefreshToken.class, refreshTokenKey); } + }); + } + + @Override + protected void doRevokeRefreshToken(final RefreshToken rt) { + executeInTransaction(new EntityManagerOperation<Void>() { + @Override + public Void execute(EntityManager em) { + RefreshToken tokentoRemove = em.getReference(RefreshToken.class, rt.getTokenKey()); + em.remove(tokentoRemove); + return null; + } + }); + } + + @Override + protected ServerAccessToken doCreateAccessToken(AccessTokenRegistration atReg) { + ServerAccessToken at = super.doCreateAccessToken(atReg); + // we override this in order to get rid of elementCollections directly injected + // from another entity + // this can be the case when using multiple cmt dataProvider operation in a single entityManager + // lifespan + if (at.getAudiences() != null) { + at.setAudiences(new ArrayList<String>(at.getAudiences())); } - serverToken.setScopes(perms); - - UserSubject sub = getEntityManager().find(UserSubject.class, serverToken.getSubject().getLogin()); - if (sub == null) { - getEntityManager().persist(serverToken.getSubject()); - } else { - sub = getEntityManager().merge(serverToken.getSubject()); - serverToken.setSubject(sub); + if (at.getExtraProperties() != null) { + at.setExtraProperties(new HashMap<String, String>(at.getExtraProperties())); + } + if (at.getScopes() != null) { + at.setScopes(new ArrayList<OAuthPermission>(at.getScopes())); } - - getEntityManager().persist(serverToken); - getEntityManager().getTransaction().commit(); + if (at.getParameters() != null) { + at.setParameters(new HashMap<String, String>(at.getParameters())); + } + return at; + } + + protected void saveAccessToken(final ServerAccessToken serverToken) { + executeInTransaction(new EntityManagerOperation<Void>() { + @Override + public Void execute(EntityManager em) { + List<OAuthPermission> perms = new LinkedList<OAuthPermission>(); + for (OAuthPermission perm : serverToken.getScopes()) { + OAuthPermission permSaved = em.find(OAuthPermission.class, perm.getPermission()); + if (permSaved != null) { + perms.add(permSaved); + } else { + em.persist(perm); + perms.add(perm); + } + } + serverToken.setScopes(perms); + + UserSubject sub = em.find(UserSubject.class, serverToken.getSubject().getLogin()); + if (sub == null) { + em.persist(serverToken.getSubject()); + } else { + sub = em.merge(serverToken.getSubject()); + serverToken.setSubject(sub); + } + // ensure we have a managed association + // (needed for OpenJPA : InvalidStateException: Encountered unmanaged object) + if (serverToken.getClient() != null) { + serverToken.setClient(em.find(Client.class, serverToken.getClient().getClientId())); + } + + em.persist(serverToken); + return null; + } + }); } - + protected void saveRefreshToken(RefreshToken refreshToken) { persistEntity(refreshToken); } - protected void persistEntity(Object entity) { - entityManager.getTransaction().begin(); - entityManager.persist(entity); - entityManager.getTransaction().commit(); + + protected void persistEntity(final Object entity) { + executeInTransaction(new EntityManagerOperation<Void>() { + @Override + public Void execute(EntityManager em) { + em.persist(entity); + return null; + } + }); } - protected void removeEntity(Object entity) { - entityManager.getTransaction().begin(); - entityManager.remove(entity); - entityManager.getTransaction().commit(); + + protected void removeEntity(final Object entity) { + executeInTransaction(new EntityManagerOperation<Void>() { + @Override + public Void execute(EntityManager em) { + em.remove(entity); + return null; + } + }); } - protected TypedQuery<Client> getClientsQuery(UserSubject resourceOwnerSubject) { + + protected TypedQuery<Client> getClientsQuery(UserSubject resourceOwnerSubject, EntityManager entityManager) { if (resourceOwnerSubject == null) { - return entityManager.createQuery("SELECT c FROM " + CLIENT_TABLE_NAME + " c", Client.class); + return entityManager.createQuery(CLIENT_QUERY, Client.class); } else { - return entityManager.createQuery( - "SELECT c FROM " + CLIENT_TABLE_NAME + " c JOIN c.resourceOwnerSubject r WHERE r.login = '" - + resourceOwnerSubject.getLogin() + "'", Client.class); + return entityManager.createQuery(CLIENT_QUERY + " WHERE ros.login = :login", Client.class). + setParameter("login", resourceOwnerSubject.getLogin()); } } - protected TypedQuery<BearerAccessToken> getTokensQuery(Client c, UserSubject resourceOwnerSubject) { + + protected TypedQuery<BearerAccessToken> getTokensQuery(Client c, UserSubject resourceOwnerSubject, + EntityManager entityManager) { if (c == null && resourceOwnerSubject == null) { - return entityManager.createQuery("SELECT t FROM " + BEARER_TOKEN_TABLE_NAME + " t", - BearerAccessToken.class); + return entityManager.createQuery("SELECT t FROM BearerAccessToken t", + BearerAccessToken.class); } else if (c == null) { return entityManager.createQuery( - "SELECT t FROM " + BEARER_TOKEN_TABLE_NAME + " t JOIN t.subject s WHERE s.login = '" - + resourceOwnerSubject.getLogin() + "'", BearerAccessToken.class); + "SELECT t FROM BearerAccessToken t" + + " JOIN t.subject s" + + " WHERE s.login = :login", BearerAccessToken.class) + .setParameter("login", resourceOwnerSubject.getLogin()); } else if (resourceOwnerSubject == null) { return entityManager.createQuery( - "SELECT t FROM " + BEARER_TOKEN_TABLE_NAME + " t JOIN t.client c WHERE c.clientId = '" - + c.getClientId() + "'", BearerAccessToken.class); + "SELECT t FROM BearerAccessToken t" + + " JOIN t.client c" + + " WHERE c.clientId = :clientId", BearerAccessToken.class) + .setParameter("clientId", c.getClientId()); } else { return entityManager.createQuery( - "SELECT t FROM " + BEARER_TOKEN_TABLE_NAME + " t JOIN t.subject s JOIN t.client c WHERE s.login = '" - + resourceOwnerSubject.getLogin() + "' AND c.clientId = '" + c.getClientId() + "'", - BearerAccessToken.class); + "SELECT t FROM BearerAccessToken t" + + " JOIN t.subject s" + + " JOIN t.client c" + + " WHERE s.login = :login AND c.clientId = :clientId", BearerAccessToken.class) + .setParameter("login", resourceOwnerSubject.getLogin()) + .setParameter("clientId", c.getClientId()); } } - protected TypedQuery<RefreshToken> getRefreshTokensQuery(Client c, UserSubject resourceOwnerSubject) { + + protected TypedQuery<RefreshToken> getRefreshTokensQuery(Client c, UserSubject resourceOwnerSubject, + EntityManager entityManager) { if (c == null && resourceOwnerSubject == null) { - return entityManager.createQuery("SELECT t FROM " + REFRESH_TOKEN_TABLE_NAME + " t", - RefreshToken.class); + return entityManager.createQuery("SELECT t FROM RefreshToken t", + RefreshToken.class); } else if (c == null) { return entityManager.createQuery( - "SELECT t FROM " + REFRESH_TOKEN_TABLE_NAME + " t JOIN t.subject s WHERE s.login = '" - + resourceOwnerSubject.getLogin() + "'", RefreshToken.class); + "SELECT t FROM RefreshToken t" + + " JOIN t.subject s" + + " WHERE s.login = :login", RefreshToken.class) + .setParameter("login", resourceOwnerSubject.getLogin()); } else if (resourceOwnerSubject == null) { return entityManager.createQuery( - "SELECT t FROM " + REFRESH_TOKEN_TABLE_NAME + " t JOIN t.client c WHERE c.clientId = '" - + c.getClientId() + "'", RefreshToken.class); + "SELECT t FROM RefreshToken t" + + " JOIN t.client c" + + " WHERE c.clientId = :clientId", RefreshToken.class) + .setParameter("clientId", c.getClientId()); } else { return entityManager.createQuery( - "SELECT t FROM " + REFRESH_TOKEN_TABLE_NAME + " t JOIN t.subject s JOIN t.client c WHERE s.login = '" - + resourceOwnerSubject.getLogin() + "' AND c.clientId = '" + c.getClientId() + "'", - RefreshToken.class); + "SELECT t FROM RefreshToken t" + + " JOIN t.subject s" + + " JOIN t.client c" + + " WHERE s.login = :login AND c.clientId = :clientId", RefreshToken.class) + .setParameter("login", resourceOwnerSubject.getLogin()) + .setParameter("clientId", c.getClientId()); } } - public void setEntityManager(EntityManager entityManager) { - this.entityManager = entityManager; + + /** + * Returns the entityManaged used for the current operation. + */ + protected EntityManager getEntityManager() { + return entityManagerFactory.createEntityManager(); } - public EntityManager getEntityManager() { - return entityManager; + + /** + * Begins the current transaction. + * + * This method needs to be overridden in a CMT environment. + */ + protected EntityTransaction beginIfNeeded(EntityManager em) { + EntityTransaction tx = em.getTransaction(); + tx.begin(); + return tx; } - @Override - public void close() { - entityManager.close(); + + /** + * Flush the current transaction. + */ + protected void flushIfNeeded(EntityManager em) { + em.flush(); + } + + /** + * Commits the current transaction. + * + * This method needs to be overridden in a CMT environment. + */ + protected void commitIfNeeded(EntityManager em) { + em.getTransaction().commit(); + } + + /** + * Closes the current em. + * + * This method needs to be overriden in a CMT environment. + */ + protected void closeIfNeeded(EntityManager em) { + em.close(); + } + + public interface EntityManagerOperation<T> { + T execute(EntityManager em); } }
http://git-wip-us.apache.org/repos/asf/cxf/blob/88cde365/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/refresh/RefreshToken.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/refresh/RefreshToken.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/refresh/RefreshToken.java index da937b8..4eedea2 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/refresh/RefreshToken.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/refresh/RefreshToken.java @@ -23,6 +23,8 @@ import java.util.List; import javax.persistence.ElementCollection; import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.OrderColumn; import org.apache.cxf.rs.security.oauth2.common.Client; import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken; @@ -34,28 +36,28 @@ import org.apache.cxf.rs.security.oauth2.utils.OAuthUtils; */ @Entity public class RefreshToken extends ServerAccessToken { - + private static final long serialVersionUID = 2837120382251693874L; private List<String> accessTokens = new LinkedList<String>(); - - public RefreshToken(Client client, + + public RefreshToken(Client client, long lifetime) { - super(client, - OAuthConstants.REFRESH_TOKEN_TYPE, - OAuthUtils.generateRandomTokenKey(), - lifetime, - OAuthUtils.getIssuedAt()); + super(client, + OAuthConstants.REFRESH_TOKEN_TYPE, + OAuthUtils.generateRandomTokenKey(), + lifetime, + OAuthUtils.getIssuedAt()); } - - public RefreshToken(Client client, - String tokenKey, - long lifetime, - long issuedAt) { - super(client, - OAuthConstants.REFRESH_TOKEN_TYPE, - tokenKey, - lifetime, - issuedAt); + + public RefreshToken(Client client, + String tokenKey, + long lifetime, + long issuedAt) { + super(client, + OAuthConstants.REFRESH_TOKEN_TYPE, + tokenKey, + lifetime, + issuedAt); } public RefreshToken(ServerAccessToken token, @@ -64,10 +66,13 @@ public class RefreshToken extends ServerAccessToken { super(validateTokenType(token, OAuthConstants.REFRESH_TOKEN_TYPE), key); this.accessTokens = accessTokens; } + public RefreshToken() { - + } - @ElementCollection + + @ElementCollection(fetch = FetchType.EAGER) + @OrderColumn public List<String> getAccessTokens() { return accessTokens; } @@ -75,11 +80,11 @@ public class RefreshToken extends ServerAccessToken { public void setAccessTokens(List<String> accessTokens) { this.accessTokens = accessTokens; } - + public void addAccessToken(String token) { getAccessTokens().add(token); } - + public boolean removeAccessToken(String token) { return getAccessTokens().remove(token); } http://git-wip-us.apache.org/repos/asf/cxf/blob/88cde365/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.java index c1a1474..d08969b 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.java @@ -21,6 +21,7 @@ package org.apache.cxf.rs.security.oauth2.utils; import java.security.Principal; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Properties; @@ -287,7 +288,7 @@ public final class OAuthUtils { if (!StringUtils.isEmpty(scopeString)) { clientToken.setApprovedScope(scopeString); } - clientToken.setParameters(serverToken.getParameters()); + clientToken.setParameters(new HashMap<String, String>(serverToken.getParameters())); } return clientToken; } http://git-wip-us.apache.org/repos/asf/cxf/blob/88cde365/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTCodeDataProviderOpenJPATest.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTCodeDataProviderOpenJPATest.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTCodeDataProviderOpenJPATest.java new file mode 100644 index 0000000..d9d3d9b --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTCodeDataProviderOpenJPATest.java @@ -0,0 +1,43 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.rs.security.oauth2.grants.code; + +import org.junit.runner.RunWith; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * Runs the same tests as JPACodeDataProviderTest but within a Spring Managed Transaction. + * + * Spring spawns a transaction before each call to <code><oauthProvider</code>. + * + * Note : this test needs <code>@DirtiesContext</code>, otherwise + * spring tests cache and reuse emf across test classes + * while non spring unit tests are closing emf (hence connection exception: closed). + * + * @author agonzalez + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("JPACMTCodeDataProvider.xml") +@DirtiesContext +@ActiveProfiles(value = "openJPA", inheritProfiles = false) +public class JPACMTCodeDataProviderOpenJPATest extends JPACMTCodeDataProviderTest { +} http://git-wip-us.apache.org/repos/asf/cxf/blob/88cde365/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTCodeDataProviderTest.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTCodeDataProviderTest.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTCodeDataProviderTest.java new file mode 100644 index 0000000..8894706 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTCodeDataProviderTest.java @@ -0,0 +1,65 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.rs.security.oauth2.grants.code; + +import org.junit.After; +import org.junit.Before; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * Runs the same tests as JPACodeDataProviderTest but within a Spring Managed Transaction. + * + * Spring spawns a transaction before each call to <code><oauthProvider</code>. + * + * Note : this test needs <code>@DirtiesContext</code>, otherwise + * spring tests cache and reuse emf across test classes + * while non spring unit tests are closing emf (hence connection exception: closed). + * + * @author agonzalez + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("JPACMTCodeDataProvider.xml") +@DirtiesContext +@ActiveProfiles("hibernate") +public class JPACMTCodeDataProviderTest extends JPACodeDataProviderTest { + + @Autowired + private JPACMTCodeDataProvider oauthProvider; + + @Override + protected JPACodeDataProvider getProvider() { + return this.oauthProvider; + } + + @Before + @Override + public void setUp() { + initializeProvider(oauthProvider); + } + + @After + @Override + public void tearDown() { + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/88cde365/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTOAuthDataProviderOpenJPATest.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTOAuthDataProviderOpenJPATest.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTOAuthDataProviderOpenJPATest.java new file mode 100644 index 0000000..4324ba3 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTOAuthDataProviderOpenJPATest.java @@ -0,0 +1,44 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.rs.security.oauth2.grants.code; + +import org.apache.cxf.rs.security.oauth2.provider.JPAOAuthDataProviderTest; +import org.junit.runner.RunWith; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * Runs the same tests as JPAOAuthDataProviderTest but within a Spring Managed Transaction. + * + * Spring spawns a transaction before each call to <code><oauthProvider</code>. + * + * Note : this test needs <code>@DirtiesContext</code>, otherwise + * spring tests cache and reuse emf across test classes + * while non spring unit tests are closing emf (hence connection exception: closed). + * + * @author agonzalez + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("JPACMTCodeDataProvider.xml") +@DirtiesContext +@ActiveProfiles(value = "openJPA", inheritProfiles = false) +public class JPACMTOAuthDataProviderOpenJPATest extends JPAOAuthDataProviderTest { +} http://git-wip-us.apache.org/repos/asf/cxf/blob/88cde365/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTOAuthDataProviderTest.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTOAuthDataProviderTest.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTOAuthDataProviderTest.java new file mode 100644 index 0000000..a7245e2 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTOAuthDataProviderTest.java @@ -0,0 +1,67 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.rs.security.oauth2.grants.code; + +import org.apache.cxf.rs.security.oauth2.provider.JPAOAuthDataProvider; +import org.apache.cxf.rs.security.oauth2.provider.JPAOAuthDataProviderTest; +import org.junit.After; +import org.junit.Before; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * Runs the same tests as JPAOAuthDataProviderTest but within a Spring Managed Transaction. + * + * Spring spawns a transaction before each call to <code><oauthProvider</code>. + * + * Note : this test needs <code>@DirtiesContext</code>, otherwise + * spring tests cache and reuse emf across test classes + * while non spring unit tests are closing emf (hence connection exception: closed). + * + * @author agonzalez + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("JPACMTCodeDataProvider.xml") +@DirtiesContext +@ActiveProfiles("hibernate") +public class JPACMTOAuthDataProviderTest extends JPAOAuthDataProviderTest { + + @Autowired + private JPACMTCodeDataProvider oauthProvider; + + @Override + protected JPAOAuthDataProvider getProvider() { + return this.oauthProvider; + } + + @Before + @Override + public void setUp() { + initializeProvider(oauthProvider); + } + + @After + @Override + public void tearDown() { + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/88cde365/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACodeDataProviderOpenJPATest.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACodeDataProviderOpenJPATest.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACodeDataProviderOpenJPATest.java new file mode 100644 index 0000000..d227ff8 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACodeDataProviderOpenJPATest.java @@ -0,0 +1,26 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.rs.security.oauth2.grants.code; + +public class JPACodeDataProviderOpenJPATest extends JPACodeDataProviderTest { + @Override + protected String getPersistenceUnitName() { + return "testUnitOpenJPA"; + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/88cde365/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACodeDataProviderTest.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACodeDataProviderTest.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACodeDataProviderTest.java index cbbea51..27ee049 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACodeDataProviderTest.java +++ b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACodeDataProviderTest.java @@ -22,14 +22,11 @@ import java.sql.Connection; import java.sql.DriverManager; import java.util.Collections; import java.util.List; - -import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import org.apache.cxf.rs.security.oauth2.common.Client; import org.apache.cxf.rs.security.oauth2.common.UserSubject; - import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -39,6 +36,7 @@ public class JPACodeDataProviderTest extends Assert { private EntityManagerFactory emFactory; private Connection connection; private JPACodeDataProvider provider; + @Before public void setUp() throws Exception { try { @@ -49,17 +47,28 @@ public class JPACodeDataProviderTest extends Assert { fail("Exception during HSQL database init."); } try { - emFactory = Persistence.createEntityManagerFactory("testUnitHibernate"); - EntityManager em = emFactory.createEntityManager(); + emFactory = Persistence.createEntityManagerFactory(getPersistenceUnitName()); provider = new JPACodeDataProvider(); - provider.setEntityManager(em); - provider.setSupportedScopes(Collections.singletonMap("a", "A Scope")); + getProvider().setEntityManagerFactory(emFactory); + initializeProvider(provider); } catch (Exception ex) { ex.printStackTrace(); fail("Exception during JPA EntityManager creation."); } } + protected String getPersistenceUnitName() { + return "testUnitHibernate"; + } + + protected void initializeProvider(JPACodeDataProvider dataProvider) { + dataProvider.setSupportedScopes(Collections.singletonMap("a", "A Scope")); + } + + protected JPACodeDataProvider getProvider() { + return provider; + } + @Test public void testAddGetDeleteCodeGrants() { Client c = addClient("111", "bob"); @@ -69,25 +78,34 @@ public class JPACodeDataProviderTest extends Assert { atr.setApprovedScope(Collections.singletonList("a")); atr.setSubject(c.getResourceOwnerSubject()); - ServerAuthorizationCodeGrant grant = provider.createCodeGrant(atr); + ServerAuthorizationCodeGrant grant = getProvider().createCodeGrant(atr); - List<ServerAuthorizationCodeGrant> grants = provider.getCodeGrants(c, c.getResourceOwnerSubject()); + List<ServerAuthorizationCodeGrant> grants = getProvider().getCodeGrants(c, c.getResourceOwnerSubject()); assertNotNull(grants); assertEquals(1, grants.size()); assertEquals(grant.getCode(), grants.get(0).getCode()); - grants = provider.getCodeGrants(c, null); + grants = getProvider().getCodeGrants(c, null); assertNotNull(grants); assertEquals(1, grants.size()); assertEquals(grant.getCode(), grants.get(0).getCode()); - ServerAuthorizationCodeGrant grant2 = provider.removeCodeGrant(grant.getCode()); + ServerAuthorizationCodeGrant grant2 = getProvider().removeCodeGrant(grant.getCode()); assertEquals(grant.getCode(), grant2.getCode()); - grants = provider.getCodeGrants(c, null); + grants = getProvider().getCodeGrants(c, null); assertNotNull(grants); assertEquals(0, grants.size()); } + + @Test + public void testResetClient() { + Client c = addClient("111", "bob"); + c.setClientSecret("newSecret"); + getProvider().setClient(c); + Client savedClient = getProvider().getClient(c.getClientId()); + assertEquals(c.getClientSecret(), savedClient.getClientSecret()); + } @Test public void testAddGetDeleteCodeGrants2() { @@ -98,13 +116,13 @@ public class JPACodeDataProviderTest extends Assert { atr.setApprovedScope(Collections.singletonList("a")); atr.setSubject(c.getResourceOwnerSubject()); - provider.createCodeGrant(atr); + getProvider().createCodeGrant(atr); - List<ServerAuthorizationCodeGrant> grants = provider.getCodeGrants(c, c.getResourceOwnerSubject()); + List<ServerAuthorizationCodeGrant> grants = getProvider().getCodeGrants(c, c.getResourceOwnerSubject()); assertNotNull(grants); assertEquals(1, grants.size()); - provider.removeClient(c.getClientId()); - grants = provider.getCodeGrants(c, c.getResourceOwnerSubject()); + getProvider().removeClient(c.getClientId()); + grants = getProvider().getCodeGrants(c, c.getResourceOwnerSubject()); assertNotNull(grants); assertEquals(0, grants.size()); } @@ -114,14 +132,15 @@ public class JPACodeDataProviderTest extends Assert { c.setRedirectUris(Collections.singletonList("http://client/redirect")); c.setClientId(clientId); c.setResourceOwnerSubject(new UserSubject(userLogin)); - provider.setClient(c); + getProvider().setClient(c); return c; } + @After public void tearDown() throws Exception { try { if (provider != null) { - provider.close(); + getProvider().close(); } if (emFactory != null) { emFactory.close(); http://git-wip-us.apache.org/repos/asf/cxf/blob/88cde365/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProviderOpenJPATest.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProviderOpenJPATest.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProviderOpenJPATest.java new file mode 100644 index 0000000..e6a2d25 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProviderOpenJPATest.java @@ -0,0 +1,26 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.rs.security.oauth2.provider; + +public class JPAOAuthDataProviderOpenJPATest extends JPAOAuthDataProviderTest { + @Override + protected String getPersistenceUnitName() { + return "testUnitOpenJPA"; + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/88cde365/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProviderTest.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProviderTest.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProviderTest.java index ed2e0a6..4eb8533 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProviderTest.java +++ b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProviderTest.java @@ -18,13 +18,9 @@ */ package org.apache.cxf.rs.security.oauth2.provider; -import java.sql.Connection; -import java.sql.DriverManager; import java.util.Arrays; import java.util.Collections; import java.util.List; - -import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; @@ -35,159 +31,162 @@ import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken; import org.apache.cxf.rs.security.oauth2.common.UserSubject; import org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken; import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants; - import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class JPAOAuthDataProviderTest extends Assert { - private EntityManagerFactory emFactory; - private Connection connection; + protected EntityManagerFactory emFactory; private JPAOAuthDataProvider provider; + @Before public void setUp() throws Exception { try { - Class.forName("org.hsqldb.jdbcDriver"); - connection = DriverManager.getConnection("jdbc:hsqldb:mem:oauth-jpa", "sa", ""); - } catch (Exception ex) { - ex.printStackTrace(); - fail("Exception during HSQL database init."); - } - try { - emFactory = Persistence.createEntityManagerFactory("testUnitHibernate"); - EntityManager em = emFactory.createEntityManager(); + emFactory = Persistence.createEntityManagerFactory(getPersistenceUnitName()); provider = new JPAOAuthDataProvider(); - provider.setEntityManager(em); - provider.setSupportedScopes(Collections.singletonMap("a", "A Scope")); - provider.setSupportedScopes(Collections.singletonMap("refreshToken", "RefreshToken")); + provider.setEntityManagerFactory(emFactory); + initializeProvider(provider); } catch (Exception ex) { ex.printStackTrace(); fail("Exception during JPA EntityManager creation."); } } + protected String getPersistenceUnitName() { + return "testUnitHibernate"; + } + + protected void initializeProvider(JPAOAuthDataProvider dataProvider) { + dataProvider.setSupportedScopes(Collections.singletonMap("a", "A Scope")); + dataProvider.setSupportedScopes(Collections.singletonMap("refreshToken", "RefreshToken")); + } + + protected JPAOAuthDataProvider getProvider() { + return provider; + } + @Test public void testAddGetDeleteClient() { Client c = addClient("12345", "alice"); - Client c2 = provider.getClient(c.getClientId()); + Client c2 = getProvider().getClient(c.getClientId()); compareClients(c, c2); - + c2.setClientSecret("567"); - provider.setClient(c2); - Client c22 = provider.getClient(c.getClientId()); + getProvider().setClient(c2); + Client c22 = getProvider().getClient(c.getClientId()); compareClients(c2, c22); - - provider.removeClient(c.getClientId()); - Client c3 = provider.getClient(c.getClientId()); + + getProvider().removeClient(c.getClientId()); + Client c3 = getProvider().getClient(c.getClientId()); assertNull(c3); } - + @Test public void testAddGetDeleteClients() { Client c = addClient("12345", "alice"); Client c2 = addClient("56789", "alice"); Client c3 = addClient("09876", "bob"); - - List<Client> aliceClients = provider.getClients(new UserSubject("alice")); + + List<Client> aliceClients = getProvider().getClients(new UserSubject("alice")); assertNotNull(aliceClients); assertEquals(2, aliceClients.size()); - compareClients(c, aliceClients.get(0).getClientId().equals("12345") + compareClients(c, aliceClients.get(0).getClientId().equals("12345") ? aliceClients.get(0) : aliceClients.get(1)); - compareClients(c2, aliceClients.get(0).getClientId().equals("56789") + compareClients(c2, aliceClients.get(0).getClientId().equals("56789") ? aliceClients.get(0) : aliceClients.get(1)); - - List<Client> bobClients = provider.getClients(new UserSubject("bob")); + + List<Client> bobClients = getProvider().getClients(new UserSubject("bob")); assertNotNull(bobClients); assertEquals(1, bobClients.size()); Client bobClient = bobClients.get(0); compareClients(c3, bobClient); - - List<Client> allClients = provider.getClients(null); + + List<Client> allClients = getProvider().getClients(null); assertNotNull(allClients); assertEquals(3, allClients.size()); - provider.removeClient(c.getClientId()); - provider.removeClient(c2.getClientId()); - provider.removeClient(c3.getClientId()); - allClients = provider.getClients(null); + getProvider().removeClient(c.getClientId()); + getProvider().removeClient(c2.getClientId()); + getProvider().removeClient(c3.getClientId()); + allClients = getProvider().getClients(null); assertNotNull(allClients); assertEquals(0, allClients.size()); } - + @Test public void testAddGetDeleteAccessToken() { Client c = addClient("101", "bob"); - + AccessTokenRegistration atr = new AccessTokenRegistration(); atr.setClient(c); atr.setApprovedScope(Collections.singletonList("a")); atr.setSubject(c.getResourceOwnerSubject()); - - ServerAccessToken at = provider.createAccessToken(atr); - ServerAccessToken at2 = provider.getAccessToken(at.getTokenKey()); + + ServerAccessToken at = getProvider().createAccessToken(atr); + ServerAccessToken at2 = getProvider().getAccessToken(at.getTokenKey()); assertEquals(at.getTokenKey(), at2.getTokenKey()); List<OAuthPermission> scopes = at2.getScopes(); assertNotNull(scopes); assertEquals(1, scopes.size()); OAuthPermission perm = scopes.get(0); assertEquals("a", perm.getPermission()); - - List<ServerAccessToken> tokens = provider.getAccessTokens(c, c.getResourceOwnerSubject()); + + List<ServerAccessToken> tokens = getProvider().getAccessTokens(c, c.getResourceOwnerSubject()); assertNotNull(tokens); assertEquals(1, tokens.size()); assertEquals(at.getTokenKey(), tokens.get(0).getTokenKey()); - - tokens = provider.getAccessTokens(c, null); + + tokens = getProvider().getAccessTokens(c, null); assertNotNull(tokens); assertEquals(1, tokens.size()); assertEquals(at.getTokenKey(), tokens.get(0).getTokenKey()); - - tokens = provider.getAccessTokens(null, c.getResourceOwnerSubject()); + + tokens = getProvider().getAccessTokens(null, c.getResourceOwnerSubject()); assertNotNull(tokens); assertEquals(1, tokens.size()); assertEquals(at.getTokenKey(), tokens.get(0).getTokenKey()); - - tokens = provider.getAccessTokens(null, null); + + tokens = getProvider().getAccessTokens(null, null); assertNotNull(tokens); assertEquals(1, tokens.size()); assertEquals(at.getTokenKey(), tokens.get(0).getTokenKey()); - - provider.revokeToken(c, at.getTokenKey(), OAuthConstants.ACCESS_TOKEN); - assertNull(provider.getAccessToken(at.getTokenKey())); + + getProvider().revokeToken(c, at.getTokenKey(), OAuthConstants.ACCESS_TOKEN); + assertNull(getProvider().getAccessToken(at.getTokenKey())); } - + @Test public void testAddGetDeleteAccessToken2() { Client c = addClient("102", "bob"); - + AccessTokenRegistration atr = new AccessTokenRegistration(); atr.setClient(c); atr.setApprovedScope(Collections.singletonList("a")); atr.setSubject(c.getResourceOwnerSubject()); - - provider.createAccessToken(atr); - List<ServerAccessToken> tokens = provider.getAccessTokens(c, null); + + getProvider().createAccessToken(atr); + List<ServerAccessToken> tokens = getProvider().getAccessTokens(c, null); assertNotNull(tokens); assertEquals(1, tokens.size()); - - provider.removeClient(c.getClientId()); - - tokens = provider.getAccessTokens(c, null); + + getProvider().removeClient(c.getClientId()); + + tokens = getProvider().getAccessTokens(c, null); assertNotNull(tokens); assertEquals(0, tokens.size()); } - + @Test public void testAddGetDeleteRefreshToken() { Client c = addClient("101", "bob"); - + AccessTokenRegistration atr = new AccessTokenRegistration(); atr.setClient(c); atr.setApprovedScope(Arrays.asList("a", "refreshToken")); atr.setSubject(c.getResourceOwnerSubject()); - - ServerAccessToken at = provider.createAccessToken(atr); - ServerAccessToken at2 = provider.getAccessToken(at.getTokenKey()); + + ServerAccessToken at = getProvider().createAccessToken(atr); + ServerAccessToken at2 = getProvider().getAccessToken(at.getTokenKey()); assertEquals(at.getTokenKey(), at2.getTokenKey()); List<OAuthPermission> scopes = at2.getScopes(); assertNotNull(scopes); @@ -196,28 +195,28 @@ public class JPAOAuthDataProviderTest extends Assert { assertEquals("a", perm.getPermission()); OAuthPermission perm2 = scopes.get(1); assertEquals("refreshToken", perm2.getPermission()); - - RefreshToken rt = provider.getRefreshToken(at2.getRefreshToken()); + + RefreshToken rt = getProvider().getRefreshToken(at2.getRefreshToken()); assertNotNull(rt); assertEquals(at2.getTokenKey(), rt.getAccessTokens().get(0)); - - List<RefreshToken> tokens = provider.getRefreshTokens(c, c.getResourceOwnerSubject()); + + List<RefreshToken> tokens = getProvider().getRefreshTokens(c, c.getResourceOwnerSubject()); assertNotNull(tokens); assertEquals(1, tokens.size()); assertEquals(rt.getTokenKey(), tokens.get(0).getTokenKey()); - - provider.revokeToken(c, rt.getTokenKey(), OAuthConstants.REFRESH_TOKEN); - - assertNull(provider.getRefreshToken(rt.getTokenKey())); + + getProvider().revokeToken(c, rt.getTokenKey(), OAuthConstants.REFRESH_TOKEN); + + assertNull(getProvider().getRefreshToken(rt.getTokenKey())); } - + private Client addClient(String clientId, String userLogin) { Client c = new Client(); c.setRedirectUris(Collections.singletonList("http://client/redirect")); c.setClientId(clientId); c.setClientSecret("123"); c.setResourceOwnerSubject(new UserSubject(userLogin)); - provider.setClient(c); + getProvider().setClient(c); return c; } private void compareClients(Client c, Client c2) { @@ -228,12 +227,12 @@ public class JPAOAuthDataProviderTest extends Assert { assertEquals("http://client/redirect", c.getRedirectUris().get(0)); assertEquals(c.getResourceOwnerSubject().getLogin(), c2.getResourceOwnerSubject().getLogin()); } - + @After public void tearDown() throws Exception { try { if (provider != null) { - provider.close(); + getProvider().close(); } if (emFactory != null) { emFactory.close(); @@ -242,7 +241,7 @@ public class JPAOAuthDataProviderTest extends Assert { ex.printStackTrace(); } finally { try { - connection.createStatement().execute("SHUTDOWN"); + //connection.createStatement().execute("SHUTDOWN"); } catch (Throwable ex) { ex.printStackTrace(); } http://git-wip-us.apache.org/repos/asf/cxf/blob/88cde365/rt/rs/security/oauth-parent/oauth2/src/test/resources/META-INF/orm.xml ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/resources/META-INF/orm.xml b/rt/rs/security/oauth-parent/oauth2/src/test/resources/META-INF/orm.xml deleted file mode 100644 index 0b25439..0000000 --- a/rt/rs/security/oauth-parent/oauth2/src/test/resources/META-INF/orm.xml +++ /dev/null @@ -1,99 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, either express or implied. See the License for the - specific language governing permissions and limitations - under the License. ---> -<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd" - version="2.0"> - - <mapped-superclass class="org.apache.cxf.rs.security.oauth2.common.AccessToken"> - <attributes> - <id name="tokenKey"/> - <element-collection name="parameters"> - <map-key-column name="propName"/> - </element-collection> - </attributes> - </mapped-superclass> - <mapped-superclass class="org.apache.cxf.rs.security.oauth2.common.ServerAccessToken"> - <attributes> - <many-to-one name="subject" fetch="LAZY"/> - <many-to-one name="client" fetch="LAZY"/> - <many-to-many name="scopes"/> - <element-collection name="audiences" target-class="java.lang.String"/> - <element-collection name="extraProperties"> - <map-key-column name="extraPropName"/> - </element-collection> - </attributes> - </mapped-superclass> - <mapped-superclass class="org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrant"> - <attributes> - <id name="code"/> - </attributes> - </mapped-superclass> - <entity class="org.apache.cxf.rs.security.oauth2.tokens.bearer.BearerAccessToken"> - <attributes/> - </entity> - <entity class="org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken"> - <attributes> - <element-collection name="accessTokens" target-class="java.lang.String"/> - </attributes> - </entity> - <entity class="org.apache.cxf.rs.security.oauth2.common.OAuthPermission"> - <attributes> - <id name="permission"/> - <element-collection name="httpVerbs" target-class="java.lang.String"/> - <element-collection name="uris" target-class="java.lang.String"/> - </attributes> - </entity> - <entity class="org.apache.cxf.rs.security.oauth2.common.Client"> - <attributes> - <id name="clientId"/> - <many-to-one name="resourceOwnerSubject" fetch="LAZY"/> - <one-to-one name="subject" fetch="LAZY"/> - <element-collection name="applicationCertificates" target-class="java.lang.String"/> - <element-collection name="redirectUris" target-class="java.lang.String"/> - <element-collection name="allowedGrantTypes" target-class="java.lang.String"/> - <element-collection name="registeredScopes" target-class="java.lang.String"/> - <element-collection name="registeredAudiences" target-class="java.lang.String"/> - <element-collection name="properties"> - <map-key-column name="name"/> - </element-collection> - </attributes> - </entity> - <entity class="org.apache.cxf.rs.security.oauth2.common.UserSubject"> - <attributes> - <id name="login"/> - <element-collection name="roles" target-class="java.lang.String"/> - <element-collection name="properties"> - <map-key-column name="name"/> - </element-collection> - </attributes> - </entity> - <entity class="org.apache.cxf.rs.security.oauth2.grants.code.ServerAuthorizationCodeGrant"> - <attributes> - <many-to-one name="subject" fetch="LAZY"/> - <many-to-one name="client" fetch="LAZY"/> - <element-collection name="requestedScopes" target-class="java.lang.String"/> - <element-collection name="approvedScopes" target-class="java.lang.String"/> - <element-collection name="extraProperties"> - <map-key-column name="extraPropName"/> - </element-collection> - </attributes> - </entity> - </entity-mappings> http://git-wip-us.apache.org/repos/asf/cxf/blob/88cde365/rt/rs/security/oauth-parent/oauth2/src/test/resources/META-INF/persistence.xml ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/resources/META-INF/persistence.xml b/rt/rs/security/oauth-parent/oauth2/src/test/resources/META-INF/persistence.xml index 25c7f76..b572fbd 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/test/resources/META-INF/persistence.xml +++ b/rt/rs/security/oauth-parent/oauth2/src/test/resources/META-INF/persistence.xml @@ -2,51 +2,62 @@ 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" version="2.0"> - - <persistence-unit name="testUnitHibernate" transaction-type="RESOURCE_LOCAL"> - <provider>org.hibernate.ejb.HibernatePersistence</provider> - <class>org.apache.cxf.rs.security.oauth2.common.Client</class> - <class>org.apache.cxf.rs.security.oauth2.common.UserSubject</class> - <class>org.apache.cxf.rs.security.oauth2.grants.code.ServerAuthorizationCodeGrant</class> - <class>org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrant</class> - <class>org.apache.cxf.rs.security.oauth2.tokens.bearer.BearerAccessToken</class> - <class>org.apache.cxf.rs.security.oauth2.common.ServerAccessToken</class> - <class>org.apache.cxf.rs.security.oauth2.common.AccessToken</class> - <class>org.apache.cxf.rs.security.oauth2.common.OAuthPermission</class> - <class>org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken</class> - <exclude-unlisted-classes>true</exclude-unlisted-classes> - <properties> - <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:oauth-jpa"/> - <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/> - <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/> - <property name="hibernate.hbm2ddl.auto" value="create-drop"/> - <property name="hibernate.connection.username" value="sa"/> - <property name="hibernate.connection.password" value=""/> - <property name="javax.persistence.validation.mode" value="none"/> - </properties> - </persistence-unit> - - <!-- - <persistence-unit name="testUnitOpenJPA" transaction-type="RESOURCE_LOCAL"> - <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> - <class>org.apache.cxf.rs.security.oauth2.common.Client</class> - <class>org.apache.cxf.rs.security.oauth2.common.UserSubject</class> - <class>org.apache.cxf.rs.security.oauth2.grants.code.ServerAuthorizationCodeGrant</class> - <class>org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrant</class> - <class>org.apache.cxf.rs.security.oauth2.tokens.bearer.BearerAccessToken</class> - <class>org.apache.cxf.rs.security.oauth2.common.ServerAccessToken</class> - <class>org.apache.cxf.rs.security.oauth2.common.AccessToken</class> - <class>org.apache.cxf.rs.security.oauth2.common.OAuthPermission</class> - <class>org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken</class> - <exclude-unlisted-classes>true</exclude-unlisted-classes> - <properties> - <property name="openjpa.ConnectionURL" value="jdbc:hsqldb:mem:oauth-jpa"/> - <property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver"/> - <property name="openjpa.jdbc.DBDictionary" value="hsql" /> - <property name="openjpa.ConnectionUserName" value="sa"/> - <property name="openjpa.ConnectionPassword" value=""/> - <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/> - </properties> + + <persistence-unit name="testUnitHibernate" transaction-type="RESOURCE_LOCAL"> + <provider>org.hibernate.ejb.HibernatePersistence</provider> + <class>org.apache.cxf.rs.security.oauth2.common.Client</class> + <class>org.apache.cxf.rs.security.oauth2.common.UserSubject</class> + <class>org.apache.cxf.rs.security.oauth2.grants.code.ServerAuthorizationCodeGrant</class> + <class>org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrant</class> + <class>org.apache.cxf.rs.security.oauth2.tokens.bearer.BearerAccessToken</class> + <class>org.apache.cxf.rs.security.oauth2.common.ServerAccessToken</class> + <class>org.apache.cxf.rs.security.oauth2.common.AccessToken</class> + <class>org.apache.cxf.rs.security.oauth2.common.OAuthPermission</class> + <class>org.apache.cxf.rs.security.oauth2.common.Permission</class> + <class>org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken</class> + <exclude-unlisted-classes>true</exclude-unlisted-classes> + <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode> + <properties> + <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:oauth-jpa"/> + <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/> + <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/> + <property name="hibernate.hbm2ddl.auto" value="create-drop"/> + <property name="hibernate.connection.username" value="sa"/> + <property name="hibernate.connection.password" value=""/> + <property name="javax.persistence.validation.mode" value="none"/> + <property name="hibernate.cache.region.factory_class" + value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory"/> + <property name="hibernate.max_fetch_depth" value="3"/> + </properties> </persistence-unit> - --> + + <persistence-unit name="testUnitOpenJPA" transaction-type="RESOURCE_LOCAL"> + <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> + <class>org.apache.cxf.rs.security.oauth2.common.Client</class> + <class>org.apache.cxf.rs.security.oauth2.common.UserSubject</class> + <class>org.apache.cxf.rs.security.oauth2.grants.code.ServerAuthorizationCodeGrant</class> + <class>org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrant</class> + <class>org.apache.cxf.rs.security.oauth2.tokens.bearer.BearerAccessToken</class> + <class>org.apache.cxf.rs.security.oauth2.common.ServerAccessToken</class> + <class>org.apache.cxf.rs.security.oauth2.common.AccessToken</class> + <class>org.apache.cxf.rs.security.oauth2.common.OAuthPermission</class> + <class>org.apache.cxf.rs.security.oauth2.common.Permission</class> + <class>org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken</class> + <exclude-unlisted-classes>true</exclude-unlisted-classes> + <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode> + <properties> + <property name="openjpa.ConnectionURL" value="jdbc:hsqldb:mem:oauth-jpa"/> + <property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver"/> + <property name="openjpa.jdbc.DBDictionary" value="hsql"/> + <property name="openjpa.ConnectionUserName" value="sa"/> + <property name="openjpa.ConnectionPassword" value=""/> + <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/> + <property name="openjpa.jdbc.EagerFetchMode" value="parallel"/> + <property name="openjpa.MaxFetchDepth" value="20"/> + <!-- + <property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=TRACE, Tool=INFO"/> + --> + </properties> + </persistence-unit> + </persistence> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cxf/blob/88cde365/rt/rs/security/oauth-parent/oauth2/src/test/resources/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTCodeDataProvider.xml ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/resources/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTCodeDataProvider.xml b/rt/rs/security/oauth-parent/oauth2/src/test/resources/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTCodeDataProvider.xml new file mode 100644 index 0000000..c80434a --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2/src/test/resources/org/apache/cxf/rs/security/oauth2/grants/code/JPACMTCodeDataProvider.xml @@ -0,0 +1,113 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:aop="http://www.springframework.org/schema/aop" + xmlns:context="http://www.springframework.org/schema/context" + xmlns:tx="http://www.springframework.org/schema/tx" + xmlns:util="http://www.springframework.org/schema/util" + xsi:schemaLocation="http://www.springframework.org/schema/aop + http://www.springframework.org/schema/aop/spring-aop.xsd + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context.xsd + http://www.springframework.org/schema/tx + http://www.springframework.org/schema/tx/spring-tx.xsd + http://www.springframework.org/schema/util + http://www.springframework.org/schema/util/spring-util.xsd"> + + + <bean id="oauthProvider" + class="org.apache.cxf.rs.security.oauth2.grants.code.JPACMTCodeDataProvider" + init-method="init" destroy-method="close"> + </bean> + + + <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> + <property name="entityManagerFactory" ref="entityManagerFactory"/> + </bean> + + <tx:annotation-driven transaction-manager="transactionManager"/> + + <aop:config proxy-target-class="true"> + <aop:pointcut id="oauthProviderOperation" + expression="bean(oauthProvider)"/> + <aop:advisor advice-ref="txAdvice" pointcut-ref="oauthProviderOperation"/> + </aop:config> + <tx:advice id="txAdvice" transaction-manager="transactionManager"> + <tx:attributes> + <tx:method name="*"/> + </tx:attributes> + </tx:advice> + + <beans profile="hibernate"> + <bean id="entityManagerFactory" + class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> + <!-- + <property name="dataSource" ref="dataSource"/> + --> + <!--<property name="jpaVendorAdapter">--> + <!--<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">--> + <!--<property name="showSql" value="true"/>--> + <!--<property name="generateDdl" value="true"/>--> + <!--</bean>--> + <!--</property>--> + <property name="persistenceUnitName" value="testUnitHibernate"/> + <property name="jpaPropertyMap"> + <map> + <entry key="hibernate.jdbc.fetch_size" value="400"/> + <entry key="hibernate.jdbc.batch_size" value="100"/> + <!--<entry key="hibernate.cache.use_second_level_cache" value="true"/>--> + <!--<entry key="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory"/>--> + </map> + </property> + </bean> + </beans> + + <beans profile="openJPA"> + <bean id="entityManagerFactory" + class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> + <!-- + <property name="dataSource" ref="dataSource"/> + --> + <!--<property name="jpaVendorAdapter">--> + <!--<bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">--> + <!--<property name="showSql" value="true"/>--> + <!--<property name="generateDdl" value="true"/>--> + <!--</bean>--> + <!--</property>--> + <property name="persistenceUnitName" value="testUnitOpenJPA"/> + <!-- + <property name="loadTimeWeaver"> + <bean class="org.springframework.instrument.classloading.SimpleLoadTimeWeaver"/> + </property> + --> + <!--<property name="jpaPropertyMap">--> + <!--<map>--> + <!--<entry key="openjpa.Log" value="slf4j"/>--> + <!--<entry key="openjpa.Log" value="SQL=TRACE"/>--> + <!--<entry key="openjpa.ConnectionFactoryProperties"--> + <!--value="PrintParameters=true, PrettyPrint=true, PrettyPrintLineLength=80"/>--> + <!--<entry key="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>--> + <!--</map>--> + </bean> + </beans> +</beans> \ No newline at end of file
