package com.nfl.pageimporter; import info.magnolia.rest.service.node.v1.RepositoryNode; import javax.ws.rs.core.MediaType; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.AuthCache; import org.apache.http.client.protocol.ClientContext; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.client.BasicAuthCache; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.PoolingClientConnectionManager; import org.apache.http.protocol.BasicHttpContext; import org.jboss.resteasy.client.ClientExecutor; import org.jboss.resteasy.client.ClientRequest; import org.jboss.resteasy.client.ClientResponse; import org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor; public class MagnoliaRestClient { private static final String NODE_SERVICE_PATH = "/.rest/nodes/v1/"; private static final String PROPERTY_SERVICE_PATH = "/.rest/properties/v1/"; private String scheme = "http"; private String hostname; private int port = 80; private String username; private String password; private String serviceBasePath = "/magnoliaAuthor"; private ClientExecutor clientExecutor; public String getScheme() { return scheme; } public void setScheme(String scheme) { this.scheme = scheme; } public String getHostname() { return hostname; } public void setHostname(String hostname) { this.hostname = hostname; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getServiceBasePath() { return serviceBasePath; } public void setServiceBasePath(String serviceBasePath) { this.serviceBasePath = serviceBasePath; } public RepositoryNode readNode(String workspace, String path) throws Exception { ClientRequest request = createNodeServiceRequest(workspace, path); ClientResponse response = request.get(RepositoryNode.class); validateResponseCode(response); RepositoryNode entity = response.getEntity(); response.releaseConnection(); return entity; } public void createNode(String workspace, String path, RepositoryNode node) throws Exception { ClientRequest request = createNodeServiceRequest(workspace, path); request.body(MediaType.APPLICATION_JSON_TYPE, node); ClientResponse response = request.put(); validateResponseCode(response); response.releaseConnection(); } public boolean nodeExists(String workspace, String path) throws Exception { ClientRequest request = createNodeServiceRequest(workspace, path); ClientResponse response = request.get(RepositoryNode.class); int apiResponseCode = response.getResponseStatus().getStatusCode(); response.releaseConnection(); if (response.getResponseStatus().getStatusCode() == 200) { return true; } if (response.getResponseStatus().getStatusCode() == 404) { return false; } throw new RuntimeException("Failed with HTTP error code : " + apiResponseCode); } /** * Updates all the properties on a node. If path and name are specified in the RepositoryNode * they must match the path given to the method, otherwise a HTTP 400 response is returned. Also * note that JCR will refuse to update the jcr:uuid and jcr:primaryType * properties. */ public void updateNode(String workspace, String path, RepositoryNode node) throws Exception { ClientRequest request = createNodeServiceRequest(workspace, path); request.body(MediaType.APPLICATION_JSON_TYPE, node); ClientResponse response = request.post(); validateResponseCode(response); response.releaseConnection(); } public void deleteNode(String workspace, String path) throws Exception { ClientRequest request = createNodeServiceRequest(workspace, path); ClientResponse response = request.delete(); validateResponseCode(response); response.releaseConnection(); } public void close() throws Exception { clientExecutor.close(); } private ClientRequest createNodeServiceRequest(String workspace, String path) { return createClientRequest(NODE_SERVICE_PATH, workspace, path); } private ClientRequest createClientRequest(String servicePath, String workspace, String path) { String uri = scheme + "://" + hostname + ":" + port + serviceBasePath + servicePath + workspace; if (!path.equals("/")) { uri += path; } ClientRequest request = new ClientRequest(uri, getOrCreateClientExecutor()); request.accept("application/json"); return request; } private synchronized ClientExecutor getOrCreateClientExecutor() { if (clientExecutor != null) { return clientExecutor; } // Configure HttpClient to authenticate preemptively // by prepopulating the authentication data cache. // 1. Create AuthCache instance AuthCache authCache = new BasicAuthCache(); // 2. Generate BASIC scheme object and add it to the local auth cache BasicScheme basicAuth = new BasicScheme(); authCache.put(new HttpHost(hostname, port), basicAuth); // 3. Add AuthCache to the execution context BasicHttpContext localContext = new BasicHttpContext(); localContext.setAttribute(ClientContext.AUTH_CACHE, authCache); // 4. Create client executor and proxy ClientConnectionManager cm = new PoolingClientConnectionManager(); DefaultHttpClient httpClient = new DefaultHttpClient(cm); httpClient.getCredentialsProvider().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password)); return clientExecutor = new ApacheHttpClient4Executor(httpClient, localContext); } private void validateResponseCode(ClientResponse response) { int apiResponseCode = response.getResponseStatus().getStatusCode(); if (response.getResponseStatus().getStatusCode() != 200) { throw new RuntimeException("Failed with HTTP error code : " + apiResponseCode); } } }