Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright (C) 2011 JFrog Ltd.
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   * http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package org.jfrog.hudson.release;
 
 import  org.jfrog.build.api.builder.PromotionBuilder;
 import  org.jfrog.build.client.ArtifactoryBuildInfoClient;
 
 import java.util.List;
 import java.util.Map;

This badge action is added to a successful staged builds. It allows performing additional promotion.

Deprecated:
Use org.jfrog.hudson.release.UnifiedPromoteBuildAction for all builder types
Author(s):
Yossi Shaul
 
 public abstract class PromoteBuildAction extends TaskAction implements BuildBadgeAction {
     private final AbstractBuild build;
 
     private String targetStatus;
     private String repositoryKey;
     private String comment;
     private boolean useCopy;
     private boolean includeDependencies;
     private PluginSettings promotionPlugin;
 
     public PromoteBuildAction(AbstractBuild build) {
         this. = build;
     }
 
     public String getIconFileName() {
         return "/plugin/artifactory/images/artifactory-release.png";
     }
 
     public String getDisplayName() {
         return "Artifactory Release Promotion";
     }
 
     public String getUrlName() {
         if (hasPromotionPermission()) {
             return "promote";
         }
         // return null to hide this action
         return null;
     }
 
     public boolean hasPromotionPermission() {
         return getACL().hasPermission(getPermission());
     }
 
     public AbstractBuild getBuild() {
         return ;
     }
 
     public void setTargetStatus(String targetStatus) {
        this. = targetStatus;
    }
    public void setRepositoryKey(String repositoryKey) {
        this. = repositoryKey;
    }
    public void setComment(String comment) {
        this. = comment;
    }
    public void setUseCopy(boolean useCopy) {
        this. = useCopy;
    }
    public void setIncludeDependencies(boolean includeDependencies) {
        this. = includeDependencies;
    }
    public String getPromotionPluginName() {
        return ( != null) ? .getPluginName() : null;
    }
    public void setPromotionPlugin(PluginSettings promotionPlugin) {
        this. = promotionPlugin;
    }
    public String getPluginParamValue(String pluginNameString paramKey) {
        return ( != null) ? .getPluginParamValue(pluginNameparamKey) : null;
    }

    

Returns:
List of target repositories for deployment (release repositories first). Called from the UI.
    public abstract List<StringgetRepositoryKeys();
    @SuppressWarnings({"UnusedDeclaration"})
    public List<StringgetTargetStatuses() {
        return Lists.newArrayList(/*"Staged", */"Released""Rolled-back");
    }

    

Returns:
The repository selected by the latest promotion (to be selected by default).
    public String lastPromotionRepository() {
        // TODO: implement
        return null;
    }

    
Select which view to display based on the state of the promotion. Will return the form if user selects to perform promotion. Progress will be returned if the promotion is currently in progress.
    @SuppressWarnings({"UnusedDeclaration"})
    public void doIndex(StaplerRequest reqStaplerResponse respthrows IOExceptionServletException {
        req.getView(thischooseAction()).forward(reqresp);
    }

    
Form submission is calling this method
    @SuppressWarnings({"UnusedDeclaration"})
    public void doSubmit(StaplerRequest reqStaplerResponse respthrows IOExceptionServletException {
        req.bindParameters(this);
        JSONObject formData = req.getSubmittedForm();
        if (formData.has("promotionPlugin")) {
            JSONObject pluginSettings = formData.getJSONObject("promotionPlugin");
            if (pluginSettings.has("pluginName")) {
                String pluginName = pluginSettings.getString("pluginName");
                if (!..equals(pluginName)) {
                    PluginSettings settings = new PluginSettings();
                    Map<StringStringparamMap = Maps.newHashMap();
                    settings.setPluginName(pluginName);
                    Map<StringObjectfilteredPluginSettings = Maps.filterKeys(pluginSettings,
                            new Predicate<String>() {
                                public boolean apply(String input) {
                                    return StringUtils.isNotBlank(input) && !"pluginName".equals(input);
                                }
                            });
                    for (Map.Entry<StringObjectsettingsEntry : filteredPluginSettings.entrySet()) {
                        String key = settingsEntry.getKey();
                        paramMap.put(keypluginSettings.getString(key));
                    }
                    if (!paramMap.isEmpty()) {
                        settings.setParamMap(paramMap);
                    }
                    setPromotionPlugin(settings);
                }
            }
        }
        ArtifactoryRedeployPublisher artifactoryPublisher = ActionableHelper.getPublisher(
                .getProject(), ArtifactoryRedeployPublisher.class);
        ArtifactoryServer server = getArtifactoryServer();
        new PromoteWorkerThread(servergetCredentials(server)).start();
        resp.sendRedirect(".");
    }
    }

    

Returns:
The Artifactory server that is used for the build.
    protected abstract ArtifactoryServer getArtifactoryServer();

    

Parameters:
server The Artifactory server that is used for the build.
Returns:
The credentials that were used for this server.
    protected abstract Credentials getCredentials(ArtifactoryServer server);
    @Override
    protected ACL getACL() {
        return .getACL();
    }
    private synchronized String chooseAction() {
        return  == null ? "form.jelly" : "progress.jelly";
    }

    
The thread that performs the promotion asynchronously.
    public final class PromoteWorkerThread extends TaskThread {
        private final ArtifactoryServer artifactoryServer;
        private final Credentials deployer;
        private final String ciUser;
        public PromoteWorkerThread(ArtifactoryServer artifactoryServerCredentials deployer) {
            super(PromoteBuildAction.this, ListenerAndText.forMemory(null));
            this. = artifactoryServer;
            this. = deployer;
            // current user is bound to the thread and will be lost in the perform method
            User user = User.current();
            this. = (user == null) ? "anonymous" : user.getId();
        }
        @Override
        protected void perform(TaskListener listener) {
            ArtifactoryBuildInfoClient client = null;
            try {
                long started = System.currentTimeMillis();
                listener.getLogger().println("Promoting build ....");
                client = .createArtifactoryClient(.getUsername(), .getPassword(),
                        .createProxyConfiguration(Hudson.getInstance().));
                if (( != null) &&
                        !..equals(.getPluginName())) {
                    handlePluginPromotion(listenerclient);
                } else {
                    handleStandardPromotion(listenerclient);
                }
                .save();
                // if the client gets back to the progress (after the redirect) page when this thread already done,
                // she will get an error message because the log dies with the thread. So lets delay up to 3 seconds
                long timeToWait = 2000 - (System.currentTimeMillis() - started);
                if (timeToWait > 0) {
                    Thread.sleep(timeToWait);
                }
                 = null;
            } catch (Throwable e) {
                e.printStackTrace(listener.error(e.getMessage()));
            } finally {
                if (client != null) {
                    client.shutdown();
                }
            }
        }
        private void handlePluginPromotion(TaskListener listener, ArtifactoryBuildInfoClient client)
                throws IOException {
            String buildName = ExtractorUtils.sanitizeBuildName(.getParent().getFullName());
            String buildNumber = .getNumber() + "";
            HttpResponse pluginPromotionResponse = client.executePromotionUserPlugin(
                    .getPluginName(), buildNamebuildNumber.getParamMap());
            if (checkSuccess(pluginPromotionResponsefalsefalselistener)) {
                listener.getLogger().println("Promotion completed successfully!");
            }
        }
        private void handleStandardPromotion(TaskListener listener, ArtifactoryBuildInfoClient client)
                throws IOException {
            // do a dry run first
            PromotionBuilder promotionBuilder = new PromotionBuilder()
                    .status()
                    .comment()
                    .ciUser()
                    .targetRepo()
                    .dependencies()
                    .copy()
                    .dryRun(true);
            listener.getLogger()
                    .println("Performing dry run promotion (no changes are made during dry run) ...");
            String buildName = ExtractorUtils.sanitizeBuildName(.getParent().getFullName());
            String buildNumber = .getNumber() + "";
            HttpResponse dryResponse = client.stageBuild(buildNamebuildNumberpromotionBuilder.build());
            if (checkSuccess(dryResponsetruetruelistener)) {
                listener.getLogger().println("Dry run finished successfully.\nPerforming promotion ...");
                HttpResponse wetResponse = client.stageBuild(buildName,
                        buildNumberpromotionBuilder.dryRun(false).build());
                if (checkSuccess(wetResponsefalsetruelistener)) {
                    listener.getLogger().println("Promotion completed successfully!");
                }
            }
        }

        
Checks the status and return true on success

Parameters:
response
dryRun
parseMessages
listener
Returns:
        private boolean checkSuccess(HttpResponse responseboolean dryRunboolean parseMessages,
                TaskListener listener) {
            StatusLine status = response.getStatusLine();
            try {
                String content = entityToString(response);
                if (assertResponseStatus(dryRunlistenerstatuscontent)) {
                    if (parseMessages) {
                        JSONObject json = JSONObject.fromObject(content);
                        JSONArray messages = json.getJSONArray("messages");
                        for (Object messageObj : messages) {
                            JSONObject messageJson = (JSONObjectmessageObj;
                            String level = messageJson.getString("level");
                            String message = messageJson.getString("message");
                            // TODO: we don't want to fail if no items were moved/copied. find a way to support it
                            if ((level.equals("WARNING") || level.equals("ERROR")) &&
                                    !message.startsWith("No items were")) {
                                listener.error("Received " + level + ": " + message);
                                return false;
                            }
                        }
                    }
                    return true;
                }
            } catch (IOException e) {
                e.printStackTrace(listener.error("Failed parsing promotion response:"));
            }
            return false;
        }
        private boolean assertResponseStatus(boolean dryRunTaskListener listenerStatusLine statusString content) {
            if (status.getStatusCode() != 200) {
                if (dryRun) {
                    listener.error(
                            "Promotion failed during dry run (no change in Artifactory was done): " + status +
                                    "\n" + content);
                } else {
                    listener.error(
                            "Promotion failed. View Artifactory logs for more details: " + status + "\n" + content);
                }
                return false;
            }
            return true;
        }
        private String entityToString(HttpResponse responsethrows IOException {
            HttpEntity entity = response.getEntity();
            InputStream is = entity.getContent();
            return IOUtils.toString(is"UTF-8");
        }
    }
New to GrepCode? Check out our FAQ X