diff options
author | Simon Brandhof <simon.brandhof@gmail.com> | 2012-04-25 18:00:00 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@gmail.com> | 2012-04-25 18:00:42 +0200 |
commit | b97522763c56241f7f0c23914eeeca571c13ff26 (patch) | |
tree | 833b0c4b028d8651d3262c3615e069572c466bf4 | |
parent | f341ea6efa8bd7c08318b78b50f200a6af830932 (diff) | |
download | sonarqube-b97522763c56241f7f0c23914eeeca571c13ff26.tar.gz sonarqube-b97522763c56241f7f0c23914eeeca571c13ff26.zip |
SONAR-3431 Complete the web service /api/profiles to backup and restore profile
5 files changed, 82 insertions, 13 deletions
diff --git a/sonar-server/src/main/java/org/sonar/server/rules/ProfilesConsole.java b/sonar-server/src/main/java/org/sonar/server/rules/ProfilesConsole.java index 16d5c5c65bd..0b7d3e7c6f9 100644 --- a/sonar-server/src/main/java/org/sonar/server/rules/ProfilesConsole.java +++ b/sonar-server/src/main/java/org/sonar/server/rules/ProfilesConsole.java @@ -65,15 +65,19 @@ public final class ProfilesConsole implements ServerComponent { return null; } - public ValidationMessages restoreProfile(String xmlBackup) { + public ValidationMessages restoreProfile(String xmlBackup, boolean deleteExisting) { ValidationMessages messages = ValidationMessages.create(); RulesProfile profile = xmlProfileParser.parse(new StringReader(xmlBackup), messages); - if (profile != null) { + if (profile != null && !messages.hasErrors()) { DatabaseSession session = sessionFactory.getSession(); RulesProfile existingProfile = session.getSingleResult(RulesProfile.class, "name", profile.getName(), "language", profile.getLanguage()); - if (existingProfile != null) { + if (existingProfile != null && !deleteExisting) { messages.addErrorText("The profile " + profile + " already exists. Please delete it before restoring."); - } else if (!messages.hasErrors()) { + + } else { + if (existingProfile!=null) { + session.removeWithoutFlush(existingProfile); + } session.saveWithoutFlush(profile); session.commit(); } diff --git a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java index d5683bddddb..55de1e0aabe 100644 --- a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java +++ b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java @@ -252,9 +252,9 @@ public final class JRubyFacade { return getContainer().getComponentByType(ProfilesConsole.class).backupProfile(profileId); } - public ValidationMessages restoreProfile(String xmlBackup) { - return getContainer().getComponentByType(ProfilesConsole.class).restoreProfile(xmlBackup); - } + public ValidationMessages restoreProfile(String xmlBackup, boolean deleteExisting) { + return getContainer().getComponentByType(ProfilesConsole.class).restoreProfile(xmlBackup, deleteExisting); + } public List<ProfileExporter> getProfileExportersForLanguage(String language) { return getContainer().getComponentByType(ProfilesConsole.class).getProfileExportersForLanguage(language); diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/profiles_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/profiles_controller.rb index f6549c56be8..b180bc3b79e 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/profiles_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/profiles_controller.rb @@ -21,6 +21,7 @@ require 'fastercsv' require "json" class Api::ProfilesController < Api::ApiController + verify :method => :post, :only => [:restore] def index begin @@ -36,21 +37,71 @@ class Api::ProfilesController < Api::ApiController raise ApiException.new(404, "Profile not found") if @profile.nil? @active_rules=filter_rules() - + respond_to do |format| format.json { render :json => jsonp(to_json) } - format.xml {render :xml => to_xml} + format.xml { render :xml => to_xml } format.text { render :text => text_not_supported } end - + rescue ApiException => e render_error(e.msg, e.code) end end + # + # Backup a profile. If output format is xml, then backup is directly returned. + # + # curl -u admin:admin http://localhost:9000/api/profiles/backup?language=java[&name=my_profile] -v + # + def backup + access_denied unless has_role?(:admin) + bad_request('Missing parameter: language') if params[:language].blank? + + if params[:name].blank? + profile=Profile.find(:first, :conditions => ['language=? and default_profile=? and enabled=?', params[:language], true, true]) + else + profile=Profile.find(:first, :conditions => ['language=? and name=? and enabled=?', params[:language], params[:name], true]) + end + not_found('Profile not found') unless profile + + backup = java_facade.backupProfile(profile.id) + respond_to do |format| + format.xml { render :xml => backup } + format.json { render :json => jsonp({:backup => backup}) } + end + end + + # + # Restore a profile backup. + # + # curl -X POST -u admin:admin -F 'backup=<my>backup</my>' -v http://localhost:9000/api/profiles/restore + # curl -X POST -u admin:admin -F 'backup=@backup.xml' -v http://localhost:9000/api/profiles/restore + # + def restore + access_denied unless has_role?(:admin) + bad_request('Missing parameter: backup') if params[:backup].blank? + + backup = Api::Utils.read_post_request_param(params[:backup]) + + messages=java_facade.restoreProfile(backup, true) + status=(messages.hasErrors() ? 400 : 200) + respond_to do |format| + format.json { render :json => jsonp(validation_messages_to_json(messages)), :status => status } + end + end + private + def validation_messages_to_json(messages) + hash={} + hash[:errors]=messages.getErrors().to_a.map { |message| message } + hash[:warnings]=messages.getWarnings().to_a.map { |message| message } + hash[:infos]=messages.getInfos().to_a.map { |message| message } + hash + end + def filter_rules conditions=['active_rules.profile_id=?'] condition_values=[@profile.id] @@ -62,7 +113,7 @@ class Api::ProfilesController < Api::ApiController if params[:rule_severities].present? conditions<<'failure_level in (?)' - condition_values<<params[:rule_severities].split(',').map{|severity| Sonar::RulePriority.id(severity)} + condition_values<<params[:rule_severities].split(',').map { |severity| Sonar::RulePriority.id(severity) } end ActiveRule.find(:all, :include => [:rule, {:active_rule_parameters => :rules_parameter}], :conditions => [conditions.join(' AND ')].concat(condition_values)) @@ -139,4 +190,5 @@ class Api::ProfilesController < Api::ApiController end end end + end
\ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb index 08795e95357..061183c3b84 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb @@ -160,7 +160,7 @@ class ProfilesController < ApplicationController if params[:backup].blank? flash[:warning]=message('quality_profiles.please_upload_backup_file') else - messages=java_facade.restoreProfile(read_file_param(params[:backup])) + messages=java_facade.restoreProfile(read_file_param(params[:backup]), false) flash_validation_messages(messages) end redirect_to :action => 'index' diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/api/utils.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/api/utils.rb index 09eda567abc..7ceec9ad93b 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/api/utils.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/api/utils.rb @@ -124,11 +124,24 @@ class Api::Utils end end end - + # # Since Sonar 3.0 # def self.valid_period_index?(index) Api::Utils.is_integer?(index) && index.to_i > 0 && index.to_i <6 end + + # + # Since Sonar 3.1 + # + # Read content of HTTP POST request. Example: read_post_request_param(params[:backup]) + # + def self.read_post_request_param(param_value) + if param_value + param_value.respond_to?(:read) ? param_value.read : param_value + else + nil + end + end end |