Este artigo foi traduzido por máquina.

Previsão: Nublado

Colocando o conteúdo do SharePoint no armazenamento do Windows Azure

Joseph Fultz

Baixar o exemplo de código

Eu tenho um co-autor deste mês, como o colega que Shad Phillips me ajudou com um recente projeto onde eu estava trabalhando com um cliente em uma prova de conceito usado SharePoint 2010 como uma plataforma de aplicativos. Do lado, um dos funcionários do cliente me perguntou se eu poderia pensar de uma maneira razoável de levar conteúdo aprovado do SharePoint e publicá-lo, tornando-o disponível para pessoas fora da rede corporativa.

Infra-estrutura atual do cliente não suporta conteúdo externo (vídeos e documentos para download). Tendo feito um monte de trabalho com Windows Azure, imediatamente pensei que seria bastante simple para incorporar empurrando o conteúdo para o armazenamento de Azure Windows como parte do fluxo de trabalho e, em seguida, dependendo precisa, tornando-se publicamente disponíveis ou fornecendo acesso com base em locação para restringidos conteúdo.

Com isso em mente, eu falei com o meu colega, Shad, que anteriormente tinha resolvido um problema semelhante onde ele tinha implementado um método de amostra para arquivar documentos do SharePoint da biblioteca do Windows Azure armazenamento. Embora a intenção de que a solução é diferente do meu objetivo, a mecânica é os mesmos. Este mês, sável e eu andará com uma implementação de exemplo que empurra conteúdo do SharePoint para Windows Azure armazenamento e capa um pouco mais sobre controle de locação-acesso aos arquivos.

Cenário e configuração

Especificamente, nós desenvolvemos um recurso personalizado que permite que um usuário seletivamente enviar um documento do SharePoint para Windows Azure armazenamento. Por alguma razão inexplicável, os usuários não normalmente gostam quando seus documentos são movidos e não são fornecidos links para encontrá-los, assim que saímos de um link na biblioteca de documentos para o local de nuvem que se comporta da mesma como seria se o documento fosse em um local não-cloud.

Software necessário:

  • Visual Studio 2010
  • Microsoft SharePoint 2010
  • Windows SDK Azure
  • Serviço de azul-celeste de desenvolvimento de armazenamento do Windows

Site do SharePoint 2010 e configuração da biblioteca de documento

Para este cenário, criamos um site do SharePoint usando o modelo de Site de equipe. Na biblioteca de documentos compartilhados, criamos uma coluna que permite-nos sinalizar um item como arquivados para Windows Azure. Isso é feito através das configurações de biblioteca acessível através da faixa de opções. Uma vez nas configurações da biblioteca, criamos uma coluna com propriedades ilustradas em de Figura 1.

image: Column Settings on the Team Site Template

Figura 1 de configurações de coluna no modelo de Site de equipe

Em configurações avançadas, nós também seleccionado "Sim" para a configuração "Permitir o gerenciamento de tipos de conteúdo".

Nós usamos isso como parte do tipo de conteúdo que temos denominado Link para um documento. Em seguida, criamos instâncias desse tipo de conteúdo como um meio de link para o documento arquivado, como mostrado em de Figura 2.

image: Our New “Link to a Document” Content Type

Figura 2 de nosso novo tipo de conteúdo "Link para um documento"

Depois que a coluna e o tipo de conteúdo foram adicionados à biblioteca de documentos, enviou um documento do Word exemplo chamado SOW.docx de serviços.

SharePoint 2010 Web. config

Para conectar-se a nuvem, precisávamos obter as configurações necessárias para conectar-se com Windows Azure. Neste caso, nós usou o armazenamento de desenvolvimento e acrescentou as chaves para o <appSettings>elemento em Web. config, como mostrado em de Figura 3.

image: Adding Keys in Web.config

Figura 3 Adicionando chaves no Web. config

Projeto do SharePoint

Felizmente, para o SharePoint 2010 usando Visual Studio 2010, é uma experiência agradável do desenvolvedor para criar, Depurar e publicar novos recursos. Nós criamos um recurso do SharePoint (ver msdn.microsoft.com/library/bb861828(office.12) de para obter mais informações sobre isso), que adiciona uma ação personalizada para menus de drop-down de ação dos itens na biblioteca de documentos. O usuário clicará para usar o recurso de arquivamento.

