Sep 30

Create a CloudFront distribution with AWS SDK for Go

Amazon Web Services provides different SDKs, Toolkits and Command Line Tools to develop and manage application running on AWS. AWS SDK for Go is one of the latest tools provided. New versions are pushed almost every 5 days.

In this blog post, we will write a simple Go code to create a CloudFront distribution with the default settings and the following:

  • An S3 bucket as origin for the distribution
  • A Lambda@Edge function associated to the default behavior
  • A WAF Rule

For more information about:

  • CloudFront
  • Installing and configuring AWS SDK for Go
  • CloudFront APIs with AWS SDK for Go
  • Lambda@Edge
  • WAF (Web Application Firewal)

  • package main

    import (
    "fmt"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/cloudfront"
    "github.com/aws/aws-sdk-go/aws/awserr"
    )

    func main() {

    creds := aws.Creds(accessKey, secretKey, "")
    svc := cloudfront.New(creds, "us-east-1", nil)

    // svc := cloudfront.New(session.New()) Can replace the 2 lines above if using Instance Role or Env. Variables

    input := &cloudfront.CreateDistributionWithTagsInput{
    Tags: &cloudfront.Tags{
    Items: []*cloudfront.Tag{
    },
    },
    DistributionConfig: &cloudfront.DistributionConfig{
    CallerReference: aws.String("Sat Sept. 30 2017"),
    Comment: aws.String("My WordPress Blog"),
    Enabled: aws.Bool(true),
    WebACLId: aws.String("eSamplec-5a3e-4857-9b92-0a5Sample3a4"),
    Origins: &cloudfront.Origins{
    Quantity: aws.Int64(1),
    Items: []*cloudfront.Origin{
    {
    Id: aws.String("Jil_S3Origin"),
    DomainName: aws.String("mydomain.com.s3.amazonaws.com"),
    S3OriginConfig: &cloudfront.S3OriginConfig{
    OriginAccessIdentity: aws.String(""),
    },
    },
    },
    },
    DefaultCacheBehavior: &cloudfront.DefaultCacheBehavior{
    TargetOriginId: aws.String("Jil_S3Origin"),
    MinTTL: aws.Int64(10),
    ViewerProtocolPolicy: aws.String("allow-all"),
    LambdaFunctionAssociations: &cloudfront.LambdaFunctionAssociations{
    Quantity: aws.Int64(1),
    Items: []*cloudfront.LambdaFunctionAssociation{
    {
    EventType: aws.String("viewer-request"), // "viewer-request" | "viewer-response" | "origin-request" | "origin-response"
    LambdaFunctionARN: aws.String("arn:aws:lambda:us-east-1:123456789012:function:myFunctionName:2"), // the version of the function must be added
    },
    },
    },
    TrustedSigners: &cloudfront.TrustedSigners{
    Enabled: aws.Bool(false),
    Quantity: aws.Int64(0),
    },
    ForwardedValues: &cloudfront.ForwardedValues{
    Cookies: &cloudfront.CookiePreference{
    Forward: aws.String("none"),
    },
    QueryString: aws.Bool(false),
    },
    },
    },
    }

    result, err := svc.CreateDistributionWithTags(input)

    if err != nil {
    if aerr, ok := err.(awserr.Error); ok {
    switch aerr.Code() {
    case cloudfront.ErrCodeCNAMEAlreadyExists:
    fmt.Println(cloudfront.ErrCodeCNAMEAlreadyExists, aerr.Error())
    case cloudfront.ErrCodeDistributionAlreadyExists:
    fmt.Println(cloudfront.ErrCodeDistributionAlreadyExists, aerr.Error())
    case cloudfront.ErrCodeInvalidOrigin:
    fmt.Println(cloudfront.ErrCodeInvalidOrigin, aerr.Error())
    case cloudfront.ErrCodeInvalidOriginAccessIdentity:
    fmt.Println(cloudfront.ErrCodeInvalidOriginAccessIdentity, aerr.Error())
    case cloudfront.ErrCodeAccessDenied:
    fmt.Println(cloudfront.ErrCodeAccessDenied, aerr.Error())
    case cloudfront.ErrCodeTooManyTrustedSigners:
    fmt.Println(cloudfront.ErrCodeTooManyTrustedSigners, aerr.Error())
    case cloudfront.ErrCodeTrustedSignerDoesNotExist:
    fmt.Println(cloudfront.ErrCodeTrustedSignerDoesNotExist, aerr.Error())
    case cloudfront.ErrCodeInvalidViewerCertificate:
    fmt.Println(cloudfront.ErrCodeTooManyCertificates, aerr.Error())
    case cloudfront.ErrCodeInvalidLocationCode:
    fmt.Println(cloudfront.ErrCodeInvalidLocationCode, aerr.Error())
    case cloudfront.ErrCodeInvalidGeoRestrictionParameter:
    fmt.Println(cloudfront.ErrCodeInvalidGeoRestrictionParameter, aerr.Error())
    case cloudfront.ErrCodeInvalidProtocolSettings:
    fmt.Println(cloudfront.ErrCodeInvalidProtocolSettings, aerr.Error())
    case cloudfront.ErrCodeInvalidTTLOrder:
    fmt.Println(cloudfront.ErrCodeInvalidTTLOrder, aerr.Error())
    case cloudfront.ErrCodeInvalidWebACLId:
    fmt.Println(cloudfront.ErrCodeInvalidWebACLId, aerr.Error())
    case cloudfront.ErrCodeTooManyOriginCustomHeaders:
    fmt.Println(cloudfront.ErrCodeTooManyOriginCustomHeaders, aerr.Error())
    case cloudfront.ErrCodeTooManyQueryStringParameters:
    fmt.Println(cloudfront.ErrCodeTooManyQueryStringParameters, aerr.Error())
    case cloudfront.ErrCodeInvalidQueryStringParameters:
    fmt.Println(cloudfront.ErrCodeInvalidQueryStringParameters, aerr.Error())
    case cloudfront.ErrCodeTooManyDistributionsWithLambdaAssociations:
    fmt.Println(cloudfront.ErrCodeTooManyDistributionsWithLambdaAssociations, aerr.Error())
    case cloudfront.ErrCodeTooManyLambdaFunctionAssociations:
    fmt.Println(cloudfront.ErrCodeTooManyLambdaFunctionAssociations, aerr.Error())
    case cloudfront.ErrCodeInvalidLambdaFunctionAssociation:
    fmt.Println(cloudfront.ErrCodeInvalidLambdaFunctionAssociation, aerr.Error())
    case cloudfront.ErrCodeInvalidOriginReadTimeout:
    fmt.Println(cloudfront.ErrCodeInvalidOriginReadTimeout, aerr.Error())
    case cloudfront.ErrCodeInvalidOriginKeepaliveTimeout:
    fmt.Println(cloudfront.ErrCodeInvalidOriginKeepaliveTimeout, aerr.Error())
    default:
    fmt.Println(aerr.Error())
    }
    } else { // Print the error, cast err to awserr.Error to get the Code and Message from an error.
    fmt.Println(err.Error())
    }
    return
    }
    fmt.Println(result)
    }

