Repository: james-project Updated Branches: refs/heads/master a3aa6a005 -> b3fb0ef51
MAILBOX-270: Checking the old behavior with enable metadata extension Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/b3fb0ef5 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/b3fb0ef5 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/b3fb0ef5 Branch: refs/heads/master Commit: b3fb0ef51bd4de402a05faa1c49abd68d2ad6651 Parents: a3aa6a0 Author: Quynh Nguyen <qngu...@linagora.com> Authored: Tue Aug 30 11:27:37 2016 +0700 Committer: Quynh Nguyen <qngu...@linagora.com> Committed: Thu Sep 15 11:06:46 2016 +0700 ---------------------------------------------------------------------- .../mailbox/store/StoreMailboxManager.java | 7 +- .../store/event/MailboxAnnotationListener.java | 73 ++++++++++ .../StoreMailboxManagerAnnotationTest.java | 19 ++- .../event/MailboxAnnotationListenerTest.java | 132 +++++++++++++++++++ .../apache/james/imap/scripts/Annotation.test | 26 ++++ 5 files changed, 252 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/b3fb0ef5/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java index 1f46c77..6bdb110 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java @@ -64,6 +64,7 @@ import org.apache.james.mailbox.quota.QuotaManager; import org.apache.james.mailbox.quota.QuotaRootResolver; import org.apache.james.mailbox.store.event.DefaultDelegatingMailboxListener; import org.apache.james.mailbox.store.event.DelegatingMailboxListener; +import org.apache.james.mailbox.store.event.MailboxAnnotationListener; import org.apache.james.mailbox.store.event.MailboxEventDispatcher; import org.apache.james.mailbox.store.mail.AnnotationMapper; import org.apache.james.mailbox.store.mail.MailboxMapper; @@ -203,6 +204,10 @@ public class StoreMailboxManager implements MailboxManager { if (moveBatcher == null) { moveBatcher = new MessageBatcher(MessageBatcher.NO_BATCH_SIZE); } + if (hasCapability(MailboxCapabilities.Annotation)) { + MailboxSession session = null; + this.addGlobalListener(new MailboxAnnotationListener(mailboxSessionMapperFactory), session); + } } @Override @@ -491,7 +496,7 @@ public class StoreMailboxManager implements MailboxManager { } @Override - public void deleteMailbox(final MailboxPath mailboxPath, MailboxSession session) throws MailboxException { + public void deleteMailbox(final MailboxPath mailboxPath, final MailboxSession session) throws MailboxException { session.getLog().info("deleteMailbox " + mailboxPath); final MailboxMapper mapper = mailboxSessionMapperFactory.getMailboxMapper(session); http://git-wip-us.apache.org/repos/asf/james-project/blob/b3fb0ef5/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxAnnotationListener.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxAnnotationListener.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxAnnotationListener.java new file mode 100644 index 0000000..43656a5 --- /dev/null +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxAnnotationListener.java @@ -0,0 +1,73 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you 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.apache.james.mailbox.store.event; + +import org.apache.james.mailbox.MailboxListener; +import org.apache.james.mailbox.exception.MailboxException; +import org.apache.james.mailbox.model.MailboxAnnotation; +import org.apache.james.mailbox.model.MailboxId; +import org.apache.james.mailbox.store.MailboxSessionMapperFactory; +import org.apache.james.mailbox.store.mail.AnnotationMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +public class MailboxAnnotationListener implements MailboxListener { + private static final Logger logger = LoggerFactory.getLogger(MailboxAnnotationListener.class); + private MailboxSessionMapperFactory mailboxSessionMapperFactory; + + public MailboxAnnotationListener(MailboxSessionMapperFactory mailboxSessionMapperFactory) { + this.mailboxSessionMapperFactory = mailboxSessionMapperFactory; + } + @Override + public ListenerType getType() { + return ListenerType.EACH_NODE; + } + + @Override + public ExecutionMode getExecutionMode() { + return ExecutionMode.SYNCHRONOUS; + } + + @Override + public void event(Event event) { + if (event instanceof EventFactory.MailboxDeletionImpl) { + try { + AnnotationMapper annotationMapper = mailboxSessionMapperFactory.getAnnotationMapper(event.getSession()); + MailboxId mailboxId = ((EventFactory.MailboxDeletionImpl) event).getMailbox().getMailboxId(); + + deleteRelatedAnnotations(mailboxId, annotationMapper); + } catch (MailboxException e) { + logger.error("Unable to look up AnnotationMapper", e); + } + } + } + + private void deleteRelatedAnnotations(MailboxId mailboxId, AnnotationMapper annotationMapper) { + List<MailboxAnnotation> annotations = annotationMapper.getAllAnnotations(mailboxId); + for (MailboxAnnotation annotation : annotations) { + try { + annotationMapper.deleteAnnotation(mailboxId, annotation.getKey()); + } catch (Exception e) { + logger.error("Unable to delete annotation {0} cause {1}", annotation.getKey(), e.getMessage()); + } + } + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/b3fb0ef5/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerAnnotationTest.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerAnnotationTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerAnnotationTest.java index c28a6a9..232b397 100644 --- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerAnnotationTest.java +++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerAnnotationTest.java @@ -23,14 +23,18 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import java.util.Collections; +import java.util.EnumSet; import java.util.List; import java.util.Set; +import org.apache.james.mailbox.MailboxManager; import org.apache.james.mailbox.MailboxSession; import org.apache.james.mailbox.acl.GroupMembershipResolver; import org.apache.james.mailbox.acl.MailboxACLResolver; @@ -44,14 +48,18 @@ import org.apache.james.mailbox.store.mail.AnnotationMapper; import org.apache.james.mailbox.store.mail.MailboxMapper; import org.apache.james.mailbox.store.mail.model.Mailbox; import org.apache.james.mailbox.store.mail.model.impl.MessageParser; +import org.apache.james.mailbox.store.transaction.Mapper; import org.junit.Before; import org.junit.Test; +import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; public class StoreMailboxManagerAnnotationTest { private static final MailboxAnnotationKey PRIVATE_KEY = new MailboxAnnotationKey("/private/comment"); @@ -63,13 +71,12 @@ public class StoreMailboxManagerAnnotationTest { private static final List<MailboxAnnotation> ANNOTATIONS = ImmutableList.of(PRIVATE_ANNOTATION, SHARED_ANNOTATION); private static final List<MailboxAnnotation> ANNOTATIONS_WITH_NIL_ENTRY = ImmutableList.of(PRIVATE_ANNOTATION, MailboxAnnotation.nil(SHARED_KEY)); - private static final MailboxSession session = new MockMailboxSession("userName"); + private static final MockMailboxSession session = new MockMailboxSession("userName"); @Mock private MailboxSessionMapperFactory mailboxSessionMapperFactory; @Mock private Authenticator authenticator; @Mock private MailboxACLResolver aclResolver; @Mock private GroupMembershipResolver groupMembershipResolver; - @Mock private MailboxMapper mailboxMapper; @Mock private AnnotationMapper annotationMapper; @Mock private MailboxPath mailboxPath; @@ -80,16 +87,21 @@ public class StoreMailboxManagerAnnotationTest { @InjectMocks private StoreMailboxManager storeMailboxManager; + private ArgumentCaptor<Mapper.Transaction> mapperTransactionCaptor; + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); + mapperTransactionCaptor = ArgumentCaptor.forClass(Mapper.Transaction.class); + when(mailboxSessionMapperFactory.getMailboxMapper(eq(session))).thenReturn(mailboxMapper); when(mailboxSessionMapperFactory.getAnnotationMapper(eq(session))).thenReturn(annotationMapper); when(mailbox.getMailboxId()).thenReturn(mailboxId); when(mailboxMapper.findMailboxByPath(eq(mailboxPath))).thenReturn(mailbox); - storeMailboxManager = new StoreMailboxManager(mailboxSessionMapperFactory, authenticator, aclResolver, groupMembershipResolver, messageParser); + storeMailboxManager = spy(new StoreMailboxManager(mailboxSessionMapperFactory, authenticator, aclResolver, groupMembershipResolver, messageParser)); + storeMailboxManager.init(); } @Test(expected = MailboxException.class) @@ -150,5 +162,4 @@ public class StoreMailboxManagerAnnotationTest { assertThat(storeMailboxManager.getAnnotationsByKeys(mailboxPath, session, KEYS)).isEqualTo(ANNOTATIONS); } - } http://git-wip-us.apache.org/repos/asf/james-project/blob/b3fb0ef5/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/MailboxAnnotationListenerTest.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/MailboxAnnotationListenerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/MailboxAnnotationListenerTest.java new file mode 100644 index 0000000..fec0d22 --- /dev/null +++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/MailboxAnnotationListenerTest.java @@ -0,0 +1,132 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you 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.apache.james.mailbox.store.event; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import com.google.common.collect.ImmutableList; +import org.apache.james.mailbox.MailboxListener; +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.mock.MockMailboxSession; +import org.apache.james.mailbox.model.MailboxAnnotation; +import org.apache.james.mailbox.model.MailboxAnnotationKey; +import org.apache.james.mailbox.model.MailboxId; +import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.store.MailboxSessionMapperFactory; +import org.apache.james.mailbox.store.mail.AnnotationMapper; +import org.apache.james.mailbox.store.mail.model.Mailbox; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.List; + +public class MailboxAnnotationListenerTest { + private static final MailboxPath MAILBOX_PATH = new MailboxPath("namespace", "user", "name"); + private static final MailboxSession mailboxSession = new MockMailboxSession("test"); + + private static final MailboxAnnotationKey PRIVATE_KEY = new MailboxAnnotationKey("/private/comment"); + private static final MailboxAnnotationKey SHARED_KEY = new MailboxAnnotationKey("/shared/comment"); + + private static final MailboxAnnotation PRIVATE_ANNOTATION = MailboxAnnotation.newInstance(PRIVATE_KEY, "My private comment"); + private static final MailboxAnnotation SHARED_ANNOTATION = MailboxAnnotation.newInstance(SHARED_KEY, "My shared comment"); + + private static final List<MailboxAnnotation> ANNOTATIONS = ImmutableList.of(PRIVATE_ANNOTATION, SHARED_ANNOTATION); + + @Mock private MailboxSessionMapperFactory mailboxSessionMapperFactory; + @Mock private AnnotationMapper annotationMapper; + @Mock private Mailbox mailbox; + @Mock private MailboxId mailboxId; + + private EventFactory eventFactory; + private MailboxAnnotationListener listener; + private MailboxListener.Event deleteEvent; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + listener = new MailboxAnnotationListener(mailboxSessionMapperFactory); + eventFactory = new EventFactory(); + deleteEvent = eventFactory.mailboxDeleted(mailboxSession, mailbox); + + when(mailbox.getMailboxId()).thenReturn(mailboxId); + when(mailboxSessionMapperFactory.getAnnotationMapper(eq(deleteEvent.getSession()))).thenReturn(annotationMapper); + } + + @Test + public void eventShouldDoNothingIfDoNotHaveMailboxDeletionEvent() { + MailboxListener.Event event = new MailboxListener.Event(null, MAILBOX_PATH) {}; + listener.event(event); + + verifyNoMoreInteractions(mailboxSessionMapperFactory); + verifyNoMoreInteractions(annotationMapper); + } + + @Test + public void eventShoudlDoNothingIfMailboxDoesNotHaveAnyAnnotation() throws Exception{ + when(annotationMapper.getAllAnnotations(any(MailboxId.class))).thenReturn(ImmutableList.<MailboxAnnotation>of()); + + listener.event(deleteEvent); + + verify(mailboxSessionMapperFactory).getAnnotationMapper(eq(deleteEvent.getSession())); + verify(annotationMapper).getAllAnnotations(eq(mailboxId)); + + verifyNoMoreInteractions(mailboxSessionMapperFactory); + verifyNoMoreInteractions(annotationMapper); + + } + + @Test + public void eventShoudlDeleteAllMailboxAnnotation() throws Exception{ + when(annotationMapper.getAllAnnotations(eq(mailboxId))).thenReturn(ANNOTATIONS); + + listener.event(deleteEvent); + + verify(mailboxSessionMapperFactory).getAnnotationMapper(eq(deleteEvent.getSession())); + verify(annotationMapper).getAllAnnotations(eq(mailboxId)); + verify(annotationMapper).deleteAnnotation(eq(mailboxId), eq(PRIVATE_KEY)); + verify(annotationMapper).deleteAnnotation(eq(mailboxId), eq(SHARED_KEY)); + + verifyNoMoreInteractions(mailboxSessionMapperFactory); + verifyNoMoreInteractions(annotationMapper); + + } + + @Test + public void eventShouldDeteleAllMailboxIfHasAnyOneFailed() throws Exception { + when(annotationMapper.getAllAnnotations((eq(mailboxId)))).thenReturn(ANNOTATIONS); + doThrow(new RuntimeException()).when(annotationMapper).deleteAnnotation(eq(mailboxId), eq(PRIVATE_KEY)); + + listener.event(deleteEvent); + + verify(mailboxSessionMapperFactory).getAnnotationMapper(eq(deleteEvent.getSession())); + verify(annotationMapper).getAllAnnotations(eq(mailboxId)); + verify(annotationMapper).deleteAnnotation(eq(mailboxId), eq(PRIVATE_KEY)); + verify(annotationMapper).deleteAnnotation(eq(mailboxId), eq(SHARED_KEY)); + + verifyNoMoreInteractions(mailboxSessionMapperFactory); + verifyNoMoreInteractions(annotationMapper); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/b3fb0ef5/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/Annotation.test ---------------------------------------------------------------------- diff --git a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/Annotation.test b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/Annotation.test index 0c2bdd1..673729a 100644 --- a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/Annotation.test +++ b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/Annotation.test @@ -157,3 +157,29 @@ S: a23 BAD SETMETADATA failed. Illegal arguments. C: a24 SETMETADATA INBOX (/shared/vendor/token/comment "My token comment") S: a24 OK SETMETADATA completed. +######Delete mailbox should delete its annotation####### +C: m01 CREATE mailboxTest +S: m01 OK CREATE completed. + +C: m02 SETMETADATA mailboxTest (/private/comment "The mailboxTest private comment") +S: m02 OK SETMETADATA completed. + +C: m03 SETMETADATA mailboxTest (/shared/comment "The mailboxTest shared comment") +S: m03 OK SETMETADATA completed. + +C: m04 GETMETADATA "mailboxTest" +S: \* METADATA "mailboxTest" \(\/private\/comment "The mailboxTest private comment" \/shared\/comment "The mailboxTest shared comment"\) +S: m04 OK GETMETADATA completed. + +C: m05 DELETE mailboxTest +S: m05 OK DELETE completed. + +C: m06 GETMETADATA "mailboxTest" +S: m06 NO \[TRYCREATE\] GETMETADATA failed. No such mailbox. + +C: m07 CREATE mailboxTest +S: m07 OK CREATE completed. + +C: m08 GETMETADATA "mailboxTest" +S: \* METADATA "mailboxTest" +S: m08 OK GETMETADATA completed. \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org