All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xlcloud.openstack.client.OpenStackKeystoneClient Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2012 AMG.lab, a Bull Group Company
 * 
 * Licensed 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.xlcloud.openstack.client;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.List;

import javax.ws.rs.core.MediaType;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.xlcloud.logging.LoggingUtils;
import org.xlcloud.openstack.api.IdentityManagementClient;
import org.xlcloud.openstack.api.identity.IdentityAdministrationEndpoint;
import org.xlcloud.openstack.api.identity.UserResource;
import org.xlcloud.openstack.api.identity.UsersResource;
import org.xlcloud.openstack.model.exceptions.OpenStackAuthenticationException;
import org.xlcloud.openstack.model.exceptions.OpenStackNotFoundException;
import org.xlcloud.openstack.model.identity.Access;
import org.xlcloud.openstack.model.identity.Role;
import org.xlcloud.openstack.model.identity.RoleList;
import org.xlcloud.openstack.model.identity.Tenant;
import org.xlcloud.openstack.model.identity.TenantList;
import org.xlcloud.openstack.model.identity.Token;
import org.xlcloud.openstack.model.identity.User;
import org.xlcloud.openstack.model.identity.UserForCreate;
import org.xlcloud.openstack.model.identity.UserList;
import org.xlcloud.openstack.model.identity.keystone.KeystoneAccess;
import org.xlcloud.openstack.model.identity.keystone.KeystoneAuthentication;
import org.xlcloud.openstack.rest.PerformanceMonitorFilter;
import org.xlcloud.rest.client.config.ClientLoggingFilter;

import com.sun.jersey.api.client.Client;

/**
 * This class is the main implementation of the {@link IdentityManagementClient}
 * . As there is no public constructor of this class, the only way to retrieve
 * the instance of this class is by invoking one of static methods getInstance.
 * To see the difference between them, compare
 * {@link OpenStackKeystoneClient#getInstance(String,String,String,String)} and
 * {@link OpenStackKeystoneClient#getInstance(Token, String)}.
 * 
 * @author Andrzej Stasiak, AMG.net
 */
public class OpenStackKeystoneClient implements IdentityManagementClient {

    private static final Logger LOG = Logger.getLogger(OpenStackKeystoneClient.class);

    private final String resourceUri;

    private final Client client;

    private String tokenId;
    
    private OpenStackKeystoneClient( String endpoint ) {
        this.client = KeystoneRestClientProducer.INSTANCE.produceClient();
        this.resourceUri = endpoint;
        
        LOG.debug("Using Jersey client " + client.hashCode());
    }

