/// <summary>
 /// Serializes the object to JSON.
 /// </summary>
 /// <param name="writer">The <see cref="T: Newtonsoft.Json.JsonWriter" /> to write to.</param>
 /// <param name="obj">The object to serialize to JSON.</param>
 internal static void Serialize(JsonWriter writer, FabricError obj)
 {
     // Required properties are always serialized, optional properties are serialized when not null.
     writer.WriteStartObject();
     writer.WriteProperty(obj.Error, "Error", FabricErrorErrorConverter.Serialize);
     writer.WriteEndObject();
 }
        /// <summary>
        /// Reads JSON to create a particular Retention policy Type
        /// </summary>
        /// <returns>Retention Type Object created from JSON</returns>
        public override object ReadJson(JsonReader reader,
                                        Type objectType,
                                        object existingValue,
                                        JsonSerializer serializer)
        {
            RetentionPolicy retentionPolicy        = null;
            JObject         retentionPolicyJObject = JObject.Load(reader);

            // RetentionPolicyType is optional as only Basic Type is there.
            if ("Basic".Equals(retentionPolicyJObject["RetentionPolicyType"].Value <string>()))
            {
                retentionPolicy = new BasicRetentionPolicy();
            }
            else
            {
                var fabricError = new FabricError
                {
                    Message = string.Format("Invalid Retention policy Type {0} ", retentionPolicyJObject["RetentionPolicyType"].Value <string>()),
                    Code    = NativeTypes.FABRIC_ERROR_CODE.E_INVALIDARG,
                };

                throw new HttpResponseException(new FabricErrorError(fabricError).ToHttpResponseMessage());
            }
            serializer.Populate(retentionPolicyJObject.CreateReader(), retentionPolicy);
            return(retentionPolicy);
        }
        /// <summary>
        /// Sends an HTTP get request to cluster http gateway.
        /// </summary>
        /// <param name="requestFunc">Func to create HttpRequest to send.</param>
        /// <param name="relativeUri">The relative URI.</param>
        /// <param name="requestId">Request Id for corelation</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The payload of the GET response.</returns>
        /// <exception cref="ServiceFabricException">When the response is not a success.</exception>
        private async Task <HttpResponseMessage> SendAsyncHandleUnsuccessfulResponse(
            Func <HttpRequestMessage> requestFunc,
            string relativeUri,
            string requestId,
            CancellationToken cancellationToken)
        {
            var response = await this.SendAsyncHandleSecurityExceptions(relativeUri, requestId, requestFunc, cancellationToken);

            if (response.IsSuccessStatusCode)
            {
                return(response);
            }

            var message = string.Format(
                SR.ErrorHttpOperationUnsuccessfulFormatString,
                relativeUri,
                response.StatusCode,
                response.ReasonPhrase,
                response.RequestMessage);

            ServiceFabricHttpClientEventSource.Current.ErrorResponse($"{this.ClientId}:{requestId}", message);

            if (response.Content != null)
            {
                FabricError error = null;

                try
                {
                    var contentStream = await response.Content.ReadAsStreamAsync();

                    using (var streamReader = new StreamReader(contentStream))
                    {
                        using (var reader = new JsonTextReader(streamReader))
                        {
                            error = FabricErrorConverter.Deserialize(reader);
                        }
                    }
                }
                catch (JsonReaderException)
                {
                    throw new ServiceFabricException(
                              $"Server returned error while processing the request but did not provide a meaningful error response. Response Error Code {response.StatusCode}");
                }

                if (error != null)
                {
                    throw new ServiceFabricException($"{error.Error.Code.ToString()}. {error.Error.Message}");
                }
            }
            else
            {
                throw new ServiceFabricException(
                          $"Server returned error while processing the request but did not provide a meaningful error response. Response Error Code {response.StatusCode}");
            }

            return(response);
        }
