Sunday, July 5, 2015

Using IAM Roles for Amazon Services


What is IAM?


AWS Identity and Access Management (IAM) is a web service that helps you securely control access to AWS resources such as S3 bucket, EC2 Instance etc. for your users. Using IAM you can control who can use your AWS resources (authentication) and what resources they can use and in what access rights (authorization).

IAM can also keep your account credentials private. With IAM, you can create multiple IAM users under the umbrella of your AWS account or enable temporary access through identity federation with your corporate directory. In some cases, you can also enable access to resources across AWS accounts.

Watch this short video to understand IAM:






IAM Features:
IAM provides important features such as Shared access to your AWS account, Granular permissions, Secure access to AWS resources for applications that run on Amazon EC2, Multi-factor authentication (MFA) etc.
For more details visit:


Accessing IAM:
You can work with AWS Identity and Access Management in any of the following ways.

1- AWS Management Console

2- AWS Command Line Tools

3- AWS SDKs

4- IAM HTTPS API


For details visit:



Why IAM?


Without IAM, you must either create multiple AWS accounts and must share the security credentials of an each AWS account. In addition, without IAM, you cannot control the tasks a particular user or system can do and what AWS resources they might use.

Let’s take a scenario where I have an application which access S3 bucket to store contents. Below diagram illustrate the above statement:



You can see following process in above diagram:

1-      A java web application is running on EC2 instance.
2-      A user using the application and uploading contents to Amazon S3 bucket.
3-      Java web application has the access key and secret key to access the S3 bucket. These keys are distributed with the application always in order to connect to S3 bucket.

           If you are using JetS3 library to connect to S3 bucket you would use:
      S3Service s3Service=new RestS3Service(new AWSCredentials(“xxxx”,”yyy/zzz”));

           If you are using AWS SDK library to connect to S3 bucket you would use:
               AWSCredentials credentials = new BasicAWSCredentials(“xxxx”,”yyy/zzz”);
               // create a client connection using keys
       AmazonS3 s3client = new AmazonS3Client(credentials);

4-      Java web application used the keys to access the bucket and processes the user request to upload the content to S3 bucket.

So, you can clearly see that every time an application is deployed to a new environment you have to distribute the access keys along with application, which is not a best practice.

Let see how IAM solves the above problem. Below diagram illustrate the above statement:



You can see following process in above diagram:

1-      An application is running on EC2 instance and EC2 instance is configured with an IAM role “writeAccessS3_Role”.
2-      A user using the application and uploading contents to Amazon S3 bucket.
3-      At this point when application gets the request to upload the content to S3 bucket, it queries EC2 instance metadata and retrieves the credentials based on the role assigned to EC2 instance.

//Create a client connection using keys
AmazonS3 s3client = new AmazonS3Client(credentials);

4-      AWS will return the credentials based on role mapped for the EC2 instance where application is running.
5-      Java application uses the above credentials to access the bucket and processes the user request to upload the content to S3 bucket.
6-      In this case the whole operation is role based; application cannot perform other operations which are not associated with the role.
7-      If role has ‘read-only’ permission then, application cannot upload content. Hence a role called “writeAceessS3_Role” created and mapped with EC2 instance.


So, you can see now we don’t have to distribute the credentials with application, we need to only create roles and map the EC2 instance with it and we are done. Impressive isn’t It J

Note: You can take the advantage of IAM Roles only if application is running on EC2 instance.

Configuring the IAM:


Follow the below given steps:

Ø  Create an IAM role that grants read-only access to Amazon S3.

To create the IAM role
1.       Open the IAM console.
2.       In the navigation pane, click Roles, and then click Create New Role.
3.       Enter a name for the role, and then click Next Step. Remember this name, as you'll need it when you launch your EC2 instance.
4.       On the Select Role Type page, under AWS Service Roles, select Amazon EC2.
5.       On the Set Permissions page, under Select Policy Template, select Amazon S3 Read Only Access. Click Next Step.
6.       On the Review page, click Create Role.

Ø  Launch an EC2 Instance and Specify Your IAM Role

You can launch an EC2 instance with an IAM role using the Amazon EC2 console or the SDK for Java.

1-      To launch an EC2 instance using the console, follow the directions in Launch an EC2 Instance in the Amazon EC2 User Guide for Linux Instances. When you reach the Review Instance Launch page, click Edit instance details. In IAM role, specify the IAM role that you created previously. Complete the procedure as directed. Notice that you'll need to create or use an existing security group and key pair in order to connect to the instance.
2-      To launch an EC2 instance with an IAM role using the SDK for Java, see Run an Amazon EC2 Instance.


Refer to below video to see how to create IAM role and Map EC2 instance:







I have created a utility in java which can perform operations on Amazon S3 buckets using secret keys as well as IAM role.


