001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*- 002 * 003 * Copyright © 2017-2018 microBean. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 014 * implied. See the License for the specific language governing 015 * permissions and limitations under the License. 016 */ 017package org.microbean.helm.maven; 018 019import java.util.ArrayList; 020import java.util.Collection; 021import java.util.List; 022import java.util.Objects; 023 024import java.util.concurrent.Callable; 025import java.util.concurrent.Future; 026 027import hapi.services.tiller.Tiller.GetHistoryRequest; 028import hapi.services.tiller.Tiller.GetHistoryResponse; 029 030import org.apache.maven.plugin.logging.Log; 031 032import org.apache.maven.plugins.annotations.Mojo; 033import org.apache.maven.plugins.annotations.Parameter; 034 035import org.microbean.helm.ReleaseManager; 036 037/** 038 * Retrieves the history of a release. 039 * 040 * @author <a href="https://about.me/lairdnelson" 041 * target="_parent">Laird Nelson</a> 042 */ 043@Mojo(name = "history") 044public class GetHistoryMojo extends AbstractSingleReleaseMojo { 045 046 047 /* 048 * Instance fields. 049 */ 050 051 052 /** 053 * The maximum number of versions to return. 054 */ 055 @Parameter 056 private int max; 057 058 /** 059 * A {@link List} of <a 060 * href="apidocs/org/microbean/helm/maven/ReleaseHistoryListener.html">{@code 061 * ReleaseHistoryListener}</a>s whose elements will be notified of 062 * each item in the history. 063 */ 064 @Parameter(alias = "releaseHistoryListenersList") 065 private List<ReleaseHistoryListener> releaseHistoryListeners; 066 067 068 /* 069 * Constructors. 070 */ 071 072 073 /** 074 * Creates a new {@link GetHistoryMojo}. 075 */ 076 public GetHistoryMojo() { 077 super(); 078 } 079 080 081 /* 082 * Protected instance methods. 083 */ 084 085 086 /** 087 * {@inheritDoc} 088 * 089 * <p>This implementation retrieves the history for a {@linkplain 090 * #getReleaseName() given release} and {@linkplain 091 * ReleaseHistoryListener#releaseHistoryRetrieved(ReleaseHistoryEvent) 092 * notifies} registered {@link ReleaseHistoryListener}s.</p> 093 */ 094 @Override 095 protected void execute(final Callable<ReleaseManager> releaseManagerCallable) throws Exception { 096 Objects.requireNonNull(releaseManagerCallable); 097 final Log log = this.getLog(); 098 assert log != null; 099 100 final Collection<? extends ReleaseHistoryListener> listeners = this.getReleaseHistoryListenersList(); 101 if (listeners == null || listeners.isEmpty()) { 102 if (log.isInfoEnabled()) { 103 log.info("Skipping execution because there are no ReleaseHistoryListeners specified."); 104 } 105 return; 106 } 107 108 final GetHistoryRequest.Builder requestBuilder = GetHistoryRequest.newBuilder(); 109 assert requestBuilder != null; 110 111 requestBuilder.setMax(this.getMax()); 112 113 final String releaseName = this.getReleaseName(); 114 if (releaseName != null) { 115 requestBuilder.setName(releaseName); 116 } 117 118 final ReleaseManager releaseManager = releaseManagerCallable.call(); 119 if (releaseManager == null) { 120 throw new IllegalStateException("releaseManagerCallable.call() == null"); 121 } 122 123 if (log.isInfoEnabled()) { 124 log.info("Retrieving history for release " + releaseName); 125 } 126 127 final Future<GetHistoryResponse> getHistoryResponseFuture = releaseManager.getHistory(requestBuilder.build()); 128 assert getHistoryResponseFuture != null; 129 final GetHistoryResponse getHistoryResponse = getHistoryResponseFuture.get(); 130 assert getHistoryResponse != null; 131 132 final ReleaseHistoryEvent event = new ReleaseHistoryEvent(this, getHistoryResponse); 133 for (final ReleaseHistoryListener listener : listeners) { 134 if (listener != null) { 135 listener.releaseHistoryRetrieved(event); 136 } 137 } 138 139 } 140 141 142 /* 143 * Public instance methods. 144 */ 145 146 147 /** 148 * Returns the maximum number of history entries to retrieve. 149 * 150 * @return the maximum number of history entries to retrieve 151 * 152 * @see #setMax(int) 153 */ 154 public int getMax() { 155 return this.max; 156 } 157 158 /** 159 * Sets the maximum number of history entries to retrieve. 160 * 161 * @param max the maximum number of history entries to retrieve 162 * 163 * @see #getMax() 164 */ 165 public void setMax(final int max) { 166 this.max = max; 167 } 168 169 /** 170 * Adds a {@link ReleaseHistoryListener} that will be {@linkplain 171 * ReleaseHistoryListener#releaseHistoryRetrieved(ReleaseHistoryEvent) 172 * notified} when a release history is retrieved 173 * 174 * @param listener the {@link ReleaseHistoryListener} to add; may be 175 * {@code null} in which case no action will be taken 176 * 177 * @see #removeReleaseHistoryListener(ReleaseHistoryListener) 178 * 179 * @see #getReleaseHistoryListenersList() 180 */ 181 public void addReleaseHistoryListener(final ReleaseHistoryListener listener) { 182 if (listener != null) { 183 if (this.releaseHistoryListeners == null) { 184 this.releaseHistoryListeners = new ArrayList<>(); 185 } 186 this.releaseHistoryListeners.add(listener); 187 } 188 } 189 190 /** 191 * Removes a {@link ReleaseHistoryListener} from this {@link 192 * GetHistoryMojo}. 193 * 194 * @param listener the {@link ReleaseHistoryListener} to remove; may 195 * be {@code null} in which case no action will be taken 196 * 197 * @see #addReleaseHistoryListener(ReleaseHistoryListener) 198 * 199 * @see #getReleaseHistoryListenersList() 200 */ 201 public void removeReleaseHistoryListener(final ReleaseHistoryListener listener) { 202 if (listener != null && this.releaseHistoryListeners != null) { 203 this.releaseHistoryListeners.remove(listener); 204 } 205 } 206 207 /** 208 * Invokes the {@link #getReleaseHistoryListenersList()} method and 209 * {@linkplain Collection#toArray(Object[]) converts its return 210 * value to an array}. 211 * 212 * <p>This method never returns {@code null}.</p> 213 * 214 * <p>Overrides of this method must not return {@code null}.</p> 215 * 216 * @return a non-{@code null} array of {@link 217 * ReleaseHistoryListener}s 218 * 219 * @see #getReleaseHistoryListenersList() 220 */ 221 public ReleaseHistoryListener[] getReleaseHistoryListeners() { 222 final Collection<ReleaseHistoryListener> listeners = this.getReleaseHistoryListenersList(); 223 if (listeners == null || listeners.isEmpty()) { 224 return new ReleaseHistoryListener[0]; 225 } else { 226 return listeners.toArray(new ReleaseHistoryListener[listeners.size()]); 227 } 228 } 229 230 /** 231 * Returns the {@link List} of {@link ReleaseHistoryListener}s whose 232 * elements will be {@linkplain 233 * ReleaseHistoryListener#releaseHistoryRetrieved(ReleaseHistoryEvent) 234 * notified} when a release history is retrieved. 235 * 236 * <p>This method may return {@code null}.</p> 237 * 238 * <p>Overrides of this method are permitted to return {@code 239 * null}.</p> 240 * 241 * @return a {@link List} of {@link ReleaseHistoryListener}s, or 242 * {@code null} 243 * 244 * @see #setReleaseHistoryListenersList(List) 245 * 246 * @see #addReleaseHistoryListener(ReleaseHistoryListener) 247 * 248 * @see #removeReleaseHistoryListener(ReleaseHistoryListener) 249 */ 250 public List<ReleaseHistoryListener> getReleaseHistoryListenersList() { 251 return this.releaseHistoryListeners; 252 } 253 254 /** 255 * Installs the {@link List} of {@link ReleaseHistoryListener}s 256 * whose elements will be {@linkplain 257 * ReleaseHistoryListener#releaseHistoryRetrieved(ReleaseHistoryEvent) 258 * notified when a release history is retrieved}. 259 * 260 * @param releaseHistoryListeners the {@link List} of {@link 261 * ReleaseHistoryListener}s whose elements will be {@linkplain 262 * ReleaseHistoryListener#releaseHistoryRetrieved(ReleaseHistoryEvent) 263 * notified when a release history is retrieved}; may be {@code 264 * null} 265 * 266 * @see #getReleaseHistoryListenersList() 267 * 268 * @see #addReleaseHistoryListener(ReleaseHistoryListener) 269 * 270 * @see #removeReleaseHistoryListener(ReleaseHistoryListener) 271 */ 272 public void setReleaseHistoryListenersList(final List<ReleaseHistoryListener> releaseHistoryListeners) { 273 this.releaseHistoryListeners = releaseHistoryListeners; 274 } 275 276}