/**
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is available at https://svn.forge.morfeo-project.org/claudia
*
* The Initial Developer of the Original Code is Telefonica Investigacion y Desarrollo S.A.U.,
* (http://www.tid.es), Emilio Vargas 6, 28043 Madrid, Spain.
.*
* No portions of the Code have been created by third parties.
* All Rights Reserved.
*
* Contributor(s): ______________________________________.
*
*/
/**
* This class is to hold utilities that does not fit in any other utility class, e.g. OVFEnvelopeUtils,
* OVFEnvironmentUtils, etc., because they can be used from many places
*/
package com.telefonica.claudia.ovf.utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.abiquo.ovf.OVFEnvironmentUtils;
import com.abiquo.ovf.exceptions.DNSServerNotFoundException;
import com.abiquo.ovf.exceptions.GatewayNotFoundException;
import com.abiquo.ovf.exceptions.IPNotFoundException;
import com.abiquo.ovf.exceptions.NetmaskNotFoundException;
import com.abiquo.ovf.exceptions.NotEnoughIPsInPoolException;
import com.abiquo.ovf.exceptions.PoolNameNotFoundException;
import com.abiquo.ovf.exceptions.PrecedentTierEntryPointNotFoundException;
public class OVFGeneralUtils {
/* String used for macros in macroReplacement method*/
private final static String IP_MACRO = "IP";
private final static String ID_MACRO = "id";
private final static String NETMASK_MACRO = "Netmask";
private final static String DNSSERVER_MACRO = "DNSServer";
private final static String GATEWAY_MACRO = "Gateway";
private final static String SERVICEID_MACRO = "ServiceId";
private final static String VEEID_MACRO="VmId";
private final static String DOMAIN_MACRO = "Domain";
private final static String MONITORINGCHANNEL_MACRO = "MonitoringChannel";
private final static String PRECEDENTTIERENTRYPOINT_MACRO = "PrecedentTierEntryPoint";
private final static String NOIP_TOKEN = "nullIP";
private final static String NOPRECEDENTTIERENTTYPOINT_TOKEN = "nullEP";
private final static Logger log = LoggerFactory.getLogger(OVFEnvironmentUtils.class);
public static String macroReplacement (String value,
int instanceNumber,
String domain,
String serviceId,
String veeId,
String monitoringChannel,
HashMap<String,ArrayList<String>> ips,
HashMap<String, String> netmasks,
HashMap<String, String> dnsServers,
HashMap<String, String> gateways,
HashMap<String, HashMap<String, String> > entryPoints,
HashMap<String, HashMap<String,String>> registeredAliasIPs)
throws IPNotFoundException,
DNSServerNotFoundException,
NetmaskNotFoundException,
GatewayNotFoundException,
PrecedentTierEntryPointNotFoundException,
NotEnoughIPsInPoolException,
PoolNameNotFoundException {
/* FIXME: the current implementation is limited to just one macro per property value. E.g.,
* the following can not be used:
*
* ovf:value="http://@IP(net)/app/@ServiceId/"
*
* In order to overcome this limitation a sequential processing ('if' after 'if', instead
* of using 'else if', could be used)*/
if (value.contains("@"+IP_MACRO))
{
String prefix = "@" + IP_MACRO + "(";
String macroValue = value.substring(value.indexOf(prefix)+prefix.length(),value.indexOf(")"));
/* Two possibilities to take into account: @IP(net) or @IP(net,alias). Note that
* alias = "" in the case @IP(net) is used */
String network;
String alias = "";
StringTokenizer macroValueTokenizer = new StringTokenizer(macroValue,",");
network = macroValueTokenizer.nextToken();
if (macroValueTokenizer.hasMoreElements()) {
alias = macroValueTokenizer.nextToken();
}
log.debug("IP@ = " + network);
if (ips != null) {
/* Is there any IP already used for that alias? In positive case, take it.
* In negative case, get one from the pool for that network, then register
* it in the alias register hash */
String ip;
if ((registeredAliasIPs.get(network) != null) && (registeredAliasIPs.get(network).get(alias)) != null) {
ip = registeredAliasIPs.get(network).get(alias);
}
else {
ArrayList<String> pool = (ArrayList<String>)ips.get(network);
if (pool!=null)
{
if (pool.size()>0)
{
ip = pool.get(0);
pool.remove(0);
}
else
{
final String msg = "Not enough IP in pool for network '" + network + "'";
throw new NotEnoughIPsInPoolException(msg);
}
}
else
{
final String msg = "Pool name for network '" + network + "' not found";
throw new PoolNameNotFoundException(msg);
}
/* It has been already created the hashmap for the network? */
if (registeredAliasIPs.get(network) != null) {
HashMap<String,String> aliasHm = registeredAliasIPs.get(network);
aliasHm.put(alias, ip);
registeredAliasIPs.put(network, aliasHm);
}
else {
/* Create the hashmap fof the network, then add the alias */
HashMap<String,String> aliasHm = new HashMap<String,String>();
aliasHm.put(alias, ip);
registeredAliasIPs.put(network, aliasHm);
}
}
return value.replace(value.substring(value.indexOf(prefix),value.indexOf(")")+1), ip);
}
else {
return value.replace(value.substring(value.indexOf(prefix),value.indexOf(")")+1), NOIP_TOKEN);
}
}
else if (value.contains("@"+ID_MACRO))
{
String prefix = "@" + ID_MACRO + "(";
int offset = Integer.parseInt(value.substring(value.indexOf(prefix)+prefix.length(),value.indexOf(")")));
int index = offset + instanceNumber;
log.debug("Id@ = " + index);
return value.replace(value.substring(value.indexOf(prefix),value.indexOf(")")+1), String.valueOf(index));
}
else if (value.contains("@"+NETMASK_MACRO))
{
String prefix = "@" + NETMASK_MACRO + "(";
String network = value.substring(value.indexOf(prefix)+prefix.length(),value.indexOf(")"));
String mask = netmasks.get(network);
log.debug("Netmask@ = " + mask);
if (mask!=null)
{
return value.replace(value.substring(value.indexOf(prefix),value.indexOf(")")+1), mask);
}
else
{
final String msg = "DNSserver for network '" + network + "' not found";
throw new NetmaskNotFoundException(msg);
}
}
else if (value.contains("@"+DNSSERVER_MACRO))
{
String prefix = "@" + DNSSERVER_MACRO + "(";
String network = value.substring(value.indexOf(prefix)+prefix.length(),value.indexOf(")"));
String dnsserver = dnsServers.get(network);
log.debug("DNSServer@ = " + dnsserver);
if (dnsserver!=null)
{
return value.replace(value.substring(value.indexOf(prefix),value.indexOf(")")+1), dnsserver);
}
else
{
final String msg = "DNSserver for network '" + network + "' not found";
throw new DNSServerNotFoundException(msg);
}
}
else if (value.contains("@"+GATEWAY_MACRO))
{
String prefix = "@" + GATEWAY_MACRO + "(";
String network = value.substring(value.indexOf(prefix)+prefix.length(),value.indexOf(")"));
String gw = gateways.get(network);
log.debug("Gateway@ = " + gw);
if (gw!=null)
{
return value.replace(value.substring(value.indexOf(prefix),value.indexOf(")")+1), gw);
}
else
{
final String msg = "Gateway for network '" + network + "' not found";
throw new GatewayNotFoundException(msg);
}
}
else if (value.contains("@"+PRECEDENTTIERENTRYPOINT_MACRO))
{
String prefix = "@" + PRECEDENTTIERENTRYPOINT_MACRO + "(";
String network = value.substring(value.indexOf(prefix)+prefix.length(),value.indexOf(","));
// the +1 is for the ','
log.info("Data precedent " + prefix + network);
String vs = value.substring(value.indexOf(prefix)+prefix.length()+1+network.length(),value.indexOf(")"));
if (entryPoints != null) {
HashMap<String, String> entryPointsPerNetwork = (HashMap<String, String>)entryPoints.get(network);
if (entryPointsPerNetwork == null) {
final String msg = "PrecendentTierEntryPoint for network '" + network + "' not found";
throw new PrecedentTierEntryPointNotFoundException(msg);
}
String ep = entryPointsPerNetwork.get(vs);
log.debug("PrecendentTierEntryPoint@ = " + ep);
if (ep!=null)
{
return value.replace(value.substring(value.indexOf(prefix),value.indexOf(")")+1), ep);
}
else
{
final String msg = "PrecendentTierEntryPoint for VirtualSystem '"+vs+"' in network '" + network + "' not found";
throw new PrecedentTierEntryPointNotFoundException(msg);
}
}
else {
return value.replace(value.substring(value.indexOf(prefix),value.indexOf(")")+1), NOPRECEDENTTIERENTTYPOINT_TOKEN);
}
}
else if (value.contains("@" + DOMAIN_MACRO))
{
String prefix = "@" + DOMAIN_MACRO;
return value.replace(prefix, domain);
}
else if (value.contains("@" + SERVICEID_MACRO))
{
String prefix = "@" + SERVICEID_MACRO;
return value.replace(prefix,serviceId);
}
else if (value.contains("@" + VEEID_MACRO))
{
String prefix = "@" + VEEID_MACRO;
System.out.println ("VEE MACRO" + prefix);
return value.replace(prefix,veeId);
}
else if (value.contains("@" + MONITORINGCHANNEL_MACRO))
{
String prefix = "@" + MONITORINGCHANNEL_MACRO;
return value.replace(prefix,monitoringChannel);
}
else {
// Unknown cloudConfigurable @ macro: deal with it in the same way a a
// no-cloudConfigurable value: i.e. do nothing
// FIXME: raise exception?
return value;
}
}
}