I'm new in Ignite.net technology and trying to implement it with data persistence feature (using EF core 2.1 for my cache store classes).
I configure Ignite Configuration in this way
var cfg = new IgniteConfiguration
{
JvmDllPath = #"C:\Program Files\Java\jdk-11.0.1\bin\server\jvm.dll",
IsActiveOnStart = true,
ClientMode = false,
IgniteInstanceName = FirstValues.IgniteInstanceName,
WorkDirectory = #"C:\IGNITE_HOME\workspace",
GridName = Guid.NewGuid().ToString(),
DataStorageConfiguration = new DataStorageConfiguration()
{
DefaultDataRegionConfiguration = new DataRegionConfiguration()
{
PersistenceEnabled = true,
Name = "inMemoryRegion",
CheckpointPageBufferSize = 1024,
},
WriteThrottlingEnabled = true
},
BinaryConfiguration = new BinaryConfiguration()
{
CompactFooter = true,
KeepDeserialized = false
}
};
cfg = FirstValues.cacheConfigAll(cfg);
cfg = FirstValues.setupDiscoveryConfig(cfg);
Environment.SetEnvironmentVariable("IGNITE_H2_DEBUG_CONSOLE", "true");
var ignite = Ignition.TryGetIgnite() ?? Ignition.Start(cfg);
ignite.SetActive(true);
var s = ignite.GetCluster().ForServers().GetNodes();
ignite.GetCluster().SetBaselineTopology(s);
these two classes implemented in this way
public static IgniteConfiguration cacheConfigAll(IgniteConfiguration config)
{
CacheConfiguration cacheConfigVehicle = VehicleCacheCfgReader();
CacheConfiguration cacheConfigDevice = DeviceCacheCfgReader();
CacheConfiguration cacheConfigZone = ZoneCacheCfgReader();
CacheConfiguration cacheConfigGeoPoint = GeoPointCacheCfgReader();
List<CacheConfiguration> list = new List<CacheConfiguration>();
list.Add(cacheConfigVehicle);
list.Add(cacheConfigDevice);
list.Add(cacheConfigZone);
list.Add(cacheConfigGeoPoint);
config.CacheConfiguration = list;
return config;
}
public static IgniteConfiguration setupDiscoveryConfig(IgniteConfiguration config)
{
TcpDiscoverySpi spi = new TcpDiscoverySpi();
var ipFinder = new TcpDiscoveryMulticastIpFinder();
((TcpDiscoveryMulticastIpFinder)ipFinder).MulticastGroup = "228.10.10.157";
ipFinder.LocalAddress = "127.0.0.1";
spi.IpFinder = ipFinder;
config.DiscoverySpi = spi;
return config;
}
and here it is one of my cache stores (All of them are similar to each other)
public static CacheConfiguration VehicleCacheCfgReader()
{
return new CacheConfiguration(FmsCacheName)
{
Name = VehicleCacheName,
SqlSchema = "PUBLIC",
Backups = 1,
CacheMode = CacheMode.Partitioned,
WriteSynchronizationMode = CacheWriteSynchronizationMode.FullSync,
AtomicityMode = CacheAtomicityMode.Atomic,
WriteBehindEnabled = true,
CacheStoreFactory = new VehicleCacheStoreFactory(),
ReadThrough = true,
WriteThrough = true,
KeepBinaryInStore = false,
DataRegionName = "inMemoryRegion",
QueryEntities = new List<QueryEntity>()
{
new QueryEntity()
{
TableName = VehicleCacheName,
KeyType = typeof(string),
KeyFieldName = "Id",
ValueType = typeof(Vehicle),
Fields = new List<QueryField>() {
new QueryField("Id", typeof(string)) { IsKeyField = true },
new QueryField("Name", typeof(string)),
new QueryField("ZoneId", typeof(string))
}
}
}
};
}
and now when i'm starting my ignite I have this error
class org.apache.ignite.IgniteException: An error occurred during cache configuration loading from file [file=C:\IGNITE_HOME\workspace\db\node00-f9d2cd52-ad3e-4304-92ce-92f6585cb0a6\cache-DeviceCache1212201883355PM\cache_data.dat]
at org.
apache.ignite.internal.util.IgniteUtils.convertException(IgniteUtils.java:1025)
at org.apache.ignite.internal.processors.platform.PlatformAbstractBootstrap.start(PlatformAbstractBootstrap.java:48)
at org.apache.ignite.internal.processors.platform.PlatformIgnition.start(PlatformIgnition.java:75)
Caused by: class org.apache.ignite.IgniteCheckedException: An error occurred during cache configuration loading from file [file=C:\IGNITE_HOME\workspace\db\node00-f9d2cd52-ad3e-4304-92ce-92f6585cb0a6\cache-DeviceCache1212201883355PM\cache_data.dat]
at org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.readCacheData(FilePageStoreManager.java:843)
at org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.readCacheConfigurations(FilePageStoreManager.java:785)
at org.apache.ignite.internal.processors.cache.GridCacheProcessor.addCacheOnJoinFromConfig(GridCacheProcessor.java:888)
at org.apache.ignite.internal.processors.cache.GridCacheProcessor.startCachesOnStart(GridCacheProcessor.java:753)
at org.apache.ignite.internal.processors.cache.GridCacheProcessor.onReadyForRead(GridCacheProcessor.java:737)
at org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager.notifyMetastorageReadyForRead(GridCacheDatabaseSharedManager.java:396)
at org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager.readMetastore(GridCacheDatabaseSharedManager.java:662)
at org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager.notifyMetaStorageSubscribersOnReadyForRead(GridCacheDatabaseSharedManager.java:4610)
at org.apache.ignite.internal.IgniteKernal.start(IgniteKernal.java:1048)
at org.apache.ignite.internal.IgnitionEx$IgniteNamedInstance.start0(IgnitionEx.java:2038)
at org.apache.ignite.internal.IgnitionEx$IgniteNamedInstance.start(IgnitionEx.java:1730)
at org.apache.ignite.internal.IgnitionEx.start0(IgnitionEx.java:1158)
at org.apache.ignite.internal.IgnitionEx.start(IgnitionEx.java:656)
at org.apache.ignite.internal.processors.platform.PlatformAbstractBootstrap.start(PlatformAbstractBootstrap.java:43)
... 1 more
Caused by: class org.apache.ignite.IgniteCheckedException: Failed to deserialize object with given class loader: jdk.internal.loader.ClassLoaders$AppClassLoader#14514713
at org.apache.ignite.marshaller.jdk.JdkMarshaller.unmarshal0(JdkMarshaller.java:147)
at org.apache.ignite.marshaller.AbstractNodeNameAwareMarshaller.unmarshal(AbstractNodeNameAwareMarshaller.java:94)
at org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.readCacheData(FilePageStoreManager.java:839)
... 14 more
Caused by: java.lang.IllegalArgumentException: Ignite instance name thread local must be set or this method should be accessed under org.apache.ignite.thread.IgniteThread
at org.apache.ignite.internal.IgnitionEx.localIgnite(IgnitionEx.java:1411)
at org.apache.ignite.internal.binary.GridBinaryMarshaller.threadLocalContext(GridBinaryMarshaller.java:398)
at org.apache.ignite.internal.binary.BinaryObjectImpl.readExternal(BinaryObjectImpl.java:695)
at java.base/java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:2136)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2085)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
at java.base/java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2355)
at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2249)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2087)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
at java.base/java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2355)
at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2249)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2087)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
at java.base/java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2355)
at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2249)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2087)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:430)
at org.apache.ignite.marshaller.jdk.JdkMarshaller.unmarshal0(JdkMarshaller.java:139)
My previous guess was wrong, as it seems.
There is an issue IGNITE-10451, I'm afraid it will mean you will not be able to use Cache Store together with Persistence when using Ignite.Net.
If you remove CacheStore definition on all caches and remove work dir, it will start without errors.
After some search I've decided to implement cache store mechanism by myself.
As you can see In Ignite architecture we should access to storage database when we do not have data on cache, thus I write some codes in my get functions to read data and write them on cache when its cache does not have asked data.
Related
I'm trying to import a solution via a small c# console app. I am able to import the solution but I am not able to StageAndUpgradeRequest. I get an error "The [mysolution] solution doesn’t have an upgrade that is ready to be applied."
Here is my code:
ImportSolutionRequest importSolutionRequest = new ImportSolutionRequest()
{
CustomizationFile = data,
ImportJobId = importId,
OverwriteUnmanagedCustomizations = true,
ConvertToManaged = true,
SkipProductUpdateDependencies = false,
//SolutionParameters = new Microsoft.Xrm.Sdk.SolutionParameter
//{
// StageSolutionUploadId = Guid.NewGuid()
//}
};
var importResponse = (ImportSolutionResponse)svc.Execute(importSolutionRequest);
Console.WriteLine(importResponse.ResponseName);
var request = new DeleteAndPromoteRequest
{
UniqueName = "JEuvin",
};
var applyResponse = (DeleteAndPromoteResponse)svc.Execute(request);
Console.WriteLine(applyResponse.SolutionId);
Console.WriteLine("Imported Successfully");
What am I missing?
Currently I am trying to write tests for Dynamics CRM app using Fake XRM Easy. This code gives me an error.
var executeMultiple = new ExecuteMultipleRequest
{
Settings = new ExecuteMultipleSettings
{
ContinueOnError = true,
ReturnResponses = true
},
Requests = new OrganizationRequestCollection()
};
executeMultiple.Requests.AddRange(this.requestBag.Select(x => x.request));
try
{
var batchResponse = (ExecuteMultipleResponse)this.orgService.Execute(executeMultiple);
foreach (var response in batchResponse.Responses)
{
this.requestsPerformedByServiceCounter++;
this.OnResponseReceived(new ResponseReceivedEventArgs
{
Fault = response.Fault,
RequestIndex = response.RequestIndex,
Response = response.Response,
Request = this.requestBag[response.RequestIndex].request,
Identifier = this.requestBag[response.RequestIndex].identifier,
TotalRequestsPerformed = this.requestsPerformedByServiceCounter,
});
}
this.requestBag.Clear();
This method is calling upper method
foreach (var company in this.companies)
{
EntityReference existedAccountRef = null;
if (!string.IsNullOrEmpty(company.id.ToString()))
{
var existedAccount = this.crmService.IsCompanyExistInCrm(company.id);
existedAccountRef = existedAccount != null ? existedAccount.ToEntityReference() : null;
}
if (existedAccountRef != null)
{
bulkExecutionService.Update(new Account()
{
AccountId = existedAccountRef.Id,
Name = company.name,
odx_Bank_Account_Number = company.bank_account_number,
// odx_Company_share_Capital = company.company_share_capital, todo
odx_Is_Foreign = company.is_foreign,
odx_KRS = company.krs,
odx_Legal_form = company.legal_form,
odx_NIP = company.nip,
odx_Paynow_Created_at = company.created_at,
odx_Paynow_Modified_at = company.modified_at,
odx_PaynowID = company.id,
odx_pkd = company.pkd,
odx_regon = company.regon,
odx_Vat_EU = company.vat_eu
}, company.id);
}
else
{
bulkExecutionService.Create(new Account()
{
Name = company.name,
odx_Bank_Account_Number = company.bank_account_number,
// odx_Company_share_Capital = company.company_share_capital, todo
odx_Is_Foreign = company.is_foreign,
odx_KRS = company.krs,
odx_Legal_form = company.legal_form,
odx_NIP = company.nip,
odx_Paynow_Created_at = company.created_at,
odx_Paynow_Modified_at = company.modified_at,
odx_PaynowID = company.id,
odx_pkd = company.pkd,
odx_regon = company.regon,
odx_Vat_EU = company.vat_eu
}, company.id);
}
}
bulkExecutionService.FinalizeExecutor();
Error I am getting is in this line:
var batchResponse = (ExecuteMultipleResponse)this.orgService.Execute(executeMultiple);
FakeXrmEasy.Abstractions.Exceptions.PullRequestException: 'Exception: The organization request type 'Microsoft.Xrm.Sdk.Messages.ExecuteMultipleRequest' is not yet supported...
To be honest i don't know what can I do with it.
Did you try installing FakeXrmEasy.Messages package?
FakeXrmEasy v2 or later now use a modular architecture.
Create, Retrieve, Update, Delete, Upsert, Associate or Dissasociate messages live in the FakeXrmEasy.Core package but other messages live now in that dedicated FakeXrmEasy.Messages package.
This is covered in the Installing section of the docs site
EDIT: After installing the Messages package, please also add a reference to one of the fake message executors in the middleware setup like this:
.AddFakeMessageExecutors(Assembly.GetAssembly(typeof(AddListMembersListRequestExecutor)))
This will use reflection to find any other fake messages. You can call that method as many times as you want in case you have your own messages in your own assembly. This is possible since the 2.1.x and 3.1.x versions.
Please check the release notes here:
https://dynamicsvalue.github.io/fake-xrm-easy-docs/releases/2x/2.1.1/
I am using AWSSDK.dll version 2.1.3.0
i am trying to add new lifecycle rule
here is the code
IAmazonS3 _s3Client = new AmazonS3Client("A*****************Z", "a*************b", bucketRegion);
// Retrieve current configuration
var configuration = _s3Client.GetLifecycleConfiguration(
new GetLifecycleConfigurationRequest
{
BucketName = bucketName
}).Configuration;
//Adding new Rule
configuration.Rules.Add(new LifecycleRule
{
Id = "ATam",
Prefix = "ATam/PanCake QA/Avaniti/",
Expiration = new LifecycleRuleExpiration()
{
Days = 3650
},
Transition = new LifecycleTransition()
{
StorageClass = S3StorageClass.Glacier,
Days = 14
},
Status = LifecycleRuleStatus.Enabled,
});
PutLifecycleConfigurationRequest request = new PutLifecycleConfigurationRequest
{
BucketName = bucketName,
Configuration = configuration
};
var response = _s3Client.PutLifecycleConfiguration(request);
But i am getting this exception
An unhandled exception of type 'Amazon.S3.AmazonS3Exception' occurred in AWSSDK.dll Additional information: The XML you provided was not well-formed or did not validate against our published schema
Can anyone let me know where i am going wrong.
Thanks in advance
You need to set LifecycleTransition properties Days and Storage Class.
LifecycleConfiguration newConfiguration = new LifecycleConfiguration
{
Rules = new List<LifecycleRule>
{
new LifecycleRule
{
Id = "some id here",
Filter = new LifecycleFilter()
{
LifecycleFilterPredicate = new LifecyclePrefixPredicate()
{
}
},
Status = LifecycleRuleStatus.Enabled,
Transitions = new List<LifecycleTransition>
{
new LifecycleTransition
{
Days = 0,
StorageClass = S3StorageClass.Glacier
}
},
Expiration = new LifecycleRuleExpiration()
{
Days = 1
}
}
}
};
My team is developing an application that needs to clone existing templates in our vSphere environment. We're using VMware.Vim in a C# application to do this. We're replacing an already existing implementation that uses PowerShell.
Below is the code that is throwing the error. We are eventually going to load balance based on memory usage, but currently we are selecting the host by random. That's why there is some extra code with collecting all of the hosts and then picking one.
When it gets to CloneVM_Task, an exception with the message 'The operation is not allowed in the current state.' is thrown. The exception doesn't give me much to work with and I can't find any useful logs in vSphere. vSphere just says "An error prevented the virtual machine from being cloned" in the events log. We're using version 6.7. I'm new to VMWare, so any help is appreciated. Their documentation is lacking, to say the least.
public async void CreateVirtualMachineAsync(NewVMRequest newVMRequest)
{
var appliance = await _applianceService.GetAppliance(newVMRequest.Appliance);
var vimClient = new VimClientImpl
{
IgnoreServerCertificateErrors = true, ServiceUrl = appliance.ServiceUrl
};
vimClient.Login(appliance.User, appliance.Password);
var datacenter = GetDatacenter(vimClient);
var hostCollection = GetListOfHosts(vimClient, datacenter);
var randomHost = PickRandomHost(hostCollection);
var sourceVm = GetSelectedVm(vimClient, newVMRequest);
if (sourceVm == null)
{
_logger.LogDebug($"Could not find virtual machine {newVMRequest.Source} to use for template");
_logger.LogError($"Could not find virtual machine {newVMRequest.Source} to use for template", null);
return;
}
var selectedStore = ConnectToDataStore(vimClient);
var cluster = GetCluster(vimClient);
var mySpec = CreateCloneSpec(selectedStore, randomHost, cluster, sourceVm);
vimClient.WaitForTask(sourceVm.CloneVM_Task(sourceVm.Parent, newVMRequest.Name, mySpec));
vimClient.Disconnect();
}
private VirtualMachineCloneSpec CreateCloneSpec(Datastore selectedStore, ManagedObjectReference randomHost, ClusterComputeResource cluster, VirtualMachine sourceVm)
{
var mySpec = new VirtualMachineCloneSpec
{
Location = new VirtualMachineRelocateSpec
{
Datastore = selectedStore.MoRef,
Transform = VirtualMachineRelocateTransformation.sparse,
Host = randomHost,
Pool = cluster.ResourcePool
},
Config = new VirtualMachineConfigSpec()
};
var networkDevice = new VirtualDevice();
foreach (var vDevice in sourceVm.Config.Hardware.Device)
{
if (vDevice.DeviceInfo.Label.Contains("Network"))
{
networkDevice = vDevice;
}
}
var devSpec = new VirtualDeviceConfigSpec
{
Device = networkDevice, FileOperation = VirtualDeviceConfigSpecFileOperation.create
};
mySpec.Config.DeviceChange = new[] { devSpec };
return mySpec;
}
private Datacenter GetDatacenter(VimClient vimClient)
{
var entities = vimClient.FindEntityViews(typeof(Datacenter), null, null, null);
return (Datacenter)entities.First();
}
private List<ManagedObjectReference> GetListOfHosts(VimClient vimClient, Datacenter datacenter)
{
var hostCollection = new List<ManagedObjectReference>();
var hostFolderMoRef = datacenter.HostFolder;
var hostFolder = (Folder)vimClient.GetView(hostFolderMoRef, null);
var childEntityMoRefs = hostFolder.ChildEntity;
foreach (var childEntityMoRef in childEntityMoRefs)
{
var thisCluster = (ClusterComputeResource)vimClient.GetView(childEntityMoRef, null);
var clusterHostMoRefs = thisCluster.Host;
foreach (var clusterHostMoRef in clusterHostMoRefs)
{
var hostSystem = (HostSystem)vimClient.GetView(clusterHostMoRef, null);
hostCollection.Add(hostSystem.MoRef);
}
}
return hostCollection;
}
private ManagedObjectReference PickRandomHost(List<ManagedObjectReference> hostCollection)
{
var rand = new Random();
return hostCollection[rand.Next(0, hostCollection.Count)];
}
private VirtualMachine GetSelectedVm(VimClient vimClient, NewVMRequest newVMRequest)
{
var filter = new NameValueCollection
{
{"name", newVMRequest.Source},
{"Config.Template", newVMRequest.UseTemplate.ToString().ToLower()}
};
var entityViews = vimClient.FindEntityViews(typeof(VMware.Vim.VirtualMachine), null, filter, null);
if (entityViews.Count == 0)
{
return null;
}
return (VirtualMachine)vimClient.FindEntityViews(typeof(VMware.Vim.VirtualMachine), null, filter, null).First();
}
private Datastore ConnectToDataStore(VimClient vimClient)
{
var myDs = vimClient.FindEntityView(typeof(Datastore), null, null /*dsFilter*/, null);
return (Datastore)myDs;
}
private ClusterComputeResource GetCluster(VimClient vimClient)
{
var appClusters = vimClient.FindEntityViews(typeof(ClusterComputeResource), null, null, null);
return (ClusterComputeResource)appClusters?.FirstOrDefault();
}
For the most part, your code looks good. I would suggest changing the spec file and using the least possible information to create a clone from existing template. Once you have success, you can add more details and see if that errors out.
Start off with this and see if this gets you going.
private VirtualMachineCloneSpec CreateCloneSpec(Datastore selectedStore, ManagedObjectReference randomHost, ClusterComputeResource cluster, VirtualMachine sourceVm)
{
var mySpec = new VirtualMachineCloneSpec
{
Location = new VirtualMachineRelocateSpec
{
Datastore = selectedStore.MoRef,
Host = randomHost,
Pool = cluster.ResourcePool
},
PowerOn = false,
Template = false
};
return mySpec;
}
If the above goes through, then add the VirtualMachineRelocateTransformation to transform your thick VM as thin VM and network connections as needed.
Assume I already have purchased a domain example.com with IP address 203.0.113.2. Using C# and the The Amazon Web Services SDK for .NET 2.0.2.2, I'd like to create a static website using a custom domain using Amazon S3 and Route 53. The manual process is described in the Amazon documentation.
When trying to create an alias, I get an exception with the message:
Invalid XML ; cvc-complex-type.2.4.a: Invalid content was found starting with element 'AliasTarget'.
One of '{"https://route53.amazonaws.com/doc/2012-12-12/":ResourceRecords}' is expected.
First, I created or updated a bucket (e.g. "example.com") in Amazon S3. If it already existed, content is deleted.
using (var client = AWSClientFactory.CreateAmazonS3Client(RegionEndpoint.USWest1))
{
if (!S3BucketExists(name, client))
{
client.PutBucket(new PutBucketRequest
{
BucketName = name,
BucketRegion = S3Region.USW1,
CannedACL = S3CannedACL.PublicRead
});
}
else
{
var request = new ListObjectsRequest
{
BucketName = name
};
var objects = client.ListObjects(request).S3Objects;
foreach (var o in objects)
{
client.DeleteObject(new DeleteObjectRequest
{
BucketName = name,
Key = o.Key
});
}
client.PutACL(new PutACLRequest
{
CannedACL = S3CannedACL.PublicRead,
BucketName = name
});
}
client.PutBucketWebsite(new PutBucketWebsiteRequest
{
BucketName = name,
WebsiteConfiguration = new WebsiteConfiguration
{
ErrorDocument = "404.html",
IndexDocumentSuffix = "index.html"
}
});
CreateObject(name, client, "index.html", "text/html", "<p>The site is under maintenance</p>");
CreateObject(name, client, "404.html", "text/html", "<p>Not Found</p>");
}
S3BucketExists returns whether a bucket exist or not, and CreateObject creates a simple page and uploads it to the bucket. Its omitted for brevity sake. I'm able to connect to the S3 hosted site without any problems.
Then I use the Route 53 API to update an existing hosted zone or create one for "example.com". All resources, except for the SOA and NS entries are deleted.
using (var client = AWSClientFactory.CreateAmazonRoute53Client())
{
var hostedZone = FindHostedZoneByName(client, domainName);
if (hostedZone != null)
{
var resourceRecordSets = client.ListResourceRecordSets(new ListResourceRecordSetsRequest
{
HostedZoneId = hostedZone.Id,
});
bool hasElements = false;
var request1 = new ChangeResourceRecordSetsRequest
{
HostedZoneId = hostedZone.Id,
ChangeBatch = new ChangeBatch
{
Changes = new List<Change>()
}
};
foreach (var resourceRecordSet in resourceRecordSets.ResourceRecordSets)
{
switch (resourceRecordSet.Type)
{
case "SOA":
case "NS":
continue;
}
var change = new Change
{
Action = "DELETE",
ResourceRecordSet = resourceRecordSet
};
request1.ChangeBatch.Changes.Add(change);
hasElements = true;
}
if (hasElements)
{
var response = client.ChangeResourceRecordSets(request1);
}
}
else
{
hostedZone = CreateHostedZone(client, domainName);
}
var hostedZoneId = hostedZone.Id;
var request = new ChangeResourceRecordSetsRequest
{
HostedZoneId = hostedZoneId,
ChangeBatch = new ChangeBatch
{
Changes = new List<Change>
{
new Change
{
Action = ChangeAction.CREATE,
ResourceRecordSet = new ResourceRecordSet
{
Name = GetQualifiedName(domainName),
Type = RRType.A,
TTL = 300,
AliasTarget = new AliasTarget()
{
HostedZoneId = "Z2F56UZL2M1ACD",
DNSName = "s3-website-us-west-1.amazonaws.com.",
},
},
},
}
}
};
client.ChangeResourceRecordSets(request);
}
The hosted zone id ("Z2F56UZL2M1ACD") and DNS names ("s3-website-us-west-1.amazonaws.com.") are public knowledge and documented on Amazon's website.
The call to ChangeResourceRecordSets throws the exception. I created an empty ResourceRecords list, with a A record of "203.0.113.2", but have not had any luck creating an alias.
That said, I can manually create the alias to the Amazon S3 site afterwards using the "Route 53 Management Console". I'm sure it's something small I'm missing.
After re-reading the documentation, it turns out that one cannot specify the TTL when specifying an alias. The following change works. Replace the code that creates an instance of ChangeResourceRecordSetsRequest to the following:
var request = new ChangeResourceRecordSetsRequest
{
HostedZoneId = hostedZoneId,
ChangeBatch = new ChangeBatch
{
Changes = new List<Change>
{
new Change
{
Action = ChangeAction.CREATE,
ResourceRecordSet = new ResourceRecordSet
{
Name = GetQualifiedName(domainName),
Type = RRType.A,
AliasTarget = new AliasTarget
{
HostedZoneId = "Z2F56UZL2M1ACD",
DNSName = "s3-website-us-west-1.amazonaws.com.",
EvaluateTargetHealth = false,
},
},
},
}
}
};
The difference was evident when the output produced by System.Net tracing was compared to the request specified in the Amazon example.