Exemple #4
0
        /// <summary>
        /// Reads JSON to create a particular Backup Storage Type
        /// </summary>
        /// <returns> Backup storage type Object from JSON</returns>
        public override object ReadJson(JsonReader reader,
                                        Type objectType,
                                        object existingValue,
                                        JsonSerializer serializer)
        {
            BackupStorage backupStorage;

            if (IsNullValueAllowed)
            {
                // Backup storage can be null
                if (reader.TokenType == JsonToken.Null)
                {
                    return(null);
                }
            }

            var backupStorageJObject = JObject.Load(reader);

            if (backupStorageJObject["StorageKind"] == null)
            {
                var fabricError = new FabricError
                {
                    Message = string.Format("StorageType is Required"),
                    Code    = NativeTypes.FABRIC_ERROR_CODE.E_INVALIDARG,
                };

                throw new HttpResponseException(new FabricErrorError(fabricError).ToHttpResponseMessage());
            }

            switch (backupStorageJObject["StorageKind"].Value <string>())
            {
            case "FileShare":
                backupStorage = new FileShareBackupStorageInfo();
                break;

            case "AzureBlobStore":
                backupStorage = new AzureBlobBackupStorageInfo();
                break;

            case "DsmsAzureBlobStore":
                backupStorage = new DsmsAzureBlobBackupStorageInfo();
                break;

            default:
                var fabricError = new FabricError
                {
                    Message = string.Format(String.Format("Invalid StorageKind {0} ", backupStorageJObject["StorageKind"].Value <string>())),
                    Code    = NativeTypes.FABRIC_ERROR_CODE.E_INVALIDARG,
                };

                throw new HttpResponseException(new FabricErrorError(fabricError).ToHttpResponseMessage());
            }

            serializer.Populate(backupStorageJObject.CreateReader(), backupStorage);
            return(backupStorage);
        }
Exemple #5
0
        protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request,
                                                                      CancellationToken cancellationToken)
        {
            if (this.ValidateRequestIdentity(request))
            {
                return(await base.SendAsync(request, cancellationToken));
            }

            FabricError fabricError = new FabricError()
            {
                Message = "Access Denied.",
                Code    = NativeTypes.FABRIC_ERROR_CODE.E_ACCESSDENIED
            };

            BackupRestoreTrace.TraceSource.WriteWarning(TraceType, "Access Denied for message {0}", request.ToString());
            return(new FabricErrorError(fabricError).ToHttpResponseMessage());
        }
