[UI] Support UI partial control
[validation.git] / ui / src / main / java / org / akraino / validation / ui / client / jenkins / JenkinsExecutorClient.java
1 /*
2  * Copyright (c) 2019 AT&T Intellectual Property. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may
5  * not use this file except in compliance with the License. You may obtain
6  * a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13  * implied. See the License for the specific language governing
14  * permissions and limitations under the License.
15  */
16 package org.akraino.validation.ui.client.jenkins;
17
18 import java.io.IOException;
19 import java.net.HttpURLConnection;
20 import java.net.InetSocketAddress;
21 import java.net.MalformedURLException;
22 import java.net.Proxy;
23 import java.net.URL;
24 import java.security.KeyManagementException;
25 import java.security.NoSuchAlgorithmException;
26 import java.util.Iterator;
27
28 import javax.annotation.Nonnull;
29 import javax.ws.rs.core.MultivaluedMap;
30
31 import org.akraino.validation.ui.client.jenkins.resources.CrumbResponse;
32 import org.akraino.validation.ui.client.jenkins.resources.Parameter;
33 import org.akraino.validation.ui.client.jenkins.resources.Parameters;
34 import org.akraino.validation.ui.client.jenkins.resources.QueueJobItem;
35 import org.apache.commons.httpclient.HttpException;
36 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
37 import org.springframework.stereotype.Service;
38
39 import com.sun.jersey.api.client.Client;
40 import com.sun.jersey.api.client.ClientHandlerException;
41 import com.sun.jersey.api.client.ClientResponse;
42 import com.sun.jersey.api.client.UniformInterfaceException;
43 import com.sun.jersey.api.client.WebResource;
44 import com.sun.jersey.api.client.config.ClientConfig;
45 import com.sun.jersey.api.client.config.DefaultClientConfig;
46 import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
47 import com.sun.jersey.api.json.JSONConfiguration;
48 import com.sun.jersey.client.urlconnection.HttpURLConnectionFactory;
49 import com.sun.jersey.client.urlconnection.URLConnectionClientHandler;
50
51 @Service
52 public final class JenkinsExecutorClient {
53
54     private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(JenkinsExecutorClient.class);
55
56     private static final Object LOCK = new Object();
57     private final Client client;
58
59     private final String user;
60     private final String password;
61     private final String baseurl;
62
63     public JenkinsExecutorClient() {
64         this.baseurl = System.getenv("JENKINS_URL");
65         this.user = System.getenv("JENKINS_USERNAME");
66         this.password = System.getenv("JENKINS_USER_PASSWORD");
67         ClientConfig clientConfig = new DefaultClientConfig();
68         clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
69         this.client = new Client(new URLConnectionClientHandler(new HttpURLConnectionFactory() {
70             Proxy proxy = null;
71
72             @Override
73             public HttpURLConnection getHttpURLConnection(URL url) throws IOException {
74                 try {
75                     String proxyIp = System.getenv("JENKINS_PROXY").substring(0,
76                             System.getenv("JENKINS_PROXY").lastIndexOf(":"));
77                     String proxyPort = System.getenv("JENKINS_PROXY")
78                             .substring(System.getenv("JENKINS_PROXY").lastIndexOf(":") + 1);
79                     proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyIp, Integer.parseInt(proxyPort)));
80                     return (HttpURLConnection) url.openConnection(proxy);
81                 } catch (Exception ex) {
82                     return (HttpURLConnection) url.openConnection();
83                 }
84             }
85         }), clientConfig);
86         this.client.addFilter(new HTTPBasicAuthFilter(user, password));
87     }
88
89     public String getUser() {
90         return this.user;
91     }
92
93     public String getPassword() {
94         return this.password;
95     }
96
97     public String getBaseUrl() {
98         return this.baseurl;
99     }
100
101     public QueueJobItem getQueueJobItem(URL queueJobItemUrl) throws HttpException, ClientHandlerException,
102     UniformInterfaceException, KeyManagementException, NoSuchAlgorithmException {
103         synchronized (LOCK) {
104             LOGGER.info(EELFLoggerDelegate.applicationLogger, "Trying to get a Jenkins resource");
105             String crumb = this.getCrumb();
106             LOGGER.debug(EELFLoggerDelegate.debugLogger, "Jenkins crumb is: " + crumb);
107             WebResource webResource = this.client.resource(queueJobItemUrl + "/api/json");
108             LOGGER.debug(EELFLoggerDelegate.debugLogger, "Request URI of get: " + webResource.getURI().toString());
109             WebResource.Builder builder = webResource.getRequestBuilder();
110             builder.header("Jenkins-Crumb", crumb);
111             ClientResponse response = builder.accept("application/json").type("application/json")
112                     .get(ClientResponse.class);
113             if (response.getStatus() != 200) {
114                 throw new HttpException("Get on Jenkins failed. HTTP error code : " + response.getStatus()
115                 + " and message: " + response.getEntity(String.class));
116             }
117             LOGGER.info(EELFLoggerDelegate.applicationLogger, "Get of Jenkins resource succeeded");
118             return response.getEntity(QueueJobItem.class);
119         }
120     }
121
122     public URL postJobWithQueryParams(@Nonnull String jobName, @Nonnull Parameters parameters)
123             throws HttpException, ClientHandlerException, UniformInterfaceException, MalformedURLException,
124             KeyManagementException, NoSuchAlgorithmException {
125         synchronized (LOCK) {
126             LOGGER.info(EELFLoggerDelegate.applicationLogger, "Trying to trigger a job in Jenkins");
127             String crumb = this.getCrumb();
128             LOGGER.debug(EELFLoggerDelegate.debugLogger, "Jenkins crumb is: " + crumb);
129             String queryParams = "?";
130             for (Parameter parameter : parameters.getParameter()) {
131                 queryParams = queryParams + parameter.getName() + "=" + parameter.getValue() + "&";
132             }
133             queryParams = queryParams.substring(0, queryParams.length() - 1);
134             WebResource webResource = this.client
135                     .resource(this.getBaseUrl() + "/job/" + jobName + "/buildWithParameters" + queryParams);
136             LOGGER.debug(EELFLoggerDelegate.debugLogger, "Request URI of post: " + webResource.getURI().toString());
137             WebResource.Builder builder = webResource.getRequestBuilder();
138             builder.header("Jenkins-Crumb", crumb);
139             ClientResponse response = builder.type("application/json").post(ClientResponse.class, String.class);
140             if (response.getStatus() != 200 && response.getStatus() != 201) {
141                 throw new HttpException("Post of Jenkins job failed. HTTP error code : " + response.getStatus()
142                 + " and message: " + response.getEntity(String.class));
143             }
144             LOGGER.info(EELFLoggerDelegate.applicationLogger, "Jenkins job has been successfully triggered");
145             URL buildQueueUrl = null;
146             MultivaluedMap<String, String> responseValues = response.getHeaders();
147             Iterator<String> iter = responseValues.keySet().iterator();
148             while (iter.hasNext()) {
149                 String key = iter.next();
150                 if (key.equals("Location")) {
151                     buildQueueUrl = new URL(responseValues.getFirst(key));
152                 }
153             }
154             return buildQueueUrl;
155         }
156     }
157
158     private String getCrumb() throws HttpException, ClientHandlerException, UniformInterfaceException,
159     KeyManagementException, NoSuchAlgorithmException {
160         LOGGER.info(EELFLoggerDelegate.applicationLogger, "Attempting to get the crumb");
161         String crumbUri = baseurl + "/crumbIssuer/api/json";
162         WebResource webResource = this.client.resource(crumbUri);
163         ClientResponse response = webResource.accept("application/json").type("application/json")
164                 .get(ClientResponse.class);
165         if (response.getStatus() == 201 || response.getStatus() == 200) {
166             CrumbResponse crumbResponse = response.getEntity(CrumbResponse.class);
167             LOGGER.info(EELFLoggerDelegate.applicationLogger, "Successful crumb retrieval");
168             return crumbResponse.getCrumb();
169         }
170         throw new HttpException("Get crumb attempt towards Jenkins failed. HTTP error code: " + response.getStatus()
171         + " and message: " + response.getEntity(String.class));
172     }
173
174 }