afe5d3e7023619432311af910d39e492c4a5735a
[sdc.git] / openecomp-be / tools / artifact-copy-plugin / src / main / java / org / openecomp / sdc / onboarding / util / InitializationHelperMojo.java
1 /*
2  * Copyright © 2018 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain 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 a "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.openecomp.sdc.onboarding.util;
18
19 import java.io.File;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.lang.reflect.Method;
23 import java.net.URL;
24 import java.nio.file.Files;
25 import java.nio.file.Paths;
26 import java.nio.file.StandardCopyOption;
27 import java.util.List;
28 import java.util.regex.Matcher;
29 import java.util.regex.Pattern;
30 import org.apache.maven.artifact.repository.ArtifactRepository;
31 import org.apache.maven.execution.MavenSession;
32 import org.apache.maven.plugin.AbstractMojo;
33 import org.apache.maven.plugin.MojoExecutionException;
34 import org.apache.maven.plugin.MojoFailureException;
35 import org.apache.maven.plugins.annotations.LifecyclePhase;
36 import org.apache.maven.plugins.annotations.Mojo;
37 import org.apache.maven.plugins.annotations.Parameter;
38 import org.apache.maven.plugins.annotations.ResolutionScope;
39 import org.apache.maven.project.MavenProject;
40 import org.apache.maven.settings.Proxy;
41
42 @Mojo(name = "init-artifact-helper", threadSafe = true, defaultPhase = LifecyclePhase.PRE_CLEAN,
43         requiresDependencyResolution = ResolutionScope.NONE)
44 public class InitializationHelperMojo extends AbstractMojo {
45
46     private static final String UNICORN_INITIALIZED = "unicorn_initialized";
47     private static final String HTTP = "http";
48     private static final String HTTPS = "https";
49     private static final String SNAPSHOT = "SNAPSHOT";
50     private static final String DOT = ".";
51
52     @Parameter(defaultValue = "${session}")
53     private MavenSession session;
54     @Parameter(defaultValue = "${project}", readonly = true)
55     private MavenProject project;
56     @Parameter
57     private String groupId;
58     @Parameter
59     private String artifactId;
60     @Parameter
61     private String version;
62     @Parameter
63     private String excludePackaging;
64     @Parameter
65     private ArtifactHelper artifactHelper;
66
67     @Override
68     public void execute() throws MojoExecutionException {
69         if (System.getProperties().containsKey(UNICORN_INITIALIZED)) {
70             try {
71                 artifactHelper.shutDown(project);
72             } catch (IOException | ClassNotFoundException e) {
73                 throw new MojoExecutionException("Unexpected Error Occurred during shutdown activities", e);
74             }
75             return;
76         }
77         artifactHelper.init(groupId + ":" + artifactId);
78         artifactHelper.deleteAll(artifactHelper.getUnicornMetaLocation());
79         String resolvedVersion =
80                 getResolvedVersion(artifactHelper.getRepositories(version.contains(SNAPSHOT)), artifactId);
81         getLog().info(resolvedVersion.equals(version) ? "Unicorn Initialization Failed!!!" :
82                               "Unicorn Initialization Completed Successfully!!!");
83         System.getProperties().setProperty(UNICORN_INITIALIZED, Boolean.TRUE.toString());
84     }
85
86     private String getResolvedVersion(List<ArtifactRepository> list, String artifactId) {
87         Pattern timestampPattern = Pattern.compile(".*<timestamp>(.*)</timestamp>.*");
88         Pattern buildNumberPattern = Pattern.compile(".*<buildNumber>(.*)</buildNumber>.*");
89
90         String timestamp = null;
91         String buildNumber = null;
92         for (ArtifactRepository repo : list) {
93             try {
94                 URL url = new URL(repo.getUrl() + (groupId.replace('.', '/')) + '/' + artifactId + '/' + version
95                                           + "/maven-metadata.xml");
96                 setProxy(url);
97                 String content = artifactHelper.getContents(url);
98                 Matcher m = timestampPattern.matcher(content);
99                 if (m.find()) {
100                     timestamp = m.group(1);
101                 }
102                 m = buildNumberPattern.matcher(content);
103                 if (m.find()) {
104                     buildNumber = m.group(1);
105                 }
106
107                 URL fallbackUrl =
108                         new URL(repo.getUrl() + (groupId.replace('.', '/')) + '/' + artifactId + '/' + version + '/');
109                 timestamp = verifyBuildTimestamp(buildNumber, timestamp, fallbackUrl);
110                 if (timestamp != null && buildNumber != null) {
111                     byte[] data = fetchContents(repo.getUrl(), artifactId, timestamp + "-" + buildNumber);
112                     artifactHelper.store(artifactId, data);
113                     getLog().info(artifactId + " Version to be copied is " + timestamp + "-" + buildNumber);
114                     ArtifactHelper.setSnapshotBuildNumber(Integer.parseInt(buildNumber) + 1);
115                     return timestamp + "-" + buildNumber;
116                 }
117             } catch (IOException e) {
118                 getLog().debug(e);
119             }
120         }
121         return version;
122     }
123
124     private String verifyBuildTimestamp(String buildNumber, String timestamp, URL fallbackUrl) throws IOException {
125         if (buildNumber == null) {
126             return timestamp;
127         }
128         String buildPage = artifactHelper.getContents(fallbackUrl);
129         Pattern verifyPattern = Pattern.compile(
130                 ".*" + artifactId + "-" + version.replace(SNAPSHOT, "") + "(.*)" + "-" + buildNumber + ".jar</a>.*");
131         Matcher m = verifyPattern.matcher(buildPage);
132         if (m.find()) {
133             String str = m.group(1);
134             if (!str.equals(timestamp)) {
135                 return str;
136             }
137         }
138         return timestamp;
139     }
140
141     private byte[] fetchContents(String repoUrl, String artifactId, String resolvedVersion) throws IOException {
142         File location = Paths.get(project.getBuild().getDirectory(), "build-data").toFile();
143         location.mkdirs();
144         File file = new File(location, artifactId + "-" + (version.equals(resolvedVersion) ? version :
145                                                                    version.replace(SNAPSHOT, resolvedVersion)) + DOT
146                                                + "jar");
147         URL path = new URL(repoUrl + (groupId.replace('.', '/')) + '/' + artifactId + '/' + version + '/' + artifactId
148                                    + "-" + (version.equals(resolvedVersion) ? version :
149                                                     version.replace(SNAPSHOT, resolvedVersion)) + DOT + "jar");
150         try (InputStream is = path.openStream()) {
151             Files.copy(is, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
152         }
153         byte[] data = Files.readAllBytes(file.toPath());
154         try {
155             addJarToClasspath(file);
156         } catch (Exception e) {
157             getLog().error("Error while feeding the build-data into system.", e);
158         }
159
160         return data;
161     }
162
163     private void setProxy(URL url) {
164         if (url.getProtocol().equalsIgnoreCase(HTTP)) {
165             setProperties("http.proxyHost", "http.proxyPort", "http.nonProxyHosts", HTTP);
166         } else if (url.getProtocol().equalsIgnoreCase(HTTPS)) {
167             setProperties("https.proxyHost", "https.proxyPort", "https.nonProxyHosts", HTTPS);
168         }
169     }
170
171     private void setProperties(String proxyHostProperty, String proxyPortProperty, String nonProxyHostsProperty,
172             String protocol) {
173         for (Proxy proxy : session.getSettings().getProxies()) {
174             if (proxy.isActive() && proxy.getProtocol().equalsIgnoreCase(protocol)) {
175                 if (proxy.getHost() != null && !proxy.getHost().trim().isEmpty()) {
176                     System.setProperty(proxyHostProperty, proxy.getHost());
177                     System.setProperty(proxyPortProperty, String.valueOf(proxy.getPort()));
178                 }
179                 if (proxy.getNonProxyHosts() != null && !proxy.getNonProxyHosts().trim().isEmpty()) {
180                     System.setProperty(nonProxyHostsProperty, proxy.getNonProxyHosts());
181                 }
182             }
183         }
184     }
185
186     public void addJarToClasspath(File jar) throws MojoFailureException {
187         try {
188             ClassLoader cl = ClassLoader.getSystemClassLoader();
189             Class<?> clazz = cl.getClass();
190
191             Method method = clazz.getSuperclass().getDeclaredMethod("addURL", URL.class);
192
193             method.setAccessible(true);
194             method.invoke(cl, jar.toURI().toURL());
195         } catch (Exception e) {
196             throw new MojoFailureException("Problem while loading build-data", e);
197         }
198     }
199
200 }