aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@gmail.com>2012-04-25 18:00:00 +0200
committerSimon Brandhof <simon.brandhof@gmail.com>2012-04-25 18:00:42 +0200
commitb97522763c56241f7f0c23914eeeca571c13ff26 (patch)
tree833b0c4b028d8651d3262c3615e069572c466bf4
parentf341ea6efa8bd7c08318b78b50f200a6af830932 (diff)
downloadsonarqube-b97522763c56241f7f0c23914eeeca571c13ff26.tar.gz
sonarqube-b97522763c56241f7f0c23914eeeca571c13ff26.zip
SONAR-3431 Complete the web service /api/profiles to backup and restore profile
-rw-r--r--sonar-server/src/main/java/org/sonar/server/rules/ProfilesConsole.java12
-rw-r--r--sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java6
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/api/profiles_controller.rb60
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb2
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/models/api/utils.rb15
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