Exemple #6
0
        protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            IEnumerable <string> xRoleHeaderValues = null;

            if (request.Headers.TryGetValues(BackupRestoreEndPointsConstants.FabricXRoleHeaderKey, out xRoleHeaderValues)
                )
            {
                foreach (var xRoleHeaderValue in xRoleHeaderValues)
                {
                    FabricXRole fabricXRole = FabricXRole.Invalid;
                    if (Enum.TryParse(xRoleHeaderValue, out fabricXRole))
                    {
                        switch (fabricXRole)
                        {
                        case FabricXRole.Admin:
                        case FabricXRole.All:
                            return(await base.SendAsync(request, cancellationToken));

                        case FabricXRole.User:
                            if (request.Method == HttpMethod.Get)
                            {
                                return(await base.SendAsync(request, cancellationToken));
                            }
                            break;

                        case FabricXRole.None:
                            if (serverAuthCredentialType == CredentialType.None)
                            {
                                return(await base.SendAsync(request, cancellationToken));
                            }
                            break;
                        }
                    }
                }
            }
            FabricError fabricError = new FabricError()
            {
                Message = "Access Denied.",
                Code    = NativeTypes.FABRIC_ERROR_CODE.E_ACCESSDENIED
            };

            BackupRestoreTrace.TraceSource.WriteWarning(TraceType, "Access Denied for message {0}", request.ToString());
            return(new FabricErrorError(fabricError).ToHttpResponseMessage());
        }
        /// <summary>
        /// Reads the JSON representation of the object.
        /// </summary>
        /// <param name = "reader">JsonReader to read from.</param>
        /// <param name = "objectType">Type of the object.</param>
        /// <param name = "existingValue">The existing value of object being read.</param>
        /// <param name = "serializer">The calling serializer.</param>
        /// <returns>The object value.</returns>
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.String)
            {
                try
                {
                    return(DateTime.ParseExact(
                               (string)reader.Value,
                               datetimeFormatStrings,
                               CultureInfo.InvariantCulture,
                               DateTimeStyles.AdjustToUniversal));
                }
                catch (Exception)
                {
                    // datetime could be given as ticks
                }
                try
                {
                    long ticks = long.Parse((string)reader.Value, CultureInfo.InvariantCulture);
                    return(NativeTypes.FromNativeTicks(ticks));
                }
                catch (Exception)
                {
                    var fabricError = new FabricError
                    {
                        Message = string.Format(String.Format("Invalid DateTime format {0} ", reader.Value)),
                        Code    = NativeTypes.FABRIC_ERROR_CODE.E_INVALIDARG,
                    };

                    throw new HttpResponseException(new FabricErrorError(fabricError).ToHttpResponseMessage());
                }
            }
            else
            {
                var fabricError = new FabricError
                {
                    Message = string.Format(String.Format("Invalid DateTime format {0} ", reader.Value)),
                    Code    = NativeTypes.FABRIC_ERROR_CODE.E_INVALIDARG,
                };

                throw new HttpResponseException(new FabricErrorError(fabricError).ToHttpResponseMessage());
            }
        }
        /// <summary>
        /// Reads JSON to create a particular Retention policy Type
        /// </summary>
        /// <returns>Retention Type Object created from JSON</returns>
        public override object ReadJson(JsonReader reader,
                                        Type objectType,
                                        object existingValue,
                                        JsonSerializer serializer)
        {
            BackupEntity backupEntity           = null;
            JObject      retentionPolicyJObject = JObject.Load(reader);

            if (retentionPolicyJObject["EntityKind"] == null)
            {
                var fabricError = new FabricError
                {
                    Message = string.Format("EntityKind is Required"),
                    Code    = NativeTypes.FABRIC_ERROR_CODE.E_INVALIDARG,
                };

                throw new HttpResponseException(new FabricErrorError(fabricError).ToHttpResponseMessage());
            }
            if ("Application".Equals(retentionPolicyJObject["EntityKind"].Value <string>()))
            {
                backupEntity = new ApplicationBackupEntity();
            }
            else if ("Service".Equals(retentionPolicyJObject["EntityKind"].Value <string>()))
            {
                backupEntity = new ServiceBackupEntity();
            }
            else if ("Partition".Equals(retentionPolicyJObject["EntityKind"].Value <string>()))
            {
                backupEntity = new PartitionBackupEntity();
            }
            else
            {
                var fabricError = new FabricError
                {
                    Message = string.Format("Invalid Backup Entitiy Type {0} ", retentionPolicyJObject["EntityKind"].Value <string>()),
                    Code    = NativeTypes.FABRIC_ERROR_CODE.E_INVALIDARG,
                };

                throw new HttpResponseException(new FabricErrorError(fabricError).ToHttpResponseMessage());
            }
            serializer.Populate(retentionPolicyJObject.CreateReader(), backupEntity);
            return(backupEntity);
        }
Exemple #9
0
        /// <summary>
        /// Reads JSON to create a particular Schedule policy Type
        /// </summary>
        /// <returns> Schedule Policy Type Object from JSON</returns>
        public override object ReadJson(JsonReader reader,
                                        Type objectType,
                                        object existingValue,
                                        JsonSerializer serializer)
        {
            BackupSchedule backupSchedule        = null;
            JObject        schedulePolicyJObject = JObject.Load(reader);

            if (schedulePolicyJObject["ScheduleKind"] == null)
            {
                var fabricError = new FabricError
                {
                    Message = " ScheduleKind is Required",
                    Code    = NativeTypes.FABRIC_ERROR_CODE.E_INVALIDARG
                };

                throw new HttpResponseException(new FabricErrorError(fabricError).ToHttpResponseMessage());
            }
            if ("TimeBased".Equals(schedulePolicyJObject["ScheduleKind"].Value <string>()))
            {
                backupSchedule = new TimeBasedBackupSchedule();
            }
            else if ("FrequencyBased".Equals(
                         schedulePolicyJObject["ScheduleKind"].Value <string>()))
            {
                backupSchedule = new FrequencyBasedBackupSchedule();
            }
            else
            {
                var fabricError = new FabricError
                {
                    Message = string.Format("Invalid Schedule Type {0}", schedulePolicyJObject["ScheduleKind"].Value <string>()),
                    Code    = NativeTypes.FABRIC_ERROR_CODE.E_INVALIDARG
                };

                throw new HttpResponseException(new FabricErrorError(fabricError).ToHttpResponseMessage());
            }
            serializer.Populate(schedulePolicyJObject.CreateReader(), backupSchedule);
            return(backupSchedule);
        }
        protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request,
                                                                      CancellationToken cancellationToken)
        {
            X509Certificate2 x509Certificate2 = request.GetClientCertificate();

            if ((x509Certificate2 != null) && (x509Certificate2.IsValid()) &&
                ((this.fabricBrSecuritySetting.ServerAuthX509FindType == X509FindType.FindByThumbprint) && this.ValidateRequestCertificateThumbprint(x509Certificate2) ||
                 (this.fabricBrSecuritySetting.ServerAuthX509FindType == X509FindType.FindBySubjectName) && this.ValidateRequestCertificateByCommonName(x509Certificate2))
                )
            {
                return(await base.SendAsync(request, cancellationToken));
            }

            FabricError fabricError = new FabricError()
            {
                Message = "Access Denied.",
                Code    = NativeTypes.FABRIC_ERROR_CODE.E_ACCESSDENIED
            };

            BackupRestoreTrace.TraceSource.WriteWarning(TraceType, "Access Denied for message {0}", request.ToString());
            return(new FabricErrorError(fabricError).ToHttpResponseMessage());
        }
Exemple #11
0
        internal string GetFabricRequestFromRequstHeader()
        {
            string fabricRequest;

            try
            {
                var headers = Request.Headers.GetValues(BackupRestoreEndPointsConstants.FabricUriHeaderKey);
                fabricRequest = headers.FirstOrDefault();
            }
            catch (Exception)
            {
                var fabricError = new FabricError
                {
                    Message = StringResources.InvalidRequestHeader,
                    Code    = NativeTypes.FABRIC_ERROR_CODE.E_INVALIDARG
                };

                throw new HttpResponseException(new FabricErrorError(fabricError).ToHttpResponseMessage());
            }

            return(fabricRequest);
        }
Exemple #12
0
        internal async Task <TResult> RunAsync <TResult>(BaseOperation <TResult> operationBase, int timeoutInSeconds)
        {
            var cancellationTokenSource = new CancellationTokenSource();

            if (timeoutInSeconds <= 0)
            {
                throw new ArgumentException(StringResources.InvalidTimeout);
            }

            var timeout = new TimeSpan(0, 0, timeoutInSeconds);

            cancellationTokenSource.CancelAfter(timeout);
            BackupRestoreTrace.TraceSource.WriteInfo(TraceType, "Controller {0} Operation requested : {1}", this.GetType(), operationBase);
            await this.ValidateInput();

            do
            {
                try
                {
                    this._retryCount++;
                    return(await operationBase.RunAsyncWrappper(timeout, cancellationTokenSource.Token));
                }
                catch (HttpResponseException)
                {
                    throw;
                }
                catch (Exception exception)
                {
                    this.LogException(TraceType, exception);
                    var fabricException = exception as FabricException;
                    if (fabricException != null)
                    {
                        var fabricError = new FabricError(fabricException);
                        var fabricBackupRestoreError = new FabricErrorError(fabricError);
                        throw new HttpResponseException(fabricBackupRestoreError.ToHttpResponseMessage());
                    }
                    else if (exception is ArgumentException)
                    {
                        FabricErrorError fabricBackupRestoreError = new FabricErrorError(new FabricError()
                        {
                            Code    = NativeTypes.FABRIC_ERROR_CODE.E_INVALIDARG,
                            Message = exception.Message
                        });
                        throw new HttpResponseException(fabricBackupRestoreError.ToHttpResponseMessage());
                    }
                    else if (exception is OperationCanceledException || exception is TimeoutException)
                    {
                        FabricErrorError fabricBackupRestoreError = new FabricErrorError(new FabricError()
                        {
                            Code    = NativeTypes.FABRIC_ERROR_CODE.FABRIC_E_TIMEOUT,
                            Message = StringResources.RequestTimeout
                        });
                        throw new HttpResponseException(fabricBackupRestoreError.ToHttpResponseMessage());
                    }
                    else if (exception is FabricBackupRestoreLocalRetryException)  //TODO Remove this and change to correct message
                    {
                        if (this._retryCount >= MaxRetryCount)
                        {
                            throw;
                        }
                    }
                    else
                    {
                        var stringBuilder = new StringBuilder();
                        if (exception is AggregateException)
                        {
                            var aggregateException = (AggregateException)exception;
                            foreach (var innerException in aggregateException.InnerExceptions)
                            {
                                stringBuilder.AppendFormat("{0} ,", innerException.Message).AppendLine();
                            }
                        }
                        else
                        {
                            stringBuilder.AppendFormat("{0}", exception.Message);
                        }
                        FabricErrorError fabricBackupRestoreError = new FabricErrorError(new FabricError()
                        {
                            Message = stringBuilder.ToString(),
                            Code    = NativeTypes.FABRIC_ERROR_CODE.E_UNEXPECTED
                        });
                        throw new HttpResponseException(fabricBackupRestoreError.ToHttpResponseMessage());
                    }
                }
            } while (this._retryCount <= MaxRetryCount);
            throw new HttpResponseException(HttpStatusCode.InternalServerError);
        }
