org.jclouds.vcloud.binders.BindInstantiateVAppTemplateParamsToXmlPayload Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vcloud Show documentation
Show all versions of vcloud Show documentation
jclouds components to access an implementation of VMWare vCloud
/*
* 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.jclouds.vcloud.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.transform;
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_NAMESPACE;
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_SCHEMA;
import java.net.URI;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import org.jclouds.http.HttpRequest;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.rest.MapBinder;
import org.jclouds.rest.binders.BindToStringPayload;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.VAppTemplate;
import org.jclouds.vcloud.domain.Vm;
import org.jclouds.vcloud.domain.network.FenceMode;
import org.jclouds.vcloud.domain.network.NetworkConfig;
import org.jclouds.vcloud.endpoints.Network;
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableSet;
import com.jamesmurty.utils.XMLBuilder;
@Singleton
public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder {
protected final String ns;
protected final String schema;
protected final BindToStringPayload stringBinder;
protected final Supplier defaultNetwork;
protected final FenceMode defaultFenceMode;
protected final LoadingCache templateCache;
protected final Function defaultNetworkNameInTemplate;
@Inject
public BindInstantiateVAppTemplateParamsToXmlPayload(LoadingCache templateCache,
@Network Function defaultNetworkNameInTemplate, BindToStringPayload stringBinder,
@Named(PROPERTY_VCLOUD_XML_NAMESPACE) String ns, @Named(PROPERTY_VCLOUD_XML_SCHEMA) String schema,
@Network Supplier network, FenceMode fenceMode) {
this.templateCache = templateCache;
this.defaultNetworkNameInTemplate = defaultNetworkNameInTemplate;
this.ns = ns;
this.schema = schema;
this.stringBinder = stringBinder;
this.defaultNetwork = network;
this.defaultFenceMode = fenceMode;
}
@Override
public R bindToRequest(R request, Map postParams) {
checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest,
"this binder is only valid for GeneratedHttpRequests!");
GeneratedHttpRequest gRequest = (GeneratedHttpRequest) request;
String name = checkNotNull(postParams.remove("name"), "name").toString();
URI template = URI.create(checkNotNull(postParams.remove("template"), "template").toString());
Set networkConfig = null;
NetworkConfigDecorator networkConfigDecorator = new NetworkConfigDecorator(templateCache.getUnchecked(template),
defaultNetwork.get().getHref(), defaultFenceMode, defaultNetworkNameInTemplate);
InstantiateVAppTemplateOptions options = findOptionsInArgsOrNull(gRequest);
if (options != null) {
if (options.getNetworkConfig().size() > 0)
networkConfig = ImmutableSet
.copyOf(transform(options.getNetworkConfig(), networkConfigDecorator));
} else {
options = new InstantiateVAppTemplateOptions();
}
if (networkConfig == null)
networkConfig = ImmutableSet.of(networkConfigDecorator.apply(null));
try {
return stringBinder.bindToRequest(request, generateXml(name, options.getDescription(), options.shouldDeploy(),
options.shouldPowerOn(), template, networkConfig));
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
} catch (FactoryConfigurationError e) {
throw new RuntimeException(e);
} catch (TransformerException e) {
throw new RuntimeException(e);
}
}
@VisibleForTesting
Set ifCustomizationScriptIsSetGetVmsInTemplate(String customizationScript, final URI template) {
Set vms = ImmutableSet.of();
if (customizationScript != null) {
VAppTemplate vAppTemplate = templateCache.getUnchecked(template);
checkArgument(vAppTemplate != null, "vAppTemplate %s not found!", template);
vms = vAppTemplate.getChildren();
checkArgument(vms.size() > 0, "no vms found in vAppTemplate %s", vAppTemplate);
}
return vms;
}
protected static final class NetworkConfigDecorator implements Function {
private final VAppTemplate template;
private final URI defaultNetwork;
private final FenceMode defaultFenceMode;
private final Function defaultNetworkNameInTemplate;
protected NetworkConfigDecorator(VAppTemplate template, URI defaultNetwork, FenceMode defaultFenceMode,
Function defaultNetworkNameInTemplate) {
this.template = checkNotNull(template, "template");
this.defaultNetwork = checkNotNull(defaultNetwork, "defaultNetwork");
this.defaultFenceMode = checkNotNull(defaultFenceMode, "defaultFenceMode");
this.defaultNetworkNameInTemplate = checkNotNull(defaultNetworkNameInTemplate, "defaultNetworkNameInTemplate");
}
@Override
public NetworkConfig apply(NetworkConfig from) {
if (from == null)
return new NetworkConfig(defaultNetworkNameInTemplate.apply(template), defaultNetwork, defaultFenceMode);
URI network = ifNullDefaultTo(from.getParentNetwork(), defaultNetwork);
FenceMode fenceMode = ifNullDefaultTo(from.getFenceMode(), defaultFenceMode);
// using conditional statement instead of ifNullDefaultTo so that we lazy invoke the
// function, as it is an expensive one.
String networkName = from.getNetworkName() != null ? from.getNetworkName() : defaultNetworkNameInTemplate
.apply(template);
return new NetworkConfig(networkName, network, fenceMode);
}
}
protected String generateXml(String name, @Nullable String description, boolean deploy, boolean powerOn,
URI template, Iterable networkConfig)
throws ParserConfigurationException, FactoryConfigurationError, TransformerException {
XMLBuilder rootBuilder = buildRoot(name).a("deploy", deploy + "").a("powerOn", powerOn + "");
if (description != null)
rootBuilder.e("Description").t(description);
XMLBuilder instantiationParamsBuilder = rootBuilder.e("InstantiationParams");
addNetworkConfig(instantiationParamsBuilder, networkConfig);
rootBuilder.e("Source").a("href", template.toASCIIString());
rootBuilder.e("AllEULAsAccepted").t("true");
Properties outputProperties = new Properties();
outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
return rootBuilder.asString(outputProperties);
}
protected void addNetworkConfig(XMLBuilder instantiationParamsBuilder,
Iterable networkConfig) {
XMLBuilder networkConfigBuilder = instantiationParamsBuilder.e("NetworkConfigSection");
networkConfigBuilder.e("ovf:Info").t("Configuration parameters for logical networks");
for (NetworkConfig n : networkConfig) {
XMLBuilder configurationBuilder = networkConfigBuilder.e("NetworkConfig").a("networkName", n.getNetworkName())
.e("Configuration");
configurationBuilder.e("ParentNetwork").a("href", n.getParentNetwork().toASCIIString());
if (n.getFenceMode() != null) {
configurationBuilder.e("FenceMode").t(n.getFenceMode().toString());
}
}
}
protected XMLBuilder buildRoot(String name) throws ParserConfigurationException, FactoryConfigurationError {
return XMLBuilder.create("InstantiateVAppTemplateParams").a("name", name).a("xmlns", ns)
.a("xmlns:ovf", "http://schemas.dmtf.org/ovf/envelope/1");
}
protected InstantiateVAppTemplateOptions findOptionsInArgsOrNull(GeneratedHttpRequest gRequest) {
for (Object arg : gRequest.getInvocation().getArgs()) {
if (arg instanceof InstantiateVAppTemplateOptions) {
return (InstantiateVAppTemplateOptions) arg;
} else if (arg instanceof InstantiateVAppTemplateOptions[]) {
InstantiateVAppTemplateOptions[] options = (InstantiateVAppTemplateOptions[]) arg;
return (options.length > 0) ? options[0] : null;
}
}
return null;
}
@Override
public R bindToRequest(R request, Object input) {
throw new IllegalStateException("InstantiateVAppTemplateParams is needs parameters");
}
public static T ifNullDefaultTo(T value, T defaultValue) {
return value != null ? value : checkNotNull(defaultValue, "defaultValue");
}
}