/// <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); }
/// <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); }
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()); }
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); }
/// <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()); }
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); }
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); }
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); }
/// <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)); }