Sep 09

14 ans déjà que le Lion du Panjshir nous a quitté

Le Lion du Panjshir

Commandant Massoud

09 septembre 2001 – 09 septembre 2015, 14 ans déjà que le Lion du Panjshir nous a quitté. Celui qui a combattu les russes, les Talibans et Al Qaïda est mort suite à un attentat-suicide de deux prétendus journalistes qui font exploser leur camera pendant une interview.

A 25 ans (1978) Ahmed Chah Massoud (qui deviendra plus tard le Commandant Massoud) crée et prend la tête du “Conseil de surveillance”, il est un tacticien et un stratège hors pair et le seul chef de la Résistance à avoir jamais réussi à imposer une trêve avec l’Armée Rouge en échange de son retrait.

Il périt deux jours avant les attentats du 11 septembre, il avait pourtant plusieurs fois tenté d’alerter la communauté internationale sur le danger Al Qaïda.

RIP‬ Massoud!

Feb 08

Rapport mHealth au Congo – Etude de faisabilité et recommandations

De septembre à décembre 2013, j’ai mené une étude de faisabilité de l’utilisation de la téléphonie mobile pour l’amélioration de la couverture vaccinale au Congo (Brazzaville).

Objectifs de l’étude

L’objectif de la mission était d’étudier la faisabilité tant sur les plans technique, organisationnel que technologique du projet d” « utilisation de la téléphonie mobile pour l’amélioration de la couverture des interventions à haut impact au Congo : Vaccination, déparasitage, supplémentation en vitamine A » et de réviser le draft du projet sur la base des résultats et du contexte effectif au Congo.

