blog.darkstar.work - a simple url encoder/decoder

 a simple url encoder/decoder
 http://blog.darkstar.work

Labels

Wirtschaft (150) Pressefreiheit (125) Österreich (120) IT (96) code (61) Staatsschulden (37) EZB (27) Pensionssystem (16)
Posts mit dem Label code werden angezeigt. Alle Posts anzeigen
Posts mit dem Label code werden angezeigt. Alle Posts anzeigen

2020-11-02

Snaps, snapd,, Snap Store, snapcraft.io

Tonight in the early morn, when I tried to write(1) an open os based solution(2) to transform almost any modern personal computer or laptop(3) to a simple generic wifi router(4).

Then I unexpectedly found a  community platform, that was still unknown to me:

snapcraft.io

Snaps are there defined as  app packages for desktop, cloud and IoT that are easy to install, secure, cross‐platform and dependency‐free. Snaps are discoverable and installable from the Snap Store, the app store for Linux with an audience of millions, 


I tried first the search functionality of that platform and let's say clearly: 
The layout design looks excellent, the community is well visited, but some functions could be better. Lets look at these 2 examples: 
Searching common phrase file
Searching 1 char only d  
Search results also could be sorted more meaningful & understandable, e.g. 
  1. show all results, where the search phrase  directly corresponds to the package app name /(no matter if sql like (prefix, suffix, substring), sql fulltext match or Levenstein distance.
  2. then show all results, where the search phrase is found in the shown package descripton
  3. at least show all results, that appear like a magical fog or smoke for the user. I know, that your search function is probably not returning total random or bad fuzzy hit results, but I guess the search algorithm searches in fields, which are not shown in search result view.




Snapcraft web site provides at the moment the snap app package search page, a store, tutorials, documentation, developer blog, forum and IOT special bulletin.


Conclusio: Snapcraft has surly more potential, but additional functionality must be added and especially a more clear vision and road-map needs to be specified, followed and permanently filled with life. (Under my point of view, without any additional improvements, vision and road-map the project and the community won't grow up and then after some time, this will remain as small circle of developer project or even become orphaned.)
So far I see this nevertheless as an good opportunity for developers and community to get seen and to receive good jobs offers.

Simply said: Thou must have very soon an idea, where this should go and what exactly you want with  it. If thou don't want to expand and keep this project as a nice and gentle private hobby, then you can keep everything and don't have to change anything. But if you want to expand, become at least a small player for long time, ...


2020-08-10

State management in Blazor

There is a sufficient document for state management in Blazor.
Here is a quick & fast work through with all prerequisites, how to get state management in Blazor working.

Example with Blazored.LocalStorage package


Install nuget package for your project

# Find packages providing a "Blazored.LocalStorage" 
Find-Package Blazored.LocalStorage
# install "Blazored.LocalStorage"  Install-Package Blazored.LocalStorage -Project YourProject# alternatively

Add Blazored.LocalStorage to ConfigureServices at your Startup.cs

using System;
/* ... */
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
/* ... */
using Blazored.LocalStorage;
public class Startup {   /* ... */     public void ConfigureServices(IServiceCollection services)  {      /* ... */     services.AddRazorPages();      services.AddServerSideBlazor();     /* ... */     services.AddBlazoredLocalStorage();     /* ... */   } }

Using LocalStorage inside a razor page / control

@page "/MyPage"
using Blazored.LocalStorage
@inject ILocalStorageService localStorage
@code {
  /* ... */
  Dictionary<stringstring> sessionDict;
  /* ... */
  protected override async Task OnAfterRenderAsync(bool firstRender)  { 
    
if (firstRender)    {
      sessionDict = 
        await localStorage.GetItemAsync<Dictionary<stringstring>>("SessDict");       StateHasChanged();     }    await base.OnAfterRenderAsync(firstRender);   }          protected async Task PersistSessionDict(<Dictionary<stringstring> persistDict) { if (persistDict != sessionDict) { await localStorage.SetItemAsync("SessDict", persistDict); } } }

Using LocalStorage inside an entity class

using System;
/* ... */
using Blazored.LocalStorage;
 
public class MyEntity
{
  [Inject] 
  public ILocalStorageService LS
  {  
    get => _localStorage;
    set => value;
  }
  private ILocalStorageService _localStorage; 



  interal async Task<Dictionary<stringstring>> GetSessionDict() =>  
      await LS.GetItemAsync<Dictionary<stringstring>>("SessDict");
  /* ... */
}

Example with ProtectedBrowserStorage package


Install nuget package for your project


# Find packages providing a "ProtectedBrowserStorage" 
Find-Package ProtectedBrowserStorage 

# install "Microsoft.AspNetCore.ProtectedBrowserStorage"
Install-Package Microsoft.AspNetCore.ProtectedBrowserStorage -Project YourProject
# alternatively install "ProtectedBrowserStorage.NETStandard"  
Install-Package ProtectedBrowserStorage.NETStandard -Project YourProject


Add ProtectedBrowserStorage to ConfigureServices at your Startup.cs

using System;
/* ... */
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
/* ... */
using Microsoft.AspNetCore.ProtectedBrowserStorage;

public class Startup {   /* ... */   public void ConfigureServices(IServiceCollection services) {       /* ... */     services.AddRazorPages();      services.AddServerSideBlazor();     /*... */     services.AddProtectedBrowserStorage();     /* ... */   } }

Using ProtectedBrowserStorage inside a razor page / control

@page "/MyPage"
@using Microsoft.AspNetCore.ProtectedBrowserStorage
@inject ProtectedSessionStorage ProtectedSessionStore
@code {   /* ... */   Dictionary<string, string> sessionDict;   /* ... */   protected override async TaskOnAfterRenderAsync(boolfirstRender)   {      if(firstRender)     {       sessionDict =         await ProtectedSessionStore.GetAsync<Dictionary<string, string>>("SessDict");       StateHasChanged();     }     await base.OnAfterRenderAsync(firstRender);   }     protected async Task PersistSessionDict(Dictionary<stringstring> persistDict) { if (persistDict != sessionDict) { await ProtectedSessionStore.SetAsync("SessDict", persistDict); } } }

Sources and links:

2020-02-15

Semantic Internet: Trends, Facts, Futures, Verification

[Draft] [Concept] [Prototype]

Semantic Internet (former known as Semantic Web, see also RDF) has the possibility to record different semantic trends occurring at different sources with a certain frequency inside the in principle accessible to the public internet.
Day after day, month after month, semantic contexts are published on the Internet. area23 semantic web filters all semantic statements that occur with a certain frequency from different sources. Furthermore, not all trends and semantically significant events are more relevant for most semantic miners.

With area23 semantic web you can filter by region, topic categories, relevance from different sources and subsequent complexity.

A filter for a region can be set similiar to Google Trends, e.g. for United States or for Germany, etc.

Basic main categories are:

  • politics (Brexit, Sinn Féin, Thüringen, ...)
  • sports  (soccer, american football events, ...)
  • entertainement (music, cinema, tv, ...)
  • technology
  • business (stock markets, trading, bonds, central bank news, different economic indictors)
  • health
  • lifestyle (eating, drinking, other events)
  • housing (appartments, flat, hotel, camping / caravan sites, vacation rentals, accommodations, e.g.: Airbnb, Wimdu)
  • infrastructure (traffic reports, flights & airports occupancy, train connections, ships & ferries connections)
  • weather (including unexpected temperatures / weather effects, like ice, heavy rain, storm, dry periods plus enviroment disasters, like hurricanes, floodings, earthquakes, volcanic eruptions)
  • and many more
Once you created your filter enviroment, you can start collecting & recording semantic events.

After some time, collected semantic events will appear, e.g.: 'coronavirus'

In that example, 'coronavirus' the most common and reliable semantic logical statements are shown (extracted from different internet sites / ressources), e.g.: number of infections, behavior to stay healty, flights canceled to / from China, stock market risk for China in the next year.

Every statement extracted from the data pool that directly makes a statement or an assumption regarding matters other than the corona virus is now checked with other data sources as to whether the statement actually has a formal fuzzy truth content. So in that (our) example, the flight connections from and to China will be verified immediately as a result. Chinese economic data and the change behavior of futures in Hang Seng, which changed in the period since the outbreak of the coronavirus, will be checked too.

Warning, formally epistemologically an extracted statement is not necessarily true, even if 15 different articles from different countries in different languages in the web claim: "Corona virus has negative effects on the current Chinese fiscal year 2020." and if the outlook for futures in Hang Seng and the economic data have deteriorated in the same period.


to be continued...



Links about semantic web and similar topics:
https://www.semantic-mediawiki.org/wiki/Semantic_MediaWiki
https://www.opensemanticdata.org/
http://jena.apache.org/
https://www.nngroup.com/articles/user-need-statements/

2019-10-07

query tools openID bearer

invoke-webrequest

$url = "https://webapi.area23.at/api/bearertest"
$headers = @{} 
$headers.Add("Accept","application/json")  
$headers.Add("Authorization", "bearer myBearer")

invoke-webrequest -Uri $url -Headers $headers  
invoke-webrequest -Uri $url -Method GET -Headers $headers 

curl

curl -X GET \
    -H "accept: application/json" \
    -H "Authorization: bearer myBearer" \
    "https://webapi.area23.at/api/bearertest"

wget

wget \ 
    --header="Authorization: Bearer myBearer" \ 
    --header="Content-Type: application/json" \ 
    --no-check-certificate \ 
    https://webapi.area23.at/api/bearertest

Postman


2018-12-25

AWS CodePipeline for android Github project

A short summary, how to create an amazon code pipeline and build project by using an android java github as source repository. (inspired by j-a.f)

I have choosen my github schnapslet project android subtree for trial.

Login into amazon webservices console

https://console.aws.amazon.com/codesuite/codepipeline/pipelines?region=us-east-1#

Click on "Create pipeline"

Choose pipeline settings

Enter a "Pipeline name" and a service role for your new pipeline here. Click "Next".

Choose source provider

Choose Gitub, authorize with your github credentials or choose a public github project, choose repositoty, choose branch, then click "Next".

Add build stage

Choose AWS CodeBuild and click on "Create project".

Create build project

In section "Project" configuration fill out "Project name" (Description - optional).

In section "Environment", I choosed the simplest way with "Managed image" as environment image, "Ubuntu" as operating system, "Android" as runtime, "aws/codebuild/android-java-8:26.1.1" as runtime version, default new service role.

In subsection "Additional configuration", you can enable a VPC on your virtual Ubuntu build server, e.g. if you want to login with ssh; you can select various performance features here, like "15 GB memory, 8 vCPUs" for your build server, you can set manually environment variables here and so on. We didn't need that here for only a simple proof of concepts.


In section "Buildspec" I choosed "Insert build commands", then switched to source editor and edited the following buildspec.yaml:
version: 0.2
phases:
  #install: #commands: # - command
  #pre_build: #commands: # - command
  build:
    commands
     - sudo chmod 755 $CODEBUILD_SRC_DIR/android/Schnapslet/gradlew
     - $CODEBUILD_SRC_DIR/android/Schnapslet/gradlew init -i
     - $CODEBUILD_SRC_DIR/android/Schnapslet/gradlew build -i
     - $CODEBUILD_SRC_DIR/android/Schnapslet/gradlew build --build-file $CODEBUILD_SRC_DIR/android/Schnapslet/app/build.gradle -i
#post_build: #commands: # - command
#artifacts: #files: # - location
#cache: #paths: # - paths

Finally click "Continue to CodePipeline".

Now click "Next", when you are back again on "Add build stage" site.

Add deploy stage

I skipped that option for that proof of concept.

Review

Rewiew "Pipeline settings", "Add source stage", "Add build stage", "Add deploy stage" here and finally click "Create pipeline".

Release change

Finally "Release change".

You can configure your "Build project" seperatly now here: https://console.aws.amazon.com/codesuite/codebuild/projects?region=us-east-1
e.g. if you want to change your buildspec.yaml or view different build logs.

2018-12-18

Html-Sql-Injection Detection

A very simple prototype of html injection detection in MS SQLServer, please notice, that real detection is much more complex...

If Exists(Select Top 1 object_id From tempdb.sys.tables Where name = '##InjWatch')
Delete From ##InjWatch
Else
Create Table ##InjWatch ( ctext nvarchar(Max), tab varchar(768), col varchar(768)
);
GO 

Declare InjectCursor Cursor FAST_FORWARD READ_ONLY For 
  Select 'Cast([' + c.name + '] as nvarchar(max))' as c_cast,
    c.name as c_name, '' + s.name + '.[' +T.name + ']' as sT_name
  From sys.tables T
  Inner Join sys.columns c
    On  c.object_id = T.object_id
    and c.max_length > 16 and c.system_type_id In (Select system_type_id From sys.types Where name In('varchar', 'nvarchar''char''nchar''text''ntext'))
  Inner Join sys.schemas s
    On s.schema_id = T.schema_id

Declare @c_cast varchar(1024), @c_name varchar(768), @sT_name varchar(768)
Open InjectCursor
Fetch Next From InjectCursor Into @c_cast, @c_name, @sT_name

While
 (@@FETCH_STATUS = 0)
Begin
  Declare @execSQL nvarchar(max)
  Set @execSQL = 'insert into ##InjWatch (ctext, tab, col) '+
    'select ' + @c_cast + ' as ctext, ''' + @sT_name + ''' as tab, ''' + @c_name + ''' as col ' +
    ' from ' + @sT_name + ' with (nolock) ' +
    ' where (' + @c_cast + ' like ''%<%'' and ' + @c_cast + ' like ''%>%'') ' +
    ' or ' + @c_cast + ' like ''%script:%'' or ' + @c_cast + ' like ''%://%''' +
    ' or ' + @c_cast + ' like ''%href%'' or ' + @c_cast + ' like ''%return %''' +
    ' or ' + @c_cast + ' like ''%mailto:%'''
  Execute sp_executesql @execSQL;
  Fetch Next From InjectCursor Into @c_cast, @c_name, @sT_name
End
Close InjectCursor
Deallocate InjectCursor

Select Distinct * From ##InjWatch
GO 

2018-05-28

Generate WSDL on the fly, with CodeDom instead WSDL:EXE

Generate WSDL on the fly, with CodeDom instead WSDL:EXE

#C#

var wsdlDescription = ServiceDescription.Read(YourWSDLFile);
var wsdlImporter = new ServiceDescriptionImporter();
wsdlImporter.ProtocolName = "Soap12"; //Might differ
wsdlImporter.AddServiceDescription(wsdlDescription, null, null);
wsdlImporter.Style = ServiceDescriptionImportStyle.Server;
wsdlImporter.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties;
var codeNamespace = new CodeNamespace();
var codeUnit = new CodeCompileUnit();
codeUnit.Namespaces.Add(codeNamespace);
var importWarning = wsdlImporter.Import(codeNamespace, codeUnit);
if (importWarning == 0) {
var stringBuilder = new StringBuilder();
var stringWriter = new StringWriter(stringBuilder);
var codeProvider = CodeDomProvider.CreateProvider("Vb");
codeProvider.GenerateCodeFromCompileUnit(codeUnit, stringWriter, new CodeGeneratorOptions());
stringWriter.Close();
File.WriteAllText(WhereYouWantYourClass, stringBuilder.ToString(), Encoding.UTF8);

} else {

Console.WriteLine(importWarning);

}


#VB

Dim SoapClient As MSSOAPLib30.SoapClient30
Dim XMLDoc As MSXML2.DOMDocument40
Dim vCol As Collection
Dim abc As Variant

Set SoapClient = New MSSOAPLib30.SoapClient30

Set XMLDoc = New MSXML2.DOMDocument40
SoapClient.ClientProperty("ServerHTTPRequest") = True

Call
SoapClient.MSSoapInit("http://169.242.82.87:8080/apex/CurveWebService.ws dl",
"CurveWebServiceService", "CurveWebService")

SoapClient.ConnectorProperty("Timeout") = 30000
SoapClient.ConnectorProperty("UseSSL") = 0

abc = SoapClient.getCurve("EMGLN", "YC_EUR_LIBOR", "GDAXML")

XMLDoc.validateOnParse = False
XMLDoc.LoadXml abc


https://weblog.west-wind.com/posts/2009/Feb/12/WSDL-Imports-without-WSDLexe

2017-04-16

Chrome Browser execs "cmd.exe" on local machine :(

When Chrome browser execs cmd.exe as child process,
which popens McAfee as child,
so that McAfee's parent is cmd.exe
and McAfee's grandparent is Chrome,
I feel so really very strange!

An internet browser could write cookies to your harddisk,
a web browser could write cached data files to your harddrive,
a browser might read/write registry keys ( if proper implemented only to its registry area ) under Microsoft Windows,
but a browser should never ever start processes [ under Posix/unix a.k.a exec/popen/fork ] such as unsandboxed binary programs, (see WinAPI index)
that will running under users privileges with maximum users rights on local machine!

2017-04-09

Swisscom Auto Login

/data/misc/wifi/

wpa_supplicant.conf

ctrl_interface=/data/misc/wifi/sockets
driver_param=use_p2p_group_interface=1
update_config=1
device_name=Hol-U19
manufacturer=HUAWEI
model_name=Hol-U19
model_number=Hol-U19
serial_number=******
device_type=10-0050F204-5
os_version=01020300
config_methods=physical_display virtual_push_button
p2p_no_group_iface=1

network={
 ssid="Swisscom_Auto_Login"
 key_mgmt=WPA-EAP IEEE8021X
 eap=SIM
 sim_slot="0"
 imsi="1232072504805647@wlan.mnc007.mcc232.3gppnetwork.org"
}

network={
 ssid="Free_Swisscom_Auto_Login"
 key_mgmt=WPA-EAP IEEE8021X
 eap=SIM
}

network={
 ssid="Swisscom_Auto_Login"
 key_mgmt=WPA-EAP IEEE8021X
 eap=SIM
 sim_slot="0"
 imsi="1232072504805647@wlan.mnc007.mcc232.3gppnetwork.org"
 priority=1
}

network={
 ssid="Free_Swisscom_Auto_Login"
 key_mgmt=WPA-EAP IEEE8021X
 eap=SIM
}

hostapd.conf

interface=ap0
driver=nl80211
ctrl_interface=/data/misc/wifi/hostapd
ssid=Hol-U19_8639
channel=6
ieee80211n=1
hw_mode=g
ignore_broadcast_ssid=0
max_num_sta=5
eap_server=1
wps_state=2
config_methods=display physical_display push_button
device_name=AndroidAP
manufacturer=MediaTek Inc.
model_name=MTK Wireless Model
model_number=66xx
serial_number=1.0
device_type=10-0050F204-5
wpa=2
rsn_pairwise=CCMP
wpa_psk=f8e8dc3c535319f60c1166220c1b843e82aa5f6a4ad0854d65c92a7befd0017e

p2p_supplicant.conf

ctrl_interface=/data/misc/wifi/sockets
driver_param=use_p2p_group_interface=1
update_config=1
device_name=1466568
manufacturer=MediaTek Inc.
model_name=MTK Wireless Model
model_number=1.0
serial_number=******
device_type=10-0050F204-5
os_version=01020300
config_methods=virtual_push_button physical_display keypad
p2p_ssid_postfix=-1466568
persistent_reconnect=1
p2p_no_group_iface=1

2017-03-20

avoid arpspoofing and seperate clients not together same unsure pool

We know it all very well:
There is this cheap standard router, where all clients no matter, how they were connected, swim like little gold fishes in one and the same 256 subnet pool. All those connecting clients are often not really seperated from all other clients, the best way for hackers & arpspoofers to do evil monkey biz
This is a new concept, where each connecting client gets a seperate subnet with only 1 free IPaddr

2017-03-19

There are infinite prime numbers

supposing , that there are finite prime numbers, p1, p2, ..., p(n-1), pn,
where pn is the hightest prime number. 
this furthermore implies, that a number q would exists, which is defined:
q = p1 * p2 * ... * p(n-1) * pn + 1
q is greater than 1 and cause pn is the highest prime number,
q must have at least one or more divider r from p1, p2, ..., p(n-1), pn
since r|q and r|(p1...pn) => r|1 (what is not possible)
q.e.d.


2016-10-17

Got many spams from magyardomain last days

Delivered-To: heinrichelsigan@mail
Received: by 10.103.128.150 with SMTP id b144csp183855vsd;
        Fri, 14 Oct 2016 07:42:20 -0700 (PDT)
X-Received: by 10.28.133.202 with SMTP id h193mr5795470wmd.85.1476456140232;
        Fri, 14 Oct 2016 07:42:20 -0700 (PDT)
Return-Path: 
Received: from mail.dgbmail.eu (mailto.dgbmail.eu. [87.229.51.250])
        by mx.google.com with ESMTPS id hd9si25509736wjc.88.2016.10.14.07.42.19
        for 
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Fri, 14 Oct 2016 07:42:20 -0700 (PDT)
Received-SPF: pass (google.com: best guess record for domain of root@mail.dgbmail.eu designates 87.229.51.250 as permitted sender) client-ip=87.229.51.250;
Authentication-Results: mx.google.com;
       spf=pass (google.com: best guess record for domain of root@mail.dgbmail.eu designates 87.229.51.250 as permitted sender) smtp.mailfrom=root@mail.dgbmail.eu
Received: from root by mail.dgbmail.eu with local (Exim 4.84) (envelope-from ) id 1bv3gh-0005R4-OW for heinrichelsigan@.com; Fri, 14 Oct 2016 16:42:19 +0200
Received: from apache by mail.dataglobe.eu with local (Exim 4.86) (envelope-from [apache mail.dataglobe.eu=""]) id 1bv3g7-0003UM-Iu for heinrichelsigan@mail; Fri, 14 Oct 2016 14:41:43 +0000
X-Provider-Server: no-user-x110
X-Provider-Path: /MAGYARDOMAIN/WEB/metronic/theme_rtl/assets/global/plugins/ckeditor/plugins/flash/images
To: heinrichelsigan@mail
Subject: B@ng Me Tonight
X-Provider-IP: 89.212.78.219
Date: Fri, 14 Oct 2016 16:41:43 +0200
From: Julie Owens [julie_owens clicks.net=""]
Message-ID: [3e8a73cf1c642dcd2d9a3993a6814756 clicks.net=""]
X-Priority: 3
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="b1_3e8a73cf1c642dcd2d9a3993a6814756"
Content-Transfer-Encoding: 8bit
Sender: apache mail.dataglobe.eu=""

--b1_3e8a73cf1c642dcd2d9a3993a6814756
Content-Type: text/plain; charset=us-ascii

I apologize, but can we ... f@ck?

Watch me m@sturbating on the sofa

Spank my rack for your pleasure!

[ http://woodandstonefloors.co.uk/css.php?i=142&dBTkDgan=VVmVWWkXRZp&Qn=Aeu&5=6njeQ ] My photos for your pleasure

See you soon!


--b1_3e8a73cf1c642dcd2d9a3993a6814756--

Results returned from whois.arin.net:
#
# ARIN WHOIS data and services are subject to the Terms of Use
# available at: https://www.arin.net/whois_tou.html

87.229.51.250 is from Hungary (HU) in region Eastern Europe
Input: 87.229.51.250
canonical name: mailto.dgbmail.eu
Registered Domain: dgbmail.eu

87.229.51.250 is from Hungary (HU) in region Eastern Europe
Whois query for 87.229.51.250...

Domain dgbmail.eu

Registrant:
NOT DISCLOSED!
Visit www.eurid.eu for webbased whois.

Technical:
Name Dataglobe Technical staff
Organisation Dataglobe Zrt
Language hu
Phone +36.18088230
Fax +36.19980206
Email info@dataglobe.eu

Registrar:
Name Magyar Domain Ltd
Website http://www.magyardomain.eu/

Name servers:
ns0.dataglobe.eu
ns2.dataglobe.eu

Please visit www.eurid.eu for more info.


2016-06-05

A new approach on monetarisation, when remixing copy left

Some years ago, I guess sometime between late 2009 and early 2014, I was so free to remix several artworks and popular scientific explanations from others founders to visualize relationships between subprime market crisis in the US and the problems of the countries of the € zone with all the rumor, demonstrations, civil unrests inside Europe. I mixed music from The KLF in (who called them self "Kopyright Liberation Front" and who excessivly remixed samples of other artists.)



I didn't enable the monetization switch at YouTube on this remix video, because I didn't find it fair, that all gain would be transferred to me alone.
Rather I would prefer a model, where every artists involced in this remix would receive shares from monetarisation proportionately to time his or her part was mixed in.

2016-04-22

AWSSDK Demo Sample in C# .NET

This article just shows, how to use some basic functions of the Amazon WebServices SDK under C# .NET with Visual Studio 2013

Pre-requesties: 



/*******************************************************************************
* Copyright 2009-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may
* not use this file except in compliance with the License. A copy of the
* License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file 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.
*******************************************************************************/

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;

using Amazon;
using Amazon.EC2;
using Amazon.EC2.Model;
using Amazon.EC2.Util;

using Amazon.IdentityManagement;
using Amazon.IdentityManagement.Model;

using Amazon.Auth.AccessControlPolicy;
using Amazon.Auth.AccessControlPolicy.ActionIdentifiers;

using Amazon.S3;
using Amazon.S3.Model;
using Amazon.S3.Util;

namespace AwsEC2Sample1
{
    /// <summary>
    /// This sample shows how to launch an Amazon EC2 instance with a PowerShell script that is executed when the
    /// instance becomes available and access Amazon S3.
    /// </summary>
    class Program
    {      

        static readonly string RESOURCDE_POSTFIX = DateTime.Now.Ticks.ToString();
        static readonly string SAMPLE_PREFIX = AWSConfigSettings.AWSSamplePrefix;
        static readonly string SAMPLE_NAME = SAMPLE_PREFIX +
            DateTime.Now.ToShortDateString() + "_" + DateTime.Now.ToShortTimeString().Replace(":", ".");
        static readonly string SAMPLE_LONG_UNIQUE_NAME = SAMPLE_PREFIX + RESOURCDE_POSTFIX;
        const bool CREATE_AND_SAVE_KEY_PAIR = true;


        public static void Main(string[] args)
        {

            string awsProfileName = AWSConfigSettings.AWSProfileName;

            AmazonEC2Config config = new AmazonEC2Config();
            config.ServiceURL = AWSConfigSettings.AWSServiceUrl;
            Amazon.Runtime.AWSCredentials credentials = new Amazon.Runtime.StoredProfileAWSCredentials(awsProfileName);
            // AmazonEC2Client ec2Client = new AmazonEC2Client(credentials, config);
            AmazonEC2Client ec2Client = new AmazonEC2Client();

            var bucketName = SAMPLE_LONG_UNIQUE_NAME;           

            // Get latest 2012 Base AMI
            var imageId = ImageUtilities.FindImage(ec2Client, ImageUtilities.WINDOWS_2012_BASE).ImageId;
            Console.WriteLine("Using Image ID: {0}", imageId);

            // Create an IAM role
            var instanceProfileArn = CreateInstanceProfile();
            Console.WriteLine("Created Instance Profile: {0}", instanceProfileArn);

            Thread.Sleep(15000);

            // Check existing keypairs
            string keyPairName = SAMPLE_LONG_UNIQUE_NAME;

            var dkpRequest = new DescribeKeyPairsRequest();
            var dkpResponse = ec2Client.DescribeKeyPairs(dkpRequest);
            List<KeyPairInfo> myKeyPairs = dkpResponse.KeyPairs;
            foreach (KeyPairInfo item in myKeyPairs)
            {
                Console.WriteLine("Existing key pair: " + item.KeyName);
            }

            // Create new KeyPair
            KeyPair newKeyPair = null;
            CreateKeyPairRequest newKeyRequest = new CreateKeyPairRequest() { KeyName = keyPairName };
            CreateKeyPairResponse ckpResponse = ec2Client.CreateKeyPair(newKeyRequest);
            // store the received new Key  
            newKeyPair = ckpResponse.KeyPair;
            Console.WriteLine();
            Console.WriteLine("New key: " + keyPairName);
            Console.WriteLine("fingerprint: " + newKeyPair.KeyFingerprint);
            Console.WriteLine();
            // Save the private key in a .pem file
            using (FileStream s = new FileStream(keyPairName + ".pem", FileMode.Create))
            {
                using (StreamWriter writer = new StreamWriter(s))
                {
                    writer.WriteLine(newKeyPair.KeyMaterial);
                    Console.WriteLine(newKeyPair.KeyMaterial);
                }
            }

            string secGroupId = string.Empty;
            // Create new security Group
            try
            {
                HttpStatusCode createSecGrCode = CreateSecurityGroup(ec2Client, ref secGroupId);
            }
            catch (AmazonEC2Exception ae)
            {
                if (string.Equals(ae.ErrorCode, "InvalidGroup.Duplicate", StringComparison.InvariantCulture))
                    Console.WriteLine(ae.Message);
                else throw;
            }

            // add ip ranges
            String ipSource = "0.0.0.0/0";
            List<String> ipRanges = new List<String>();
            ipRanges.Add(ipSource);

            List<IpPermission> ipPermissions = new List<IpPermission>();
            IpPermission tcpSSH = new IpPermission() { IpProtocol = "tcp", FromPort = 22, ToPort = 22, IpRanges = ipRanges };
            ipPermissions.Add(tcpSSH);
            IpPermission tcpHTTP = new IpPermission() { IpProtocol = "tcp", FromPort = 80, ToPort = 80, IpRanges = ipRanges };
            ipPermissions.Add(tcpHTTP);
            IpPermission tcpHTTPS = new IpPermission() { IpProtocol = "tcp", FromPort = 443, ToPort = 443, IpRanges = ipRanges };
            ipPermissions.Add(tcpHTTPS);
            IpPermission tcpMYSQL = new IpPermission() { IpProtocol = "tcp", FromPort = 3306, ToPort = 3306, IpRanges = ipRanges };
            ipPermissions.Add(tcpMYSQL);
            IpPermission tcpRDP = new IpPermission() { IpProtocol = "tcp", FromPort = 3389, ToPort = 3389, IpRanges = ipRanges };
            ipPermissions.Add(tcpRDP);

            try
            {
                // Authorize the ports to be used.

                AuthorizeSecurityGroupIngressRequest ipPermissionsRequest = new AuthorizeSecurityGroupIngressRequest();
                ipPermissionsRequest.IpPermissions = ipPermissions;
                ipPermissionsRequest.GroupName = SAMPLE_NAME;
                if (!string.IsNullOrEmpty(secGroupId)) {
                    ipPermissionsRequest.GroupId = secGroupId;
                }
                AuthorizeSecurityGroupIngressResponse authResp = ec2Client.AuthorizeSecurityGroupIngress(ipPermissionsRequest);
                
                Console.WriteLine("Auth SecurityGroup Request HttpStatusCode " + authResp.HttpStatusCode + " ");
                Console.WriteLine(authResp.ResponseMetadata);
            }
            catch (AmazonEC2Exception ae)
            {
                if (String.Equals(ae.ErrorCode, "InvalidPermission.Duplicate", StringComparison.InvariantCulture))
                    Console.WriteLine(ae.Message);
                else
                    throw;
            }

            // run ec2 instance request with existing or new generated keypair
            var runRequest = new RunInstancesRequest
            {
                ImageId = imageId,
                MinCount = 1,
                MaxCount = 1,
                KeyName = newKeyPair.KeyName, //keyPair.KeyName,
                IamInstanceProfile = new IamInstanceProfileSpecification { Arn = instanceProfileArn },                           
                   
                // Add the region for the S3 bucket and the name of the bucket to create
                UserData = EncodeToBase64(
                    string.Format(
                        AWSConfigSettings.POWERSHELL_S3_BUCKET_SCRIPT,
                        AWSConfigSettings.AWSRegionEndpoint.SystemName,
                        bucketName)
                    )
            };

            // add secGroupId
            if (!string.IsNullOrEmpty(secGroupId)) {
                runRequest.SecurityGroupIds.Add(secGroupId);
            }
           
            var instanceId = ec2Client.RunInstances(runRequest).Reservation.Instances[0].InstanceId;
            Console.WriteLine("Launch Instance {0}", instanceId);


            // Create the name tag
            ec2Client.CreateTags(new CreateTagsRequest
            {
                Resources = new List<string> { instanceId },
                Tags = new List<Amazon.EC2.Model.Tag> { new Amazon.EC2.Model.Tag { Key = "Name", Value = "Processor" } }
            });
            Console.WriteLine("Adding Name Tag to instance");

            // create ElastiCache Cluster
            try
            {
                Amazon.ElastiCache.AmazonElastiCacheConfig eCacheConfig = new Amazon.ElastiCache.AmazonElastiCacheConfig();
                eCacheConfig.ServiceURL = AWSConfigSettings.AWSServiceUrl;
                Amazon.ElastiCache.AmazonElastiCacheClient eCacheClient = new Amazon.ElastiCache.AmazonElastiCacheClient();
                // List<string> x = new List<string>();
                // x.Add(secGroupId);
                // Amazon.ElastiCache.Model.CreateCacheClusterRequest eCacheReq = new Amazon.ElastiCache.Model.CreateCacheClusterRequest(
                //    "cache-cluster" + SAMPLE_NAME, 2, "cache.t2.medium", "memcached", x);
                Amazon.ElastiCache.Model.CreateCacheClusterRequest eCacheReq = new Amazon.ElastiCache.Model.CreateCacheClusterRequest(
                                    "Christian", 2, "cache.t2.medium", "memcached", new List<string>());
               
                Amazon.ElastiCache.Model.CreateCacheClusterResponse eCacheResp = eCacheClient.CreateCacheCluster(eCacheReq);
                Console.WriteLine("Cache Cluster Created" + eCacheResp.HttpStatusCode.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine();
            }

            // rds client
            Amazon.RDS.AmazonRDSConfig rdsConf = new Amazon.RDS.AmazonRDSConfig();
            rdsConf.ServiceURL = AWSConfigSettings.AWSServiceUrl;
            Amazon.RDS.AmazonRDSClient rdsClient = new Amazon.RDS.AmazonRDSClient();
           
            // create Database Cluster with aurora DB
            string dbClusterIdentifier = string.Empty;
            try
            {
                Amazon.RDS.Model.DBCluster createdCluster =
                    CreateDBClusterRDS(rdsClient, SAMPLE_NAME, "aurora", "root", SAMPLE_LONG_UNIQUE_NAME, secGroupId, ref dbClusterIdentifier);
                Console.WriteLine("Created DBCluster with Id " + createdCluster.DBClusterIdentifier);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine();
            }

            Console.WriteLine("Waiting for EC2 Instance to stop");
            // The script put in the user data will shutdown the instance when it is complete.  Wait
            // till the instance has stopped which signals the script is done so the instance can be terminated.
            Instance = null;
            var instanceDescribeRequest = new DescribeInstancesRequest { InstanceIds = new List<string> { instanceId } };
            do
            {
                Thread.Sleep(10000);
                instance = ec2Client.DescribeInstances(instanceDescribeRequest).Reservations[0].Instances[0];

                if (instance.State.Name == "stopped")
                {
                    // Demonstrate how to get the Administrator password using the keypair.
                    var passwordResponse = ec2Client.GetPasswordData(new GetPasswordDataRequest
                    {
                        InstanceId = instanceId
                    });

                    // Make sure we actually got a password
                    if (passwordResponse.PasswordData != null)
                    {
                        var password = passwordResponse.GetDecryptedPassword(newKeyPair.KeyMaterial);
                        Console.WriteLine("The Windows Administrator password is: {0}", password);
                    }
                }
            } while (instance.State.Name == "pending" || instance.State.Name == "running");


            // Terminate instance
            Console.WriteLine("Terminate Instances " + instanceId.ToString());
            ec2Client.TerminateInstances(new TerminateInstancesRequest
            {
                InstanceIds = new List<string>() { instanceId }
            });

            // Delete key pair created for sample.
            Console.WriteLine("Delete KeyPair " + newKeyPair.KeyName);
            ec2Client.DeleteKeyPair(new DeleteKeyPairRequest { KeyName = newKeyPair.KeyName });
           
            try
            {
                var s3Client = new AmazonS3Client();
                var listResponse = s3Client.ListObjects(new ListObjectsRequest
                {
                    BucketName = bucketName
                });
                if (listResponse.S3Objects.Count > 0)
                {
                    Console.WriteLine("Found results file {0} in S3 bucket {1}", listResponse.S3Objects[0].Key, bucketName);
                }

                // Delete bucket created for sample.
                AmazonS3Util.DeleteS3BucketWithObjects(s3Client, bucketName);
                Console.WriteLine("Deleted S3 bucket created for sample.");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine();
            }

            // delete DB Cluster
            try
            {
                HttpStatusCode delClusterStatus = DeleteDBClusterRDS(rdsClient, dbClusterIdentifier);
                Console.WriteLine("Delete Cluster Request with Id " + dbClusterIdentifier + " returned " + delClusterStatus.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine();
            }


            Thread.Sleep(1000);

            Console.WriteLine("Delete Instance Profile created for sample.");
            DeleteInstanceProfile();

            // delete Security Group

            try
            {
                HttpStatusCode delSecGroupStatus = DeleteSecurityGroup(ec2Client, secGroupId);
                Console.WriteLine("Delete SecurityGroup " + secGroupId + " returned " + delSecGroupStatus.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine();
            }


            Console.WriteLine("Instance terminated, push enter to exit the program");
            Console.Read();

        }


        /// <summary>
        /// CreateSecurityGroup
        /// </summary>
        /// <param name="ref ec2Client"></param>
        /// <param name="secGroupId"></param>
        /// <returns>HttpStatusCode</returns>
        static HttpStatusCode CreateSecurityGroup(AmazonEC2Client ec2Client, ref string secGroupId)
        {
            CreateSecurityGroupRequest securityGroupRequest = new CreateSecurityGroupRequest();
            securityGroupRequest.GroupName = SAMPLE_NAME;
            securityGroupRequest.Description = SAMPLE_LONG_UNIQUE_NAME;
            CreateSecurityGroupResponse secRes = ec2Client.CreateSecurityGroup(securityGroupRequest);
            Console.WriteLine("Created security Group with GroupId " + secRes.GroupId);

            secGroupId = secRes.GroupId;
            Console.WriteLine(secRes.ResponseMetadata);
            return secRes.HttpStatusCode;
        }

        /// <summary>
        /// CreateDBClusterRDS
        /// </summary>
        /// <param name="rdsClient"></param>
        /// <param name="databaseName"></param>
        /// <param name="databaseEngine"></param>
        /// <param name="MasterUsername"></param>
        /// <param name="MasterUserPassword"></param>
        /// <param name="secGroupId"></param>
        /// <param name="ref dbClusterIdentifier"></param>
        /// <returns></returns>
        static Amazon.RDS.Model.DBCluster CreateDBClusterRDS(Amazon.RDS.AmazonRDSClient rdsClient,
            string databaseName,
            string databaseEngine,
            string MasterUsername,
            string MasterUserPassword,
            string secGroupId, ref string dbClusterIdentifier)
        {
            Amazon.RDS.Model.CreateDBClusterRequest createClusterReq = new Amazon.RDS.Model.CreateDBClusterRequest();
            createClusterReq.DatabaseName = databaseName;
            createClusterReq.DBClusterIdentifier = dbClusterIdentifier;
            createClusterReq.Engine = databaseEngine;
            if (!string.IsNullOrEmpty(secGroupId))
            {
                createClusterReq.VpcSecurityGroupIds.Add(secGroupId);
            }
            createClusterReq.MasterUserPassword = MasterUserPassword;
            createClusterReq.MasterUsername = MasterUsername;

            Amazon.RDS.Model.CreateDBClusterResponse createClusterResp = rdsClient.CreateDBCluster(createClusterReq);
            Amazon.RDS.Model.DBCluster createdCluster = createClusterResp.DBCluster;
            dbClusterIdentifier = createdCluster.DBClusterIdentifier;
            return createdCluster;
        }

        /// <summary>
        /// DeleteDBClusterRDS
        /// </summary>
        /// <param name="rdsClient">Amazon.RDS.AmazonRDSClient</param>
        /// <param name="dbClusterIdentifier">Identifier of RDS DatabaseCluster 2 delete</param>
        /// <returns>HttpStatusCode</returns>
        static HttpStatusCode DeleteDBClusterRDS(Amazon.RDS.AmazonRDSClient rdsClient, string dbClusterIdentifier)
        {
            if (!string.IsNullOrEmpty(dbClusterIdentifier))
            {
                throw new ArgumentException("Null or Empty DBClusterIdentifier which is needed for Amazon.RDS.Model.DeleteDBClusterRequest", "string dbClusterIdentifier");
            }
            Console.WriteLine("Deleting DeleteDBClusterRDS with identifier " + dbClusterIdentifier);
            Amazon.RDS.Model.DeleteDBClusterRequest delClusterReq = new Amazon.RDS.Model.DeleteDBClusterRequest();
            delClusterReq.DBClusterIdentifier = dbClusterIdentifier;
            Amazon.RDS.Model.DeleteDBClusterResponse delClusterResp = rdsClient.DeleteDBCluster(delClusterReq);
            return delClusterResp.HttpStatusCode;
        }

        /// <summary>
        /// DeleteSecurityGroup
        /// </summary>
        /// <param name="ec2Client">EC2Client</param>
        /// <param name="securityGroupId">Identifier of SecurityGroup 2 delete</param>
        /// <returns>HttpStatusCode</returns>
        static HttpStatusCode DeleteSecurityGroup(AmazonEC2Client ec2Client, string securityGroupId)
        {
            if (!string.IsNullOrEmpty(securityGroupId))
            {
                throw new ArgumentException("Null or Empty securityGroupId which is needed for Amazon.EC2.Model.DeleteSecurityGroupRequest", "string securityGroupId");
            }
            Console.WriteLine("Deleting SecurityGroup " + securityGroupId);
            DeleteSecurityGroupRequest delSecGroupReq = new DeleteSecurityGroupRequest();
            delSecGroupReq.GroupId = securityGroupId;
            DeleteSecurityGroupResponse delSecGroupResp = ec2Client.DeleteSecurityGroup(delSecGroupReq);
            return delSecGroupResp.HttpStatusCode;
        }

        /// <summary>
        /// Create instance profile & grant EC2 instance requesting S3 bucket
        /// </summary>
        /// <returns></returns>
        static string CreateInstanceProfile()
        {
            var roleName = SAMPLE_NAME;
            var client = new AmazonIdentityManagementServiceClient();
            client.CreateRole(new CreateRoleRequest
            {
                RoleName = roleName,
                AssumeRolePolicyDocument = @"{""Statement"":[{""Principal"":{""Service"":[""ec2.amazonaws.com""]},""Effect"":""Allow"",""Action"":[""sts:AssumeRole""]}]}"
            });

            var statement = new Amazon.Auth.AccessControlPolicy.Statement(
                Amazon.Auth.AccessControlPolicy.Statement.StatementEffect.Allow);
            statement.Actions.Add(S3ActionIdentifiers.AllS3Actions);
            statement.Resources.Add(new Resource("*"));

            var policy = new Policy();
            policy.Statements.Add(statement);

            client.PutRolePolicy(new PutRolePolicyRequest
            {
                RoleName = roleName,
                PolicyName = "S3Access",
                PolicyDocument = policy.ToJson()
            });

            var response = client.CreateInstanceProfile(new CreateInstanceProfileRequest
            {
                InstanceProfileName = roleName
            });

            client.AddRoleToInstanceProfile(new AddRoleToInstanceProfileRequest
            {
                InstanceProfileName = roleName,
                RoleName = roleName
            });

            return response.InstanceProfile.Arn;
        }

        /// <summary>
        /// Delete the instance profile created for the sample.
        /// </summary>
        static void DeleteInstanceProfile()
        {
            var roleName = SAMPLE_NAME;
            var client = new AmazonIdentityManagementServiceClient();

            client.DeleteRolePolicy(new DeleteRolePolicyRequest
            {
                RoleName = roleName,
                PolicyName = "S3Access"
            });

            client.RemoveRoleFromInstanceProfile(new RemoveRoleFromInstanceProfileRequest
            {
                InstanceProfileName = roleName,
                RoleName = roleName
            });

            client.DeleteRole(new DeleteRoleRequest
            {
                RoleName = roleName
            });

            client.DeleteInstanceProfile(new DeleteInstanceProfileRequest
            {
                InstanceProfileName = roleName
            });
        }

        static string EncodeToBase64(string str)
        {
            byte[] toEncodeAsBytes = System.Text.Encoding.UTF8.GetBytes(str);
            string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
            return returnValue;
        }
    }

    /// <summary>
    /// AWSConfigSettings Helper Facade
    /// </summary>
    internal static class AWSConfigSettings
    {      
        const string PROTO = "https://";
        const string DOMAIN = "amazonaws.com"; //amazonaws.com
        const char DOT = '.';

        /// <summary>
        /// PowerShell script for creating S3 bucket and allowing write access to it
        /// </summary>
        internal const string POWERSHELL_S3_BUCKET_SCRIPT =
             "<powershell>\n" +
                "Import-Module \"C:\\Program Files (x86)\\AWS Tools\\PowerShell\\AWSPowerShell\\AWSPowerShell.psd1\"\n" +
                "Set-DefaultAWSRegion {0}\n" +
                "New-Item C:\\Windows\\Temp -type directory\n" +
                "Add-Content -path C:\\Windows\\Temp\\s3-bucket-results.txt -value \"Results from lots of data processing\"\n" +
                "New-S3Bucket -BucketName {1}\n" +
                "Write-S3Object -BucketName {1} -File C:\\Windows\\Temp\\s3-bucket-results.txt -Key results.txt\n" +
                "shutdown.exe /s\n" +
            "</powershell>";
      
        /// <summary>
        /// Gets AWSAppSettings from Configuration
        /// </summary>
        internal static NameValueCollection AWSAppSettings
        {
            get {
                return System.Configuration.ConfigurationManager.AppSettings;
            }
        }

        /// <summary>
        /// Gets value stored at AWSAppSettings[key]
        /// </summary>
        /// <param name="key">key string from KeyValuePair of Configuration AppSettings</param>
        /// <returns>value string</returns>
        internal static string AWSConfigGetKey(string key)
        {
            string awsValue = null;
            foreach (var nextKey in AWSConfigSettings.AWSAppSettings.Keys)
            {
                if (nextKey.ToString() == key)
                {
                    awsValue = AWSConfigSettings.AWSAppSettings.Get(key);
                    if (!string.IsNullOrEmpty(awsValue))
                    {
                        return awsValue;
                    }
                    throw new ConfigurationErrorsException(
                        String.Format("AWSConfigSettings.AWSAppSettings[\"{0}\"] returns null or void Value", key),
                        new NullReferenceException(String.Format("AWSConfigSettings.AWSAppSettings[\"{0}\"] is \'\\0\' || \"\"", key))
                    );
                }
            }

            throw new ConfigurationErrorsException(
                String.Format("AWSConfigSettings.AWSAppSettings[\"{0}\"] contains no key {1} not found inside <configuration>[...]<appSettings>[...]", key, key),
                new NullReferenceException(String.Format("AWSConfigSettings.AWSAppSettings[\"{0}\"] is \'\\0\' (null)", key))
                );
        }

        /// <summary>
        /// Gets AWSProfileName from ConfigSettings
        /// </summary>
        public static string AWSProfileName
        {
            get {
                return AWSConfigSettings.AWSConfigGetKey("AWSProfileName");
            }
        }

        /// <summary>
        /// Gets AWSRegion from ConfigSettings
        /// </summary>
        public static string AWSRegion
        {
            get
            {
                string region = "eu-central-1";
                try
                {
                    region = AWSConfigSettings.AWSConfigGetKey("AWSRegion");
                }
                catch (Exception)
                {
                    region = "ap-southeast-2";
                }
                return region;
            }
        }

        /// <summary>
        /// Gets Amazon.RegionEndpoint from ConfigSettings
        /// </summary>
        public static Amazon.RegionEndpoint AWSRegionEndpoint
        {
            get {
                string compareRegion = AWSConfigSettings.AWSRegion.Replace("_", string.Empty).ToLower();
                foreach (Amazon.RegionEndpoint endpoint in Amazon.RegionEndpoint.EnumerableAllRegions)
                {
                    if ((endpoint.DisplayName.ToLower() == AWSConfigSettings.AWSRegion.Replace("_", string.Empty).ToLower()) ||
                        (endpoint.SystemName.ToLower() == AWSConfigSettings.AWSRegion.Replace("_", string.Empty).ToLower()) ||
                        (endpoint.ToString().ToLower() == AWSConfigSettings.AWSRegion.Replace("_", string.Empty).ToLower()))
                    {
                        return endpoint;
                    }
                }
                return Amazon.RegionEndpoint.EUWest1;
            }
        }

        /// <summary>
        /// Gets AWSServiceUrl from ConfigSettings
        /// </summary>
        public static String AWSServiceUrl
        {
            get {
                string serviceUrl = String.Concat(
                    PROTO.ToString(),
                    AWSConfigSettings.AWSRegion,
                    ((DOMAIN[0] != DOT) ? DOT.ToString() : string.Empty),
                    DOMAIN.ToString()
                    );
                return serviceUrl;
            }
        }

        /// <summary>
        /// Gets AWSServiceUri from ConfigSettings
        /// </summary>
        public static Uri AWSServiceUri
        {
            get {
                return (new Uri(AWSConfigSettings.AWSServiceUrl, UriKind.Absolute));
            }
        }

        /// <summary>
        /// Gets AWSSamplePrefix from Configuration
        /// </summary>
        public static string AWSSamplePrefix
        {
            get
            {
                return AWSConfigSettings.AWSConfigGetKey("AWSSamplePrefix");
            }

        }

        /// <summary>
        /// Gets AWSAccessKey from Configuration
        /// </summary>
        public static string AWSAccessKey
        {
            get {
                return AWSConfigSettings.AWSConfigGetKey("AWSAccessKey");
            }
        }

        /// <summary>
        /// Gets AWSSecretKey from Configuration
        /// </summary>
        public static string AWSSecretKey
        {
            get
            {
                return AWSConfigSettings.AWSConfigGetKey("AWSSecretKey");
            }
        }

    }

}



Ҁ and ү.