1 package org.influxdb.dto;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collection;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Objects;
9 import java.util.TreeMap;
10 import java.util.concurrent.TimeUnit;
11
12 import org.influxdb.InfluxDB.ConsistencyLevel;
13
14 /**
15  * {Purpose of This Type}.
16  *
17  * {Other Notes Relating to This Type (Optional)}
18  *
19  * @author stefan
20  *
21  */

22 public class BatchPoints {
23   private String database;
24   private String retentionPolicy;
25   private Map<String, String> tags;
26   private List<Point> points;
27   private ConsistencyLevel consistency;
28   private TimeUnit precision;
29
30   BatchPoints() {
31     // Only visible in the Builder
32   }
33
34   /**
35    * Create a new BatchPoints build to create a new BatchPoints in a fluent manner.
36    *
37    * @return the Builder to be able to add further Builder calls.
38    */

39   public static Builder builder() {
40     return new Builder(null);
41   }
42
43   /**
44    * Create a new BatchPoints build to create a new BatchPoints in a fluent manner.
45    *
46    * @param database
47    *            the name of the Database
48    * @return the Builder to be able to add further Builder calls.
49    */

50   public static Builder database(final String database) {
51     return new Builder(database);
52   }
53
54   /**
55    * The Builder to create a new BatchPoints instance.
56    */

57   public static final class Builder {
58     private final String database;
59     private String retentionPolicy;
60     private final Map<String, String> tags = new TreeMap<>();
61     private final List<Point> points = new ArrayList<>();
62     private ConsistencyLevel consistency;
63     private TimeUnit precision;
64
65     /**
66      * @param database
67      */

68     Builder(final String database) {
69       this.database = database;
70     }
71
72     /**
73      * The retentionPolicy to use.
74      *
75      * @param policy the retentionPolicy to use
76      * @return the Builder instance
77      */

78     public Builder retentionPolicy(final String policy) {
79       this.retentionPolicy = policy;
80       return this;
81     }
82
83     /**
84      * Add a tag to this set of points.
85      *
86      * @param tagName
87      *            the tag name
88      * @param value
89      *            the tag value
90      * @return the Builder instance.
91      */

92     public Builder tag(final String tagName, final String value) {
93       this.tags.put(tagName, value);
94       return this;
95     }
96
97     /**
98      * Add a Point to this set of points.
99      *
100      * @param pointToAdd the Point to add
101      * @return the Builder instance
102      */

103     public Builder point(final Point pointToAdd) {
104       this.points.add(pointToAdd);
105       return this;
106     }
107
108     /**
109      * Add a set of Points to this set of points.
110      *
111      * @param pointsToAdd the Points to add
112      * @return the Builder instance
113      */

114     public Builder points(final Point... pointsToAdd) {
115       this.points.addAll(Arrays.asList(pointsToAdd));
116       return this;
117     }
118
119     /**
120      * Add a set of Points to this set of points.
121      *
122      * @param pointsToAdd the Points to add
123      * @return the Builder instance
124      */

125     public Builder points(final Collection<Point> pointsToAdd) {
126       this.points.addAll(pointsToAdd);
127       return this;
128     }
129
130     /**
131      * Set the ConsistencyLevel to use. If not given it defaults to {@link ConsistencyLevel#ONE}
132      *
133      * @param consistencyLevel the ConsistencyLevel
134      * @return the Builder instance
135      */

136     public Builder consistency(final ConsistencyLevel consistencyLevel) {
137       this.consistency = consistencyLevel;
138       return this;
139     }
140
141     /**
142      * Set the time precision to use for the whole batch. If unspecified, will default to {@link TimeUnit#NANOSECONDS}
143      * @param precision the precision of the points
144      * @return the Builder instance
145      */

146     public Builder precision(final TimeUnit precision) {
147       this.precision = precision;
148       return this;
149     }
150
151     /**
152      * Create a new BatchPoints instance.
153      *
154      * @return the created BatchPoints.
155      */

156     public BatchPoints build() {
157       BatchPoints batchPoints = new BatchPoints();
158       batchPoints.setDatabase(this.database);
159       for (Point point : this.points) {
160         point.getTags().putAll(this.tags);
161       }
162       batchPoints.setPoints(this.points);
163       batchPoints.setRetentionPolicy(this.retentionPolicy);
164       batchPoints.setTags(this.tags);
165       if (null == this.consistency) {
166         this.consistency = ConsistencyLevel.ONE;
167       }
168       batchPoints.setConsistency(this.consistency);
169       if (null == this.precision) {
170         this.precision = TimeUnit.NANOSECONDS;
171       }
172       batchPoints.setPrecision(this.precision);
173       return batchPoints;
174     }
175   }
176
177   /**
178    * @return the database
179    */

180   public String getDatabase() {
181     return this.database;
182   }
183
184   /**
185    * @param database
186    *            the database to set
187    */

188   void setDatabase(final String database) {
189     this.database = database;
190   }
191
192   /**
193    * @return the retentionPolicy
194    */

195   public String getRetentionPolicy() {
196     return this.retentionPolicy;
197   }
198
199   /**
200    * @param retentionPolicy
201    *            the retentionPolicy to set
202    */

203   void setRetentionPolicy(final String retentionPolicy) {
204     this.retentionPolicy = retentionPolicy;
205   }
206
207   /**
208    * @return the points
209    */

210   public List<Point> getPoints() {
211     return this.points;
212   }
213
214   /**
215    * @param points
216    *            the points to set
217    */

218   void setPoints(final List<Point> points) {
219     this.points = points;
220   }
221
222   /**
223    * @return the time precision unit
224    */

225   public TimeUnit getPrecision() {
226     return precision;
227   }
228
229   /**
230    * @param precision the time precision to set for the batch points
231    */

232   void setPrecision(final TimeUnit precision) {
233     this.precision = precision;
234   }
235
236   /**
237    * Add a single Point to these batches.
238    *
239    * @param point the Point to add
240    * @return this Instance to be able to daisy chain calls.
241    */

242   public BatchPoints point(final Point point) {
243     point.getTags().putAll(this.tags);
244     this.points.add(point);
245     return this;
246   }
247
248   /**
249    * @return the tags
250    */

251   public Map<String, String> getTags() {
252     return this.tags;
253   }
254
255   /**
256    * @param tags
257    *            the tags to set
258    */

259   void setTags(final Map<String, String> tags) {
260     this.tags = tags;
261   }
262
263   /**
264    * @return the consistency
265    */

266   public ConsistencyLevel getConsistency() {
267     return this.consistency;
268   }
269
270   /**
271    * @param consistency
272    *            the consistency to set
273    */

274   void setConsistency(final ConsistencyLevel consistency) {
275     this.consistency = consistency;
276   }
277
278   @Override
279   public boolean equals(final Object o) {
280     if (this == o) {
281       return true;
282     }
283     if (o == null || getClass() != o.getClass()) {
284       return false;
285     }
286     BatchPoints that = (BatchPoints) o;
287     return Objects.equals(database, that.database)
288             && Objects.equals(retentionPolicy, that.retentionPolicy)
289             && Objects.equals(tags, that.tags)
290             && Objects.equals(points, that.points)
291             && consistency == that.consistency
292             && precision == that.precision;
293   }
294
295   @Override
296   public int hashCode() {
297     return Objects.hash(database, retentionPolicy, tags, points, consistency, precision);
298   }
299
300   /**
301    * {@inheritDoc}
302    */

303   @Override
304   public String toString() {
305     StringBuilder builder = new StringBuilder();
306     builder.append("BatchPoints [database=")
307            .append(this.database)
308            .append(", retentionPolicy=")
309            .append(this.retentionPolicy)
310            .append(", consistency=")
311            .append(this.consistency)
312            .append(", tags=")
313            .append(this.tags)
314            .append(", precision=")
315            .append(this.precision)
316            .append(", points=")
317            .append(this.points)
318            .append("]");
319     return builder.toString();
320   }
321
322   // measurement[,tag=value,tag2=value2...] field=value[,field2=value2...] [unixnano]
323   /**
324    * calculate the lineprotocol for all Points.
325    *
326    * @return the String with newLines.
327    */

328   public String lineProtocol() {
329     StringBuilder sb = new StringBuilder();
330
331     for (Point point : this.points) {
332       sb.append(point.lineProtocol(this.precision)).append("\n");
333     }
334     return sb.toString();
335   }
336
337   /**
338    * Test whether is possible to merge two BatchPoints objects.
339    *
340    * @param that batch point to merge in
341    * @return true if the batch points can be sent in a single HTTP request write
342    */

343   public boolean isMergeAbleWith(final BatchPoints that) {
344     return Objects.equals(database, that.database)
345             && Objects.equals(retentionPolicy, that.retentionPolicy)
346             && Objects.equals(tags, that.tags)
347             && consistency == that.consistency;
348   }
349
350   /**
351    * Merge two BatchPoints objects.
352    *
353    * @param that batch point to merge in
354    * @return true if the batch points have been merged into this BatchPoints instance. Return false otherwise.
355    */

356   public boolean mergeIn(final BatchPoints that) {
357     boolean mergeAble = isMergeAbleWith(that);
358     if (mergeAble) {
359       this.points.addAll(that.points);
360     }
361     return mergeAble;
362   }
363 }
364