L’étude devrait fournir suffisamment d’informations à l’UNICEF et aux principaux partenaires (gouvernement, compagnies de téléphonie mobile, etc.) pour leur permettre de valider l’implémentation du projet. Elle devra également permettre d’orienter les choix stratégiques et les modalités de mise en œuvre d’un tel projet, les informations suivantes doivent en ressortir :

  • Les usages des téléphones portables par les ménages au Congo,
  • Mapping des projets utilisant la téléphonie mobile et évaluation des bonnes
    pratiques en matière de téléphonie mobile pour le développement au Congo,
  • Développement du document du projet pilote dans les départements de Brazzaville et Pointe Noire (plan d’implémentation, budget détaillé, équipe projet avec rôle de chaque partie prenante, suivi et évaluation, risques du projet, etc.),
  • Recommandations sur l’implémentation du projet pilote, les négociations avec les compagnies de téléphonie mobile, l’appropriation par le gouvernement et son
    extension à l’ensemble du territoire congolais.

Méthodologie utilisée

Etude de faisabilité : Méthodologie

Télécharger le rapport

Rapport sur l’étude de faisabilité et les recommandations (PDF, 40 pages, 1.9Mo)

 

Dec 07

Téléphonie mobile pour le développement – Risques et mesures d’atténuation

Total African Mobile Connections and Penetration Rate (million, percentage penetration).

Total African Mobile Connections and Penetration Rate (million, percentage penetration).

Plusieurs organisations internationales et ONG (UNESCO, UNICEF, Plan International, Carter Center, etc.) souhaitent profiter du taux de pénétration de la téléphonie mobile dans les pays en développement pour améliorer les conditions de vie des populations. De plus en plus projets sur la santé, l’éducation, la bonne gouvernance, etc.  incluant les téléphones portables voient donc le jour, un bon pourcentage utilise les SMS (Short Message Services) via les applications telles que RapidSMS et FrontLineSMS.

Comme pour toute initiative, en particulier celles basées sur les technologies de l’information, plusieurs risques peuvent impacter son bon déroulement et affecter de façon significative les résultats attendus. Dans le tableau ci-dessous un certain nombre de risques et des mesures d’atténuation à prendre en compte dans la conception du projet, risques à adapter en fonction du projet bien évidemment ;-), divisés en deux types :

  1. Les risques fonctionnels, techniques et liés aux processus sont associés au fonctionnement, aux procédures, aux ressources, à la communication du projet
  2. Les risques du projet sont associés aux aspects techniques et de mise en œuvre
Risque Prob. Impact Mesures d’atténuation
Risques fonctionnels, techniques et liés aux processus
Erreurs dans l’envoi des SMS par le public cible Moyen Elevé. Données non utilisables par le système Limiter le nombre de procédures, utiliser une nomenclature simple, simple bien former les utilisateurs
Les interfaces utilisateurs sont difficiles à comprendre, ou l’utilisation requiert une longue procédure Moyen Modéré. Système difficile à utiliser, utilisateurs finaux découragés Prendre en compte l’utilisateur pendant la conception, Produire les règles d’ergonomie
Anomalies de fonctionnement et instabilité de l’environnement Bas Elevé. Intégrité des données. Système souvent hors utilisation Renforcement des tests, Recensement des bugs, Choix techniques
Risques du projet
Ne pas avoir l’adhésion du gouvernement
et des partenaires
Appropriation et viabilité à long terme du projet Impliquer le gouvernement et les partenaires dès la conception du projet
Ne pas héberger le système au sein du gouvernement Inclure un coût pour l’hébergement et le personnel technique. Renforcer les capacités afin d’assurer le support
Ne pas avoir un spécialiste TIC et un coordonateur du projet au sein du gouvernement
Les personnes chargées du monitoring sur le terrain ne possèdent pas de téléphone, ou ont des téléphones non fiables Impact élevé sur la mise à jour de la BD et l’intégrité des données Inclure un coût supplémentaire dans le budget, évaluer les téléphones pendant les formations
La langue d’envoi des messages n’est pas appropriée Impact élevé, les utilisateurs auront de la peine à les lire Savoir les préférences des utilisateurs finaux. Utiliser plusieurs langues au besoin
Le public bénéficiaire ne consulte pas sa messagerie Un bon pourcentage de messages ne sont pas lus Renforcer la communication autour du projet
Ne pas avoir une compagnie IT locale (ou un développeur local) pour développer l’application et en assurer le suivi Difficultés dans l’implémentation et le support du système Mettre sur pied une équipe technique à long terme (entreprise IT ou recruter un développeur)
Les utilisateurs finaux ne sont pas impliqués dès le début du projet, et ne sont pas bien formés Mauvaise utilisation et appropriation du dispositif Créer un groupe de travail pour valider les spécifications, Créer un comité d’utilisateurs

