Projeto SitkaLibrary exemplo para SSDS.
Olá pessoal, tudo certo?
Durante o Tech-Ed Brasil 2008, apresentei a sessão ACP301 - Introdução ao SQL Server Data Services, um dos principais serviços online da plataforma Microsoft na nuvem. Algumas pessoas me pediram os exemplos que utilizei durante as demos.
Em primeiro lugar, o serviço exige uma credencial USERNAME/PASSWORD para ser acessado. Você pode obter sua credencial através do link abaixo, via registro no programa Beta do SSDS.
Ref.: https://www.microsoft.com/sql/dataservices/default.mspx
Usando essas credenciais, você pode utilizar o SSDS SDK (diga isso 3 vezes :) para exercitar os conceitos "ACE", AUTHORITY, CONTAINER e ENTITY. O console do SSDS Explorer oferece os templates de criação "ACE", que deverão ser usados por sua aplicação. Faça o donwload do SDK no link abaixo. Lembre-se que esse pacote ainda é Beta.
Finalmente, você pode construir uma solução no Visual Studio 2008 com dois projetos básicos: um projeto com a Service Reference para o serviço SSDS e um projeto com sua aplicação cliente, usuária do serviço, como vemos abaixo:
Note que no exemplo, temos uma biblioteca básica de serviços SSDS chamada SitkaLibrary. Esse projeto encapsula a Service Reference para o SSDS. Também, podemos implementar uma classe chamada SitkaClass, que contém os principais métodos de manipulação de Authority, Container e Entity. Esses códigos podem ser obtidos do site do MSDN, a partir do link abaixo:
Ref.: https://msdn.microsoft.com/pt-br/library/cc512417(en-us).aspx
Para uma ajudinha, segue o código-fonte da biblioteca criada:
1: using System;
2: using System.IO;
3: using System.Net;
4: using System.Text;
5:
6: namespace CreateAuthority
7: {
8: public class SitkaClass
9: {
10: public const string sampleAuthorityId = "";
11: public const string sampleContainerId = "";
12: public const string sampleEntityId = "";
13: public const string userName = "";
14: public const string password = "";
15:
16: /// <summary>
17: /// SitkaClass
18: /// </summary>
19: public SitkaClass()
20: {
21: }
22:
23: /// <summary>
24: /// CreateAuthority
25: /// </summary>
26: /// <param name="serviceUri"></param>
27: /// <returns></returns>
28: public static string CreateAuthority(string serviceUri)
29: {
30: const string AuthorityTemplate =
31: @"<s:Authority xmlns:s='https://schemas.microsoft.com/sitka/2008/03/'>
32: <s:Id>{0}</s:Id>
33: </s:Authority>";
34:
35: if (String.IsNullOrEmpty(serviceUri))
36: {
37: throw new ArgumentOutOfRangeException("ServiceUri");
38: }
39:
40: string authorityUri = null;
41: try
42: {
43: string requestPayload = string.Format(AuthorityTemplate, sampleAuthorityId);
44: HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(serviceUri);
45: request.Credentials = new NetworkCredential(userName, password);
46:
47: // POST=create; PUT=update; DELETE=delete; GET=retrieve
48: request.Method = "POST";
49: UTF8Encoding encoding = new UTF8Encoding();
50: request.ContentLength = encoding.GetByteCount(requestPayload);
51: request.ContentType = "application/x-ssds+xml";
52:
53: using (Stream reqStm = request.GetRequestStream())
54: {
55: reqStm.Write(encoding.GetBytes(requestPayload), 0, encoding.GetByteCount(requestPayload));
56: }
57:
58: using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
59: {
60: if (response.StatusCode == HttpStatusCode.Created)
61: {
62: Console.WriteLine("Authority created");
63: authorityUri = String.Format("https://{0}.data.beta.mssds.com/v1/", sampleAuthorityId);
64: }
65: else
66: {
67: Console.WriteLine("Failed to create authority");
68: }
69: }
70: }
71: catch (WebException ex)
72: {
73: using (HttpWebResponse response = ex.Response as HttpWebResponse)
74: {
75: if (response != null)
76: {
77: string errorMsg = ReadResponse(response);
78: Console.WriteLine(string.Format("Error: {0}", errorMsg));
79: Console.WriteLine("Unexpected status code returned: {0} ", response.StatusCode);
80: }
81: }
82: }
83: return authorityUri;
84: }
85:
86: /// <summary>
87: /// CreateContainer
88: /// </summary>
89: /// <param name="authorityUri"></param>
90: /// <returns></returns>
91: public static string CreateContainer(string authorityUri)
92: {
93: const string ssdsContentType = "application/x-ssds+xml";
94:
95: if (String.IsNullOrEmpty(authorityUri))
96: {
97: throw new ArgumentOutOfRangeException("AuthorityUri");
98: }
99: string containerUri = null;
100: try
101: {
102: const string ContainerTemplate =
103: @"<s:Container xmlns:s='https://schemas.microsoft.com/sitka/2008/03/'>
104: <s:Id>{0}</s:Id>
105: </s:Container>";
106:
107: string requestPayload = string.Format(ContainerTemplate, sampleContainerId);
108: HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(authorityUri);
109: request.Credentials = new NetworkCredential(userName, password);
110:
111: // POST=create; PUT=update; DELETE=delete; GET=retrieve
112: request.Method = "POST";
113: UTF8Encoding encoding = new UTF8Encoding();
114: request.ContentLength = encoding.GetByteCount(requestPayload);
115: request.ContentType = ssdsContentType;
116:
117: using (Stream reqStm = request.GetRequestStream())
118: {
119: reqStm.Write(encoding.GetBytes(requestPayload), 0,
120: encoding.GetByteCount(requestPayload));
121: }
122:
123: using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
124: {
125: if (response.StatusCode == HttpStatusCode.Created)
126: {
127: Console.WriteLine("Container created. System assigned container version: {0}", response.Headers["ETag"]);
128: containerUri = string.Format("{0}/{1}", authorityUri, sampleContainerId);
129: }
130: else
131: {
132: Console.WriteLine("Failed to create container");
133: }
134: }
135: }
136: catch (WebException ex)
137: {
138: using (HttpWebResponse response = ex.Response as HttpWebResponse)
139: {
140: if (response != null)
141: {
142: string errorMsg = ReadResponse(response);
143: Console.WriteLine(string.Format("Error: {0}", errorMsg));
144: Console.WriteLine("Unexpected status code returned: {0} ", response.StatusCode);
145: }
146: }
147: }
148:
149: return containerUri;
150: }
151:
152: /// <summary>
153: /// CreateEntityTemplate
154: /// </summary>
155: /// <param name="id"></param>
156: /// <param name="title"></param>
157: /// <param name="summary"></param>
158: /// <param name="isbn"></param>
159: /// <returns></returns>
160: public static string CreateEntityTemplate(string id, string title, string summary, string isbn)
161: {
162: const string EntityTemplate =
163: @"<Book xmlns:s='https://schemas.microsoft.com/sitka/2008/03/'
164: xmlns:xsi='https://www.w3.org/2001/XMLSchema-instance'
165: xmlns:x='https://www.w3.org/2001/XMLSchema' >
166: <s:Id>{0}</s:Id>
167: <title xsi:type='x:string'>{1}</title>
168: <summary xsi:type='x:string'>{2}</summary>
169: <isbn xsi:type='x:string'>{3}</isbn>
170: </Book>";
171: return String.Format(EntityTemplate, id, title, summary, isbn);
172: }
173:
174: /// <summary>
175: /// CreateEntity
176: /// </summary>
177: /// <param name="containerUri"></param>
178: /// <param name="requestPayload"></param>
179: /// <returns></returns>
180: public static string CreateEntity(string containerUri, string requestPayload)
181: {
182: const string HttpPostMethod = "POST";
183: const string ssdsContentType = "application/x-ssds+xml";
184: string entityUri = null;
185: if (String.IsNullOrEmpty(containerUri))
186: {
187: throw new ArgumentOutOfRangeException(containerUri);
188: }
189: if (String.IsNullOrEmpty(requestPayload))
190: {
191: throw new ArgumentOutOfRangeException(requestPayload);
192: }
193: try
194: {
195: WebRequest request = HttpWebRequest.Create(containerUri);
196: request.Credentials = new NetworkCredential(userName, password);
197:
198: // POST=create; PUT=update; DELETE=delete; GET=retrieve
199: request.Method = HttpPostMethod;
200: UTF8Encoding encoding = new UTF8Encoding();
201: request.ContentLength = encoding.GetByteCount(requestPayload);
202: request.ContentType = ssdsContentType;
203:
204: using (Stream reqStm = request.GetRequestStream())
205: {
206: reqStm.Write(encoding.GetBytes(requestPayload), 0,
207: encoding.GetByteCount(requestPayload));
208: }
209:
210: using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
211: {
212:
213: if (response.StatusCode == HttpStatusCode.Created)
214: {
215: Console.WriteLine("Entity created. System assigned version: {0}", response.Headers["ETag"]);
216: entityUri = string.Format(containerUri + "/" + sampleEntityId);
217: }
218: else
219: {
220: Console.WriteLine("Unexpected status code returned: {0}", response.StatusCode);
221: }
222: }
223: }
224: catch (WebException ex)
225: {
226: using (HttpWebResponse response = ex.Response as HttpWebResponse)
227: {
228: if (response != null)
229: {
230: string errorMsg = ReadResponse(response);
231: Console.WriteLine(string.Format("Error:{0}", errorMsg));
232: Console.WriteLine("Unexpected status code returned: {0} ", response.StatusCode);
233: }
234: }
235: }
236:
237: return entityUri;
238: }
239:
240: /// <summary>
241: /// GetEntity
242: /// </summary>
243: /// <param name="entityUri"></param>
244: /// <returns></returns>
245: public static string GetEntity(string entityUri)
246: {
247: string data = null;
248: const string ssdsContentType = "application/x-ssds+xml";
249:
250: if (string.IsNullOrEmpty(entityUri))
251: {
252: throw new ArgumentOutOfRangeException("entityUri");
253: }
254: try
255: {
256: WebRequest request = HttpWebRequest.Create(entityUri);
257: request.Method = "GET";
258: request.ContentType = ssdsContentType;
259: request.Credentials = new NetworkCredential(userName, password);
260: using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
261: {
262: data = ReadResponse(response);
263: if (response.StatusCode != HttpStatusCode.OK)
264: {
265: Console.WriteLine("Error: {0}", data);
266: Console.WriteLine("Unexpected status code returned: {0}", response.StatusCode);
267: }
268: }
269: }
270: catch (WebException ex)
271: {
272: using (HttpWebResponse response = ex.Response as HttpWebResponse)
273: {
274: if (response != null)
275: {
276: string errorMsg = ReadResponse(response);
277: Console.WriteLine("Error:{0}", errorMsg);
278: Console.WriteLine("Unexpected status code returned: {0}", response.StatusCode);
279: throw ex;
280: }
281: }
282: }
283: return data;
284: }
285:
286: /// <summary>
287: /// ReadResponse
288: /// </summary>
289: /// <param name="response"></param>
290: /// <returns></returns>
291: public static string ReadResponse(HttpWebResponse response)
292: {
293: if (response == null)
294: {
295: throw new ArgumentNullException("response", "Value cannot be null");
296: }
297: string responseBody = "";
298: using (StreamReader reader = new StreamReader(response.GetResponseStream()))
299: {
300: responseBody = reader.ReadToEnd();
301: reader.Close();
302: }
303: return responseBody;
304: }
305:
306: }
307: }
Como vimos, o código acima implementa alguns dos métodos disponíveis para uma interface REST do serviço SSDS. Outros métodos que você pode adicionar são para consultar Authority, Container, atualizar Entity, deletar Entity, deletar Container, etc.
Semana que vem teremos o PDC 2008, a Professional Development Conference da Microsoft, que promete uma série de novidades sobre o SSDS, assim como o anúncio de novas features para o serviço.
Desde já, fique ligado com as novidades que estarei publicando aqui no blog, durante o evento.
Por enquanto é só! Até o próximo post :)
Waldemir.
Comments
- Anonymous
October 23, 2008
Vc poderia explicar quais as diferenças,semelhanças e aplicações para: 1.SSDS 2.Ado.NetData Service
- Astoria Grato
- Anonymous
October 23, 2008
Olá Lobo, tudo certo? Obrigado pelos comentários no blog. Rapidamente, SSDS é o Microsoft SQL Server Data Services (codenome "Sitka"), um serviço building block da composição de serviços online da Microsoft, que oferece um banco de dados virtual na nuvem (internet), ou seja, hosteado nos datacenters da Microsoft pelo mundo. De fato, não é um banco relacional tradicional, mas sim um repositório de dados não estruturados, para alta escalabilidade e armazenamento massivo. O ADO.NET Data Services (codenome "Astoria") é a interface de publicação REST para banco de dados locais ou no enterprise, que permite a exposição de dados de um banco relacional para aplicações web. Veja que essa interface ADO.NET está sobre o ADO.NET Entity Framework, o que permite abstração não apenas de bancos relacionais, mas qualquer tipo de fontes de dados, como arquivos XML, texto, objetos, etc. Publiquei recentemente um artigo que fala mais detalhes dos dois projetos, veja: Uma introdução sobre o SQL Server Data Services (codinome “Sitka”) e o ADO.NET Data Services (codinome “Astoria”). Por Waldemir Cambiucci Ref.: http://www.microsoft.com/brasil/msdn/arquitetura/Journal/IntroducaoSQLServerDataServices_ADO.NETDataServices.mspx Um abraço! Waldemir.