|
| 1 | +# frozen_string_literal: true |
| 2 | +# (C) 2019-2020 GoodData Corporation |
| 3 | +require_relative 'base_action' |
| 4 | + |
| 5 | +# Migrate date dimension urn:gooddata:date or urn:custom:date to urn:custom_v2:date |
| 6 | +module GoodData |
| 7 | + module LCM2 |
| 8 | + class MigrateGdcDateDimension < BaseAction |
| 9 | + DESCRIPTION = 'Migrate Gdc Date Dimension' |
| 10 | + DATE_DIMENSION_CUSTOM_V2 = 'urn:custom_v2:date' |
| 11 | + DATE_DIMENSION_OLD = %w[urn:gooddata:date urn:custom:date] |
| 12 | + |
| 13 | + PARAMS = define_params(self) do |
| 14 | + description 'Client Used for Connecting to GD' |
| 15 | + param :gdc_gd_client, instance_of(Type::GdClientType), required: true |
| 16 | + |
| 17 | + description 'Specifies how to synchronize LDM and resolve possible conflicts' |
| 18 | + param :synchronize_ldm, instance_of(Type::SynchronizeLDM), required: false, default: 'diff_against_master_with_fallback' |
| 19 | + |
| 20 | + description 'Synchronization Info' |
| 21 | + param :synchronize, array_of(instance_of(Type::SynchronizationInfoType)), required: true, generated: true |
| 22 | + end |
| 23 | + |
| 24 | + RESULT_HEADER = %i[from to status] |
| 25 | + |
| 26 | + class << self |
| 27 | + def call(params) |
| 28 | + results = [] |
| 29 | + params.synchronize.map do |segment_info| |
| 30 | + result = migrate_date_dimension(params, segment_info) |
| 31 | + results.concat(result) |
| 32 | + end |
| 33 | + |
| 34 | + { |
| 35 | + results: results |
| 36 | + } |
| 37 | + end |
| 38 | + |
| 39 | + def migrate_date_dimension(params, segment_info) |
| 40 | + results = [] |
| 41 | + client = params.gdc_gd_client |
| 42 | + latest_blueprint = segment_info[:from_blueprint] |
| 43 | + # don't migrate when latest master doesn't contain custom v2 date. |
| 44 | + return results unless contain_v2?(latest_blueprint) |
| 45 | + |
| 46 | + previous_blueprint = segment_info[:previous_master]&.blueprint |
| 47 | + # check latest master and previous master |
| 48 | + master_upgrade_datasets = get_upgrade_dates(latest_blueprint, previous_blueprint) if params[:synchronize_ldm].downcase == 'diff_against_master' && previous_blueprint |
| 49 | + unless master_upgrade_datasets&.empty? |
| 50 | + segment_info[:to].pmap do |entry| |
| 51 | + pid = entry[:pid] |
| 52 | + to_project = client.projects(pid) || fail("Invalid 'to' project specified - '#{pid}'") |
| 53 | + to_blueprint = to_project.blueprint |
| 54 | + upgrade_datasets = get_upgrade_dates(latest_blueprint, to_blueprint) |
| 55 | + next if upgrade_datasets.empty? |
| 56 | + |
| 57 | + message = get_upgrade_message(upgrade_datasets) |
| 58 | + |
| 59 | + results << { |
| 60 | + from: segment_info[:from], |
| 61 | + to: pid, |
| 62 | + status: to_project.upgrade_custom_v2(message) |
| 63 | + } |
| 64 | + end |
| 65 | + end |
| 66 | + |
| 67 | + results |
| 68 | + end |
| 69 | + |
| 70 | + def get_upgrade_dates(src_blueprint, dest_blueprint) |
| 71 | + dest_dates = get_date_dimensions(dest_blueprint) if dest_blueprint |
| 72 | + src_dates = get_date_dimensions(src_blueprint) if src_blueprint |
| 73 | + |
| 74 | + return false if dest_dates.empty? || src_dates.empty? |
| 75 | + |
| 76 | + upgrade_datasets = [] |
| 77 | + dest_dates.each do |dest| |
| 78 | + src_dim = get_date_dimension(src_blueprint, dest[:id]) |
| 79 | + next unless src_dim |
| 80 | + |
| 81 | + upgrade_datasets << src_dim[:identifier] if upgrade?(src_dim, dest) && src_dim[:identifier] |
| 82 | + end |
| 83 | + |
| 84 | + upgrade_datasets |
| 85 | + end |
| 86 | + |
| 87 | + def get_upgrade_message(upgrade_datasets) |
| 88 | + { |
| 89 | + upgrade: { |
| 90 | + dateDatasets: { |
| 91 | + upgrade: "exact", |
| 92 | + datasets: upgrade_datasets |
| 93 | + } |
| 94 | + } |
| 95 | + } |
| 96 | + end |
| 97 | + |
| 98 | + def upgrade?(src_dim, dest_dim) |
| 99 | + src_dim[:urn] == DATE_DIMENSION_CUSTOM_V2 && DATE_DIMENSION_OLD.any? { |e| dest_dim[:urn] == e } |
| 100 | + end |
| 101 | + |
| 102 | + def contain_v2?(blueprint) |
| 103 | + get_date_dimensions(blueprint).any? { |e| e[:urn] == DATE_DIMENSION_CUSTOM_V2 } |
| 104 | + end |
| 105 | + |
| 106 | + def get_date_dimension(blueprint, id) |
| 107 | + GoodData::Model::ProjectBlueprint.find_date_dimension(blueprint, id) |
| 108 | + end |
| 109 | + |
| 110 | + def get_date_dimensions(blueprint) |
| 111 | + GoodData::Model::ProjectBlueprint.date_dimensions(blueprint) |
| 112 | + end |
| 113 | + end |
| 114 | + end |
| 115 | + end |
| 116 | +end |
0 commit comments