]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8574 Delete api/resources/index WS 1536/head
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Wed, 18 Jan 2017 11:37:08 +0000 (12:37 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Wed, 18 Jan 2017 14:23:41 +0000 (15:23 +0100)
it/it-tests/src/test/java/it/serverSystem/HttpHeadersTest.java
server/sonar-server/src/main/java/org/sonar/server/component/ws/ResourcesWs.java
server/sonar-server/src/main/java/org/sonar/server/ws/RemovedWebServiceHandler.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/component/ws/ResourcesWsTest.java
server/sonar-server/src/test/java/org/sonar/server/ws/RemovedWebServiceHandlerTest.java [new file with mode: 0644]
server/sonar-web/src/main/webapp/WEB-INF/app/controllers/api/resources_controller.rb

index 4910729c859d3ea2f4590b6a4ac22c6c8e0e09a3..02f362bbfdf52c68e3296d12e8906d869c45d2dc 100644 (file)
@@ -69,7 +69,7 @@ public class HttpHeadersTest {
 
   @Test
   public void verify_headers_of_ruby_ws() throws Exception {
-    Response response = call(orchestrator.getServer().getUrl() + "/api/resources/index");
+    Response response = call(orchestrator.getServer().getUrl() + "/api/resources/search");
 
     verifySecurityHeaders(response);
     verifyContentType(response, "application/json;charset=utf-8");
index c7b8b93d1c944f997a4a9908e14dfd1ee6ba38aa..e25f41a1898c3dbab64a0846b6c60bf6fd6bd7ea 100644 (file)
@@ -22,8 +22,7 @@ package org.sonar.server.component.ws;
 import com.google.common.io.Resources;
 import org.sonar.api.server.ws.RailsHandler;
 import org.sonar.api.server.ws.WebService;
-
-import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
+import org.sonar.server.ws.RemovedWebServiceHandler;
 
 public class ResourcesWs implements WebService {
 
@@ -40,91 +39,18 @@ public class ResourcesWs implements WebService {
   }
 
   private void defineIndexAction(NewController controller) {
-    NewAction action = controller.createAction("index")
-      .setDescription("Gets a list of components. Requires Browse permission on resource.<br>" +
-        "The web service is deprecated and you're invited to use the alternatives: " +
+    controller.createAction("index")
+      .setDescription("The web service is removed and you're invited to use the alternatives: " +
         "<ul>" +
         "<li>if you need one component without measures: api/components/show</li>" +
         "<li>if you need one component with measures: api/measures/component</li>" +
         "<li>if you need several components without measures: api/components/tree</li>" +
         "<li>if you need several components with measures: api/measures/component_tree</li>" +
-        "</ul>" +
-        "When you provide one metric, the number of results is limited to 500. When several metrics are provided, the number of measures is limited to 10000. " +
-        "The number of components is limited to 500." +
-        "This is a known limitation and it won't be fixed. You're invited to use the alternatives suggested above.")
+        "</ul>")
       .setSince("2.10")
       .setDeprecatedSince("5.4")
-      .setHandler(RailsHandler.INSTANCE)
+      .setHandler(RemovedWebServiceHandler.INSTANCE)
       .setResponseExample(Resources.getResource(this.getClass(), "resources-example-index.json"));
-
-    action.createParam("resource")
-      .setDescription("id or key of the resource")
-      .setExampleValue(KEY_PROJECT_EXAMPLE_001);
-
-    action.createParam("metrics")
-      .setDescription("Comma-separated list of <a href=\"http://redirect.sonarsource.com/doc/metric-definitions.html\">metric keys/ids</a>. " +
-        "Load measures on selected metrics. If only one metric is set, then measures are ordered by value")
-      .setExampleValue("lines,blocker_violations");
-
-    action.createParam("depth")
-      .setDescription("Used only when resource is set:<br/>" +
-        "<ul>" +
-        "<li>0: only selected resource</li>" +
-        "<li>-1: all children, including selected resource</li>" +
-        "<li>>0: depth toward the selected resource</li>" +
-        "</ul>")
-      .setDefaultValue("0")
-      .setExampleValue("-1");
-
-    action.createParam("scopes")
-      .setDescription("Comma-separated list of scopes:<br/>" +
-        "<ul>" +
-        "<li>PRJ: project/module</li>" +
-        "<li>DIR: directory (like Java package)</li>" +
-        "<li>FIL: file</li>" +
-        "</ul>")
-      .setExampleValue("PRJ,DIR");
-
-    action.createParam("qualifiers")
-      .setDescription("Comma-separated list of qualifiers:<br/>" +
-        "<ul>" +
-        "<li>VW: view</li>" +
-        "<li>SVW: sub-view</li>" +
-        "<li>TRK: project</li>" +
-        "<li>BRC: module</li>" +
-        "<li>UTS: unit test</li>" +
-        "<li>DIR: directory</li>" +
-        "<li>FIL: file</li>" +
-        "<li>DEV: developer</li>" +
-        "</ul>")
-      .setExampleValue("TRK,BRC");
-
-    action.createParam("verbose")
-      .setDescription("Add some data to response")
-      .setBooleanPossibleValues()
-      .setDefaultValue(String.valueOf(false));
-
-    action.createParam("limit")
-      .setDescription("Limit the number of results. Only used if one metric, and only one, is set")
-      .setExampleValue("10");
-
-    action.createParam("includetrends")
-      .setDescription("Include period variations in response: add nodes &ltp*&gt for period variations")
-      .setDefaultValue(String.valueOf(false))
-      .setBooleanPossibleValues();
-
-    action.createParam("includealerts")
-      .setDescription("Include alerts data: add nodes &ltalert&gt (ERROR, WARN, OK) and &ltalert_text&gt")
-      .setBooleanPossibleValues()
-      .setDefaultValue(String.valueOf(false));
-
-    action.createParam("rules")
-      .setDescription("Filter on rules: setting it to true will return rules id and rule name for measure having such info " +
-        "(such as 'blocker_violations', 'critical_violations', ..., 'new_blocker_violations', ...). Possible values: true | false | list of rule ids")
-      .setBooleanPossibleValues()
-      .setDefaultValue(String.valueOf(true));
-
-    RailsHandler.addFormatParam(action);
   }
 
   private void defineSearchAction(NewController controller) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/ws/RemovedWebServiceHandler.java b/server/sonar-server/src/main/java/org/sonar/server/ws/RemovedWebServiceHandler.java
new file mode 100644 (file)
index 0000000..da2882c
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.ws;
+
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.RequestHandler;
+import org.sonar.api.server.ws.Response;
+import org.sonar.server.exceptions.ServerException;
+
+import static java.net.HttpURLConnection.HTTP_GONE;
+
+/**
+ * Used to declare web services that are removed
+ */
+public enum RemovedWebServiceHandler implements RequestHandler {
+
+  INSTANCE;
+
+  @Override
+  public void handle(Request request, Response response) throws Exception {
+    throw new ServerException(HTTP_GONE, String.format("The web service '%s' doesn't exists anymore, please read its documentation to use alternatives", request.getPath()));
+  }
+}
index e6530a01785f4ea19687043ea76c3684d3d8dabe..55c6dbdcc9d830e83c5c8a72d57a0cf8a4059fde 100644 (file)
@@ -23,6 +23,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.server.ws.RailsHandler;
 import org.sonar.api.server.ws.WebService;
+import org.sonar.server.ws.RemovedWebServiceHandler;
 import org.sonar.server.ws.WsTester;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -49,9 +50,9 @@ public class ResourcesWsTest {
   public void define_index_action() {
     WebService.Action action = controller.action("index");
     assertThat(action).isNotNull();
-    assertThat(action.handler()).isInstanceOf(RailsHandler.class);
+    assertThat(action.handler()).isInstanceOf(RemovedWebServiceHandler.class);
     assertThat(action.responseExampleAsString()).isNotEmpty();
-    assertThat(action.params()).hasSize(11);
+    assertThat(action.params()).isEmpty();
   }
 
   @Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/ws/RemovedWebServiceHandlerTest.java b/server/sonar-server/src/test/java/org/sonar/server/ws/RemovedWebServiceHandlerTest.java
new file mode 100644 (file)
index 0000000..747747d
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.ws;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.server.ws.Request;
+import org.sonar.server.exceptions.ServerException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class RemovedWebServiceHandlerTest {
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  @Test
+  public void throw_server_exception() throws Exception {
+    Request request = mock(Request.class);
+    when(request.getPath()).thenReturn("/api/resources/index");
+
+    try {
+      RemovedWebServiceHandler.INSTANCE.handle(request, null);
+      fail();
+    } catch (ServerException e) {
+      assertThat(e.getMessage()).isEqualTo("The web service '/api/resources/index' doesn't exists anymore, please read its documentation to use alternatives");
+      assertThat(e.httpCode()).isEqualTo(410);
+    }
+  }
+}
index 9fde244c889defa0263fda2cdc2b07c066ad7885..b5f695e2743c3cc468f378ce58366e76c6bdad9a 100644 (file)
@@ -99,343 +99,4 @@ class Api::ResourcesController < Api::ApiController
     end
   end
 
-  def index
-    begin
-      resource_id=params[:resource]
-      if resource_id
-        @resource=Project.by_key(resource_id)
-        @analysis=(@resource && @resource.last_analysis)
-        raise ApiException.new(404, "Resource [#{resource_id}] not found") if @analysis.nil?
-        raise ApiException.new(401, "Unauthorized") unless has_role?(:user, @resource)
-      else
-        @analysis=nil
-        if params['scopes'].blank? && params['qualifiers'].blank?
-          params['scopes']='PRJ'
-          params['qualifiers']='TRK'
-        end
-      end
-
-      # ---------- PARAMETERS
-      components_conditions=['snapshots.islast=:islast']
-      components_values={:islast => true}
-
-      load_measures=false
-      measures_conditions=[]
-      measures_values={}
-      measures_order = nil
-      measures_limit = nil
-      measures_by_component_uuid={}
-      measures=nil
-
-      if params['scopes']
-        components_conditions << 'projects.scope in (:scopes)'
-        components_values[:scopes]=params['scopes'].split(',')
-      end
-
-      if params['qualifiers']
-        components_conditions << 'projects.qualifier in (:qualifiers)'
-        components_values[:qualifiers]=params['qualifiers'].split(',')
-      end
-
-      if @analysis
-        depth=(params['depth'] ? params['depth'].to_i : 0)
-        if depth==0
-          components_conditions << 'projects.uuid=:component_uuid'
-          components_values[:component_uuid]=@resource.uuid
-
-        else
-          # negative : all the tree
-          components_conditions << 'projects.project_uuid = :project_uuid and projects.enabled=:enabled and (projects.uuid=:component_uuid OR projects.uuid_path LIKE :uuid_path)'
-          components_values[:component_uuid]=@resource.uuid
-          components_values[:project_uuid] = @resource.project_uuid
-          components_values[:enabled] = true
-          components_values[:uuid_path]="#{@resource.uuid_path}#{@resource.uuid}.%"
-        end
-      end
-
-      if params['metrics'] && params['metrics']!='false'
-        load_measures=true
-
-        if params['metrics']!='true'
-          metrics = Metric.by_keys(params[:metrics].split(','))
-          # Derby does not accept "metric_id in (NULL)"
-          # The workaround is to use the unknown id -1
-          if metrics.empty?
-            measures_conditions << 'project_measures.metric_id=-1'
-          else
-            measures_conditions << 'project_measures.metric_id IN (:metrics)'
-            measures_values[:metrics]=metrics.select { |m| m.id }
-          end
-          if metrics.size==1
-            measures_limit = (params[:limit] ? [params[:limit].to_i, 500].min : 500)
-            measures_order = "project_measures.value #{'DESC' if metrics.first.direction<0}"
-          end
-        end
-
-        measures_conditions << 'project_measures.person_id IS NULL'
-
-        measures = ProjectMeasure.all(:joins => [:analysis, :project],
-                                     :select => select_columns_for_measures,
-                                     :conditions => [(components_conditions + measures_conditions).join(' AND '), components_values.merge(measures_values)],
-                                     :order => measures_order,
-                                     # SONAR-6584 avoid OOM errors
-                                     :limit => measures_limit ? measures_limit : 10000)
-
-        measures.each do |measure|
-          measures_by_component_uuid[measure.component_uuid] ||= []
-          measures_by_component_uuid[measure.component_uuid] << measure
-        end
-
-        if measures_limit
-          components_conditions << 'projects.uuid IN (:component_uuids)'
-          components_values[:component_uuids] = measures_by_component_uuid.keys
-        end
-
-      end
-
-      # ---------- LOAD COMPONENTS
-      # H2 does not support empty lists, so short-breaking if no measures
-      if measures_limit && measures_by_component_uuid.empty?
-        components = []
-      else
-        components = Project.all(
-          :include => :last_analysis,
-          :conditions => [components_conditions.join(' AND '), components_values],
-          # SONAR-6584 avoid OOM errors
-          :limit => 500)
-      end
-
-      # ---------- APPLY SECURITY - remove unauthorized resources - only if no selected resource
-      if @resource.nil?
-        components = select_authorized(:user, components)
-      end
-
-      # ---------- PREPARE RESPONSE
-      components_by_uuid = {}
-      components.each do |c|
-        components_by_uuid[c.uuid]=c
-      end
-
-
-      # ---------- SORT RESOURCES
-      if load_measures && measures_order && measures && !measures.empty?
-        # components are sorted by measures
-        sorted_components = measures.map do |measure|
-          components_by_uuid[measure.component_uuid]
-        end
-      else
-        # no specific sort
-        sorted_components = components
-      end
-
-      sorted_components = sorted_components.uniq.compact
-
-      # ---------- FORMAT RESPONSE
-      objects={:sorted_components => sorted_components, :components_by_uuid => components_by_uuid, :measures_by_component_uuid => measures_by_component_uuid, :params => params}
-      respond_to do |format|
-        format.json { render :json => jsonp(to_json(objects)) }
-        format.xml { render :xml => to_xml(objects) }
-        format.text { render :text => text_not_supported }
-      end
-    rescue ApiException => e
-      render_error(e.msg, e.code)
-    end
-  end
-
-  private
-
-  def select_columns_for_measures
-    select_columns='project_measures.id,project_measures.value,project_measures.metric_id,project_measures.component_uuid,project_measures.text_value,project_measures.measure_data'
-    if params[:includetrends]=='true'
-      select_columns+=',project_measures.variation_value_1,project_measures.variation_value_2,project_measures.variation_value_3,project_measures.variation_value_4,project_measures.variation_value_5'
-    end
-    if params[:includealerts]=='true'
-      select_columns+=',project_measures.alert_status,project_measures.alert_text'
-    end
-    if params[:includedescriptions]=='true'
-      select_columns+=',project_measures.url,project_measures.description'
-    end
-    select_columns
-  end
-
-  def to_json(objects)
-    components = objects[:sorted_components]
-    components_by_uuid = objects[:components_by_uuid]
-    measures_by_component_uuid = objects[:measures_by_component_uuid]
-    params = objects[:params]
-
-    result=[]
-    components.each do |component|
-      measures = measures_by_component_uuid[component.uuid]
-      result << component_to_json(component, measures, params)
-    end
-    result
-  end
-
-  def to_xml(objects)
-    components = objects[:sorted_components]
-    components_by_uuid = objects[:components_by_uuid]
-    measures_by_component_uuid = objects[:measures_by_component_uuid]
-    params = objects[:params]
-
-    xml = Builder::XmlMarkup.new(:indent => 0)
-    xml.instruct!
-
-    xml.resources do
-      components.each do |component|
-        measures = measures_by_component_uuid[component.uuid]
-        component_to_xml(xml, component, measures, params)
-      end
-    end
-  end
-
-  def component_to_json(component, measures, options={})
-    verbose=(options[:verbose]=='true')
-    include_alerts=(options[:includealerts]=='true')
-    include_trends=(options[:includetrends]=='true')
-    include_descriptions=(options[:includedescriptions]=='true')
-
-    json = {
-      'id' => component.id,
-      'uuid' => component.uuid,
-      'key' => component.key,
-      'uuid' => component.uuid,
-      'name' => component.name,
-      'scope' => component.scope,
-      'qualifier' => component.qualifier,
-      'creationDate' => Api::Utils.format_datetime(component.created_at)}
-    json['date'] =  Api::Utils.format_datetime(component.last_analysis.created_at) if component.last_analysis
-    json['lname'] = component.long_name if component.long_name
-    json['lang']=component.language if component.language
-    json['version']= component.last_analysis.version if component.last_analysis && component.last_analysis.version
-    json['branch']=component.branch if component.branch
-    json['description']=component.description if component.description
-    if include_trends && component.last_analysis
-      json[:p1]=component.last_snapshot.period1_mode if component.last_analysis.period1_mode
-      json[:p1p]=component.last_analysis.period1_param if component.last_analysis.period1_param
-      json[:p1d]=Api::Utils.format_datetime(component.last_analysis.period1_date) if component.last_analysis.period1_date
-
-      json[:p2]=component.last_analysis.period2_mode if component.last_analysis.period2_mode
-      json[:p2p]=component.last_analysis.period2_param if component.last_analysis.period2_param
-      json[:p2d]=Api::Utils.format_datetime(component.last_analysis.period2_date) if component.last_analysis.period2_date
-
-      json[:p3]=component.last_analysis.period3_mode if component.last_analysis.period3_mode
-      json[:p3p]=component.last_analysis.period3_param if component.last_analysis.period3_param
-      json[:p3d]=Api::Utils.format_datetime(component.last_analysis.period3_date) if component.last_analysis.period3_date
-
-      json[:p4]=component.last_analysis.period4_mode if component.last_analysis.period4_mode
-      json[:p4p]=component.last_analysis.period4_param if component.last_analysis.period4_param
-      json[:p4d]=Api::Utils.format_datetime(component.last_analysis.period4_date) if component.last_analysis.period4_date
-
-      json[:p5]=component.last_analysis.period5_mode if component.last_analysis.period5_mode
-      json[:p5p]=component.last_analysis.period5_param if component.last_analysis.period5_param
-      json[:p5d]=Api::Utils.format_datetime(component.last_analysis.period5_date) if component.last_analysis.period5_date
-    end
-    if measures
-      json_measures=[]
-      json['msr']=json_measures
-      measures.select { |measure| !measure.metric.key.start_with?('new_') || include_trends }.each do |measure|
-        json_measure={}
-        json_measures<<json_measure
-        json_measure[:key]=measure.metric.name
-        json_measure[:name]=measure.metric.short_name if verbose
-        json_measure[:val]=measure.value.to_f if measure.value
-        json_measure[:frmt_val]=measure.formatted_value if measure.value
-        json_measure[:data]=measure.data if measure.data
-        json_measure[:description]=measure.description if include_descriptions && measure.description
-        json_measure[:url]=measure.url if include_descriptions && measure.url
-        if include_alerts
-          json_measure[:alert]=measure.alert_status
-          json_measure[:alert_text]=measure.alert_text
-        end
-        if include_trends
-          json_measure[:var1]=measure.variation_value_1.to_f if measure.variation_value_1
-          json_measure[:fvar1]=measure.format_numeric_value(measure.variation_value_1.to_f) if measure.variation_value_1
-          json_measure[:var2]=measure.variation_value_2.to_f if measure.variation_value_2
-          json_measure[:fvar2]=measure.format_numeric_value(measure.variation_value_2.to_f) if measure.variation_value_2
-          json_measure[:var3]=measure.variation_value_3.to_f if measure.variation_value_3
-          json_measure[:fvar3]=measure.format_numeric_value(measure.variation_value_3.to_f) if measure.variation_value_3
-          json_measure[:var4]=measure.variation_value_4.to_f if measure.variation_value_4
-          json_measure[:fvar4]=measure.format_numeric_value(measure.variation_value_4.to_f) if measure.variation_value_4
-          json_measure[:var5]=measure.variation_value_5.to_f if measure.variation_value_5
-          json_measure[:fvar5]=measure.format_numeric_value(measure.variation_value_5.to_f) if measure.variation_value_5
-        end
-      end
-    end
-    json
-  end
-
-  def component_to_xml(xml, component, measures, options={})
-    verbose=(options[:verbose]=='true')
-    include_alerts=(options[:includealerts]=='true')
-    include_trends=(options[:includetrends]=='true')
-    include_descriptions=(options[:includedescriptions]=='true')
-
-    xml.resource do
-      xml.id(component.id)
-      xml.key(component.key)
-      xml.name(component.name)
-      xml.lname(component.long_name) if component.long_name
-      xml.branch(component.branch) if component.branch
-      xml.scope(component.scope)
-      xml.qualifier(component.qualifier)
-      xml.lang(component.language) if component.language
-      xml.version(component.last_analysis.version) if component.last_analysis && component.last_analysis.version
-      xml.date(Api::Utils.format_datetime(component.last_analysis.created_at)) if component.last_analysis
-      xml.creationDate(Api::Utils.format_datetime(component.created_at))
-      xml.description(component.description) if include_descriptions && component.description
-
-      if include_trends && component.last_analysis
-        xml.period1(component.last_analysis.period1_mode) if component.last_analysis.period1_mode
-        xml.period1_param(component.last_analysis.period1_param) if component.last_analysis.period1_param
-        xml.period1_date(Api::Utils.format_datetime(component.last_analysis.period1_date)) if component.last_analysis.period1_date
-
-        xml.period2(component.last_analysis.period2_mode) if component.last_analysis.period2_mode
-        xml.period2_param(component.last_analysis.period2_param) if component.last_analysis.period2_param
-        xml.period2_date(Api::Utils.format_datetime(component.last_analysis.period2_date)) if component.last_analysis.period2_date
-
-        xml.period3(component.last_analysis.period3_mode) if component.last_analysis.period3_mode
-        xml.period3_param(component.last_analysis.period3_param) if component.last_analysis.period3_param
-        xml.period3_date(Api::Utils.format_datetime(component.last_analysis.period3_date)) if component.last_analysis.period3_date
-
-        xml.period4(component.last_analysis.period4_mode) if component.last_analysis.period4_mode
-        xml.period4_param(component.last_analysis.period4_param) if component.last_analysis.period4_param
-        xml.period4_date(Api::Utils.format_datetime(component.last_analysis.period4_date)) if component.last_analysis.period4_date
-
-        xml.period5(component.last_analysis.period5_mode) if component.last_analysis.period5_mode
-        xml.period5_param(component.last_analysis.period5_param) if component.last_analysis.period5_param
-        xml.period5_date(Api::Utils.format_datetime(component.last_analysis.period5_date)) if component.last_analysis.period5_date
-      end
-
-      if measures
-        measures.select { |measure| !measure.metric.key.start_with?('new_') || include_trends }.each do |measure|
-          xml.msr do
-            xml.key(measure.metric.name)
-            xml.name(measure.metric.short_name) if verbose
-            xml.val(measure.value.to_f) if measure.value
-            xml.frmt_val(measure.formatted_value) if measure.value
-            xml.data(measure.data) if measure.data
-            xml.description(measure.description) if include_descriptions && measure.description
-            xml.url(measure.url) if include_descriptions && measure.url
-            if include_alerts
-              xml.alert(measure.alert_status) if measure.alert_status
-              xml.alert_text(measure.alert_text) if measure.alert_text
-            end
-            if include_trends
-              xml.var1(measure.variation_value_1.to_f) if measure.variation_value_1
-              xml.fvar1(measure.format_numeric_value(measure.variation_value_1.to_f)) if measure.variation_value_1
-              xml.var2(measure.variation_value_2.to_f) if measure.variation_value_2
-              xml.fvar2(measure.format_numeric_value(measure.variation_value_2.to_f)) if measure.variation_value_2
-              xml.var3(measure.variation_value_3.to_f) if measure.variation_value_3
-              xml.fvar3(measure.format_numeric_value(measure.variation_value_3.to_f)) if measure.variation_value_3
-              xml.var4(measure.variation_value_4.to_f) if measure.variation_value_4
-              xml.fvar4(measure.format_numeric_value(measure.variation_value_4.to_f)) if measure.variation_value_4
-              xml.var5(measure.variation_value_5.to_f) if measure.variation_value_5
-              xml.fvar5(measure.format_numeric_value(measure.variation_value_5.to_f)) if measure.variation_value_5
-            end
-          end
-        end
-      end
-    end
-  end
 end