Oct 18

Utilisation de la téléphonie mobile pour l’amélioration de la santé de l’enfant au Congo

Le bureau de l’UNICEF à Brazzaville met sur pieds en ce moment un projet innovant sur l’utilisation de la téléphonie mobile pour l’amélioration de la couverture des interventions à haut impact (Vaccination, déparasitage, supplémentation en vitamine A). Utilisation des mobiles pour le développement

Au Congo 54,5% d’enfants de 12-24 mois n’ont pas été complètement vaccinés, de plus la malnutrition chronique touche 24.4% d’enfants de moins de 5 ans et constitue un problème de santé publique majeur. Le projet vise à exploiter le fort taux de pénétration de la téléphonie (plus de 92% de ménages en milieu urbain possèdent un téléphone) pour informer (alerter) les parents des dates de vaccination de leurs enfants par SMS et éventuellement par messages vocaux automatiques (OBD, IVR). Le projet mettra également sur pieds un système de calendrier vaccinal électronique.

Un serveur enregistrera quelques informations lorsqu’une femme vient accoucher (nom de l’enfant, date et lieu d’accouchement, noms des parents et numéros de téléphones, centre de santé, etc.) et enverra ensuite automatiquement des SMS (et éventuellement messages vocaux) de rappel aux parents, centres de santé et agents de santé, une semaine et un jour avant un événement, et éventuellement 3 jours et une semaine après l’événement, si les parents ne se sont pas présentés. Il sera aussi possible pour les parents d’envoyer des SMS gratuits au système afin de donner leur feedback sur les services dont ils bénéficient, des sondages par SMS seront aussi organisés pendant toute la durée du projet.

Toutes les informations et données enregistrées pendant la durée du projet seront consultables en temps réel sur un site web internet, ce qui pourra permettre au gouvernement et partenaires à mieux orienter leurs politiques. L’architecture technique du serveur sera conçue autour des technologies suivantes: la librairie RapidSMS, un OS GNU/Linux (Debian ou Ubuntu Server), Python et les Packages requis, le Framework Web Django, un Gateway SMS (Kannel?), MySQL comme base de données et un serveur web.

Présentation PowerPoint de l’étude de faisabilité du projet et des recommandations

Oct 01

Cloud Storage Providers: Amazon S3, Google Cloud Storage and Microsoft Azure Comparison

IaaS - AWS, Google and Microsoft

IaaS – AWS, Google and Microsoft

Choosing a Cloud Storage solution depends on several criteria: cost, accessibility, durability, scalability, flexibility and more. The Cloud Storage has several advantages and benefits over on premises storage, especially when it comes to cost and reliability. The Cloud Storage giants, namely Amazon S3 (Simple Storage Service), Microsoft Azure and Google Cloud Storage are constantly reducing costs, and innovating with more and more functionality.

The table below compares some of the fundamental Cloud Storage features provided by these three Cloud Storage giants.

