diff --git a/web/api/src/test/java/org/onosproject/rest/MetersResourceTest.java b/web/api/src/test/java/org/onosproject/rest/MetersResourceTest.java
new file mode 100644
index 0000000..3714e48
--- /dev/null
+++ b/web/api/src/test/java/org/onosproject/rest/MetersResourceTest.java
@@ -0,0 +1,461 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.rest;
+
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+import com.google.common.collect.ImmutableSet;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.rest.BaseResource;
+import org.onosproject.codec.CodecService;
+import org.onosproject.codec.impl.CodecManager;
+import org.onosproject.codec.impl.MeterCodec;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.meter.Band;
+import org.onosproject.net.meter.DefaultBand;
+import org.onosproject.net.meter.Meter;
+import org.onosproject.net.meter.MeterId;
+import org.onosproject.net.meter.MeterService;
+import org.onosproject.net.meter.MeterState;
+
+import javax.ws.rs.core.MediaType;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyShort;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onosproject.net.NetTestTools.APP_ID;
+
+/**
+ * Unit tests for meters REST APIs.
+ */
+public class MetersResourceTest extends ResourceTest {
+    final MeterService mockMeterService = createMock(MeterService.class);
+    CoreService mockCoreService = createMock(CoreService.class);
+    final DeviceService mockDeviceService = createMock(DeviceService.class);
+
+    final HashMap<DeviceId, Set<Meter>> meters = new HashMap<>();
+
+    final DeviceId deviceId1 = DeviceId.deviceId("1");
+    final DeviceId deviceId2 = DeviceId.deviceId("2");
+    final DeviceId deviceId3 = DeviceId.deviceId("3");
+    final Device device1 = new DefaultDevice(null, deviceId1, Device.Type.OTHER,
+            "", "", "", "", null);
+    final Device device2 = new DefaultDevice(null, deviceId2, Device.Type.OTHER,
+            "", "", "", "", null);
+
+    final MockMeter meter1 = new MockMeter(deviceId1, 1, 111, 1);
+    final MockMeter meter2 = new MockMeter(deviceId1, 2, 222, 2);
+    final MockMeter meter3 = new MockMeter(deviceId2, 3, 333, 3);
+    final MockMeter meter4 = new MockMeter(deviceId2, 4, 444, 4);
+    final MockMeter meter5 = new MockMeter(deviceId3, 5, 555, 5);
+
+    /**
+     * Mock class for a meter.
+     */
+    private static class MockMeter implements Meter {
+
+        final DeviceId deviceId;
+        final ApplicationId appId;
+        final MeterId meterId;
+        final long baseValue;
+        final List<Band> bandList;
+
+        public MockMeter(DeviceId deviceId, int appId, long meterId, int id) {
+            this.deviceId = deviceId;
+            this.appId = new DefaultApplicationId(appId, String.valueOf(appId));
+            this.baseValue = id * 200;
+            this.meterId = MeterId.meterId(meterId);
+
+            Band band = DefaultBand.builder()
+                    .ofType(Band.Type.REMARK)
+                    .withRate(10)
+                    .dropPrecedence((short) 20)
+                    .burstSize(30).build();
+
+            this.bandList = new ArrayList<>();
+            this.bandList.add(band);
+        }
+
+        @Override
+        public DeviceId deviceId() {
+            return this.deviceId;
+        }
+
+        @Override
+        public MeterId id() {
+            return this.meterId;
+        }
+
+        @Override
+        public ApplicationId appId() {
+            return this.appId;
+        }
+
+        @Override
+        public Unit unit() {
+            return Unit.KB_PER_SEC;
+        }
+
+        @Override
+        public boolean isBurst() {
+            return false;
+        }
+
+        @Override
+        public Collection<Band> bands() {
+            return this.bandList;
+        }
+
+        @Override
+        public MeterState state() {
+            return MeterState.ADDED;
+        }
+
+        @Override
+        public long life() {
+            return baseValue + 11;
+        }
+
+        @Override
+        public long referenceCount() {
+            return baseValue + 22;
+        }
+
+        @Override
+        public long packetsSeen() {
+            return baseValue + 33;
+        }
+
+        @Override
+        public long bytesSeen() {
+            return baseValue + 44;
+        }
+    }
+
+    /**
+     * Populates some meters used as testing data.
+     */
+    private void setupMockMeters() {
+        final Set<Meter> meters1 = new HashSet<>();
+        meters1.add(meter1);
+        meters1.add(meter2);
+
+        final Set<Meter> meters2 = new HashSet<>();
+        meters2.add(meter3);
+        meters2.add(meter4);
+
+        meters.put(deviceId1, meters1);
+        meters.put(deviceId2, meters2);
+
+        Set<Meter> allMeters = new HashSet<>();
+        for (DeviceId deviceId : meters.keySet()) {
+            allMeters.addAll(meters.get(deviceId));
+        }
+
+        expect(mockMeterService.getAllMeters()).andReturn(allMeters).anyTimes();
+    }
+
+    /**
+     * Sets up the global values for all the tests.
+     */
+    @Before
+    public void setUpTest() {
+        // Mock device service
+        expect(mockDeviceService.getDevice(deviceId1))
+                .andReturn(device1);
+        expect(mockDeviceService.getDevice(deviceId2))
+                .andReturn(device2);
+        expect(mockDeviceService.getDevices())
+                .andReturn(ImmutableSet.of(device1, device2));
+
+        // Mock Core Service
+        expect(mockCoreService.getAppId(anyShort()))
+                .andReturn(NetTestTools.APP_ID).anyTimes();
+        expect(mockCoreService.registerApplication(MeterCodec.REST_APP_ID))
+                .andReturn(APP_ID).anyTimes();
+        replay(mockCoreService);
+
+        // Register the services needed for the test
+        final CodecManager codecService = new CodecManager();
+        codecService.activate();
+        ServiceDirectory testDirectory =
+                new TestServiceDirectory()
+                        .add(MeterService.class, mockMeterService)
+                        .add(DeviceService.class, mockDeviceService)
+                        .add(CodecService.class, codecService)
+                        .add(CoreService.class, mockCoreService);
+
+        BaseResource.setServiceDirectory(testDirectory);
+    }
+
+    /**
+     * Cleans up and verifies the mocks.
+     */
+    @After
+    public void tearDownTest() {
+        verify(mockMeterService);
+        verify(mockCoreService);
+    }
+
+    /**
+     * Hamcrest matcher to check that a meter representation in JSON matches
+     * the actual meter.
+     */
+    public static class MeterJsonMatcher extends TypeSafeMatcher<JsonObject> {
+        private final Meter meter;
+        private String reason = "";
+
+        public MeterJsonMatcher(Meter meterValue) {
+            this.meter = meterValue;
+        }
+
+        @Override
+        protected boolean matchesSafely(JsonObject jsonMeter) {
+
+            // check application id
+            final String jsonAppId = jsonMeter.get("appId").asString();
+            final String appId = meter.appId().toString();
+            if (!jsonAppId.equals(appId)) {
+                reason = "appId " + meter.appId().toString();
+                return false;
+            }
+
+            // check device id
+            final String jsonDeviceId = jsonMeter.get("deviceId").asString();
+            if (!jsonDeviceId.equals(meter.deviceId().toString())) {
+                reason = "deviceId " + meter.deviceId();
+                return false;
+            }
+
+            // check band array
+            if (meter.bands() != null) {
+                final JsonArray jsonBands = jsonMeter.get("bands").asArray();
+                if (meter.bands().size() != jsonBands.size()) {
+                    reason = "bands array size of " +
+                            Integer.toString(meter.bands().size());
+                    return false;
+                }
+                for (final Band band : meter.bands()) {
+                    boolean bandFound = false;
+                    for (int bandIndex = 0; bandIndex < jsonBands.size(); bandIndex++) {
+                        final String jsonType = jsonBands.get(bandIndex).asObject().get("type").asString();
+                        final String bandType = band.type().name();
+                        if (jsonType.equals(bandType)) {
+                            bandFound = true;
+                        }
+                    }
+                    if (!bandFound) {
+                        reason = "meter band " + band.toString();
+                        return false;
+                    }
+                }
+            }
+
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    private static MeterJsonMatcher matchesMeter(Meter meter) {
+        return new MeterJsonMatcher(meter);
+    }
+
+    /**
+     * Hamcrest matcher to check that a meter is represented properly in a JSON
+     * array of meters.
+     */
+    public static class MeterJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
+        private final Meter meter;
+        private String reason = "";
+
+        public MeterJsonArrayMatcher(Meter meterValue) {
+            meter = meterValue;
+        }
+
+        @Override
+        protected boolean matchesSafely(JsonArray json) {
+            boolean meterFound = false;
+            for (int jsonMeterIndex = 0; jsonMeterIndex < json.size(); jsonMeterIndex++) {
+                final JsonObject jsonMeter = json.get(jsonMeterIndex).asObject();
+
+                final String meterId = meter.id().toString();
+                final String jsonMeterId = jsonMeter.get("id").asString();
+                if (jsonMeterId.equals(meterId)) {
+                    meterFound = true;
+
+                    assertThat(jsonMeter, matchesMeter(meter));
+                }
+            }
+            if (!meterFound) {
+                reason = "Meter with id " + meter.id().toString() + " not found";
+                return false;
+            } else {
+                return true;
+            }
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a meter array matcher.
+     *
+     * @param meter meter object we are looking for
+     * @return matcher
+     */
+    private static MeterJsonArrayMatcher hasMeter(Meter meter) {
+        return new MeterJsonArrayMatcher(meter);
+    }
+
+    @Test
+    public void testMeterEmptyArray() {
+        expect(mockMeterService.getAllMeters()).andReturn(null).anyTimes();
+        replay(mockMeterService);
+        replay(mockDeviceService);
+        final WebResource rs = resource();
+        final String response = rs.path("meters").get(String.class);
+        assertThat(response, is("{\"meters\":[]}"));
+    }
+
+    /**
+     * Tests the result of the rest api GET when there are active meters.
+     */
+    @Test
+    public void testMetersPopulatedArray() {
+        setupMockMeters();
+        replay(mockMeterService);
+        replay(mockDeviceService);
+        final WebResource rs = resource();
+        final String response = rs.path("meters").get(String.class);
+        final JsonObject result = JsonObject.readFrom(response);
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("meters"));
+        final JsonArray jsonMeters = result.get("meters").asArray();
+        assertThat(jsonMeters, notNullValue());
+        assertThat(jsonMeters, hasMeter(meter1));
+        assertThat(jsonMeters, hasMeter(meter2));
+        assertThat(jsonMeters, hasMeter(meter3));
+        assertThat(jsonMeters, hasMeter(meter4));
+    }
+
+    /**
+     * Tests the result of a rest api GET for a device.
+     */
+    @Test
+    public void testMeterSingleDeviceWithId() {
+        setupMockMeters();
+
+        expect(mockMeterService.getMeter(anyObject(), anyObject()))
+                .andReturn(meter5).anyTimes();
+        replay(mockMeterService);
+        replay(mockDeviceService);
+
+        final WebResource rs = resource();
+        final String response = rs.path("meters/" + deviceId3.toString()
+                + "/" + meter5.id().id()).get(String.class);
+        final JsonObject result = JsonObject.readFrom(response);
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("meters"));
+        final JsonArray jsonFlows = result.get("meters").asArray();
+        assertThat(jsonFlows, notNullValue());
+        assertThat(jsonFlows, hasMeter(meter5));
+    }
+
+    /**
+     * Tests creating a meter with POST.
+     */
+    @Test
+    public void testPost() {
+        mockMeterService.submit(anyObject());
+        expectLastCall().andReturn(meter5).anyTimes();
+        replay(mockMeterService);
+
+        WebResource rs = resource();
+        InputStream jsonStream = MetersResourceTest.class
+                .getResourceAsStream("post-meter.json");
+
+        ClientResponse response = rs.path("meters/of:0000000000000001")
+                .type(MediaType.APPLICATION_JSON_TYPE)
+                .post(ClientResponse.class, jsonStream);
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+    }
+
+    /**
+     * Tests deleting a meter.
+     */
+    @Test
+    public void testDelete() {
+        setupMockMeters();
+        expect(mockMeterService.getMeter(anyObject(), anyObject()))
+                .andReturn(meter5).anyTimes();
+        mockMeterService.withdraw(anyObject(), anyObject());
+        expectLastCall();
+        replay(mockMeterService);
+
+        WebResource rs = resource();
+
+        String location = "/meters/3/555";
+
+        ClientResponse deleteResponse = rs.path(location)
+                .type(MediaType.APPLICATION_JSON_TYPE)
+                .delete(ClientResponse.class);
+        assertThat(deleteResponse.getStatus(),
+                is(HttpURLConnection.HTTP_NO_CONTENT));
+    }
+}
