You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2022/11/19 06:20:27 UTC

[syncope] branch 2_1_X updated: [SYNCOPE-1713] Adding after and before parameter to Audit, Task, Report and Remediation queries (#392) (#393)

This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch 2_1_X
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/2_1_X by this push:
     new 8b9465f25e [SYNCOPE-1713] Adding after and before parameter to Audit, Task, Report and Remediation queries (#392) (#393)
8b9465f25e is described below

commit 8b9465f25eb0bc87275f34586175316f015c36f5
Author: Francesco Chicchiriccò <il...@users.noreply.github.com>
AuthorDate: Sat Nov 19 07:20:20 2022 +0100

    [SYNCOPE-1713] Adding after and before parameter to Audit, Task, Report and Remediation queries (#392) (#393)
---
 .../commands/report/ReportSyncopeOperations.java   |   4 +-
 .../cli/commands/task/TaskSyncopeOperations.java   |   4 +-
 .../syncope/client/console/batch/BatchContent.java |   8 +-
 .../client/console/rest/ReportRestClient.java      |   9 +-
 .../client/console/rest/TaskRestClient.java        |   4 +-
 .../rest/api/beans/AbstractTimeframeQuery.java     | 107 +++++++++++++++
 .../common/rest/api/beans/AccessTokenQuery.java    |   1 -
 .../syncope/common/rest/api/beans/AuditQuery.java  |   4 +-
 .../common/rest/api/beans/ExecDeleteQuery.java     | 148 ---------------------
 .../syncope/common/rest/api/beans/ExecQuery.java   |   4 +-
 .../beans/{ExecuteQuery.java => ExecSpecs.java}    |   6 +-
 .../common/rest/api/beans/RemediationQuery.java    |   4 +-
 .../common/rest/api/service/ExecutableService.java |   7 +-
 .../core/logic/AbstractExecutableLogic.java        |  11 +-
 .../org/apache/syncope/core/logic/LoggerLogic.java |   7 +-
 .../syncope/core/logic/RemediationLogic.java       |   7 +-
 .../org/apache/syncope/core/logic/ReportLogic.java |  36 ++---
 .../org/apache/syncope/core/logic/TaskLogic.java   |  22 +--
 .../core/persistence/api/dao/LoggerDAO.java        |   9 +-
 .../core/persistence/api/dao/RemediationDAO.java   |  10 +-
 .../core/persistence/api/dao/ReportExecDAO.java    |  14 +-
 .../core/persistence/api/dao/TaskExecDAO.java      |  15 ++-
 .../persistence/jpa/dao/MyJPAJSONLoggerDAO.java    |  22 +--
 .../persistence/jpa/dao/PGJPAJSONLoggerDAO.java    |  22 +--
 .../core/persistence/jpa/dao/JPALoggerDAO.java     |  51 ++++++-
 .../persistence/jpa/dao/JPARemediationDAO.java     |  43 +++++-
 .../core/persistence/jpa/dao/JPAReportExecDAO.java | 107 ++++++++-------
 .../core/persistence/jpa/dao/JPATaskExecDAO.java   |  97 +++++++-------
 .../persistence/jpa/inner/RemediationTest.java     |   2 +-
 .../core/persistence/jpa/inner/TaskExecTest.java   |   3 +-
 .../cxf/service/AbstractExecutableService.java     |  15 +--
 .../core/rest/cxf/service/LoggerServiceImpl.java   |   2 +
 .../rest/cxf/service/RemediationServiceImpl.java   |   6 +-
 .../jpa/dao/ElasticsearchLoggerDAO.java            |  23 +++-
 .../syncope/fit/core/AbstractTaskITCase.java       |   4 +-
 .../org/apache/syncope/fit/core/AuditITCase.java   |  12 +-
 .../syncope/fit/core/NotificationTaskITCase.java   |   4 +-
 .../syncope/fit/core/PropagationTaskITCase.java    |  13 +-
 .../apache/syncope/fit/core/PullTaskITCase.java    |   4 +-
 .../org/apache/syncope/fit/core/ReportITCase.java  |  12 +-
 .../apache/syncope/fit/core/SchedTaskITCase.java   |   4 +-
 41 files changed, 504 insertions(+), 383 deletions(-)

diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/report/ReportSyncopeOperations.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/report/ReportSyncopeOperations.java
index 17c6efad48..da1d267f4a 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/report/ReportSyncopeOperations.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/report/ReportSyncopeOperations.java
@@ -29,7 +29,7 @@ import org.apache.syncope.client.cli.util.XMLUtils;
 import org.apache.syncope.common.lib.to.JobTO;
 import org.apache.syncope.common.lib.to.ReportTO;
 import org.apache.syncope.common.lib.types.ReportExecExportFormat;
-import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
+import org.apache.syncope.common.rest.api.beans.ExecSpecs;
 import org.apache.syncope.common.rest.api.service.ReportService;
 
 public class ReportSyncopeOperations {
@@ -98,7 +98,7 @@ public class ReportSyncopeOperations {
     }
 
     public void execute(final String reportKey) {
-        reportService.execute(new ExecuteQuery.Builder().key(reportKey).build());
+        reportService.execute(new ExecSpecs.Builder().key(reportKey).build());
     }
 
     public void deleteExecution(final String executionKey) {
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskSyncopeOperations.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskSyncopeOperations.java
index d577968292..2314c04484 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskSyncopeOperations.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskSyncopeOperations.java
@@ -24,7 +24,7 @@ import org.apache.syncope.common.lib.to.TaskTO;
 import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.to.JobTO;
 import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
+import org.apache.syncope.common.rest.api.beans.ExecSpecs;
 import org.apache.syncope.common.rest.api.beans.TaskQuery;
 import org.apache.syncope.common.rest.api.service.TaskService;
 
@@ -58,6 +58,6 @@ public class TaskSyncopeOperations {
 
     public ExecTO execute(final String executionKey, final boolean dryRun) {
         return taskService.execute(
-                new ExecuteQuery.Builder().key(executionKey).dryRun(dryRun).build());
+                new ExecSpecs.Builder().key(executionKey).dryRun(dryRun).build());
     }
 }
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/batch/BatchContent.java b/client/console/src/main/java/org/apache/syncope/client/console/batch/BatchContent.java
index 7d6919c515..be473f1d14 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/batch/BatchContent.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/batch/BatchContent.java
@@ -58,7 +58,7 @@ import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.syncope.common.lib.types.StatusPatchType;
 import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
+import org.apache.syncope.common.rest.api.beans.ExecSpecs;
 import org.apache.syncope.common.rest.api.service.AnyObjectService;
 import org.apache.syncope.common.rest.api.service.AnyService;
 import org.apache.syncope.common.rest.api.service.GroupService;
@@ -300,7 +300,7 @@ public class BatchContent<T extends Serializable, S> extends MultilevelPanel.Sec
                                         TaskTO task = (TaskTO) item;
 
                                         batchTaskService.execute(
-                                                new ExecuteQuery.Builder().dryRun(true).key(task.getKey()).build());
+                                                new ExecSpecs.Builder().dryRun(true).key(task.getKey()).build());
                                     });
                                     break;
 
@@ -309,12 +309,12 @@ public class BatchContent<T extends Serializable, S> extends MultilevelPanel.Sec
                                         if (singleItem instanceof TaskTO) {
                                             TaskTO task = (TaskTO) item;
 
-                                            batchTaskService.execute(new ExecuteQuery.Builder().
+                                            batchTaskService.execute(new ExecSpecs.Builder().
                                                     dryRun(false).key(task.getKey()).build());
                                         } else if (singleItem instanceof ReportTO) {
                                             ReportTO report = (ReportTO) item;
 
-                                            batchReportService.execute(new ExecuteQuery.Builder().
+                                            batchReportService.execute(new ExecSpecs.Builder().
                                                     key(report.getKey()).build());
                                         }
                                     });
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
index f783f465a8..a2ea0dad18 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
@@ -40,7 +40,7 @@ import org.apache.syncope.common.lib.types.ReportTemplateFormat;
 import org.apache.syncope.common.rest.api.batch.BatchRequestItem;
 import org.apache.syncope.common.rest.api.batch.BatchResponseItem;
 import org.apache.syncope.common.rest.api.beans.ExecQuery;
-import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
+import org.apache.syncope.common.rest.api.beans.ExecSpecs;
 import org.apache.syncope.common.rest.api.service.ReportService;
 import org.apache.syncope.common.rest.api.service.ReportTemplateService;
 import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
@@ -89,7 +89,7 @@ public class ReportRestClient extends BaseRestClient
 
     @Override
     public void startExecution(final String reportKey, final Date start) {
-        getService(ReportService.class).execute(new ExecuteQuery.Builder().key(reportKey).startAt(start).build());
+        getService(ReportService.class).execute(new ExecSpecs.Builder().key(reportKey).startAt(start).build());
     }
 
     @Override
@@ -110,9 +110,8 @@ public class ReportRestClient extends BaseRestClient
     public List<ExecTO> listExecutions(
             final String taskKey, final int page, final int size, final SortParam<String> sort) {
 
-        return getService(ReportService.class).
-                listExecutions(new ExecQuery.Builder().key(taskKey).page(page).size(size).
-                        orderBy(toOrderBy(sort)).build()).getResult();
+        return getService(ReportService.class).listExecutions(new ExecQuery.Builder().
+                key(taskKey).page(page).size(size).orderBy(toOrderBy(sort)).build()).getResult();
     }
 
     @Override
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java
index 6f0655b5d7..ed1f078103 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java
@@ -40,7 +40,7 @@ import org.apache.syncope.common.lib.types.JobAction;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.rest.api.batch.BatchRequestItem;
 import org.apache.syncope.common.rest.api.batch.BatchResponseItem;
-import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
+import org.apache.syncope.common.rest.api.beans.ExecSpecs;
 import org.apache.syncope.common.rest.api.beans.ExecQuery;
 import org.apache.syncope.common.rest.api.beans.TaskQuery;
 import org.apache.syncope.common.rest.api.service.TaskService;
@@ -213,7 +213,7 @@ public class TaskRestClient extends BaseRestClient implements ExecutionRestClien
 
     public void startExecution(final String taskKey, final Date start, final boolean dryRun) {
         getService(TaskService.class).execute(
-                new ExecuteQuery.Builder().key(taskKey).startAt(start).dryRun(dryRun).build());
+                new ExecSpecs.Builder().key(taskKey).startAt(start).dryRun(dryRun).build());
     }
 
     @Override
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AbstractTimeframeQuery.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AbstractTimeframeQuery.java
new file mode 100644
index 0000000000..2e7979b646
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AbstractTimeframeQuery.java
@@ -0,0 +1,107 @@
+/*
+ * 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.syncope.common.rest.api.beans;
+
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
+import io.swagger.v3.oas.annotations.media.Schema;
+import java.util.Date;
+import javax.ws.rs.QueryParam;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+public abstract class AbstractTimeframeQuery extends AbstractQuery {
+
+    private static final long serialVersionUID = -6858655425207486223L;
+
+    protected abstract static class Builder<Q extends AbstractTimeframeQuery, B extends Builder<Q, B>>
+            extends AbstractQuery.Builder<Q, B> {
+
+        @Override
+        protected Q getInstance() {
+            return super.getInstance();
+        }
+
+        @SuppressWarnings("unchecked")
+        public B before(final Date before) {
+            getInstance().setBefore(before);
+            return (B) this;
+        }
+
+        @SuppressWarnings("unchecked")
+        public B after(final Date after) {
+            getInstance().setAfter(after);
+            return (B) this;
+        }
+    }
+
+    private Date before;
+
+    private Date after;
+
+    @Parameter(name = "before", in = ParameterIn.QUERY, schema =
+            @Schema(implementation = Date.class))
+    public Date getBefore() {
+        return before;
+    }
+
+    @QueryParam("before")
+    public void setBefore(final Date before) {
+        this.before = before;
+    }
+
+    @Parameter(name = "after", in = ParameterIn.QUERY, schema =
+            @Schema(implementation = Date.class))
+    public Date getAfter() {
+        return after;
+    }
+
+    @QueryParam("after")
+    public void setAfter(final Date after) {
+        this.after = after;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        AbstractTimeframeQuery other = (AbstractTimeframeQuery) obj;
+        return new EqualsBuilder().
+                appendSuper(super.equals(obj)).
+                append(before, other.before).
+                append(after, other.after).
+                build();
+    }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().
+                appendSuper(super.hashCode()).
+                append(before).
+                append(after).
+                build();
+    }
+}
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AccessTokenQuery.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AccessTokenQuery.java
index abdea3f897..e7e8ce3bbd 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AccessTokenQuery.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AccessTokenQuery.java
@@ -29,5 +29,4 @@ public class AccessTokenQuery extends AbstractQuery {
             return new AccessTokenQuery();
         }
     }
-
 }
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AuditQuery.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AuditQuery.java
index 71814c35eb..ac843d947d 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AuditQuery.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AuditQuery.java
@@ -28,11 +28,11 @@ import javax.ws.rs.QueryParam;
 import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.rest.api.service.JAXRSService;
 
-public class AuditQuery extends AbstractQuery {
+public class AuditQuery extends AbstractTimeframeQuery {
 
     private static final long serialVersionUID = -2863334226169614417L;
 
-    public static class Builder extends AbstractQuery.Builder<AuditQuery, Builder> {
+    public static class Builder extends AbstractTimeframeQuery.Builder<AuditQuery, Builder> {
 
         @Override
         protected AuditQuery newInstance() {
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecDeleteQuery.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecDeleteQuery.java
deleted file mode 100644
index 664a705b95..0000000000
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecDeleteQuery.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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.syncope.common.rest.api.beans;
-
-import java.io.Serializable;
-import java.util.Date;
-import javax.validation.constraints.NotNull;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.QueryParam;
-
-public class ExecDeleteQuery implements Serializable {
-
-    private static final long serialVersionUID = 3846547401120638351L;
-
-    public static class Builder {
-
-        private final ExecDeleteQuery instance = new ExecDeleteQuery();
-
-        public Builder key(final String key) {
-            instance.setKey(key);
-            return this;
-        }
-
-        public Builder startedBefore(final Date date) {
-            instance.setStartedBefore(date);
-            return this;
-        }
-
-        public Builder startedAfter(final Date date) {
-            instance.setStartedAfter(date);
-            return this;
-        }
-
-        public Builder endedBefore(final Date date) {
-            instance.setEndedBefore(date);
-            return this;
-        }
-
-        public Builder endedAfter(final Date date) {
-            instance.setEndedAfter(date);
-            return this;
-        }
-
-        public ExecDeleteQuery build() {
-            return instance;
-        }
-    }
-
-    private String key;
-
-    private Date startedBefore;
-
-    private Date startedAfter;
-
-    private Date endedBefore;
-
-    private Date endedAfter;
-
-    public String getKey() {
-        return key;
-    }
-
-    @NotNull
-    @PathParam("key")
-    public void setKey(final String key) {
-        this.key = key;
-    }
-
-    public Date getStartedBefore() {
-        if (startedBefore != null) {
-            return new Date(startedBefore.getTime());
-        }
-        return null;
-    }
-
-    @QueryParam("startedBefore")
-    public void setStartedBefore(final Date startedBefore) {
-        if (startedBefore != null) {
-            this.startedBefore = new Date(startedBefore.getTime());
-        } else {
-            this.startedBefore = null;
-        }
-    }
-
-    public Date getStartedAfter() {
-        if (startedAfter != null) {
-            return new Date(startedAfter.getTime());
-        }
-        return null;
-    }
-
-    @QueryParam("startedAfter")
-    public void setStartedAfter(final Date startedAfter) {
-        if (startedAfter != null) {
-            this.startedAfter = new Date(startedAfter.getTime());
-        } else {
-            this.startedAfter = null;
-        }
-    }
-
-    public Date getEndedBefore() {
-        if (endedBefore != null) {
-            return new Date(endedBefore.getTime());
-        }
-        return null;
-    }
-
-    @QueryParam("endedBefore")
-    public void setEndedBefore(final Date endedBefore) {
-        if (endedBefore != null) {
-            this.endedBefore = new Date(endedBefore.getTime());
-        } else {
-            this.endedBefore = null;
-        }
-    }
-
-    public Date getEndedAfter() {
-        if (endedAfter != null) {
-            return new Date(endedAfter.getTime());
-        }
-        return null;
-    }
-
-    @QueryParam("endedAfter")
-    public void setEndedAfter(final Date endedAfter) {
-        if (endedAfter != null) {
-            this.endedAfter = new Date(endedAfter.getTime());
-        } else {
-            this.endedAfter = null;
-        }
-    }
-}
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecQuery.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecQuery.java
index e307d3e2bc..abf444541d 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecQuery.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecQuery.java
@@ -23,11 +23,11 @@ import javax.ws.rs.PathParam;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
 
-public class ExecQuery extends AbstractQuery {
+public class ExecQuery extends AbstractTimeframeQuery {
 
     private static final long serialVersionUID = -8792519310029596796L;
 
-    public static class Builder extends AbstractQuery.Builder<ExecQuery, Builder> {
+    public static class Builder extends AbstractTimeframeQuery.Builder<ExecQuery, Builder> {
 
         @Override
         protected ExecQuery newInstance() {
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecuteQuery.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecSpecs.java
similarity index 93%
rename from common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecuteQuery.java
rename to common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecSpecs.java
index ac6ef36d79..bc4dce0bc4 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecuteQuery.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecSpecs.java
@@ -25,13 +25,13 @@ import javax.ws.rs.DefaultValue;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.QueryParam;
 
-public class ExecuteQuery implements Serializable {
+public class ExecSpecs implements Serializable {
 
     private static final long serialVersionUID = 3846547401120638351L;
 
     public static class Builder {
 
-        private final ExecuteQuery instance = new ExecuteQuery();
+        private final ExecSpecs instance = new ExecSpecs();
 
         public Builder key(final String key) {
             instance.setKey(key);
@@ -48,7 +48,7 @@ public class ExecuteQuery implements Serializable {
             return this;
         }
 
-        public ExecuteQuery build() {
+        public ExecSpecs build() {
             return instance;
         }
     }
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/RemediationQuery.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/RemediationQuery.java
index f70858c3eb..d237c49c9f 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/RemediationQuery.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/RemediationQuery.java
@@ -18,11 +18,11 @@
  */
 package org.apache.syncope.common.rest.api.beans;
 
-public class RemediationQuery extends AbstractQuery {
+public class RemediationQuery extends AbstractTimeframeQuery {
 
     private static final long serialVersionUID = 4000880445378096031L;
 
-    public static class Builder extends AbstractQuery.Builder<RemediationQuery, Builder> {
+    public static class Builder extends AbstractTimeframeQuery.Builder<RemediationQuery, Builder> {
 
         @Override
         protected RemediationQuery newInstance() {
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ExecutableService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ExecutableService.java
index 808aae818f..dc8fb11664 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ExecutableService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ExecutableService.java
@@ -39,9 +39,8 @@ import org.apache.syncope.common.lib.to.JobTO;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.types.JobAction;
 import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.apache.syncope.common.rest.api.beans.ExecDeleteQuery;
 import org.apache.syncope.common.rest.api.beans.ExecQuery;
-import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
+import org.apache.syncope.common.rest.api.beans.ExecSpecs;
 
 public interface ExecutableService extends JAXRSService {
 
@@ -91,7 +90,7 @@ public interface ExecutableService extends JAXRSService {
                     description = "Batch results available, returned as Response entity"))
     @Path("{key}/executions")
     @Produces(RESTHeaders.MULTIPART_MIXED)
-    Response deleteExecutions(@BeanParam ExecDeleteQuery query);
+    Response deleteExecutions(@BeanParam ExecQuery query);
 
     /**
      * Executes the executable matching the given query.
@@ -102,7 +101,7 @@ public interface ExecutableService extends JAXRSService {
     @POST
     @Path("{key}/execute")
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
-    ExecTO execute(@BeanParam ExecuteQuery query);
+    ExecTO execute(@BeanParam ExecSpecs query);
 
     /**
      * Returns job (running or scheduled) for the executable matching the given key.
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractExecutableLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractExecutableLogic.java
index a030cacb75..a6f592f4ff 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractExecutableLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractExecutableLogic.java
@@ -33,14 +33,21 @@ public abstract class AbstractExecutableLogic<T extends EntityTO> extends Abstra
     public abstract ExecTO execute(String key, Date startAt, boolean dryRun);
 
     public abstract Pair<Integer, List<ExecTO>> listExecutions(
-        String key, int page, int size, List<OrderByClause> orderByClauses);
+            String key,
+            Date before,
+            Date after,
+            int page,
+            int size,
+            List<OrderByClause> orderByClauses);
 
     public abstract List<ExecTO> listRecentExecutions(int max);
 
     public abstract ExecTO deleteExecution(String executionKey);
 
     public abstract List<BatchResponseItem> deleteExecutions(
-        String key, Date startedBefore, Date startedAfter, Date endedBefore, Date endedAfter);
+            String key,
+            Date before,
+            Date after);
 
     public abstract JobTO getJob(String key);
 
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
index 09384620bb..228f24753d 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.logic;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
@@ -406,11 +407,13 @@ public class LoggerLogic extends AbstractTransactionalLogic<EntityTO> {
             final String subcategory,
             final List<String> events,
             final AuditElements.Result result,
+            final Date before,
+            final Date after,
             final List<OrderByClause> orderByClauses) {
 
-        int count = loggerDAO.countAuditEntries(entityKey, type, category, subcategory, events, result);
+        int count = loggerDAO.countAuditEntries(entityKey, type, category, subcategory, events, result, before, after);
         List<AuditEntry> matching = loggerDAO.findAuditEntries(
-                entityKey, page, size, type, category, subcategory, events, result, orderByClauses);
+                entityKey, page, size, type, category, subcategory, events, result, before, after, orderByClauses);
         return Pair.of(count, matching);
     }
 
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/RemediationLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/RemediationLogic.java
index 9b593e4884..214240467f 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/RemediationLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/RemediationLogic.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.core.logic;
 
 import java.lang.reflect.Method;
+import java.util.Date;
 import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
@@ -67,13 +68,15 @@ public class RemediationLogic extends AbstractLogic<RemediationTO> {
     @PreAuthorize("hasRole('" + StandardEntitlement.REMEDIATION_LIST + "')")
     @Transactional(readOnly = true)
     public Pair<Integer, List<RemediationTO>> list(
+            final Date before,
+            final Date after,
             final int page,
             final int size,
             final List<OrderByClause> orderByClauses) {
 
-        int count = remediationDAO.count();
+        int count = remediationDAO.count(before, after);
 
-        List<RemediationTO> result = remediationDAO.findAll(page, size, orderByClauses).stream().
+        List<RemediationTO> result = remediationDAO.findAll(before, after, page, size, orderByClauses).stream().
                 map(binder::getRemediationTO).collect(Collectors.toList());
 
         return Pair.of(count, result);
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java
index 250abcec52..417389c9e4 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java
@@ -24,10 +24,12 @@ import java.lang.reflect.Method;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.stream.Collectors;
 import java.util.zip.ZipInputStream;
 import javax.ws.rs.core.Response;
@@ -219,7 +221,7 @@ public class ReportLogic extends AbstractExecutableLogic<ReportTO> {
 
         // streaming SAX handler from a compressed byte array stream
         try (ByteArrayInputStream bais = new ByteArrayInputStream(reportExec.getExecResult());
-                ZipInputStream zis = new ZipInputStream(bais)) {
+             ZipInputStream zis = new ZipInputStream(bais)) {
 
             // a single ZipEntry in the ZipInputStream (see ReportJob)
             zis.getNextEntry();
@@ -300,16 +302,19 @@ public class ReportLogic extends AbstractExecutableLogic<ReportTO> {
     @PreAuthorize("hasRole('" + StandardEntitlement.REPORT_READ + "')")
     @Override
     public Pair<Integer, List<ExecTO>> listExecutions(
-            final String key, final int page, final int size, final List<OrderByClause> orderByClauses) {
+            final String key,
+            final Date before,
+            final Date after,
+            final int page,
+            final int size,
+            final List<OrderByClause> orderByClauses) {
 
-        Report report = reportDAO.find(key);
-        if (report == null) {
-            throw new NotFoundException("Report " + key);
-        }
+        Report report = Optional.ofNullable(reportDAO.find(key)).
+                orElseThrow(() -> new NotFoundException("Report " + key));
 
-        Integer count = reportExecDAO.count(key);
+        Integer count = reportExecDAO.count(report, before, after);
 
-        List<ExecTO> result = reportExecDAO.findAll(report, page, size, orderByClauses).stream().
+        List<ExecTO> result = reportExecDAO.findAll(report, before, after, page, size, orderByClauses).stream().
                 map(reportExec -> binder.getExecTO(reportExec)).collect(Collectors.toList());
 
         return Pair.of(count, result);
@@ -339,16 +344,15 @@ public class ReportLogic extends AbstractExecutableLogic<ReportTO> {
     @Override
     public List<BatchResponseItem> deleteExecutions(
             final String key,
-            final Date startedBefore, final Date startedAfter, final Date endedBefore, final Date endedAfter) {
+            final Date before,
+            final Date after) {
 
-        Report report = reportDAO.find(key);
-        if (report == null) {
-            throw new NotFoundException("Report " + key);
-        }
+        Report report = Optional.ofNullable(reportDAO.find(key)).
+                orElseThrow(() -> new NotFoundException("Report " + key));
 
         List<BatchResponseItem> batchResponseItems = new ArrayList<>();
 
-        reportExecDAO.findAll(report, startedBefore, startedAfter, endedBefore, endedAfter).forEach(exec -> {
+        reportExecDAO.findAll(report, before, after, -1, -1, Collections.emptyList()).forEach(exec -> {
             BatchResponseItem item = new BatchResponseItem();
             item.getHeaders().put(RESTHeaders.RESOURCE_KEY, Arrays.asList(exec.getKey()));
             batchResponseItems.add(item);
@@ -372,8 +376,8 @@ public class ReportLogic extends AbstractExecutableLogic<ReportTO> {
 
         Report report = reportDAO.find(key);
         return report == null
-            ? null
-            : Triple.of(JobType.REPORT, key, binder.buildRefDesc(report));
+                ? null
+                : Triple.of(JobType.REPORT, key, binder.buildRefDesc(report));
     }
 
     @PreAuthorize("hasRole('" + StandardEntitlement.REPORT_LIST + "')")
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
index f43e588800..a844bde5d4 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.logic;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -335,17 +336,22 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
     @PreAuthorize("hasRole('" + StandardEntitlement.TASK_READ + "')")
     @Override
     public Pair<Integer, List<ExecTO>> listExecutions(
-            final String key, final int page, final int size, final List<OrderByClause> orderByClauses) {
+            final String key,
+            final Date before,
+            final Date after,
+            final int page,
+            final int size,
+            final List<OrderByClause> orderByClauses) {
 
         Task task = taskDAO.find(key);
         if (task == null) {
             throw new NotFoundException("Task " + key);
         }
 
-        Integer count = taskExecDAO.count(key);
+        Integer count = taskExecDAO.count(task, before, after);
 
-        List<ExecTO> result = taskExecDAO.findAll(task, page, size, orderByClauses).stream().
-                map(taskExec -> binder.getExecTO(taskExec)).collect(Collectors.toList());
+        List<ExecTO> result = taskExecDAO.findAll(task, before, after, page, size, orderByClauses).stream().
+                map(exec -> binder.getExecTO(exec)).collect(Collectors.toList());
 
         return Pair.of(count, result);
     }
@@ -374,10 +380,8 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
     @Override
     public List<BatchResponseItem> deleteExecutions(
             final String key,
-            final Date startedBefore,
-            final Date startedAfter,
-            final Date endedBefore,
-            final Date endedAfter) {
+            final Date before,
+            final Date after) {
 
         Task task = taskDAO.find(key);
         if (task == null) {
@@ -386,7 +390,7 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
 
         List<BatchResponseItem> batchResponseItems = new ArrayList<>();
 
-        taskExecDAO.findAll(task, startedBefore, startedAfter, endedBefore, endedAfter).forEach(exec -> {
+        taskExecDAO.findAll(task, before, after, -1, -1, Collections.emptyList()).forEach(exec -> {
             BatchResponseItem item = new BatchResponseItem();
             item.getHeaders().put(RESTHeaders.RESOURCE_KEY, Arrays.asList(exec.getKey()));
             batchResponseItems.add(item);
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/LoggerDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/LoggerDAO.java
index a4c355d50f..be56715805 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/LoggerDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/LoggerDAO.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.persistence.api.dao;
 
+import java.util.Date;
 import java.util.List;
 import org.apache.syncope.common.lib.log.AuditEntry;
 import org.apache.syncope.common.lib.types.AuditElements;
@@ -31,6 +32,8 @@ public interface LoggerDAO extends DAO<Logger> {
 
     String AUDIT_MESSAGE_COLUMN = "MESSAGE";
 
+    String AUDIT_ENTRY_EVENT_DATE_COLUMN = "EVENT_DATE";
+
     Logger find(String key);
 
     List<Logger> findAll(LoggerType type);
@@ -47,7 +50,9 @@ public interface LoggerDAO extends DAO<Logger> {
             String category,
             String subcategory,
             List<String> events,
-            AuditElements.Result result);
+            AuditElements.Result result,
+            Date before,
+            Date after);
 
     List<AuditEntry> findAuditEntries(
             String entityKey,
@@ -58,5 +63,7 @@ public interface LoggerDAO extends DAO<Logger> {
             String subcategory,
             List<String> events,
             AuditElements.Result result,
+            Date before,
+            Date after,
             List<OrderByClause> orderBy);
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RemediationDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RemediationDAO.java
index 73216b30cf..ca415665db 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RemediationDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RemediationDAO.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.persistence.api.dao;
 
+import java.util.Date;
 import java.util.List;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
@@ -32,9 +33,14 @@ public interface RemediationDAO extends DAO<Remediation> {
 
     List<Remediation> findByPullTask(PullTask pullTask);
 
-    int count();
+    int count(Date before, Date after);
 
-    List<Remediation> findAll(int page, int itemsPerPage, List<OrderByClause> orderByClauses);
+    List<Remediation> findAll(
+            Date before,
+            Date after,
+            int page,
+            int itemsPerPage,
+            List<OrderByClause> orderByClauses);
 
     Remediation save(Remediation remediation);
 
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ReportExecDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ReportExecDAO.java
index 61c7cfcfed..f662cbc06c 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ReportExecDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ReportExecDAO.java
@@ -34,11 +34,15 @@ public interface ReportExecDAO extends DAO<ReportExec> {
 
     ReportExec findLatestEnded(Report report);
 
-    int count(String reportKey);
-
-    List<ReportExec> findAll(Report report, int page, int itemsPerPage, List<OrderByClause> orderByClauses);
-
-    List<ReportExec> findAll(Report report, Date startedBefore, Date startedAfter, Date endedBefore, Date endedAfter);
+    int count(Report report, Date before, Date after);
+
+    List<ReportExec> findAll(
+            Report report,
+            Date before,
+            Date after,
+            int page,
+            int itemsPerPage,
+            List<OrderByClause> orderByClauses);
 
     ReportExec save(ReportExec execution);
 
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/TaskExecDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/TaskExecDAO.java
index e90cc8d25b..29389b2fd1 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/TaskExecDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/TaskExecDAO.java
@@ -34,12 +34,15 @@ public interface TaskExecDAO extends DAO<TaskExec> {
 
     <T extends Task> TaskExec findLatestEnded(T task);
 
-    int count(String taskKey);
-
-    <T extends Task> List<TaskExec> findAll(T task, int page, int itemsPerPage, List<OrderByClause> orderByClauses);
-
-    <T extends Task> List<TaskExec> findAll(
-            T task, Date startedBefore, Date startedAfter, Date endedBefore, Date endedAfter);
+    int count(Task task, Date before, Date after);
+
+    List<TaskExec> findAll(
+            Task task,
+            Date before,
+            Date after,
+            int page,
+            int itemsPerPage,
+            List<OrderByClause> orderByClauses);
 
     TaskExec save(TaskExec execution);
 
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONLoggerDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONLoggerDAO.java
index bbffaedafa..6b388d1e3a 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONLoggerDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONLoggerDAO.java
@@ -29,16 +29,22 @@ public class MyJPAJSONLoggerDAO extends AbstractJPAJSONLoggerDAO {
 
         @Override
         protected String doBuild(final List<ObjectNode> containers) {
-            query.append('(').append(AUDIT_MESSAGE_COLUMN).append(" -> '$.before' LIKE '%").append(entityKey).
-                    append("%' OR ").append(AUDIT_MESSAGE_COLUMN).append(" -> '$.input' LIKE '%").append(entityKey).
-                    append("%' OR ").append(AUDIT_MESSAGE_COLUMN).append(" -> '$.output' LIKE '%").append(entityKey).
-                    append("%')");
+            if (entityKey != null) {
+                query.append(andIfNeeded()).append('(').
+                        append(AUDIT_MESSAGE_COLUMN).append("->'$.before' LIKE '%").append(entityKey).
+                        append("%' OR ").
+                        append(AUDIT_MESSAGE_COLUMN).append("->'$.input' LIKE '%").append(entityKey).
+                        append("%' OR ").
+                        append(AUDIT_MESSAGE_COLUMN).append("->'$.output' LIKE '%").append(entityKey).
+                        append("%')");
+            }
 
             if (!containers.isEmpty()) {
-                query.append(" AND (").
-                        append(containers.stream().map(container -> "JSON_CONTAINS(" + AUDIT_MESSAGE_COLUMN + ", '"
-                        + POJOHelper.serialize(container).replace("'", "''")
-                        + "')").collect(Collectors.joining(" OR "))).
+                query.append(andIfNeeded()).append('(').
+                        append(containers.stream().
+                                map(container -> "JSON_CONTAINS(" + AUDIT_MESSAGE_COLUMN + ", '"
+                                + POJOHelper.serialize(container).replace("'", "''")
+                                + "')").collect(Collectors.joining(" OR "))).
                         append(')');
             }
 
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONLoggerDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONLoggerDAO.java
index 2eb15ffa8b..8928dd74d0 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONLoggerDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONLoggerDAO.java
@@ -30,16 +30,22 @@ public class PGJPAJSONLoggerDAO extends AbstractJPAJSONLoggerDAO {
 
         @Override
         protected String doBuild(final List<ObjectNode> containers) {
-            query.append('(').append(AUDIT_MESSAGE_COLUMN).append(" ->> 'before' LIKE '%").append(entityKey).
-                    append("%' OR ").append(AUDIT_MESSAGE_COLUMN).append(" ->> 'input' LIKE '%").append(entityKey).
-                    append("%' OR ").append(AUDIT_MESSAGE_COLUMN).append(" ->> 'output' LIKE '%").append(entityKey).
-                    append("%')");
+            if (entityKey != null) {
+                query.append(andIfNeeded()).append('(').
+                        append(AUDIT_MESSAGE_COLUMN).append(" ->> 'before' LIKE '%").append(entityKey).
+                        append("%' OR ").
+                        append(AUDIT_MESSAGE_COLUMN).append(" ->> 'input' LIKE '%").append(entityKey).
+                        append("%' OR ").
+                        append(AUDIT_MESSAGE_COLUMN).append(" ->> 'output' LIKE '%").append(entityKey).
+                        append("%')");
+            }
 
             if (!containers.isEmpty()) {
-                query.append(" AND (").
-                        append(containers.stream().map(container -> AUDIT_MESSAGE_COLUMN + "::jsonb @> '"
-                        + POJOHelper.serialize(container).replace("'", "''")
-                        + "'::jsonb").collect(Collectors.joining(" OR "))).
+                query.append(andIfNeeded()).append('(').
+                        append(containers.stream().
+                                map(container -> AUDIT_MESSAGE_COLUMN + "::jsonb @> '"
+                                + POJOHelper.serialize(container).replace("'", "''")
+                                + "'::jsonb").collect(Collectors.joining(" OR "))).
                         append(')');
             }
 
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPALoggerDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPALoggerDAO.java
index 1b6f0c0ff6..8da2346c47 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPALoggerDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPALoggerDAO.java
@@ -20,6 +20,8 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.sql.Clob;
 import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 import java.util.Objects;
 import java.util.stream.Collectors;
@@ -47,6 +49,11 @@ public class JPALoggerDAO extends AbstractDAO<Logger> implements LoggerDAO {
             return query.length() == 0 ? " " : " AND ";
         }
 
+        protected int setParameter(final List<Object> parameters, final Object parameter) {
+            parameters.add(parameter);
+            return parameters.size();
+        }
+
         protected MessageCriteriaBuilder entityKey(final String entityKey) {
             if (entityKey != null) {
                 query.append(andIfNeeded()).append(AUDIT_MESSAGE_COLUMN).
@@ -98,6 +105,22 @@ public class JPALoggerDAO extends AbstractDAO<Logger> implements LoggerDAO {
             return this;
         }
 
+        public MessageCriteriaBuilder before(final Date before, final List<Object> parameters) {
+            if (before != null) {
+                query.append(andIfNeeded()).append(AUDIT_ENTRY_EVENT_DATE_COLUMN).
+                        append(" <= ?").append(setParameter(parameters, before));
+            }
+            return this;
+        }
+
+        public MessageCriteriaBuilder after(final Date after, final List<Object> parameters) {
+            if (after != null) {
+                query.append(andIfNeeded()).append(AUDIT_ENTRY_EVENT_DATE_COLUMN).
+                        append(" >= ?").append(setParameter(parameters, after));
+            }
+            return this;
+        }
+
         public String build() {
             return query.toString();
         }
@@ -144,6 +167,16 @@ public class JPALoggerDAO extends AbstractDAO<Logger> implements LoggerDAO {
         return new MessageCriteriaBuilder().entityKey(entityKey);
     }
 
+    protected void fillWithParameters(final Query query, final List<Object> parameters) {
+        for (int i = 0; i < parameters.size(); i++) {
+            if (parameters.get(i) instanceof Boolean) {
+                query.setParameter(i + 1, ((Boolean) parameters.get(i)) ? 1 : 0);
+            } else {
+                query.setParameter(i + 1, parameters.get(i));
+            }
+        }
+    }
+
     @Override
     public int countAuditEntries(
             final String entityKey,
@@ -151,8 +184,11 @@ public class JPALoggerDAO extends AbstractDAO<Logger> implements LoggerDAO {
             final String category,
             final String subcategory,
             final List<String> events,
-            final AuditElements.Result result) {
+            final AuditElements.Result result,
+            final Date before,
+            final Date after) {
 
+        List<Object> parameters = new ArrayList<>();
         String queryString = "SELECT COUNT(0)"
                 + " FROM " + AUDIT_TABLE
                 + " WHERE " + messageCriteriaBuilder(entityKey).
@@ -161,10 +197,13 @@ public class JPALoggerDAO extends AbstractDAO<Logger> implements LoggerDAO {
                         subcategory(subcategory).
                         result(result).
                         events(events).
+                        before(before, parameters).
+                        after(after, parameters).
                         build();
-        Query countQuery = entityManager().createNativeQuery(queryString);
+        Query query = entityManager().createNativeQuery(queryString);
+        fillWithParameters(query, parameters);
 
-        return ((Number) countQuery.getSingleResult()).intValue();
+        return ((Number) query.getSingleResult()).intValue();
     }
 
     protected String select() {
@@ -182,8 +221,11 @@ public class JPALoggerDAO extends AbstractDAO<Logger> implements LoggerDAO {
             final String subcategory,
             final List<String> events,
             final AuditElements.Result result,
+            final Date before,
+            final Date after,
             final List<OrderByClause> orderBy) {
 
+        List<Object> parameters = new ArrayList<>();
         String queryString = "SELECT " + select()
                 + " FROM " + AUDIT_TABLE
                 + " WHERE " + messageCriteriaBuilder(entityKey).
@@ -192,6 +234,8 @@ public class JPALoggerDAO extends AbstractDAO<Logger> implements LoggerDAO {
                         subcategory(subcategory).
                         result(result).
                         events(events).
+                        before(before, parameters).
+                        after(after, parameters).
                         build();
         if (!orderBy.isEmpty()) {
             queryString += " ORDER BY " + orderBy.stream().
@@ -200,6 +244,7 @@ public class JPALoggerDAO extends AbstractDAO<Logger> implements LoggerDAO {
         }
 
         Query query = entityManager().createNativeQuery(queryString);
+        fillWithParameters(query, parameters);
         query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
         if (itemsPerPage >= 0) {
             query.setMaxResults(itemsPerPage);
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARemediationDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARemediationDAO.java
index f8aefa169b..b1ca843bd7 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARemediationDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARemediationDAO.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.lang.reflect.Field;
+import java.util.Date;
 import java.util.List;
 import javax.persistence.Query;
 import javax.persistence.TypedQuery;
@@ -59,20 +60,47 @@ public class JPARemediationDAO extends AbstractDAO<Remediation> implements Remed
         return query.getResultList();
     }
 
+    protected StringBuilder query(
+            final StringBuilder select,
+            final Date before,
+            final Date after) {
+
+        StringBuilder query = select.
+                append(JPARemediation.class.getSimpleName()).
+                append(" e WHERE 1=1 ");
+        if (before != null) {
+            query.append("AND e.instant <= :before ");
+        }
+        if (after != null) {
+            query.append("AND e.instant >= :after ");
+        }
+        return query;
+    }
+
     @Override
-    public int count() {
-        Query query = entityManager().createNativeQuery("SELECT COUNT(id) FROM " + JPARemediation.TABLE);
+    public int count(final Date before, final Date after) {
+        StringBuilder queryString = query(new StringBuilder("SELECT COUNT(e) FROM "), before, after);
+
+        Query query = entityManager().createQuery(queryString.toString());
+        if (before != null) {
+            query.setParameter("before", before);
+        }
+        if (after != null) {
+            query.setParameter("after", after);
+        }
+
         return ((Number) query.getSingleResult()).intValue();
     }
 
     @Override
     public List<Remediation> findAll(
+            final Date before,
+            final Date after,
             final int page,
             final int itemsPerPage,
             final List<OrderByClause> orderByClauses) {
 
-        StringBuilder queryString = new StringBuilder(
-                "SELECT e FROM " + JPARemediation.class.getSimpleName() + " e");
+        StringBuilder queryString = query(new StringBuilder("SELECT e FROM "), before, after);
 
         if (!orderByClauses.isEmpty()) {
             queryString.append(" ORDER BY ");
@@ -104,7 +132,12 @@ public class JPARemediationDAO extends AbstractDAO<Remediation> implements Remed
         }
 
         TypedQuery<Remediation> query = entityManager().createQuery(queryString.toString(), Remediation.class);
-
+        if (before != null) {
+            query.setParameter("before", before);
+        }
+        if (after != null) {
+            query.setParameter("after", after);
+        }
         query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
 
         if (itemsPerPage > 0) {
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
index e26ce3127a..d945ac3f19 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
@@ -49,7 +49,7 @@ public class JPAReportExecDAO extends AbstractDAO<ReportExec> implements ReportE
         return query.getResultList();
     }
 
-    private ReportExec findLatest(final Report report, final String field) {
+    protected ReportExec findLatest(final Report report, final String field) {
         TypedQuery<ReportExec> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAReportExec.class.getSimpleName() + " e "
                 + "WHERE e.report=:report ORDER BY e." + field + " DESC", ReportExec.class);
@@ -72,16 +72,44 @@ public class JPAReportExecDAO extends AbstractDAO<ReportExec> implements ReportE
         return findLatest(report, "end");
     }
 
+    protected StringBuilder query(
+            final StringBuilder select,
+            final Date before,
+            final Date after) {
+
+        StringBuilder query = select.
+                append(JPAReportExec.class.getSimpleName()).
+                append(" e WHERE e.report=:report ");
+        if (before != null) {
+            query.append("AND e.start <= :before ");
+        }
+        if (after != null) {
+            query.append("AND e.start >= :after ");
+        }
+        return query;
+    }
+
     @Override
-    public int count(final String reportKey) {
-        Query countQuery = entityManager().createNativeQuery(
-                "SELECT COUNT(e.id) FROM " + JPAReportExec.TABLE + " e WHERE e.report_id=?1");
-        countQuery.setParameter(1, reportKey);
+    public int count(
+            final Report report,
+            final Date before,
+            final Date after) {
+
+        StringBuilder queryString = query(new StringBuilder("SELECT COUNT(e) FROM "), before, after);
 
-        return ((Number) countQuery.getSingleResult()).intValue();
+        Query query = entityManager().createQuery(queryString.toString());
+        query.setParameter("report", report);
+        if (before != null) {
+            query.setParameter("before", before);
+        }
+        if (after != null) {
+            query.setParameter("after", after);
+        }
+
+        return ((Number) query.getSingleResult()).intValue();
     }
 
-    private String toOrderByStatement(final List<OrderByClause> orderByClauses) {
+    protected String toOrderByStatement(final List<OrderByClause> orderByClauses) {
         StringBuilder statement = new StringBuilder();
 
         for (OrderByClause clause : orderByClauses) {
@@ -92,23 +120,33 @@ public class JPAReportExecDAO extends AbstractDAO<ReportExec> implements ReportE
         }
 
         if (statement.length() == 0) {
-            statement.append("ORDER BY e.id DESC");
+            statement.append(" ORDER BY e.id DESC");
         } else {
-            statement.insert(0, "ORDER BY ");
+            statement.insert(0, " ORDER BY ");
         }
         return statement.toString();
     }
 
     @Override
-    public List<ReportExec> findAll(final Report report,
-            final int page, final int itemsPerPage, final List<OrderByClause> orderByClauses) {
+    public List<ReportExec> findAll(
+            final Report report,
+            final Date before,
+            final Date after,
+            final int page,
+            final int itemsPerPage,
+            final List<OrderByClause> orderByClauses) {
 
-        String queryString =
-                "SELECT e FROM " + JPAReportExec.class.getSimpleName() + " e WHERE e.report=:report "
-                + toOrderByStatement(orderByClauses);
+        StringBuilder queryString = query(new StringBuilder("SELECT e FROM "), before, after).
+                append(toOrderByStatement(orderByClauses));
 
-        TypedQuery<ReportExec> query = entityManager().createQuery(queryString, ReportExec.class);
+        TypedQuery<ReportExec> query = entityManager().createQuery(queryString.toString(), ReportExec.class);
         query.setParameter("report", report);
+        if (before != null) {
+            query.setParameter("before", before);
+        }
+        if (after != null) {
+            query.setParameter("after", after);
+        }
 
         // page starts from 1, while setFirtResult() starts from 0
         query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
@@ -120,45 +158,6 @@ public class JPAReportExecDAO extends AbstractDAO<ReportExec> implements ReportE
         return query.getResultList();
     }
 
-    @Override
-    public List<ReportExec> findAll(
-            final Report report,
-            final Date startedBefore, final Date startedAfter, final Date endedBefore, final Date endedAfter) {
-
-        StringBuilder queryString = new StringBuilder("SELECT e FROM ").append(JPAReportExec.class.getSimpleName()).
-                append(" e WHERE e.report=:report ");
-
-        if (startedBefore != null) {
-            queryString.append(" AND e.start < :startedBefore");
-        }
-        if (startedAfter != null) {
-            queryString.append(" AND e.start > :startedAfter");
-        }
-        if (endedBefore != null) {
-            queryString.append(" AND e.end < :endedBefore");
-        }
-        if (endedAfter != null) {
-            queryString.append(" AND e.end > :endedAfter");
-        }
-
-        TypedQuery<ReportExec> query = entityManager().createQuery(queryString.toString(), ReportExec.class);
-        query.setParameter("report", report);
-        if (startedBefore != null) {
-            query.setParameter("startedBefore", startedBefore);
-        }
-        if (startedAfter != null) {
-            query.setParameter("startedAfter", startedAfter);
-        }
-        if (endedBefore != null) {
-            query.setParameter("endedBefore", endedBefore);
-        }
-        if (endedAfter != null) {
-            query.setParameter("endedAfter", endedAfter);
-        }
-
-        return query.getResultList();
-    }
-
     @Transactional(rollbackFor = Throwable.class)
     @Override
     public ReportExec save(final ReportExec execution) {
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
index e694dfb982..42ccf2c7e5 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
@@ -77,52 +77,43 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec> implements TaskExecDAO
         return findLatest(task, "end");
     }
 
-    @Override
-    public <T extends Task> List<TaskExec> findAll(
-            final T task,
-            final Date startedBefore, final Date startedAfter, final Date endedBefore, final Date endedAfter) {
-
-        StringBuilder queryString = new StringBuilder("SELECT e FROM ").append(JPATaskExec.class.getSimpleName()).
+    protected StringBuilder query(
+            final StringBuilder select,
+            final Task task,
+            final Date before,
+            final Date after) {
+
+        StringBuilder query = select.
+                append(JPATaskExec.class.getSimpleName()).
                 append(" e WHERE e.task=:task ");
-
-        if (startedBefore != null) {
-            queryString.append(" AND e.start < :startedBefore");
-        }
-        if (startedAfter != null) {
-            queryString.append(" AND e.start > :startedAfter");
-        }
-        if (endedBefore != null) {
-            queryString.append(" AND e.end < :endedBefore");
-        }
-        if (endedAfter != null) {
-            queryString.append(" AND e.end > :endedAfter");
-        }
-
-        TypedQuery<TaskExec> query = entityManager().createQuery(queryString.toString(), TaskExec.class);
-        query.setParameter("task", task);
-        if (startedBefore != null) {
-            query.setParameter("startedBefore", startedBefore);
-        }
-        if (startedAfter != null) {
-            query.setParameter("startedAfter", startedAfter);
-        }
-        if (endedBefore != null) {
-            query.setParameter("endedBefore", endedBefore);
+        if (before != null) {
+            query.append("AND e.start <= :before ");
         }
-        if (endedAfter != null) {
-            query.setParameter("endedAfter", endedAfter);
+        if (after != null) {
+            query.append("AND e.start >= :after ");
         }
 
-        return query.getResultList();
+        return query;
     }
 
     @Override
-    public int count(final String taskKey) {
-        Query countQuery = entityManager().createNativeQuery(
-                "SELECT COUNT(e.id) FROM " + JPATaskExec.TABLE + " e WHERE e.task_id=?1");
-        countQuery.setParameter(1, taskKey);
+    public int count(
+            final Task task,
+            final Date before,
+            final Date after) {
+
+        StringBuilder queryString = query(new StringBuilder("SELECT COUNT(e) FROM "), task, before, after);
+
+        Query query = entityManager().createQuery(queryString.toString());
+        query.setParameter("task", task);
+        if (before != null) {
+            query.setParameter("before", before);
+        }
+        if (after != null) {
+            query.setParameter("after", after);
+        }
 
-        return ((Number) countQuery.getSingleResult()).intValue();
+        return ((Number) query.getSingleResult()).intValue();
     }
 
     private String toOrderByStatement(final List<OrderByClause> orderByClauses) {
@@ -136,23 +127,33 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec> implements TaskExecDAO
         });
 
         if (statement.length() == 0) {
-            statement.append("ORDER BY e.id DESC");
+            statement.append(" ORDER BY e.id DESC");
         } else {
-            statement.insert(0, "ORDER BY ");
+            statement.insert(0, " ORDER BY ");
         }
         return statement.toString();
     }
 
     @Override
-    public <T extends Task> List<TaskExec> findAll(
-            final T task, final int page, final int itemsPerPage, final List<OrderByClause> orderByClauses) {
-
-        String queryString =
-                "SELECT e FROM " + JPATaskExec.class.getSimpleName() + " e WHERE e.task=:task "
-                + toOrderByStatement(orderByClauses);
-
-        TypedQuery<TaskExec> query = entityManager().createQuery(queryString, TaskExec.class);
+    public List<TaskExec> findAll(
+            final Task task,
+            final Date before,
+            final Date after,
+            final int page,
+            final int itemsPerPage,
+            final List<OrderByClause> orderByClauses) {
+
+        StringBuilder queryString = query(new StringBuilder("SELECT e FROM "), task, before, after).
+                append(toOrderByStatement(orderByClauses));
+
+        Query query = entityManager().createQuery(queryString.toString());
         query.setParameter("task", task);
+        if (before != null) {
+            query.setParameter("before", before);
+        }
+        if (after != null) {
+            query.setParameter("after", after);
+        }
 
         // page starts from 1, while setFirtResult() starts from 0
         query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RemediationTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RemediationTest.java
index 15e3e5baae..3a8261f438 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RemediationTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RemediationTest.java
@@ -55,7 +55,7 @@ public class RemediationTest extends AbstractTest {
 
     @Test
     public void findAll() {
-        List<Remediation> remediations = remediationDAO.findAll(1, 1, Collections.emptyList());
+        List<Remediation> remediations = remediationDAO.findAll(null, null, 1, 1, Collections.emptyList());
         assertTrue(remediations.isEmpty());
     }
 
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java
index af257f5112..fad0702357 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java
@@ -22,6 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 import java.util.Calendar;
+import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import org.apache.syncope.common.lib.types.ExecStatus;
@@ -52,7 +53,7 @@ public class TaskExecTest extends AbstractTest {
         calendar.clear();
         calendar.set(2015, 11, 18, 0, 0, 0);
 
-        List<TaskExec> execs = taskExecDAO.findAll(task, calendar.getTime(), null, null, null);
+        List<TaskExec> execs = taskExecDAO.findAll(task, calendar.getTime(), null, -1, -1, Collections.emptyList());
         assertNotNull(execs);
         assertEquals(1, execs.size());
     }
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractExecutableService.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractExecutableService.java
index 10936bfbcb..a42b1df757 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractExecutableService.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractExecutableService.java
@@ -28,9 +28,8 @@ import org.apache.syncope.common.lib.types.JobAction;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.batch.BatchPayloadGenerator;
 import org.apache.syncope.common.rest.api.batch.BatchResponseItem;
-import org.apache.syncope.common.rest.api.beans.ExecDeleteQuery;
 import org.apache.syncope.common.rest.api.beans.ExecQuery;
-import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
+import org.apache.syncope.common.rest.api.beans.ExecSpecs;
 import org.apache.syncope.common.rest.api.service.ExecutableService;
 import org.apache.syncope.common.rest.api.service.JAXRSService;
 import org.apache.syncope.core.logic.AbstractExecutableLogic;
@@ -44,6 +43,8 @@ public abstract class AbstractExecutableService extends AbstractServiceImpl impl
     public PagedResult<ExecTO> listExecutions(final ExecQuery query) {
         Pair<Integer, List<ExecTO>> result = getExecutableLogic().listExecutions(
                 query.getKey(),
+                query.getBefore(),
+                query.getAfter(),
                 query.getPage(),
                 query.getSize(),
                 getOrderByClauses(query.getOrderBy()));
@@ -61,13 +62,11 @@ public abstract class AbstractExecutableService extends AbstractServiceImpl impl
     }
 
     @Override
-    public Response deleteExecutions(final ExecDeleteQuery query) {
+    public Response deleteExecutions(final ExecQuery query) {
         List<BatchResponseItem> batchResponseItems = getExecutableLogic().deleteExecutions(
                 query.getKey(),
-                query.getStartedBefore(),
-                query.getStartedAfter(),
-                query.getEndedBefore(),
-                query.getEndedAfter());
+                query.getBefore(),
+                query.getAfter());
 
         String boundary = "deleteExecutions_" + SecureRandomUtils.generateRandomUUID().toString();
         return Response.ok(BatchPayloadGenerator.generate(
@@ -77,7 +76,7 @@ public abstract class AbstractExecutableService extends AbstractServiceImpl impl
     }
 
     @Override
-    public ExecTO execute(final ExecuteQuery query) {
+    public ExecTO execute(final ExecSpecs query) {
         return getExecutableLogic().execute(query.getKey(), query.getStartAt(), query.getDryRun());
     }
 
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/LoggerServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/LoggerServiceImpl.java
index b8ab5b4ac7..5fffd67039 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/LoggerServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/LoggerServiceImpl.java
@@ -138,6 +138,8 @@ public class LoggerServiceImpl extends AbstractServiceImpl implements LoggerServ
                 auditQuery.getSubcategory(),
                 auditQuery.getEvents(),
                 auditQuery.getResult(),
+                auditQuery.getBefore(),
+                auditQuery.getAfter(),
                 getOrderByClauses(auditQuery.getOrderBy()));
 
         return buildPagedResult(result.getRight(), auditQuery.getPage(), auditQuery.getSize(), result.getLeft());
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RemediationServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RemediationServiceImpl.java
index b6ba6e673a..ba4b00dda7 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RemediationServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RemediationServiceImpl.java
@@ -56,7 +56,11 @@ public class RemediationServiceImpl extends AbstractServiceImpl implements Remed
     @Override
     public PagedResult<RemediationTO> list(final RemediationQuery query) {
         Pair<Integer, List<RemediationTO>> result = logic.list(
-                query.getPage(), query.getSize(), getOrderByClauses(query.getOrderBy()));
+                query.getBefore(),
+                query.getAfter(),
+                query.getPage(),
+                query.getSize(),
+                getOrderByClauses(query.getOrderBy()));
         return buildPagedResult(result.getRight(), query.getPage(), query.getSize(), result.getLeft());
     }
 
diff --git a/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchLoggerDAO.java b/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchLoggerDAO.java
index 78be158a96..2e100d446f 100644
--- a/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchLoggerDAO.java
+++ b/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchLoggerDAO.java
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 import java.util.Objects;
 import java.util.stream.Collectors;
@@ -63,7 +64,9 @@ public class ElasticsearchLoggerDAO extends JPALoggerDAO {
             final String category,
             final String subcategory,
             final List<String> events,
-            final AuditElements.Result result) {
+            final AuditElements.Result result,
+            final Date before,
+            final Date after) {
 
         List<QueryBuilder> queryBuilders = new ArrayList<>();
 
@@ -101,6 +104,14 @@ public class ElasticsearchLoggerDAO extends JPALoggerDAO {
             queryBuilders.add(QueryBuilders.termQuery("message.logger.result", result.name()));
         }
 
+        if (before != null) {
+            queryBuilders.add(QueryBuilders.rangeQuery("instant").lte(before.getTime()));
+        }
+
+        if (after != null) {
+            queryBuilders.add(QueryBuilders.rangeQuery("instant").gte(after.getTime()));
+        }
+
         BoolQueryBuilder bool = QueryBuilders.boolQuery();
         queryBuilders.forEach(bool::must);
         return bool;
@@ -113,11 +124,13 @@ public class ElasticsearchLoggerDAO extends JPALoggerDAO {
             final String category,
             final String subcategory,
             final List<String> events,
-            final AuditElements.Result result) {
+            final AuditElements.Result result,
+            final Date before,
+            final Date after) {
 
         CountRequest request = new CountRequest(
                 ElasticsearchUtils.getAuditIndex(AuthContextUtils.getDomain())).
-                query(getQueryBuilder(entityKey, type, category, subcategory, events, result));
+                query(getQueryBuilder(entityKey, type, category, subcategory, events, result, before, after));
         try {
             return (int) client.count(request, RequestOptions.DEFAULT).getCount();
         } catch (IOException e) {
@@ -147,10 +160,12 @@ public class ElasticsearchLoggerDAO extends JPALoggerDAO {
             final String subcategory,
             final List<String> events,
             final AuditElements.Result result,
+            final Date before,
+            final Date after,
             final List<OrderByClause> orderBy) {
 
         SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().
-                query(getQueryBuilder(entityKey, type, category, subcategory, events, result)).
+                query(getQueryBuilder(entityKey, type, category, subcategory, events, result, before, after)).
                 from(itemsPerPage * (page <= 0 ? 0 : page - 1)).
                 size(itemsPerPage < 0 ? elasticsearchUtils.getIndexMaxResultWindow() : itemsPerPage);
         sortBuilders(orderBy).forEach(sourceBuilder::sort);
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java
index b9f0f4b240..43a742ad82 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java
@@ -41,7 +41,7 @@ import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.rest.api.beans.AnyQuery;
-import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
+import org.apache.syncope.common.rest.api.beans.ExecSpecs;
 import org.apache.syncope.common.rest.api.beans.TaskQuery;
 import org.apache.syncope.common.rest.api.service.TaskService;
 import org.apache.syncope.core.provisioning.java.job.notification.NotificationJob;
@@ -127,7 +127,7 @@ public abstract class AbstractTaskITCase extends AbstractITCase {
 
         AtomicReference<TaskTO> taskTO = new AtomicReference<>(taskService.read(type, taskKey, true));
         int preSyncSize = taskTO.get().getExecutions().size();
-        ExecTO execution = taskService.execute(new ExecuteQuery.Builder().key(taskKey).dryRun(dryRun).build());
+        ExecTO execution = taskService.execute(new ExecSpecs.Builder().key(taskKey).dryRun(dryRun).build());
         assertEquals(initialStatus, execution.getStatus());
 
         await().atMost(maxWaitSeconds, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> {
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuditITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuditITCase.java
index edcf9d7586..e3c0654ed0 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuditITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuditITCase.java
@@ -25,10 +25,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotEquals;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
+import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.time.DateUtils;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.log.AuditEntry;
@@ -84,8 +86,13 @@ public class AuditITCase extends AbstractITCase {
         UserTO userTO = createUser(UserITCase.getUniqueSampleTO("audit@syncope.org")).getEntity();
         assertNotNull(userTO.getKey());
 
-        AuditQuery query = new AuditQuery.Builder().entityKey(userTO.getKey()).orderBy("event_date desc").
-                page(1).size(1).build();
+        AuditQuery query = new AuditQuery.Builder().
+                entityKey(userTO.getKey()).
+                before(DateUtils.addSeconds(new Date(), 30)).
+                page(1).
+                size(1).
+                orderBy("event_date desc").
+                build();
         AuditEntry entry = queryWithFailure(query, MAX_WAIT_SECONDS);
         assertNotNull(entry);
         userService.delete(userTO.getKey());
@@ -105,6 +112,7 @@ public class AuditITCase extends AbstractITCase {
                 category(UserLogic.class.getSimpleName()).
                 event("create").
                 result(AuditElements.Result.SUCCESS).
+                after(DateUtils.addSeconds(new Date(), -30)).
                 build();
         AuditEntry entry = queryWithFailure(query, MAX_WAIT_SECONDS);
         assertNotNull(entry);
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java
index 4c1d0b4593..a67dd9da85 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java
@@ -41,7 +41,7 @@ import org.apache.syncope.common.lib.types.ImplementationType;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.lib.types.TraceLevel;
 import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
+import org.apache.syncope.common.rest.api.beans.ExecSpecs;
 import org.apache.syncope.common.rest.api.beans.TaskQuery;
 import org.apache.syncope.common.rest.api.service.NotificationService;
 import org.apache.syncope.core.provisioning.java.job.notification.NotificationJob;
@@ -186,7 +186,7 @@ public class NotificationTaskITCase extends AbstractNotificationTaskITCase {
         assertNotNull(taskTO.getNotification());
         assertTrue(taskTO.getExecutions().isEmpty());
 
-        taskService.execute(new ExecuteQuery.Builder().key(taskTO.getKey()).build());
+        taskService.execute(new ExecSpecs.Builder().key(taskTO.getKey()).build());
 
         try {
             Thread.sleep(5);
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java
index f3b7e66e49..1325d511e9 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java
@@ -33,6 +33,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Collections;
+import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Optional;
@@ -47,6 +48,7 @@ import javax.ws.rs.core.GenericType;
 import javax.xml.ws.WebServiceException;
 import org.apache.commons.lang3.SerializationUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.DateUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.patch.AttrPatch;
@@ -83,7 +85,7 @@ import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
+import org.apache.syncope.common.rest.api.beans.ExecSpecs;
 import org.apache.syncope.common.rest.api.beans.ExecQuery;
 import org.apache.syncope.common.rest.api.beans.TaskQuery;
 import org.apache.syncope.common.rest.api.service.TaskService;
@@ -357,9 +359,9 @@ public class PropagationTaskITCase extends AbstractTaskITCase {
     @Test
     public void issueSYNCOPE741() {
         for (int i = 0; i < 3; i++) {
-            taskService.execute(new ExecuteQuery.Builder().
+            taskService.execute(new ExecSpecs.Builder().
                     key("1e697572-b896-484c-ae7f-0c8f63fcbc6c").build());
-            taskService.execute(new ExecuteQuery.Builder().
+            taskService.execute(new ExecSpecs.Builder().
                     key("316285cc-ae52-4ea2-a33b-7355e189ac3f").build());
         }
         try {
@@ -395,8 +397,9 @@ public class PropagationTaskITCase extends AbstractTaskITCase {
         assertFalse(task.getExecutions().isEmpty());
 
         // check list executions
-        PagedResult<ExecTO> execs = taskService.listExecutions(new ExecQuery.Builder().key(
-                "1e697572-b896-484c-ae7f-0c8f63fcbc6c").
+        PagedResult<ExecTO> execs = taskService.listExecutions(new ExecQuery.Builder().
+                key("1e697572-b896-484c-ae7f-0c8f63fcbc6c").
+                before(DateUtils.addSeconds(new Date(), 30)).
                 page(1).size(2).build());
         assertTrue(execs.getTotalCount() >= execs.getResult().size());
     }
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
index ef431aed48..8f3ed2391a 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
@@ -53,6 +53,7 @@ import javax.ws.rs.core.Response;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.SerializationUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.DateUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.commons.lang3.tuple.Triple;
 import org.apache.syncope.client.lib.SyncopeClient;
@@ -856,7 +857,8 @@ public class PullTaskITCase extends AbstractTaskITCase {
                 assertEquals(ClientExceptionType.Reconciliation, sce.getType());
             }
             Optional<RemediationTO> remediation = remediationService.list(
-                    new RemediationQuery.Builder().page(1).size(1000).build()).getResult().stream().
+                    new RemediationQuery.Builder().after(DateUtils.addSeconds(new Date(), -30)).
+                            page(1).size(1000).build()).getResult().stream().
                     filter(r -> "uid=pullFromLDAP,ou=People,o=isp".equalsIgnoreCase(r.getRemoteName())).
                     findFirst();
             assertTrue(remediation.isPresent());
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java
index 62bd2d6530..9ae1a65f39 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java
@@ -54,8 +54,8 @@ import org.apache.syncope.common.lib.types.ReportExecExportFormat;
 import org.apache.syncope.common.lib.types.ReportExecStatus;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.batch.BatchResponseItem;
-import org.apache.syncope.common.rest.api.beans.ExecDeleteQuery;
-import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
+import org.apache.syncope.common.rest.api.beans.ExecSpecs;
+import org.apache.syncope.common.rest.api.beans.ExecQuery;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.fit.AbstractITCase;
 import org.junit.jupiter.api.Test;
@@ -65,7 +65,7 @@ public class ReportITCase extends AbstractITCase {
     protected static String execReport(final String reportKey) {
         AtomicReference<ReportTO> reportTO = new AtomicReference<>(reportService.read(reportKey));
         int preExecSize = reportTO.get().getExecutions().size();
-        reportService.execute(new ExecuteQuery.Builder().key(reportKey).build());
+        reportService.execute(new ExecSpecs.Builder().key(reportKey).build());
 
         await().atMost(MAX_WAIT_SECONDS, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> {
             try {
@@ -290,7 +290,7 @@ public class ReportITCase extends AbstractITCase {
         Date end = new Date();
 
         Response response = reportService.deleteExecutions(
-                new ExecDeleteQuery.Builder().key(reportTO.getKey()).startedAfter(start).endedBefore(end).build());
+                new ExecQuery.Builder().key(reportTO.getKey()).after(start).before(end).build());
         List<BatchResponseItem> batchResponseItems = parseBatchResponse(response);
         assertEquals(1, batchResponseItems.size());
         assertEquals(execKey, batchResponseItems.get(0).getHeaders().get(RESTHeaders.RESOURCE_KEY).get(0));
@@ -345,7 +345,7 @@ public class ReportITCase extends AbstractITCase {
         reportTO = createReport(reportTO);
         assertNotNull(reportTO);
 
-        ExecTO execution = reportService.execute(new ExecuteQuery.Builder().key(reportTO.getKey()).build());
+        ExecTO execution = reportService.execute(new ExecSpecs.Builder().key(reportTO.getKey()).build());
         assertNotNull(execution);
 
         int maxit = MAX_WAIT_SECONDS;
@@ -374,7 +374,7 @@ public class ReportITCase extends AbstractITCase {
 
         // Execute (multiple requests)
         for (int i = 0; i < 10; i++) {
-            assertNotNull(reportService.execute(new ExecuteQuery.Builder().key(reportKey).build()));
+            assertNotNull(reportService.execute(new ExecSpecs.Builder().key(reportKey).build()));
         }
 
         // Wait for one execution
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java
index 94ca3df933..56948646ed 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java
@@ -46,7 +46,7 @@ import org.apache.syncope.common.lib.to.TaskTO;
 import org.apache.syncope.common.lib.types.ImplementationType;
 import org.apache.syncope.common.lib.types.JobAction;
 import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
+import org.apache.syncope.common.rest.api.beans.ExecSpecs;
 import org.apache.syncope.common.rest.api.beans.ExecQuery;
 import org.apache.syncope.common.rest.api.beans.TaskQuery;
 import org.apache.syncope.common.rest.api.service.TaskService;
@@ -111,7 +111,7 @@ public class SchedTaskITCase extends AbstractTaskITCase {
 
         AtomicReference<TaskTO> taskTO = new AtomicReference<>(task);
         int preSyncSize = taskTO.get().getExecutions().size();
-        taskService.execute(new ExecuteQuery.Builder().key(task.getKey()).startAt(later).build());
+        taskService.execute(new ExecSpecs.Builder().key(task.getKey()).startAt(later).build());
 
         await().atMost(MAX_WAIT_SECONDS, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> {
             try {