Java tutorial
/* * Athena Peacock Project - Server Provisioning Engine for IDC or Cloud * * Copyright (C) 2013 Open Source Consulting, Inc. All rights reserved by Open Source Consulting, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * Revision History * Author Date Description * --------------- ---------------- ------------ * Sang-cheon Park 2013. 10. 31. First Draft. */ package com.athena.peacock.controller.common.component; import java.io.IOException; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.net.URI; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.PropertyException; import javax.xml.namespace.QName; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.util.Assert; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; /** * <pre> * Spring RestTemplate? ? RHEV Manager? RESTFul Component ? * </pre> * @author Sang-cheon Park * @version 1.0 */ public class RHEVMRestTemplate { private static final Logger logger = LoggerFactory.getLogger(RHEVMRestTemplate.class); private static final String HOST_HEADER_KEY = "Host"; private static final String AUTH_HEADER_KEY = "Authorization"; private Integer hypervisorId; private String rhevmName; private String protocol; private String host; private String domain; private String port; private String username; private String password; private int major; private int minor; private String credential; public RHEVMRestTemplate(String protocol, String host, String domain, String port, String username, String password) { this.protocol = protocol; this.host = host; this.domain = domain; this.port = port; this.username = username; this.password = password; try { init(); } catch (Exception e) { // ignore } } public Integer getHypervisorId() { return hypervisorId; } public void setHypervisorId(Integer hypervisorId) { this.hypervisorId = hypervisorId; } public String getRhevmName() { return rhevmName; } public void setRhevmName(String rhevmName) { this.rhevmName = rhevmName; } public String getProtocol() { return protocol; } public String getHost() { return host; } public String getDomain() { return domain; } public String getPort() { return port; } public String getUsername() { return username; } public String getPassword() { return password; } public int getMajor() { return major; } public void setMajor(int major) { this.major = major; } public int getMinor() { return minor; } public void setMinor(int minor) { this.minor = minor; } /** * <pre> * ? ?? HTTPS HandShake Exception ? ?? Exception? ? ? * RHEV Manager(host) ? SSL ?? ? ? ?? ?. * </pre> * @throws Exception */ public void init() throws Exception { // http://javaresolutions.blogspot.kr/2014/07/javaxnetsslsslprotocolexception.html // -Djsse.enableSNIExtension=false // System.setProperty("jsse.enableSNIExtension", "false"); System.setProperty("jsse.enableSNIExtension", "false"); // Create a hostname verifier that does not validate hostname HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { /* if (hostname.equals(host)) { return true; } return false; */ return true; } }); // Create a trust manager that does not validate certificate chains // Refer to https://code.google.com/p/misc-utils/wiki/JavaHttpsUrl TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { // nothing to do. } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { // nothing to do. } @Override public X509Certificate[] getAcceptedIssuers() { return null; } } }; try { // Install the all-trusting trust manager SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); } catch (KeyManagementException e) { logger.error("KeyManagementException has occurred.", e); } catch (NoSuchAlgorithmException e) { logger.error("NoSuchAlgorithmException has occurred.", e); } }//end of init() /** * <pre> * HTTP Header? ?? ?. * </pre> * @return */ private HttpEntity<Object> setHTTPEntity(Object body, String rootElementName) { List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>(); acceptableMediaTypes.add(MediaType.APPLICATION_XML); HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.setContentType(MediaType.APPLICATION_XML); requestHeaders.setAccept(acceptableMediaTypes); requestHeaders.set(HOST_HEADER_KEY, host); requestHeaders.set(AUTH_HEADER_KEY, getCredential()); if (body != null) { logger.debug("Content Body => {}", marshal(body, rootElementName)); return new HttpEntity<Object>(marshal(body, rootElementName), requestHeaders); } else { return new HttpEntity<Object>(requestHeaders); } }//end of addAuth() /** * <pre> * RHEV Manager? ?? ?. * </pre> * @return */ public String getCredential() { if (credential == null) { try { String plain = username + "@" + domain + ":" + password; credential = "Basic " + Base64.encodeBase64String(plain.getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { logger.error("UnsupportedEncodingException has occurred.", e); } } return credential; }//end of getCredential() /** * <pre> * RHEV Manager URL . * </pre> * @param api * @return */ public String getUrl(String api) { StringBuilder sb = new StringBuilder(); if (protocol.toLowerCase().equals("http")) { sb.append("http://"); } else { sb.append("https://"); } sb.append(host).append(":").append(port); if (!api.startsWith("/")) { sb.append("/"); } sb.append(api); return sb.toString(); }//end of getUrl() @SuppressWarnings({ "unchecked", "rawtypes" }) private static String marshal(Object obj, String rootElementName) { StringWriter sw = new StringWriter(); try { JAXBContext jaxbCtx = JAXBContext.newInstance(obj.getClass().getPackage().getName()); Marshaller marshaller = jaxbCtx.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.marshal(new JAXBElement(new QName(rootElementName), obj.getClass(), obj), sw); sw.close(); } catch (PropertyException e) { e.printStackTrace(); } catch (JAXBException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return sw.toString(); } /** * <pre> * RHEV Manager API . * </pre> * @param api RHEV Manager API (/api, /api/vms ) * @param clazz ? Target Object Class * @return * @throws RestClientException * @throws Exception */ public <T> T submit(String api, HttpMethod method, Class<T> clazz) throws RestClientException, Exception { Assert.isTrue(StringUtils.isNotEmpty(api), "api must not be null"); Assert.notNull(clazz, "clazz must not be null."); return submit(api, method, null, null, clazz); }//end of submit() /** * <pre> * RHEV Manager API . * </pre> * @param api RHEV Manager API (/api, /api/vms ) * @param body xml contents * @param clazz ? Target Object Class * @return * @throws RestClientException * @throws Exception */ public synchronized <T> T submit(String api, HttpMethod method, Object body, String rootElementName, Class<T> clazz) throws RestClientException, Exception { Assert.isTrue(StringUtils.isNotEmpty(api), "api must not be null"); Assert.notNull(clazz, "clazz must not be null."); // Multi RHEV Manager ? ?? HostnameVerifier ??, // ?? ? ?.(java.io.IOException: HTTPS hostname wrong: should be <{host}>) //init(); try { RestTemplate rt = new RestTemplate(); ResponseEntity<?> response = rt.exchange(new URI(getUrl(api)), method, setHTTPEntity(body, rootElementName), clazz); logger.debug("[Request URL] : {}", getUrl(api)); logger.debug("[Response] : {}", response); if (response.getStatusCode().equals(HttpStatus.BAD_REQUEST) || response.getStatusCode().equals(HttpStatus.UNAUTHORIZED) || response.getStatusCode().equals(HttpStatus.PAYMENT_REQUIRED) || response.getStatusCode().equals(HttpStatus.FORBIDDEN) || response.getStatusCode().equals(HttpStatus.METHOD_NOT_ALLOWED) || response.getStatusCode().equals(HttpStatus.NOT_ACCEPTABLE) || response.getStatusCode().equals(HttpStatus.INTERNAL_SERVER_ERROR) || response.getStatusCode().equals(HttpStatus.NOT_IMPLEMENTED) || response.getStatusCode().equals(HttpStatus.BAD_GATEWAY) || response.getStatusCode().equals(HttpStatus.SERVICE_UNAVAILABLE) || response.getStatusCode().equals(HttpStatus.GATEWAY_TIMEOUT)) { throw new Exception(response.getStatusCode().value() + " " + response.getStatusCode().toString()); } return clazz.cast(response.getBody()); } catch (RestClientException e) { logger.error("RestClientException has occurred.", e); throw e; } catch (Exception e) { logger.error("Unhandled Exception has occurred.", e); throw e; } }//end of submit() public static void main(String[] args) { String protocol = "HTTPS"; String host = ""; String domain = "internal"; String port = "8443"; String username = "admin"; String password = ""; RHEVMRestTemplate rhevTemplate = new RHEVMRestTemplate(protocol, host, domain, port, username, password); System.out.println(rhevTemplate.getCredential()); } } //end of RHEVMRestTemplate.java