Começamos criando uma solução chamada MSSAzureArchive usando o modelo de projeto vazio do SharePoint (consulte de Figura 4).

image: Project Selection in Visual Studio 2010

Figura 4 de seleção de projetos no Visual Studio 2010

Em seguida, especificamos o nível de segurança e site para depuração. Estamos decididos a escolha "Implantar como uma solução de farm" porque o código vai precisarfazer chamadas externas, que não vai permitir que a solução no modo seguro. As referências necessárias para ser adicionado ao projeto deMicrosoft.Windows.Azure.StorageClient e System. Web. Em seguida, adicionamos um item de elemento vazio para o projeto usando o modelo de EmptyElement e échamado AzureStorageElement. Nós adicionamos um <CustomAction/>elemento para adicionar um novo item de ação para o menu de contexto para os itens dabiblioteca de documento (consulte de Figura 5).

image: Adding an AzureStorageElement via Add New Item

Figura 5 do adicionando um AzureStorageElement através de adicionar Novo Item

Um novo recurso chamado Feature1 foi adicionado automaticamente ao projeto, que nós renomeado para MSSAzureArchive. Substituímos o conteúdo do arquivo elements para o AzureStorageElement que foi adicionado com o seguinte:

<?xml version="1.0" encoding="utf-8"?>
 <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   <CustomAction
     Id="UserInterfaceCustomActions.ECBItemToolbar"
     RegistrationType="List"
     RegistrationId="101"
     Location="EditControlBlock"
     Sequence="106"
     Title="Azure Storage">
     <UrlAction Url="~sitecollection/
       _layouts/MSSAzureArchive/
       AzureStorage.aspx?ItemUrl={ItemUrl}" />
   </CustomAction>
 </Elements>

Para o desenvolvedor do SharePoint uninitiated, de Figura 6 mostra uma breve descrição de alguns do <CustomAction/>Propriedades (mais informações sobre o <CustomAction/>elemento e suas propriedades podem ser encontradas em msdn.microsoft.com/library/ms460194 ).

Figura 6 Propriedades da <CustomAction/>Elemento

Propriedade. Função
ID Identificador exclusivo.
Localização Especifica onde o elemento deve aparecer na interface do usuário do SharePoint. Neste caso, o item de menu (EditControlBlock) é o local desejado versus, por exemplo, a faixa de opções.
Seqüência Especifica a prioridade de classificação para as ações.

Observe a propriedade Url do elemento UrlAction.Esta é a acção de navegação que acontece para lidar com o comando para arquivar o documento. Com base nessa configuração, SharePoint sabe onde colocar o recurso na interface do usuário e também o que fazer quando alguém clica nele. SharePoint irá navegar para uma página que criamos que manipulará o arquivamento do documento selecionado. Esta página permitirá que o usuário selecione um recipiente de armazenamento de destino ou criar um novo recipiente de armazenamento para o item, assim que precisávamos para adicionar um item de página do aplicativo para o projeto. Mais uma vez usando os modelos de SharePoint 2010, escolhemos o modelo de página de aplicativo e é chamado AzureStorage.aspx (consulte a Figura 7).

image: Adding a New Page in SharePoint 2010

A Figura 7 do adicionando uma nova página no SharePoint 2010

Porque este exemplo não era para impressionar qualquer um com um design de interface do usuário de gênio, nós adicionamos apenas mínimos controles necessários para fazer o trabalho. Em < asp: Content >elemento de marcação da página, nós adicionamos o código mostrado em de Figura 8.

Figura 8 do Adicionando controles mínimo necessário

Document to Archive:
<asp:Label ID="fileName" runat="server" ></asp:Label>   <br/>   
Choose Azure Container:
<asp:DropDownList ID="azureContainers" runat="server"  
  Visible="true"></asp:DropDownList>   
<asp:TextBox id="newContainerName" runat="server" Visible="false"></asp:TextBox>
<asp:Button ID="saveContainer" runat="server" Text="Save Container" 
  OnClick="SaveContainer_Click" Visible="false"></asp:Button>
<br />
<asp:Button ID="createContainer" runat="server" Text="Create New Container" 
  OnClick="CreateContainer_Click" />
<br/>
<asp:Button ID="archiveFile" runat="server" Text="Archive File" 
  OnClick="Archive_Click" />       
<br/>
<asp:Label ID="errMessage" runat="server" Text=""></asp:Label>

