This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit e5915c83cf4f39a8807d3a9a59bd8ef09ab80341 Author: Benoit Tellier <[email protected]> AuthorDate: Fri Mar 6 22:45:03 2020 +0700 JAMES-3105 Task for recomputing mailbox counters A simple wrapper around the already existing service... --- .../mail/task/RecomputeMailboxCountersTask.java | 102 +++++++++++++++++++++ ...ailboxCountersTaskAdditionalInformationDTO.java | 87 ++++++++++++++++++ .../mail/task/RecomputeMailboxCountersTaskDTO.java | 56 +++++++++++ ...omputeMailboxCountersTaskSerializationTest.java | 66 +++++++++++++ 4 files changed, 311 insertions(+) diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersTask.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersTask.java new file mode 100644 index 0000000..74082f3 --- /dev/null +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersTask.java @@ -0,0 +1,102 @@ +/**************************************************************** + * 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.cassandra.mail.task; + +import static org.apache.james.mailbox.cassandra.mail.task.RecomputeMailboxCountersService.Context.Snapshot; + +import java.time.Clock; +import java.time.Instant; +import java.util.Optional; + +import org.apache.james.mailbox.model.MailboxId; +import org.apache.james.task.Task; +import org.apache.james.task.TaskExecutionDetails; +import org.apache.james.task.TaskType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.steveash.guavate.Guavate; +import com.google.common.collect.ImmutableList; + +import reactor.core.scheduler.Schedulers; + +public class RecomputeMailboxCountersTask implements Task { + public static final Logger LOGGER = LoggerFactory.getLogger(RecomputeMailboxCountersTask.class); + static final TaskType RECOMPUTE_MAILBOX_COUNTERS = TaskType.of("recompute-mailbox-counters"); + + public static class Details implements TaskExecutionDetails.AdditionalInformation { + private final Instant instant; + private final long processedMailboxes; + private final ImmutableList<String> failedMailboxes; + + Details(Instant instant, long processedMailboxes, ImmutableList<String> failedMailboxes) { + this.instant = instant; + this.processedMailboxes = processedMailboxes; + this.failedMailboxes = failedMailboxes; + } + + @Override + public Instant timestamp() { + return instant; + } + + @JsonProperty("processedMailboxes") + long getProcessedMailboxes() { + return processedMailboxes; + } + + @JsonProperty("failedMailboxes") + ImmutableList<String> getFailedMailboxes() { + return failedMailboxes; + } + } + + private final RecomputeMailboxCountersService service; + private RecomputeMailboxCountersService.Context context; + + public RecomputeMailboxCountersTask(RecomputeMailboxCountersService service) { + this.service = service; + this.context = new RecomputeMailboxCountersService.Context(); + } + + @Override + public Result run() { + return service.recomputeMailboxCounters(context) + .subscribeOn(Schedulers.elastic()) + .block(); + } + + @Override + public TaskType type() { + return RECOMPUTE_MAILBOX_COUNTERS; + } + + @Override + public Optional<TaskExecutionDetails.AdditionalInformation> details() { + Snapshot snapshot = context.snapshot(); + + return Optional.of(new Details(Clock.systemUTC().instant(), + snapshot.getProcessedMailboxCount(), + snapshot.getFailedMailboxes().stream() + .map(MailboxId::serialize) + .collect(Guavate.toImmutableList()))); + } +} diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersTaskAdditionalInformationDTO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersTaskAdditionalInformationDTO.java new file mode 100644 index 0000000..e7eef3d --- /dev/null +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersTaskAdditionalInformationDTO.java @@ -0,0 +1,87 @@ +/**************************************************************** + * 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.cassandra.mail.task; + +import java.time.Instant; + +import org.apache.james.json.DTOModule; +import org.apache.james.server.task.json.dto.AdditionalInformationDTO; +import org.apache.james.server.task.json.dto.AdditionalInformationDTOModule; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.collect.ImmutableList; + +public class RecomputeMailboxCountersTaskAdditionalInformationDTO implements AdditionalInformationDTO { + private static RecomputeMailboxCountersTaskAdditionalInformationDTO fromDomainObject(RecomputeMailboxCountersTask.Details details, String type) { + return new RecomputeMailboxCountersTaskAdditionalInformationDTO( + type, + details.getProcessedMailboxes(), + details.getFailedMailboxes(), + details.timestamp()); + } + + public static final AdditionalInformationDTOModule<RecomputeMailboxCountersTask.Details, RecomputeMailboxCountersTaskAdditionalInformationDTO> MODULE = + DTOModule + .forDomainObject(RecomputeMailboxCountersTask.Details.class) + .convertToDTO(RecomputeMailboxCountersTaskAdditionalInformationDTO.class) + .toDomainObjectConverter(RecomputeMailboxCountersTaskAdditionalInformationDTO::toDomainObject) + .toDTOConverter(RecomputeMailboxCountersTaskAdditionalInformationDTO::fromDomainObject) + .typeName(RecomputeMailboxCountersTask.RECOMPUTE_MAILBOX_COUNTERS.asString()) + .withFactory(AdditionalInformationDTOModule::new); + + private final String type; + private final long processedMailboxes; + private final ImmutableList<String> failedMailboxes; + private final Instant timestamp; + + public RecomputeMailboxCountersTaskAdditionalInformationDTO(@JsonProperty("type") String type, + @JsonProperty("processedMailboxes") long processedMailboxes, + @JsonProperty("failedMailboxes") ImmutableList<String> failedMailboxes, + @JsonProperty("timestamp") Instant timestamp) { + this.type = type; + this.processedMailboxes = processedMailboxes; + this.failedMailboxes = failedMailboxes; + this.timestamp = timestamp; + } + + public long getProcessedMailboxes() { + return processedMailboxes; + } + + public ImmutableList<String> getFailedMailboxes() { + return failedMailboxes; + } + + @Override + public Instant getTimestamp() { + return timestamp; + } + + @Override + public String getType() { + return type; + } + + private RecomputeMailboxCountersTask.Details toDomainObject() { + return new RecomputeMailboxCountersTask.Details(timestamp, + processedMailboxes, + failedMailboxes); + } +} diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersTaskDTO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersTaskDTO.java new file mode 100644 index 0000000..b8fa112 --- /dev/null +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersTaskDTO.java @@ -0,0 +1,56 @@ +/**************************************************************** + * 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.cassandra.mail.task; + +import org.apache.james.json.DTOModule; +import org.apache.james.server.task.json.dto.TaskDTO; +import org.apache.james.server.task.json.dto.TaskDTOModule; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class RecomputeMailboxCountersTaskDTO implements TaskDTO { + private static RecomputeMailboxCountersTaskDTO toDTO(RecomputeMailboxCountersTask domainObject, String typeName) { + return new RecomputeMailboxCountersTaskDTO(typeName); + } + + public static TaskDTOModule<RecomputeMailboxCountersTask, RecomputeMailboxCountersTaskDTO> module(RecomputeMailboxCountersService service) { + return DTOModule + .forDomainObject(RecomputeMailboxCountersTask.class) + .convertToDTO(RecomputeMailboxCountersTaskDTO.class) + .toDomainObjectConverter(dto -> dto.toDomainObject(service)) + .toDTOConverter(RecomputeMailboxCountersTaskDTO::toDTO) + .typeName(RecomputeMailboxCountersTask.RECOMPUTE_MAILBOX_COUNTERS.asString()) + .withFactory(TaskDTOModule::new); + } + + private final String type; + + public RecomputeMailboxCountersTaskDTO(@JsonProperty("type") String type) { + this.type = type; + } + + private RecomputeMailboxCountersTask toDomainObject(RecomputeMailboxCountersService service) { + return new RecomputeMailboxCountersTask(service); + } + + @Override + public String getType() { + return type; + } +} diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersTaskSerializationTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersTaskSerializationTest.java new file mode 100644 index 0000000..15c787c --- /dev/null +++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersTaskSerializationTest.java @@ -0,0 +1,66 @@ +/**************************************************************** + * 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.cassandra.mail.task; + +import static org.mockito.Mockito.mock; + +import java.time.Instant; +import java.util.UUID; + +import org.apache.james.JsonSerializationVerifier; +import org.apache.james.core.Username; +import org.apache.james.mailbox.cassandra.ids.CassandraId; +import org.apache.james.mailbox.model.MailboxConstants; +import org.apache.james.mailbox.model.MailboxPath; +import org.junit.jupiter.api.Test; + +import com.google.common.collect.ImmutableList; + +class RecomputeMailboxCountersTaskSerializationTest { + private static final Instant TIMESTAMP = Instant.parse("2018-11-13T12:00:55Z"); + private static final String MAILBOX_ID_AS_STRING = "464765a0-e4e7-11e4-aba4-710c1de3782b"; + + private static final RecomputeMailboxCountersService SERVICE = mock(RecomputeMailboxCountersService.class); + private static final RecomputeMailboxCountersTask TASK = new RecomputeMailboxCountersTask(SERVICE); + private static final String SERIALIZED_TASK = "{\"type\": \"recompute-mailbox-counters\"}"; + private static final RecomputeMailboxCountersTask.Details DETAILS = new RecomputeMailboxCountersTask.Details(TIMESTAMP, 12, ImmutableList.of(MAILBOX_ID_AS_STRING)); + private static final String SERIALIZED_ADDITIONAL_INFORMATION = "{" + + " \"type\":\"recompute-mailbox-counters\"," + + " \"processedMailboxes\":12," + + " \"failedMailboxes\":[\"464765a0-e4e7-11e4-aba4-710c1de3782b\"]," + + " \"timestamp\":\"2018-11-13T12:00:55Z\"" + + "}"; + + @Test + void taskShouldBeSerializable() throws Exception { + JsonSerializationVerifier.dtoModule(RecomputeMailboxCountersTaskDTO.module(SERVICE)) + .bean(TASK) + .json(SERIALIZED_TASK) + .verify(); + } + + @Test + void additionalInformationShouldBeSerializable() throws Exception { + JsonSerializationVerifier.dtoModule(RecomputeMailboxCountersTaskAdditionalInformationDTO.MODULE) + .bean(DETAILS) + .json(SERIALIZED_ADDITIONAL_INFORMATION) + .verify(); + } +} \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