How do I get the usable jar ?

1    Download a stable version from Maven Central Repository

      Download from Maven Central: 


How do I get the project ?

1-      Visit my github repository


2-      Download or Clone the project and build in local machine.

Note: Use access keys before build in order to pass the test cases or use skip test parameter (-Dmaven.test.skip=true).

To skip the test: e.g. mvn clean install -Dmaven.test.skip=true
3-      For testing IAM services on EC2 instance which is already mapped with IAM role, use the default constructor call to create instance of AwsS3IamService.
Example:
AwsS3IamService awsS3IamService = new AwsS3IamServiceImpl();

4-      For testing IAM services anywhere else use the parameterized constructor call to create instance of AwsS3IamService.
Example:
AwsS3IamService awsS3IamService = new AwsS3IamServiceImpl(AWS_ACCESS_KEY,AWS_SECRET_KEY);

                         
5-      You will get the usable aws-s3-utils.jar file and documentation.


Note: This is a maven based project, so if you are new to maven read my post here.




References:
2-      www.youtube.com





Debugging Alfresco and Share in Eclipse


Prerequisites:


  • Download Eclipse (Note: Eclipse should be JavaEE compitable and should have m2e installed)
  • Get the Alfresco maven archetype (follow the previous post)
  • Import the alfresco project in eclipse

Let's get started..

It is possible to start alfresco in debug mode by using the Maven mvnDebug command. 

Follow the below given steps to debug Alfresco and Share application in Eclipse

1- Right click the pom file of the project which you want to debug.

2- Select Run > Debug Configuration from main menu.

     





3- Click the New Launch Configuration icon on the top left of the dialog.

     




4- Give the Debug Configuration a suitable name.

5- For Goals enter integration-test (for SDK 2.x). For SDK 3.x on wards use goal as "alfresco:run"

6- For Profile enter amp-to-war (for SDK 2.x). For SDK 3.x on wards profile is not needed



    For SDK 3.x: 



7- In the Main tab ensure that Debug Output is selected.

8- Click Apply

9- On the JRE tab add the following VM arguments: -Xms1024m -Xmx4096m -XX:PermSize=1024m to avoid PermGenexceptions.

10- Click Apply.

11- Click Debug to run the Debug Configuration.

12- In Eclipse, click the Debug perspective and wait for the server to start.

By default Alfresco starts on 8080 port. You can change the port by modifying the value in pom.xml. or by adding/overriding the below property in pom.xml (you can find these properties in main project level pom.xml) 
Click Add  (in pom overview section in eclipse)  to add a new parameter name and value. You will enter a parameter name of maven.tomcat.port with a value of 8080.

For alfresco:
 <!-- (Alfresco SDK) | SDK properties have sensible defaults in the SDK parent, | but you can override the properties below to use another version. | 
    For more available properties see the alfresco-sdk-parent POM. -->
  <properties>
    <app.log.root.level>WARN</app.log.root.level>
    <alfresco.data.location>alf_data_dev</alfresco.data.location>
    <!-- This controls which properties will be picked in src/test/properties for embedded run -->
    <env>local</env>
    <!-- Defines the target WAR artifactId to run this amp, only used with the -Pamp-to-war profile | Defaults to a vanilla repository AMP, but could point 
      to your foundation / aggregator WAR . | Allowed values for Community: alfresco | share | Allowed values for Enterprise: alfresco-enterprise | share-enterprise 
      <alfresco.client.war>${alfresco.repo.artifactId}</alfresco.client.war> -->
    <!-- Context path to run alfresco on -->
    <alfresco.client.contextPath>/alfresco</alfresco.client.contextPath>
    <!-- Defines the target WAR groupId to run this amp, only used with the -Pamp-to-war switch . | Could be org.alfresco or your corporate groupId -->
    <!-- <alfresco.client.war.groupId>${alfresco.groupId}</alfresco.client.war.groupId> -->

    <!-- Defines the target WAR version to run this amp, only used with the -Pamp-to-war switch -->
    <!-- <alfresco.client.war.version>${alfresco.version}</alfresco.client.war.version> -->

    <maven.tomcat.port>8080</maven.tomcat.port>
  </properties>



13- For 'Share' we will follow exactly same process as we did above. Follow all steps from 1 to 10.

14- We have configured VM arguments at step 9. It is not required in case of share.

15- Share will run by default on 8081 port. you can modify the port number using the same approach as we did in 12th step. Click Add (in pom overview section in eclipse) to add a new parameter name and value. You will enter a parameter name of maven.tomcat.port with a value of 8081. This causes Share to listen on the 8081 port.