Amazon S3 Microsoft Azure Google Cloud Storage
Reliability (durability & availability)
Stores data with up to 99.999999999% durability, with 99.99% availability. There can be no single points of failure. All failures must be tolerated or repaired by the system without any downtime Keeps 3 copies of objects within a single region, a geo-redundancy option can create 3 additional copies Delivers 99.9 percent or better uptime through its highly available, geo-redundant data-replication system
Scalability
Can scale in terms of storage, request rate, and users to support an unlimited number of web-scale applications. It uses scale as an advantage: Adding nodes to the system increases, not decreases, its availability, speed, throughput, capacity, and robustness Up to 500 TB of total storage per account. A single subscription supports up to 50 storage accounts, delivering petabytes of storage for the largest scenarios You can store almost unlimited amounts of data and easily scale up or down
Supported libraries for developers
.NET, Java, JavaScript, PHP, Python, Node.js, Ruby, iOS and Android .NET, Java, Android, C++, and Node.js .NET, Java, JavaScript (beta), PHP (beta), Objective-C, Python, Node.js (alpha), Ruby (alpha) and Go (alpha)
Global presence
Available in 9 regions across 4 continents: US Standard, US West (Oregon), US West (Northern California), EU (Ireland), Asia Pacific (Singapore), Asia Pacific (Tokyo), Asia Pacific (Sydney), South America (Sao Paulo), and GovCloud (US) regions Available in 12 regions across 4 continents: US Central (Iowa), US East (Virginia), US North Central (Illinois), US South Central (Texas), US West (California), Europe North (Ireland), Europe West (Netherlands), Asia Pacific East (Hong Kong), Asia Pacific Southeast (Singapore), Japan East (Saitama), Japan West (Osaka), Brazil South (Sao Paulo) Available in 8 zones across 3 continents: US (us-central1-a, us-central1-b, us-central1-f), Europe (europe-west1-a, europe-west1-b), Asia (asia-east1-a, asia-east1-b, asia-east1-c)
Default region prices per GiB (from 0 to 5,000 TB).
Since May 1, 2015 Microsoft aligned its prices to Amazon S3 ones
0-1 TB: $0.03, 1-50 TB: $0.0295, 50-500 TB: $0.029, 500-1,000 TB: $0.0285, 1,000-5,000 TB: $0.028, 0-1 TB: $0.03, 0-5,000 TB: $0.026
Some major customers
Netflix, Nasdaq, Dropbox, Slideshare, Instagram, Pinterest XBox One, Mazda, Tesco Ubisoft, JustDevelopIt, CloudLock

Cloud Storage

Websites

Sep 27

6 things you should know about Amazon CloudSearch

Amazon CloudSearch is a fully-managed service in the AWS Cloud that makes it simple and cost-effective to set up, manage, and scale a custom search solution for your website or application.

Amazon CloudSearch supports a rich set of features including language-specific text processing for 34 languages, free text search, faceted search, geospatial search, customizable relevance ranking, highlighting, autocomplete and user configurable scaling and availability options [1].

Here are six key things you should know about Amazon CloudSearch.

1. How to build a search solution with Amazon CloudSearch?

There are three main steps:
Amazon-CloudSearch

  1. Create and configure a search domain: A search domain includes your searchable data and the search instances that handle your search requests. If you have multiple collections of data that you want to make searchable, you can create multiple search domains
  2. Upload the data you want to search to your domain: Amazon CloudSearch indexes your data and deploys the search index to one or more search instances,
  3. Search your domain: You send a search request to your domain’s search endpoint as an HTTP/HTTPS GET request.

2. How much data can you store in CloudSearch?

The number of partitions you need depends on your data and configuration. When you upload data, Amazon CloudSearch deploys one or more search instances. As your data volume grows, more search instances or larger search instances are deployed to contain your indexed data. The maximum number of search instances that can be deployed for a domain is 50, and a search index can be splited across a maximum of 10 partitions. For more information about CloudSearch limits, see Ref. [2].

3. How are you charged?

You are charged for Search instances, Document batch uploads, IndexDocuments requests and Data transfer. The Ref. [3] provides a useful resource to estimate your CloudSearch monthly bill.

4. Can you query for documents older than X and then send a batch delete request?

At the moment, Amazon CloudSearch does not provide this feature, but you can use one of their SDKs to list documents based on some parameters, and then delete them.

5. Do you need to keep a copy of the index anywhere?

You don’t really need, you can rely only on CloudSearch as source of the analytics data, as far as you respect AWS Security Best practices [5]. Amazon CloudSearch stores your data internally in high availability stores, you will not have to re-index your data, should a CloudSearch instance have an issue (this will be handled transparently). It offers key benefits including automatic node monitoring and recovery, built in data durability, easy setup and configuration and hands off auto scaling.

6. What’s the difference in the different instance sizes for CloudSearch?

A search instance is a single search engine that indexes documents and responds to search requests. It has a finite amount of RAM and CPU resources for indexing data and processing requests. There are four available instance types within CloudSearch: search.m1.small (2 Million documents), search.m1.large (8 Million documents), search.m2.xlarge (16 Million documents) and search.m2.2xlarge (32 Million documents).

Short Amazon CloudSearch Video

References:
[1] – Amazon CloudSearch
[2] – Understanding Amazon CloudSearch Limits
[3] – AWS Simple Monthly Calculator
[4] – AWS Security Best practices [pdf]

Sep 21

Uploading a Large File to Amazon Web Services S3

AWS_S3

Amazon Web Services Simple Storage Service

The largest single file that can be uploaded into an Amazon S3 Bucket in a single PUT operation is 5 GB. If you want to upload large objects (> 5 GB), you will consider using multipart upload API, which allows to upload objects from 5 MB up to 5 TB.

The Multipart Upload API is designed to improve the upload experience for larger objects, which can be uploaded in parts, independently, in any order, and in parallel. The AWS tool to use to perform this is API-Level (s3api) command set.

In this tutorial, we assume:

  • You have installed and configured AWS Command Line Interface on a Linux OS computer/server,
  • You have an Amazon account and a S3 Bucket (MyBucketName),
  • The size of the file to upload is 20 GB (MyObject.zip),
  • 100 MB can be uploaded without problem using our internet connection.

Theoretically, how it works

The process involves in 4 steps:

  1. Separate the object into multiple parts. There are several ways to do this in Linux, ‘dd‘, ‘split‘, etc. We will use ‘dd’ in this tutorial,
  2. Initiate the multipart upload and receive an upload id in return (aws s3api create-multipart-upload),
  3. Upload each part (a contiguous portion of an object’s data) accompanied by the upload id and a part number (aws s3api upload-object),
  4. Finalize the upload by providing the upload id and the part number / ETag pairs for each part of the object (aws s3api complete-multipart-upload).

And practically?

1. Separate the object into multiple parts

We will create 205 parts (100 MB * 204 + 80 MB):

$ dd if=/dev/urandom of=MyObject.zip bs=1024k count=20000

$ dd if=MyObject.zip of=MyObject1.zip bs=1024k skip=0 count=100
$ dd if=MyObject.zip of=MyObject2.zip bs=1024k skip=100 count=100
$ dd if=MyObject.zip of=MyObject3.zip bs=1024k skip=200 count=100
...
$ dd if=MyObject.zip of=MyObject10.zip bs=1024k skip=900 count=100
$ dd if=MyObject.zip of=MyObject11.zip bs=1024k skip=1000 count=100
$ dd if=MyObject.zip of=MyObject12.zip bs=1024k skip=1100 count=100
...
$ dd if=MyObject.zip of=MyObject203.zip bs=1024k skip=20200 count=100
$ dd if=MyObject.zip of=MyObject204.zip bs=1024k skip=20300 count=100
$ dd if=MyObject.zip of=MyObject205.zip bs=1024k skip=20400 count=100

A one line shell script can be written to automate this process:

$ for i in {1..205}; do dd if=MyObject.zip of=MyObject"$i".zip bs=1024k skip=$[i*100 - 100] count=100; done

2. Initiate the multipart upload and receive an upload id in return

aws s3api create-multipart-upload --bucket MyBucketName --key MyObject.zip
You will received as output something like:
{
"UploadId": "UVditMTG8U--MyLongUploadId--ksmFT7N6bNTWD",
"Bucket": "MyBucketName",
"Key": "MyObject.zip"
}

3. Upload each part

For the following commands, note the console output:
{
"ETag": "\"fggcd799--ETagValue1--dhe76dd8dc\""
}


$ aws s3api upload-part --bucket MyBucketName --key MyObject.zip --upload-id \ MyLongUploadId --part-number 1 --body MyObject1.zip
$ aws s3api upload-part --bucket MyBucketName --key MyObject.zip --upload-id \ MyLongUploadId --part-number 2 --body MyObject2.zip
...
$ aws s3api upload-part --bucket MyBucketName --key MyObject.zip --upload-id \ MyLongUploadId --part-number 100 --body MyObject100.zip
...
$ aws s3api upload-part --bucket MyBucketName --key MyObject.zip --upload-id \ MyLongUploadId --part-number 204 --body MyObject204.zip
$ aws s3api upload-part --bucket MyBucketName --key MyObject.zip --upload-id \ MyLongUploadId --part-number 205 --body MyObject205.zip

Note: Once more you can write a small shell script to automate this process.

Finalize the upload

Create a JSON file MyMultiPartUpload.json containing the following:

{
"Parts": [
{
"ETag": "\"ETagValue1\"",
"PartNumber": 1
},
{
"ETag": "\"ETagValue2\"",
"PartNumber": 2
},
...
{
"ETag": "\"ETagValue100\"",
"PartNumber": 100
},
...
{
"ETag": "\"ETagValue204\"",
"PartNumber": 204
},
{
"ETag": "\"ETagValue205\"",
"PartNumber": 205
},
]
}