Em seguida, temos editado o code-behind e com fio os elementos de interface do usuário para algum código para conversar com Windows Azure armazenamento e processado a informação. Inicializado o cliente de armazenamento de nuvem dentro do evento de carga para a página e agarrou os recipientes disponíveis usando as configurações de Web. config anteriores (ver de Figura 9).

Figura 9 do inicializar o cliente de armazenamento de nuvem

protected void Page_Load(object sender, EventArgs e)
{

  this.InitializeCloudStorage();
  if (!IsPostBack)
  {
    this.GetContainers();
  }
}

private void GetContainers()
{
  IEnumerable<CloudBlobContainer> blobContainers =  
    cloudBlobClient.ListContainers();

  this.azureContainers.DataSource = blobContainers;
  azureContainers.DataTextField = "Name";
  this.azureContainers.DataBind();
  if (azureContainers.Items.Count < 1)
  {
    ListItem defaultContainer = new ListItem(defaultContainerName);
    defaultContainer.Selected = true;
    azureContainers.Items.Add(defaultContainer);
  }
}

Porque o foco aqui é sobre a funcionalidade de arquivamento, concentrámo-nos sobre isso. O código está disponível através de download ( code.msdn.microsoft.com/mag201012Cloudy ). Adicionamos um manipulador de click do botão archiveFile e com fio a função Archive_Click para ele. Com base no elemento UrlAction, podemos recuperar o caminho para o item. Na função de clique, o item é buscado do SharePoint usando o modelo de objeto, verificado para ver se ele já foi arquivado e — se não — carregado para o recipiente selecionado (consulte de Figura 10).

Figura 10 de código para a função de clique para buscar o Item do SharePoint