<properties>
        <!-- Defines the target WAR artifactId to run this amp, only used with the -Pamp-to-war switch
        | Allowed values: alfresco | share. In this case it's configured to use OOTB share -->
        <alfresco.client.war>share</alfresco.client.war>

        <!-- Since Alfresco is already running on port 8080, we run Share on port 8081 -->
        <maven.tomcat.port>8081</maven.tomcat.port>

        <!-- Used in share-config-custom.xml. By default points to standard location of Alfresco -->
        <alfresco.repo.url>http://localhost:8080/alfresco</alfresco.repo.url>

        <!-- Defines the log level used in log4j.properties -->
        <app.log.root.level>WARN</app.log.root.level>

    <alfresco.client.contextPath>/share</alfresco.client.contextPath>
    </properties>

16- Once server completes startup process, put the break point in the class file and open share in browser and perform some action where you want to debug. Eclipse will automatically prompt and stop at debug break point.

Note: 
We talked about debugging here, using the same approach we can run alfresco without debug mode. Configure the pom file via "Run > Run Configuration" from main menu (refer step 2 above). And all other steps are same.

For SDK 4.x, see this post:  Alfresco 6.x with SDK4.x and docker command cheatseet


Maven Basics and working with Maven Archetype for Alfresco

1          What is Maven?

Maven is a powerful build tool for Java software projects. Actually, you can build software projects using other languages too, but Maven is developed in Java, and is thus historically used more for Java projects.

The Maven website is located here: http://maven.apache.org/

2          What is a build tool?

A build tool is a tool that automates everything related to building the software project. Building a software project typically includes one or more of these activities:

·         Generating source code (if auto-generated code is used in the project).
·         Generating documentation from the source code.
·         Compiling source code.
·         Packaging compiled code into JAR files or ZIP files.
·         Installing the packaged code on a server, in a repository or somewhere else.

Any given software project may have more activities than these needed to build the finished software. Such activities can normally be plugged into a build tool, so these activities can be automated too.

The advantage of automating the build process is that you minimize the risk of humans making errors while building the software manually. Additionally, an automated build tool is typically faster than a human performing the same steps manually.

3          Maven vs. Ant

Ant is another popular build tool by Apache. If you are used to Ant and you are trying to learn Maven, you will notice a difference in the approach of the two projects.

Ant uses an imperative approach, meaning you specify in the Ant build file what actions Ant should take. You can specify low level actions like copying files, compiling code etc. You specify the actions, and you also specify the sequence in which they are carried out. Ant has no default directory layout.

Maven uses a more declarative approach, meaning that you specify in the Maven POM file what to build, but now how to build it. The POM file describes your project resources - not how to build it. Contrarily, an Ant file describes how to build your project. In Maven, how to build your project is predefined in the Maven Build Life Cycles, Phases and Goals.

4          Overview of Maven

Maven is centered around the concept of POM files (Project Object Model). A POM file is an XML representation of project resources like source code, test code, dependencies (external JARs used) etc. The POM contains references to all of these resources. The POM file should be located in the root directory of the project it belongs to.


Here is a steps illustrating how Maven uses the POM file, and what the POM file primarily contains:

1- Maven parses the pom.xml and starts reading it.

2- Downloads and stores all dependencies provided in pom.xml to local maven repository (%userhome%\.m2\repository).

3-Executes the life cycles, build phases, and goals which are provided in pom.xml.

4- Executes the plug-in (s) provided in pom.xml.


POM Files
When you execute a Maven command you give Maven a POM file to execute the commands on. Maven will then execute the command on the resources described in the POM.

Build Life Cycles, Phases and Goals
The build process in Maven is split up into build life cycles, phases and goals. A build life cycle consists of a sequence of build phases, and each build phase consists of a sequence of goals. When you run Maven you pass a command to Maven. This command is the name of a build life cycle, phase or goal. If a life cycle is requested executed, all build phases in that life cycle are executed. If a build phase is requested executed, all build phases before it in the pre-defined sequence of build phases are executed too.

Dependencies and Repositories
One of the first goals Maven executes is to check the dependencies needed by your project. Dependencies are external JAR files (Java libraries) that your project uses. If the dependencies are not found in the local Maven repository, Maven downloads them from a central Maven repository and puts them in your local repository. The local repository is just a directory on your computer's hard disk. You can specify where the local repository should be located if you want to (I do). You can also specify which remote repository to use for downloading dependencies. All this will be explained in more detail later in this tutorial.

Build Plugins
Build plugins are used to insert extra goals into a build phase. If you need to perform a set of actions for your project which are not covered by the standard Maven build phases and goals, you can add a plugin to the POM file. Maven has some standard plugins you can use, and you can also implement your own in Java if you need to.