    /**
     * This method creates and returns new object of OpenStackClient class. It
     * takes as parameters following items: user credentials (username and
     * password), name of the tenant the user should be logged on (one user may
     * belong to many tenants, and their privileges may differ between tenants)
     * and endpoint URI indicating the location of Keystone server (including
     * port number).
     * 

* The return value is not instance of OpenStackClient, but instead * {@link java.lang.reflect.Proxy} with {@link RefreshAuthenticationHandler} * . Note that, therefore, authentication on openstack is not performed at * the time of creating the client, but during the first request. This * behaviour is different than behavior of * {@link OpenStackKeystoneClient#getInstance(String, String)}. *

* * @param username * name of user to be logged as * @param password * password of user to be logged as * @param tenantName * name of tenant to be logged in * @param keystoneEndpointUri * an absolute URI to Keystone server * @return instance of OpenStackClient */ public static IdentityManagementClient getKeystoneClientInstance(String username, String password, String tenantName, String endpointUri) { if (LOG.isDebugEnabled()) { LOG.debug("Creating new OpenStackClient for user " + username + " on tenant " + tenantName + ". Endpoint URI: " + endpointUri); } OpenStackKeystoneClient osClient = new OpenStackKeystoneClient(endpointUri); osClient.setFilters(); InvocationHandler handler = new RefreshAuthenticationHandler(osClient, username, password, tenantName); IdentityManagementClient imClient = (IdentityManagementClient) Proxy.newProxyInstance( OpenStackKeystoneClient.class.getClassLoader(), new Class[] { IdentityManagementClient.class }, handler); return imClient; } /** * This method creates and returns new object of OpenStackClient class. It * takes as parameters keystone token and endpoint URI indicating the * location of Keystone server (including port number). In contrary to * {@link OpenStackKeystoneClient#getInstance(String,String,String,String)} * this method returns real OpenStackClient object, without proxy. *

* This is not default way of obtaining OpenStackClient. You should use it * only when you want to connect with existing Keystone session (e.g. super * as Keystone superuser, who has fixed token and no user credentials). *

* When given endpointUri does not indicate Keystone server, * {@link OpenStackNotFoundException} is thrown. If given token id is not * valid, {@link OpenStackAuthenticationException} is thrown. *

* As an implementation of {@link IdentityManagementClient} it uses set of * implementations of identity interfaces (package * org.xlcloud.openstack.model.identity) from package * org.xlcloud.openstack.model.identity.keystone. * * @param token * Keystone token id * @param endpointUri * an absolute URI to Keystone server * @return */ public static IdentityManagementClient getKeystoneClientInstance(String token, String endpointUri) { if (LOG.isDebugEnabled()) { LOG.debug("Creating new OpenStackClient with token: " + LoggingUtils.maskPartially(token) + ". Endpoint URI: " + endpointUri); } OpenStackKeystoneClient osClient = new OpenStackKeystoneClient(endpointUri); osClient.setToken(token); return osClient; } /** {@inheritDoc} */ public void reauthenticate(String username, String password, String tenantName) { if (isTokenValid(tokenId)) { // throw new OpenStackAuthenticationException("Current token is valid"); LOG.warn("Current token is valid, but we'll reauthenticate the user anyway."); } KeystoneAuthentication authentication = KeystoneAuthentication.withPasswordCredentials(username, password); if (StringUtils.isNotBlank(tenantName)) { authentication.setTenantName(tenantName); } Access access = client.resource(resourceUri + "/tokens").type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON) .post(KeystoneAccess.class, authentication); tokenId = access.getToken().getId(); setFilters(); } /** * This method should not be invoked directly, it is invoked by * RefreshAuthenticationHandler. * * @param id * token id to be used */ void setToken(String id) { this.tokenId = id; setFilters(); } /** * This method is made for testing purposes. It should not be invoked when * using OpenStackClient. * * @return token of current Keystone session. */ @Override public String getToken() { return this.tokenId; } private void setFilters() { client.removeAllFilters(); if (tokenId != null) { client.addFilter(new AuthFilter(tokenId)); } client.addFilter(new ClientLoggingFilter()); client.addFilter(new ExceptionHandlingFilter()); client.addFilter(new PerformanceMonitorFilter()); } private IdentityAdministrationEndpoint getIdentityAdministationEndpoint() { return new IdentityAdministrationEndpoint(client, resourceUri); } /** * {@inheritDoc} */ @Override public boolean isTokenValid(String token) { if (StringUtils.isBlank(token)) { return false; } try { String digest = DigestUtils.md5Hex(token); LOG.debug("Transformed token [" + LoggingUtils.maskPartially(token) + "] to digest [" + digest + "]"); getIdentityAdministationEndpoint().tokens().token(digest).get(); } catch (OpenStackAuthenticationException | OpenStackNotFoundException ex) { return false; } return true; } /** * {@inheritDoc} */ @Override public UserList getUserResources() { return getIdentityAdministationEndpoint().users().get(); } /** * {@inheritDoc} */ @Override public User getUserById(String id) { return getIdentityAdministationEndpoint().users().user(id).get(); } /** * {@inheritDoc} */ @Override public User getUserByName(String name) throws OpenStackNotFoundException { return getIdentityAdministationEndpoint().users().getUserByName(name); } /** * {@inheritDoc} */ @Override public void deleteUserById(String id) { getIdentityAdministationEndpoint().users().user(id).delete(); } /** * {@inheritDoc} */ @Override public User createUser(UserForCreate user) { IdentityAdministrationEndpoint identityAdministationEndpoint = getIdentityAdministationEndpoint(); UsersResource users = identityAdministationEndpoint.users(); return users.post(user); } /** * {@inheritDoc} */ @Override public User updateUser(UserForCreate user) { IdentityAdministrationEndpoint identityAdministationEndpoint = getIdentityAdministationEndpoint(); UserResource userRespource = identityAdministationEndpoint.users().user(user.getId()); return userRespource.put(user); } /** * {@inheritDoc} */ @Override public Tenant createTentant(Tenant tenant) { return getIdentityAdministationEndpoint().tenants().post(tenant); } /** * {@inheritDoc} */ @Override public Role createRole(Role role) { return getIdentityAdministationEndpoint().roles().post(role); } /** * {@inheritDoc} */ @Override public TenantList getTenantResources() { return getIdentityAdministationEndpoint().tenants().get(); } /** * {@inheritDoc} */ @Override public Role assignRole(String userId, String roleId, String tenantId) { return getIdentityAdministationEndpoint().tenants().tenant(tenantId).users().user(userId).roles().role(roleId).put(); } /** * {@inheritDoc} */ @Override public void removeRole(String userId, String roleId, String tenantId) { getIdentityAdministationEndpoint().tenants().tenant(tenantId).users().user(userId).roles().role(roleId).delete(); } /** * {@inheritDoc} */ @Override public RoleList getRoleResources() { return getIdentityAdministationEndpoint().roles().get(); } /** * {@inheritDoc} */ @Override public Tenant getTenantByName(String name) throws OpenStackNotFoundException { return getIdentityAdministationEndpoint().tenants().getTenantByName(name); } /** * {@inheritDoc} */ @Override public Role getRoleByName(String name) throws OpenStackNotFoundException { /* * According to the documentation * (http://docs.openstack.org/api/openstack * -identity-service/2.0/content/ * Admin_API_Service_Developer_Operations-d1e1357.html), it should be * possible to get role by name in the same manner as in getUserByName() * and getTentantByName(). However for some reason the "name" parameter * is ignored and the whole list is returned. */ RoleList roleList = getRoleResources(); if (roleList != null) { List roles = roleList.getList(); for (Role role : roles) { if (name.equals(role.getName())) { return role; } } } throw new OpenStackNotFoundException("Could not find role: " + name); } /** * {@inheritDoc} */ @Override public Tenant getTenantById(String id) { return getIdentityAdministationEndpoint().tenants().tenant(id).get(); } @Override public void removeTenant(String id) { getIdentityAdministationEndpoint().tenants().tenant(id).delete(); } /** {@inheritDoc} */ @Override public RoleList getUserRolesInTenant(String userId, String tenantId) { return getIdentityAdministationEndpoint().tenants().tenant(tenantId).users().user(userId).roles().get(); } /** {@inheritDoc} */ @Override public void removeAllUserRolesInTenant(String userId, String tenantId) { RoleList roleList = getUserRolesInTenant(userId, tenantId); if (roleList == null) { return; } for (Role role : roleList.getList()) { removeRole(userId, role.getId(), tenantId); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy