/// <summary> /// Asynchronously sets the value for a single label on a dataset. The label will be added if it does /// not exist, or updated if it already exists. /// This method just creates a <see cref="DatasetReference"/> and delegates to <see cref="SetDatasetLabelAsync(DatasetReference, string, string, ModifyLabelsOptions, CancellationToken)"/>. /// </summary> /// <remarks> /// <para> /// The dataset is first fetched to retrieve the current values, then a patch call is made. /// </para> /// </remarks> /// <param name="datasetId">The dataset ID. Must not be null.</param> /// <param name="labelName">The name of the label. Must not be null.</param> /// <param name="labelValue">The new value of the label. Must not be null.</param> /// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <returns>A task representing the asynchronous operation. When complete, the result is /// the previous value of the label, or <c>null</c> if the label was not previously set.</returns> public virtual Task <string> SetDatasetLabelAsync(string datasetId, string labelName, string labelValue, ModifyLabelsOptions options = null, CancellationToken cancellationToken = default) => SetDatasetLabelAsync(GetDatasetReference(datasetId), labelName, labelValue, options, cancellationToken);
/// <summary> /// Sets the value for a single label on a dataset. The label will be added if it does /// not exist, or updated if it already exists. /// This method just creates a <see cref="DatasetReference"/> and delegates to <see cref="SetDatasetLabel(DatasetReference, string, string, ModifyLabelsOptions)"/>. /// </summary> /// <remarks> /// <para> /// The dataset is first fetched to retrieve the current values, then a patch call is made. /// </para> /// </remarks> /// <param name="projectId">The project ID. Must not be null.</param> /// <param name="datasetId">The dataset ID. Must not be null.</param> /// <param name="labelName">The name of the label. Must not be null.</param> /// <param name="labelValue">The new value of the label. Must not be null.</param> /// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param> /// <returns>The previous value of the label, or <c>null</c> if the label was not previously set.</returns> public virtual string SetDatasetLabel(string projectId, string datasetId, string labelName, string labelValue, ModifyLabelsOptions options = null) => SetDatasetLabel(GetDatasetReference(projectId, datasetId), labelName, labelValue, options);
/// <summary> /// Sets the value for a single label on a dataset. The label will be added if it does /// not exist, or updated if it already exists. /// </summary> /// <remarks> /// <para> /// The dataset is first fetched to retrieve the current values, then a patch call is made. /// </para> /// </remarks> /// <param name="datasetReference">A fully-qualified identifier for the dataset. Must not be null.</param> /// <param name="labelName">The name of the label. Must not be null.</param> /// <param name="labelValue">The new value of the label. Must not be null.</param> /// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param> /// <returns>The previous value of the label, or <c>null</c> if the label was not previously set.</returns> public virtual string SetDatasetLabel(DatasetReference datasetReference, string labelName, string labelValue, ModifyLabelsOptions options = null) => throw new NotImplementedException();
/// <summary> /// Asynchronously sets or removes one or more labels on the specified dataset. /// This method just creates a <see cref="DatasetReference"/> and delegates to <see cref="ModifyDatasetLabelsAsync(DatasetReference, IDictionary{string, string}, ModifyLabelsOptions, CancellationToken)"/>. /// </summary> /// <remarks> /// Each entry in <paramref name="labels" /> is treated as a label to set or remove. If the value is null, /// it will be removed from the dataset; otherwise, it will be set/added. Labels which do not have an entry /// in the dictionary will be ignored. /// </remarks> /// <param name="projectId">The project ID. Must not be null.</param> /// <param name="datasetId">The dataset ID. Must not be null.</param> /// <param name="labels">The labels to set. Must contain at least one entry; keys must not be null, but values may be (indicating label removal).</param> /// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <returns>A task representing the asynchronous operation. When complete, the result is /// a dictionary with the same keys as <paramref name="labels" />, and values indicating the corresponding label value /// before this operation completed. Labels which weren't present on the dataset before the modification have corresponding /// null values in the returned dictionary. /// </returns> public virtual Task <IDictionary <string, string> > ModifyDatasetLabelsAsync(string projectId, string datasetId, IDictionary <string, string> labels, ModifyLabelsOptions options = null, CancellationToken cancellationToken = default) => ModifyDatasetLabelsAsync(GetDatasetReference(projectId, datasetId), labels, options, cancellationToken);
/// <summary> /// Asynchronously sets or removes one or more labels on the specified dataset. /// </summary> /// <remarks> /// Each entry in <paramref name="labels" /> is treated as a label to set or remove. If the value is null, /// it will be removed from the dataset; otherwise, it will be set/added. Labels which do not have an entry /// in the dictionary will be ignored. /// </remarks> /// <param name="datasetReference">A fully-qualified identifier for the dataset. Must not be null.</param> /// <param name="labels">The labels to set. Must contain at least one entry; keys must not be null, but values may be (indicating label removal).</param> /// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <returns>A task representing the asynchronous operation. When complete, the result is /// a dictionary with the same keys as <paramref name="labels" />, and values indicating the corresponding label value /// before this operation completed. Labels which weren't present on the dataset before the modification have corresponding /// null values in the returned dictionary. /// </returns> public virtual Task <IDictionary <string, string> > ModifyDatasetLabelsAsync(DatasetReference datasetReference, IDictionary <string, string> labels, ModifyLabelsOptions options = null, CancellationToken cancellationToken = default) => throw new NotImplementedException();
/// <summary> /// Sets or removes one or more labels on the specified dataset. /// This method just creates a <see cref="DatasetReference"/> and delegates to <see cref="ModifyDatasetLabels(DatasetReference, IDictionary{string, string}, ModifyLabelsOptions)"/>. /// </summary> /// <remarks> /// Each entry in <paramref name="labels" /> is treated as a label to set or remove. If the value is null, /// it will be removed from the dataset; otherwise, it will be set/added. Labels which do not have an entry /// in the dictionary will be ignored. /// </remarks> /// <param name="projectId">The project ID. Must not be null.</param> /// <param name="datasetId">The dataset ID. Must not be null.</param> /// <param name="labels">The labels to set. Must contain at least one entry; keys must not be null, but values may be (indicating label removal).</param> /// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param> /// <returns> /// A dictionary with the same keys as <paramref name="labels" />, and values indicating the corresponding label value /// before this operation completed. Labels which weren't present on the dataset before the modification have corresponding /// null values in the returned dictionary. /// </returns> public virtual IDictionary <string, string> ModifyDatasetLabels(string projectId, string datasetId, IDictionary <string, string> labels, ModifyLabelsOptions options = null) => ModifyDatasetLabels(GetDatasetReference(projectId, datasetId), labels, options);
/// <summary> /// Sets or removes one or more labels on the specified dataset. /// </summary> /// <remarks> /// Each entry in <paramref name="labels" /> is treated as a label to set or remove. If the value is null, /// it will be removed from the dataset; otherwise, it will be set/added. Labels which do not have an entry /// in the dictionary will be ignored. /// </remarks> /// <param name="datasetReference">A fully-qualified identifier for the dataset. Must not be null.</param> /// <param name="labels">The labels to set. Must contain at least one entry; keys must not be null, but values may be (indicating label removal).</param> /// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param> /// <returns> /// A dictionary with the same keys as <paramref name="labels" />, and values indicating the corresponding label value /// before this operation completed. Labels which weren't present on the dataset before the modification have corresponding /// null values in the returned dictionary. /// </returns> public virtual IDictionary <string, string> ModifyDatasetLabels(DatasetReference datasetReference, IDictionary <string, string> labels, ModifyLabelsOptions options = null) => throw new NotImplementedException();
/// <summary> /// Clears all labels on the specified dataset within this client's project. /// This method just creates a <see cref="DatasetReference"/> and delegates to <see cref="ClearDatasetLabels(DatasetReference, ModifyLabelsOptions)"/>. /// </summary> /// <param name="datasetId">The dataset ID. Must not be null.</param> /// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param> /// <returns>A dictionary with the labels on the dataset before they were cleared.</returns> public virtual IDictionary <string, string> ClearDatasetLabels(string datasetId, ModifyLabelsOptions options = null) => ClearDatasetLabels(GetDatasetReference(datasetId), options);
/// <summary> /// Asynchronously clears all labels on the specified dataset within this client's project. /// This method just creates a <see cref="DatasetReference"/> and delegates to <see cref="ClearDatasetLabelsAsync(DatasetReference, ModifyLabelsOptions, CancellationToken)"/>. /// </summary> /// <param name="datasetId">The dataset ID. Must not be null.</param> /// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <returns>A task representing the asynchronous operation. When complete, the result is /// a dictionary with the labels on the dataset before they were cleared.</returns> public virtual Task <IDictionary <string, string> > ClearDatasetLabelsAsync(string datasetId, ModifyLabelsOptions options = null, CancellationToken cancellationToken = default) => ClearDatasetLabelsAsync(GetDatasetReference(datasetId), options, cancellationToken);
/// <summary> /// Asynchronously removes a label from a dataset, if it previously existed. It is not an error to /// attempt to remove a label that doesn't already exist. /// This method just creates a <see cref="DatasetReference"/> and delegates to <see cref="RemoveDatasetLabelAsync(DatasetReference, string, ModifyLabelsOptions, CancellationToken)"/>. /// </summary> /// <param name="projectId">The project ID. Must not be null.</param> /// <param name="datasetId">The dataset ID. Must not be null.</param> /// <param name="labelName">The name of the label. Must not be null.</param> /// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <returns>A task representing the asynchronous operation. When complete, the result is /// the previous value of the label, or <c>null</c> if the label was not previously set.</returns> public virtual Task <string> RemoveDatasetLabelAsync(string projectId, string datasetId, string labelName, ModifyLabelsOptions options = null, CancellationToken cancellationToken = default) => RemoveDatasetLabelAsync(GetDatasetReference(projectId, datasetId), labelName, options, cancellationToken);
/// <summary> /// Asynchronously removes a label from a dataset, if it previously existed. It is not an error to /// attempt to remove a label that doesn't already exist. /// </summary> /// <param name="datasetReference">A fully-qualified identifier for the dataset. Must not be null.</param> /// <param name="labelName">The name of the label. Must not be null.</param> /// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <returns>A task representing the asynchronous operation. When complete, the result is /// the previous value of the label, or <c>null</c> if the label was not previously set.</returns> public virtual Task <string> RemoveDatasetLabelAsync(DatasetReference datasetReference, string labelName, ModifyLabelsOptions options = null, CancellationToken cancellationToken = default) => throw new NotImplementedException();
/// <summary> /// Removes a label from a dataset, if it previously existed. It is not an error to /// attempt to remove a label that doesn't already exist. /// This method just creates a <see cref="DatasetReference"/> and delegates to <see cref="RemoveDatasetLabel(DatasetReference, string, ModifyLabelsOptions)"/>. /// </summary> /// <param name="datasetId">The dataset ID. Must not be null.</param> /// <param name="labelName">The name of the label. Must not be null.</param> /// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param> /// <returns>The previous value of the label, or <c>null</c> if the label was not previously set.</returns> public virtual string RemoveDatasetLabel(string datasetId, string labelName, ModifyLabelsOptions options = null) => RemoveDatasetLabel(GetDatasetReference(datasetId), labelName, options);
// Most of the work is done here... /// <inheritdoc /> public override IDictionary <string, string> ModifyDatasetLabels(DatasetReference datasetReference, IDictionary <string, string> labels, ModifyLabelsOptions options = null) { GaxPreconditions.CheckNotNull(datasetReference, nameof(datasetReference)); GaxPreconditions.CheckNotNull(labels, nameof(labels)); int retries = options?.Retries ?? ModifyLabelsOptions.DefaultRetries; var getOptions = new GetDatasetOptions { ETag = options?.ETag }; while (true) { // Outside the catch, as we don't need to retry if *this* fails the precondition. // If the dataset originally has the "right" version but then changes before we patch it, we'll end up retrying this // part as well, and it will immediately fail. var dataset = GetDataset(datasetReference, getOptions); try { var existingLabels = dataset.Resource.Labels ?? new Dictionary <string, string>(); var differences = GetDifferences(labels, existingLabels); // If everything's already as we want it to be, we don't need to patch. if (differences.Count != 0) { dataset.Patch(new Dataset { Labels = differences }, matchETag: true); } var oldValues = new Dictionary <string, string>(); foreach (var entry in labels) { existingLabels.TryGetValue(entry.Key, out string existingValue); oldValues[entry.Key] = existingValue; // May be null } return(oldValues); } catch (GoogleApiException e) when(retries > 0 && e.HttpStatusCode == HttpStatusCode.PreconditionFailed) { retries--; // No delay here: we're only trying to catch the case where another change is made between Get/Patch. } } }
/// <inheritdoc /> public override async Task <string> SetDatasetLabelAsync(DatasetReference datasetReference, string labelName, string labelValue, ModifyLabelsOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { GaxPreconditions.CheckNotNull(datasetReference, nameof(DatasetReference)); GaxPreconditions.CheckNotNull(labelName, nameof(labelName)); GaxPreconditions.CheckNotNull(labelValue, nameof(labelValue)); var newLabels = new Dictionary <string, string> { [labelName] = labelValue }; var oldLabels = await ModifyDatasetLabelsAsync(datasetReference, newLabels, options, cancellationToken).ConfigureAwait(false); return(oldLabels[labelName]); }
/// <inheritdoc /> public override string SetDatasetLabel(DatasetReference datasetReference, string labelName, string labelValue, ModifyLabelsOptions options = null) { GaxPreconditions.CheckNotNull(datasetReference, nameof(DatasetReference)); GaxPreconditions.CheckNotNull(labelName, nameof(labelName)); GaxPreconditions.CheckNotNull(labelValue, nameof(labelValue)); var newLabels = new Dictionary <string, string> { [labelName] = labelValue }; var oldLabels = ModifyDatasetLabels(datasetReference, newLabels, options); return(oldLabels[labelName]); }
/// <inheritdoc /> public override async Task <IDictionary <string, string> > ClearDatasetLabelsAsync(DatasetReference datasetReference, ModifyLabelsOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { GaxPreconditions.CheckNotNull(datasetReference, nameof(datasetReference)); int retries = options?.Retries ?? ModifyLabelsOptions.DefaultRetries; var getOptions = new GetDatasetOptions { ETag = options?.ETag }; while (true) { // Outside the catch, as we don't need to retry if *this* fails the precondition. // If the dataset originally has the "right" version but then changes before we patch it, we'll end up retrying this // part as well, and it will immediately fail. var dataset = await GetDatasetAsync(datasetReference, getOptions, cancellationToken).ConfigureAwait(false); try { var existingLabels = dataset.Resource.Labels; if (existingLabels == null || existingLabels.Count == 0) { return(new Dictionary <string, string>()); } var labels = existingLabels.Keys.ToDictionary(key => key, key => (string)null); await dataset.PatchAsync(new Dataset { Labels = labels }, matchETag : true, cancellationToken : cancellationToken).ConfigureAwait(false); return(existingLabels); } catch (GoogleApiException e) when(retries > 0 && e.HttpStatusCode == HttpStatusCode.PreconditionFailed) { retries--; // No delay here: we're only trying to catch the case where another change is made between Get/Patch. } } }