blob: 9eb2f3d7e6c5107fff245889e98bc509127172b1 [file] [log] [blame]
/*
* 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.drill.exec.store.http;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import org.apache.commons.lang3.StringUtils;
import org.apache.drill.common.PlanStringBuilder;
import org.apache.drill.common.exceptions.UserException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Objects;
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
@JsonDeserialize(builder = HttpPaginatorConfig.HttpPaginatorConfigBuilder.class)
public class HttpPaginatorConfig {
private static final Logger logger = LoggerFactory.getLogger(HttpPaginatorConfig.class);
// For Offset Pagination
@JsonProperty
private final String limitParam;
@JsonProperty
private final String offsetParam;
// For Page Pagination
@JsonProperty
private final String pageParam;
@JsonProperty
private final String pageSizeParam;
@JsonProperty
private final int pageSize;
@JsonProperty
private final int maxRecords;
@JsonProperty
private final String method;
// For index/keyset pagination
@JsonProperty
private final String hasMoreParam;
@JsonProperty
private final String indexParam;
@JsonProperty
private final String nextPageParam;
public HttpPaginatorConfig(HttpPaginatorConfigBuilder builder) {
this.limitParam = builder.limitParam;
this.offsetParam = builder.offsetParam;
this.pageParam = builder.pageParam;
this.pageSizeParam = builder.pageSizeParam;
this.pageSize = builder.pageSize;
this.maxRecords = builder.maxRecords;
this.hasMoreParam = builder.hasMoreParam;
this.indexParam = builder.indexParam;
this.nextPageParam = builder.nextPageParam;
this.method = StringUtils.isEmpty(builder.method)
? PaginatorMethod.OFFSET.toString() : builder.method.trim().toUpperCase();
PaginatorMethod paginatorMethod = PaginatorMethod.valueOf(this.method);
/*
* For pagination to function key fields must be defined. This block validates the required fields for
* each type of paginator.
*/
switch (paginatorMethod) {
case OFFSET:
if (StringUtils.isEmpty(this.limitParam) || StringUtils.isEmpty(this.offsetParam)) {
throw UserException
.validationError()
.message("Invalid paginator configuration. For OFFSET pagination, limitField and offsetField must be defined.")
.build(logger);
} else if (this.pageSize <= 0) {
throw UserException
.validationError()
.message("Invalid paginator configuration. For OFFSET pagination, maxPageSize must be defined and greater than zero.")
.build(logger);
}
break;
case PAGE:
if (StringUtils.isEmpty(this.pageParam) || StringUtils.isEmpty(this.pageSizeParam)) {
throw UserException
.validationError()
.message("Invalid paginator configuration. For PAGE pagination, pageField and pageSizeField must be defined.")
.build(logger);
} else if (this.pageSize <= 0) {
throw UserException
.validationError()
.message("Invalid paginator configuration. For PAGE pagination, maxPageSize must be defined and greater than zero.")
.build(logger);
}
break;
case INDEX:
// Either the nextPageParam OR the indexParam must be populated
if ((StringUtils.isEmpty(this.nextPageParam) && StringUtils.isNotEmpty(this.indexParam)) &&
(StringUtils.isNotEmpty(this.nextPageParam) && StringUtils.isEmpty(this.indexParam))) {
throw UserException
.validationError()
.message("Invalid paginator configuration. For INDEX pagination, the nextPageParam or indexParam must be defined.")
.build(logger);
} else if (StringUtils.isEmpty(this.nextPageParam) && StringUtils.isEmpty(this.indexParam)) {
throw UserException
.validationError()
.message("Invalid paginator configuration. For INDEX pagination, the nextPageParam or indexParam must be defined.")
.build(logger);
}
break;
case HEADER_INDEX:
if (StringUtils.isEmpty(this.nextPageParam)) {
throw UserException
.validationError()
.message("Invalid paginator configuration. For HEADER_INDEX pagination, the nextPageParam must be defined.")
.build(logger);
}
break;
default:
throw UserException
.validationError()
.message("Invalid paginator method: %s. Drill supports 'OFFSET', 'INDEX', 'HEADER_INDEX' and 'PAGE'", method)
.build(logger);
}
}
public static HttpPaginatorConfigBuilder builder() {
return new HttpPaginatorConfigBuilder();
}
public String limitParam() {
return this.limitParam;
}
public String offsetParam() {
return this.offsetParam;
}
public String pageParam() {
return this.pageParam;
}
public String pageSizeParam() {
return this.pageSizeParam;
}
public int pageSize() {
return this.pageSize;
}
public int maxRecords() {
return this.maxRecords;
}
public String method() {
return this.method;
}
public String hasMoreParam() {
return hasMoreParam;
}
public String nextPageParam() {
return nextPageParam;
}
public String indexParam() {
return indexParam;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
HttpPaginatorConfig that = (HttpPaginatorConfig) o;
return pageSize == that.pageSize
&& maxRecords == that.maxRecords
&& Objects.equals(limitParam, that.limitParam)
&& Objects.equals(offsetParam, that.offsetParam)
&& Objects.equals(pageParam, that.pageParam)
&& Objects.equals(pageSizeParam, that.pageSizeParam)
&& Objects.equals(method, that.method)
&& Objects.equals(hasMoreParam, that.hasMoreParam)
&& Objects.equals(indexParam, that.indexParam)
&& Objects.equals(nextPageParam, that.nextPageParam);
}
@Override
public int hashCode() {
return Objects.hash(limitParam, offsetParam, pageParam, pageSizeParam,
pageSize, maxRecords, method, nextPageParam, indexParam, hasMoreParam);
}
@Override
public String toString() {
return new PlanStringBuilder(this)
.field("limitParam", limitParam)
.field("offsetParam", offsetParam)
.field("pageParam", pageParam)
.field("pageSizeParam", pageSizeParam)
.field("pageSize", pageSize)
.field("maxRecords", maxRecords)
.field("method", method)
.field("indexParam", indexParam)
.field("hasMoreParam", hasMoreParam)
.field("nextPageParam", nextPageParam)
.toString();
}
public enum PaginatorMethod {
OFFSET,
PAGE,
INDEX,
HEADER_INDEX
}
@JsonIgnore
public PaginatorMethod getMethodType() {
return PaginatorMethod.valueOf(this.method.toUpperCase());
}
@JsonPOJOBuilder(withPrefix = "")
public static class HttpPaginatorConfigBuilder {
private String limitParam;
private String offsetParam;
private String pageParam;
private String pageSizeParam;
private int pageSize;
private int maxRecords;
private String method;
private String hasMoreParam;
private String indexParam;
private String nextPageParam;
public HttpPaginatorConfigBuilder hasMoreParam(String hasMoreParam) {
this.hasMoreParam = hasMoreParam;
return this;
}
public HttpPaginatorConfigBuilder indexParam(String indexParam) {
this.indexParam = indexParam;
return this;
}
public HttpPaginatorConfigBuilder nextPageParam(String nextPageParam) {
this.nextPageParam = nextPageParam;
return this;
}
public HttpPaginatorConfigBuilder limitParam(String limitParam) {
this.limitParam = limitParam;
return this;
}
public HttpPaginatorConfigBuilder offsetParam(String offsetParam) {
this.offsetParam = offsetParam;
return this;
}
public HttpPaginatorConfigBuilder pageParam(String pageParam) {
this.pageParam = pageParam;
return this;
}
public HttpPaginatorConfigBuilder pageSizeParam(String pageSizeParam) {
this.pageSizeParam = pageSizeParam;
return this;
}
public HttpPaginatorConfigBuilder pageSize(int pageSize) {
this.pageSize = pageSize;
return this;
}
public HttpPaginatorConfigBuilder maxRecords(int maxRecords) {
this.maxRecords = maxRecords;
return this;
}
public HttpPaginatorConfigBuilder method(String method) {
this.method = method;
return this;
}
public HttpPaginatorConfig build() {
return new HttpPaginatorConfig(this);
}
}
}