Exemple #13
0
        internal async Task <TResult> RunAsync <TResult>(BaseOperation <TResult> operationBase, int timeoutInSeconds = (2 * 60))
        {
            var cancellationTokenSource = new CancellationTokenSource();

            if (timeoutInSeconds <= 0)
            {
                throw new ArgumentException("Invalid Timeout");
            }

            var timeout = new TimeSpan(0, 0, timeoutInSeconds);

            cancellationTokenSource.CancelAfter(timeout);

            await this.ValidateInputAsync();

            try
            {
                var startTime = DateTimeOffset.UtcNow;

                var results = await operationBase.RunAsyncWrappper(timeout, cancellationTokenSource.Token).ConfigureAwait(false);

                return(results);
            }
            catch (Exception exception)
            {
                FabricEvents.Events.EventStoreFailed(operationBase.GetSupportedEntityType().ToString(), ExtractDetails(exception));

                if (exception is ConnectionParsingException)
                {
                    // This indicates to the caller that the API's are not available as the connection information is not configured.
                    throw new HttpResponseException(HttpStatusCode.ServiceUnavailable);
                }

                if (exception is HttpResponseException)
                {
                    throw;
                }

                var fabricException = exception as FabricException;
                if (fabricException != null)
                {
                    var fabricError = new FabricError(fabricException);
                    var fabricBackupRestoreError = new FabricErrorError(fabricError);
                    throw new HttpResponseException(fabricBackupRestoreError.ToHttpResponseMessage());
                }
                else if (exception is ArgumentException)
                {
                    FabricErrorError fabricEventStoreSvcErrorMessage = new FabricErrorError(
                        new FabricError
                    {
                        Code    = NativeTypes.FABRIC_ERROR_CODE.E_INVALIDARG,
                        Message = exception.Message
                    });
                    throw new HttpResponseException(fabricEventStoreSvcErrorMessage.ToHttpResponseMessage());
                }
                else if (exception is OperationCanceledException || exception is TimeoutException)
                {
                    FabricErrorError fabricEventStoreSvcErrorMessage = new FabricErrorError(
                        new FabricError
                    {
                        Code    = NativeTypes.FABRIC_ERROR_CODE.FABRIC_E_TIMEOUT,
                        Message = "Timeout"
                    });
                    throw new HttpResponseException(fabricEventStoreSvcErrorMessage.ToHttpResponseMessage());
                }
                else
                {
                    var stringBuilder = new StringBuilder();
                    if (exception is AggregateException)
                    {
                        var aggregateException = (AggregateException)exception;
                        foreach (var innerException in aggregateException.InnerExceptions)
                        {
                            stringBuilder.AppendFormat("{0} ,", innerException.Message).AppendLine();
                        }
                    }
                    else
                    {
                        stringBuilder.AppendFormat("{0}", exception.Message);
                    }
                    FabricErrorError fabricEventStoreSvcErrorMessage = new FabricErrorError(
                        new FabricError
                    {
                        Message = stringBuilder.ToString(),
                        Code    = NativeTypes.FABRIC_ERROR_CODE.E_UNEXPECTED
                    });
                    throw new HttpResponseException(fabricEventStoreSvcErrorMessage.ToHttpResponseMessage());
                }
            }

            throw new HttpResponseException(HttpStatusCode.InternalServerError);
        }
Exemple #14
0
        /// <summary>
        /// Sends an HTTP get request to cluster http gateway.
        /// </summary>
        /// <param name="requestFunc">Func to create HttpRequest to send.</param>
        /// <param name="requestUri">Request Uri.</param>
        /// <param name="clientRequestId">Request Id for corelation</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The payload of the GET response.</returns>
        /// <exception cref="ServiceFabricException">When the response is not a success.</exception>
        private async Task <HttpResponseMessage> SendAsyncHandleUnsuccessfulResponse(
            Func <HttpRequestMessage> requestFunc,
            Uri requestUri,
            string clientRequestId,
            CancellationToken cancellationToken)
        {
            HttpRequestMessage FinalRequestFunc()
            {
                var request = requestFunc.Invoke();

                request.RequestUri = requestUri;

                // Add claims token to request if needed.
                this.bearerTokenHandler.AddTokenToRequest(request);

                // Add client request id to header for corelation on server.
                request.Headers.Add(Constants.ServiceFabricHttpRequestIdHeaderName, $"{clientRequestId}");
                request.Headers.Add(Constants.ServiceFabricHttpClientTypeHeaderName, $"{this.ClientTypeHeaderValue}");
                return(request);
            }

            var response = await this.SendAsyncHandleSecurityExceptions(FinalRequestFunc, clientRequestId, cancellationToken);

            if (response.IsSuccessStatusCode)
            {
                return(response);
            }

            // Continue with handling the unsuccessful response.
            var message = string.Format(
                SR.ErrorHttpOperationUnsuccessfulFormatString,
                requestUri.ToString(),
                response.StatusCode,
                response.ReasonPhrase,
                response.RequestMessage);

            ServiceFabricHttpClientEventSource.Current.ErrorResponse($"{clientRequestId}", message);

            // Try to get Fabric Error Code if present in response body.
            if (response.Content != null)
            {
                FabricError error = null;

                try
                {
                    var contentStream = await response.Content.ReadAsStreamAsync();

                    if (contentStream.Length != 0)
                    {
                        using (var streamReader = new StreamReader(contentStream))
                        {
                            using (var reader = new JsonTextReader(streamReader))
                            {
                                error = FabricErrorConverter.Deserialize(reader);
                            }
                        }
                    }
                }
                catch (JsonReaderException ex)
                {
                    ServiceFabricHttpClientEventSource.Current.ErrorMessage($"{clientRequestId}", $"Request Url: {requestUri} JsonReaderException: {ex.ToString()}");
                    throw new ServiceFabricException(string.Format(SR.ServerErrorNoMeaningFulResponse, response.StatusCode));
                }

                if (error != null)
                {
                    throw new ServiceFabricException(error.Message, error.ErrorCode ?? FabricErrorCodes.UNKNOWN, false);
                }
                else
                {
                    // Handle NotFound 404, without any ErrorCode.
                    if (response.StatusCode.Equals(HttpStatusCode.NotFound))
                    {
                        throw new ServiceFabricException(SR.ErrorMessageHTTP404, FabricErrorCodes.FABRIC_E_DOES_NOT_EXIST, false);
                    }
                }
            }

            // Couldn't determine FabricError code, throw exception with status code.
            throw new ServiceFabricException(string.Format(SR.ServerErrorNoMeaningFulResponse, response.StatusCode));
        }