CloudAPI – Envio de arquivos para Amazon S3 e Windows Azure – Parte 2

Nesta segunda e última parte do artigo sobre envio de arquivos para as nuvens vamos detalhar como funciona o envio de arquivos para o para Amazon S3.

Você pode ler os artigos que antecedem estas sequência nos links abaixo, é importante ler estes artigos para melhor entendimento deste artigo:

Na primeira parte do artigo descrevo como obter sua conta no Amazon e os significados do Bucket e Blog, considerando que você leu os artigos anteriores nos resta saber como funciona o CloudAPI para envio de arquivos para o Amazon S3, que é bem parecido ao do Windows Azure.

Envio de arquivos para Amazon S3

A implementação do Shell Extension utiliza o método UploadtoAmazon (CloudDM.pas) para o envio de arquivos para o Amazon S3, antes de enviar o arquivo temos definir em qual pasta (Bucket) será armazenado este arquivo.

Como o bucket pode não existir, ou o usuário pode querer criar um novo, implementei um formulário que permite o usuário selecionar um bucket já existente ou criar um novo.

Abaixo parte do código responsável pelo envio do arquivo, as linhas em destaque refletem o código que irá listar e criar ou selecionar o bucket.

Ao fazer uma solicitação ao Amazon S3 através do CloudAPI a maioria dos métodos retorna um objeto do tipo TCloudResponseInfo, este objeto contém o status do retorno referente a sua solicitação, todas estas solicitações são chamadas REST.

Para obter a lista de buckets utilizamos o método ListBuckets que é parte do objeto StorageService instanciando anteriormente, todos os serviços relacionados a Storage fazem parte desta classe, assim como a criação do bucket através do método CreateBucket.

Amazon e Windows Azure diferem no que diz respeito ao suporte a metadata na criação do container/bucket, Amazon não suporta metadata enquanto Windows Azure sim.

function TCloud.UploadtoAmazon(FileName: String): TCloudResponseInfo;
var
  StorageService: TAmazonStorageService;
  BucketList, Metadata: TStrings;
  Content: TBytes;
  ResponseList: TCloudResponseInfo;
  FrmList: TFrmContainerList;
  Act: TContainerAction;
  BucketName: String;
  I: Integer;
begin
  Result := TCloudResponseInfo.Create;

  if (FileName = EmptyStr) then
    Exit;

  StorageService := TAmazonStorageService.Create(AmazonConnection);

{$REGION 'Define the Bucket'}
  ResponseList := TCloudResponseInfo.Create;
  BucketList := StorageService.ListBuckets(ResponseList);

  if ResponseList.StatusCode = 200 then
  begin

    // Amazon return date/time information for each Bucket
    // this for is required to remove that information
    for I := 0 to BucketList.Count - 1 do
      BucketList[I] := BucketList.Names[I];

    FrmList := TFrmContainerList.Create(nil, BucketList, TClouds[AmazonIndex]);
    try
      FrmList.ShowModal;
      Act := FrmList.Action;

      case Act of
        caCreate:
          begin
            if StorageService.CreateBucket(FrmList.Container, amzbaNotSpecified,
              amzrNotSpecified, Result) then
              BucketName := FrmList.Container;
          end;
        caUpload:
          begin
            BucketName := FrmList.Container;
          end;
      end;
    finally
      FrmList.Free;
    end;

    if Act = TContainerAction.caNone then
      Exit;

  end;

 

Com o bucket definido podemos adiante e preparar o envio do arquivo.

Para o envio do arquivo utilizamos o método StorageService.UploadObject que contém diversos parâmetros como: nome e o conteúdo do arquivo em TBytes, metadata e alguns outros que não são necessários para este exemplo. Você deve utilizar alguma função para fazer o encode do nome do arquivo, por exemplo  TIdURI.URLEncode(str).

Podemos adicionar metadata ao arquivo, neste exemplo adiciono o nome do computador\usuário e a localização original do arquivo a ser enviado.

    Metadata.Clear;
    Metadata.Values[SMDPath] := ExtractFilePath(FileName);
    Metadata.Values[SMDFrom] := GetComputerandUserName;

    Content := ContentOf(FileName);
    BlobName := ExtractFileName(FileName);

O método ContentOf retorna o conteúdo do arquivo em TBytes.

function TCloud.ContentOf(const FileName: String;
  RequiredSizeMod: Integer): TBytes;
var
  fs: TFileStream;
begin
  if FileName <> EmptyStr then
  begin
    fs := TFileStream.Create(FileName, fmOpenRead);
    try
      if RequiredSizeMod < 1 then
        SetLength(Result, fs.Size)
      else
        SetLength(Result, ((fs.Size div RequiredSizeMod) + 1) *
          RequiredSizeMod);
      fs.ReadBuffer(Result[0], fs.Size);
    finally
      fs.Free;
    end;
  end
  else
    SetLength(Result, 0);

end;

O resultado do envio será um parâmetro de saída do tipo TCloudResponseInfo, este contém a propriedade StatusCode, requisições realizadas com sucesso retornam o código 200 ou 201.

    StorageService.UploadObject(BucketName, ExtractFileName(FileName), Content, False, Metadata, nil, amzbaPublicRead, Result);
    ShowResponseInfo(TClouds[AmazonIndex], Result);

Clique aqui para visualizar o código fonte da unit CloudDM.pas.

O código fonte completo está disponível no repositório do RAD Studio XE2 no sourceforge e as informações para efetuar o download dos fontes completo estão disponíveis aqui.
Nesta sequência de artigos você pode aprender a criar Shell Extensions, compilar pra 32-bit e 64 bit e utilizar o CloudAPI, vale lembrar que o ClouAPI traz muitas outras API’s para interagir com as nuvens

1 responder

Deixe uma resposta

Want to join the discussion?
Feel free to contribute!

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *


Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.