$ aws s3api complete-multipart-upload --bucket MyBucketName --key \
MyObject.zip --upload-id MyLongUploadId --multipart-upload MyMultiPartUpload.json

That is all, you can verify that the large file is uploaded with:
aws s3 ls s3://MyBucketName/MyObject.zip
2014-09-18 20:29:19 20495340 MyObject.zip

References and resources:

Jun 16

Solution de portail Intranet : Intégration de Liferay 6.1 et Alfresco 4.2 sous Ubuntu Server avec MySQL

Liferay est une solution aboutie Open Source de gestion de contenu, orientée portail social et collaboratif (internet, extranet ou intranet) ; plusieurs grandes entreprises et administrations l’ont utilisé pour déployer leur portail internet.

Lorsqu’il faut cependant mettre sur pied un portail intranet ou extranet, la fonctionnalité GED (gestion et archivage électronique de documents) est indispensable (partage de documents, sécurité, accès CIFS/FTP/Lecteur réseau, etc.), malgré les efforts des équipes de développement de Liferay dans l’ajout de cette fonctionnalité (notamment dans sa dernière version (6.1) avec l’apparition de Liferay Sync qui permet de synchroniser les documents distants avec un dossier local ou sur un mobile – un peu comme DropBox), les fonctionnalités de base d’une GED sont loin d’être remplies.

Heureusement Liferay a dans cette même version 6.1, facilité l’intégration de quelques systèmes de gestion documentaire, en particulier Alfresco, SharePoint et Documentum. La collaboration entre Liferay et Alfresco permet:

  • soit d’intégrer Alfresco à Liferay – Liferay joue ici un rôle de présentation des documents
  • soit de faire cohabiter les deux applications – toutes les données de Alfresco peuvent être vues dans Liferay, avec une gestion commune des droits d’accès.

Le but de ce tutoriel est de mettre sur pied la deuxième solution.
Alfresco Liferay Integration

Principales étapes

  1. Installation de Alfresco 4.2.c sur Ubuntu Server 12.04 avec MySQL

    Suivre ce tutoriel. Il est préférable d’installer le serveur Tomcat à part, et d’utiliser un port différent que 8080 (utiliser par exemple 8081) pour Alfresco.

  2. Installation de Liferay 6.1 sur Ubuntu Server 12.04 avec MySQL

    Suivre ce tutoriel

  3. Démarrer Alfresco (service alfresco start)
  4. Le couple (utilisateur, mot de passe) doit être le même à Alfresco et Liferay, Alfresco étant prioritaire. Par défaut Liferay ne sauvegarde pas les mots de passe en session, il faut l’activer dans le fichier des propriétés – portal-ext.properties. Modifier ce fichier comme suit :
    session.store.password=true
    company.security.auth.type=screenName
  5. Démarrer Liferay (service liferay start)
  6. Ouvrir Liferay dans votre navigateur favori et se connecter comme administrateur, puis aller sur le panneau d’administration.
  7. Cliquer sur Documents et médias puis ajouter un nouveau dépôt (voir Image 1 ci-dessous). Vous ajoutez ici les détails de connexion à Alfresco comme suit:
    • Nom: Donner un nom au dépôt (Documents Alfresco par exemple)
    • Description: Une brève description du dépôt
    • Type de dépôt: Vous pouvez choisir Services Web ou AtomPub (que nous utliserons)
    • AtomPub URL: http://localhost:8081/alfresco/cmisatom
    • ID du dépôt: paramètre optionnel, important si nous avons plusieurs dépôts. Si rien n’est mis le système choisira le 1er dépôt
    • Cliquer sur Enregistrer. Liferay essaiera de se connecter à Alfresco avec les paramètres entrés et affichera le résultat (rassurez-vous que Alfresco et bien démarré et fonctionnel). En cas de succès vous verrez s’afficher tous les dossiers et fichiers d’Alfresco dans la partie Documents et médias de Liferay (Image 2 ci-dessous)

Tous les documents ajoutés à Liferay seront visibles dans Alfresco, et vice versa, tout est synchronisé, les droits d’accès sont conservés. Elle n’est pas belle la vie???

Nouveau Depot
Paramètres de configuration de la connexion de Liferay à Alfresco
Alfresco Dans Liferay
Documents présents à la fois dans Alfresco et dans Liferay