protected void Archive_Click(object o, EventArgs e)
{
  try
  {
    webSite = SPContext.Current.Web;
    filePath = webSite.Url.ToString() + 
    Request.QueryString["ItemUrl"].ToString();
    fileToArchive = webSite.GetFile(filePath);
    string sArchived = fileToArchive.Item["IsArchived"].ToString(); 

    bool isArchived = Convert.ToBoolean(sArchived);

    if (isArchived)
    {
      errMessage.Text = "This document has already been archived!";
    }
    else
    {
      string newGuid = Guid.NewGuid().ToString();
      string uniqueBlobName = string.Format(newGuid + "_" + 
        fileToArchive.Name.ToString());

      blobContainer = cloudBlobClient.GetContainerReference(
        this.azureContainers.SelectedValue);
      blobContainer.CreateIfNotExist();
      cloudBlob = blobContainer.GetBlockBlobReference(uniqueBlobName);
      cloudBlob.UploadByteArray(fileToArchive.OpenBinary());

Depois que o item é carregado para o armazenamento, um novo item de arquivo do tipo "Link para um documento" é criado no lugar do documento original e o documento original é excluído. Se isso fosse um publicação caso em vez de arquivamento, o item original provavelmente não iria ser excluído, mas prefiro apenas marcado como publicado com um link para a versão publicada. O item original é usado para obter a biblioteca de documentos de destino e o caminho do documento original. O novo item é marcado como arquivados por adicionar a propriedade de IsArchived e atribuir o valor "true". Pela primeira vez fizemos algum trabalho para obter alguns dos valores que precisávamos e, em seguida, criamos o novo item e os valores atribuídos a ele, como mostrado aqui:

SPDocumentLibrary docLib = 
  fileToArchive.DocumentLibrary;

Hashtable docProperties = new Hashtable();
docProperties["IsArchived"] = true;
string docLibRelPath = 
  docLib.RootFolder.ServerRelativeUrl;
string docLibPath = string.Empty;
webSiteCollection = SPContext.Current.Site;
docLibPath = 
  webSiteCollection.MakeFullUrl(docLibRelPath);

string azureURL = cloudBlob.Uri.ToString();

A função BuildLinkToItem cria uma instância do tipo de conteúdo "Link para um documento" usando o caminho para o item no armazenamento do Windows Azure. Esta instância do tipo de conteúdo será adicionada à biblioteca como o link para recuperar o item de armazenamento de Azure Windows via a interface do usuário do SharePoint, como mostrado aqui:

string azureStub = this.BuildLinkToItem(azureURL).ToString();

  SPFile newFile = webSite.Files.Add(documentPath,     
    UTF8Encoding.UTF8.GetBytes(azureStub), docProperties, true);

  SPListItem item = newFile.Item;
  item["Content Type"] = "Link to a Document";
  SPFieldUrlValue itemUrl = new SPFieldUrlValue();
  itemUrl.Description = fileToArchive.Name;
  itemUrl.Url = azureURL;
  item["URL"] = itemUrl;
  item["IsArchived"] = true;
  item.Update();
  fileToArchive.Delete();

Com o código concluído para salvar o documento, movê-lo e substituí-lo com um link para o armazenamento do Windows Azure, era hora de concentrar-se a compilação e implantação da solução. Duplo clique no arquivo Package.package para abrir o designer de pacote e posteriormente selecionadas na guia Avançado na parte inferior da tela. Isso é onde nós adicionamos os assemblies de pacote que precisávamos para incluir o Microsoft.WindowsAzure.StorageClient.dll. Manter as coisas simples para este exemplo, definimos o destino de implantação para o GlobalAssemblyCache. Assegurámos que armazenamento de desenvolvimento estava funcionando navegando para o Gerenciador de servidores, clicando no nó de armazenamento do Windows Azure e, em seguida, clicando no nó "(desenvolvimento)".

Jogando cautela ao vento, nós pressionado F5 para criar, implantar, anexar a um processo e iniciar uma sessão de navegador para iniciar nosso recurso de depuração. Navega-se voltar para a biblioteca de documentos compartilhados mencionada anteriormente e abriu o drop-down menu anexado ao documento que são carregados anteriormente. No drop-down, escolhemos nosso novo elemento, armazenamento de Azure, que nos levou para a página de aplicativo personalizado para selecionar o recipiente de destino (consulte de Figura 11).

image: Selecting the Azure Storage Element

Figura 11 do selecionando o elemento de armazenamento Azure Windows

Uma vez na página, poderia ter criado um novo recipiente, mas em vez disso, usamos o contêiner de documentos que criamos e clicado no botão de arquivo morto para executar o código de anteriormente (ver de Figura 12).

image: Selecting the Container

Figura 12 selecionando o contêiner de

Com o arquivo arquivado no Windows Azure Storage, navegou Voltar à biblioteca de documentos compartilhados. Em vez de ver o documento, vimos um Link para um item de documento substituído o documento do Word de SOW.docx de serviços (ver de Figura 13).

image: Link to Document in the SharePoint Documents Library

Figura 13 de Link para documentos na biblioteca de documentos do SharePoint

Quando olhamos para as propriedades do item, vimos os campos relacionados ao tipo de conteúdo, e em particular a URL para onde o documento agora reside em Windows Azure armazenamento (veja de Figura 14).

image: Link Properties

Figura 14 de Link Propriedades

Nós foi possível abrir o documento diretamente do Windows Azure armazenamento clicando no Link para um documento. Nós poderia usar a propriedade URL para acessá-lo diretamente ou por meio de algum outro código ou interface do usuário. Por exemplo, se queríamos ainda indexar esses itens por meio do serviço de índice do SharePoint, nós poderia criar um IFilter personalizado que sabe como processar meu Link para um tipo de conteúdo de documento para garantir que o conteúdo seria obter indexado corretamente.

Com a implementação do arquivamento de conteúdo de uma biblioteca de documentos do SharePoint em um contêiner de Windows Azure armazenamento fora do caminho, ele deixou-nos apenas público ou sem acesso a documentos arquivados para não autenticado solicitações.

Controle de acesso ao publicar

Como mencionado anteriormente, o que levam-me a falar com Shad sua peça arquivamento foi o uso do Windows Azure armazenamento como um meio para fornecer um público inicial no local para o conteúdo que tinha ido através de revisão e aprovação. No caso em que eu estava pensando, eu não tive que incluir qualquer controle de acesso, porque os documentos estavam a ser compartilhado com todos. No entanto, levou apenas alguns minutos de alguém para fazer a pergunta: "E se queremos publicar algo e torná-lo disponível apenas para algumas pessoas, por exemplo, fornecedores, clientes ou funcionários?" Muitas vezes uma tarefa como esta é realizada dentro das empresas, incluindo as pessoas como parte de um domínio corporativo ou tê-los de alguma forma federado para eles estão identificados através do desafio de nome de usuário e senha. Este não era o caso aqui, e o cliente realmente não quero configurar alguns de camada de aplicativo ou front-end para controlar o acesso;desenvolver o front-end reduziria o valor, aumentando os custos de implementação.

Uma solução é usar um SharedAccessPolicy sobre as bolhas. O recipiente e blobs no contêiner teria seu conjunto de PublicAccess para fora com um pouco de código que você provavelmente iria escrever fazendo desenvolvimento Windows Azure armazenamento de qualquer forma. O exemplo de código a seguir mostra como eu posso definir a PublicAccess para fora, mas permitir para SharedAccess no recipiente deve eu gerar uma assinatura e distribuí-lo:

BlobContainerPermissions permissions = new BlobContainerPermissions();
  permissions.PublicAccess = BlobContainerPublicAccessType.Off;

  SharedAccessPolicy accesspolicy = new SharedAccessPolicy();
  accesspolicy.Permissions = SharedAccessPermissions.Read;
  permissions.SharedAccessPolicies.Add("Read", accesspolicy);

  BlobContainer.SetPermissions(permissions);

Se perguntarmos para um recurso diretamente no recipiente de armazenamento, vamos começar um 404, página não encontrada. Como carregarmos as bolhas, fazemos um pouco semelhante de trabalho para o blob propriamente dito, mas podemos criar um SharedAccessPolicy que permite ler, definir um tempo de expiração para ele e pedir uma assinatura de acesso compartilhado, como este:

SharedAccessPolicy policy = new SharedAccessPolicy();
policy.Permissions = SharedAccessPermissions.Read;
policy.SharedAccessExpiryTime = DateTime.Now.AddDays(5);
string SharedAccessSignature = destBlob.GetSharedAccessSignature(policy));

A chamada para GetSharedAccessSignature retorna uma Cadeia de caracteres como este:

?se=2010-08-26T18%3A22%3A07Z&sr=b&sp=r&sig=WdUHKvQYnbOcMwUdFavn4QS0lvhAnqBAnVnC6x0zPj8%3D

Se eu concatenar essa Cadeia de caracteres de consulta para a extremidade do URI para o blob, eu deveria recebê-lo novamente, fornecendo que o termo não tem passado. Mais informações sobre a assinatura e políticas de acesso compartilhado podem ser encontradas em msdn.microsoft.com/library/ee395415 .

Para resolver o problema, eu iria gerar assinaturas e fornecer assinado URIs que tinha um longo termo, que torna mais fácil para criá-los no momento de carregar e armazenar uma lista de links para documentos publicados. Para algo um pouco mais seguro e que eu quero fornecer acesso a um único usuário por um curto período de tempo, eu precisaria de um pedaço de interface do usuário. Essa interface do usuário seria permitir que um usuário solicitar acesso a um ou mais recursos e get back assinado URIs que daria acesso por um curto período de tempo.

A mistura com a nuvem

Aqui Shad e eu costumávamos uma implementação geral para abordar dois cenários diferentes. Isso foi particularmente útil para ambos os cenários, como precisávamos de uma determinada parte da funcionalidade (armazenamento escalável, confiável e expansível) que a nuvem fornecida sem ter que fazer muito em forma de instalação e custando apenas o que usamos. A idéia principal que esperamos para transmitir é que, como profissionais olhando para criar soluções para os nossos clientes (internos ou externos), nossos conceitos de solução não tem que ser exclusivamente na nuvem ou no local. Os dois podem ser facilmente combinados. Como as atualizações de serviço são aplicadas ao longo do tempo, será mais fácil e mais fácil de misturar-se à rede corporativa para a rede de nuvem. Espero que no futuro ele irá misturar até ao ponto de não ser muita diferença. Assim, como você procura soluções para os seus sistemas de software ou de negócios, você pode ter um momento para parar e pensar, "Há algo na nuvem que vai me ajudar?"

Joseph Fultz é um arquiteto no Microsoft Technology Center, em Dallas, onde ele trabalha com clientes corporativos e ISVs Projetando e soluções de software de criação de protótipos para atender às demandas de negócios e mercado. Ele é falado em eventos, como Tech·Ed e eventos de treinamento interno semelhante.

Shad Phillips é um arquiteto no Microsoft Technology Center, em Dallas, onde ele trabalha com clientes corporativos e parceiros criar e implantar soluções de gerenciamento de conteúdo corporativo construídas sobre Microsoft SharePoint 2010.

Graças a seguinte especialista técnico para revisão deste artigo: Jas Tenney