PASTABA: šis straipsnis nagrinėja identišką puslapį aprašytą ketvirtoje ir penktoje dalyse, bet vietoje BLOB saugyklos naudojama esybių lentelių saugykla.
Šioje dalyje mes panaudosime prieš tai sukonfigūruotą lokalią esybių lentelių saugyklą, o vėliau pereisime ir prie realios. Kaip pavyzdį aš pateiksiu ASP.NET puslapį, kuriame galima pridėti naują failą į objektinę esybių lentelių saugyklą, atvaizduoti esamus failus, juos parsisiųsti bei ištrinti. Kaip ir 4 dalyje, visos operacijos su Windows Azure yra apvilktos į repozitorijaus (angl. repository) projektavimo šabloną.
Esybių lentelės pagrindai
Esybių lentelės (angl. tables) – tai viena iš Windows Azure objektinių saugyklų, kuri yra skirta esybių saugojimui. Lentelių saugykla yra sudaryta iš lentelių (esybių), kur kiekviena eilutė atitinka konkrečią esybę. Kiekviena esybė mažiausiai yra sudaryta iš trijų savybių: PartitionKey, RowKey ir Timestamp.Timestamp nusako esybės versiją (panašiai kaip SQL Server duomenų bazėje), PartitionKey ir RowKey kartu sudaro unikalų esybės raktą.
Jeigu turėjote reikalų su SQL serverio greitaveikos gerinimu – tikriausiai žinoti sąvoką Partitioning. Pagrindinė jos esmė – automatiškai paskirstyti duomenis tarp visų prieinamų SQL serverių, taip pagerinant bendrą duomenų bazės greitaveiką. Windows Azure esybių lentelėse įgyvendinta labai panaši technologija: PartitionKey nusako kurioje particijoje reikia ieškoti duomenų, o RowKey apibrėžia unikalų įrašo ID toje particijoje.
Taip pat norėtųsi pridėti, kad visos esybės taip pat yra pasiekiamos ADO.NET Data Services pagalba.
„Hello World“ projekto pakeitimai
Už pagrindą aš pasiėmiau 2 dalyje aprašytą „Hello World“ Windows Azure ASP.NET aplikaciją. Kadangi darbui su objektinėmis saugyklomis mums reikės nurodyti Windows Azure prisijungimo duomenis, tam HelloWorldCloud projekte reikia nueiti į nustatymus ir pridėti naują prisijungimo eilutę, kurią aš pavadinau StorageConnectionString:
Atkreipkite dėmesį, kad laikinai mes naudojame ne realius Windows Azure prisijungimo duomenis, bet lokalią saugyklą. Kitas svarbus momentas – Web rolės klasės aprašymas. Kadangi Windows Azure esybių lentelių saugykla nepriklauso nuo .NET vykdymo aplinkos (skaitykit nuo Microsoft.WindowsAzure.ServiceRuntime), reikia HelloWorldWeb projekte sukurti Web rolės klasę ir joje nusakyti kaip reaguoti į konfigūracijos failo pakeitimus. Žemiau pateiktas kodas yra nukopijuotas iš Windows Azure SDK, tikiuosi ateityje Microsoft sugalvos patogesnį sprendimą:
public class WebRole : RoleEntryPoint
{
public override bool OnStart()
{
DiagnosticMonitor.Start("DiagnosticsConnectionString");
// This code sets up a handler to update CloudStorageAccount instances when their corresponding
// configuration settings change in the service configuration file.
CloudStorageAccount.SetConfigurationSettingPublisher((settingName, configSetter) =>
{
// Provide the configSetter with the initial value
configSetter(RoleEnvironment.GetConfigurationSettingValue(settingName));
RoleEnvironment.Changed += (sender, arg) =>
{
if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
.Any(change => (change.ConfigurationSettingName == settingName)))
{
// The corresponding configuration setting has changed, propagate the value
if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(settingName)))
{
// In this case, the change to the storage account credentials in the
// service configuration is significant enough that the role needs to be
// recycled in order to use the latest settings. (for example, the
// endpoint has changed)
RoleEnvironment.RequestRecycle();
}
}
};
});
// For information on handling configuration changes
// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
RoleEnvironment.Changing += (sender, arg) =>
{
// If a configuration setting is changing
if (arg.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange))
{
// Set e.Cancel to true to restart this role instance
arg.Cancel = true;
}
};
return base.OnStart();
}
}
Puslapio sukūrimas
Kadangi puslapyje mes operuosime failais, apibrėškime klasę FileEntity, kurioje saugosime failo pavadinimą, turinio tipą bei patį failo turinį. Taip pat reikia apibrėžti anksčiau minėtas savybes PartitionKey, RowKey ir Timestamp arba tiesiog paveldėti iš TableServiceEntity (iš vardų srities Microsoft.WindowsAzure.StorageClient):
public class FileEntity : TableServiceEntity
{
public FileEntity(string partitionKey, string rowKey)
: base(partitionKey, rowKey)
{
}
public FileEntity()
: this(Guid.NewGuid().ToString(), String.Empty)
{
}
public string FileName { get; set; }
public string ContentType { get; set; }
public byte[] Data { get; set; }
}
Dabar apibrėšime repozitorijaus interfeisą su mums reikalingomis operacijomis:
public interface IFileRepository
{
IEnumerable<FileEntity> List();
FileEntity Get(Guid id);
void Insert(FileEntity file);
void Delete(FileEntity file);
void Delete(Guid id);
}
Aptarkime kiekvieno metodo paskirtį:
- metodas List skirtas pateikti esybių lentelių saugykloje saugomų failų sąrašą
- metodas Get gauna nurodytą failą
- metodas Insert įterpia į esybių lentelių saugyklą failą
- metodas Delete ištrina nurodytą failą iš esybių lentelių saugyklos
Nesigilinant į IFileRepository realizaciją, pateiksiu Web puslapio kodą:
<%@ Page Language="C#" AutoEventWireup="true"
CodeBehind="Table.aspx.cs" Inherits="HelloWorldWeb.Table" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Failų sąrašas</title>
</head>
<body>
<form id="form" runat="server">
<h1>Failai</h1>
Pridėti naują
<asp:FileUpload ID="FileUpload" runat="server" />
<asp:Button runat="server" Text="Pridėti" OnClick="UploadFile" />
<asp:ListView ID="Files" runat="server">
<LayoutTemplate>
<ul>
<li id="itemPlaceHolder" runat="server" />
</ul>
</LayoutTemplate>
<ItemTemplate>
<li>
<asp:LinkButton runat="server" Text='<%# Eval("FileName") %>'
OnCommand="DownloadFile" CommandArgument='<%# Eval("PartitionKey") %>' />
<asp:LinkButton runat="server" Text="[x]"
OnCommand="DeleteFile" CommandArgument='<%# Eval("PartitionKey") %>' />
</li>
</ItemTemplate>
</asp:ListView>
</form>
</body>
</html>
Kaip matote, puslapyje tėra failo pridėjimo elementas bei sąrašas jau pridėtų failų su galimybe ištrinti. Failų pavadinimas yra atvaizduojamas kaip nuoroda, kad galima būtų jį parsisiųsti paprastu paspaudimu. C# pusė atrodo taip:
public partial class Table : Page
{
private readonly IFileRepository repository =
new FileRepository("StorageConnectionString");
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ListFiles();
}
}
protected void UploadFile(object sender, EventArgs e)
{
if (FileUpload.HasFile)
{
var file = new FileEntity
{
FileName = FileUpload.PostedFile.FileName,
ContentType = FileUpload.PostedFile.ContentType,
Data = FileUpload.FileBytes
};
repository.Insert(file);
ListFiles();
}
}
protected void DownloadFile(object sender, CommandEventArgs e)
{
var file = repository.Get(new Guid(e.CommandArgument.ToString()));
Response.AppendHeader("content-disposition", "attachment; filename=" + file.FileName);
Response.ContentType = file.ContentType;
Response.BinaryWrite(file.Data);
Response.End();
}
protected void DeleteFile(object sender, CommandEventArgs e)
{
repository.Delete(new Guid(e.CommandArgument.ToString()));
ListFiles();
}
private void ListFiles()
{
Files.DataSource = repository.List();
Files.DataBind();
}
}
Repozitorijaus dėka, šis ASP.NET puslapis neturi jokio supratimo apie Windows Azure panaudojimą.
FileRepository įgyvendinimas
Žemiau pateikta FileRepository realizacija reikalauja nuorodų į tokias bibliotekas:
- Microsoft.WindowsAzure.ServiceRuntime.dll
- Microsoft.WindowsAzure.StorageClient.dll
- System.Data.Services.Client.dll
Atskirai norėtųsi paminėti FileRepository konstruktorių: jis priima vieną argumentą – prisijungimo prie Windows Azure saugyklos eilutės pavadinimą iš mūsų konfigūracijos failo. Kitus paaiškinimus parašiau kaip komentarus:
public class FileRepository : IFileRepository
{
private readonly TableServiceContext context;
private const string TableName = "Files";
public FileRepository(string connectionString)
{
// aprašome mūsų lentelės klientą
var storageAccount = CloudStorageAccount.FromConfigurationSetting(connectionString);
// jeigu lentelė dar neegzistuoja - sukuriame naują
storageAccount.CreateCloudTableClient().CreateTableIfNotExist(TableName);
// sukuriame lentelės kontekstą (ADO.NET data services kontekstą)
context = new TableServiceContext(storageAccount.TableEndpoint.ToString(),
storageAccount.Credentials);
}
public IEnumerable<FileEntity> List()
{
return (from f in context.CreateQuery<FileEntity>(TableName)
select f).ToList();
}
public FileEntity Get(Guid id)
{
return (from f in context.CreateQuery<FileEntity>(TableName)
where f.PartitionKey == id.ToString()
select f).SingleOrDefault();
}
public void Insert(FileEntity file)
{
context.AddObject(TableName, file);
context.SaveChanges();
}
public void Delete(FileEntity file)
{
context.AttachTo(TableName, file);
context.DeleteObject(file);
context.SaveChanges();
}
public void Delete(Guid id)
{
var file = Get(id);
if (file != null)
{
context.DeleteObject(file);
context.SaveChanges();
}
}
}
Esybių lentelių saugyklos sukūrimas
Iki šiol esybių lentelių saugyklos testavimui mes naudojome taip vadinamą „Development Storage“. Norėdami išpublikuoti mūsų Windows Azure aplikaciją į debesis, pirma reikia sukurti saugyklą Windows Azure portale. Įvedus norimą saugyklos pavadinimą bei adresą, jus pamatysite panašų vaizdą:
Iš paveiksliuko matyti, kad mano saugyklos pavadinimas yra Files, o nuoroda – http://sergejus.table.core.windows.net. Taip pat žemiau pateikiami kodai, kurių pagalba galima prisijungti ir dirbti su saugykla iš aplikacijos.
Pakeitimai konfigūracijos faile
Turėdami egzistuojančią Windows Azure esybių lentelių saugyklą, belieka nueiti į WindowsCloudWeb projekto konfigūracijos failą ir jame pakeisti prisijungimo eilutės StorageConnectionString reikšmę į prieš tai sukurtos saugyklos duomenis. Account name laukelyje reikia įvesti jūsų esybių lentelių saugyklos nuorodos pradžią (viskas kas iki table.core.windows.net, mano atveju – sergejus). Account key laukelyje įveskite Primary Access Key kodą:
Svarbu pažymėti, kad naujus esybių lentelių saugyklos duomenis reikia nurodyti ne tik StorageConnectionString prisijungimo eilutėje, bet ir standartinėje DiagnosticsConnectionString prisijungimo eilutėje.
Tam kad patikrinti, ar saugykla veikia, užtenka paleisti aplikaciją derinimui. Įsitikinus, kad viskas veikia kaip numatyta, galite išpublikuoti aplikaciją į Windows Azure kaip buvo aprašyta antroje dalyje.
Veikiantį programos pavyzdį galite rasti adresu http://hellocloud.cloudapp.net/Table.aspx.
Kitoje dalyje…
Mes pratęsime nagrinėti Windows Azure saugyklas ir iš arčiau pasižiūrėsime į eiles (angl. queues).
Rodyk draugams
Naujausi komentarai