org.dasein.cloud.aws.platform.RDS Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dasein-cloud-aws Show documentation
Show all versions of dasein-cloud-aws Show documentation
Implementation of the Dasein Cloud API for AWS.
/**
* Copyright (C) 2009-2015 Dell, Inc.
* See annotations for authorship information
*
* ====================================================================
* 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 org.dasein.cloud.aws.platform;
import java.util.*;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.dasein.cloud.*;
import org.dasein.cloud.aws.AWSCloud;
import org.dasein.cloud.aws.compute.EC2Exception;
import org.dasein.cloud.aws.compute.EC2Method;
import org.dasein.cloud.aws.model.DatabaseProductDefinition;
import org.dasein.cloud.aws.model.DatabaseProvider;
import org.dasein.cloud.aws.model.DatabaseRegion;
import org.dasein.cloud.identity.ServiceAction;
import org.dasein.cloud.network.Direction;
import org.dasein.cloud.network.FirewallRule;
import org.dasein.cloud.network.FirewallSupport;
import org.dasein.cloud.network.Protocol;
import org.dasein.cloud.network.RuleTargetType;
import org.dasein.cloud.platform.*;
import static org.dasein.cloud.platform.DatabaseEngine.*;
import org.dasein.cloud.util.APITrace;
import org.dasein.util.CalendarWrapper;
import org.dasein.util.Jiterator;
import org.dasein.util.JiteratorPopulator;
import org.dasein.util.PopulatorThread;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import static org.dasein.cloud.platform.DatabaseLicenseModel.*;
/**
* AWS RDS Support
*
* @author George Reese
* @author Stas Maksimov
* @version 2014.08 deprecated methods moved to capabilities
* @since ?
*/
public class RDS extends AbstractRelationalDatabaseSupport {
static private final Logger logger = AWSCloud.getLogger(RDS.class);
static public final String SERVICE_ID = "rds";
static public final String AUTHORIZE_DB_SECURITY_GROUP_INGRESS = "AuthorizeDBSecurityGroupIngress";
static public final String CREATE_DB_INSTANCE = "CreateDBInstance";
static public final String CREATE_DB_PARAMETER_GROUP = "CreateDBParameterGroup";
static public final String CREATE_DB_SECURITY_GROUP = "CreateDBSecurityGroup";
static public final String CREATE_DB_SNAPSHOT = "CreateDBSnapshot";
static public final String DELETE_DB_INSTANCE = "DeleteDBInstance";
static public final String DELETE_DB_PARAMETER_GROUP = "DeleteDBParameterGroup";
static public final String DELETE_DB_SECURITY_GROUP = "DeleteDBSecurityGroup";
static public final String DELETE_DB_SNAPSHOT = "DeleteDBSnapshot";
static public final String DESCRIBE_DB_ENGINE_VERSIONS = "DescribeDBEngineVersions";
static public final String DESCRIBE_DB_INSTANCES = "DescribeDBInstances";
static public final String DESCRIBE_ENGINE_DEFAULT_PARAMETERS = "DescribeEngineDefaultParameters";
static public final String DESCRIBE_DB_PARAMETER_GROUPS = "DescribeDBParameterGroups";
static public final String DESCRIBE_DB_PARAMETERS = "DescribeDBParameters";
static public final String DESCRIBE_DB_SECURITY_GROUPS = "DescribeDBSecurityGroups";
static public final String DESCRIBE_DB_SNAPSHOTS = "DescribeDBSnapshots";
static public final String DESCRIBE_DB_EVENTS = "DescribeDBEvents";
static public final String MODIFY_DB_INSTANCE = "ModifyDBInstance";
static public final String MODIFY_DB_PARAMETER_GROUP = "ModifyDBParameterGroup";
static public final String REBOOT_DB_INSTANCE = "RebootDBInstance";
static public final String RESET_DB_PARAMETER_GROUP = "ResetDBParameterGroup";
static public final String RESTORE_DB_INSTANCE_FROM_SNAPSHOT = "RestoreDBInstanceFromDBSnapshot";
static public final String RESTORE_DB_INSTANCE_TO_TIME = "RestoreDBInstanceToPointInTime";
static public final String REVOKE_DB_SECURITY_GROUP_INGRESS = "RevokeDBSecurityGroupIngress";
static private final String AWS_ENGINE_MYSQL = "MySQL";
static private final String AWS_ENGINE_POSTGRES = "postgres";
static private final String AWS_ENGINE_ORACLE_SE1 = "oracle-se1";
static private final String AWS_ENGINE_ORACLE_SE = "oracle-se";
static private final String AWS_ENGINE_ORACLE_EE = "oracle-ee";
static private final String AWS_ENGINE_SQLSERVER_EE = "sqlserver-ee";
static private final String AWS_ENGINE_SQLSERVER_SE = "sqlserver-se";
static private final String AWS_ENGINE_SQLSERVER_EX = "sqlserver-ex";
static private final String AWS_ENGINE_SQLSERVER_WEB = "sqlserver-web";
static public @Nonnull ServiceAction[] asRDSServiceAction(@Nonnull String action) {
return null; // TODO: implement me
}
private volatile transient RDSCapabilities capabilities;
RDS(AWSCloud provider) {
super(provider);
}
/**
* Use this to authorize with security groups in EC2-Classic
* @param groupName
* @param sourceCidr
* @throws CloudException
* @throws InternalException
*/
private void authorizeClassicDbSecurityGroup(String groupName, String sourceCidr) throws CloudException, InternalException {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), AUTHORIZE_DB_SECURITY_GROUP_INGRESS);
parameters.put("DBSecurityGroupName", groupName);
parameters.put("CIDRIP", sourceCidr);
EC2Method method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
method.invoke();
}
catch( EC2Exception e ) {
String code = e.getCode();
if( code != null && code.equals("AuthorizationAlreadyExists") ) {
return;
}
throw new CloudException(e);
}
}
public void addAccess(String providerDatabaseId, String sourceCidr) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.addAccess");
try {
Database db = getDatabase(providerDatabaseId);
Iterator securityGroups = getSecurityGroups(providerDatabaseId).iterator();
String groupName;
if( !securityGroups.hasNext() ) {
// FIXME: not sure we need to do this. a db should always have a security group right from the start
groupName = createSecurityGroup(providerDatabaseId);
setSecurityGroup(providerDatabaseId, groupName);
}
else {
groupName = securityGroups.next();
}
String ec2Type = getProvider().getDataCenterServices().isRegionEC2VPC(getProvider().getContext().getRegionId());
if(ec2Type.equals(AWSCloud.PLATFORM_EC2)) {
authorizeClassicDbSecurityGroup(groupName, sourceCidr);
}
else if( getProvider().hasNetworkServices() && getProvider().getNetworkServices().hasFirewallSupport() ) {
FirewallSupport firewallSupport = getProvider().getNetworkServices().getFirewallSupport();
firewallSupport.authorize(groupName, sourceCidr, Protocol.TCP, db.getHostPort(), db.getHostPort());
}
}
finally {
APITrace.end();
}
}
/**
* Formats a time window as hh24:mi-hh24:mi or ddd:hh24:mi-ddd:hh24:mi
* @param window
* @param includeDays must be false for PreferredBackupWindow parameter
* @return formatted time window text representation
*/
private String getWindowString(TimeWindow window, boolean includeDays) {
StringBuilder str = new StringBuilder();
if( includeDays ) {
if( window.getStartDayOfWeek() == null ) {
str.append("*");
}
else {
str.append(window.getStartDayOfWeek().getShortString());
}
str.append(":");
}
str.append(String.format("%02d:%02d", window.getStartHour(), window.getStartMinute()));
str.append("-");
if( includeDays ) {
if( window.getEndDayOfWeek() == null ) {
str.append("*");
}
else {
str.append(window.getEndDayOfWeek().getShortString());
}
str.append(":");
}
str.append(String.format("%02d:%02d", window.getEndHour(), window.getEndMinute()));
return str.toString();
}
@Override
public void alterDatabase(String providerDatabaseId, boolean applyImmediately, String productSize, int storageInGigabytes, String configurationId, String newAdminUser, String newAdminPassword, int newPort, int snapshotRetentionInDays, TimeWindow preferredMaintenanceWindow, TimeWindow preferredBackupWindow) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.alterDatabase");
try {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), MODIFY_DB_INSTANCE);
EC2Method method;
parameters.put("DBInstanceIdentifier", providerDatabaseId);
parameters.put("ApplyImmediately", String.valueOf(applyImmediately));
if( configurationId != null ) {
parameters.put("DBParameterGroupName", configurationId);
}
if( preferredMaintenanceWindow != null ) {
String window = getWindowString(preferredMaintenanceWindow, true);
parameters.put("PreferredMaintenanceWindow", window);
}
if( preferredBackupWindow != null ) {
String window = getWindowString(preferredBackupWindow, false);
parameters.put("PreferredBackupWindow", window);
}
if( newAdminPassword != null ) {
parameters.put("MasterUserPassword", newAdminPassword);
}
if( storageInGigabytes > 0 ) {
parameters.put("AllocatedStorage", String.valueOf(storageInGigabytes));
}
if( productSize != null ) {
parameters.put("DBInstanceClass", productSize);
}
if( snapshotRetentionInDays > -1 ) {
parameters.put("BackupRetentionPeriod", String.valueOf(snapshotRetentionInDays));
}
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
}
}
finally {
APITrace.end();
}
}
/**
*
* @param groupName
* @return groupName if successful
* @throws CloudException
* @throws InternalException
*/
private String createSecurityGroup(String groupName) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.createSecurityGroup");
try {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), CREATE_DB_SECURITY_GROUP);
EC2Method method;
parameters.put("DBSecurityGroupName", groupName);
parameters.put("DBSecurityGroupDescription", "Auto-generated DB security group for " + groupName);
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
method.invoke();
}
catch( EC2Exception e ) {
String code = e.getCode();
if( code != null && code.equals("DBSecurityGroupAlreadyExists") ) {
return groupName;
}
throw new CloudException(e);
}
return groupName;
}
finally {
APITrace.end();
}
}
@Override
public String createFromScratch(String databaseName, DatabaseProduct product, String engineVersion, String withAdminUser, String withAdminPassword, int hostPort) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.createFromScratch");
try {
Map parameters;
String id = toIdentifier(databaseName);
EC2Method method;
NodeList blocks;
Document doc;
if( engineVersion == null ) {
engineVersion = getDefaultVersion(product.getEngine());
}
int size = product.getStorageInGigabytes();
if( size < 5 ) {
size = 5;
}
parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), CREATE_DB_INSTANCE);
parameters.put("DBInstanceIdentifier", id);
parameters.put("AllocatedStorage", String.valueOf(size));
parameters.put("DBInstanceClass", product.getProductSize());
parameters.put("Engine", getEngineString(product.getEngine()));
parameters.put("EngineVersion", engineVersion);
parameters.put("MasterUsername", withAdminUser);
parameters.put("MasterUserPassword", withAdminPassword);
parameters.put("Port", String.valueOf(hostPort));
if( !isSQLServer(product.getEngine()) ) {
String instanceName = toInstanceName(databaseName, product.getEngine());
parameters.put("DBName", instanceName);
}
String ec2Type = getProvider().getDataCenterServices().isRegionEC2VPC(getProvider().getContext().getRegionId());
if(ec2Type.equals(AWSCloud.PLATFORM_EC2)){
String securityGroupId = createSecurityGroup(id);
parameters.put("DBSecurityGroups.member.1", securityGroupId);
}
// TODO: refactor into a toLicense() method
String license = "general-public-license";
switch (product.getLicenseModel()) {
case BRING_YOUR_OWN_LICENSE:
license = "bring-your-own-license";
break;
case LICENSE_INCLUDED:
license = "license-included";
break;
case POSTGRESQL_LICENSE:
license = "postgresql-license";
break;
}
parameters.put("LicenseModel", license);
if( product.isHighAvailability() ) {
parameters.put("MultiAZ", "true");
}
else if( product.getProviderDataCenterId() != null ) {
// set az if not empty, otherwise the region's default is used
parameters.put("AvailabilityZone", product.getProviderDataCenterId());
}
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
doc = method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
}
blocks = doc.getElementsByTagName("DBInstanceIdentifier");
if( blocks.getLength() > 0 ) {
String dbId = blocks.item(0).getFirstChild().getNodeValue().trim();
// Set tags
ArrayList tags = new ArrayList();
tags.add(new Tag("Name", databaseName));
getProvider().createTags(SERVICE_ID, "arn:aws:rds:" + getProvider().getContext().getRegionId() + ":" + getProvider().getContext().getAccountNumber().replace("-", "") +":db:" + dbId , tags.toArray(new Tag[tags.size()]));
return dbId;
}
return null;
}
finally {
APITrace.end();
}
}
public String createFromLatest(String databaseName, String providerDatabaseId, String productSize, String providerDataCenterId, int hostPort) throws InternalException, CloudException {
APITrace.begin(getProvider(), "RDBMS.createFromLatest");
try {
Map parameters;
String id = toIdentifier(databaseName);
EC2Method method;
NodeList blocks;
Document doc;
parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), RESTORE_DB_INSTANCE_TO_TIME);
parameters.put("SourceDBInstanceIdentifier", providerDatabaseId);
parameters.put("UseLatestRestorableTime", "true"); // booleans should be lowercase, as per xsd1.1
parameters.put("TargetDBInstanceIdentifier", id);
parameters.put("DBInstanceClass", productSize);
parameters.put("Port", String.valueOf(hostPort));
if( providerDataCenterId == null ) {
parameters.put("MultiAZ", "true");
}
else {
parameters.put("AvailabilityZone", providerDataCenterId);
parameters.put("MultiAZ", "false");
}
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
doc = method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
}
blocks = doc.getElementsByTagName("DBInstanceIdentifier");
if( blocks.getLength() > 0 ) {
ArrayList tags = new ArrayList();
tags.add(new Tag("Name", databaseName));
getProvider().createTags(SERVICE_ID, "arn:aws:rds:" + getProvider().getContext().getRegionId() + ":" + getProvider().getContext().getAccountNumber().replace("-", "") +":db:" + id, tags.toArray(new Tag[tags.size()]));
return id;
}
return null;
}
finally {
APITrace.end();
}
}
public String createFromSnapshot(String databaseName, String providerDatabaseId, String providerDbSnapshotId, String productSize, String providerDataCenterId, int hostPort) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.createFromSnapshot");
try {
Map parameters;
String id = toIdentifier(databaseName);
EC2Method method;
NodeList blocks;
Document doc;
parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), RESTORE_DB_INSTANCE_FROM_SNAPSHOT);
parameters.put("DBSnapshotIdentifier", providerDbSnapshotId);
parameters.put("DBInstanceIdentifier", id);
parameters.put("DBInstanceClass", productSize);
parameters.put("Port", String.valueOf(hostPort));
if( providerDataCenterId == null ) {
parameters.put("MultiAZ", "true");
}
else {
parameters.put("AvailabilityZone", providerDataCenterId);
parameters.put("MultiAZ", "false");
}
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
doc = method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
}
blocks = doc.getElementsByTagName("DBInstanceIdentifier");
if( blocks.getLength() > 0 ) {
ArrayList tags = new ArrayList();
tags.add(new Tag("Name", databaseName));
getProvider().createTags(SERVICE_ID, "arn:aws:rds:" + getProvider().getContext().getRegionId() + ":" + getProvider().getContext().getAccountNumber().replace("-", "") +":db:" + id, tags.toArray(new Tag[tags.size()]));
return id;
}
return null;
}
finally {
APITrace.end();
}
}
public String createFromTimestamp(String databaseName, String providerDatabaseId, long beforeTimestamp, String productSize, String providerDataCenterId, int hostPort) throws InternalException, CloudException {
APITrace.begin(getProvider(), "RDBMS.createFromTimestamp");
try {
Map parameters;
String id = toIdentifier(databaseName);
EC2Method method;
NodeList blocks;
Document doc;
parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), RESTORE_DB_INSTANCE_TO_TIME);
parameters.put("SourceDBInstanceIdentifier", providerDatabaseId);
parameters.put("RestoreTime", getProvider().getTimestamp(beforeTimestamp, false));
parameters.put("TargetDBInstanceIdentifier", id);
parameters.put("DBInstanceClass", productSize);
parameters.put("Port", String.valueOf(hostPort));
if( providerDataCenterId == null ) {
parameters.put("MultiAZ", "true");
}
else {
parameters.put("AvailabilityZone", providerDataCenterId);
parameters.put("MultiAZ", "false");
}
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
doc = method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
}
blocks = doc.getElementsByTagName("DBInstanceIdentifier");
if( blocks.getLength() > 0 ) {
ArrayList tags = new ArrayList();
tags.add(new Tag("Name", databaseName));
getProvider().createTags(SERVICE_ID, "arn:aws:rds:" + getProvider().getContext().getRegionId() + ":" + getProvider().getContext().getAccountNumber().replace("-", "") +":db:" + id, tags.toArray(new Tag[tags.size()]));
return id;
}
return null;
}
finally {
APITrace.end();
}
}
@Override
public @Nonnull RelationalDatabaseCapabilities getCapabilities() throws InternalException, CloudException {
if( capabilities == null ) {
capabilities = new RDSCapabilities(getProvider());
}
return capabilities;
}
public DatabaseConfiguration getConfiguration(String providerConfigurationId) throws CloudException, InternalException {
if( providerConfigurationId == null ) {
return null;
}
PopulatorThread populator;
final String id = providerConfigurationId;
getProvider().hold();
populator = new PopulatorThread(new JiteratorPopulator() {
public void populate(Jiterator iterator) throws CloudException, InternalException {
try {
populateConfigurationList(id, iterator);
}
finally {
getProvider().release();
}
}
});
populator.populate();
Iterator it = populator.getResult().iterator();
if( it.hasNext() ) {
return it.next();
}
return null;
}
public Database getDatabase(String providerDatabaseId) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.getDatabase");
try {
if( providerDatabaseId == null ) {
return null;
}
for( Database database : listDatabases(providerDatabaseId) ) {
if( database.getProviderDatabaseId().equals(providerDatabaseId) ) {
return database;
}
}
return null;
}
finally {
APITrace.end();
}
}
static private volatile List engines = null;
@Override
public Iterable getDatabaseEngines() {
if( engines == null ) {
engines = Arrays.asList(
DatabaseEngine.MYSQL,
DatabaseEngine.ORACLE_EE,
DatabaseEngine.ORACLE_SE,
DatabaseEngine.ORACLE_SE1,
DatabaseEngine.POSTGRES,
DatabaseEngine.SQLSERVER_EE,
DatabaseEngine.SQLSERVER_EX,
DatabaseEngine.SQLSERVER_SE,
DatabaseEngine.SQLSERVER_WEB
);
}
return engines;
}
static private volatile Map defaultVersions = new HashMap();
static private volatile Map> engineVersions = new HashMap>();
@Override
public String getDefaultVersion(DatabaseEngine forEngine) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.getDefaultVersion");
try {
String version = defaultVersions.get(forEngine);
if( version == null ) {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), DESCRIBE_DB_ENGINE_VERSIONS);
EC2Method method;
Document doc;
parameters.put("Engine", getEngineString(forEngine));
parameters.put("DefaultOnly", "true");
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
doc = method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
};
NodeList blocks = doc.getElementsByTagName("DBEngineVersions");
for( int i=0; i getSupportedVersions(DatabaseEngine forEngine) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.getSupportedVersions");
try {
Collection versions = engineVersions.get(forEngine);
if( versions == null ) {
ArrayList list = new ArrayList();
String marker = null;
do {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), DESCRIBE_DB_ENGINE_VERSIONS);
EC2Method method;
Document doc;
parameters.put("Engine", getEngineString(forEngine));
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
doc = method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
}
marker = null;
NodeList blocks;
blocks = doc.getElementsByTagName("Marker");
if( blocks.getLength() > 0 ) {
for( int i=0; i listDatabaseProducts( DatabaseEngine engine ) throws CloudException, InternalException {
List products = new ArrayList();
DatabaseProvider databaseProvider = DatabaseProvider.fromFile("/org/dasein/cloud/aws/dbproducts.json", "AWS");
org.dasein.cloud.aws.model.DatabaseEngine databaseEngine = databaseProvider.findEngine(getEngineString(engine));
if( databaseEngine != null ) {
for ( DatabaseRegion region : databaseEngine.getRegions() ) {
if( region.getName().equalsIgnoreCase( getProvider().getContext().getRegionId()) ) {
for( org.dasein.cloud.aws.model.DatabaseProduct databaseProduct : region.getProducts() ) {
DatabaseProduct product = new DatabaseProduct(databaseProduct.getName());
product.setEngine(engine);
product.setHighAvailability(databaseProduct.isHighAvailability());
product.setStandardHourlyRate(databaseProduct.getHourlyRate());
product.setStandardIoRate(databaseProduct.getIoRate());
product.setStandardStorageRate(databaseProduct.getStorageRate());
DatabaseLicenseModel lic = GENERAL_PUBLIC_LICENSE;
if( "included".equalsIgnoreCase(databaseProduct.getLicense())) {
lic = LICENSE_INCLUDED;
} else if( "byol".equalsIgnoreCase(databaseProduct.getLicense())) {
lic = BRING_YOUR_OWN_LICENSE;
} else if( "postgres".equalsIgnoreCase(databaseProduct.getLicense())) {
lic = POSTGRESQL_LICENSE;
}
product.setLicenseModel(lic);
product.setCurrency(databaseProduct.getCurrency());
DatabaseProductDefinition def = databaseProvider.findProductDefinition(databaseProduct.getName());
if( def != null) {
product.setName(String.format("%.2fGB RAM, %d CPU, %s Network Performance", def.getMemory(), def.getvCpus(), def.getNetworkPerformance()));
}
product.setStorageInGigabytes(databaseProduct.getMinStorage());
products.add(product);
}
}
}
}
return products;
}
private DayOfWeek getDay(String str) {
if( str.equalsIgnoreCase("Sun") ) {
return DayOfWeek.SUNDAY;
}
else if( str.equalsIgnoreCase("Mon") ) {
return DayOfWeek.MONDAY;
}
else if( str.equalsIgnoreCase("Tue") ) {
return DayOfWeek.TUESDAY;
}
else if( str.equalsIgnoreCase("Wed") ) {
return DayOfWeek.WEDNESDAY;
}
else if( str.equalsIgnoreCase("Thu") ) {
return DayOfWeek.THURSDAY;
}
else if( str.equalsIgnoreCase("Fri") ) {
return DayOfWeek.FRIDAY;
}
else if( str.equalsIgnoreCase("Sat") ) {
return DayOfWeek.SATURDAY;
}
return null;
}
private TimeWindow getTimeWindow(String start, String end) {
String[] parts = start.split(":");
int startHour = 0, endHour = 0;
int startMinute = 0, endMinute = 0;
DayOfWeek startDay = null, endDay = null;
if( parts.length < 3 ) {
if( parts.length < 2 ) {
try {
startHour = Integer.parseInt(start);
}
catch( NumberFormatException ignore ) {
// ignore
}
}
else {
try {
startHour = Integer.parseInt(parts[0]);
}
catch( NumberFormatException ignore ) {
// ignore
}
try {
startMinute = Integer.parseInt(parts[1]);
}
catch( NumberFormatException e ) {
// ignore
}
}
}
else {
startDay = getDay(parts[0]);
try {
startHour = Integer.parseInt(parts[1]);
}
catch( NumberFormatException ignore ) {
// ignore
}
try {
startMinute = Integer.parseInt(parts[2]);
}
catch( NumberFormatException e ) {
// ignore
}
}
parts = end.split(":");
if( parts.length < 3 ) {
if( parts.length < 2 ) {
try {
endHour = Integer.parseInt(start);
}
catch( NumberFormatException ignore ) {
// ignore
}
}
else {
try {
endHour = Integer.parseInt(parts[0]);
}
catch( NumberFormatException ignore ) {
// ignore
}
try {
endMinute = Integer.parseInt(parts[1]);
}
catch( NumberFormatException e ) {
// ignore
}
}
}
else {
endDay = getDay(parts[0]);
try {
endHour = Integer.parseInt(parts[1]);
}
catch( NumberFormatException ignore ) {
// ignore
}
try {
endMinute = Integer.parseInt(parts[2]);
}
catch( NumberFormatException e ) {
// ignore
}
}
TimeWindow window = new TimeWindow();
window.setStartDayOfWeek(startDay);
window.setStartHour(startHour);
window.setStartMinute(startMinute);
window.setEndDayOfWeek(endDay);
window.setEndHour(endHour);
window.setEndMinute(endMinute);
return window;
}
/**
* Get Amazon-specific engine name
* @param engine database engine
* @return Amazon-spefic engine name, returns 'MySQL' if engine was null.
*/
private String getEngineString(@Nullable DatabaseEngine engine) {
if( engine == null ) {
return AWS_ENGINE_MYSQL;
}
switch( engine ) {
case ORACLE_SE1: return AWS_ENGINE_ORACLE_SE1;
case ORACLE_SE: return AWS_ENGINE_ORACLE_SE;
case ORACLE_EE: return AWS_ENGINE_ORACLE_EE;
case SQLSERVER_SE: return AWS_ENGINE_SQLSERVER_SE;
case SQLSERVER_EE: return AWS_ENGINE_SQLSERVER_EE;
case SQLSERVER_EX: return AWS_ENGINE_SQLSERVER_EX;
case SQLSERVER_WEB: return AWS_ENGINE_SQLSERVER_WEB;
case POSTGRES: return AWS_ENGINE_POSTGRES;
case MYSQL:
default: return AWS_ENGINE_MYSQL;
}
}
@Deprecated
public String getProviderTermForDatabase(Locale locale) {
try {
return getCapabilities().getProviderTermForDatabase(locale);
} catch( InternalException e ) {
} catch( CloudException e ) {
}
return "database"; // legacy
}
@Deprecated
public String getProviderTermForSnapshot(Locale locale) {
try {
return getCapabilities().getProviderTermForSnapshot(locale);
} catch( InternalException e ) {
} catch( CloudException e ) {
}
return "snapshot"; // legacy
}
private String getRDSUrl() throws InternalException, CloudException {
//noinspection ConstantConditions
return ("https://rds." + getProvider().getContext().getRegionId() + ".amazonaws.com");
}
private Iterable getSecurityGroups(String databaseId) throws CloudException, InternalException {
PopulatorThread populator;
final String dbId = databaseId;
getProvider().hold();
populator = new PopulatorThread(new JiteratorPopulator() {
public void populate(Jiterator iterator) throws CloudException, InternalException {
try {
populateSecurityGroupIds(dbId, iterator);
}
finally {
getProvider().release();
}
}
});
populator.populate();
return populator.getResult();
}
public DatabaseSnapshot getSnapshot(String providerDbSnapshotId) throws CloudException, InternalException {
if( providerDbSnapshotId == null ) {
return null;
}
PopulatorThread populator;
final String id = providerDbSnapshotId;
getProvider().hold();
populator = new PopulatorThread(new JiteratorPopulator() {
public void populate(Jiterator iterator) throws CloudException, InternalException {
try {
populateSnapshotList(id, null, iterator);
}
finally {
getProvider().release();
}
}
});
populator.populate();
Iterator it = populator.getResult().iterator();
if( it.hasNext() ) {
return it.next();
}
return null;
}
public boolean isSubscribed() throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.isSubscribed");
try {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), DESCRIBE_DB_INSTANCES);
EC2Method method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
method.invoke();
return true;
}
catch( EC2Exception e ) {
if( e.getStatus() == HttpServletResponse.SC_UNAUTHORIZED || e.getStatus() == HttpServletResponse.SC_FORBIDDEN ) {
return false;
}
String code = e.getCode();
if( code != null && (code.equals("SubscriptionCheckFailed") || code.equals("AuthFailure") || code.equals("SignatureDoesNotMatch") || code.equals("InvalidClientTokenId") || code.equals("OptInRequired")) ) {
return false;
}
logger.warn(e.getSummary());
if( logger.isDebugEnabled() ) {
e.printStackTrace();
}
throw new CloudException(e);
}
}
finally {
APITrace.end();
}
}
public Iterable listAccess(String toProviderDatabaseId) throws CloudException, InternalException {
PopulatorThread idPopulator, accessPopulator;
final String dbId = toProviderDatabaseId;
getProvider().hold();
idPopulator = new PopulatorThread(new JiteratorPopulator() {
public void populate(Jiterator iterator) throws CloudException, InternalException {
try {
populateSecurityGroupIds(dbId, iterator);
}
finally {
getProvider().release();
}
}
});
idPopulator.populate();
final Iterable ids = idPopulator.getResult();
String ec2Type = getProvider().getDataCenterServices().isRegionEC2VPC(getProvider().getContext().getRegionId());
if(ec2Type.equals(AWSCloud.PLATFORM_EC2)) {
getProvider().hold();
accessPopulator = new PopulatorThread(new JiteratorPopulator() {
public void populate(Jiterator iterator) throws CloudException, InternalException {
try {
for( String id : ids ) {
populateAccess(id, iterator);
}
}
finally {
getProvider().release();
}
}
});
accessPopulator.populate();
return accessPopulator.getResult();
}
else {
List cidrs = new ArrayList();
if( getProvider().hasNetworkServices() && getProvider().getNetworkServices().hasFirewallSupport() ) {
for( String id : ids ) {
for( FirewallRule rule : getProvider().getNetworkServices().getFirewallSupport().getRules(id) ) {
// FIXME: We need to be able to include GLOBAL rule targets too, but they don't have the CIDR
if( rule.getDirection().equals(Direction.INGRESS) && rule.getSourceEndpoint().getRuleTargetType().equals(RuleTargetType.CIDR) ) {
cidrs.add(rule.getSourceEndpoint().getCidr());
}
}
}
}
return cidrs;
}
}
public Iterable listConfigurations() throws CloudException, InternalException {
PopulatorThread populator;
populator = new PopulatorThread(new JiteratorPopulator() {
public void populate(Jiterator iterator) throws CloudException, InternalException {
populateConfigurationList(null, iterator);
}
});
populator.populate();
return populator.getResult();
}
@Override
public @Nonnull Iterable listDatabaseStatus() throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.listDatabaseStatus");
try {
ArrayList list = new ArrayList();
String marker = null;
do {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), DESCRIBE_DB_INSTANCES);
EC2Method method;
NodeList blocks;
Document doc;
if( marker != null ) {
parameters.put("Marker", marker);
}
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
doc = method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
}
marker = null;
blocks = doc.getElementsByTagName("Marker");
if( blocks.getLength() > 0 ) {
for( int i=0; i listDatabases() throws CloudException, InternalException {
return listDatabases(null);
}
private Iterable listDatabases(String targetId) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.listDatabases");
try {
ArrayList list = new ArrayList();
String marker = null;
do {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), DESCRIBE_DB_INSTANCES);
EC2Method method;
NodeList blocks;
Document doc;
if( marker != null ) {
parameters.put("Marker", marker);
}
if( targetId != null ) {
parameters.put("DBInstanceIdentifier", targetId);
}
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
doc = method.invoke();
}
catch( EC2Exception e ) {
if( targetId != null ) {
String code = e.getCode();
if( code != null && code.equals("DBInstanceNotFound") || code.equals("InvalidParameterValue") ) {
return list;
}
}
throw new CloudException(e);
}
marker = null;
blocks = doc.getElementsByTagName("Marker");
if( blocks.getLength() > 0 ) {
for( int i=0; i listParameters(String forProviderConfigurationId) throws CloudException, InternalException {
PopulatorThread populator;
final String id = forProviderConfigurationId;
getProvider().hold();
populator = new PopulatorThread(new JiteratorPopulator() {
public void populate(Jiterator iterator) throws CloudException, InternalException {
try {
populateParameterList(id, null, iterator);
}
finally {
getProvider().release();
}
}
});
populator.populate();
return populator.getResult();
}
public Collection listDefaultParameters(DatabaseEngine engine) throws CloudException, InternalException {
PopulatorThread populator;
final DatabaseEngine dbEngine = engine;
getProvider().hold();
populator = new PopulatorThread(new JiteratorPopulator() {
public void populate(Jiterator iterator) throws CloudException, InternalException {
try {
populateParameterList(null, dbEngine, iterator);
}
finally {
getProvider().release();
}
}
});
populator.populate();
return populator.getResult();
}
public Iterable listSnapshots(String forOptionalProviderDatabaseId) throws CloudException, InternalException {
PopulatorThread populator;
getProvider().hold();
final String id = (forOptionalProviderDatabaseId == null ? null : forOptionalProviderDatabaseId);
populator = new PopulatorThread(new JiteratorPopulator() {
public void populate(Jiterator iterator) throws CloudException, InternalException {
try {
populateSnapshotList(null, id, iterator);
}
finally {
getProvider().release();
}
}
});
populator.populate();
return populator.getResult();
}
@Override
public @Nonnull String[] mapServiceAction(@Nonnull ServiceAction action) {
return new String[0]; // TODO: implement me
}
private void populateAccess(String securityGroupId, Jiterator iterator) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.populateDBSGAccess");
try {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), DESCRIBE_DB_SECURITY_GROUPS);
EC2Method method;
NodeList blocks;
Document doc;
parameters.put("DBSecurityGroupName", securityGroupId);
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
doc = method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
}
blocks = doc.getElementsByTagName("DBSecurityGroups");
for( int i=0; i iterator) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.populateConfigurationList");
try {
String marker = null;
do {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), DESCRIBE_DB_PARAMETER_GROUPS);
EC2Method method;
NodeList blocks;
Document doc;
if( marker != null ) {
parameters.put("Marker", marker);
}
if( targetId != null ) {
parameters.put("DBParameterGroupName", targetId);
}
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
doc = method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
}
marker = null;
blocks = doc.getElementsByTagName("Marker");
if( blocks.getLength() > 0 ) {
for( int i=0; i iterator) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.populateParameterList");
try {
String marker = null;
do {
Map parameters;
EC2Method method;
NodeList blocks;
Document doc;
if( cfgId != null ) {
parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), DESCRIBE_DB_PARAMETERS);
parameters.put("DBParameterGroupName", cfgId);
}
else {
parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), DESCRIBE_ENGINE_DEFAULT_PARAMETERS);
parameters.put("Engine", getEngineString(engine));
}
if( marker != null ) {
parameters.put("Marker", marker);
}
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
doc = method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
}
marker = null;
blocks = doc.getElementsByTagName("Marker");
if( blocks.getLength() > 0 ) {
for( int i=0; i iterator) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.populateDBSecurityGroups");
try {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), DESCRIBE_DB_INSTANCES);
EC2Method method;
NodeList blocks;
Document doc;
parameters.put("DBInstanceIdentifier", providerDatabaseId);
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
doc = method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
}
blocks = doc.getElementsByTagName("DBInstances");
for( int i=0; i iterator) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.populateDBSnapshotList");
try {
String marker = null;
do {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), DESCRIBE_DB_SNAPSHOTS);
EC2Method method;
NodeList blocks;
Document doc;
if( marker != null ) {
parameters.put("Marker", marker);
}
if( snapshotId != null ) {
parameters.put("DBSnapshotIdentifier", snapshotId);
}
if( databaseId != null ) {
parameters.put("DBInstanceIdentifier", databaseId);
}
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
doc = method.invoke();
}
catch( EC2Exception e ) {
String code = e.getCode();
if( code != null && code.equals("DBSnapshotNotFound") ) {
return;
}
throw new CloudException(e);
}
marker = null;
blocks = doc.getElementsByTagName("Marker");
if( blocks.getLength() > 0 ) {
for( int i=0; i parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), DELETE_DB_PARAMETER_GROUP);
EC2Method method;
parameters.put("DBParameterGroupName", providerConfigurationId);
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
}
}
finally {
APITrace.end();
}
}
private void removeSecurityGroup(String securityGroupId) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.removeSecurityGroup");
try {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), DELETE_DB_SECURITY_GROUP);
EC2Method method;
parameters.put("DBSecurityGroupName", securityGroupId);
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
method.invoke();
}
catch( EC2Exception e ) {
throw e;
}
}
finally {
APITrace.end();
}
}
public void removeDatabase(String providerDatabaseId) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.removeDatabase");
try {
long timeout = System.currentTimeMillis() + (CalendarWrapper.MINUTE*10L);
Database db = getDatabase(providerDatabaseId);
while( timeout > System.currentTimeMillis() ) {
if( db == null || DatabaseState.DELETED.equals(db.getCurrentState()) ) {
return;
}
if( DatabaseState.AVAILABLE.equals(db.getCurrentState()) ) {
break;
}
try { Thread.sleep(15000L); }
catch( InterruptedException ignore ) { }
try { db = getDatabase(providerDatabaseId); }
catch( Throwable ignore ) { }
}
Iterable securityGroups = getSecurityGroups(providerDatabaseId);
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), DELETE_DB_INSTANCE);
EC2Method method;
parameters.put("DBInstanceIdentifier", providerDatabaseId);
parameters.put("FinalDBSnapshotIdentifier", providerDatabaseId + "-FINAL-" + System.currentTimeMillis());
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
method.invoke();
}
catch( EC2Exception e ) {
parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), DELETE_DB_INSTANCE);
parameters.put("DBInstanceIdentifier", providerDatabaseId);
parameters.put("SkipFinalSnapshot", "true");
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
method.invoke();
}
catch( EC2Exception again ) {
throw new CloudException(e);
}
}
try {
for( String securityGroupId : securityGroups ) {
if( securityGroupId.equals(providerDatabaseId) ) {
for( int i=0; i<3; i++ ) {
try {
removeSecurityGroup(securityGroupId);
break;
}
catch( EC2Exception e ) {
if (e.getProviderCode().equalsIgnoreCase("InvalidDBSecurityGroupState")) {
try { Thread.sleep(6000L); }
catch( InterruptedException ie ) { }
// ignore this because it means it is a shared security group
}
else throw new CloudException(e);
}
}
}
}
}
catch( Throwable t ) {
t.printStackTrace();
}
}
finally {
APITrace.end();
}
}
public void removeSnapshot(String providerSnapshotId) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.removeSnapshot");
try {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), DELETE_DB_SNAPSHOT);
EC2Method method;
parameters.put("DBSnapshotIdentifier", providerSnapshotId);
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
}
}
finally {
APITrace.end();
}
}
public void resetConfiguration(String providerConfigurationId, String ... params) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.resetConfiguration");
try {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), RESET_DB_PARAMETER_GROUP);
EC2Method method;
parameters.put("DBParameterGroupName", providerConfigurationId);
if( params == null || params.length < 1 ) {
parameters.put("ResetAllParameters", "True");
}
else {
int i = 0;
parameters.put("ResetAllParameters", "False");
for( String param : params ) {
i++;
parameters.put("Parameters.member." + i + ".ParameterName", param);
parameters.put("Parameters.member." + i + ".ApplyMethod", "pending-reboot");
}
}
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
}
}
finally {
APITrace.end();
}
}
public void restart(String providerDatabaseId, boolean blockUntilDone) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.restart");
try {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), REBOOT_DB_INSTANCE);
EC2Method method;
parameters.put("DBInstanceIdentifier", providerDatabaseId);
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
}
}
finally {
APITrace.end();
}
}
/**
* Use this to revoke access of security groups in EC2-Classic
* @param groupName
* @param sourceCidr
* @throws CloudException
* @throws InternalException
*/
private void revokeClassicDbSecurityGroup(String groupName, String sourceCidr) throws CloudException, InternalException {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), REVOKE_DB_SECURITY_GROUP_INGRESS);
parameters.put("CIDRIP", sourceCidr);
parameters.put("DBSecurityGroupName", groupName);
EC2Method method = new EC2Method(SERVICE_ID, getProvider(), parameters);
method.invoke();
}
public void revokeAccess(String providerDatabaseId, String sourceCidr) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.revokeAccess");
try {
EC2Exception error = null;
Database db = getDatabase(providerDatabaseId);
for( String securityGroup : getSecurityGroups(providerDatabaseId) ) {
try {
String ec2Type = getProvider().getDataCenterServices().isRegionEC2VPC(getProvider().getContext().getRegionId());
if( ec2Type.equals(AWSCloud.PLATFORM_EC2) ) {
revokeClassicDbSecurityGroup(securityGroup, sourceCidr);
}
else if( getProvider().hasNetworkServices() && getProvider().getNetworkServices().hasFirewallSupport() ) {
FirewallSupport firewallSupport = getProvider().getNetworkServices().getFirewallSupport();
firewallSupport.revoke(securityGroup, sourceCidr, Protocol.TCP, db.getHostPort(), db.getHostPort());
}
}
catch( EC2Exception e ) {
error = e;
}
}
if( error != null ) {
throw new CloudException(error);
}
}
finally {
APITrace.end();
}
}
public void updateConfiguration(String providerConfigurationId, ConfigurationParameter ... params) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.updateConfiguration");
try {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), MODIFY_DB_PARAMETER_GROUP);
EC2Method method;
parameters.put("DBParameterGroupName", providerConfigurationId);
int i = 0;
for( ConfigurationParameter param : params ) {
i++;
parameters.put("Parameters.member." + i + ".ParameterName", param.getKey());
parameters.put("Parameters.member." + i + ".ParameterValue", param.getParameter().toString());
parameters.put("Parameters.member." + i + ".ApplyMethod", param.isApplyImmediately() ? "immediate" : "pending-reboot");
if( i >= 20 ) {
break;
}
}
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
}
if( params.length > 20 ) {
ConfigurationParameter[] repeat = new ConfigurationParameter[params.length-20];
i = 0;
for( ; i parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), MODIFY_DB_INSTANCE);
EC2Method method;
parameters.put("DBInstanceIdentifier", id);
parameters.put("ApplyImmediately", "true");
String ec2Type = getProvider().getDataCenterServices().isRegionEC2VPC(getProvider().getContext().getRegionId());
if(ec2Type.equals(AWSCloud.PLATFORM_EC2)){
parameters.put("DBSecurityGroups.member.1", securityGroupId);
}
else {
parameters.put("VpcSecurityGroupIds.member.1", securityGroupId);
}
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
}
}
finally {
APITrace.end();
}
}
public DatabaseSnapshot snapshot(String providerDatabaseId, String name) throws CloudException, InternalException {
APITrace.begin(getProvider(), "RDBMS.snapshot");
try {
Map parameters = getProvider().getStandardRdsParameters(getProvider().getContext(), CREATE_DB_SNAPSHOT);
String id = toIdentifier(name);
EC2Method method;
parameters.put("DBSnapshotIdentifier", id);
parameters.put("DBInstanceIdentifier", providerDatabaseId);
method = new EC2Method(SERVICE_ID, getProvider(), parameters);
try {
method.invoke();
}
catch( EC2Exception e ) {
throw new CloudException(e);
}
return getSnapshot(id);
}
finally {
APITrace.end();
}
}
private DatabaseConfiguration toConfiguration(Node cfgNode) throws CloudException {
String id = null, cfgName = null, description = null;
DatabaseEngine engine = DatabaseEngine.MYSQL; //default
NodeList attrs = cfgNode.getChildNodes();
for( int i=0; i maxLength ) {
rawName = rawName.substring(0, maxLength);
}
if( rawName.length() < 1 ) {
return "x";
}
return rawName;
}
private String toIdentifier(String rawName) {
StringBuilder str = new StringBuilder();
if( rawName.length() < 1 ) {
return "x";
}
if( !Character.isLetter(rawName.charAt(0)) ) {
rawName = "db-" + rawName;
}
char last = '\0';
for( int i=0; i 63 ) {
rawName = rawName.substring(0,63);
}
while( rawName.charAt(rawName.length()-1) == '-' ) {
rawName = rawName.substring(0,rawName.length()-1);
}
if( rawName.length() < 1 ) {
return "x";
}
return rawName;
}
private ConfigurationParameter toParameter(Node pNode) throws CloudException {
ConfigurationParameter param = new ConfigurationParameter();
NodeList attrs = pNode.getChildNodes();
param.setModifiable(false);
param.setApplyImmediately(false);
for( int i=0; i