package com.nimbits.it.basic; import com.nimbits.client.io.Nimbits; import com.nimbits.client.model.entity.Entity; import com.nimbits.client.model.point.Point; import com.nimbits.client.model.point.PointModel; import com.nimbits.client.model.user.User; import com.nimbits.client.model.value.Value; import com.nimbits.it.AbstractNimbitsTest; import org.apache.commons.lang3.StringUtils; import org.junit.Before; import org.junit.Test; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import static org.junit.Assert.fail; /** * Exercises the V3 Rest API - designed to run continuously against a server as an integration test. */ public class V3RestClientTester extends AbstractNimbitsTest { private List<Entity> pointList = new ArrayList<>(); private Map<Entity, List<Value>> storedValues = new HashMap<Entity, List<Value>>(); @Before public void setUp() throws Exception { super.setUp(); } @Test public void executeTest() throws InterruptedException { log("Starting up"); if (user != null) { log("Continuing with user: " + user.getEmail() + " " + user.getId()); createRegularUsers(); createPoints(); Thread.sleep(5000); recordSeriesData(); } else { log("User was null! Exiting Test"); } log("Done!"); } private void createRegularUsers() { for (int i = 0; i < 10; i++) { log("Creating regular user " + i); String password = "password"; User regularUser = createUser(UUID.randomUUID().toString() + "@example.com", password); Nimbits nonAdminClient = new Nimbits.Builder() .email(regularUser.getEmail().getValue()) .token(password) .instance(host).create(); User verify = nonAdminClient.getMe(true); if (verify.equals(regularUser)) { log("Verified Creating Regular " + i + " User can login "); } else { throw new RuntimeException("Could not verify regular user"); } } } /** * Create some data points with the new user as the parent */ private void createPoints() { for (int i = 0; i < 10; i++) { Point point = new PointModel.Builder().name(UUID.randomUUID().toString()).parent(user.getId()) .create(); Entity newPoint = nimbits.addPoint(user, point); pointList.add(newPoint); log("Created : " + newPoint.getName().getValue()); } } /** * Record large amounts of data to each point */ private void recordSeriesData() throws InterruptedException { log("Recording Data"); Random r = new Random(); String[] meta = {"foo", "bar"}; for (Entity entity : pointList) { List<Value> values = new ArrayList<Value>(); Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DAY_OF_YEAR, -30); for (int i = 0; i < 1000; i++) { calendar.add(Calendar.SECOND, 1); String metavalue = meta[(i & 1) == 0 ? 0 : 1]; //flip between meta values for testing search values.add(new Value.Builder() .timestamp(calendar.getTimeInMillis()) .doubleValue(r.nextDouble() * 1000) .lat(0.0) .lng(0.0) .meta(metavalue).data("{}").create()); } nimbits.recordValues(entity, values); log("Recorded : " + values.size() + " for " + entity.getName()); storedValues.put(entity, values); } log("Waiting for things to settle down server side"); Thread.sleep(60000); log("Verifying Data"); verifySeriesData(null); Thread.sleep(1000); log("Verifying Data again!"); verifySeriesData(""); log("Verifying Data again with perfect match mask!"); verifySeriesData(meta[0]); log("Verifying Data again with other perfect match mask mask!"); verifySeriesData(meta[1]); log("Verifying Data again with regex mask!"); verifySeriesData("[o]+"); log("Make sure Count param is working"); verifyCountParam(); } private void verifySeriesData(String mask) throws InterruptedException { for (Entity entity : pointList) { Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DAY_OF_YEAR, -31); log(entity.getId()); List<Value> downloadedValues = nimbits.getValues(entity, calendar.getTime(), new Date(), mask); log("Downloaded " + downloadedValues.size() + " for " + entity.getName()); sleep(); List<Value> stored = storedValues.get(entity); Collections.sort(stored); Collections.sort(downloadedValues); for (Value value : stored) { if (StringUtils.isEmpty(mask) || mask.equals(value.getMetaData()) || containsMask(value, mask)) if (!downloadedValues.contains(value)) { log("R Range: " + stored.get(0).getLTimestamp() + " to " + stored.get(stored.size() - 1).getLTimestamp()); log("Q Range: " + calendar.getTime() + " to " + new Date()); fail( "downloaded values did not contain expected posted value. " + value.toString()); } } } } private void verifyCountParam() { for (Entity entity : pointList) { for (int i = 1; i < 1000; i++) { log("getting " + i + " values for " + entity.getName()); List<Value> values = nimbits.getValues(entity, i); if (values.size() != i) { error("asked for " + i + " values but got " + values.size()); } } } } public static boolean containsMask(Value value, String mask) { if (StringUtils.isEmpty(mask)) { return true; } else if (!StringUtils.isEmpty(mask) && mask.equals(value.getMetaData())) { return true; } else if (!StringUtils.isEmpty(mask)) { try { Pattern p = Pattern.compile(mask); Matcher m = p.matcher(value.getMetaData()); return m.find(); } catch (PatternSyntaxException ex) { return false; } } return false; } }