lib/gooddata/models/segment.rb in gooddata-0.6.53 vs lib/gooddata/models/segment.rb in gooddata-0.6.54

- old
+ new

@@ -13,14 +13,19 @@ require_relative '../mixins/rest_resource' require_relative '../mixins/uri_getter' module GoodData class Segment < Rest::Resource - SYNCHRONIZE_URI = '/gdc/domains/%s/segments/%s/synchronizeClients' + SYNCHRONIZE_URI = '/gdc/domains/%s/dataproducts/%s/segments/%s/synchronizeClients' + # + ProvisioningResult = Struct.new('ProvisioningResult', :id, :status, :project_uri, :error) + attr_accessor :domain + attr_writer :data_product + data_property_reader 'id' include Mixin::Links include Mixin::UriGetter @@ -41,14 +46,16 @@ fail ArgumentError, 'No :domain specified' if domain.nil? client = domain.client fail ArgumentError, 'No client specified' if client.nil? + data_product = opts[:data_product] + if id == :all GoodData::Segment.all(opts) else - result = client.get(domain.segments_uri + "/segments/#{CGI.escape(id)}") + result = client.get(base_uri(domain, data_product) + "/segments/#{CGI.escape(id)}") client.create(GoodData::Segment, result.merge('domain' => domain)) end end # Returns list of all segments for domain @@ -58,37 +65,56 @@ def all(opts = {}) domain = opts[:domain] fail 'Domain has to be passed in options' unless domain client = domain.client - results = client.get(domain.segments_uri + '/segments') - GoodData::Helpers.get_path(results, %w(segments items)).map { |i| client.create(GoodData::Segment, i.merge('domain' => domain)) } + data_product = opts[:data_product] + results = client.get(base_uri(domain, data_product) + '/segments') + GoodData::Helpers.get_path(results, %w(segments items)).map { |i| client.create(GoodData::Segment, i, domain: domain) } end + def base_uri(domain, data_product) + if data_product + GoodData::DataProduct::ONE_DATA_PRODUCT_PATH % { domain_name: domain.name, id: data_product.data_product_id } + else + domain.segments_uri + end + end + # Creates new segment from parameters passed # # @param data [Hash] Data for segment namely :segment_id and :master_project is accepted. Master_project can be given as either a PID or a Project instance # @param options [Hash] Trigger of schedule. Can be cron string or reference to another schedule. # @return [GoodData::Segment] New Segment instance def create(data = {}, options = {}) segment_id = data[:segment_id] - fail 'Custom ID has to be provided' if segment_id.blank? + fail 'segment_id has to be provided' if segment_id.blank? client = options[:client] - segment = client.create(GoodData::Segment, GoodData::Helpers.stringify_keys(SEGMENT_TEMPLATE).merge('domain' => options[:domain])) + segment = client.create(GoodData::Segment, GoodData::Helpers.stringify_keys(SEGMENT_TEMPLATE), options) segment.tap do |s| s.segment_id = segment_id s.master_project = data[:master_project] end end end def initialize(data) super @domain = data.delete('domain') + @data_product = nil @json = data end + def data_product + if @data_product + @data_product + else + json = client.get(data['links']['dataProduct']) + @data_product = client.create(GoodData::DataProduct, json) + end + end + # Segment id getter for the Segment. Called segment_id since id is a reserved word in ruby world # # @return [String] Segment id def segment_id data['id'] @@ -157,32 +183,32 @@ # @return [GoodData::Segment] Segment instance def save if uri client.put(uri, json) else - res = client.post(domain.segments_uri + '/segments', json) + res = client.post(self.class.base_uri(domain, @data_product ? data_product : nil) + '/segments', json) @json = res end self end - # Runs async process that walks thorugh segments and provisions projects if necessary. + # Runs async process that walks through segments and provisions projects if necessary. # # @return [Array] Returns array of results def synchronize_clients - sync_uri = SYNCHRONIZE_URI % [domain.obj_id, id] + sync_uri = SYNCHRONIZE_URI % [domain.obj_id, data_product.data_product_id, id] res = client.post sync_uri, nil # wait until the instance is created res = client.poll_on_response(res['asyncTask']['links']['poll'], :sleep_interval => 1) do |r| r['synchronizationResult'].nil? end client.create(ClientSynchronizationResult, res) end - def synchronize_processes(projects = [], options = { dataproduct: 'default' }) + def synchronize_processes(projects = []) projects = [projects] unless projects.is_a?(Array) projects = projects.map do |p| p = p.pid if p.respond_to?('pid') fail('wrong type of argument. Should be either project ID or path') unless GoodData::Project.project_id_or_path?(p) p.split('/').last @@ -196,11 +222,12 @@ } } } end - uri = '/gdc/internal/lcm/domains/%s/dataproducts/%s/segments/%s/syncProcesses' % [domain.obj_id, options[:dataproduct], id] + uri = '/gdc/internal/lcm/domains/%{domain}/dataproducts/%{dataproduct}/segments/%{segment}/syncProcesses' + uri = uri % { domain: domain.name, dataproduct: data_product.data_product_id, segment: segment_id } res = client.post(uri, body) client.poll_on_response(GoodData::Helpers.get_path(res, %w(asyncTask link poll)), sleep_interval: 1) do |r| r['syncedResult'].nil? end @@ -214,14 +241,34 @@ clients.peach(&:delete) if force client.delete(uri) if uri self rescue RestClient::BadRequest => e payload = GoodData::Helpers.parse_http_exception(e) - case GoodData::Helpers.get_path(payload) - when 'gdc.c4.conflict.domain.segment.contains_clients' - throw SegmentNotEmpty - else - raise e + e = SegmentNotEmpty if GoodData::Helpers.get_path(payload) == 'gdc.c4.conflict.domain.segment.contains_clients' + raise e + end + + def provision_client_projects(segments = []) + body = { + provisionClientProjects: { + segments: segments.empty? ? [segment_id] : segments + } + } + res = client.post(GoodData::DataProduct::ONE_DATA_PRODUCT_PATH % { domain_name: domain.name, id: data_product.data_product_id } + '/provisionClientProjects', body) + res = client.poll_on_code(res['asyncTask']['links']['poll']) + failed_count = GoodData::Helpers.get_path(res, %w(clientProjectProvisioningResult failed count), 0) + created_count = GoodData::Helpers.get_path(res, %w(clientProjectProvisioningResult created count), 0) + return Enumerator.new([]) if (failed_count + created_count).zero? + Enumerator.new do |y| + uri = GoodData::Helpers.get_path(res, %w(clientProjectProvisioningResult links details)) + loop do + result = client.get(uri) + (GoodData::Helpers.get_path(result, %w(clientProjectProvisioningResultDetails items)) || []).each do |item| + y << ProvisioningResult.new(item['id'], item['status'], item['project'], item['error']) + end + uri = GoodData::Helpers.get_path(res, %w(clientProjectProvisioningResultDetails paging next)) + break if uri.nil? + end end end end end