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

com.huawei.openstack4j.openstack.internal.BaseOpenStackService 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.                                                                     
 *******************************************************************************/
/******************************************************************************* 	                                                                                 
 *  Huawei has modified this source file.
 * 	Copyright 2018 Huawei Technologies Co.,Ltd.                                         
 * 	                                                                                 
 * 	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.internal;

import static com.huawei.openstack4j.core.transport.ClientConstants.HEADER_USER_AGENT;
import static com.huawei.openstack4j.core.transport.ClientConstants.USER_AGENT;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.huawei.openstack4j.api.client.CloudProvider;
import com.huawei.openstack4j.api.exceptions.OS4JException;
import com.huawei.openstack4j.api.types.ServiceType;
import com.huawei.openstack4j.core.transport.ClientConstants;
import com.huawei.openstack4j.core.transport.ExecutionOptions;
import com.huawei.openstack4j.core.transport.HttpMethod;
import com.huawei.openstack4j.core.transport.HttpRequest;
import com.huawei.openstack4j.core.transport.HttpRequest.RequestBuilder;
import com.huawei.openstack4j.core.transport.HttpResponse;
import com.huawei.openstack4j.core.transport.internal.HttpExecutor;
import com.huawei.openstack4j.model.common.ActionResponse;
import com.huawei.openstack4j.model.common.Payload;
import com.huawei.openstack4j.model.identity.AuthVersion;
import com.huawei.openstack4j.model.identity.v2.Access;
import com.huawei.openstack4j.model.identity.v3.Service;
import com.huawei.openstack4j.model.identity.v3.Token;

public class BaseOpenStackService {

	public static String CONTENT_JSON = "application/json;charset=utf-8";

	ServiceType serviceType = ServiceType.IDENTITY;
	Function endpointFunc;

	private static ThreadLocal reqIdContainer = new ThreadLocal();

	public String getXOpenstackRequestId() {
		return reqIdContainer.get();
	}

	protected BaseOpenStackService() {
	}

	protected BaseOpenStackService(ServiceType serviceType) {
		this(serviceType, null);
	}

	protected BaseOpenStackService(ServiceType serviceType, Function endpointFunc) {
		this.serviceType = serviceType;
		this.endpointFunc = endpointFunc;
	}

	protected  Invocation get(Class returnType, String... path) {
		return builder(returnType, path, HttpMethod.GET);
	}

	protected  Invocation post(Class returnType, String... path) {
		return builder(returnType, path, HttpMethod.POST);
	}

	protected  Invocation postWithResponse(String... path) {
		return builder(ActionResponse.class, path, HttpMethod.POST);
	}

	protected  Invocation put(Class returnType, String... path) {
		return builder(returnType, path, HttpMethod.PUT);
	}

	protected  Invocation putWithResponse(String... path) {
		return builder(ActionResponse.class, path, HttpMethod.PUT);
	}

	protected  Invocation patch(Class returnType, String... path) {
		return builder(returnType, path, HttpMethod.PATCH);
	}

	protected  Invocation patchWithResponse(String... path) {
		return builder(ActionResponse.class, path, HttpMethod.PATCH);
	}

	protected  Invocation delete(Class returnType, String... path) {
		return builder(returnType, path, HttpMethod.DELETE);
	}

	protected  Invocation deleteWithResponse(String... path) {
		return builder(ActionResponse.class, path, HttpMethod.DELETE);
	}

	protected  Invocation head(Class returnType, String... path) {
		return builder(returnType, path, HttpMethod.HEAD);
	}

	protected  Invocation request(HttpMethod method, Class returnType, String path) {
		return builder(returnType, path, method);
	}

	protected String uri(String path, Object... params) {
		if (params.length == 0)
			return path;
		return String.format(path, params);
	}

	protected  Invocation builder(Class returnType, String[] path, HttpMethod method) {
		return builder(returnType, Joiner.on("").join(path), method);
	}

	@SuppressWarnings("rawtypes")
	protected  Invocation builder(Class returnType, String path, HttpMethod method) {
		OSClientSession ses = OSClientSession.getCurrent();
		if (ses == null) {
			throw new OS4JException(
					"Unable to retrieve current session. Please verify thread has a current session available.");
		}

		// huawei RDS service will put `/{version}/%(project_id)s` in API request path but not endpoint.
		// so, we need to filter the path if we could get project_id
		if (ses instanceof OSClientSessionV3) {
			OSClientSessionV3 v3 = (OSClientSessionV3) ses;
			Token token = v3.getToken();
			if (null != token && token.getProject() != null && token.getProject().getId() != null) {
				path = path.replace("%(project_id)s", token.getProject().getId());
			}
		}else if (ses instanceof OSClientSessionAKSK) {
			OSClientSessionAKSK AKSK = (OSClientSessionAKSK) ses;
			if (!Strings.isNullOrEmpty(AKSK.getProjectId())) {
				path = path.replace("%(project_id)s", AKSK.getProjectId());
			}
		}

		RequestBuilder req = HttpRequest.builder(returnType).endpointTokenProvider(ses).config(ses.getConfig())
				.method(method).path(path);
		Map headers = ses.getHeaders();
		if (headers != null && headers.size() > 0) {
			return new Invocation(req, serviceType, endpointFunc).headers(headers);
		} else {
			return new Invocation(req, serviceType, endpointFunc);
		}
	}

	protected static class Invocation {
		RequestBuilder req;

		protected Invocation(RequestBuilder req, ServiceType serviceType, Function endpointFunc) {
			this.req = req;
			req.serviceType(serviceType);
			req.endpointFunction(endpointFunc);
		}

		public HttpRequest getRequest() {
			return req.build();
		}

		public Invocation param(String name, Object value) {
			req.queryParam(name, value);
			return this;
		}

		public Invocation updateParam(String name, Object value) {
			req.updateQueryParam(name, value);
			return this;
		}

		public Invocation params(Map params) {
			if (params != null) {
				for (String name : params.keySet())
					req.queryParam(name, params.get(name));
			}
			return this;
		}

		public Invocation param(boolean condition, String name, Object value) {
			if (condition)
				req.queryParam(name, value);
			return this;
		}

		public Invocation paramLists(Map> params) {
			if (params != null) {
				for (Map.Entry> pair : params.entrySet())
					for (Object value : pair.getValue())
						req.queryParam(pair.getKey(), value);
			}
			return this;
		}

		public Invocation serviceType(ServiceType serviceType) {
			req.serviceType(serviceType);
			return this;
		}

		public Invocation entity(Object entity) {
			req.entity(entity);
			return this;
		}

		public Invocation entity(Payload entity) {
			req.entity(entity);
			req.contentType(ClientConstants.CONTENT_TYPE_OCTECT_STREAM);
			return this;
		}

		public Invocation contentType(String contentType) {
			req.contentType(contentType);
			return this;
		}

		public Invocation json(String json) {
			req.json(json);
			return this;
		}

		public Invocation headers(Map headers) {
			if (headers != null)
				req.headers(headers);
			return this;
		}

		public Invocation header(String name, Object value) {
			req.header(name, value);
			return this;
		}

		public R execute() {
			return execute(null);
		}

		public R execute(ExecutionOptions options) {
			header(HEADER_USER_AGENT, USER_AGENT);
			HttpRequest request = req.build();
			HttpResponse res = HttpExecutor.create().execute(request);

			reqIdContainer.remove();

			String reqId = null;
			if (res.headers().containsKey(ClientConstants.X_COMPUTE_REQUEST_ID)) {
				reqId = res.header(ClientConstants.X_COMPUTE_REQUEST_ID);
			} else {
				reqId = res.header(ClientConstants.X_OPENSTACK_REQUEST_ID);
			}

			reqIdContainer.set(reqId);
			return res.getEntity(request.getReturnType(), options);
		}

		public HttpResponse executeWithResponse() {
			HttpResponse res = HttpExecutor.create().execute(req.build());
			reqIdContainer.remove();

			String reqId = null;
			if (res.headers().containsKey(ClientConstants.X_COMPUTE_REQUEST_ID)) {
				reqId = res.header(ClientConstants.X_COMPUTE_REQUEST_ID);
			} else {
				reqId = res.header(ClientConstants.X_OPENSTACK_REQUEST_ID);
			}

			reqIdContainer.set(reqId);
			return res;
		}

	}

	@SuppressWarnings("rawtypes")
	protected int getServiceVersion() {
		OSClientSession session = OSClientSession.getCurrent();
		if (session.getAuthVersion() == AuthVersion.V3) {
			SortedSet services = ((OSClientSessionV3) session).getToken().getAggregatedCatalog()
					.get(serviceType.getType());
			Service service = ((OSClientSessionV3) session).getToken().getAggregatedCatalog().get(serviceType.getType())
					.first();

			if (services.isEmpty()) {
				return 1;
			}

			return service.getVersion();

		} else {
			SortedSet services = ((OSClientSession.OSClientSessionV2) session).getAccess()
					.getAggregatedCatalog().get(serviceType.getType());
			Access.Service service = ((OSClientSession.OSClientSessionV2) session).getAccess().getAggregatedCatalog()
					.get(serviceType.getType()).first();

			if (services.isEmpty()) {
				return 1;
			}

			return service.getVersion();
		}

	}

	protected  List toList(T[] arr) {
		if (arr == null)
			return Collections.emptyList();
		return Arrays.asList(arr);
	}

	protected CloudProvider getProvider() {
		return OSClientSession.getCurrent().getProvider();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy