I am using ExecuteMultipleResponse method to insert 10 account records at a time using SSIS.
List<Entity> _Accounts = new List<Entity>();
// Check the batch size and process
public override void InputAccount_ProcessInput(InputAccountBuffer Buffer)
{
//List<int> personIDs = new List<int>();
int index = 0;
while (Buffer.NextRow())
{
_Accounts.Add(InputAccountFromBuffer(Buffer));
//personIDs.Add(int.Parse(Buffer.sPersonID));
index++;
if (index == 10)
{
ImportBatch();
index = 0;
}
}
ImportBatch();
}
private void ImportBatch()
{
if (_Accounts.Count > 0)
{
var multipleRequest = new ExecuteMultipleRequest()
{
Settings = new ExecuteMultipleSettings()
{
ContinueOnError = true,
ReturnResponses = true
},
Requests = new OrganizationRequestCollection()
};
foreach (var profContact in _Accounts)
{
CreateRequest reqCreate = new CreateRequest();
reqCreate.Target = profContact;
reqCreate.Parameters.Add("SuppressDuplicateDetection", false);
multipleRequest.Requests.Add(reqCreate);
}
ExecuteMultipleResponse multipleResponses = (ExecuteMultipleResponse)organizationservice.Execute(multipleRequest);
var responses = (ExecuteMultipleResponseItemCollection)multipleResponses.Results["Responses"];
foreach (var response in responses)
{
if (response.Fault != null)
{
// A fault has occurred, handle it here
}
else
{
// THIS IS WHERE I KNOW THE GUID VALUE EXIST.
}
}
//IEnumerator f = multipleResponses.Responses.GetEnumerator();
_Accounts.Clear();
}
}
Above code is working fine, however, I now need to read and store Guids from response to a List. This information is essential for the next step in the package. I know, if I am creating single record I can simply say,
Guid newRecord = _service.Create(account);
I even managed to get down to check if the response have 'Fault' or not and if it doesn't have fault then Guid value should exist in the response.
Running response.Response.Results.Values in QuickWatch shows me the guid but I just can't find a way to read it directly and store it as a Guid.
The guid of a created record should be stored in the OrganizationResponse which can be found inside the ExecuteMultipleResponseItem
Try the following to get the guid as a string:
string id = response.Response.Results["id"].ToString()
If it works as expected you should also be able to instantiate a guid, if needed:
Guid guid = new Guid(id);
Related
I am using Confluent.Kafka .NET client version 1.3.0. I would like to start consuming messages from a given time onwards.
To do so, I could use OffsetsForTimes to get the desired offset and Commit that offset for that partition:
private void SetOffset()
{
const string Topic = "myTopic";
const string BootstrapServers = "server1, server2";
var adminClient = new AdminClientBuilder(
new Dictionary<string, string>
{
{ "bootstrap.servers", BootstrapServers },
{ "security.protocol", "sasl_plaintext" },
{ "sasl.mechanisms", "PLAIN" },
{ "sasl.username", this.kafkaUsername },
{ "sasl.password", this.kafkaPassword }
}).Build();
var consumer = new ConsumerBuilder<byte[], byte[]>(
new Dictionary<string, string>
{
{ "bootstrap.servers", BootstrapServers },
{ "group.id", this.groupId },
{ "enable.auto.commit", "false" },
{ "security.protocol", "sasl_plaintext" },
{ "sasl.mechanisms", "PLAIN" },
{ "sasl.username", this.kafkaUsername },
{ "sasl.password", this.kafkaPassword }
}).Build();
// Timestamp to which the offset should be set to
var timeStamp = new DateTime(2020, 3, 1, 0, 0, 0, DateTimeKind.Utc);
var newOffsets = new List<TopicPartitionOffset>();
var metadata = adminClient.GetMetadata(Topic, TimeSpan.FromSeconds(30));
foreach (var topicMetadata in metadata.Topics)
{
if (topicMetadata.Topic == Topic)
{
foreach (var partitionMetadata in topicMetadata.Partitions.OrderBy(p => p.PartitionId))
{
var topicPartition = new TopicPartition(topicMetadata.Topic, partitionMetadata.PartitionId);
IEnumerable<TopicPartitionOffset> found = consumer.OffsetsForTimes(
new[] { new TopicPartitionTimestamp(topicPartition, new Timestamp(timeStamp, TimestampType.CreateTime)) },
TimeSpan.FromSeconds(5));
newOffsets.Add(new TopicPartitionOffset(topicPartition, new Offset(found.First().Offset)));
}
}
}
consumer.Commit(newOffsets);
// Consume messages
consumer.Subscribe(Topic);
var consumerResult = consumer.Consume();
// process message
//consumer.Commit(consumerResult);
}
This works fine if I want to skip messages and jump to a given offset if the offset to which I would like to jump is after the last committed message.
However, the above approach won't work if the given timestamp is before the timestamp of the last committed message. In the above code, if the timeStamp is before the timestamp of the last committed message, then OffsetsForTimes will return the offset of that last committed message + 1. Even if I manually set the offset to a lower offset, then consumer.Commit(newOffsets) seems to have no effect and I am getting the first uncommitted message when consuming.
Is there a way to achive this from the code?
You can do it if you assign to each partition and state the offset from which to start reading.
this is how you get the list of topic partitions:
public static List<TopicPartition> GetTopicPartitions(string bootstrapServers, string topicValue) {
var tp = new List<TopicPartition>();
using (var adminClient = new AdminClientBuilder(new AdminClientConfig { BootstrapServers = bootstrapServers }).Build()) {
var meta = adminClient.GetMetadata(TimeSpan.FromSeconds(20));
meta.Topics.ForEach(topic => {
if (topic.Topic == topicValue) {
foreach (PartitionMetadata partition in topic.Partitions) {
tp.Add(new TopicPartition(topic.Topic, partition.PartitionId));
}
}
});
}
return tp;
}
This is how you find the offset of a particular time:
List<TopicPartition> topic_partitions = frmMain.GetTopicPartitions(mBootstrapServers, txtTopic.Text);
using (var consumer = new ConsumerBuilder<Ignore, string>(cfg).Build()) {
consumer.Assign(topic_partitions);
List<TopicPartitionTimestamp> new_times = new List<TopicPartitionTimestamp>();
foreach (TopicPartition tp in topic_partitions) {
new_times.Add(new TopicPartitionTimestamp(tp, new Timestamp(dtpNewTime.Value)));
}
List<TopicPartitionOffset> seeked_offsets = consumer.OffsetsForTimes(new_times, TimeSpan.FromSeconds(40));
string s = "";
foreach (TopicPartitionOffset tpo in seeked_offsets) {
s += $"{tpo.TopicPartition}: {tpo.Offset.Value}\n";
}
Console.WriteLine(s);
consumer.Close();
}
This is how you consume by assigning to all topic partition and specific offsets:
using (var consumer =
new ConsumerBuilder<string, string>(config)
.SetErrorHandler((_, e) => Log($"Error: {e.Reason}"))
.Build()) {
consumer.Assign(seeked_offsets);
try {
while (true) {
try {
var r = consumer.Consume(cancellationToken);
// do something with r
} catch (ConsumeException e) {
//Log($"Consume error: {e.Error.Reason}");
}
}
} catch (OperationCanceledException) {
//Log("Closing consumer.");
consumer.Close();
}
}
The other option, if you insist in applying this to the consumer group, would be to reset the consumer group and use your code, or to create a new consumer group.
I'm not an expert but i'm going to try to explain how you could do it.
In first place, we have to mention subscribe and assign methods.
When you use subscribe, you pass a one or more topics. With this, a list of partitions of each topics are assigned to the consumer depending of the number of consumers in its group. A topic partition is an object formed by the topic name and the partition number.
consumer.Subscribe(Topic);
You can use assign to pass the partitions of which the consumer will read. This method does not use the consumer's group management functionality (where no need of group.id)
If i'm not wrong, in assign method you can specify the initial offset.
consumer.Assign(topicName, 0, new Offset(lastConsumedOffset));
consumer.Assign(topicPartition, new Offset(lastConsumedOffset));
Another option is to use seek() method to set the offset
consumer.Seek(topicPartitionOffset);
If you are going to mix subscribe and assign remember that you have to use unsubscribe before.
Another option, if you want to re-consume all the messages is create a
consumer in a new different consumer group.
EXAMPLE (TO REVIEW)
I'm leaving you and example for now, i will check it later.
I have done the example in java because i'm more familiar with it.
In this example, i don't use subscribe, i use assign.
First topic partitions are retrieved, we set a start datetime to read messages from, we create a map specifing that that datetime for each partition.
With the created map we get the offset of each partition on the specified datetime with offsetsForTimes method. With the offset of each partition we use seek to move to that offset on each partitions and finally we consume the messages.
I don't have time now to check the code, but i will do it.
I hope it helps.
AdminClient client = AdminClient.create(getAdminClientProperties());
KafkaConsumer<String, GenericRecord> consumer = new KafkaConsumer<String, GenericRecord>(
getConsumerProperties());
String TOPIC = "topic";
// get info of all partitions of a topic
List<PartitionInfo> partitionsInfo = consumer.partitionsFor(TOPIC);
// create TopicPartition list
Set<TopicPartition> partitions = new HashSet<>();
for (PartitionInfo p : partitionsInfo) {
partitions.add(new TopicPartition(p.topic(), p.partition()));
}
// Consumer will read from all partitions
consumer.assign(partitions);
DateTime timeToStartReadMessagesFrom = new DateTime(2020, 3, 1, 0, 0, 0);
Map<TopicPartition, Long> timestamps = new HashMap<>();
for (TopicPartition tp : partitions) {
timestamps.put(tp, timeToStartReadMessagesFrom.getMillis());
}
// get the offset for that time in each partition
Map<TopicPartition, OffsetAndTimestamp> offsets = consumer.offsetsForTimes(timestamps);
for (TopicPartition tp : partitions) {
consumer.seek(tp, offsets.get(tp).offset());
}
while (true) {
final ConsumerRecords<String, GenericRecord> consumerRecords = consumer.poll(1000);
// do something
break;
}
consumer.close();
System.out.println("DONE");
I wish to automate the transfer of ether to a list of people.
Assume the list is in a csv.
I wrote some code to automate the process.
class Program
{
int nonce = 0;
static void Main(string[] args)
{
var account = SetupAccount();
var recipients = ReadCsv();
var web3Init = GetConnection();
nonce = web3.Eth.Transactions.GetTransactionCount.SendRequestAsync(account.Address).Result;
//var recipients = new List<Records>() { new Records() { Value = 10000000000000000, Address = "0x5CC494843e3f4AC175A5e730c300b011FAbF2cEa" } };
foreach (var recipient in recipients)
{
try
{
var web3 = GetConnection();
var receipt = SendEther(account, recipient, web3).Result;
}
catch (System.Exception)
{
MessageBox.Show("Failed");
}
Thread.Sleep(30000);
}
}
private static async Task<TransactionReceipt> SendEther(Account account, Records recipient, Web3 web3)
{
var transactionPolling = web3.TransactionManager.TransactionReceiptService;
//var currentBalance = await web3.Eth.GetBalance.SendRequestAsync(account.Address);
//assumed client is mining already
//when sending a transaction using an Account, a raw transaction is signed and send using the private key
return await transactionPolling.SendRequestAndWaitForReceiptAsync(() =>
{
var transactionInput = new TransactionInput
{
From = account.Address,
//Gas = new HexBigInteger(25000),
GasPrice = new HexBigInteger(10 ^ 10),
To = recipient.Address,
Value = new HexBigInteger(new BigInteger(recipient.Value)),
Nonce = nonce
};
var txSigned = new Nethereum.Signer.TransactionSigner();
var signedTx = txSigned.SignTransaction(account.PrivateKey, transactionInput.To, transactionInput.Value, transactionInput.Nonce);
var transaction = new Nethereum.RPC.Eth.Transactions.EthSendRawTransaction(web3.Client);
nonce++;
return transaction.SendRequestAsync(signedTx);
});
}
private static Web3 GetConnection()
{
return new Web3("https://mainnet.infura.io");
}
private static Account SetupAccount()
{
var password = "#Password";
var accountFilePath = #"filePath";
return Account.LoadFromKeyStoreFile(accountFilePath, password);
}
private static List<Records> ReadCsv()
{
string filePath = #"C:\Users\Potti\source\repos\ConversionFiles\XrcfRecipients.csv";
if (File.Exists(filePath))
{
using (StreamReader stream = new StreamReader(filePath))
{
CsvReader reader = new CsvReader(stream, new Configuration
{
TrimOptions = TrimOptions.Trim,
HasHeaderRecord = true,
HeaderValidated = null
});
reader.Configuration.RegisterClassMap<RecordMapper>();
return reader.GetRecords<Records>().ToList();
}
}
else
{
return null;
}
}
}
class Records
{
public string Address { get; set; }
public decimal Value { get; set; }
}
sealed class RecordMapper : ClassMap<Records>
{
public RecordMapper()
{
Map(x => x.Address).Name("Address");
Map(x => x.Value).Name("Value");
}
}
How do i modify the process to execute all the transactions at once instead of waiting for each to complete? (Fire and forget)
Also, are there any security considerations of doing this?
What you are currently doing is waiting for each transaction to be mined. What you can do is the following:
var account = new Account("privateKey"); // or load it from your keystore file as you are doing.
var web3 = new Web3(account, "https://mainnet.infura.io");
First create a web3 instance using the same Account object, because we are using an account with a private key, Nethereum will sign your transactions offline before sending them.
Now using the TransactionManager, you can then send a transaction per each recepient
var transactionHashes = new List<string>();
foreach(var recepient in recepients){
var transactionInput = new TransactionInput
{
From = account.Address,
GasPrice = Web3.Convert.ToWei(1.5, UnitConversion.EthUnit.Gwei);,
To = recipient.Address,
Value = new HexBigInteger(new BigInteger(recipient.Value)),
};
var transactionHash = web3.Eth.TransactionManager.SendTransactionAsync(transactionInput);
transanctionHashes.Add(transactionHash);
}
Note that when Nethereum uses the same instance of an Account and TransactionManager (or Web3 in this scenario) it creates a default NonceMemoryService, so you don't need to keep track of your nonces (Transaction number), to sign the transaction.
Also I have done a conversion for the GasPrice from Gwei to Wei, as an example of Unit conversions, I assume that you already have converted to Wei the Ether amounts you are going to send.
Finally, another note, to further simplify this, there is an upcoming EtherTransferService which allows you to input Ether amounts and Gwei price amounts to avoid doing conversions. Also the gas price will be calculated for you, if not passed any parameter.
web3.Eth.GetEtherTransferService().TransferEtherAsync("toAddress", EtherAmount);
I have a scenario in CRM where I need to update existing accounts with their Vat and Registration number. There is well over 30 thousand accounts in the system. I am trying to update using the CRM SDK API but I am battling to figure out how to perform the actual update. The vat number and reg have been provided to me in a spreadsheet with their corresponding number, please note that the accounts are already in CRM so I just need to update the correct account with its Vat and Reg number, How can I do this in CRM, please advice on my code below:
public static void UpdateAllCRMAccountsWithVATAndRegistrationNumber(IOrganizationService service)
{
QueryExpression qe = new QueryExpression();
qe.EntityName = "account";
qe.ColumnSet = new ColumnSet("account", "new_vatno", "new_registrationnumber");
qe.Criteria.AddCondition("accountnumber", ConditionOperator.In,"TA10024846", "TA10028471", "TA20014015", "TA4011652", "TA4011557");
EntityCollection response = service.RetrieveMultiple(qe);
foreach (var acc in response.Entities)
{
acc.Attributes["new_vatno"] = //this is where I am struggling to figure out how I am gong to match the records up,
acc.Attributes["new_registrationnumber"] = //this is where I am struggling to figure out how I am gong to match the records up,
service.Update(acc);
}
}
How am I going to ensure that I update the correct records. I have the vat and reg numbers for the accounts in a spreadsheet, please see example image below. Can I please get advised here. Thanks.
I would load the list of VAT updates from the spreadsheet into a dictionary and then load the 30k record from CRM into memory. Then I would match them up and use ExecuteMultipleRequest to do the updates. Alternatively, you could query CRM using the account numbers (if the list is small enough.) I made the assumption you had thousands of updates to do across the record set of 30k. Note, if the Account record size was very large and couldn't be loaded into memory you would need to do account number queries.
Here is the rough code for the basic solution (I haven't tested, method should be split up, and there is minimal error handling):
public class VatInfo
{
public string RegistrationNumber;
public string TaxNumber;
public static Dictionary<string, VatInfo> GetVatList()
{
//TODO: Implement logic to load CSV file into a list. Dictionary key value should be Account Number
throw new NotImplementedException();
}
}
public class UpdateVatDemo
{
public const int maxBatchSize = 100;
public static void RunVatUpdate(IOrganizationService conn)
{
var vats = VatInfo.GetVatList();
var pagingQuery = new QueryExpression("account");
pagingQuery.ColumnSet = new ColumnSet("accountnumber");
Queue<Entity> allEnts = new Queue<Entity>();
while (true)
{
var results = conn.RetrieveMultiple(pagingQuery);
if (results.Entities != null && results.Entities.Any())
results.Entities.ToList().ForEach(allEnts.Enqueue);
if (!results.MoreRecords) break;
pagingQuery.PageInfo.PageNumber++;
pagingQuery.PageInfo.PagingCookie = results.PagingCookie;
}
ExecuteMultipleRequest emr = null;
while (allEnts.Any())
{
if (emr == null)
emr = new ExecuteMultipleRequest()
{
Settings = new ExecuteMultipleSettings()
{
ContinueOnError = true,
ReturnResponses = true
},
Requests = new OrganizationRequestCollection()
};
var ent = allEnts.Dequeue();
if (vats.ContainsKey(ent.GetAttributeValue<string>("accountnumber")))
{
var newEnt = new Entity("account", ent.Id);
newEnt.Attributes.Add("new_vatno", vats[ent.GetAttributeValue<string>("accountnumber")].TaxNumber);
newEnt.Attributes.Add("new_registrationnumber", vats[ent.GetAttributeValue<string>("accountnumber")].RegistrationNumber);
emr.Requests.Add(new UpdateRequest() { Target = newEnt });
}
if (emr.Requests.Count >= maxBatchSize)
{
try
{
var emResponse = (ExecuteMultipleResponse) conn.Execute(emr);
foreach (
var responseItem in emResponse.Responses.Where(responseItem => responseItem.Fault != null))
DisplayFault(emr.Requests[responseItem.RequestIndex],
responseItem.RequestIndex, responseItem.Fault);
}
catch (Exception ex)
{
Console.WriteLine($"Exception during ExecuteMultiple: {ex.Message}");
throw;
}
emr = null;
}
}
}
private static void DisplayFault(OrganizationRequest organizationRequest, int count,
OrganizationServiceFault organizationServiceFault)
{
Console.WriteLine(
"A fault occurred when processing {1} request, at index {0} in the request collection with a fault message: {2}",
count + 1,
organizationRequest.RequestName,
organizationServiceFault.Message);
}
}
Updating the fetched entity is bound to fail because of its entity state, which would not be null.
To update the fetched entities, you need to new up the entity:
foreach (var acc in response.Entities)
{
var updateAccount = new Entity("account") { Id = acc.Id };
updateAccount .Attributes["new_vatno"] = null; //using null as an example.
updateAccount .Attributes["new_registrationnumber"] = null;
service.Update(acc);
}
Code below shows how I managed to get it righy. forst let me explain. I imported my records into a seperate SQL table, in my code I read that table into a list in memory, I then query CRM accounts that need to be updated, I then loop though each account and check if the account number in CRM matches the account number from my sql database, if it matches, I then update the relevant Reg no and Vat no, See code below:
List<Sheet1_> crmAccountList = new List<Sheet1_>();
//var crmAccount = db.Sheet1_.Select(x => x).ToList().Take(2);
var crmAccounts = db.Sheet1_.Select(x => x).ToList();
foreach (var dbAccount in crmAccounts)
{
CRMDataObject modelObject = new CRMDataObject()
{
ID = dbAccount.ID,
Account_No = dbAccount.Account_No,
Tax_No = dbAccount.Tax_No.ToString(),
Reg_No = dbAccount.Reg_No
//Tarsus_Country = dbAccount.Main_Phone
};
}
var officialDatabaseList = crmAccounts;
foreach (var crmAcc in officialDatabaseList)
{
QueryExpression qe = new QueryExpression();
qe.EntityName = "account";
qe.ColumnSet = new ColumnSet("accountnumber", "new_vatno", "new_registrationnumber");
qe.Criteria.AddCondition("accountnumber", ConditionOperator.In,'list of account numbers go here'
EntityCollection response = service.RetrieveMultiple(qe);
foreach (var acc in response.Entities)
{
if (crmAcc.Account_No == acc.Attributes["accountnumber"].ToString())
{
//acc.Attributes["new_vatno"] = crmAcc.VAT_No.ToString();
acc.Attributes["new_registrationnumber"] = crmAcc.Reg_No.ToString();
service.Update(acc);
}
}
}
I am using ExecuteMultipleResponse method to insert 10 account records at a time using SSIS.
List<Entity> _Accounts = new List<Entity>();
// Check the batch size and process
public override void InputAccount_ProcessInput(InputAccountBuffer Buffer)
{
//List<int> personIDs = new List<int>();
int index = 0;
while (Buffer.NextRow())
{
_Accounts.Add(InputAccountFromBuffer(Buffer));
//personIDs.Add(int.Parse(Buffer.sPersonID));
index++;
if (index == 10)
{
ImportBatch();
index = 0;
}
}
ImportBatch();
}
private void ImportBatch()
{
if (_Accounts.Count > 0)
{
var multipleRequest = new ExecuteMultipleRequest()
{
Settings = new ExecuteMultipleSettings()
{
ContinueOnError = true,
ReturnResponses = true
},
Requests = new OrganizationRequestCollection()
};
foreach (var profContact in _Accounts)
{
CreateRequest reqCreate = new CreateRequest();
reqCreate.Target = profContact;
reqCreate.Parameters.Add("SuppressDuplicateDetection", false);
multipleRequest.Requests.Add(reqCreate);
}
ExecuteMultipleResponse multipleResponses = (ExecuteMultipleResponse)organizationservice.Execute(multipleRequest);
var responses = (ExecuteMultipleResponseItemCollection)multipleResponses.Results["Responses"];
foreach (var response in responses)
{
if (response.Fault != null)
{
// A fault has occurred, handle it here
}
else
{
// THIS IS WHERE I KNOW THE GUID VALUE EXIST.
}
}
//IEnumerator f = multipleResponses.Responses.GetEnumerator();
_Accounts.Clear();
}
}
Above code is working fine, however, I now need to read and store Guids from response to a List. This information is essential for the next step in the package. I know, if I am creating single record I can simply say,
Guid newRecord = _service.Create(account);
I even managed to get down to check if the response have 'Fault' or not and if it doesn't have fault then Guid value should exist in the response.
Running response.Response.Results.Values in QuickWatch shows me the guid but I just can't find a way to read it directly and store it as a Guid.
The guid of a created record should be stored in the OrganizationResponse which can be found inside the ExecuteMultipleResponseItem
Try the following to get the guid as a string:
string id = response.Response.Results["id"].ToString()
If it works as expected you should also be able to instantiate a guid, if needed:
Guid guid = new Guid(id);
I'm not a developer so maybe the answer is out there for a different solution but I can't really translate it from python or something else.
I'm trying to use the AWS .NET SDK to find an instance and then get the instance's tags. I've gotten as far as being able to determine if an instance is up and running or not. I also see how I can create and delete tags (not in code example below). But I don't see an easy way to actually check if a tag exists and get the value of the tag if it does exist.
Sorry if I'm missing the obvious but this is all new to me. Here's an example of the code I'm using to check if an instance is running.
instanceID = "i-myInstanceID";
do {
var myrequest = new DescribeInstanceStatusRequest();
DescribeInstanceStatusResponse myresponse = ec2.DescribeInstanceStatus(myrequest);
int isCount = myresponse.DescribeInstanceStatusResult.InstanceStatuses.Count;
for (int isc=0; isc < isCount; isc++) {
InstanceStatus instanceStatus = myresponse.DescribeInstanceStatusResult.InstanceStatuses[isc];
if (instanceStatus.InstanceId.Contains(instanceID)) {
Console.WriteLine("It looks like instance "+instanceID+" is running.");
idIdx = isc;
foundID = true;
break;
}
}
if ((foundID==false) && (secondCounter==1)) {
Console.Write("Looking for instance "+instanceID);
} else {
Console.Write(".");
}
Thread.Sleep(1000);
secondCounter++;
if (secondCounter > 5) {
break;
}
} while (foundID == false) ;
First send a DescribeInstancesRequest to get the list of Instances:
public DescribeInstancesResult GetInstances(Ec2Key ec2Key)
{
_logger.Debug("GetInstances Start.");
AmazonEC2 ec2 = CreateAmazonEc2Client(ec2Key);
var ec2Request = new DescribeInstancesRequest();
DescribeInstancesResponse describeInstancesResponse = ec2.DescribeInstances(ec2Request);
DescribeInstancesResult result = describeInstancesResponse.DescribeInstancesResult;
_logger.Debug("GetInstances End.");
return result;
}
Then loop through the instances until you find the one you want, and then use the Tag.GetTagValueByKey method:
// This just calls the above code
DescribeInstancesResult ec2Instances = _ec2ResourceAccess.GetInstances(ec2Key);
var returnInstances = new List<Ec2UtilityInstance>();
foreach (var reservation in ec2Instances.Reservation)
{
foreach (var runningInstance in reservation.RunningInstance)
{
var returnInstance = new Ec2UtilityInstance();
returnInstance.InstanceId = runningInstance.InstanceId;
returnInstance.InstanceName = runningInstance.Tag.GetTagValueByKey("Name");
returnInstance.Status = (Ec2UtilityInstanceStatus)Enum.Parse(typeof(Ec2UtilityInstanceStatus), runningInstance.InstanceState.Name, true);
returnInstance.DefaultIp = runningInstance.Tag.GetTagValueByKey("DefaultIp");
returnInstance.InstanceType = runningInstance.InstanceType;
returnInstance.ImageId = runningInstance.ImageId;
returnInstances.Add(returnInstance);
}
}
Here is the link for full source that this was taken from:
https://github.com/escherrer/EC2Utilities
Common\Manager
and
Common\ResourceAccess