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

com.vmware.vcloud.api.rest.client.OpenApiClientImpl Maven / Gradle / Ivy

There is a newer version: 0.10.0
Show newest version
/* ***************************************************************************
 * api-extension-template-vcloud-director
 * Copyright 2018 VMware, Inc.
 * SPDX-License-Identifier: BSD-2-Clause
 * **************************************************************************/

package com.vmware.vcloud.api.rest.client;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
import com.vmware.cxfrestclient.JaxRsClient;

import org.apache.cxf.jaxrs.client.Client;
import org.apache.cxf.jaxrs.client.WebClient;

/**
 * An Open API client for VCD that allows both JAX-RS and RESTful calls to VCD's /cloudapi endpoints
 * 

* An instance of this can only be acquired from {@link VcdClient#getOpenApiClient()} call and this * client's authentication is tied to the parent {@link VcdClient} from which this is instantiated */ class OpenApiClientImpl extends AbstractVcdClientBase implements OpenApiClient { private final VcdClientImpl parentVcdClient; /** * Creates an instance of OpenApiClient by as dependent on the specified {@link VcdClientImpl} *

* This allows current authentication state to be inherited from the parent * {@code VcdClientImpl} * * @param vcdClient * {@link VcdClientImpl} from which this {@link OpenApiClientImpl} has been * inherited. */ OpenApiClientImpl(VcdClientImpl vcdClient) { super(vcdClient.getOpenApiEndpoint(), vcdClient); this.parentVcdClient = vcdClient; } @Override protected List getCxfProviders() { final ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(Include.NON_NULL); final JacksonJsonProvider provider = new JacksonJsonProvider(mapper); return Collections.singletonList(provider); } @Override protected void setAuthenticationHeaders(Client client) { parentVcdClient.setAuthenticationHeaders(client); } @Override protected String[] getAcceptHeaders() { return new String[] { MediaType.APPLICATION_JSON }; } /** * Return a custom proxy that ensures that a new proxy object is generated for each call. *

* This ensures that when underlying {@link Client} is utilized for a particular call, custom * settings for that call are reset before the next call. {@link JaxRsClient#createProxy(Class) * super.createProxy(Class)} is invoked to create proxy objects as needed. *

* * @param jaxrsApiInterface * {@link Class} for a open api generated interface * * @return a {@link Proxy} for the specified interface as described above. */ @Override public JaxRsClass createProxy(Class jaxrsApiInterface) { if (!jaxrsApiInterface.isInterface()) { throw new IllegalArgumentException(String.format("Class %s to proxy must be an interface", jaxrsApiInterface.getName())); } @SuppressWarnings("unchecked") final JaxRsClass proxiedProxy = (JaxRsClass) Proxy.newProxyInstance(jaxrsApiInterface.getClassLoader(), new Class[] { jaxrsApiInterface }, new SingleUseProxyInvoker<>(jaxrsApiInterface, this)); return proxiedProxy; } @Override public Client getWebClientForNextCall(JaxRsProxy proxy) { @SuppressWarnings("unchecked") final SingleUseProxyInvoker invocationHandler = (SingleUseProxyInvoker) Proxy.getInvocationHandler(proxy); return invocationHandler.getNextCallClient(); } private static final class SingleUseProxyInvoker extends AbstractVcdClientBase implements InvocationHandler { private final OpenApiClientImpl parentClient; private final Class api; private final AtomicReference apiProxy = new AtomicReference<>(null); SingleUseProxyInvoker(Class api, OpenApiClientImpl parentClient) { super(parentClient); this.parentClient = parentClient; this.api = api; resetWebClientProxy(); } private void resetWebClientProxy() { apiProxy.set(null); } private JaxRsApi getCurrentClientProxy() { apiProxy.compareAndSet(null, createProxy(api)); return apiProxy.get(); } Client getNextCallClient() { return WebClient.client(getCurrentClientProxy()); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { return method.invoke(getCurrentClientProxy(), args); } catch (InvocationTargetException ite) { throw ite.getCause(); } finally { resetWebClientProxy(); } } @Override protected void setAuthenticationHeaders(Client client) { parentClient.setAuthenticationHeaders(client); } /** * Return an empty array of {@code Accept} header values. *

* This will let the proxy configure the {@code Accept} based on {@link Consumes} annotation on * the method invoked. * * @return An empty array */ @Override protected String[] getAcceptHeaders() { return new String[0]; } @Override protected List getCxfProviders() { return parentClient.getCxfProviders(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy