Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce JavaClient for GWC Rest endpoints #205

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public abstract class AbstractShogunManager implements AutoCloseable {
protected HttpClientContext context;
protected ObjectMapper objectMapper;
protected boolean closed = false;
protected String shogunServiceBaseUrl;
protected String serviceBaseUrl;

/**
* Constructor: Initialize HTTP-client and contexts
Expand Down Expand Up @@ -114,7 +114,7 @@ public AbstractShogunManager(String adminUser, String adminPassword, String shog
objectMapper = new ObjectMapper();
objectMapper.registerModule(new JtsModule());

this.shogunServiceBaseUrl = shogunBaseUrl;
this.serviceBaseUrl = shogunBaseUrl;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
@Log4j2
public class ShogunClientBuilder {

private String shogunServiceBaseUrl;
private String serviceBaseUrl;
private String adminUser;
private String adminPassword;
private ShogunManagerType managerType;
Expand All @@ -29,7 +29,7 @@ public static ShogunClientBuilder builder() {
* @return builder
*/
public ShogunClientBuilder shogunServiceBaseUrl(String shogunServiceBaseUrl) {
this.shogunServiceBaseUrl = shogunServiceBaseUrl;
this.serviceBaseUrl = shogunServiceBaseUrl;
return this;
}

Expand Down Expand Up @@ -76,8 +76,8 @@ public AbstractShogunManager build() {
throw new IllegalStateException("SHOGun admin user password required");
}

if (shogunServiceBaseUrl == null) {
throw new IllegalStateException("SHOGun base URL required");
if (serviceBaseUrl == null) {
throw new IllegalStateException("Service base URL required");
}

if (managerType == null) {
Expand All @@ -86,7 +86,9 @@ public AbstractShogunManager build() {

switch (managerType) {
case GEOSERVER_INTERCEPTOR:
return new ShogunGsInterceptorManager(adminUser, adminPassword, shogunServiceBaseUrl);
return new ShogunGsInterceptorManager(adminUser, adminPassword, serviceBaseUrl);
case GWC:
return new ShogunGwcManager(adminUser, adminPassword, serviceBaseUrl);
default:
log.warn("Manager type unknown…");
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public ShogunGsInterceptorManager(String adminUser, String adminPassword, String
* @throws Exception The exception
*/
public List<InterceptorRule> getAllInterceptorRules() throws Exception {
HttpGet getRequest = new HttpGet(new URI(String.format("%s%s", this.shogunServiceBaseUrl, basePathInterceptorRule)));
HttpGet getRequest = new HttpGet(new URI(String.format("%s%s", this.serviceBaseUrl, basePathInterceptorRule)));
byte[] resultBytes = performRequest(getRequest);
if (resultBytes != null) {
return objectMapper.readValue(resultBytes, new TypeReference<>() {});
Expand All @@ -50,7 +50,7 @@ public List<InterceptorRule> getAllInterceptorRules() throws Exception {
* @throws Exception The exception
*/
public List<InterceptorRule> findAllRulesForServiceAndEvent(OgcEnum.ServiceType service, HttpEnum.EventType event) throws Exception {
String urlString = String.format("%s%s/service/%s/event/%s", this.shogunServiceBaseUrl, basePathInterceptorRule, service, event);
String urlString = String.format("%s%s/service/%s/event/%s", this.serviceBaseUrl, basePathInterceptorRule, service, event);
HttpGet getRequest = new HttpGet(new URI(urlString));
byte[] resultBytes = performRequest(getRequest);
if (resultBytes != null) {
Expand All @@ -67,7 +67,7 @@ public List<InterceptorRule> findAllRulesForServiceAndEvent(OgcEnum.ServiceType
* @throws Exception The exception
*/
public void removeAllRulesForEndpoint(String endpoint) throws Exception {
String urlString = String.format("%s%s/endpoint/%s", this.shogunServiceBaseUrl, basePathInterceptorRule, endpoint);
String urlString = String.format("%s%s/endpoint/%s", this.serviceBaseUrl, basePathInterceptorRule, endpoint);
HttpDelete httpDelete = new HttpDelete(new URI(urlString));
byte[] resultBytes = performRequest(httpDelete);
if (resultBytes == null || resultBytes.length != 1 || resultBytes[0] != 0) {
Expand All @@ -84,7 +84,7 @@ public void removeAllRulesForEndpoint(String endpoint) throws Exception {
* @throws Exception The exception
*/
public boolean addRequestRuleForServiceAndEndpoint(String endpoint, OgcEnum.ServiceType service, RuleType rule) throws Exception {
String urlString = String.format("%s%s/endpoint/%s/request/%s/%s", this.shogunServiceBaseUrl, basePathInterceptorRule, endpoint, service, rule);
String urlString = String.format("%s%s/endpoint/%s/request/%s/%s", this.serviceBaseUrl, basePathInterceptorRule, endpoint, service, rule);
HttpPost httpPost = new HttpPost(new URI(urlString));
byte[] resultBytes = performRequest(httpPost);
if (resultBytes != null && resultBytes.length == 1 && resultBytes[0] == 1) {
Expand All @@ -103,7 +103,7 @@ public boolean addRequestRuleForServiceAndEndpoint(String endpoint, OgcEnum.Serv
* @throws Exception The exception
*/
public boolean addResponseRuleForServiceAndEndpoint(String endpoint, OgcEnum.ServiceType service, RuleType rule) throws Exception {
String urlString = String.format("%s%s/endpoint/%s/response/%s/%s", this.shogunServiceBaseUrl, basePathInterceptorRule, endpoint, service, rule);
String urlString = String.format("%s%s/endpoint/%s/response/%s/%s", this.serviceBaseUrl, basePathInterceptorRule, endpoint, service, rule);
HttpPost httpPost = new HttpPost(new URI(urlString));
byte[] resultBytes = performRequest(httpPost);
if (resultBytes != null && resultBytes.length == 1 && resultBytes[0] == 1) {
Expand All @@ -122,7 +122,7 @@ public boolean addResponseRuleForServiceAndEndpoint(String endpoint, OgcEnum.Ser
* @throws Exception The exception
*/
public boolean addRuleForEndpoint(String endpoint, OgcEnum.ServiceType service, RuleType rule) throws Exception {
String urlString = String.format("%s%s/endpoint/%s/all/%s/%s", this.shogunServiceBaseUrl, basePathInterceptorRule, endpoint, service, rule);
String urlString = String.format("%s%s/endpoint/%s/all/%s/%s", this.serviceBaseUrl, basePathInterceptorRule, endpoint, service, rule);
HttpPost httpPost = new HttpPost(new URI(urlString));
byte[] resultBytes = performRequest(httpPost);
if (resultBytes != null && resultBytes.length == 1 && resultBytes[0] == 1) {
Expand All @@ -139,7 +139,7 @@ public boolean addRuleForEndpoint(String endpoint, OgcEnum.ServiceType service,
* @throws Exception The exception
*/
public boolean setModifyForAllWmsActions(String endpoint) throws Exception {
String urlString = String.format("%s%s/endpoint/%s/modifyAllWms", this.shogunServiceBaseUrl, basePathInterceptorRule, endpoint);
String urlString = String.format("%s%s/endpoint/%s/modifyAllWms", this.serviceBaseUrl, basePathInterceptorRule, endpoint);
HttpPost httpPost = new HttpPost(new URI(urlString));
byte[] resultBytes = performRequest(httpPost);
if (resultBytes != null && resultBytes.length == 0) {
Expand All @@ -156,7 +156,7 @@ public boolean setModifyForAllWmsActions(String endpoint) throws Exception {
* @throws Exception The exception
*/
public boolean setModifyForAllWfsActions(String endpoint) throws Exception {
String urlString = String.format("%s%s/endpoint/%s/modifyAllWfs", this.shogunServiceBaseUrl, basePathInterceptorRule, endpoint);
String urlString = String.format("%s%s/endpoint/%s/modifyAllWfs", this.serviceBaseUrl, basePathInterceptorRule, endpoint);
HttpPost httpPost = new HttpPost(new URI(urlString));
byte[] resultBytes = performRequest(httpPost);
if (resultBytes != null && resultBytes.length == 0) {
Expand All @@ -173,7 +173,7 @@ public boolean setModifyForAllWfsActions(String endpoint) throws Exception {
* @throws Exception The exception
*/
public boolean setModifyForAllWmsRequests(String endpoint) throws Exception {
String urlString = String.format("%s%s/endpoint/%s/modifyAllWmsRequests", this.shogunServiceBaseUrl, basePathInterceptorRule, endpoint);
String urlString = String.format("%s%s/endpoint/%s/modifyAllWmsRequests", this.serviceBaseUrl, basePathInterceptorRule, endpoint);
HttpPost httpPost = new HttpPost(new URI(urlString));
byte[] resultBytes = performRequest(httpPost);
if (resultBytes != null && resultBytes.length == 0) {
Expand All @@ -190,7 +190,7 @@ public boolean setModifyForAllWmsRequests(String endpoint) throws Exception {
* @throws Exception The exception
*/
public boolean setModifyForAllWfsRequests(String endpoint) throws Exception {
String urlString = String.format("%s%s/endpoint/%s/modifyAllWfsRequests", this.shogunServiceBaseUrl, basePathInterceptorRule, endpoint);
String urlString = String.format("%s%s/endpoint/%s/modifyAllWfsRequests", this.serviceBaseUrl, basePathInterceptorRule, endpoint);
HttpPost httpPost = new HttpPost(new URI(urlString));
byte[] resultBytes = performRequest(httpPost);
if (resultBytes != null && resultBytes.length == 0) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package de.terrestris.shogun.manager;

import de.terrestris.shogun.manager.gwc.GwcSeedRequest;
import de.terrestris.shogun.manager.gwc.SeedingTaskStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.thymeleaf.util.StringUtils;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
*
*/
public class ShogunGwcManager extends AbstractShogunManager {

private final String SEEDING_ENDPOINT = "/seed/";

public ShogunGwcManager(String adminUser, String adminPassword, String serviceBaseUrl) {
super(adminUser, adminPassword, serviceBaseUrl);
}

/**
* Trigger (re-)seed / truncate for certain layer
* @param gwcSeedRequest The GWC reseed object (instance of {@link GwcSeedRequest})
* @return true if seeding / truncating was triggered successfully
* @throws Exception Exception on error
*/
public boolean startSeeding(GwcSeedRequest gwcSeedRequest) throws Exception {
Map<String, Object> payLoad = gwcSeedRequest.getPayLoad();
String qualifiedLayerName = gwcSeedRequest.getQualifiedLayerName();
if (StringUtils.isEmpty(qualifiedLayerName)) {
throw new Exception("Qualified layer name is not provided");
}
HttpPost request = new HttpPost(new URI(String.format("%s%s%s.json", this.serviceBaseUrl, SEEDING_ENDPOINT, qualifiedLayerName)));
StringEntity stringEntity = new StringEntity(objectMapper.writeValueAsString(payLoad), ContentType.APPLICATION_JSON);
request.setEntity(stringEntity);

byte[] resultBytes = performRequest(request);
if (resultBytes != null) {
return true;
} else {
throw new IOException("Could not read interceptor rules from backend");
}
}

/**
* Return List of {@link SeedingTaskStatus} for given layer
* @param qualifiedLayerName The qualified layer name
* @return List of {@link SeedingTaskStatus}
* @throws Exception Exception
*/
public List<SeedingTaskStatus> getRunningTasksForLayer(String qualifiedLayerName) throws Exception {
if (StringUtils.isEmpty(qualifiedLayerName)) {
throw new Exception("Qualified layer name is not provided");
}
HttpGet getRequest = new HttpGet(new URI(String.format("%s%s%s.json", this.serviceBaseUrl, SEEDING_ENDPOINT, qualifiedLayerName)));
byte[] resultBytes = performRequest(getRequest);
if (resultBytes != null) {
Map<String, ArrayList<ArrayList<Integer>>> resultMap = objectMapper.readValue(resultBytes, Map.class);
return resultMap.get("long-array-array").stream().map(stringArrayListEntry -> new SeedingTaskStatus(
stringArrayListEntry.get(0),
stringArrayListEntry.get(1),
stringArrayListEntry.get(2),
stringArrayListEntry.get(3),
stringArrayListEntry.get(4)
)).collect(Collectors.toList());
} else {
throw new IOException(String.format("Could not tasks for layer %s from GWC", qualifiedLayerName));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@
* Enum containing the SHOGun manager types
*/
public enum ShogunManagerType {
GEOSERVER_INTERCEPTOR, APP
GEOSERVER_INTERCEPTOR, // SHOGun GeoServer interceptor
APP, // SHOGun app
GWC // GeoWebCache
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package de.terrestris.shogun.manager.gwc;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.locationtech.jts.geom.Envelope;

import java.util.HashMap;
import java.util.Map;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class GwcSeedRequest {

private String qualifiedLayerName;
private Envelope bounds;
private int srsCode;
private String gridSetId;
private int zoomStart = 0;
private int zoomStop;
private String format = "image/png";
private SeedingType type;
private int threadCount = 1;

public Map<String, Object> getPayLoad() {
Map<String, Object> seedRequest = new HashMap<>();
seedRequest.put("name", qualifiedLayerName);
seedRequest.put("gridSetId", gridSetId);
Map<String, Integer> srsMap = new HashMap<>();
srsMap.put("number", srsCode);
seedRequest.put("srs", srsMap);
seedRequest.put("zoomStop", zoomStop);
seedRequest.put("zoomStart", zoomStart);
seedRequest.put("format", format);
seedRequest.put("type", type);
seedRequest.put("threadCount", threadCount);
Map<String, Map<String, double[]>> boundsMap = new HashMap<>();
Map<String, double[]> doubleOrdsMap = new HashMap<>();
doubleOrdsMap.put("double", new double[]{bounds.getMinX(), bounds.getMinY(), bounds.getMaxX(), bounds.getMaxY()});
boundsMap.put("coords", doubleOrdsMap);
seedRequest.put("bounds", boundsMap);

Map<String, Object> returnObj = new HashMap<>();
returnObj.put("seedRequest", seedRequest);
return returnObj;
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package de.terrestris.shogun.manager.gwc;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class SeedingTaskStatus {

private int tilesProcessed;
private int totalTiles;
private int noRemainingTiles;
private int taskId;
private int taskStatus;

@Override
public String toString() {
String status;
switch (taskStatus) {
case 0:
status = "PENDING";
break;
case 1:
status = "RUNNING";
break;
case 2:
status = "DONE";
break;
default:
status = "ABORTED";
}
return String.format("Seeding-Task %d (%s): %d of %d processed.", taskId, status, tilesProcessed, totalTiles);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package de.terrestris.shogun.manager.gwc;

public enum SeedingType {
truncate,
reseed,
seed
}