Build Profiles
Build profiles are used if you need to build your project in different ways. For instance, you may need to build your project for your local computer, for development and test. And you may need to build it for deployment on your production environment. These two builds may be different. To enable different builds you can add different build profiles to your POM files. When executing Maven you can tell which build profile to use.

Directory structure of a maven project:

- src
  - main
    - java
    - resources
    - webapp
  - test
    - java
    - resources
- target

The src directory is the root directory of your source code and test code. The main directory is the root directory for source code related to the application itself (not test code). The test directory contains the test source code. The java directories under main and test contains the Java code for the application itself (under main) and the Java code for the tests (under test).

The resources directory contains other resources needed by your project. This could be property files used for internationalization of an application, or something else.

The webapp directory contains your Java web application, if your project is a web application. The webapp directory will then be the root directory of the web application. Thus the webapp directory contains the WEB-INF directory etc.

The target directory is created by Maven. It contains all the compiled classes, JAR files etc. produced by Maven. When executing the clean build phase, it is the target directory which is cleaned.

A sample pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
            <!-- The modelVersion element sets what version of the POM model you are
                        using. Use the one matching the Maven version you are using. Version 4.0.0
                        matches Maven version 2 and 3. -->
            <modelVersion>4.0.0</modelVersion>
            <!-- The groupId element is a unique ID for an organization, or a project
                        (an open source project, for instance). Most often you will use a group ID
                        which is similar to the root Java package name of the project. For instance,
                        for my project 'maven-test' I may choose the group ID com.abhinav. Each (.)
                        is replaced with a directory separator, and each word thus represents a directory.
                        The group ID com.abhinav would then be located in a directory called    MAVEN_REPO/com/abhinav.
                        The MAVEN_REPO part of the directory name will be replaced with the directory
                        path of the Maven repository. -->
            <groupId>com.abhinav</groupId>
            <!--The artifactId element contains the name of the project you are building.
                        In the case of my project, the artifact ID would be 'maven-test'. The artifact
                        ID is used as name for a subdirectory under the group ID directory in the
                        Maven repository. The artifact ID is also used as part of the name of the
                        JAR file produced when building the project. The output of the build process,
                        the build result that is, is called an artifact in Maven. Most often it is
                        a JAR, WAR or EAR file, but it could also be something else. -->
            <artifactId>maven-test</artifactId>
            <!--The versionId element contains the version number of the project. If
                        your project has been released in different versions, for instance an open
                        source API, then it is useful to version the builds. That way users of your
                        project can refer to a specific version of your project. The version number
                        is used as a name for a subdirectory under the artifact ID directory. The
                        version number is also used as part of the name of the artifact built. -->
            <version>1.0.0-SNAPSHOT</version>
           
            <!--Note: The above groupId, artifactId and version elements would result
                        in a JAR file being built and put into the local Maven repository at the
                        following path (directory and file name):
                        MAVEN_REPO/com/abhinav/maven-test/1.0.0/maven-test-1.0.0.jar -->

            <!--Maven has built-in dependency management. You specify in the POM file
                        what external libraries your project depends on, and which version, and then
                        Maven downloads them for you and puts them in your local Maven repository.
                        If any of these external libraries need other libraries, then these other
                        libraries are also downloaded into your local Maven repository. You specify
                        your project dependencies inside the dependencies element in the POM file -->

            <!--Sometimes a given dependency is not available in the central Maven
                        repository. You can then download the dependency yourself and put it into
                        your local Maven repository. Remember to put it into a subdirectory structure
                        matching the groupId, artifactId and version. Replace all dots (.) with /
                        and separate the groupId, artifactId and version with / too. Then you have
                        your subdirectory structure. The two dependencies downloaded by the example
                        above will be put into the following subdirectories:
                        1- MAVEN_REPOSITORY_ROOT/junit/junit/4.8.1
                        2- MAVEN_REPOSITORY_ROOT/org/jsoup/jsoup/1.7.1 -->
            <dependencies>
                        <dependency>
                                    <groupId>junit</groupId>
                                    <artifactId>junit</artifactId>
                                    <version>4.8.1</version>
                                    <!-- The scope of the dependency - compile, runtime, test, system, and
                                                provided. Used to calculate the various classpaths used for compilation,
                                                testing, and so on. It also assists in determining which artifacts to include
                                                in a distribution of this project. For more information, see the dependency
                                                mechanism. -->
                                    <scope>test</scope>
                        </dependency>

            <!-- External Dependencies: An external dependency in Maven is a dependency
                        (JAR file) which is not located in a Maven repository (neiterh local, central
                        or remote repository). It may be located somewhere on your local hard disk,
                        for instance in the lib directory of a webapp, or somewhere else. The word
                        "external" thus means external to the Maven repository system - not just
                        external to the project. Most dependencies are external to the project, but
                        few are external to the repository system (not located in a repository).-->

                        <dependency>
                                    <groupId>xqanalyser</groupId>
                                    <artifactId>xqanalyser</artifactId>
                                    <scope>system</scope>
                                    <version>1.0</version>
                                    <!-- The ${basedir} points to the directory where the POM is located. The
                                    rest of the path is relative from that directory. -->
                                    <systemPath>${basedir}\lib\xqanalyser.jar</systemPath>
                        </dependency>

            <!-- Snapshot Dependencies: Snapshot dependencies are dependencies (JAR
                        files) which are under development. Instead of constantly updating the version
                        numbers to get the latest version, you can depend on a snapshot version of
                        the project. Snapshot versions are always downloaded into your local repository
                        for every build, even if a matching snapshot version is already located in
                        your local repository. Always downloading the snapshot dependencies assures
                        that you always have the latest version in your local repository, for every
                        build. You can tell Maven that your project is a snapshot version simply
                        by appending -SNAPSHOT to the version number in the beginning of the POM
                        (where you also set the groupId and artifactId).
                       
                        Here is a version element example: <version>1.0-SNAPSHOT</version>
                       
                        Notice the -SNAPSHOT appended to the version number.
                        Depending on a snapshot version is also done by appending
                        the -SNAPSHOT after the version number when configuring dependencies.
                        Here is an example:
                       
                        <dependency>
                        <groupId>com.abhinav.java.rest</groupId>
                        <artifactId>java-rest-services</artifactId>
                        <version>1.0-SNAPSHOT</version>
            </dependency> -->    
           
            </dependencies>
</project>

5        Maven Repositories

Maven repositories are directories of packaged JAR files with extra metadata.
The metadata are POM files describing the projects each packaged JAR file belongs to, including what external dependencies each packaged JAR has. It is this metadata that enables Maven to download dependencies of your dependencies recursively, until the whole tree of dependencies gets downloaded and put into your local repository.

Maven repositories are covered in more detail in the Maven Introduction to Repositories, but here is a quick overview.
Maven has three types of repository:
  • Local repository
  • Central repository
  • Remote repository
Maven searches these repositories for dependencies in the above sequence. First in the local repository, then in the central repository, and third in remote repositories if specified in the POM.

Here is a diagram illustrating the three repository types and their location:




Local Repository
A local repository is a directory on the developer's computer. This repository will contain all the dependencies Maven downloads. The same Maven repository is typically used for several different projects. Thus Maven only needs to download the dependencies once, even if multiple projects depends on them (e.g. Junit).

Your own projects can also be built and installed in your local repository, using the mvn install command. That way your other projects can use the packaged JAR files of your own projects as external dependencies by specifying them as external dependencies inside their Maven POM files.

By default Maven puts your local repository inside your user home directory on your local computer. However, you can change the location of the local repository by setting the directory inside your Maven settings file. Your Maven settings file is also located in your user-home/.m2 directory and is called settings.xml. Here is how you specify another location for your local repository:

<settings>
<localRepository>
        d:\data\java\products\maven\repository
</localRepository>
</settings>
  
Central Repository
The central Maven repository is a repository provided by the Maven community. By default Maven looks in this central repository for any dependencies needed but not found in your local repository. Maven then downloads these dependencies into your local repository. You need no special configuration to access the central repository.

Remote Repository
A remote repository is a repository on a web server from which Maven can download dependencies, just like the central repository. A remote repository can be located anywhere on the internet, or inside a local network.

A remote repository is often used for hosting projects internal to your organization, which are shared by multiple projects. For instance, a common security project might be used across multiple internal projects. This security project should not be accessible to the outside world, and should thus not be hosted in the public, central Maven repository. Instead it can be hosted in an internal remote repository.

Dependencies found in a remote repository are also downloaded and put into your local repository by Maven.

You can configure a remote repository in the POM file. Put the following XML elements right after the <dependencies> element:

<repositories>
<repository>
<id>org.apache</id>
<url>http://maven.apache.com/maven2/lib</url>
</repository>
</repositories>

6          Maven Build Life Cycles, Phases and Goals

When Maven builds a software project it follows a build life cycle. The build life cycle is divided into build phases, and the build phases are divided into build goals. Maven build life cycles, build phases and goals are described in more detail in the Maven Introduction to Build Phases, but here I will give you a quick overview.

Build Life Cycles

Maven has 3 built-in build life cycles.

1.      default
2.      clean
3.      site

Each of these build life cycles takes care of a different aspect of building a software project. Thus, each of these build life cycles are executed independently of each other. You can get Maven to execute more than one build life cycle, but they will be executed in sequence, separately from each other, as if you had executed two separate Maven commands.

The default life cycle handles everything related to compiling and packaging your project. The clean life cycle handles everything related to removing temporary files from the output directory, including generated source files, compiled classes, previous JAR files etc. The site life cycle handles everything related to generating documentation for your project. In fact, site can generate a complete website with documentation for your project.

Build Phases

Each build life cycle is divided into a sequence of build phases, and the build phases are again subdivided into goals. Thus, the total build process is a sequence of build life cycle(s), build phases and goals.

You can execute either a whole build life cycle like clean or site, a build phase like install which is part of the default build life cycle, or a build goal like dependency:copy-dependencies.
Note: You cannot execute the default life cycle directly. You have to specify a build phase or goal inside the default life cycle.

When you execute a build phase, all build phases before that build phase in this standard phase sequence are executed. Thus, executing the install build phase really means executing all build phases before the installphase, and then execute the install phase after that.

The default life cycle is of most interest since that is what builds the code. Since you cannot execute the default life cycle directly, you need to execute a build phase or goal from the default life cycle. The default life cycle has an extensive sequence of build phases and goals, so I will not describe them all here. The most commonly used build phases are:

Build Phase Description
validate
Validates that the project is correct and all necessary information is available. This also makes sure the dependencies are downloaded.
compile
Compiles the source code of the project.
test
Runs the tests against the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed.
package
Packs the compiled code in its distributable format, such as a JAR.
install
Install the package into the local repository, for use as a dependency in other projects locally.
deploy
Copies the final package to the remote repository for sharing with other developers and projects.
verify
Run any checks to verify the package is valid and meets quality criteria
integration-test
Process and deploy the package if necessary into an environment where integration tests can be run



You execute one of these build phases by passing its name to the mvn command.
Here is an example:

mvn package

This example executes the package build phase, and thus also all build phases before it in Maven's predefined build phase sequence.
If the standard Maven build phases and goals are not enough to build your project, you can create Maven plugins to add the extra build functionality you need.

There are two other Maven lifecycles of note beyond the default list above. They are
  • clean: cleans up artifacts created by prior builds
  • site: generates site documentation for this project

Phases are actually mapped to underlying goals. The specific goals executed per phase is dependant upon the packaging type of the project. For example, package executes jar:jar if the project type is a JAR, and war:war if the project type is - you guessed it - a WAR.
An interesting thing to note is that phases and goals may be executed in sequence.      

mvn clean dependency:copy-dependencies package
 
This command will clean the project, copy dependencies, and package the project (executing all phases up to package, of course).

Generating the Site:

mvn site

This phase generates a site based upon information on the project's pom. You can look at the documentation generated under target/site.
  
Build Goals
Build goals are the finest steps in the Maven build process. A goal can be bound to one or more build phases or to none at all. If a goal is not bound to any build phase, you can only execute it by passing the goals name to the mvn command. If a goal is bound to multiple build phases, that goal will get executed during each of the build phases it is bound to.

7        Installing maven

To install Maven on your own system (computer), go to the Maven download page and follow the instructions there. In summary, what you need to do is:

1.      Download and unzip Maven.
2.      Set the M2_HOME environment variable to point to the directory you unzipped Maven to.
3.      Set the M2 environment variable to point to M2_HOME/bin (%M2_HOME%\bin on Windows, $M2_HOME/bin on unix).
4.      Add M2 to the PATH environment variable (%M2% on Windows, $M2 on unix).
5.      Open a command prompt and type 'mvn' (without quotes) and press enter.
After typing in the 'mvn' command you should be able to see a Maven error written to the command prompt. Don't worry about the error. It is expected because you haven't yet any POM file to pass to Maven. But the fact that you get a Maven error means that Maven is now installed.

Note: Maven uses Java when executing, so you need Java installed to. Maven needs a Java version 1.5 or later.

8 Repository AMP archetype

The Alfresco SDK Alfresco AMP archetype can be used to create an AMP-based project. This is used for simple, single module applications.

8.1         Steps to generate amp based projects:

v  Create a suitable workspace directory in which to store all your Maven projects (if you have not already done so), such as EclipseWorkspace.
v  Open command prompt and change into your EclipseWorkspace directory.
v  Run the following command:

mvn archetype:generate -Dfilter=org.alfresco.maven.archetype:


v  You will be prompted to select type of archtype:

1.      Alfresco All-in-one archetype: Sample multi-module project for All-in-One development on the Alfresco plaftorm. Includes modules for: Repository WAR overlay, Repository AMP, Share WAR overlay, Solr configuration, and embedded Tomcat runner.
2.      Alfresco AMP archetype: Sample project with full support for lifecycle and rapid development of Repository AMPs (Alfresco Module Packages).
3.      Share AMP archetype: Share project with full support for lifecycle and rapid development of AMPs (Alfresco Module Packages).


v  Suppose you want to generate Alfresco Module Package (AMP) project, then enter 2 to have the SDK create the project. I am "1" selecting for "allinone-archetype", The detailed documentation for this archetype can be found here

v  Now, you will be prompted to choose archetype version. 6th version is the latest version and will be default. I am selecting 5th version for example. Hit Enter to continue..

v  Now you will be prompted to enter a value for the property groupId. Enter com.abhinav.alfresco for the groupId, this can be thought of as the package name. here.

v  Now you will then be prompted to enter a value for the artifactId. Enter alfresco-test as the artifactId. This can be thought of as the project name. Note, hyphens are typically used in project names.

v  Now you will then be prompted to enter a value for the Alfresco version you wish to test against (currently the default is 5.0.c). Hit the Enter key to accept the default (Y) value. Else write ‘N’to provide the version for which you want to generate the stub project e.g.5.0.a. Follow the instructions after that. A new project directory containing a number of sub-directories and support files for the AMP will be created in the directory alfresco-test.



v  Go to newly created project inside EclipseWorkspace, and import the project as a maven project. 

v  Before running maven set the MAVEN_OPTS environment variable,  to avoid PermGenexceptions.

MAVEN_OPTS  = -Xms1024m -Xmx4096m -XX:PermSize=1024m 


v  You can use following command to build the project.

mvn compile

v  Now, at this point you can build and install the amp using following command, it will build the project and creates amp also.

mvn clean install

If you have maven plug-in installed in Eclipse then you can right click on ‘pom.xml’ and select Run As>Run Configuration> clean install

Note: 'clean' command is given to clean the existing compiled code and it is optional.

Maven will ensure that all requirements are downloaded. This make take some time.
The project will return with the message BUILD SUCCESS after processing.

Other common usage supported by this archetype includes the following:
Command
Description
mvn package
Runs unit tests and packages AMP in ${project.build.directory}/${project.build.finalName}.amp
mvn install
Like mvn package but also installs AMP in local Maven repository to be depended upon
mvn test
Runs unit tests
mvn install -DskipTests=true
Like mvn install but skips unit tests
mvn install -Prun
 Like mvn install but also triggers the runner project to run Alfresco, Share, Solr and Web Quick Start in Tomcat (with H2 embedded database)
