chibenwa commented on code in PR #1666:
URL: https://github.com/apache/james-project/pull/1666#discussion_r1282614089
##########
core/pom.xml:
##########
@@ -49,6 +49,10 @@
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
+ <dependency>
+ <groupId>com.google.inject</groupId>
+ <artifactId>guice</artifactId>
+ </dependency>
Review Comment:
Why is this needed?
##########
core/src/main/java/org/apache/james/core/quota/QuotaComponentFactory.java:
##########
@@ -0,0 +1,42 @@
+/****************************************************************
+ * 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.core.quota;
+
+import java.util.Set;
+
+import com.google.inject.Inject;
+
+public class QuotaComponentFactory {
+ private Set<QuotaComponent> set;
+
+ @Inject
+ public QuotaComponentFactory(Set<QuotaComponent> set) {
+ this.set = set;
+ }
+
+ public QuotaComponent parse(String value) {
+ for (QuotaComponent quotaComponent : set) {
Review Comment:
Please always favor fonctional apis like `java.util.Stream`
##########
core/src/main/java/org/apache/james/core/quota/QuotaModelModule.java:
##########
@@ -0,0 +1,55 @@
+/****************************************************************
+ * 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.core.quota;
+
+import org.apache.james.core.quota.quotacomponent.JmapUploadQuotaComponent;
+import org.apache.james.core.quota.quotacomponent.MailBoxQuotaComponent;
+import org.apache.james.core.quota.quotacomponent.SieveQuotaComponent;
+import org.apache.james.core.quota.quotascope.DomainQuotaScope;
+import org.apache.james.core.quota.quotascope.GlobalQuotaScope;
+import org.apache.james.core.quota.quotascope.UserQuotaScope;
+import org.apache.james.core.quota.quotatype.CountQuotaType;
+import org.apache.james.core.quota.quotatype.SizeQuotaType;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Scopes;
+import com.google.inject.multibindings.Multibinder;
+
+public class QuotaModelModule extends AbstractModule {
Review Comment:
This has NOTHING to do in `/core`. If needed move this to
`/server/container/guice`
##########
core/src/main/java/org/apache/james/core/quota/QuotaComponentFactory.java:
##########
@@ -0,0 +1,42 @@
+/****************************************************************
+ * 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.core.quota;
+
+import java.util.Set;
+
+import com.google.inject.Inject;
+
+public class QuotaComponentFactory {
Review Comment:
IMO overkill.
Isn't
```
public class QuotaComponent {
private final String value;
// constructor, getter, equals, hashcode, toString
}
```
Enough?
+ Dynamic registration for this IS clearly overkill, even to me.
##########
mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraQuotaModule.java:
##########
@@ -68,5 +70,26 @@ public interface CassandraQuotaModule {
.withPartitionKey(CassandraGlobalMaxQuota.KEY, TEXT)
.withColumn(CassandraGlobalMaxQuota.STORAGE, BIGINT)
.withColumn(CassandraGlobalMaxQuota.MESSAGE, BIGINT))
+
+ .table(CassandraQuotaLimit.TABLE_NAME)
+ .comment("Holds quota limit.")
Review Comment:
```suggestion
.comment("Holds quota limits.")
```
##########
mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaCurrentValueDaoTest.java:
##########
@@ -0,0 +1,58 @@
+/****************************************************************
+ * 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.quota;
+
+import org.apache.james.backends.cassandra.CassandraClusterExtension;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.blob.cassandra.CassandraBlobModule;
+import org.apache.james.core.quota.QuotaCurrentValue;
+import org.apache.james.core.quota.quotacomponent.MailBoxQuotaComponent;
+import org.apache.james.core.quota.quotatype.SizeQuotaType;
+import org.apache.james.mailbox.cassandra.mail.utils.GuiceUtils;
+import org.apache.james.mailbox.cassandra.modules.CassandraQuotaModule;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+public class CassandraQuotaCurrentValueDaoTest {
Review Comment:
Please better test edge cases...
- set A, set B
- Negative values
- 0
- etc...
##########
mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaLimitDao.java:
##########
@@ -0,0 +1,95 @@
+/****************************************************************
+ * 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.quota;
Review Comment:
No way to remove a limit in this DAO?
##########
core/src/main/java/org/apache/james/core/quota/QuotaScope.java:
##########
@@ -0,0 +1,24 @@
+/****************************************************************
+ * 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.core.quota;
+
+public interface QuotaScope {
Review Comment:
Idem I think a simple value class wrapping a String would serve us better
here.
Simpler is better.
##########
mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaLimitDao.java:
##########
@@ -0,0 +1,95 @@
+/****************************************************************
+ * 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.quota;
+
+import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.bindMarker;
+import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.insertInto;
+import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.selectFrom;
+import static
com.datastax.oss.driver.api.querybuilder.relation.Relation.column;
+
+import javax.inject.Inject;
+
+import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
+import org.apache.james.core.quota.QuotaComponent;
+import org.apache.james.core.quota.QuotaComponentFactory;
+import org.apache.james.core.quota.QuotaLimit;
+import org.apache.james.core.quota.QuotaScope;
+import org.apache.james.core.quota.QuotaScopeFactory;
+import org.apache.james.core.quota.QuotaType;
+import org.apache.james.core.quota.QuotaTypeFactory;
+import org.apache.james.mailbox.cassandra.table.CassandraQuotaLimit;
+
+import com.datastax.oss.driver.api.core.CqlSession;
+import com.datastax.oss.driver.api.core.cql.PreparedStatement;
+import com.datastax.oss.driver.api.querybuilder.insert.Insert;
+import com.datastax.oss.driver.api.querybuilder.select.Select;
+
+import reactor.core.publisher.Mono;
+
+public class CassandraQuotaLimitDao {
+
+ private final CassandraAsyncExecutor queryExecutor;
+ private final PreparedStatement getQuotaLimitStatement;
+ private final PreparedStatement setQuotaLimitStatement;
+ private final QuotaComponentFactory quotaComponentFactory;
+ private final QuotaTypeFactory quotaTypeFactory;
+ private final QuotaScopeFactory quotaScopeFactory;
+
+ @Inject
+ public CassandraQuotaLimitDao(CqlSession session, QuotaComponentFactory
quotaComponentFactory, QuotaTypeFactory quotaTypeFactory, QuotaScopeFactory
quotaScopeFactory) {
+ this.queryExecutor = new CassandraAsyncExecutor(session);
+ this.getQuotaLimitStatement =
session.prepare(getQuotaLimitStatement().build());
+ this.setQuotaLimitStatement =
session.prepare(setQuotaLimitStatement().build());
+ this.quotaComponentFactory = quotaComponentFactory;
+ this.quotaTypeFactory = quotaTypeFactory;
+ this.quotaScopeFactory = quotaScopeFactory;
+ }
+
+ Mono<QuotaLimit> getQuotaLimit(String identifier, QuotaComponent
quotaComponent, QuotaType quotaType, QuotaScope quotaScope) {
+ return
queryExecutor.executeSingleRow(getQuotaLimitStatement.bind(identifier,
quotaComponent.asString(), quotaType.asString(), quotaScope.asString()))
+ .map(row -> QuotaLimit.of(row.get(CassandraQuotaLimit.IDENTIFIER,
String.class),
quotaComponentFactory.parse(row.get(CassandraQuotaLimit.QUOTA_COMPONENT,
String.class)),
+ quotaTypeFactory.parse(row.get(CassandraQuotaLimit.QUOTA_TYPE,
String.class)),
quotaScopeFactory.parse(row.get(CassandraQuotaLimit.QUOTA_SCOPE, String.class)),
+ row.get(CassandraQuotaLimit.MAX_VALUE, Long.class)));
+ }
Review Comment:
Idem method extraction please
##########
core/src/main/java/org/apache/james/core/quota/QuotaLimit.java:
##########
@@ -0,0 +1,81 @@
+/****************************************************************
+ * 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.core.quota;
+
+import java.util.Objects;
+
+public class QuotaLimit {
+
+ private final String identifier;
+ private final QuotaComponent quotaComponent;
+ private final QuotaType quotaType;
+ private final QuotaScope quotaScope;
+ private final Long maxValue;
+
+ private QuotaLimit(String identifier, QuotaComponent quotaComponent,
QuotaType quotaType, QuotaScope quotaScope, Long maxValue) {
+ this.identifier = identifier;
+ this.quotaComponent = quotaComponent;
+ this.quotaType = quotaType;
+ this.quotaScope = quotaScope;
+ this.maxValue = maxValue;
+ }
+
+ public static QuotaLimit of(String identifier, QuotaComponent component,
QuotaType quotaType, QuotaScope scope, Long maxValue) {
Review Comment:
Static methods goes first by project convention
##########
mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaCurrentValueDao.java:
##########
@@ -0,0 +1,88 @@
+/****************************************************************
Review Comment:
No way to remove a current value in this DAO?
##########
mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaCurrentValueDao.java:
##########
@@ -0,0 +1,88 @@
+/****************************************************************
+ * 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.quota;
+
+import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.bindMarker;
+import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.insertInto;
+import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.selectFrom;
+import static
com.datastax.oss.driver.api.querybuilder.relation.Relation.column;
+
+import javax.inject.Inject;
+
+import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
+import org.apache.james.core.quota.QuotaComponent;
+import org.apache.james.core.quota.QuotaComponentFactory;
+import org.apache.james.core.quota.QuotaCurrentValue;
+import org.apache.james.core.quota.QuotaType;
+import org.apache.james.core.quota.QuotaTypeFactory;
+import org.apache.james.mailbox.cassandra.table.CassandraQuotaCurrentValue;
+
+import com.datastax.oss.driver.api.core.CqlSession;
+import com.datastax.oss.driver.api.core.cql.PreparedStatement;
+import com.datastax.oss.driver.api.querybuilder.insert.Insert;
+import com.datastax.oss.driver.api.querybuilder.select.Select;
+
+import reactor.core.publisher.Mono;
+
+public class CassandraQuotaCurrentValueDao {
+
+ private final CassandraAsyncExecutor queryExecutor;
+ private final PreparedStatement getQuotaCurrentValueStatement;
+ private final PreparedStatement setQuotaCurrentValueStatement;
+ private final QuotaComponentFactory quotaComponentFactory;
+ private final QuotaTypeFactory quotaTypeFactory;
+
+ @Inject
+ public CassandraQuotaCurrentValueDao(CqlSession session,
QuotaComponentFactory quotaComponentFactory, QuotaTypeFactory quotaTypeFactory)
{
+ this.queryExecutor = new CassandraAsyncExecutor(session);
+ this.getQuotaCurrentValueStatement =
session.prepare(getQuotaCurrentValueStatement().build());
+ this.setQuotaCurrentValueStatement =
session.prepare(setQuotaCurrentValueStatement().build());
+ this.quotaComponentFactory = quotaComponentFactory;
+ this.quotaTypeFactory = quotaTypeFactory;
+ }
+
+ Mono<QuotaCurrentValue> getQuotaCurrentValue(String identifier,
QuotaComponent quotaComponent, QuotaType quotaType) {
+ return
queryExecutor.executeSingleRow(getQuotaCurrentValueStatement.bind(identifier,
quotaComponent.asString(), quotaType.asString()))
+ .map(row ->
QuotaCurrentValue.of(row.get(CassandraQuotaCurrentValue.IDENTIFIER,
String.class),
quotaComponentFactory.parse(row.get(CassandraQuotaCurrentValue.QUOTA_COMPONENT,
String.class)),
+
quotaTypeFactory.parse(row.get(CassandraQuotaCurrentValue.QUOTA_TYPE,
String.class)), row.get(CassandraQuotaCurrentValue.CURRENT_VALUE, Long.class)));
+ }
Review Comment:
Not readable a first site (6am here)
Please try extractoring IE row -> POJO convertion
##########
core/src/main/java/org/apache/james/core/quota/QuotaType.java:
##########
@@ -0,0 +1,24 @@
+/****************************************************************
+ * 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.core.quota;
+
+public interface QuotaType {
Review Comment:
Idem
##########
core/src/main/java/org/apache/james/core/quota/QuotaCurrentValue.java:
##########
@@ -0,0 +1,74 @@
+/****************************************************************
+ * 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.core.quota;
+
+import java.util.Objects;
+
+public class QuotaCurrentValue {
+
+ private final String identifier;
+ private final QuotaComponent quotaComponent;
+ private final QuotaType quotaType;
+ private final Long currentValue;
Review Comment:
Why a `Long`? Are you using `null` so that you need a boxed value? But if so
nullity is truely dangerous and should be avoided...
Alternative (more explicit): `Optional<Long>`
##########
core/src/main/java/org/apache/james/core/quota/QuotaScopeFactory.java:
##########
@@ -0,0 +1,42 @@
+/****************************************************************
+ * 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.core.quota;
+
+import java.util.Set;
+
+import com.google.inject.Inject;
+
+public class QuotaScopeFactory {
Review Comment:
My first reflex would be to kill the factory
##########
mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaLimitDao.java:
##########
@@ -0,0 +1,95 @@
+/****************************************************************
+ * 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.quota;
+
+import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.bindMarker;
+import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.insertInto;
+import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.selectFrom;
+import static
com.datastax.oss.driver.api.querybuilder.relation.Relation.column;
+
+import javax.inject.Inject;
+
+import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
+import org.apache.james.core.quota.QuotaComponent;
+import org.apache.james.core.quota.QuotaComponentFactory;
+import org.apache.james.core.quota.QuotaLimit;
+import org.apache.james.core.quota.QuotaScope;
+import org.apache.james.core.quota.QuotaScopeFactory;
+import org.apache.james.core.quota.QuotaType;
+import org.apache.james.core.quota.QuotaTypeFactory;
+import org.apache.james.mailbox.cassandra.table.CassandraQuotaLimit;
+
+import com.datastax.oss.driver.api.core.CqlSession;
+import com.datastax.oss.driver.api.core.cql.PreparedStatement;
+import com.datastax.oss.driver.api.querybuilder.insert.Insert;
+import com.datastax.oss.driver.api.querybuilder.select.Select;
+
+import reactor.core.publisher.Mono;
+
+public class CassandraQuotaLimitDao {
+
+ private final CassandraAsyncExecutor queryExecutor;
+ private final PreparedStatement getQuotaLimitStatement;
+ private final PreparedStatement setQuotaLimitStatement;
+ private final QuotaComponentFactory quotaComponentFactory;
+ private final QuotaTypeFactory quotaTypeFactory;
+ private final QuotaScopeFactory quotaScopeFactory;
+
+ @Inject
+ public CassandraQuotaLimitDao(CqlSession session, QuotaComponentFactory
quotaComponentFactory, QuotaTypeFactory quotaTypeFactory, QuotaScopeFactory
quotaScopeFactory) {
+ this.queryExecutor = new CassandraAsyncExecutor(session);
+ this.getQuotaLimitStatement =
session.prepare(getQuotaLimitStatement().build());
+ this.setQuotaLimitStatement =
session.prepare(setQuotaLimitStatement().build());
+ this.quotaComponentFactory = quotaComponentFactory;
+ this.quotaTypeFactory = quotaTypeFactory;
+ this.quotaScopeFactory = quotaScopeFactory;
+ }
+
+ Mono<QuotaLimit> getQuotaLimit(String identifier, QuotaComponent
quotaComponent, QuotaType quotaType, QuotaScope quotaScope) {
+ return
queryExecutor.executeSingleRow(getQuotaLimitStatement.bind(identifier,
quotaComponent.asString(), quotaType.asString(), quotaScope.asString()))
+ .map(row -> QuotaLimit.of(row.get(CassandraQuotaLimit.IDENTIFIER,
String.class),
quotaComponentFactory.parse(row.get(CassandraQuotaLimit.QUOTA_COMPONENT,
String.class)),
+ quotaTypeFactory.parse(row.get(CassandraQuotaLimit.QUOTA_TYPE,
String.class)),
quotaScopeFactory.parse(row.get(CassandraQuotaLimit.QUOTA_SCOPE, String.class)),
+ row.get(CassandraQuotaLimit.MAX_VALUE, Long.class)));
+ }
+
+ Mono<Void> setQuotaLimit(QuotaLimit quotaLimit) {
Review Comment:
Increase / decrease quta limit in order to fit the cassandra counter
semantic.
##########
core/src/main/java/org/apache/james/core/quota/QuotaLimit.java:
##########
@@ -0,0 +1,81 @@
+/****************************************************************
+ * 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.core.quota;
+
+import java.util.Objects;
+
+public class QuotaLimit {
+
+ private final String identifier;
+ private final QuotaComponent quotaComponent;
+ private final QuotaType quotaType;
+ private final QuotaScope quotaScope;
+ private final Long maxValue;
Review Comment:
Idem
##########
core/src/main/java/org/apache/james/core/quota/QuotaTypeFactory.java:
##########
@@ -0,0 +1,42 @@
+/****************************************************************
+ * 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.core.quota;
+
+import java.util.Set;
+
+import com.google.inject.Inject;
+
+public class QuotaTypeFactory {
Review Comment:
Idem
##########
mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraQuotaModule.java:
##########
@@ -68,5 +70,26 @@ public interface CassandraQuotaModule {
.withPartitionKey(CassandraGlobalMaxQuota.KEY, TEXT)
.withColumn(CassandraGlobalMaxQuota.STORAGE, BIGINT)
.withColumn(CassandraGlobalMaxQuota.MESSAGE, BIGINT))
+
+ .table(CassandraQuotaLimit.TABLE_NAME)
+ .comment("Holds quota limit.")
+ .options(options -> options
+ .withCaching(true,
rows(CassandraConstants.DEFAULT_CACHED_ROW_PER_PARTITION)))
+ .statement(statement -> types -> statement
+ .withPartitionKey(CassandraQuotaLimit.IDENTIFIER, TEXT)
+ .withPartitionKey(CassandraQuotaLimit.QUOTA_COMPONENT, TEXT)
+ .withPartitionKey(CassandraQuotaLimit.QUOTA_TYPE, TEXT)
+ .withPartitionKey(CassandraQuotaLimit.QUOTA_SCOPE, TEXT)
+ .withColumn(CassandraQuotaLimit.MAX_VALUE, BIGINT))
+
+ .table(CassandraQuotaCurrentValue.TABLE_NAME)
+ .comment("Holds quota limit.")
+ .options(options -> options
+ .withCaching(true,
rows(CassandraConstants.DEFAULT_CACHED_ROW_PER_PARTITION)))
+ .statement(statement -> types -> statement
+ .withPartitionKey(CassandraQuotaCurrentValue.IDENTIFIER, TEXT)
+ .withPartitionKey(CassandraQuotaCurrentValue.QUOTA_COMPONENT, TEXT)
+ .withPartitionKey(CassandraQuotaCurrentValue.QUOTA_TYPE, TEXT)
+ .withColumn(CassandraQuotaCurrentValue.CURRENT_VALUE, BIGINT))
Review Comment:
Use a counter!
##########
mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaCurrentValueDao.java:
##########
@@ -0,0 +1,88 @@
+/****************************************************************
+ * 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.quota;
+
+import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.bindMarker;
+import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.insertInto;
+import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.selectFrom;
+import static
com.datastax.oss.driver.api.querybuilder.relation.Relation.column;
+
+import javax.inject.Inject;
+
+import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
+import org.apache.james.core.quota.QuotaComponent;
+import org.apache.james.core.quota.QuotaComponentFactory;
+import org.apache.james.core.quota.QuotaCurrentValue;
+import org.apache.james.core.quota.QuotaType;
+import org.apache.james.core.quota.QuotaTypeFactory;
+import org.apache.james.mailbox.cassandra.table.CassandraQuotaCurrentValue;
+
+import com.datastax.oss.driver.api.core.CqlSession;
+import com.datastax.oss.driver.api.core.cql.PreparedStatement;
+import com.datastax.oss.driver.api.querybuilder.insert.Insert;
+import com.datastax.oss.driver.api.querybuilder.select.Select;
+
+import reactor.core.publisher.Mono;
+
+public class CassandraQuotaCurrentValueDao {
+
+ private final CassandraAsyncExecutor queryExecutor;
+ private final PreparedStatement getQuotaCurrentValueStatement;
+ private final PreparedStatement setQuotaCurrentValueStatement;
+ private final QuotaComponentFactory quotaComponentFactory;
+ private final QuotaTypeFactory quotaTypeFactory;
+
+ @Inject
+ public CassandraQuotaCurrentValueDao(CqlSession session,
QuotaComponentFactory quotaComponentFactory, QuotaTypeFactory quotaTypeFactory)
{
+ this.queryExecutor = new CassandraAsyncExecutor(session);
+ this.getQuotaCurrentValueStatement =
session.prepare(getQuotaCurrentValueStatement().build());
+ this.setQuotaCurrentValueStatement =
session.prepare(setQuotaCurrentValueStatement().build());
+ this.quotaComponentFactory = quotaComponentFactory;
+ this.quotaTypeFactory = quotaTypeFactory;
+ }
+
+ Mono<QuotaCurrentValue> getQuotaCurrentValue(String identifier,
QuotaComponent quotaComponent, QuotaType quotaType) {
+ return
queryExecutor.executeSingleRow(getQuotaCurrentValueStatement.bind(identifier,
quotaComponent.asString(), quotaType.asString()))
+ .map(row ->
QuotaCurrentValue.of(row.get(CassandraQuotaCurrentValue.IDENTIFIER,
String.class),
quotaComponentFactory.parse(row.get(CassandraQuotaCurrentValue.QUOTA_COMPONENT,
String.class)),
+
quotaTypeFactory.parse(row.get(CassandraQuotaCurrentValue.QUOTA_TYPE,
String.class)), row.get(CassandraQuotaCurrentValue.CURRENT_VALUE, Long.class)));
+ }
+
+ Mono<Void> setQuotaCurrentValue(QuotaCurrentValue quotaCurrentValue) {
+ return
queryExecutor.executeVoid(setQuotaCurrentValueStatement.bind(quotaCurrentValue.getIdentifier(),
+ quotaCurrentValue.getQuotaComponent().asString(),
quotaCurrentValue.getQuotaType().asString(),
quotaCurrentValue.getCurrentValue()));
Review Comment:
Use named values in your binds
##########
mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaLimitDaoTest.java:
##########
@@ -0,0 +1,59 @@
+/****************************************************************
+ * 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.quota;
+
+import org.apache.james.backends.cassandra.CassandraClusterExtension;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.blob.cassandra.CassandraBlobModule;
+import org.apache.james.core.quota.QuotaLimit;
+import org.apache.james.core.quota.quotacomponent.MailBoxQuotaComponent;
+import org.apache.james.core.quota.quotascope.UserQuotaScope;
+import org.apache.james.core.quota.quotatype.SizeQuotaType;
+import org.apache.james.mailbox.cassandra.mail.utils.GuiceUtils;
+import org.apache.james.mailbox.cassandra.modules.CassandraQuotaModule;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+public class CassandraQuotaLimitDaoTest {
Review Comment:
Better test your edge cases
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]