/** * Copyright 2015 Otto (GmbH & Co KG) * * Licensed 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 com.ottogroup.bi.spqr.node.resman; import java.io.IOException; import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import com.ottogroup.bi.spqr.exception.RemoteClientConnectionFailedException; import com.ottogroup.bi.spqr.exception.RequiredInputMissingException; import com.ottogroup.bi.spqr.node.message.NodeDeRegistration.NodeDeRegistrationResponse; import com.ottogroup.bi.spqr.node.message.NodeRegistration.NodeRegistrationRequest; import com.ottogroup.bi.spqr.node.message.NodeRegistration.NodeRegistrationResponse; /** * Client to manage all communication with the SPQR resource manager * @author mnxfst * @since Apr 14, 2015 */ public class SPQRResourceManagerClient { /** our faithful logging service .... ;-) */ private static final Logger logger = Logger.getLogger(SPQRResourceManagerClient.class); /** client to be used for accessing remote processing node */ private final Client restClient; /** remote service base url */ private final String resourceManagerServiceBaseUrl; /** * Initializes the resource manager client using the provided input * @param resourceManagerProtocol * @param resourceManagerRemoteHost * @param resourceManagerServicePort * @param resourceManagerClient * @throws RequiredInputMissingException */ public SPQRResourceManagerClient(final String resourceManagerProtocol, final String resourceManagerRemoteHost, final int resourceManagerServicePort, final Client resourceManagerClient) throws RequiredInputMissingException { /////////////////////////////////////////////////////////////// // validate input if(StringUtils.isBlank(resourceManagerProtocol)) throw new RequiredInputMissingException("Missing required protocol"); if(StringUtils.isBlank(resourceManagerRemoteHost)) throw new RequiredInputMissingException("Missing required remote host"); if(resourceManagerServicePort < 1) throw new RequiredInputMissingException("Missing required service port"); if(resourceManagerClient == null) throw new RequiredInputMissingException("Missing required client"); // /////////////////////////////////////////////////////////////// this.resourceManagerServiceBaseUrl = new StringBuffer(resourceManagerProtocol).append("://").append(resourceManagerRemoteHost).append(":").append(resourceManagerServicePort).toString(); this.restClient = resourceManagerClient; } /** * Registers this node with the resource manager using the given information as instructions how to access this node * @param nodeProtocol * @param nodeHost * @param nodeServicePort * @param nodeAdminPort * @return */ public NodeRegistrationResponse registerNode(final String nodeProtocol, final String nodeHost, final int nodeServicePort, final int nodeAdminPort) throws RequiredInputMissingException, RemoteClientConnectionFailedException, IOException { ////////////////////////////////////////////////////////////////// // validate input if(StringUtils.isBlank(nodeProtocol)) throw new RequiredInputMissingException("Missing required protocol"); if(StringUtils.isBlank(nodeHost)) throw new RequiredInputMissingException("Missing required host"); if(nodeServicePort < 1) throw new RequiredInputMissingException("Missing valid service port"); if(nodeAdminPort < 1) throw new RequiredInputMissingException("Missing valid admin port"); // ////////////////////////////////////////////////////////////////// NodeRegistrationRequest message = new NodeRegistrationRequest(nodeProtocol, nodeHost, nodeServicePort, nodeAdminPort); StringBuffer url = new StringBuffer(this.resourceManagerServiceBaseUrl).append("/nodes"); if(logger.isDebugEnabled()) logger.debug("Registering processing node [protocol="+nodeProtocol+", host="+nodeHost+", servicePort="+nodeServicePort+", adminPort="+nodeAdminPort+"] at resource manager " + url.toString()); try { final WebTarget webTarget = this.restClient.target(url.toString()); return webTarget.request(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).post(Entity.entity(message, MediaType.APPLICATION_JSON), NodeRegistrationResponse.class); } catch(Exception e) { throw new RemoteClientConnectionFailedException("Failed to establish a connection with the remote resource manager [url="+url.toString()+"]. Error: " + e.getMessage()); } } /** * De-Registers the referenced node from the resource manager * @param nodeId * @return * @throws RequiredInputMissingException */ public NodeDeRegistrationResponse deregisterNode(final String nodeId) throws RequiredInputMissingException, RemoteClientConnectionFailedException { ////////////////////////////////////////////////////////////////// // validate input if(StringUtils.isBlank(nodeId)) throw new RequiredInputMissingException("Missing required node identifier"); // ////////////////////////////////////////////////////////////////// StringBuffer url = new StringBuffer(this.resourceManagerServiceBaseUrl).append("/nodes/").append(nodeId); if(logger.isDebugEnabled()) logger.debug("De-registering processing node [nodeId="+nodeId+"] at resource manager " + url.toString()); try { final WebTarget webTarget = this.restClient.target(url.toString()); return webTarget.request(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).delete(NodeDeRegistrationResponse.class); } catch(Exception e) { throw new RemoteClientConnectionFailedException("Failed to establish a connection with the remote resource manager [url="+url.toString()+"]. Error: " + e.getMessage()); } } }