May 16

Installation du PGI OpenERP 7.0 sur Debian Squeeze et CentOS 6.4

OpenERP est un PGI (Progiciel de Gestion Intégré) Open Source dont le développement a commencé il y a maintenant 14 ans par Fabien Pinckaers (pinky) pour les business de son père, et plus tard de son oncle.
OpenERP
Développé avec Python et utilisant le SGBD libre PostGreSQL, le logiciel est aujourd’hui très abouti et plusieurs grandes entreprises l’ont implémenté; il peut très facilement être installé et configuré sur plusieurs distributions de Linux, dont Debian.

Les principaux modules présents sont la gestion:

  • des ventes,
  • de la gestion de relation client (CRM),
  • de projet,
  • d’entrepôt,
  • de la production,
  • de la comptabilité et
  • des ressources humaines.

Processus d’installation sur Debian Squeeze

Mettre à jour les paquets

sudo apt-get update

Installer la base de données PostGreSQL

sudo apt-get install postgresql

Créer un utilisateur pour la base de données

su - postgres -c "createuser --createdb --no-createrole --no-superuser openerp"
echo "ALTER USER openerp WITH PASSWORD 'MonMotDePasse';ALTER USER postgres WITH PASSWORD 'MonMotDePasse';" | su postgres -c psql

Ajouter le dépôt OpenERP

echo "deb http://nightly.openerp.com/7.0/nightly/deb/ ./" >> /etc/apt/sources.list

Mettre à jour la base de données des paquets

aptitude update && aptitude && upgrade && aptitude clean

Installer OpenERP

aptitude install openerp
Accepter le Package en tapant ‘Yes’ et en validant sur le clavier, toutes les dépendances seront installées.

Accéder à OpenERP via le navigateur

http://127.0.0.1:8069

Installation sur CentOS 6.3 ou 6.4

L’installation ici est moins automatique que sous Debian, heureusement dans le domaine des logiciels libres le partage d’expérience d’expertise nous permet d’avancer relativement vite! Je vous conseille ce simple script de Mario Gielissen (http://www.openworx.nl) :

#!/bin/sh
# Modified script from Carlos E. Fonseca Zorrilla
yum -y install wget unzip
rpm -ivh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
rpm -ivh http://yum.pgrpms.org/9.2/redhat/rhel-6-i386/pgdg-centos92-9.2-6.noarch.rpm
yum -y install python-psycopg2 python-lxml PyXML python-setuptools libxslt-python pytz \
python-matplotlib python-babel python-mako python-dateutil python-psycopg2 \
pychart pydot python-reportlab python-devel python-imaging python-vobject \
hippo-canvas-python mx python-gdata python-ldap python-openid \
python-werkzeug python-vatnumber pygtk2 glade3 pydot python-dateutil \
python-matplotlib pygtk2 glade3 pydot python-dateutil python-matplotlib \
python python-devel python-psutil python-docutils make\
automake gcc gcc-c++ kernel-devel byacc flashplugin-nonfree poppler-utils pywebdav\
yum -y install postgresql92-libs postgresql92-server postgresql92
service postgresql-9.2 initdb
chkconfig postgresql-9.2 on
service postgresql-9.2 start
su - postgres -c "createuser --superuser openerp"
cd /tmp
wget http://gdata-python-client.googlecode.com/files/gdata-2.0.17.zip
unzip gdata-2.0.17.zip
rm -rf gdata-2.0.17.zip
cd gdata*
python setup.py install
cd /tmp
adduser openerp
DIR="/var/run/openerp /var/log/openerp"
for NAME in $DIR
do
if [ ! -d $NAME ]; then
mkdir $NAME
chown openerp.openerp $NAME
fi
done
rm -rf openerp*
wget http://nightly.openerp.com/7.0/nightly/src/openerp-7.0-latest.tar.gz
tar -zxvf openerp-7.0-latest.tar.gz --transform 's!^[^/]\+\($\|/\)!openerp\1!'
cd openerp
python setup.py install
rm -rf /usr/local/bin/openerp-server
cp openerp-server /usr/local/bin
cp install/openerp-server.init /etc/init.d/openerp
cp install/openerp-server.conf /etc
chown openerp:openerp /etc/openerp-server.conf
chmod u+x /etc/init.d/openerp
chkconfig openerp on
service openerp start

Voilà, c’est tout! Profitez de toutes les fonctionnalités de l’application!