mvn clean -Ppurge
Removes DB, alf_data, indexes and log files. Useful to purge the development repo (by default self contained in ${project.basedir}/alf_data_dev.
Note:This is an important command to use if you change significant settings in your project - for example you change the Alfresco edition from Community to Enterprise. It is important to purge databases and other data that might otherwise be persisted.
mvn install -Pamp-to-war,rad
Similar to mvn install -Pamp-to-war but also adds support for remote JUnit running and for hot reloading with JRebel (requires appropriate MAVEN_OPTS configuration).

v  Now run your project using:

            mvn integration-test -Pamp-to-war
or 
mvn install –Prun


v  You will see the Java application server (Tomcat is used by default) load and various tests run.
Attention: If you see PermGen space errors you will need to increase the size of memory allocated to Alfresco and Tomcat via your MAVEN_OPTS environment variable.

v  You can also install amp file to your alfresco installation (C:\Alfresco\tomcat\webapps\alfresco.war) using mmt tool and restart the server, if you don’t want to use the eclipse.

v  You can test Alfresco is running correctly by pointing your web browser at http://localhost:8080/shareor http://localhost:8080/alfresco and logging in with a username admin and a password of admin.

Importing maven artifact in eclipse, watch this video:



8.2         Adding external/custom jars into Maven project

One of the strongest points of Maven is that it automatically manages project dependencies. The developer just needs to specify which dependencies and in which version are needed and the Maven takes care of the rest including downloading and storing them at the right location and additionally packaging them into final artifact (e.g. WAR). This is very convenient and almost completely removes a need to hold additional jars in lib/ project subdirectory.
However, there is a small assumption that all required dependencies are available at one or more public repositories. It is usually the case but sometimes you may need to use a jar which is not available there for some reason. Luckily, there are few popular approaches to overcome this problem which are described below.

8.2.1        Adding jar to public Maven repository

Theoretically, the best way would be to add a jar to a public Maven repository. However, if the jar is proprietary, it is usually impossible to get the permission from the company to do so.

8.2.2        Using system dependency

The second method is to add the required dependency with the system scope and additionally provide an absolute path to the a jar file placed somewhere on the local disc:

<dependencies>
  <dependency>
    <groupId>com.abhinav.restservices</groupId>
    <artifactId>rest-services-util</artifactId>
    <version>1.0</version>
    <scope>system</scope>
    <systemPath>${basedir}/lib/rest-services-util.jar</systemPath>
  </dependency>
</dependencies>
The problem with this approach is that this dependency will be completely ignored during packaging and forcing Maven to add it to the final artifact (e.g. WAR) would result in a very clumsy POM file.

8.2.3        Installing jar into local Maven repository

Much better solution is to add the required dependency manually to the local repository using command:

$ mvn install:install-file -Dfile=<path-to-file>
    -DgroupId=<group-id> -DartifactId=<artifact-id>
    -Dversion=<version> -Dpackaging=<packaging>
There are several options to be filled on the command:
  • path-to-file: the path to the file of the artifact to install.
  • myGroup, myArtifactId, myVersion: the group, artifact name and version of the artifact to install.
  • myPackaging: the packaging of the artifact (ie: jar).
  • path: the path to the local repo.
For example adding external jar rest-services-util-1.0.jar to the local repository could look like this:

$ mvn install:install-file -Dfile=D:\Abhinav\EclipseWorkspace\RESTServicesUtil\jar\rest-services-util.jar -DgroupId=com.abhinav.restservices -DartifactId=rest-services-util  -Dversion=1.0 -Dpackaging=jar

Once the dependency is available in the local repository it can be added to POM file like any other dependency:

<dependencies>
  <dependency>
<groupId>com.abhinav.restservices</groupId>
<artifactId>rest-services-util</artifactId>
<version>1.0</version>
</dependency>
</dependencies>

This solution is still inconvenient because every new developer working on the project would have to run mvn install:install command on its own workstation.

8.2.4        Using internal Maven repository in a company


One of the best ideas is to setup an internal Maven repository in a company for storing such dependencies. The repository should be available to every developer working on a project though HTTP or other protocol supported by Maven. Of course, the repository server does not have to be available from outside of the company.
The required dependencies should be installed on the repository server using mvn install:install-file command:

$ mvn install:install-file -Dfile=D:\Abhinav\EclipseWorkspace\RESTServicesUtil\jar\rest-services-util.jar -DgroupId=com.abhinav.restservices -DartifactId=rest-services-util  -Dversion=1.0 -Dpackaging=jar-DlocalRepositoryPath=c:\mvn-repository

The only difference from the command in the previous section is that it additionally specifies the path on the repository server where the jars and metadata should be stored.
Once it is finished, the dependency can be added to the POM file. Additionally, the location of the new repository server is provided:

<repositories>
  <repository>
    <id>Internal company repository</id>
    <url>http://mvnrepo.company.com/</url>
  </repository>
</repositories>
(...)
<dependencies>
  <dependency>
<groupId>com.abhinav.restservices</groupId>
<artifactId>rest-services-util</artifactId>
<version>1.0</version>
</dependency>
</dependencies>

The advantages of this approach should be clearly visible:
§  new developers can start building the project without any additional preparation tasks
§  no need to send jars though emails, IM or downloading them from the Internet
§  reduced or completely removed need for build instructions
§  all external jars are managed in a single place
§  dependencies and the server can be shared by multiple projects
  

8.2.5        Using in-project Maven repository

The idea is quite similar to using internal repository server but this time the repository is stored in a directory (e.g. called lib) located in a project root directory. After creating the directory and installing jar files there using mvninstall:install-file command, the dependencies and the repository can be referenced from a POM file:

<repositories>
  <repository>
    <id>Internal company repository</id>
    <url>file://${basedir}/lib</url>
  </repository>
</repositories>
(...)
<dependencies>
  <dependency>
<groupId>com.abhinav.restservices</groupId>
<artifactId>rest-services-util</artifactId>
<version>1.0</version>
</dependency>
</dependencies>

The created repository including jars, pom files and checksums must be stored in a version control system so that it is available to other developers. The biggest issue with this solution is that it clutters VCS (version control system) repository with files that such never be placed there (e.g. jars).


To deploy the jar file to remote maven repository use following command:

Syntax:

mvn deploy:deploy-file -DgroupId=<group-id> 
  -DartifactId=<artifact-id> 
  -Dversion=<version> 
  -Dpackaging=<type-of-packaging> 
  -Dfile=<path-to-file> 
  -DrepositoryId=<id-to-map-on-server-section-of-settings.xml> 

  -Durl=<url-of-the-repository-to-deploy>

Example:

mvn deploy:deploy-file -DgroupId=com.abhinav.restservices -DartifactId=rest-services-util -Dversion=1.0 -Dpackaging=jar -Dfile=C:\Users\abhinav\.m2\repository\com\abhinav\restservices\rest-service-util\1.0\rest-service-util-1.0.jar -DrepositoryId=central -Durl=https://repo1.maven.org/maven2

References:  

1- http://docs.alfresco.com/community/concepts/welcome-infocenter_community.html
2- https://maven.apache.org/guides/index.html
3- www.tutorials.jenkov.com