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.GetReleaseStatusRequest; 028import hapi.services.tiller.Tiller.GetReleaseStatusResponse; 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 status of a release version. 039 * 040 * @author <a href="https://about.me/lairdnelson" 041 * target="_parent">Laird Nelson</a> 042 */ 043@Mojo(name = "status") 044public class GetReleaseStatusMojo extends AbstractSingleVersionedReleaseMojo { 045 046 047 /* 048 * Instance fields. 049 */ 050 051 052 /** 053 * A {@link List} of <a 054 * href="apidocs/org/microbean/helm/maven/ReleaseStatusListener.html">{@code 055 * ReleaseStatusListener}</a>s whose elements will be notified of 056 * the status retrieval. 057 */ 058 @Parameter(alias = "releaseStatusListenersList") 059 private List<ReleaseStatusListener> releaseStatusListeners; 060 061 062 /* 063 * Constructors. 064 */ 065 066 067 /** 068 * Creates a new {@link GetReleaseStatusMojo}. 069 */ 070 public GetReleaseStatusMojo() { 071 super(); 072 } 073 074 075 /* 076 * Protected instance methods. 077 */ 078 079 080 /** 081 * {@inheritDoc} 082 * 083 * <p>This implementation retrieves the status for a {@linkplain 084 * #getReleaseName() given release} at a {@linkplain #getVersion() 085 * particular version} and {@linkplain 086 * ReleaseStatusListener#releaseStatusRetrieved(ReleaseStatusEvent) 087 * notifies} registered {@link ReleaseStatusListener}s.</p> 088 */ 089 @Override 090 protected void execute(final Callable<ReleaseManager> releaseManagerCallable) throws Exception { 091 Objects.requireNonNull(releaseManagerCallable); 092 final Log log = this.getLog(); 093 assert log != null; 094 095 final Integer version = this.getVersion(); 096 if (version == null) { 097 throw new IllegalStateException("version was not specified"); 098 } 099 100 final Collection<? extends ReleaseStatusListener> listeners = this.getReleaseStatusListenersList(); 101 if (listeners == null || listeners.isEmpty()) { 102 if (log.isInfoEnabled()) { 103 log.info("Skipping execution because there are no ReleaseStatusListeners specified."); 104 } 105 return; 106 } 107 108 final GetReleaseStatusRequest.Builder requestBuilder = GetReleaseStatusRequest.newBuilder(); 109 assert requestBuilder != null; 110 111 final String releaseName = this.getReleaseName(); 112 if (releaseName != null) { 113 requestBuilder.setName(releaseName); 114 } 115 116 requestBuilder.setVersion(version.intValue()); 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 status for release " + releaseName); 125 } 126 127 final Future<GetReleaseStatusResponse> getReleaseStatusResponseFuture = releaseManager.getStatus(requestBuilder.build()); 128 assert getReleaseStatusResponseFuture != null; 129 final GetReleaseStatusResponse getReleaseStatusResponse = getReleaseStatusResponseFuture.get(); 130 assert getReleaseStatusResponse != null; 131 132 final ReleaseStatusEvent event = new ReleaseStatusEvent(this, getReleaseStatusResponse); 133 for (final ReleaseStatusListener listener : listeners) { 134 if (listener != null) { 135 listener.releaseStatusRetrieved(event); 136 } 137 } 138 139 } 140 141 142 /* 143 * Public instance methods. 144 */ 145 146 147 /** 148 * Adds a {@link ReleaseStatusListener} that will be {@linkplain 149 * ReleaseStatusListener#releaseStatusRetrieved(ReleaseStatusEvent) 150 * notified} when a release version's status is retrieved 151 * 152 * @param listener the {@link ReleaseStatusListener} to add; may be 153 * {@code null} in which case no action will be taken 154 * 155 * @see #removeReleaseStatusListener(ReleaseStatusListener) 156 * 157 * @see #getReleaseStatusListenersList() 158 */ 159 public void addReleaseStatusListener(final ReleaseStatusListener listener) { 160 if (listener != null) { 161 if (this.releaseStatusListeners == null) { 162 this.releaseStatusListeners = new ArrayList<>(); 163 } 164 this.releaseStatusListeners.add(listener); 165 } 166 } 167 168 /** 169 * Removes a {@link ReleaseStatusListener} from this {@link 170 * GetReleaseStatusMojo}. 171 * 172 * @param listener the {@link ReleaseStatusListener} to remove; may 173 * be {@code null} in which case no action will be taken 174 * 175 * @see #addReleaseStatusListener(ReleaseStatusListener) 176 * 177 * @see #getReleaseStatusListenersList() 178 */ 179 public void removeReleaseStatusListener(final ReleaseStatusListener listener) { 180 if (listener != null && this.releaseStatusListeners != null) { 181 this.releaseStatusListeners.remove(listener); 182 } 183 } 184 185 /** 186 * Invokes the {@link #getReleaseStatusListenersList()} method and 187 * {@linkplain Collection#toArray(Object[]) converts its return 188 * value to an array}. 189 * 190 * <p>This method never returns {@code null}.</p> 191 * 192 * <p>Overrides of this method must not return {@code null}.</p> 193 * 194 * @return a non-{@code null} array of {@link 195 * ReleaseStatusListener}s 196 * 197 * @see #getReleaseStatusListenersList() 198 */ 199 public ReleaseStatusListener[] getReleaseStatusListeners() { 200 final Collection<ReleaseStatusListener> listeners = this.getReleaseStatusListenersList(); 201 if (listeners == null || listeners.isEmpty()) { 202 return new ReleaseStatusListener[0]; 203 } else { 204 return listeners.toArray(new ReleaseStatusListener[listeners.size()]); 205 } 206 } 207 208 /** 209 * Returns the {@link List} of {@link ReleaseStatusListener}s whose 210 * elements will be {@linkplain 211 * ReleaseStatusListener#releaseStatusRetrieved(ReleaseStatusEvent) 212 * notified} when a release version's status is retrieved. 213 * 214 * <p>This method may return {@code null}.</p> 215 * 216 * <p>Overrides of this method are permitted to return {@code 217 * null}.</p> 218 * 219 * @return a {@link List} of {@link ReleaseStatusListener}s, or 220 * {@code null} 221 * 222 * @see #setReleaseStatusListenersList(List) 223 * 224 * @see #addReleaseStatusListener(ReleaseStatusListener) 225 * 226 * @see #removeReleaseStatusListener(ReleaseStatusListener) 227 */ 228 public List<ReleaseStatusListener> getReleaseStatusListenersList() { 229 return this.releaseStatusListeners; 230 } 231 232 /** 233 * Installs the {@link List} of {@link ReleaseStatusListener}s whose 234 * elements will be {@linkplain 235 * ReleaseStatusListener#releaseStatusRetrieved(ReleaseStatusEvent) 236 * notified when a release version's status is retrieved}. 237 * 238 * @param releaseStatusListeners the {@link List} of {@link 239 * ReleaseStatusListener}s whose elements will be {@linkplain 240 * ReleaseStatusListener#releaseStatusRetrieved(ReleaseStatusEvent) 241 * notified when a release status is retrieved}; may be {@code null} 242 * 243 * @see #getReleaseStatusListenersList() 244 * 245 * @see #addReleaseStatusListener(ReleaseStatusListener) 246 * 247 * @see #removeReleaseStatusListener(ReleaseStatusListener) 248 */ 249 public void setReleaseStatusListenersList(final List<ReleaseStatusListener> releaseStatusListeners) { 250 this.releaseStatusListeners = releaseStatusListeners; 251 } 252 253}