User's Guide

Xiaohao Ma edited this page Nov 23, 2016 · 16 revisions

Summary

aws-mock is compliant to all AWS-SDKs provided by Amazon (http://aws.amazon.com/tools/) as it conforms to the official WSDL. At the time of this writing, only ec2 and CloudWatch have been mocked in aws-mock. Below, we provide documentation on mocking ec2 (And mocking of CloudWatch would be quite similar to that - we'll mention the CloudWatch servlet too).

Supporting a mock implementation for limited but frequently used ec2 interfaces along with essential response data, aws-mock is proven to work with Java (aws-java-sdk) and Node.js (aws-javascript-sdk).

Typically, for testing purposes, you can run aws-mock (or its extension) as a local web service endpoint and have your application, which uses AWS-SDK, point to that local endpoint. In that way, your application can freely supervise a huge number of mock ec2 instances.

Quick start

git clone https://github.com/treelogic-swe/aws-mock.git
cd aws-mock
gradle jettyRun

Now a local ec2 endpoint is available at http://localhost:8000/aws-mock/ec2-endpoint/.

Customize configuration

Review the default configuration file src/main/resources/aws-mock-default.properties and you can override the default properties by adding your own properties to a file named aws-mock.properties, which should be put into classpath.

Define your own AMIs

predefined.mock.ami.1=ami-11223344
predefined.mock.ami.2=ami-0f0f0f0f

Then you will later be able to run new mock instances upon those 2 AMIs.

Define your own boot/shutdown time range

instance.min.boot.time=60000
instance.max.boot.time=90000

That makes each mock instance's boot time randomly between 1 minute (60000 ms) and 1.5 minutes (90000 ms), which is the amount of pending time before turning into running. Mocking of the random shutdown time can be similarly assigned as instance.min.shutdown.time and instance.max.shutdown.time.

And alternatively, you could use properties .time.seconds instead of those .time ones, to use second as the time unit instead of millisecond. And in case both of those types exists in the same property file, .time will take precedence over .time.seconds.

instance.min.boot.time.seconds=60
instance.max.boot.time.seconds=90

Also, setting max boot/shutdown time to zero indicates that the mock ec2 instance will always boot/shutdown immediately without any random delay.

Enable persistence

persistence.enabled=true
persistence.store.file=/path/to/your/aws-mock.save

With persistence enabled, on aws-mock web app re-starting, everything resumes from the point that last time you shutdown aws-mock web app.

Extending aws-mock

By default, in aws-mock, every mock ec2 instance is of com.tlswe.awsmock.ec2.model.DefaultMockEc2Instance and behaves the default way. To mock instances that emulate your own business, you probably need to 'extend' aws-mock, by creating your own web app and running your own local endpoint!

First of all create a new Java web application and add aws-mock dependency from Maven to it

For maven developers:

<dependency>
    <groupId>com.treelogic-swe</groupId>
    <artifactId>aws-mock</artifactId>
    <version>1.1.0</version>
</dependency>

For gradle developers:

compile 'com.treelogic-swe:aws-mock:1.1.0'

Create your own mock ec2 instance class

Create a new Java class, for example, com.example.MyMockEc2Instance, which extends com.tlswe.awsmock.ec2.model.AbstractMockEc2Instance, and here you can put your own business logic implementation for instances to the following overridden events:

public void onStarted(){/*your business logic here*/} // triggered when powered-on
public void onBooted(){/*your business logic here*/} // triggered on turning from pending to running
public void onStopping(){/*your business logic here*/} // triggered when stopping process begins
public void onStopped(){/*your business logic here*/} // triggered when stopping process finishes (powered-off)
public void onTerminating(){/*your business logic here*/} // triggered when termination process begins
public void onTerminated(){/*your business logic here*/} // triggered when termination process finishes

Override property ec2.instance.class

Define the overriding property ec2.instance.class=com.example.MyMockEc2Instance in file aws-mock.properties, which should be put in classpath. Override other necessary properties there as discussed above.

Add listener for persistence to your web.xml (only if you enabled persistence)

<listener>
    <listener-class>com.tlswe.awsmock.common.listener.AppServletContextListener</listener-class>
</listener>

Finally, add the servlet for mock ec2 endpoint to your web.xml

<servlet>
    <servlet-name>MockEc2EndpointServlet</servlet-name>
    <servlet-class>com.tlswe.awsmock.ec2.servlet.MockEc2EndpointServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>MockEc2EndpointServlet</servlet-name>
    <url-pattern>/ec2-endpoint/*</url-pattern>
</servlet-mapping>

Now run your new web application in servlet container and, in your client code, set ec2 endpoint url to such as http://localhost:8080/yourapp/ec2-endpoint/. You will find your client working perfectly with the instances which can mock your own business!

Similarly, if you want to mock CloudWatch, simply add the following to web.xml

<servlet>
    <servlet-name>MockCloudWatchEndpointServlet</servlet-name>
    <servlet-class>com.tlswe.awsmock.cloudwatch.servlet.MockCloudWatchEndpointServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>MockCloudWatchEndpointServlet</servlet-name>
    <url-pattern>/cloudwatch/*</url-pattern>
</servlet-mapping>

The CloudWatch endpoint will be running at: http://localhost:8080/yourapp/cloudwatch/. To customize the statistical data provided by CloudWatch mock, like we do to ec2 mock, please refer to the many properties in aws-mock-default.properties and override them if necessary.

Client side setup

For Java:

As mentioned, simply use aws-java-sdk (http://aws.amazon.com/sdkforjava/):

AmazonEC2Client eC2Client = new AmazonEC2Client(new BasicAWSCredentials("foo", "bar"));
eC2Client.setEndpoint("http://localhost:8000/aws-mock/ec2-endpoint/");
// ...

For Node.js:

  1. Install aws-sdk by running npm install -g aws-sdk.
  2. In your web server such as Nginx or Apache, add a reverse proxy route for actual backend endpoint url http://localhost:8000/aws-mock/ec2-endpoint/ to a root directory http://localhost:9090/. The reason why we proxy-pass the endpoint url to "/" can be found here.

Now you can initialize your ec2 client:

var AWS = require('aws-sdk');
AWS.config.update({ 
    accessKeyId : 'foo', secretAccessKey : 'bar', region : 'baz' 
});
var eC2Client = new AWS.EC2({ 
    endpoint : new AWS.Endpoint("http://localhost:9090/") 
});
// ...

Note that aws-mock doesn't authenticate credentials at all.

Example Code

Look into the examples for using aws-mock, which are written in Java and Node.js: https://github.com/treelogic-swe/aws-mock/tree/master/example