Commit 74d38ccb authored by Szabolcs Gyurko's avatar Szabolcs Gyurko
Browse files

Added page controller and tests.

parent c10ce20f
Pipeline #292 passed with stage
in 3 minutes and 3 seconds
package com.jeff_cms.jeff.util;
/*
Copyright (C) 2018 Szabolcs Gyurko <szabolcs@hacking.hu>
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import lombok.Getter;
/**
* Scala-like Pair implementation.
* @param <F> First param type.
* @param <S> Second param type.
*/
@Getter
public class Pair<F, S> {
private F first;
private S second;
private Pair() {
}
private Pair(final F first, final S second) {
this.first = first;
this.second = second;
}
/**
* Creates a pair from the arguments.
* @param first First object
* @param second Second object
* @param <F> First Object type
* @param <S> Second Object type
* @return An immutable pair object holding the two input object.
*/
public static <F, S> Pair<F, S> of(final F first, final S second) {
return new Pair<>(first, second);
}
}
......@@ -108,6 +108,12 @@
<version>2.0</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
......
......@@ -29,6 +29,7 @@ import com.jeff_cms.jeff.node.exception.ImageServiceException;
import com.jeff_cms.jeff.node.jcr.JcrSessionFactory;
import com.jeff_cms.jeff.node.service.ImageService;
import com.jeff_cms.jeff.node.utils.JcrUtils;
import com.jeff_cms.jeff.util.Pair;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
......@@ -63,6 +64,8 @@ import java.util.regex.Pattern;
@CacheConfig(cacheNames = "binary")
public class BinaryController {
private static final Pattern DIMENSION_PARAMETER_PATTERN = Pattern.compile("^([0-9]+)?x([0-9]+)?$");
private static final Pattern NODE_PATH_PATTERN = Pattern.compile("^/binary(/.+)/[^/]+$");
private static final Pattern NODE_PROPERTY_PATTERN = Pattern.compile("^/binary/.+/([^/]+)$");
private final JcrSessionFactory jcrSessionFactory;
private final JcrUtils jcrUtils;
......@@ -86,10 +89,9 @@ public class BinaryController {
@RequestParam(name = "ignoreAlpha", defaultValue = "false") final Boolean ignoreAlpha,
final ServletRequest servletRequest, final Principal principal) throws ImageServiceException {
final Session session = jcrSessionFactory.getSession();
final String nodePath = ((String) servletRequest
.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).replaceAll("^/binary(/.+)/[^/]+$", "$1");
final String nodeProperty = Constants.NS_JEFF + ((String) servletRequest
.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).replaceAll("^/binary/.+/([^/]+)$", "$1");
final Pair<String, String> nodePathAndProperty = getNodePathAndProperty(servletRequest);
final String nodePath = nodePathAndProperty.getFirst();
final String nodeProperty = nodePathAndProperty.getSecond();
try {
final Node node = session.getNode(nodePath);
......@@ -173,10 +175,9 @@ public class BinaryController {
public ResponseEntity<String> createBinaryData(@RequestParam("file") final MultipartFile multipartFile,
final Principal principal, final ServletRequest servletRequest) {
final Session session = jcrSessionFactory.getSession();
final String nodePath = ((String) servletRequest
.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).replaceAll("^/binary(/.+)/[^/]+$", "$1");
final String nodeProperty = Constants.NS_JEFF + ((String) servletRequest
.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).replaceAll("^/binary/.+/([^/]+)$", "$1");
final Pair<String, String> nodePathAndProperty = getNodePathAndProperty(servletRequest);
final String nodePath = nodePathAndProperty.getFirst();
final String nodeProperty = nodePathAndProperty.getSecond();
try {
final Node node = session.getNode(nodePath);
......@@ -203,8 +204,8 @@ public class BinaryController {
session.save();
ServletUriComponentsBuilder builder = ServletUriComponentsBuilder.fromCurrentRequestUri();
URI newUri = builder.build().toUri();
final ServletUriComponentsBuilder builder = ServletUriComponentsBuilder.fromCurrentRequestUri();
final URI newUri = builder.build().toUri();
return ResponseEntity.created(newUri).build();
} catch (IOException | RepositoryException e) {
......@@ -228,10 +229,9 @@ public class BinaryController {
public ResponseEntity<String> modifyBinaryData(@RequestParam("file") final MultipartFile multipartFile,
final Principal principal, final ServletRequest servletRequest) {
final Session session = jcrSessionFactory.getSession();
final String nodePath = ((String) servletRequest
.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).replaceAll("^/binary(/.+)/[^/]+$", "$1");
final String nodeProperty = Constants.NS_JEFF + ((String) servletRequest
.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).replaceAll("^/binary/.+/([^/]+)$", "$1");
final Pair<String, String> nodePathAndProperty = getNodePathAndProperty(servletRequest);
final String nodePath = nodePathAndProperty.getFirst();
final String nodeProperty = nodePathAndProperty.getSecond();
try {
final Node node = session.getNode(nodePath);
......@@ -278,10 +278,9 @@ public class BinaryController {
@Profile("author")
public ResponseEntity<String> modifyBinaryData(final Principal principal, final ServletRequest servletRequest) {
final Session session = jcrSessionFactory.getSession();
final String nodePath = ((String) servletRequest
.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).replaceAll("^/binary(/.+)/[^/]+$", "$1");
final String nodeProperty = Constants.NS_JEFF + ((String) servletRequest
.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).replaceAll("^/binary/.+/([^/]+)$", "$1");
final Pair<String, String> nodePathAndProperty = getNodePathAndProperty(servletRequest);
final String nodePath = nodePathAndProperty.getFirst();
final String nodeProperty = nodePathAndProperty.getSecond();
try {
final Node node = session.getNode(nodePath);
......@@ -310,4 +309,13 @@ public class BinaryController {
}
}
private Pair<String, String> getNodePathAndProperty(final ServletRequest servletRequest) {
return Pair.of(
NODE_PATH_PATTERN.matcher((String) servletRequest
.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).replaceAll("$1"),
Constants.NS_JEFF + NODE_PROPERTY_PATTERN.matcher((String) servletRequest
.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).replaceAll("$1")
);
}
}
......@@ -38,6 +38,7 @@ import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import javax.servlet.ServletRequest;
import java.net.URI;
import java.security.Principal;
import java.util.regex.Pattern;
/**
* Controller to expose content manipulating endpoints.
......@@ -47,6 +48,7 @@ import java.security.Principal;
@CrossOrigin("*")
@Slf4j
public class ContentController {
private static final Pattern PATH_PATTERN = Pattern.compile("^/content");
private final ContentService contentService;
public ContentController(final ContentService contentService) {
......@@ -64,8 +66,7 @@ public class ContentController {
@PreAuthorize("#oauth2.hasScope('read')")
public ResponseEntity<com.jeff_cms.jeff.model.Node> getNode(@RequestParam(defaultValue = "false") final Boolean withChildren,
final ServletRequest servletRequest, final Principal principal) throws Exception {
final String requestedUri = ((String) servletRequest
.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).replaceAll("^/content", "");
final String requestedUri = getRequestedUri(servletRequest);
final Node result = withChildren
?
......@@ -89,8 +90,7 @@ public class ContentController {
@Profile("author")
public ResponseEntity<String> createNode(@RequestBody final com.jeff_cms.jeff.model.Node node,
final Principal principal, final ServletRequest servletRequest) throws Exception {
String requestedUri = ((String) servletRequest
.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).replaceAll("^/content", "");
String requestedUri = getRequestedUri(servletRequest);
if (node.getPath() != null) {
requestedUri = node.getPath();
......@@ -98,8 +98,8 @@ public class ContentController {
contentService.saveNode(requestedUri, node, principal);
ServletUriComponentsBuilder builder = ServletUriComponentsBuilder.fromCurrentRequestUri();
URI newUri = builder.build().toUri();
final ServletUriComponentsBuilder builder = ServletUriComponentsBuilder.fromCurrentRequestUri();
final URI newUri = builder.build().toUri();
return ResponseEntity.created(newUri).build();
}
......@@ -117,8 +117,7 @@ public class ContentController {
@Profile("author")
public ResponseEntity<String> modifyNode(@RequestBody final com.jeff_cms.jeff.model.Node node,
final Principal principal, final ServletRequest servletRequest) throws Exception {
String requestedUri = ((String) servletRequest
.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).replaceAll("^/content", "");
String requestedUri = getRequestedUri(servletRequest);
if (node.getPath() != null) {
requestedUri = node.getPath();
......@@ -140,13 +139,15 @@ public class ContentController {
@PreAuthorize("#oauth2.hasScope('write')")
@Profile("author")
public ResponseEntity<String> deleteNode(final ServletRequest servletRequest, final Principal principal) throws Exception {
String requestedUri = ((String) servletRequest
.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).replaceAll("^/content", "");
final String requestedUri = getRequestedUri(servletRequest);
contentService.deleteNode(requestedUri, principal);
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}
private String getRequestedUri(final ServletRequest servletRequest) {
return PATH_PATTERN.matcher((String) servletRequest
.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).replaceAll("");
}
}
......@@ -67,6 +67,10 @@
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
<!-- Lombok for generating getters/setters -->
<dependency>
......@@ -81,6 +85,12 @@
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<!-- TEST -->
<dependency>
<groupId>org.springframework.boot</groupId>
......
package com.jeff_cms.jeff.web.config;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
/*
Copyright (C) 2018 Szabolcs Gyurko <szabolcs@hacking.hu>
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* Cache config and key generator beans.
*/
@Configuration
@Profile("cache")
@EnableCaching
public class CacheConfig {
}
......@@ -28,8 +28,6 @@ import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* Main configuration POJO.
*/
......@@ -37,5 +35,6 @@ import java.util.List;
@ConfigurationProperties(prefix = "jeff")
@Data
public class JeffConfiguration {
private List<String> apiNodes;
private String apiNode;
private String pagesNodePath;
}
package com.jeff_cms.jeff.web.config;
/*
Copyright (C) 2018 Szabolcs Gyurko <szabolcs@hacking.hu>
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2RestOperations;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.client.token.AccessTokenRequest;
import org.springframework.security.oauth2.client.token.DefaultAccessTokenRequest;
import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails;
import org.springframework.security.oauth2.common.AuthenticationScheme;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler;
import java.util.Arrays;
/**
* OAuth2 client configuration.
*/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
@EnableResourceServer
@Profile("oauth2")
public class OAuth2Config extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
@Bean(name = "oauthClientResourceDetails")
OAuth2ProtectedResourceDetails resource(@Value("${security.oauth2.client.access-token-uri}") String accessTokenUri,
@Value("${security.oauth2.client.client-id}") String clientId,
@Value("${security.oauth2.client.client-secret}") String clientSecret) {
ClientCredentialsResourceDetails resource = new ClientCredentialsResourceDetails();
resource.setAccessTokenUri(accessTokenUri);
resource.setClientId(clientId);
resource.setClientSecret(clientSecret);
resource.setGrantType("client_credentials");
resource.setClientAuthenticationScheme(AuthenticationScheme.header);
resource.setScope(Arrays.asList("read", "write"));
return resource;
}
@Bean
OAuth2RestOperations restTemplate(@Qualifier("oauthClientResourceDetails") OAuth2ProtectedResourceDetails oAuth2ProtectedResourceDetails) {
final AccessTokenRequest accessTokenRequest = new DefaultAccessTokenRequest();
return new OAuth2RestTemplate(oAuth2ProtectedResourceDetails, new DefaultOAuth2ClientContext(accessTokenRequest));
}
}
......@@ -24,11 +24,83 @@ package com.jeff_cms.jeff.web.controller;
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import org.springframework.stereotype.Controller;
import com.jeff_cms.jeff.util.Pair;
import com.jeff_cms.jeff.web.model.Page;
import com.jeff_cms.jeff.web.service.PageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.HandlerMapping;
import javax.servlet.http.HttpServletRequest;
import java.util.regex.Pattern;
/**
* Controller for the Page object.
*/
@Controller
@RestController
@RequestMapping("/page")
@CrossOrigin("*")
@Slf4j
public class PageController {
private static final Pattern PATH_PATTERN = Pattern.compile("^/page");
private final PageService pageService;
public PageController(final PageService pageService) {
this.pageService = pageService;
}
/**
* GET handler to fetch a page.
* @param servletRequest servlet request
* @return Page
*/
@GetMapping("**")
@PreAuthorize("#oauth2.hasScope('read')")
public ResponseEntity<Page> getPage(final HttpServletRequest servletRequest) {
final String requestedUri = PATH_PATTERN.matcher((String) servletRequest
.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).replaceAll("");
Pair<Page, HttpStatus> result = pageService.getPage(requestedUri);
if (result.getSecond() != HttpStatus.OK) {
return ResponseEntity.status(result.getSecond()).build();
}
return ResponseEntity.ok(result.getFirst());
}
/**
* POST mapping to create a page.
* @param servletRequest servlet request
* @return Status of the operation.
*/
@PostMapping("**")
@PreAuthorize("#oauth2.hasScope('write')")
public ResponseEntity<String> createPage(@RequestBody final Page page, final HttpServletRequest servletRequest) {
final String requestedUri = PATH_PATTERN.matcher((String) servletRequest
.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).replaceAll("");
final HttpStatus status = pageService.createPage(requestedUri, page);
return ResponseEntity.status(status).build();
}
/**
* POST mapping to create a page.
* @param servletRequest servlet request
* @return Status of the operation.
*/
@PutMapping("**")
@PreAuthorize("#oauth2.hasScope('write')")
public ResponseEntity<String> modifyPage(@RequestBody final Page page, final HttpServletRequest servletRequest) {
final String requestedUri = PATH_PATTERN.matcher((String) servletRequest
.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).replaceAll("");
final HttpStatus status = pageService.modifyPage(requestedUri, page);
return ResponseEntity.status(status).build();
}
}
......@@ -24,11 +24,74 @@ package com.jeff_cms.jeff.web.service;
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import com.jeff_cms.jeff.model.Node;
import com.jeff_cms.jeff.util.Pair;
import com.jeff_cms.jeff.web.model.Page;
import com.jeff_cms.jeff.web.util.UrlUtils;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.core.convert.ConversionService;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.client.OAuth2RestOperations;
import org.springframework.stereotype.Service;
/**
* Service class for manipulating Page objects.
*/
@Service
@CacheConfig(cacheNames = "pages")
public class PageService {
private final OAuth2RestOperations restOperations;
private final UrlUtils urlUtils;
private final ConversionService conversionService;
public PageService(final OAuth2RestOperations restOperations, final UrlUtils urlUtils, final ConversionService conversionService) {
this.restOperations = restOperations;
this.urlUtils = urlUtils;
this.conversionService = conversionService;
}
/**
* Returns a page.
* @param path Path to the page.
* @return Page data.
*/
@Cacheable
public Pair<Page, HttpStatus> getPage(final String path) {
final ResponseEntity<Node> responseEntity = restOperations.getForEntity(urlUtils.getPageContentUrl(path), Node.class);
if (responseEntity.getStatusCode() == HttpStatus.OK) {
return Pair.of(conversionService.convert(responseEntity.getBody(), Page.class), HttpStatus.OK);
}
return null;
}
/**
* Creates a page.
* @param path Path to the page.
* @param page The Page object.
* @return Status of the REST call to jeff-node.
*/
public HttpStatus createPage(final String path, final Page page) {
return restOperations.postForEntity(urlUtils.getPageContentUrl(path), conversionService.convert(page, Node.class), String.class).getStatusCode();
}
/**
* Modifies a page.
* @param path Path to the page.
* @param page The Page object.
* @return Status of the REST call to jeff-node.
*/
public HttpStatus modifyPage(final String path, final Page page) {
return restOperations.exchange(
urlUtils.getPageContentUrl(path),
HttpMethod.PUT,
new HttpEntity<>(conversionService.convert(page, Node.class)),
String.class
).getStatusCode();