All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.huawei.openstack4j.openstack.identity.internal.OverridableEndpointURLResolver Maven / Gradle / Ivy
/*******************************************************************************
* Copyright 2016 ContainX and OpenStack4j
*
* 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 com.huawei.openstack4j.openstack.identity.internal;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.SortedSet;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Optional;
import com.google.common.collect.Maps;
import com.google.common.collect.SortedSetMultimap;
import com.huawei.openstack4j.api.exceptions.RegionEndpointNotFoundException;
import com.huawei.openstack4j.api.identity.EndpointURLResolver;
import com.huawei.openstack4j.api.types.Facing;
import com.huawei.openstack4j.api.types.ServiceType;
import com.huawei.openstack4j.model.identity.URLResolverParams;
import com.huawei.openstack4j.model.identity.v2.Access;
import com.huawei.openstack4j.model.identity.v2.Endpoint;
import com.huawei.openstack4j.model.identity.v3.Token;
/**
* Most are copied from {@link DefaultEndpointURLResolver},
* Add features to explicit override endpoint of services
*
* @author QianBiao.NG
* @date 2017-06-10 18:14:04
*/
public class OverridableEndpointURLResolver implements EndpointURLResolver {
static final Logger LOG = LoggerFactory.getLogger(OverridableEndpointURLResolver.class);
static final Map CACHE = new ConcurrentHashMap();
static boolean LEGACY_EP_HANDLING = Boolean.getBoolean(LEGACY_EP_RESOLVING_PROP);
String publicHostIP;
/** service override endpoint mapping */
Map overrides = Maps.newHashMap();
/**
* register the override endpoint URL for service-type
*
* @param serviceType
* @param endpoint
*/
public void addOverrideEndpoint(ServiceType serviceType, String endpoint) {
overrides.put(serviceType, endpoint);
}
public Map getOverrides() {
return overrides;
}
@Override
public String findURLV2(URLResolverParams p) {
if (p.type == null) {
return p.access.getEndpoint();
}
Key key = Key.of(p.access.getCacheIdentifier(), p.type, p.perspective, p.region);
String url = CACHE.get(key);
if (url != null)
return url;
String endpoint = overrides.get(p.type);
if (endpoint != null) {
url = endpoint;
} else {
url = resolveV2(p);
}
if (url != null) {
CACHE.put(key, url);
return url;
} else if (p.region != null)
throw RegionEndpointNotFoundException.create(p.region, p.type.getServiceName());
return p.access.getEndpoint();
}
@Override
public String findURLV3(URLResolverParams p) {
if (p.type == null) {
return p.token.getEndpoint();
}
Key key = Key.of(p.token.getCacheIdentifier(), p.type, p.perspective, p.region);
String url = CACHE.get(key);
if (url != null)
return url;
// try use override endpoint first
String endpoint = overrides.get(p.type);
if (endpoint != null) {
if(p.token.getProject()!=null){
url = endpoint.replace("%(project_id)s", p.token.getProject().getId());
}else{
url = endpoint;
}
} else {
url = resolveV3(p);
}
if (url != null) {
CACHE.put(key, url);
return url;
} else if (p.region != null)
throw RegionEndpointNotFoundException.create(p.region, p.type.getServiceName());
return p.token.getEndpoint();
}
private String resolveV2(URLResolverParams p) {
SortedSetMultimap catalog = p.access.getAggregatedCatalog();
SortedSet services = catalog.get(p.type.getServiceName());
if (services.isEmpty()) {
services = catalog.get(p.type.getType());
}
if (!services.isEmpty()) {
Access.Service sc = p.getV2Resolver().resolveV2(p.type, services);
for (com.huawei.openstack4j.model.identity.v2.Endpoint ep : sc.getEndpoints()) {
if (p.region != null && !p.region.equalsIgnoreCase(ep.getRegion()))
continue;
if (sc.getServiceType() == ServiceType.NETWORK) {
sc.getEndpoints().get(0).toBuilder().type(sc.getServiceType().name());
}
if (p.perspective == null)
return getEndpointURL(p.access, ep);
switch (p.perspective) {
case ADMIN:
return ep.getAdminURL().toString();
case INTERNAL:
return ep.getInternalURL().toString();
case PUBLIC:
default:
return ep.getPublicURL().toString();
}
}
} else {
// if no catalog returned, if is identity service, just return endpoint
if (ServiceType.IDENTITY.equals(p.type)) {
return p.access.getEndpoint();
}
}
return null;
}
private String resolveV3(URLResolverParams p) {
Token token = p.token;
// in v3 api, if user has no default project, and token is unscoped, no catalog will be returned
// then if service is Identity service, should directly return the endpoint back
if (token.getCatalog() == null) {
if (ServiceType.IDENTITY.equals(p.type)) {
return token.getEndpoint();
} else {
return null;
}
}
for (com.huawei.openstack4j.model.identity.v3.Service service : token.getCatalog()) {
if (p.type == ServiceType.forName(service.getType())) {
if (p.perspective == null) {
p.perspective = Facing.PUBLIC;
}
for (com.huawei.openstack4j.model.identity.v3.Endpoint ep : service.getEndpoints()) {
if (matches(ep, p))
return ep.getUrl().toString();
}
}
}
return null;
}
/**
* Returns true
for any endpoint that matches a given
* {@link URLResolverParams}.
*
* @param endpoint
* @param p
* @return
*/
private boolean matches(com.huawei.openstack4j.model.identity.v3.Endpoint endpoint, URLResolverParams p) {
boolean matches = endpoint.getIface() == p.perspective;
if (Optional.fromNullable(p.region).isPresent()) {
matches &= endpoint.getRegion().equals(p.region);
}
return matches;
}
/**
* Gets the endpoint url.
*
* @param access the current access data source
* @param endpoint the endpoint
* @return the endpoint url
*/
private String getEndpointURL(Access access, Endpoint endpoint) {
if (LEGACY_EP_HANDLING) {
if (endpoint.getAdminURL() != null) {
if (getPublicIP(access) != null && !getPublicIP(access).equals(endpoint.getAdminURL().getHost())) {
return endpoint.getAdminURL().toString().replaceAll(endpoint.getAdminURL().getHost(),
getPublicIP(access));
}
return endpoint.getAdminURL().toString();
}
}
return endpoint.getPublicURL().toString();
}
private String getPublicIP(Access access) {
if (publicHostIP == null) {
try {
publicHostIP = new URI(access.getEndpoint()).getHost();
} catch (URISyntaxException e) {
LOG.error(e.getMessage(), e);
}
}
return publicHostIP;
}
private static final class Key {
private final String uid;
private final ServiceType type;
private final Facing perspective;
private Key(String uid, ServiceType type, Facing perspective) {
this.type = type;
this.perspective = perspective;
this.uid = uid;
}
static Key of(String uid, ServiceType type, Facing perspective, String region) {
return new Key((region == null) ? uid : uid + region, type, perspective);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((perspective == null) ? 0 : perspective.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
result = prime * result + ((uid == null) ? 0 : uid.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Key other = (Key) obj;
if (perspective != other.perspective)
return false;
if (type != other.type)
return false;
if (uid == null) {
if (other.uid != null)
return false;
} else if (!uid.equals(other.uid))
return false;
return true;
}
}
@Override
public String resolve(URLResolverParams p) {
Key key = Key.of(p.projectId, p.type, p.perspective, p.region);
String url = CACHE.get(key);
if(null != url){
return url;
}
String endpoint = overrides.get(p.type);
if(null != endpoint ){
if(null != p.projectId){
url = endpoint.replace("%(project_id)s", p.projectId);
}else{
url = endpoint;
}
CACHE.put(key, url);
}
return url;
}
}