Skip to content
This repository was archived by the owner on Jun 7, 2023. It is now read-only.

Commit 39fb0e7

Browse files
author
Rustam Aliyev
committed
Closes #46 improve batch operations and resolves #47 overcounting issue.
1 parent c157aec commit 39fb0e7

File tree

17 files changed

+659
-335
lines changed

17 files changed

+659
-335
lines changed

itests/src/test/java/com/elasticinbox/itests/RestV2IT.java

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
package com.elasticinbox.itests;
3030

31+
import static org.hamcrest.MatcherAssert.assertThat;
3132
import static org.hamcrest.Matchers.*;
3233
import static com.jayway.restassured.RestAssured.*;
3334
import static com.jayway.restassured.path.json.JsonPath.*;
@@ -388,6 +389,116 @@ public void messageAddRemoveLabelsMarkersTest() throws IOException
388389
get(REST_PATH + "/mailbox/message/{messageId}");
389390
}
390391

392+
/**
393+
* Adding label to the message which already has same label should not
394+
* result in overcounting.
395+
*
396+
* @throws IOException
397+
*/
398+
@Test
399+
public void overcountingTest() throws IOException
400+
{
401+
initAccount();
402+
403+
// Step 1: add message to label TRASH
404+
UUID messageId = addMessage(EMAIL_REGULAR, ReservedLabels.TRASH.getId());
405+
406+
// counters before operation
407+
String jsonResponse = expect().statusCode(200).when().get(REST_PATH + "/mailbox?metadata=true").asString();
408+
LabelCounters initialAllCounters = getCounters(jsonResponse, ReservedLabels.ALL_MAILS.getId());
409+
LabelCounters initialTrashCounters = getCounters(jsonResponse, ReservedLabels.TRASH.getId());
410+
411+
// Repeat add label TRASH
412+
for (int i=0; i<5; i++)
413+
{
414+
given().
415+
pathParam("messageId", messageId.toString()).
416+
pathParam("labelId", ReservedLabels.TRASH.getId()).
417+
expect().
418+
statusCode(204).
419+
when().
420+
put(REST_PATH + "/mailbox/message/{messageId}?addlabel={labelId}");
421+
}
422+
423+
// counters after operation
424+
jsonResponse = expect().statusCode(200).when().get(REST_PATH + "/mailbox?metadata=true").asString();
425+
LabelCounters finalAllCounters = getCounters(jsonResponse, ReservedLabels.ALL_MAILS.getId());
426+
LabelCounters finalTrashCounters = getCounters(jsonResponse, ReservedLabels.TRASH.getId());
427+
428+
assertThat(finalAllCounters, equalTo(initialAllCounters));
429+
assertThat(finalTrashCounters, equalTo(initialTrashCounters));
430+
431+
// STEP 2: remove label and add marker
432+
given().
433+
pathParam("messageId", messageId.toString()).
434+
pathParam("labelId", ReservedLabels.TRASH.getId()).
435+
pathParam("seenMarker", Marker.SEEN.toString().toLowerCase()).
436+
expect().
437+
statusCode(204).
438+
when().
439+
put(REST_PATH + "/mailbox/message/{messageId}?removelabel={labelId}&addmarker={seenMarker}");
440+
441+
// counters before operation
442+
jsonResponse = expect().statusCode(200).when().get(REST_PATH + "/mailbox?metadata=true").asString();
443+
initialAllCounters = getCounters(jsonResponse, ReservedLabels.ALL_MAILS.getId());
444+
initialTrashCounters = getCounters(jsonResponse, ReservedLabels.TRASH.getId());
445+
446+
// Repeat remove label and add marker
447+
for (int i=0; i<5; i++)
448+
{
449+
given().
450+
pathParam("messageId", messageId.toString()).
451+
pathParam("labelId", ReservedLabels.TRASH.getId()).
452+
pathParam("seenMarker", Marker.SEEN.toString().toLowerCase()).
453+
expect().
454+
statusCode(204).
455+
when().
456+
put(REST_PATH + "/mailbox/message/{messageId}?removelabel={labelId}&addmarker={seenMarker}");
457+
}
458+
459+
// counters after operation
460+
jsonResponse = expect().statusCode(200).when().get(REST_PATH + "/mailbox?metadata=true").asString();
461+
finalAllCounters = getCounters(jsonResponse, ReservedLabels.ALL_MAILS.getId());
462+
finalTrashCounters = getCounters(jsonResponse, ReservedLabels.TRASH.getId());
463+
464+
assertThat(finalAllCounters, equalTo(initialAllCounters));
465+
assertThat(finalTrashCounters, equalTo(initialTrashCounters));
466+
467+
// STEP 3: Remove Marker
468+
given().
469+
pathParam("messageId", messageId.toString()).
470+
pathParam("seenMarker", Marker.SEEN.toString().toLowerCase()).
471+
expect().
472+
statusCode(204).
473+
when().
474+
put(REST_PATH + "/mailbox/message/{messageId}?removemarker={seenMarker}");
475+
476+
// counters before operation
477+
jsonResponse = expect().statusCode(200).when().get(REST_PATH + "/mailbox?metadata=true").asString();
478+
initialAllCounters = getCounters(jsonResponse, ReservedLabels.ALL_MAILS.getId());
479+
initialTrashCounters = getCounters(jsonResponse, ReservedLabels.TRASH.getId());
480+
481+
// Repeat remove marker
482+
for (int i=0; i<5; i++)
483+
{
484+
given().
485+
pathParam("messageId", messageId.toString()).
486+
pathParam("seenMarker", Marker.SEEN.toString().toLowerCase()).
487+
expect().
488+
statusCode(204).
489+
when().
490+
put(REST_PATH + "/mailbox/message/{messageId}?removemarker={seenMarker}");
491+
}
492+
493+
// counters after operation
494+
jsonResponse = expect().statusCode(200).when().get(REST_PATH + "/mailbox?metadata=true").asString();
495+
finalAllCounters = getCounters(jsonResponse, ReservedLabels.ALL_MAILS.getId());
496+
finalTrashCounters = getCounters(jsonResponse, ReservedLabels.TRASH.getId());
497+
498+
assertThat(finalAllCounters, equalTo(initialAllCounters));
499+
assertThat(finalTrashCounters, equalTo(initialTrashCounters));
500+
}
501+
391502
@Test
392503
public void messageBatchMofifyDeleteTest() throws IOException
393504
{

modules/core/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@
136136
<dependency>
137137
<groupId>org.hectorclient</groupId>
138138
<artifactId>hector-core</artifactId>
139-
<version>1.1-3</version>
139+
<version>1.1-4</version>
140140
<type>jar</type>
141141
<scope>compile</scope>
142142
<exclusions>

modules/core/src/main/java/com/elasticinbox/core/MessageDAO.java

Lines changed: 9 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,11 @@
3333
import java.util.Date;
3434
import java.util.List;
3535
import java.util.Map;
36-
import java.util.Set;
3736
import java.util.UUID;
3837

3938
import com.elasticinbox.core.blob.BlobDataSource;
4039
import com.elasticinbox.core.model.LabelMap;
4140
import com.elasticinbox.core.model.Mailbox;
42-
import com.elasticinbox.core.model.Marker;
4341
import com.elasticinbox.core.model.Message;
4442

4543
/**
@@ -128,81 +126,27 @@ public Map<UUID, Message> getMessageIdsWithHeaders(Mailbox mailbox, int labelId,
128126
UUID start, int count, boolean reverse);
129127

130128
/**
131-
* Add markers to multiple messages
129+
* Modify message labels and markers.
132130
*
133131
* @param mailbox
134-
* @param markers
135-
* @param messageIds
136-
*/
137-
public void addMarker(Mailbox mailbox, Set<Marker> markers, List<UUID> messageIds);
138-
139-
/**
140-
* Add markers to single message
141-
*
142-
* @param mailbox
143-
* @param markers
144-
* @param messageId
145-
*/
146-
public void addMarker(Mailbox mailbox, Set<Marker> markers, UUID messageId);
147-
148-
/**
149-
* Remove markers from multiple messages
150-
*
151-
* @param mailbox
152-
* @param markers
153-
* @param messageIds
154-
*/
155-
public void removeMarker(Mailbox mailbox, Set<Marker> markers, List<UUID> messageIds);
156-
157-
/**
158-
* Remove markers from single message
159-
*
160-
* @param mailbox
161-
* @param markers
162-
* @param messageId
163-
*/
164-
public void removeMarker(Mailbox mailbox, Set<Marker> markers, UUID messageId);
165-
166-
/**
167-
* Add labels to multiple messages
168-
*
169-
* @param mailbox
170-
* @param labelIds
171-
* @param messageIds
172-
*/
173-
public void addLabel(Mailbox mailbox, Set<Integer> labelIds, List<UUID> messageIds);
174-
175-
/**
176-
* Add labels to single message
177-
*
178-
* @param mailbox
179-
* @param labelIds
180132
* @param messageId
181-
*/
182-
public void addLabel(Mailbox mailbox, Set<Integer> labelIds, UUID messageId);
183-
184-
/**
185-
* Remove labels from multiple messages
186-
*
187-
* @param mailbox
188-
* @param labelIds
189-
* @param messageIds
133+
* @param modification
190134
* @throws IllegalLabelException
191135
*/
192-
public void removeLabel(Mailbox mailbox, Set<Integer> labelIds, List<UUID> messageIds)
136+
public void modify(Mailbox mailbox, UUID messageId, MessageModification modification)
193137
throws IllegalLabelException;
194-
138+
195139
/**
196-
* Remove lables from single message
140+
* Modify message labels and markers.
197141
*
198142
* @param mailbox
199-
* @param labelIds
200-
* @param messageId
143+
* @param messageIds
144+
* @param modification
201145
* @throws IllegalLabelException
202146
*/
203-
public void removeLabel(Mailbox mailbox, Set<Integer> labelIds, UUID messageId)
147+
public void modify(Mailbox mailbox, List<UUID> messageIds, MessageModification modification)
204148
throws IllegalLabelException;
205-
149+
206150
/**
207151
* Delete multiple messages
208152
*
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/**
2+
* Copyright (c) 2011-2013 Optimax Software Ltd.
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
*
8+
* * Redistributions of source code must retain the above copyright notice,
9+
* this list of conditions and the following disclaimer.
10+
* * Redistributions in binary form must reproduce the above copyright notice,
11+
* this list of conditions and the following disclaimer in the documentation
12+
* and/or other materials provided with the distribution.
13+
* * Neither the name of Optimax Software, ElasticInbox, nor the names
14+
* of its contributors may be used to endorse or promote products derived
15+
* from this software without specific prior written permission.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27+
*/
28+
29+
package com.elasticinbox.core;
30+
31+
import java.util.HashSet;
32+
import java.util.Set;
33+
34+
import com.elasticinbox.core.model.Marker;
35+
36+
/**
37+
* Modifications which can be applied to the existing message.
38+
*
39+
* @author Rustam Aliyev
40+
*/
41+
public class MessageModification
42+
{
43+
private Set<Integer> addLabels;
44+
private Set<Integer> removeLabels;
45+
private Set<Marker> addMarkers;
46+
private Set<Marker> removeMarkers;
47+
48+
public static class Builder
49+
{
50+
private Set<Integer> addLabels = new HashSet<Integer>(1);
51+
private Set<Integer> removeLabels = new HashSet<Integer>(1);
52+
private Set<Marker> addMarkers = new HashSet<Marker>(1);
53+
private Set<Marker> removeMarkers = new HashSet<Marker>(1);
54+
55+
/**
56+
* Add labels to the message
57+
*
58+
* @param ids
59+
* @return
60+
*/
61+
public Builder addLabels(Set<Integer> ids)
62+
{
63+
addLabels.addAll(ids);
64+
return this;
65+
}
66+
67+
/**
68+
* Remove labels form the message
69+
* @param ids
70+
* @return
71+
*/
72+
public Builder removeLabels(Set<Integer> ids)
73+
{
74+
removeLabels.addAll(ids);
75+
return this;
76+
}
77+
78+
/**
79+
* Add markers to the message
80+
* @param markers
81+
* @return
82+
*/
83+
public Builder addMarkers(Set<Marker> markers)
84+
{
85+
addMarkers.addAll(markers);
86+
return this;
87+
}
88+
89+
/**
90+
* Add marker to the message
91+
* @param ids
92+
* @return
93+
*/
94+
public Builder addMarker(Marker marker)
95+
{
96+
addMarkers.add(marker);
97+
return this;
98+
}
99+
100+
/**
101+
* Remove markers from the message
102+
*
103+
* @param markers
104+
* @return
105+
*/
106+
public Builder removeMarkers(Set<Marker> markers)
107+
{
108+
removeMarkers.addAll(markers);
109+
return this;
110+
}
111+
112+
/**
113+
* Remove marker from the message
114+
* @param ids
115+
* @return
116+
*/
117+
public Builder removeMarker(Marker marker)
118+
{
119+
removeMarkers.add(marker);
120+
return this;
121+
}
122+
123+
public MessageModification build() {
124+
return new MessageModification(this);
125+
}
126+
}
127+
128+
private MessageModification(Builder b)
129+
{
130+
this.addLabels = b.addLabels;
131+
this.removeLabels = b.removeLabels;
132+
this.addMarkers = b.addMarkers;
133+
this.removeMarkers = b.removeMarkers;
134+
}
135+
136+
public Set<Integer> getLabelsToAdd() {
137+
return addLabels;
138+
}
139+
140+
public Set<Integer> getLabelsToRemove() {
141+
return removeLabels;
142+
}
143+
144+
public Set<Marker> getMarkersToAdd() {
145+
return addMarkers;
146+
}
147+
148+
public Set<Marker> getMarkersToRemove() {
149+
return removeMarkers;
150+
}
151+
}

0 commit comments

Comments
 (0)