From 3d50e43e78643eed28cab566d4ae2a6464a1fc6c Mon Sep 17 00:00:00 2001 From: KircMax Date: Sat, 2 Dec 2023 11:57:34 +0100 Subject: [PATCH] Z003pktn/library update firmware v3 1 0 (#36) Remove Unnecessary Usings Implement Cancellationtoken in ServiceFactory Implement Cancellationtoken in ApiHttpClientRequestHandler Implement Cancellationtoken in ApiBackupHandler Implement Cancellationtoken in DirectoryHandler, FileHandler Implement Cancellationtoken in WebAppDeployer, ResourceHandler Extend ApiHttpClientRequestHandler for new Methods with Firmware V3.1.0 Api.GetQuantityStructures Api.ChangePassword Api.GetPasswordPolicy Api.GetAuthenticationMode WebServer.SetDefaultPage WebServer.ReadDefaultPage PlcProgram.DownloadProfilingData PlcProgram.Browse with CodeBlocks support Plc.ReadModeSelectorState Plc.SetSystemTime Plc.SetTimeSettings Alarms.Browse Alarms.Acknowledge Syslog.Browse DiagnosticBuffer.Browse Modules.DownloadServiceData Project.ReadLanguages --- README.md | 1 + .../Enums/ApiAlarmAcknowledgementState.cs | 21 + .../Enums/ApiAlarmsBrowseFilterAttribute.cs | 53 + .../Enums/ApiAuthenticationMode.cs | 31 + .../Enums/ApiBrowseFilterMode.cs | 27 + src/Webserver.API/Enums/ApiDayOfWeek.cs | 45 + ...iDiagnosticBufferBrowseFilterAttributes.cs | 32 + src/Webserver.API/Enums/ApiErrorCode.cs | 60 +- .../Enums/ApiFailsafeHardwareType.cs | 25 + .../Enums/ApiFileResourceState.cs | 3 - .../Enums/ApiFileResourceType.cs | 3 - .../Enums/ApiObjectDirectoryStatus.cs | 21 + src/Webserver.API/Enums/ApiPlcHwId.cs | 17 + .../Enums/ApiPlcModeSelectorState.cs | 34 + .../Enums/ApiPlcOperatingMode.cs | 5 - .../Enums/ApiPlcProgramBrowseMode.cs | 5 - .../Enums/ApiPlcProgramDataType.cs | 13 +- .../Enums/ApiPlcProgramReadOrWriteMode.cs | 5 - src/Webserver.API/Enums/ApiPlcRedundancyId.cs | 25 + src/Webserver.API/Enums/ApiTicketProvider.cs | 15 +- src/Webserver.API/Enums/ApiTicketState.cs | 5 - .../Enums/ApiWebAppResourceVisibility.cs | 5 - src/Webserver.API/Enums/ApiWebAppState.cs | 5 - src/Webserver.API/Enums/ApiWebAppType.cs | 5 - .../ApiAddressDoesNotExistException.cs | 4 - .../ApiAlreadyAuthenticatedException.cs | 4 - .../ApiApplicationAlreadyExistsException.cs | 4 - .../ApiApplicationDoesNotExistException.cs | 4 - .../ApiApplicationLimitReachedException.cs | 4 - .../Exceptions/ApiBulkRequestException.cs | 5 +- .../Exceptions/ApiDirectoryParserException.cs | 7 +- .../ApiEntityAlreadyExistsException.cs | 7 +- .../ApiEntityDoesNotExistException.cs | 7 +- .../Exceptions/ApiEntityInUseException.cs | 7 +- src/Webserver.API/Exceptions/ApiException.cs | 4 - ...elperInvalidPlcProgramDataTypeException.cs | 4 - .../ApiInconsistentApiWebAppDataException.cs | 4 - .../Exceptions/ApiInternalErrorException.cs | 4 - .../Exceptions/ApiInvalidAddressException.cs | 4 - .../Exceptions/ApiInvalidAlarmIdException.cs | 37 + ...iInvalidAlarmsBrowseParametersException.cs | 37 + .../ApiInvalidApplicationNameException.cs | 4 - .../ApiInvalidArrayIndexException.cs | 4 - .../Exceptions/ApiInvalidETagException.cs | 4 - .../Exceptions/ApiInvalidHWIDException.cs | 37 + .../ApiInvalidMediaTypeException.cs | 4 - .../ApiInvalidModificationTimeException.cs | 4 - .../ApiInvalidParametersException.cs | 4 - .../ApiInvalidResourceNameException.cs | 4 - .../Exceptions/ApiInvalidResponseException.cs | 4 - .../ApiInvalidTicketIdValueException.cs | 4 - .../Exceptions/ApiInvalidTimeRuleException.cs | 37 + .../ApiInvalidTimestampException.cs | 37 + .../ApiInvalidUTCOffsetException.cs | 37 + .../Exceptions/ApiMethodNotFoundException.cs | 4 - ...NewPasswordDoesNotFollowPolicyException.cs | 38 + ...iNewPasswordMatchesOldPasswordException.cs | 37 + .../Exceptions/ApiNoResourcesException.cs | 16 +- .../ApiNoServiceDataResourcesException.cs | 37 + .../Exceptions/ApiPLCNotInStopException.cs | 4 - .../ApiPartnerNotAccessibleException.cs | 38 + .../ApiPasswordChangeNotAcceptedException.cs | 37 + .../Exceptions/ApiPasswordExpiredException.cs | 37 + .../ApiResourceAlreadyExistsException.cs | 4 - ...esourceContentHasBeenCorruptedException.cs | 4 - .../ApiResourceContentIsNotReadyException.cs | 4 - .../ApiResourceDeploymentFailedException.cs | 4 - .../ApiResourceDoesNotExistException.cs | 4 - .../ApiResourceLimitReachedException.cs | 4 - ...iResourceVisibilityIsNotPublicException.cs | 4 - .../Exceptions/ApiSystemIsBusyException.cs | 6 +- .../ApiSystemIsReadOnlyException.cs | 4 - .../Exceptions/ApiTicketNotFoundException.cs | 4 - .../ApiTicketNotInCompletedStateException.cs | 11 +- .../ApiTicketingEndpointUploadException.cs | 4 - .../ApiTimestampOutOfRangeException.cs | 37 + .../ApiUnsupportedAddressException.cs | 4 - .../ApiVariableIsNotAStructureException.cs | 4 - .../ApiWebAppConfigParserException.cs | 4 - .../ApiWebAppConfigurationFailedException.cs | 4 - .../Exceptions/InvalidHttpRequestException.cs | 4 - .../ApiPlcRestoreBackupTicketData.cs | 2 - .../AdditionalTicketData/ApiTicketDataBase.cs | 2 - .../Models/AlarmsBrowse/ApiAlarms.cs | 108 + .../Models/AlarmsBrowse/ApiAlarms_Entry.cs | 135 + .../ApiAlarms_EntryAcknowledgement.cs | 78 + .../AlarmsBrowse/ApiAlarms_RequestFilters.cs | 39 + src/Webserver.API/Models/ApiClass.cs | 5 - .../ApiDiagnosticBuffer.cs | 105 + .../ApiDiagnosticBuffer_Entry.cs | 103 + .../ApiDiagnosticBuffer_EntryEvent.cs | 64 + .../ApiDiagnosticBuffer_RequestFilters.cs | 25 + src/Webserver.API/Models/ApiError.cs | 4 - .../Models/ApiFailsafeRuntimeGroup.cs | 70 + src/Webserver.API/Models/ApiFileResource.cs | 1 - src/Webserver.API/Models/ApiLanguage.cs | 18 + .../Models/ApiPasswordExpiration.cs | 44 + src/Webserver.API/Models/ApiPasswordPolicy.cs | 62 + .../ApiPlcProgramBrowseCodeBlocksData.cs | 113 + src/Webserver.API/Models/ApiPlcProgramData.cs | 28 +- .../Models/ApiPlcProgramDataArrayIndexer.cs | 7 +- .../ApiPlcProgramDataTypes/ApiDateAndTime.cs | 36 +- .../ApiPlcProgramDataTypes/ApiS5Time.cs | 26 +- .../Models/ApiQuantityStructure.cs | 59 + .../Models/ApiSyslog/ApiPlcSyslog.cs | 82 + .../Models/ApiSyslog/ApiPlcSyslog_Entry.cs | 49 + src/Webserver.API/Models/ApiTicket.cs | 25 +- src/Webserver.API/Models/ApiWebAppData.cs | 10 +- .../Models/ApiWebAppDataSaveSetting.cs | 7 +- src/Webserver.API/Models/ApiWebAppResource.cs | 13 +- .../FailsafeParameters/FailsafeHardware.cs | 108 + .../Models/HttpClientAndWebAppCookie.cs | 4 - .../HttpClientConnectionConfiguration.cs | 9 +- src/Webserver.API/Models/IApiWebAppData.cs | 2 +- .../Models/Requests/ApiRequest.cs | 8 +- .../Models/Requests/IApiRequest.cs | 5 - .../Responses/ApiAlarmsBrowseResponse.cs | 14 + .../Responses/ApiArrayOfApiClassResponse.cs | 7 +- .../Responses/ApiBrowseFilesResponse.cs | 3 - .../Responses/ApiBrowseTicketsResponse.cs | 6 - .../Models/Responses/ApiBulkResponse.cs | 3 - .../ApiDiagnosticBufferBrowseResponse.cs | 13 + .../Models/Responses/ApiDoubleResponse.cs | 5 - .../Models/Responses/ApiErrorModel.cs | 28 +- .../ApiFailsafeReadParametersResponse.cs | 14 + .../ApiFailsafeReadRuntimeGroupsResponse.cs | 14 + .../ApiGetAuthenticationModeResponse.cs | 14 + .../Responses/ApiGetPasswordPolicyResponse.cs | 14 + .../ApiGetQuantityStructuresResponse.cs | 13 + .../Models/Responses/ApiLoginResponse.cs | 7 +- .../ApiPlcProgramBrowseCodeBlocksResponse.cs | 14 + .../Responses/ApiPlcProgramBrowseResponse.cs | 5 - .../ApiPlcReadModeSelectorStateResponse.cs | 15 + .../Responses/ApiPlcReadSystemTimeResult.cs | 3 - .../ApiPlcReadTimeSettingsResponse.cs | 3 - .../Responses/ApiReadLanguagesResponse.cs | 15 + .../Responses/ApiReadOperatingModeResponse.cs | 10 +- .../Models/Responses/ApiResultResponse.cs | 7 +- .../Responses/ApiSingleStringResponse.cs | 6 - .../Responses/ApiSyslogBrowseResponse.cs | 13 + .../Models/Responses/ApiTicketIdResponse.cs | 14 +- .../Responses/ApiTrueOnSuccessResponse.cs | 10 +- .../Responses/ApiTrueWithResourceResponse.cs | 6 - .../Responses/ApiTrueWithWebAppResponse.cs | 6 - .../ApiWebAppBrowseResourcesResponse.cs | 5 - .../Responses/ApiWebAppBrowseResponse.cs | 5 - .../ApiWebServerGetReadDefaultPageResponse.cs | 14 + .../Models/Responses/BaseApiResponse.cs | 5 - .../ApiFailsafeReadParametersResult.cs | 31 + .../ApiFailsafeReadRuntimeGroupsResult.cs | 18 + .../ApiGetAuthenticationModeResult.cs | 19 + .../ApiGetPasswordPolicyResult.cs | 17 + .../ApiPlcReadModeSelectorStateResult.cs | 18 + .../ApiPlcReadSystemTimeResult.cs | 2 - .../ApiPlcReadTimeSettingsResult.cs | 201 +- .../ResponseResults/ApiReadLanguagesResult.cs | 18 + .../ResponseResults/ApiTokenResult.cs | 25 +- .../ApiWebAppBrowseResourcesResult.cs | 6 - .../ResponseResults/ApiWebAppBrowseResult.cs | 5 - .../WebServerDefaultPageResult.cs | 17 + .../TimeSettings/DaylightSavingsRule.cs | 91 + .../DaylightSavingsTimeConfiguration.cs | 71 + .../Models/TimeSettings/PlcDate.cs | 146 + .../TimeSettings/StandardTimeConfiguration.cs | 45 + .../Services/ApiStandardServiceFactory.cs | 40 +- .../Services/Backup/ApiBackupHandler.cs | 32 +- .../Services/Backup/IApiBackupHandler.cs | 5 +- .../EnabledDisabledConverter.cs | 48 + .../FailsafeHardwareConverter.cs | 57 + .../TimeSpanISO8601Converter.cs | 68 + .../FileHandling/ApiDirectoryBuilder.cs | 12 +- .../ApiDirectoryBuilderConfiguration.cs | 2 - .../FileHandling/ApiDirectoryHandler.cs | 60 +- .../Services/FileHandling/ApiFileHandler.cs | 30 +- .../FileHandling/ApiFileResourceBuilder.cs | 2 - .../FileHandling/IApiDirectoryHandler.cs | 15 +- .../Services/FileHandling/IApiFileHandler.cs | 16 +- .../FileHandling/IApiFileResourceBuilder.cs | 2 +- .../FileParser/ApiWebAppConfigParser.cs | 11 +- .../Services/IApiServiceFactory.cs | 37 +- .../IdGenerator/CharSetIdGenerator.cs | 13 +- .../Services/IdGenerator/GUIDGenerator.cs | 5 +- .../Services/IdGenerator/IIdGenerator.cs | 1 - .../PlcProgram/ApiPlcProgramHandler.cs | 21 +- .../PlcProgram/IApiPlcProgramHandler.cs | 10 +- .../ApiHttpClientRequestHandler.cs | 5496 +++++++++-------- .../RequestHandling/ApiRequestFactory.cs | 1709 +++-- .../ApiRequestParameterChecker.cs | 120 +- .../RequestHandling/ApiResponseChecker.cs | 6 +- .../RequestHandling/IApiRequestFactory.cs | 185 +- .../RequestHandling/IApiRequestHandler.cs | 537 +- .../IApiRequestParameterChecker.cs | 28 + .../Services/ServerCertificateCallback.cs | 8 +- .../Services/Ticketing/ApiTicketHandler.cs | 128 +- .../Services/Ticketing/IApiTicketHandler.cs | 52 +- .../Services/WebApp/ApiResourceHandler.cs | 19 +- .../Services/WebApp/ApiWebAppDataSaver.cs | 9 +- .../Services/WebApp/ApiWebAppDeployer.cs | 41 +- .../Services/WebApp/IApiResourceHandler.cs | 7 +- .../Services/WebApp/IApiWebAppDeployer.cs | 5 +- .../StaticHelpers/DateTimeFormat.cs | 6 - src/Webserver.API/Webserver.API.csproj | 6 +- tests/Webserver.API.UnitTests/ApiBulkTests.cs | 5 +- .../ApiDirectoryBuilderTests.cs | 12 +- .../ApiRequestTests.cs | 565 +- .../ApiWebAppDataSaverTests.cs | 5 - tests/Webserver.API.UnitTests/EnumTests.cs | 6 +- .../Webserver.API.UnitTests/ExtensionTests.cs | 6 +- .../FileParserTests.cs | 17 +- .../IdGeneratorTests.cs | 27 +- .../Webserver.API.UnitTests/MIMETypeTests.cs | 10 +- tests/Webserver.API.UnitTests/ModelTests.cs | 363 +- .../RequestFactoryTests.cs | 10 +- .../RequestParameterCheckerTests.cs | 96 +- .../ResponseCheckerTest.cs | 6 - .../ResponseStrings.cs | 55 +- .../Webserver.Api.UnitTests.csproj | 8 +- version.json | 2 +- 218 files changed, 9254 insertions(+), 4439 deletions(-) create mode 100644 src/Webserver.API/Enums/ApiAlarmAcknowledgementState.cs create mode 100644 src/Webserver.API/Enums/ApiAlarmsBrowseFilterAttribute.cs create mode 100644 src/Webserver.API/Enums/ApiAuthenticationMode.cs create mode 100644 src/Webserver.API/Enums/ApiBrowseFilterMode.cs create mode 100644 src/Webserver.API/Enums/ApiDayOfWeek.cs create mode 100644 src/Webserver.API/Enums/ApiDiagnosticBufferBrowseFilterAttributes.cs create mode 100644 src/Webserver.API/Enums/ApiFailsafeHardwareType.cs create mode 100644 src/Webserver.API/Enums/ApiObjectDirectoryStatus.cs create mode 100644 src/Webserver.API/Enums/ApiPlcHwId.cs create mode 100644 src/Webserver.API/Enums/ApiPlcModeSelectorState.cs create mode 100644 src/Webserver.API/Enums/ApiPlcRedundancyId.cs create mode 100644 src/Webserver.API/Exceptions/ApiInvalidAlarmIdException.cs create mode 100644 src/Webserver.API/Exceptions/ApiInvalidAlarmsBrowseParametersException.cs create mode 100644 src/Webserver.API/Exceptions/ApiInvalidHWIDException.cs create mode 100644 src/Webserver.API/Exceptions/ApiInvalidTimeRuleException.cs create mode 100644 src/Webserver.API/Exceptions/ApiInvalidTimestampException.cs create mode 100644 src/Webserver.API/Exceptions/ApiInvalidUTCOffsetException.cs create mode 100644 src/Webserver.API/Exceptions/ApiNewPasswordDoesNotFollowPolicyException.cs create mode 100644 src/Webserver.API/Exceptions/ApiNewPasswordMatchesOldPasswordException.cs create mode 100644 src/Webserver.API/Exceptions/ApiNoServiceDataResourcesException.cs create mode 100644 src/Webserver.API/Exceptions/ApiPartnerNotAccessibleException.cs create mode 100644 src/Webserver.API/Exceptions/ApiPasswordChangeNotAcceptedException.cs create mode 100644 src/Webserver.API/Exceptions/ApiPasswordExpiredException.cs create mode 100644 src/Webserver.API/Exceptions/ApiTimestampOutOfRangeException.cs create mode 100644 src/Webserver.API/Models/AlarmsBrowse/ApiAlarms.cs create mode 100644 src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_Entry.cs create mode 100644 src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_EntryAcknowledgement.cs create mode 100644 src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_RequestFilters.cs create mode 100644 src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer.cs create mode 100644 src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_Entry.cs create mode 100644 src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_EntryEvent.cs create mode 100644 src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_RequestFilters.cs create mode 100644 src/Webserver.API/Models/ApiFailsafeRuntimeGroup.cs create mode 100644 src/Webserver.API/Models/ApiLanguage.cs create mode 100644 src/Webserver.API/Models/ApiPasswordExpiration.cs create mode 100644 src/Webserver.API/Models/ApiPasswordPolicy.cs create mode 100644 src/Webserver.API/Models/ApiPlcProgramBrowseCodeBlocksData.cs create mode 100644 src/Webserver.API/Models/ApiQuantityStructure.cs create mode 100644 src/Webserver.API/Models/ApiSyslog/ApiPlcSyslog.cs create mode 100644 src/Webserver.API/Models/ApiSyslog/ApiPlcSyslog_Entry.cs create mode 100644 src/Webserver.API/Models/FailsafeParameters/FailsafeHardware.cs create mode 100644 src/Webserver.API/Models/Responses/ApiAlarmsBrowseResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiDiagnosticBufferBrowseResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiFailsafeReadParametersResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiFailsafeReadRuntimeGroupsResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiGetAuthenticationModeResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiGetPasswordPolicyResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiGetQuantityStructuresResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiPlcProgramBrowseCodeBlocksResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiPlcReadModeSelectorStateResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiReadLanguagesResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiSyslogBrowseResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiWebServerGetReadDefaultPageResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ResponseResults/ApiFailsafeReadParametersResult.cs create mode 100644 src/Webserver.API/Models/Responses/ResponseResults/ApiFailsafeReadRuntimeGroupsResult.cs create mode 100644 src/Webserver.API/Models/Responses/ResponseResults/ApiGetAuthenticationModeResult.cs create mode 100644 src/Webserver.API/Models/Responses/ResponseResults/ApiGetPasswordPolicyResult.cs create mode 100644 src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadModeSelectorStateResult.cs create mode 100644 src/Webserver.API/Models/Responses/ResponseResults/ApiReadLanguagesResult.cs create mode 100644 src/Webserver.API/Models/Responses/ResponseResults/WebServerDefaultPageResult.cs create mode 100644 src/Webserver.API/Models/TimeSettings/DaylightSavingsRule.cs create mode 100644 src/Webserver.API/Models/TimeSettings/DaylightSavingsTimeConfiguration.cs create mode 100644 src/Webserver.API/Models/TimeSettings/PlcDate.cs create mode 100644 src/Webserver.API/Models/TimeSettings/StandardTimeConfiguration.cs create mode 100644 src/Webserver.API/Services/Converters/JsonConverters/EnabledDisabledConverter.cs create mode 100644 src/Webserver.API/Services/Converters/JsonConverters/FailsafeHardwareConverter.cs create mode 100644 src/Webserver.API/Services/Converters/JsonConverters/TimeSpanISO8601Converter.cs diff --git a/README.md b/README.md index c629245..808a855 100644 --- a/README.md +++ b/README.md @@ -243,6 +243,7 @@ Plc Version | Client Library Version 2.9.x | 1.0.x 2.9.x | 2.0.x 3.0.x | 2.1.x +3.0.x | 2.2.x ## SIMATIC S7-1200: Plc Version | Client Library Version diff --git a/src/Webserver.API/Enums/ApiAlarmAcknowledgementState.cs b/src/Webserver.API/Enums/ApiAlarmAcknowledgementState.cs new file mode 100644 index 0000000..58f92bc --- /dev/null +++ b/src/Webserver.API/Enums/ApiAlarmAcknowledgementState.cs @@ -0,0 +1,21 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// The acknowledgement state of the alarm + /// + public enum ApiAlarmAcknowledgementState + { + /// + /// Alarm is not acknowledged + /// + Not_Acknowledged = 0, + /// + /// Alarm is acknowledged + /// + Acknowledged = 1 + } +} diff --git a/src/Webserver.API/Enums/ApiAlarmsBrowseFilterAttribute.cs b/src/Webserver.API/Enums/ApiAlarmsBrowseFilterAttribute.cs new file mode 100644 index 0000000..0017ad8 --- /dev/null +++ b/src/Webserver.API/Enums/ApiAlarmsBrowseFilterAttribute.cs @@ -0,0 +1,53 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.Runtime.Serialization; + +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// Possible filters for ApiAlarmsBrowse request + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum ApiAlarmsBrowseFilterAttribute + { + /// + /// Filter for the alarm text. + /// + [EnumMember(Value = "alarm_text")] + AlarmText = 1, + /// + /// Filter for the info text. + /// + [EnumMember(Value = "info_text")] + InfoText = 2, + /// + /// Filter for the alarm status. The value will contain either "incoming" or "outgoing". + /// + [EnumMember(Value = "status")] + Status = 3, + /// + /// Filter for the UTC timestamp on when the alarm went into incoming or outgoing state, provided as ISO 8601 string.
+ /// This attribute does not consider the timestamp of acknowledgement. The precision will be in nanoseconds. + ///
+ [EnumMember(Value = "timestamp")] + Timestamp = 4, + /// + /// Filter for the acknowledgement. The acknowledgement exist if the alarm is acknowledgeable. If the alarm was not configured as acknowledgeable alarm, then no acknowledgement will be returned regardless of this filter. + /// + [EnumMember(Value = "acknowledgement")] + Acknowledgement = 5, + /// + /// Filter for the the alarm number. + /// + [EnumMember(Value = "alarm_number")] + AlarmNumber = 6, + /// + /// Filter for the producer of the alarm. + /// + [EnumMember(Value = "producer")] + Producer = 7 + } +} diff --git a/src/Webserver.API/Enums/ApiAuthenticationMode.cs b/src/Webserver.API/Enums/ApiAuthenticationMode.cs new file mode 100644 index 0000000..bec689e --- /dev/null +++ b/src/Webserver.API/Enums/ApiAuthenticationMode.cs @@ -0,0 +1,31 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; + +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// User Authentication modes of the PLC.
+ /// Depends on the configured user management which authentication modes will be supported by the PLC
+ /// based on the authentication mode. + ///
+ [JsonConverter(typeof(StringEnumConverter), converterParameters: typeof(SnakeCaseNamingStrategy))] + public enum ApiAuthenticationMode + { + /// + /// Legacy User Management + /// + Static, + /// + /// Only Anonymous user is available + /// + Disabled, + /// + /// The users are stored on the PLC + /// + Local + } +} diff --git a/src/Webserver.API/Enums/ApiBrowseFilterMode.cs b/src/Webserver.API/Enums/ApiBrowseFilterMode.cs new file mode 100644 index 0000000..331b281 --- /dev/null +++ b/src/Webserver.API/Enums/ApiBrowseFilterMode.cs @@ -0,0 +1,27 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.Runtime.Serialization; + +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// The mode if the attributes shall either be included or excluded. + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum ApiBrowseFilterMode + { + /// + /// The response will include the listed attributes and exclude the others. + /// + [EnumMember(Value = "include")] + Include = 0, + /// + /// The response will exclude the listed attributes and include the others. + /// + [EnumMember(Value = "exclude")] + Exclude = 1, + } +} \ No newline at end of file diff --git a/src/Webserver.API/Enums/ApiDayOfWeek.cs b/src/Webserver.API/Enums/ApiDayOfWeek.cs new file mode 100644 index 0000000..af1331b --- /dev/null +++ b/src/Webserver.API/Enums/ApiDayOfWeek.cs @@ -0,0 +1,45 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; + +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// Represents the days of the week + /// + [JsonConverter(typeof(StringEnumConverter), converterParameters: typeof(SnakeCaseNamingStrategy))] + public enum ApiDayOfWeek + { + /// + /// Sunday + /// + Sun = 1, + /// + /// Monday + /// + Mon = 2, + /// + /// Tuesday + /// + Tue = 3, + /// + /// Wednesday + /// + Wed = 4, + /// + /// Thursday + /// + Thu = 5, + /// + /// Friday + /// + Fri = 6, + /// + /// Saturday + /// + Sat = 7 + } +} diff --git a/src/Webserver.API/Enums/ApiDiagnosticBufferBrowseFilterAttributes.cs b/src/Webserver.API/Enums/ApiDiagnosticBufferBrowseFilterAttributes.cs new file mode 100644 index 0000000..dfa6003 --- /dev/null +++ b/src/Webserver.API/Enums/ApiDiagnosticBufferBrowseFilterAttributes.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.Runtime.Serialization; + +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// Possible filters for ApiDiagnosticBufferBrowse request + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum ApiDiagnosticBufferBrowseFilterAttributes + { + /// + /// Filter for the short diagnostic buffer text. + /// + [EnumMember(Value = "short_text")] + ShortText = 1, + /// + /// Filter for the long diagnostic buffer text. + /// + [EnumMember(Value = "long_text")] + LongText = 2, + /// + /// Filter for the help text message in case of an incoming event. + /// + [EnumMember(Value = "help_text")] + HelpText = 3, + } +} diff --git a/src/Webserver.API/Enums/ApiErrorCode.cs b/src/Webserver.API/Enums/ApiErrorCode.cs index 58954c5..4764e60 100644 --- a/src/Webserver.API/Enums/ApiErrorCode.cs +++ b/src/Webserver.API/Enums/ApiErrorCode.cs @@ -1,11 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Enums { @@ -44,7 +39,7 @@ public enum ApiErrorCode /// The system does not have the necessary resources to execute the Web API request. /// Execute the request again as soon as sufficient resources are available again. /// Some examples: you have - /// -reached the limit for logins (depending on plc) - wait a maximum of 120 seconds and call the method (login) again. + /// -reached the limit for logins (depending on plc) - wait 150 seconds and call the method (login) again. /// -reached the limit for tickets for one user session or still a ticket for e.g. a download that is not closed yet. Close all open tickets in order to free resources and call this method again. /// -system does generally not have the resources currently => wait for other requests to be completed /// Das System verfügt nicht über die nötigen Ressourcen, um den Web API-Request auszuführen @@ -58,6 +53,15 @@ public enum ApiErrorCode /// SystemIsReadOnly = 5, /// + /// The password change cannot be performed. This is caused for example if an older PLC project is present where password changes are not supported. + /// + PasswordChangeNotAccepted = 6, + /// + /// The data of a PLC of an R/H system is not accessible. + /// This may happen if the system is in state Syncup or RUN-redundant or if the service data of the partner PLC has been requested. + /// + PartnerNotAccessible = 7, + /// /// The given credentials dont match any downloaded credentials to the plc. /// LoginFailed = 100, @@ -67,6 +71,18 @@ public enum ApiErrorCode /// AlreadyAuthenticated = 101, /// + /// The password of the user account has expired. The user needs to change the password to successfully authenticate again. + /// + PasswordExpired = 102, + /// + /// The provided new password does not match the required password policy. + /// + NewPasswordDoesNotFollowPolicy = 103, + /// + /// The provided new password is identical with the current password. + /// + NewPasswordMatchesOldPassword = 104, + /// /// The requested address does not exist or the webserver cannot access the requested address. /// Die angeforderte Adresse existiert nicht oder der Webserver kann nicht auf die angeforderte Adresse zugreifen. /// @@ -176,10 +192,42 @@ public enum ApiErrorCode /// ResourceContentHasBeenCorrupted = 514, /// + /// Only one simultaneous ticket resource for service data across all users is possible at a time + /// + NoServiceDataResources = 600, + /// + /// The provided alarm ID is invalid. + /// + InvalidAlarmId = 800, + /// + /// The request is invalid. The user provided invalid parameters, e. g. alarm ID and count are present at the same time. + /// + InvalidAlarmsBrowseParameters = 801, + /// + /// The provided timestamp does not match the required timestamp format + /// + InvalidTimestamp = 900, + /// + /// The timestamp is not within the allowed range + /// + TimestampOutOfRange = 901, + /// + /// The provided rule is invalid. Check the DaylightSavingsRule object. If the Rule object is present, both DST and STD is required. + /// + InvalidTimeRule = 902, + /// + /// The provided UTC offset is invalid. Check the main utc offset, and the DaylightSavingsRule object's DST offset. + /// + InvalidUTCOffset = 903, + /// /// The PLC is not in operating mode stop. The method cannot be executed while the plc is not in stop mode. /// PLCNotInStop = 1004, /// + /// The requested hardware identifier is invalid + /// + InvalidHwId = 1100, + /// /// The method has not been found by the plc - check the spelling and fw-version (and according methods) of plc /// MethodNotFound = -32601, diff --git a/src/Webserver.API/Enums/ApiFailsafeHardwareType.cs b/src/Webserver.API/Enums/ApiFailsafeHardwareType.cs new file mode 100644 index 0000000..ad5f239 --- /dev/null +++ b/src/Webserver.API/Enums/ApiFailsafeHardwareType.cs @@ -0,0 +1,25 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; + +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// The type defines if the requested hardware identifier represents either the safety PLC itself or another failsafe module. + /// + [JsonConverter(typeof(StringEnumConverter), converterParameters: typeof(SnakeCaseNamingStrategy))] + public enum ApiFailsafeHardwareType + { + /// + /// The hw id is a CPU + /// + F_cpu, + /// + /// The hw id is a module + /// + F_module + } +} diff --git a/src/Webserver.API/Enums/ApiFileResourceState.cs b/src/Webserver.API/Enums/ApiFileResourceState.cs index d5b5c9c..83a4e6c 100644 --- a/src/Webserver.API/Enums/ApiFileResourceState.cs +++ b/src/Webserver.API/Enums/ApiFileResourceState.cs @@ -1,9 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Collections.Generic; -using System.Text; namespace Siemens.Simatic.S7.Webserver.API.Enums { diff --git a/src/Webserver.API/Enums/ApiFileResourceType.cs b/src/Webserver.API/Enums/ApiFileResourceType.cs index d955beb..de25306 100644 --- a/src/Webserver.API/Enums/ApiFileResourceType.cs +++ b/src/Webserver.API/Enums/ApiFileResourceType.cs @@ -1,9 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Collections.Generic; -using System.Text; namespace Siemens.Simatic.S7.Webserver.API.Enums { diff --git a/src/Webserver.API/Enums/ApiObjectDirectoryStatus.cs b/src/Webserver.API/Enums/ApiObjectDirectoryStatus.cs new file mode 100644 index 0000000..4e7e720 --- /dev/null +++ b/src/Webserver.API/Enums/ApiObjectDirectoryStatus.cs @@ -0,0 +1,21 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// The status of the entry. Either incoming or outgoing. + /// + public enum ApiObjectDirectoryStatus + { + /// + /// The entry is incoming + /// + Incoming = 1, + /// + /// The entry is outgoing + /// + Outgoing = 2 + } +} \ No newline at end of file diff --git a/src/Webserver.API/Enums/ApiPlcHwId.cs b/src/Webserver.API/Enums/ApiPlcHwId.cs new file mode 100644 index 0000000..c0d80c8 --- /dev/null +++ b/src/Webserver.API/Enums/ApiPlcHwId.cs @@ -0,0 +1,17 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// Enum containing Hardware Ids for different types of plcs + /// + public enum ApiPlcHwId + { + /// + /// HwId for a standard, non-redundant plc + /// + StandardPLC = 49 + } +} diff --git a/src/Webserver.API/Enums/ApiPlcModeSelectorState.cs b/src/Webserver.API/Enums/ApiPlcModeSelectorState.cs new file mode 100644 index 0000000..6bf5098 --- /dev/null +++ b/src/Webserver.API/Enums/ApiPlcModeSelectorState.cs @@ -0,0 +1,34 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; + +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// Represents the state of the mode selector switch of the PLC. + /// + [JsonConverter(typeof(StringEnumConverter), converterParameters: typeof(SnakeCaseNamingStrategy))] + public enum ApiPlcModeSelectorState + { + /// + /// No physical mode selector switch is present. + /// + NoSwitch, + /// + /// The mode selector switch is in position STOP. + /// + Stop, + /// + /// The mode selector switch is in position RUN. + /// + Run, + /// + /// The mode selector switch position could not be determined. + /// For example, the partner PLC of an R/H system is not reachable. + /// + Unknown + } +} diff --git a/src/Webserver.API/Enums/ApiPlcOperatingMode.cs b/src/Webserver.API/Enums/ApiPlcOperatingMode.cs index 5e2fc8c..59b44de 100644 --- a/src/Webserver.API/Enums/ApiPlcOperatingMode.cs +++ b/src/Webserver.API/Enums/ApiPlcOperatingMode.cs @@ -1,11 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Enums { diff --git a/src/Webserver.API/Enums/ApiPlcProgramBrowseMode.cs b/src/Webserver.API/Enums/ApiPlcProgramBrowseMode.cs index b6d03f9..e4d6e91 100644 --- a/src/Webserver.API/Enums/ApiPlcProgramBrowseMode.cs +++ b/src/Webserver.API/Enums/ApiPlcProgramBrowseMode.cs @@ -1,11 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Enums { diff --git a/src/Webserver.API/Enums/ApiPlcProgramDataType.cs b/src/Webserver.API/Enums/ApiPlcProgramDataType.cs index 61f9ea8..9785a98 100644 --- a/src/Webserver.API/Enums/ApiPlcProgramDataType.cs +++ b/src/Webserver.API/Enums/ApiPlcProgramDataType.cs @@ -1,13 +1,8 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using Siemens.Simatic.S7.Webserver.API.Models; using Siemens.Simatic.S7.Webserver.API.Models.ApiPlcProgramDataTypes; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Enums { @@ -80,9 +75,9 @@ public static int GetBytesOfDataType(this ApiPlcProgramDataType plcProgramDataTy public static Type GetAccordingDataType(this ApiPlcProgramDataType plcProgramDataType) { int intVal = (int)plcProgramDataType; - if(intVal >= 3 && intVal <= 4) + if (intVal >= 3 && intVal <= 4) return typeof(byte); - if(intVal >= 6 && intVal <= 7) + if (intVal >= 6 && intVal <= 7) return typeof(char); if (intVal >= 8 && intVal <= 18) return typeof(short); @@ -96,14 +91,14 @@ public static Type GetAccordingDataType(this ApiPlcProgramDataType plcProgramDat return typeof(long); if (intVal >= 62 && intVal <= 64) return typeof(ulong); - if(intVal >= 65 && intVal <= 66) + if (intVal >= 65 && intVal <= 66) return typeof(string); switch (plcProgramDataType) { case ApiPlcProgramDataType.Bool: return typeof(bool); case ApiPlcProgramDataType.Sint: - return typeof(sbyte); + return typeof(sbyte); case ApiPlcProgramDataType.S5time: return typeof(ApiS5Time); case ApiPlcProgramDataType.Date_and_time: diff --git a/src/Webserver.API/Enums/ApiPlcProgramReadOrWriteMode.cs b/src/Webserver.API/Enums/ApiPlcProgramReadOrWriteMode.cs index cf6e18d..c08694e 100644 --- a/src/Webserver.API/Enums/ApiPlcProgramReadOrWriteMode.cs +++ b/src/Webserver.API/Enums/ApiPlcProgramReadOrWriteMode.cs @@ -1,11 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Enums { diff --git a/src/Webserver.API/Enums/ApiPlcRedundancyId.cs b/src/Webserver.API/Enums/ApiPlcRedundancyId.cs new file mode 100644 index 0000000..621b833 --- /dev/null +++ b/src/Webserver.API/Enums/ApiPlcRedundancyId.cs @@ -0,0 +1,25 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// Represents which PLC with id 1 or 2 is used in an R/H system. + /// + public enum ApiPlcRedundancyId + { + /// + /// Standard PLC + /// + StandardPLC = 0, + /// + /// Redundancy ID 1 + /// + RedundancyId_1 = 1, + /// + /// Redundancy ID 2 + /// + RedundancyId_2 = 2 + } +} diff --git a/src/Webserver.API/Enums/ApiTicketProvider.cs b/src/Webserver.API/Enums/ApiTicketProvider.cs index 1172f42..d39b310 100644 --- a/src/Webserver.API/Enums/ApiTicketProvider.cs +++ b/src/Webserver.API/Enums/ApiTicketProvider.cs @@ -2,13 +2,7 @@ // // SPDX-License-Identifier: MIT using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Enums { @@ -51,8 +45,11 @@ public enum ApiTicketProvider [JsonProperty("Plc.CreateBackup")] [EnumMember(Value = "Plc.CreateBackup")] Plc_CreateBackup = 5, + /// + /// For Api: PlcProgram.DownloadProfilingData + /// + [JsonProperty("PlcProgram.DownloadProfilingData")] + [EnumMember(Value = "PlcProgram.DownloadProfilingData")] + PlcProgram_DownloadProfilingData = 6, } - - - } diff --git a/src/Webserver.API/Enums/ApiTicketState.cs b/src/Webserver.API/Enums/ApiTicketState.cs index 8438aeb..321ca05 100644 --- a/src/Webserver.API/Enums/ApiTicketState.cs +++ b/src/Webserver.API/Enums/ApiTicketState.cs @@ -1,11 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Enums { diff --git a/src/Webserver.API/Enums/ApiWebAppResourceVisibility.cs b/src/Webserver.API/Enums/ApiWebAppResourceVisibility.cs index 6f92fb4..3854c56 100644 --- a/src/Webserver.API/Enums/ApiWebAppResourceVisibility.cs +++ b/src/Webserver.API/Enums/ApiWebAppResourceVisibility.cs @@ -1,11 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Enums { diff --git a/src/Webserver.API/Enums/ApiWebAppState.cs b/src/Webserver.API/Enums/ApiWebAppState.cs index d6eb565..c1b7907 100644 --- a/src/Webserver.API/Enums/ApiWebAppState.cs +++ b/src/Webserver.API/Enums/ApiWebAppState.cs @@ -1,11 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Enums { diff --git a/src/Webserver.API/Enums/ApiWebAppType.cs b/src/Webserver.API/Enums/ApiWebAppType.cs index 71e8b8e..a6227ee 100644 --- a/src/Webserver.API/Enums/ApiWebAppType.cs +++ b/src/Webserver.API/Enums/ApiWebAppType.cs @@ -1,11 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Enums { diff --git a/src/Webserver.API/Exceptions/ApiAddressDoesNotExistException.cs b/src/Webserver.API/Exceptions/ApiAddressDoesNotExistException.cs index dc53322..7cf83a2 100644 --- a/src/Webserver.API/Exceptions/ApiAddressDoesNotExistException.cs +++ b/src/Webserver.API/Exceptions/ApiAddressDoesNotExistException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiAlreadyAuthenticatedException.cs b/src/Webserver.API/Exceptions/ApiAlreadyAuthenticatedException.cs index 17654ed..ff3446a 100644 --- a/src/Webserver.API/Exceptions/ApiAlreadyAuthenticatedException.cs +++ b/src/Webserver.API/Exceptions/ApiAlreadyAuthenticatedException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiApplicationAlreadyExistsException.cs b/src/Webserver.API/Exceptions/ApiApplicationAlreadyExistsException.cs index 64814af..77fe9a3 100644 --- a/src/Webserver.API/Exceptions/ApiApplicationAlreadyExistsException.cs +++ b/src/Webserver.API/Exceptions/ApiApplicationAlreadyExistsException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiApplicationDoesNotExistException.cs b/src/Webserver.API/Exceptions/ApiApplicationDoesNotExistException.cs index 1deddc6..a001e13 100644 --- a/src/Webserver.API/Exceptions/ApiApplicationDoesNotExistException.cs +++ b/src/Webserver.API/Exceptions/ApiApplicationDoesNotExistException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiApplicationLimitReachedException.cs b/src/Webserver.API/Exceptions/ApiApplicationLimitReachedException.cs index 36dd035..a9d0b26 100644 --- a/src/Webserver.API/Exceptions/ApiApplicationLimitReachedException.cs +++ b/src/Webserver.API/Exceptions/ApiApplicationLimitReachedException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiBulkRequestException.cs b/src/Webserver.API/Exceptions/ApiBulkRequestException.cs index 6fd3de9..d95cee2 100644 --- a/src/Webserver.API/Exceptions/ApiBulkRequestException.cs +++ b/src/Webserver.API/Exceptions/ApiBulkRequestException.cs @@ -3,10 +3,7 @@ // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses; using System; -using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { @@ -27,7 +24,7 @@ private static string GetErrorMessage(ApiBulkResponse bulkResponse) /// /// Bulk Response from PLC /// - public ApiBulkResponse BulkResponse{ get; private set; } + public ApiBulkResponse BulkResponse { get; private set; } /// /// Bulk Request Exceptions /// diff --git a/src/Webserver.API/Exceptions/ApiDirectoryParserException.cs b/src/Webserver.API/Exceptions/ApiDirectoryParserException.cs index 03ed82b..ecf4f1b 100644 --- a/src/Webserver.API/Exceptions/ApiDirectoryParserException.cs +++ b/src/Webserver.API/Exceptions/ApiDirectoryParserException.cs @@ -1,6 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Text; +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiEntityAlreadyExistsException.cs b/src/Webserver.API/Exceptions/ApiEntityAlreadyExistsException.cs index 87c2119..b766b46 100644 --- a/src/Webserver.API/Exceptions/ApiEntityAlreadyExistsException.cs +++ b/src/Webserver.API/Exceptions/ApiEntityAlreadyExistsException.cs @@ -1,6 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Text; +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiEntityDoesNotExistException.cs b/src/Webserver.API/Exceptions/ApiEntityDoesNotExistException.cs index ff0cdf8..a8fe730 100644 --- a/src/Webserver.API/Exceptions/ApiEntityDoesNotExistException.cs +++ b/src/Webserver.API/Exceptions/ApiEntityDoesNotExistException.cs @@ -1,6 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Text; +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiEntityInUseException.cs b/src/Webserver.API/Exceptions/ApiEntityInUseException.cs index 2d4f789..aaccb96 100644 --- a/src/Webserver.API/Exceptions/ApiEntityInUseException.cs +++ b/src/Webserver.API/Exceptions/ApiEntityInUseException.cs @@ -1,6 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Text; +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiException.cs b/src/Webserver.API/Exceptions/ApiException.cs index bc81e4b..e396090 100644 --- a/src/Webserver.API/Exceptions/ApiException.cs +++ b/src/Webserver.API/Exceptions/ApiException.cs @@ -5,10 +5,6 @@ using Newtonsoft.Json.Serialization; using Siemens.Simatic.S7.Webserver.API.Models.Responses; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiHelperInvalidPlcProgramDataTypeException.cs b/src/Webserver.API/Exceptions/ApiHelperInvalidPlcProgramDataTypeException.cs index af54f3a..4c787b2 100644 --- a/src/Webserver.API/Exceptions/ApiHelperInvalidPlcProgramDataTypeException.cs +++ b/src/Webserver.API/Exceptions/ApiHelperInvalidPlcProgramDataTypeException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiInconsistentApiWebAppDataException.cs b/src/Webserver.API/Exceptions/ApiInconsistentApiWebAppDataException.cs index 46bb8e3..c7a7f3b 100644 --- a/src/Webserver.API/Exceptions/ApiInconsistentApiWebAppDataException.cs +++ b/src/Webserver.API/Exceptions/ApiInconsistentApiWebAppDataException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiInternalErrorException.cs b/src/Webserver.API/Exceptions/ApiInternalErrorException.cs index 2ace38e..05fe1b4 100644 --- a/src/Webserver.API/Exceptions/ApiInternalErrorException.cs +++ b/src/Webserver.API/Exceptions/ApiInternalErrorException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiInvalidAddressException.cs b/src/Webserver.API/Exceptions/ApiInvalidAddressException.cs index cd6e116..3878d2d 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidAddressException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidAddressException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiInvalidAlarmIdException.cs b/src/Webserver.API/Exceptions/ApiInvalidAlarmIdException.cs new file mode 100644 index 0000000..d6ead62 --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiInvalidAlarmIdException.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// The provided alarm ID is invalid. This alarm does not exist (anymore). + /// + public class ApiInvalidAlarmIdException : Exception + { + private static string message = "The provided alarm ID is invalid. This alarm does not exist (anymore)."; + /// + /// The provided alarm ID is invalid. This alarm does not exist (anymore). + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiInvalidAlarmIdException(Exception innerException) : base(message, innerException) { } + /// + /// The provided alarm ID is invalid + /// + public ApiInvalidAlarmIdException() : base(message) { } + /// + /// The provided alarm ID is invalid. This alarm does not exist (anymore). + /// + /// Further information about the error message that explains the reason for the exception. + public ApiInvalidAlarmIdException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// The provided alarm ID is invalid. This alarm does not exist (anymore). + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiInvalidAlarmIdException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiInvalidAlarmsBrowseParametersException.cs b/src/Webserver.API/Exceptions/ApiInvalidAlarmsBrowseParametersException.cs new file mode 100644 index 0000000..1435dac --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiInvalidAlarmsBrowseParametersException.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// The request is invalid. The user provided invalid parameters, e. g. alarm ID and count are present at the same time. + /// + public class ApiInvalidAlarmsBrowseParametersException : Exception + { + private static string message = "The request is invalid. The user provided invalid parameters, e. g. alarm ID and count are present at the same time."; + /// + /// The request is invalid. The user provided invalid parameters, e. g. alarm ID and count are present at the same time. + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiInvalidAlarmsBrowseParametersException(Exception innerException) : base(message, innerException) { } + /// + /// The request is invalid. The user provided invalid parameters, e. g. alarm ID and count are present at the same time. + /// + public ApiInvalidAlarmsBrowseParametersException() : base(message) { } + /// + /// The request is invalid. The user provided invalid parameters, e. g. alarm ID and count are present at the same time. + /// + /// Further information about the error message that explains the reason for the exception. + public ApiInvalidAlarmsBrowseParametersException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// The request is invalid. The user provided invalid parameters, e. g. alarm ID and count are present at the same time. + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiInvalidAlarmsBrowseParametersException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiInvalidApplicationNameException.cs b/src/Webserver.API/Exceptions/ApiInvalidApplicationNameException.cs index fb63bdf..a748ee1 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidApplicationNameException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidApplicationNameException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiInvalidArrayIndexException.cs b/src/Webserver.API/Exceptions/ApiInvalidArrayIndexException.cs index 6e4e7f1..d7f5b27 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidArrayIndexException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidArrayIndexException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiInvalidETagException.cs b/src/Webserver.API/Exceptions/ApiInvalidETagException.cs index a025b2e..426cb50 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidETagException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidETagException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiInvalidHWIDException.cs b/src/Webserver.API/Exceptions/ApiInvalidHWIDException.cs new file mode 100644 index 0000000..7520330 --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiInvalidHWIDException.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// The requested hardware identifier is invalid. The user shall verify the request and look up the correct hardware identifier. + /// + public class ApiInvalidHwIdException : Exception + { + private static string message = "The requested hardware identifier is invalid. The user shall verify the request and look up the correct hardware identifier.."; + /// + /// The requested hardware identifier is invalid. The user shall verify the request and look up the correct hardware identifier. + /// + public ApiInvalidHwIdException() : base(message) { } + /// + /// The requested hardware identifier is invalid. The user shall verify the request and look up the correct hardware identifier. + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiInvalidHwIdException(Exception innerException) : base(message, innerException) { } + /// + /// The requested hardware identifier is invalid. The user shall verify the request and look up the correct hardware identifier. + /// + /// Further information about the error message that explains the reason for the exception. + public ApiInvalidHwIdException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// The requested hardware identifier is invalid. The user shall verify the request and look up the correct hardware identifier. + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiInvalidHwIdException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiInvalidMediaTypeException.cs b/src/Webserver.API/Exceptions/ApiInvalidMediaTypeException.cs index a8db341..6c17768 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidMediaTypeException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidMediaTypeException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiInvalidModificationTimeException.cs b/src/Webserver.API/Exceptions/ApiInvalidModificationTimeException.cs index 79a8ff4..6d8008e 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidModificationTimeException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidModificationTimeException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiInvalidParametersException.cs b/src/Webserver.API/Exceptions/ApiInvalidParametersException.cs index b6b970a..263f10b 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidParametersException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidParametersException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiInvalidResourceNameException.cs b/src/Webserver.API/Exceptions/ApiInvalidResourceNameException.cs index ba0d0b4..bfb524e 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidResourceNameException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidResourceNameException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiInvalidResponseException.cs b/src/Webserver.API/Exceptions/ApiInvalidResponseException.cs index 93515e7..afb3df0 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidResponseException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidResponseException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiInvalidTicketIdValueException.cs b/src/Webserver.API/Exceptions/ApiInvalidTicketIdValueException.cs index be85835..1705ab2 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidTicketIdValueException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidTicketIdValueException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiInvalidTimeRuleException.cs b/src/Webserver.API/Exceptions/ApiInvalidTimeRuleException.cs new file mode 100644 index 0000000..25fcd4d --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiInvalidTimeRuleException.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// The provided rule is invalid. Check the DaylightSavingsRule object. If the Rule object is present, both DST and STD is required. + /// + public class ApiInvalidTimeRuleException : Exception + { + private static string message = "The provided rule is invalid. Check the DaylightSavingsRule object. If the Rule object is present, both DST and STD is required."; + /// + /// The provided rule is invalid. Check the DaylightSavingsRule object. If the Rule object is present, both DST and STD is required. + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiInvalidTimeRuleException(Exception innerException) : base(message, innerException) { } + /// + /// The provided rule is invalid. Check the DaylightSavingsRule object. If the Rule object is present, both DST and STD is required. + /// + public ApiInvalidTimeRuleException() : base(message) { } + /// + /// The provided rule is invalid. Check the DaylightSavingsRule object. If the Rule object is present, both DST and STD is required. + /// + /// Further information about the error message that explains the reason for the exception. + public ApiInvalidTimeRuleException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// The provided rule is invalid. Check the DaylightSavingsRule object. If the Rule object is present, both DST and STD is required. + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiInvalidTimeRuleException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiInvalidTimestampException.cs b/src/Webserver.API/Exceptions/ApiInvalidTimestampException.cs new file mode 100644 index 0000000..8e8a209 --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiInvalidTimestampException.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// The provided timestamp does not match the required timestamp format + /// + public class ApiInvalidTimestampException : Exception + { + private static string message = "The provided timestamp does not match the required timestamp format"; + /// + /// The provided timestamp does not match the required timestamp format + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiInvalidTimestampException(Exception innerException) : base(message, innerException) { } + /// + /// The provided timestamp does not match the required timestamp format + /// + public ApiInvalidTimestampException() : base(message) { } + /// + /// The provided timestamp does not match the required timestamp format + /// + /// Further information about the error message that explains the reason for the exception. + public ApiInvalidTimestampException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// The provided timestamp does not match the required timestamp format + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiInvalidTimestampException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiInvalidUTCOffsetException.cs b/src/Webserver.API/Exceptions/ApiInvalidUTCOffsetException.cs new file mode 100644 index 0000000..0972257 --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiInvalidUTCOffsetException.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// The provided UTC offset is invalid. Check the main utc offset, and the DaylightSavingsRule object's DST offset. + /// + public class ApiInvalidUTCOffsetException : Exception + { + private static string message = "The provided UTC offset is invalid. Check the main utc offset, and the DaylightSavingsRule object's DST offset."; + /// + /// The provided UTC offset is invalid. Check the main utc offset, and the DaylightSavingsRule object's DST offset. + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiInvalidUTCOffsetException(Exception innerException) : base(message, innerException) { } + /// + /// The provided UTC offset is invalid. Check the main utc offset, and the DaylightSavingsRule object's DST offset. + /// + public ApiInvalidUTCOffsetException() : base(message) { } + /// + /// The provided UTC offset is invalid. Check the main utc offset, and the DaylightSavingsRule object's DST offset. + /// + /// Further information about the error message that explains the reason for the exception. + public ApiInvalidUTCOffsetException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// The provided UTC offset is invalid. Check the main utc offset, and the DaylightSavingsRule object's DST offset. + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiInvalidUTCOffsetException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiMethodNotFoundException.cs b/src/Webserver.API/Exceptions/ApiMethodNotFoundException.cs index 2a05ea7..69b3194 100644 --- a/src/Webserver.API/Exceptions/ApiMethodNotFoundException.cs +++ b/src/Webserver.API/Exceptions/ApiMethodNotFoundException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiNewPasswordDoesNotFollowPolicyException.cs b/src/Webserver.API/Exceptions/ApiNewPasswordDoesNotFollowPolicyException.cs new file mode 100644 index 0000000..046f920 --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiNewPasswordDoesNotFollowPolicyException.cs @@ -0,0 +1,38 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// The provided new password does not match the required password policy. + /// + public class ApiNewPasswordDoesNotFollowPolicyException : Exception + { + private static string message = "The provided new password does not match the required password policy."; + /// + /// The provided new password does not match the required password policy. + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiNewPasswordDoesNotFollowPolicyException(Exception innerException) : base(message, innerException) { } + /// + /// The provided new password does not match the required password policy. + /// + public ApiNewPasswordDoesNotFollowPolicyException() : base(message) { } + /// + /// The provided new password does not match the required password policy. + /// + /// Further information about the error message that explains the reason for the exception. + public ApiNewPasswordDoesNotFollowPolicyException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// The provided new password does not match the required password policy. + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiNewPasswordDoesNotFollowPolicyException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} + diff --git a/src/Webserver.API/Exceptions/ApiNewPasswordMatchesOldPasswordException.cs b/src/Webserver.API/Exceptions/ApiNewPasswordMatchesOldPasswordException.cs new file mode 100644 index 0000000..702c8e5 --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiNewPasswordMatchesOldPasswordException.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// The provided new password is identical with the former password. + /// + public class ApiNewPasswordMatchesOldPasswordException : Exception + { + private static string message = "The provided new password is identical with the former password."; + /// + /// The provided new password is identical with the former password. + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiNewPasswordMatchesOldPasswordException(Exception innerException) : base(message, innerException) { } + /// + /// The provided new password is identical with the former password. + /// + public ApiNewPasswordMatchesOldPasswordException() : base(message) { } + /// + /// The provided new password is identical with the former password. + /// + /// Further information about the error message that explains the reason for the exception. + public ApiNewPasswordMatchesOldPasswordException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// The provided new password is identical with the former password. + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiNewPasswordMatchesOldPasswordException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiNoResourcesException.cs b/src/Webserver.API/Exceptions/ApiNoResourcesException.cs index 2d1ce05..562a4b9 100644 --- a/src/Webserver.API/Exceptions/ApiNoResourcesException.cs +++ b/src/Webserver.API/Exceptions/ApiNoResourcesException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { @@ -13,7 +9,7 @@ namespace Siemens.Simatic.S7.Webserver.API.Exceptions /// The system does not have the necessary resources to execute the Web API request. /// Execute the request again as soon as sufficient resources are available again. /// Some examples: you have - /// -reached the limit for logins (depending on plc) - wait a maximum of 120 seconds and call the method (login) again. + /// -reached the limit for logins (depending on plc) - wait 150 seconds and call the method (login) again. /// -reached the limit for tickets for one user session or still a ticket for e.g. a download that is not closed yet. Close all open tickets in order to free resources and call this method again. /// -system does generally not have the resources currently => wait for other requests to be completed /// @@ -21,7 +17,7 @@ public class ApiNoResourcesException : Exception { private static string message = $"The system does not have the necessary resources to execute the Web API request. " + $"{Environment.NewLine}Execute the request again as soon as sufficient resources are available again. Some examples: you have{Environment.NewLine}" + - $" -reached the limit for logins (depending on plc)=> wait a maximum of 120 seconds and call the method (login) again.{Environment.NewLine}" + + $" -reached the limit for logins (depending on plc)=> wait 150 seconds and call the method (login) again.{Environment.NewLine}" + $" -reached the limit for tickets for one user session or still a ticket for e.g. a download that is not closed yet. " + $"Close all open tickets in order to free resources and call this method again. {Environment.NewLine}" + $" -system does generally not have the resources currently => wait for other requests to be completed"; @@ -29,7 +25,7 @@ public class ApiNoResourcesException : Exception /// The system does not have the necessary resources to execute the Web API request. /// Execute the request again as soon as sufficient resources are available again. /// Some examples: you have - /// -reached the limit for logins (depending on plc) - wait a maximum of 120 seconds and call the method (login) again. + /// -reached the limit for logins (depending on plc) - wait 150 seconds and call the method (login) again. /// -reached the limit for tickets for one user session or still a ticket for e.g. a download that is not closed yet. Close all open tickets in order to free resources and call this method again. /// -system does generally not have the resources currently => wait for other requests to be completed /// @@ -40,7 +36,7 @@ public ApiNoResourcesException(Exception innerException) : base(message, innerEx /// The system does not have the necessary resources to execute the Web API request. /// Execute the request again as soon as sufficient resources are available again. /// Some examples: you have - /// -reached the limit for logins (depending on plc) - wait a maximum of 120 seconds and call the method (login) again. + /// -reached the limit for logins (depending on plc) - wait 150 seconds and call the method (login) again. /// -reached the limit for tickets for one user session or still a ticket for e.g. a download that is not closed yet. Close all open tickets in order to free resources and call this method again. /// -system does generally not have the resources currently => wait for other requests to be completed /// @@ -50,7 +46,7 @@ public ApiNoResourcesException() : base(message) { } /// The system does not have the necessary resources to execute the Web API request. /// Execute the request again as soon as sufficient resources are available again. /// Some examples: you have - /// -reached the limit for logins (depending on plc) - wait a maximum of 120 seconds and call the method (login) again. + /// -reached the limit for logins (depending on plc) - wait 150 seconds and call the method (login) again. /// -reached the limit for tickets for one user session or still a ticket for e.g. a download that is not closed yet. Close all open tickets in order to free resources and call this method again. /// -system does generally not have the resources currently => wait for other requests to be completed /// @@ -60,7 +56,7 @@ public ApiNoResourcesException(string userMessage) : base(message + Environment. /// The system does not have the necessary resources to execute the Web API request. /// Execute the request again as soon as sufficient resources are available again. /// Some examples: you have - /// -reached the limit for logins (depending on plc) - wait a maximum of 120 seconds and call the method (login) again. + /// -reached the limit for logins (depending on plc) - wait 150 seconds and call the method (login) again. /// -reached the limit for tickets for one user session or still a ticket for e.g. a download that is not closed yet. Close all open tickets in order to free resources and call this method again. /// -system does generally not have the resources currently => wait for other requests to be completed /// diff --git a/src/Webserver.API/Exceptions/ApiNoServiceDataResourcesException.cs b/src/Webserver.API/Exceptions/ApiNoServiceDataResourcesException.cs new file mode 100644 index 0000000..52cb20e --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiNoServiceDataResourcesException.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// Only one simultaneous ticket resource for service data across all users is possible at a time + /// + public class ApiNoServiceDataResourcesException : Exception + { + private static string message = "Only one simultaneous ticket resource for service data across all users is possible at a time."; + /// + /// Only one simultaneous ticket resource for service data across all users is possible at a time + /// + public ApiNoServiceDataResourcesException() : base(message) { } + /// + /// Only one simultaneous ticket resource for service data across all users is possible at a time + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiNoServiceDataResourcesException(Exception innerException) : base(message, innerException) { } + /// + /// Only one simultaneous ticket resource for service data across all users is possible at a time + /// + /// Further information about the error message that explains the reason for the exception. + public ApiNoServiceDataResourcesException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// Only one simultaneous ticket resource for service data across all users is possible at a time + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiNoServiceDataResourcesException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiPLCNotInStopException.cs b/src/Webserver.API/Exceptions/ApiPLCNotInStopException.cs index c217e3a..ba79355 100644 --- a/src/Webserver.API/Exceptions/ApiPLCNotInStopException.cs +++ b/src/Webserver.API/Exceptions/ApiPLCNotInStopException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiPartnerNotAccessibleException.cs b/src/Webserver.API/Exceptions/ApiPartnerNotAccessibleException.cs new file mode 100644 index 0000000..30c70f9 --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiPartnerNotAccessibleException.cs @@ -0,0 +1,38 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// The data of a PLC of an R/H system is not accessible. + /// This may happen if the system is in state Syncup or RUN-redundant. + /// + public class ApiPartnerNotAccessibleException : Exception + { + private static string message = "The data of a PLC of an R/H system is not accessible. This may happen if the system is in state Syncup or RUN-redundant."; + /// + /// The data of a PLC of an R/H system is not accessible. This may happen if the system is in state Syncup or RUN-redundant or if the service data of the partner PLC has been requested. + /// + public ApiPartnerNotAccessibleException() : base(message) { } + /// + /// The data of a PLC of an R/H system is not accessible. This may happen if the system is in state Syncup or RUN-redundant or if the service data of the partner PLC has been requested. + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiPartnerNotAccessibleException(Exception innerException) : base(message, innerException) { } + /// + /// The data of a PLC of an R/H system is not accessible. This may happen if the system is in state Syncup or RUN-redundant or if the service data of the partner PLC has been requested. + /// + /// Further information about the error message that explains the reason for the exception. + public ApiPartnerNotAccessibleException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// The data of a PLC of an R/H system is not accessible. This may happen if the system is in state Syncup or RUN-redundant or if the service data of the partner PLC has been requested. + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiPartnerNotAccessibleException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiPasswordChangeNotAcceptedException.cs b/src/Webserver.API/Exceptions/ApiPasswordChangeNotAcceptedException.cs new file mode 100644 index 0000000..8c27e4e --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiPasswordChangeNotAcceptedException.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// The password change cannot be performed. This is caused for example if an older PLC project is present where password changes are not supported. + /// + public class ApiPasswordChangeNotAcceptedException : Exception + { + private static string message = "The password change cannot be performed. This is caused for example if an older PLC project is present where password changes are not supported."; + /// + /// The password change cannot be performed. This is caused for example if an older PLC project is present where password changes are not supported. + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiPasswordChangeNotAcceptedException(Exception innerException) : base(message, innerException) { } + /// + /// The password change cannot be performed. This is caused for example if an older PLC project is present where password changes are not supported. + /// + public ApiPasswordChangeNotAcceptedException() : base(message) { } + /// + /// The password change cannot be performed. This is caused for example if an older PLC project is present where password changes are not supported. + /// + /// Further information about the error message that explains the reason for the exception. + public ApiPasswordChangeNotAcceptedException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// The password change cannot be performed. This is caused for example if an older PLC project is present where password changes are not supported. + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiPasswordChangeNotAcceptedException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiPasswordExpiredException.cs b/src/Webserver.API/Exceptions/ApiPasswordExpiredException.cs new file mode 100644 index 0000000..2b334c9 --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiPasswordExpiredException.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// The password of the user account has expired. The user needs to change the password to successfully authenticate again. + /// + public class ApiPasswordExpiredException : Exception + { + private static string message = "The password of the user account has expired. The user needs to change the password to successfully authenticate again."; + /// + /// The password of the user account has expired. The user needs to change the password to successfully authenticate again. + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiPasswordExpiredException(Exception innerException) : base(message, innerException) { } + /// + /// The password of the user account has expired. The user needs to change the password to successfully authenticate again. + /// + public ApiPasswordExpiredException() : base(message) { } + /// + /// The password of the user account has expired. The user needs to change the password to successfully authenticate again. + /// + /// Further information about the error message that explains the reason for the exception. + public ApiPasswordExpiredException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// The password of the user account has expired. The user needs to change the password to successfully authenticate again. + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiPasswordExpiredException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} \ No newline at end of file diff --git a/src/Webserver.API/Exceptions/ApiResourceAlreadyExistsException.cs b/src/Webserver.API/Exceptions/ApiResourceAlreadyExistsException.cs index 54da8b8..c5b2306 100644 --- a/src/Webserver.API/Exceptions/ApiResourceAlreadyExistsException.cs +++ b/src/Webserver.API/Exceptions/ApiResourceAlreadyExistsException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiResourceContentHasBeenCorruptedException.cs b/src/Webserver.API/Exceptions/ApiResourceContentHasBeenCorruptedException.cs index aa55c04..40ae41f 100644 --- a/src/Webserver.API/Exceptions/ApiResourceContentHasBeenCorruptedException.cs +++ b/src/Webserver.API/Exceptions/ApiResourceContentHasBeenCorruptedException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiResourceContentIsNotReadyException.cs b/src/Webserver.API/Exceptions/ApiResourceContentIsNotReadyException.cs index 9d826ab..ef9b5e6 100644 --- a/src/Webserver.API/Exceptions/ApiResourceContentIsNotReadyException.cs +++ b/src/Webserver.API/Exceptions/ApiResourceContentIsNotReadyException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiResourceDeploymentFailedException.cs b/src/Webserver.API/Exceptions/ApiResourceDeploymentFailedException.cs index 2a52d3c..e6d65f7 100644 --- a/src/Webserver.API/Exceptions/ApiResourceDeploymentFailedException.cs +++ b/src/Webserver.API/Exceptions/ApiResourceDeploymentFailedException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiResourceDoesNotExistException.cs b/src/Webserver.API/Exceptions/ApiResourceDoesNotExistException.cs index cffdec8..152281b 100644 --- a/src/Webserver.API/Exceptions/ApiResourceDoesNotExistException.cs +++ b/src/Webserver.API/Exceptions/ApiResourceDoesNotExistException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiResourceLimitReachedException.cs b/src/Webserver.API/Exceptions/ApiResourceLimitReachedException.cs index 75aa940..1e24003 100644 --- a/src/Webserver.API/Exceptions/ApiResourceLimitReachedException.cs +++ b/src/Webserver.API/Exceptions/ApiResourceLimitReachedException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiResourceVisibilityIsNotPublicException.cs b/src/Webserver.API/Exceptions/ApiResourceVisibilityIsNotPublicException.cs index f5a07be..541afa9 100644 --- a/src/Webserver.API/Exceptions/ApiResourceVisibilityIsNotPublicException.cs +++ b/src/Webserver.API/Exceptions/ApiResourceVisibilityIsNotPublicException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiSystemIsBusyException.cs b/src/Webserver.API/Exceptions/ApiSystemIsBusyException.cs index 0ad55e3..6963528 100644 --- a/src/Webserver.API/Exceptions/ApiSystemIsBusyException.cs +++ b/src/Webserver.API/Exceptions/ApiSystemIsBusyException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { @@ -29,7 +25,7 @@ public ApiSystemIsBusyException() : base(message) { } /// /// The exception that is the cause of the current exception, or a null reference /// (Nothing in Visual Basic) if no inner exception is specified. - public ApiSystemIsBusyException(Exception innerException) : base(message, innerException){ } + public ApiSystemIsBusyException(Exception innerException) : base(message, innerException) { } /// /// The requested operation cannot be executet since the system is currently processing another request. diff --git a/src/Webserver.API/Exceptions/ApiSystemIsReadOnlyException.cs b/src/Webserver.API/Exceptions/ApiSystemIsReadOnlyException.cs index da5cff7..fd8042d 100644 --- a/src/Webserver.API/Exceptions/ApiSystemIsReadOnlyException.cs +++ b/src/Webserver.API/Exceptions/ApiSystemIsReadOnlyException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiTicketNotFoundException.cs b/src/Webserver.API/Exceptions/ApiTicketNotFoundException.cs index 3384d12..f7ec6a5 100644 --- a/src/Webserver.API/Exceptions/ApiTicketNotFoundException.cs +++ b/src/Webserver.API/Exceptions/ApiTicketNotFoundException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiTicketNotInCompletedStateException.cs b/src/Webserver.API/Exceptions/ApiTicketNotInCompletedStateException.cs index f757fe4..c2a0005 100644 --- a/src/Webserver.API/Exceptions/ApiTicketNotInCompletedStateException.cs +++ b/src/Webserver.API/Exceptions/ApiTicketNotInCompletedStateException.cs @@ -3,10 +3,6 @@ // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { @@ -23,8 +19,9 @@ public ApiTicketNotInCompletedStateException(ApiTicket ticket) : base($"Ticket: {ticket.Id + Environment.NewLine} is not in completed state! " + $"instead: {ticket.State.ToString() + Environment.NewLine} " + $"further ticket Information:{Environment.NewLine}" + - $"ticket Provider: { ticket.Provider.ToString() + Environment.NewLine}" + - $"date created: { ticket.Date_created }" + - ((ticket.Data != null && ticket.Data.ToString() != "{}") ? $"ticket data: {ticket.Data.ToString()}":"")) { } + $"ticket Provider: {ticket.Provider.ToString() + Environment.NewLine}" + + $"date created: {ticket.Date_created}" + + ((ticket.Data != null && ticket.Data.ToString() != "{}") ? $"ticket data: {ticket.Data.ToString()}" : "")) + { } } } diff --git a/src/Webserver.API/Exceptions/ApiTicketingEndpointUploadException.cs b/src/Webserver.API/Exceptions/ApiTicketingEndpointUploadException.cs index 5c2175c..518152a 100644 --- a/src/Webserver.API/Exceptions/ApiTicketingEndpointUploadException.cs +++ b/src/Webserver.API/Exceptions/ApiTicketingEndpointUploadException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiTimestampOutOfRangeException.cs b/src/Webserver.API/Exceptions/ApiTimestampOutOfRangeException.cs new file mode 100644 index 0000000..1876ea3 --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiTimestampOutOfRangeException.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// The timestamp is not within the allowed range + /// + public class ApiTimestampOutOfRangeException : Exception + { + private static string message = "The timestamp is not within the allowed range"; + /// + /// The timestamp is not within the allowed range + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiTimestampOutOfRangeException(Exception innerException) : base(message, innerException) { } + /// + /// The timestamp is not within the allowed range + /// + public ApiTimestampOutOfRangeException() : base(message) { } + /// + /// The timestamp is not within the allowed range + /// + /// Further information about the error message that explains the reason for the exception. + public ApiTimestampOutOfRangeException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// The timestamp is not within the allowed range + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiTimestampOutOfRangeException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiUnsupportedAddressException.cs b/src/Webserver.API/Exceptions/ApiUnsupportedAddressException.cs index 65e434a..8d1c5bd 100644 --- a/src/Webserver.API/Exceptions/ApiUnsupportedAddressException.cs +++ b/src/Webserver.API/Exceptions/ApiUnsupportedAddressException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiVariableIsNotAStructureException.cs b/src/Webserver.API/Exceptions/ApiVariableIsNotAStructureException.cs index aad6d49..42fa245 100644 --- a/src/Webserver.API/Exceptions/ApiVariableIsNotAStructureException.cs +++ b/src/Webserver.API/Exceptions/ApiVariableIsNotAStructureException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiWebAppConfigParserException.cs b/src/Webserver.API/Exceptions/ApiWebAppConfigParserException.cs index 1824f91..71eb8f1 100644 --- a/src/Webserver.API/Exceptions/ApiWebAppConfigParserException.cs +++ b/src/Webserver.API/Exceptions/ApiWebAppConfigParserException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/ApiWebAppConfigurationFailedException.cs b/src/Webserver.API/Exceptions/ApiWebAppConfigurationFailedException.cs index c1862a6..d59ddfe 100644 --- a/src/Webserver.API/Exceptions/ApiWebAppConfigurationFailedException.cs +++ b/src/Webserver.API/Exceptions/ApiWebAppConfigurationFailedException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Exceptions/InvalidHttpRequestException.cs b/src/Webserver.API/Exceptions/InvalidHttpRequestException.cs index 95dabfb..2d1bd8d 100644 --- a/src/Webserver.API/Exceptions/InvalidHttpRequestException.cs +++ b/src/Webserver.API/Exceptions/InvalidHttpRequestException.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Exceptions { diff --git a/src/Webserver.API/Models/AdditionalTicketData/ApiPlcRestoreBackupTicketData.cs b/src/Webserver.API/Models/AdditionalTicketData/ApiPlcRestoreBackupTicketData.cs index 1d460a1..f9375ac 100644 --- a/src/Webserver.API/Models/AdditionalTicketData/ApiPlcRestoreBackupTicketData.cs +++ b/src/Webserver.API/Models/AdditionalTicketData/ApiPlcRestoreBackupTicketData.cs @@ -2,8 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Text; namespace Siemens.Simatic.S7.Webserver.API.Models.AdditionalTicketData { diff --git a/src/Webserver.API/Models/AdditionalTicketData/ApiTicketDataBase.cs b/src/Webserver.API/Models/AdditionalTicketData/ApiTicketDataBase.cs index b4bf963..4e2a1df 100644 --- a/src/Webserver.API/Models/AdditionalTicketData/ApiTicketDataBase.cs +++ b/src/Webserver.API/Models/AdditionalTicketData/ApiTicketDataBase.cs @@ -2,8 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Text; namespace Siemens.Simatic.S7.Webserver.API.Models.AdditionalTicketData { diff --git a/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms.cs b/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms.cs new file mode 100644 index 0000000..6a65d41 --- /dev/null +++ b/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms.cs @@ -0,0 +1,108 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Siemens.Simatic.S7.Webserver.API.Models.AlarmsBrowse +{ + /// + /// The current alarms of the PLC + /// + public class ApiAlarms + { + /// + /// The actual language in which the text entries are returned.
+ ///If the provided language in the request was invalid, invalid must be returned by the API and all text attributes must be empty strings(if requested for the response). + ///
+ public string Language { get; set; } + /// + /// The timestamp of the last modification of the alarming system at the time when the Read request was performed.
+ /// Checking this, the user could find out if new changes occurred on the alarming system without polling for the data. + ///
+ public DateTime Last_Modified { get; set; } + /// + /// The number of active alarms.
+ /// It must be the number of total available entries, not the entries returned by a filtered request. + ///
+ public uint Count_Current { get; set; } + /// + /// The maximum number of possible alarms. + /// + public uint Count_Max { get; set; } + /// + /// The array of alarms where each object represents an individual alarm entry.
+ /// It must be omitted from the response if the requested count was 0.
+ /// Otherwise, it must contain either an array of alarms or an empty array in case that there are no active alarms. + ///
+ public List Entries { get; set; } + + /// + /// Check wether properties match + /// + /// + /// Returns true if the ApiAlarmsBrowse are the same + public override bool Equals(object obj) + { + var structure = obj as ApiAlarms; + if (structure == null) + { + return false; + } + if ((structure.Entries == null) != (this.Entries == null)) + { + return false; + } + if (structure.Entries != null) + { + structure.Entries.SequenceEqual(this.Entries); + } + return structure.Language == this.Language && + structure.Last_Modified == this.Last_Modified && + structure.Count_Current == this.Count_Current && + structure.Count_Max == this.Count_Max; + } + + /// + /// GetHashCode for ApiAlarmsBrowse + /// + /// Hash code of the ApiAlarms + public override int GetHashCode() + { + int EntriesHashCode = 0; + if (Entries != null) + { + foreach (var entry in Entries) + { + EntriesHashCode ^= entry.GetHashCode(); + } + } + return (EntriesHashCode, Language, Last_Modified, Count_Current, Count_Max).GetHashCode(); + } + + /// + /// ToString for ApiAlarms + /// + /// ApiAlarms as a multiline string + public override string ToString() + { + return ToString(NullValueHandling.Ignore); + } + /// + /// ToString for ApiAlarms + /// + /// Defines if null values should be ignored + /// ApiAlarms as a multiline string + public string ToString(NullValueHandling nullValueHandling) + { + JsonSerializerSettings options = new JsonSerializerSettings() + { + NullValueHandling = nullValueHandling, + }; + string result = JsonConvert.SerializeObject(this, Formatting.Indented, options); + return result; + } + } +} diff --git a/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_Entry.cs b/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_Entry.cs new file mode 100644 index 0000000..a7c56fa --- /dev/null +++ b/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_Entry.cs @@ -0,0 +1,135 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Siemens.Simatic.S7.Webserver.API.Enums; +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Models.AlarmsBrowse +{ + /// + /// Represents an individual alarm entry + /// + public class ApiAlarms_Entry + { + /// + /// The ID of the alarm. It is a 64-bit value that must be encoded as a string. + /// + public string Id { get; set; } + /// + /// Contains the alarm number. + /// + public int? Alarm_Number { get; set; } + /// + /// Contains the alarm status. The value must contain either "incoming" or "outgoing". + /// + [JsonConverter(typeof(StringEnumConverter))] + public ApiObjectDirectoryStatus? Status { get; set; } + /// + /// The UTC timestamp on when the alarm went into incoming or outgoing state, provided as ISO 8601 string.
+ /// This attribute does not consider the timestamp of acknowledgement. The precision must be in nanoseconds. + ///
+ public DateTime Timestamp { get; set; } + /// + /// The producer of the alarm. + /// + public string Producer { get; set; } + /// + /// Contains the hardware identifier in case that the alarm producer is system_diagnostics.
+ /// If any other case, the attribute will not be returned. + ///
+ public int? Hwid { get; set; } + /// + /// This exist if the alarm is an alarm that is generally acknowledgeable.
+ /// If the alarm was not configured as acknowledgeable alarm, then this object must not be returned. + ///
+ public ApiAlarms_EntryAcknowledgement Acknowledgement { get; set; } + /// + /// The alarm text in the language returned by attribute language.
+ /// Must be empty if the text parsing failed due to an internal error. + ///
+ public string Alarm_Text { get; set; } + /// + /// The info text in the language returned by attribute language.
+ /// Must be empty if the text parsing failed due to an internal error. + ///
+ public string Info_Text { get; set; } + /// + /// This attribute must be present if either alarm_text or info_text is part of the response.
+ /// If any of the two texts is inconsistent, then this flag must return true. + ///
+ public bool? Text_Inconsistent { get; set; } + + /// + /// Check wether properties match + /// + /// + /// Returns true if the ApiAlarmsBrowse are the same + public override bool Equals(object obj) + { + var structure = obj as ApiAlarms_Entry; + if (structure is null) + { + return false; + } + if ((structure.Acknowledgement == null) != (this.Acknowledgement == null)) + { + return false; + } + if (structure.Acknowledgement != null) + { + if (!structure.Acknowledgement.Equals(this.Acknowledgement)) + { + return false; + } + } + return structure != null && + structure.Id == this.Id && + structure.Alarm_Number == this.Alarm_Number && + structure.Status == this.Status && + structure.Timestamp == this.Timestamp && + structure.Hwid == this.Hwid && + structure.Alarm_Text == this.Alarm_Text && + structure.Info_Text == this.Info_Text && + structure.Text_Inconsistent == this.Text_Inconsistent; + } + + /// + /// GetHashCode for ApiAlarm_Entry + /// + /// Hash code of ApiAlarm_Entry + public override int GetHashCode() + { + int acknowledgementHash = 0; + if (Acknowledgement != null) + { + acknowledgementHash ^= Acknowledgement.GetHashCode(); + } + return (Id, Alarm_Number, Status, Timestamp, Hwid, acknowledgementHash, Alarm_Text, Info_Text, Text_Inconsistent).GetHashCode(); + } + + /// + /// ToString for ApiAlarms_Entry + /// + /// ApiAlarms as a multiline string + public override string ToString() + { + return ToString(NullValueHandling.Ignore); + } + /// + /// ToString for ApiAlarms_Entry + /// + /// Defines if null values should be ignored + /// ApiAlarms as a multiline string + public string ToString(NullValueHandling nullValueHandling) + { + JsonSerializerSettings options = new JsonSerializerSettings() + { + NullValueHandling = nullValueHandling, + }; + string result = JsonConvert.SerializeObject(this, Formatting.Indented, options); + return result; + } + } +} diff --git a/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_EntryAcknowledgement.cs b/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_EntryAcknowledgement.cs new file mode 100644 index 0000000..a9de5a6 --- /dev/null +++ b/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_EntryAcknowledgement.cs @@ -0,0 +1,78 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Siemens.Simatic.S7.Webserver.API.Enums; +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Models.AlarmsBrowse +{ + /// + /// This exist if the alarm is an alarm that is generally acknowledgeable. + /// + public class ApiAlarms_EntryAcknowledgement + { + /// + /// Readable string that tells the acknowledgement state of the alarm: + /// + /// not_acknowledged + /// acknowledged + /// + /// + [JsonConverter(typeof(StringEnumConverter))] + public ApiAlarmAcknowledgementState State { get; set; } + /// + /// In case that the alarms current incoming/outgoing status has been acknowledged, the timestamp returns the corresponding acknowledgement time encoded as ISO timestamp. + /// The precision must be in nanoseconds.
+ /// The timestamp must not be present if the alarm has not been acknowledged yet. + ///
+ public DateTime Timestamp { get; set; } + + /// + /// Check wether properties match + /// + /// + /// Returns true if the ApiAlarmsBrowse are the same + public override bool Equals(object obj) + { + var structure = obj as ApiAlarms_EntryAcknowledgement; + if (structure == null) { return false; } + return structure != null && + structure.State == this.State && + structure.Timestamp == this.Timestamp; + } + + /// + /// GetHashCode for ApiAlarmsBrowse + /// + /// Hash code of ApiAlarm_EntryAcknowledgement + public override int GetHashCode() + { + return (State, Timestamp).GetHashCode(); + } + + /// + /// ToString for ApiAlarms_EntryAcknowledgement + /// + /// ApiAlarms as a multiline string + public override string ToString() + { + return ToString(NullValueHandling.Ignore); + } + /// + /// ToString for ApiAlarms_EntryAcknowledgement + /// + /// Defines if null values should be ignored + /// ApiAlarms as a multiline string + public string ToString(NullValueHandling nullValueHandling) + { + JsonSerializerSettings options = new JsonSerializerSettings() + { + NullValueHandling = nullValueHandling, + }; + string result = JsonConvert.SerializeObject(this, Formatting.Indented, options); + return result; + } + } +} diff --git a/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_RequestFilters.cs b/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_RequestFilters.cs new file mode 100644 index 0000000..fc8f1f7 --- /dev/null +++ b/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_RequestFilters.cs @@ -0,0 +1,39 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Enums; +using System.Collections.Generic; + +namespace Siemens.Simatic.S7.Webserver.API.Models.AlarmsBrowse +{ + /// + /// Optional parameter for ApiAlarms.Browse request + /// + public class ApiAlarms_RequestFilters + { + /// + /// The mode if the attributes shall either be included or excluded. Can be either include or exclude. + /// + public ApiBrowseFilterMode Mode { get; set; } + /// + /// If present, the user has the option to include or exclude certain attributes, see mode parameter.
+ /// Possible array entries are: "alarm_text", "info_text", "status", "timestamp", "acknowledgement", "alarm_number", "producer" + ///
+ public List Attributes { get; set; } + + /// + /// Base constructor for ApiAlarms_RequestFilters + /// + public ApiAlarms_RequestFilters() { } + /// + /// Constructor with parameters. + /// + /// The mode if the attributes shall be included or excluded. Can be either include or exclude. + /// List of possible filter attributes. + public ApiAlarms_RequestFilters(ApiBrowseFilterMode mode, List attributes) + { + Mode = mode; + Attributes = attributes; + } + } +} diff --git a/src/Webserver.API/Models/ApiClass.cs b/src/Webserver.API/Models/ApiClass.cs index 04917d4..7f862c5 100644 --- a/src/Webserver.API/Models/ApiClass.cs +++ b/src/Webserver.API/Models/ApiClass.cs @@ -1,11 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models { diff --git a/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer.cs b/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer.cs new file mode 100644 index 0000000..3642e53 --- /dev/null +++ b/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer.cs @@ -0,0 +1,105 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using System; +using System.Collections.Generic; + +namespace Siemens.Simatic.S7.Webserver.API.Models.ApiDiagnosticBuffer +{ + /// + /// Containes information of the diagnosticbuffer and it's entires:
+ /// List of entries, Time of last modification, Count of current entries, Count of maximum entires, Language of the entries + ///
+ public class ApiDiagnosticBuffer + { + /// + /// The language of the response in which the texts are returned.
+ /// If the provided language in the request was invalid, invalid must be returned by the API. + ///
+ public string Language { get; set; } + /// + /// The timestamp of the system time of the last change to the diagnostic buffer (same as the timestamp of the last entry), expressed as ISO 8601 timestamp.
+ /// Precision must be nanoseconds. + ///
+ public DateTime Last_Modified { get; set; } + /// + /// The number of available diagnostic buffer entries. It must be the number of total available entries, not the entries returned by a filtered request. + /// + public int Count_Current { get; set; } + /// + /// The maximum number of possible diagnostic buffer entries. + /// + public int Count_Max { get; set; } + /// + /// The array of diagnostic buffer entries where each object represents an individual diagnostic buffer entry.
+ /// It must be omitted from the response if the requested count was 0. Otherwise, it must contain an array of entries. + ///
+ public List Entries { get; set; } + + /// + /// Check wether properties match + /// + /// ApiDiagnosticBuffer + /// Returns true if the ApiDiagnosticBuffer are the same + public override bool Equals(object obj) + { + var structure = obj as ApiDiagnosticBuffer; + if (structure == null) { return false; } + if ((structure.Entries == null) != (this.Entries == null)) + { + return false; + } + if (structure.Entries != null) + { + if (structure.Entries.Count != this.Entries.Count) { return false; } + for (int i = 0; i < structure.Entries.Count; i++) + { + if (!structure.Entries[i].Equals(this.Entries[i])) { return false; } + } + } + return structure.Last_Modified == this.Last_Modified && + structure.Count_Current == this.Count_Current && + structure.Count_Max == this.Count_Max && + structure.Language == this.Language; + } + /// + /// GetHashCode for ApiDiagnosticBuffer etc. + /// + /// hashcode for the ApiDiagnosticBuffer + public override int GetHashCode() + { + int EntriesHashCode = 0; + if (Entries != null) + { + foreach (var entry in Entries) + { + EntriesHashCode ^= entry.GetHashCode(); + } + } + return (EntriesHashCode, Last_Modified, Count_Current, Count_Max, Language).GetHashCode(); + } + /// + /// ToString for ApiDiagnosticBuffer + /// + /// ApiDiagnosticBuffer as a multiline string + public override string ToString() + { + return ToString(NullValueHandling.Ignore); + } + /// + /// ToString for ApiDiagnosticBuffer + /// + /// Defines if null values should be ignored + /// ApiDiagnosticBuffer as a multiline string + public string ToString(NullValueHandling nullValueHandling) + { + JsonSerializerSettings options = new JsonSerializerSettings() + { + NullValueHandling = nullValueHandling, + }; + string result = JsonConvert.SerializeObject(this, Formatting.Indented, options); + return result; + } + } +} diff --git a/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_Entry.cs b/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_Entry.cs new file mode 100644 index 0000000..7a8c169 --- /dev/null +++ b/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_Entry.cs @@ -0,0 +1,103 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Siemens.Simatic.S7.Webserver.API.Enums; +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Models.ApiDiagnosticBuffer +{ + /// + /// Containes one entry from the Diagnosticbuffer. + /// + public class ApiDiagnosticBuffer_Entry + { + /// + /// This attribute is provided as UTC time. The local time of the PLC is not considered for the returned timestamp.
+ /// The timestamp of the diagnostic buffer entry in UTC Time, expressed as ISO 8601 timestamp. Precision must be nanoseconds. + ///
+ public DateTime Timestamp { get; set; } + /// + /// Either "incoming" or "outgoing". + /// + [JsonConverter(typeof(StringEnumConverter))] + public ApiObjectDirectoryStatus Status { get; set; } + /// + /// The long diagnostic buffer text.
Must be empty if the text parsing failed due to an internal error. + ///
+ public string Long_Text { get; set; } + /// + /// The short diagnostic buffer text.
Must be empty if the text parsing failed due to an internal error. + ///
+ public string Short_Text { get; set; } + /// + /// The help text message in case of an incoming event.
Must be empty if the text parsing failed due to an internal error. + ///
+ public string Help_Text { get; set; } + /// + /// Contains the event ID of the diagnostic buffer entry which consists of the text list ID and text ID of the event.
+ /// On a client, the event ID is usually shown in hexadecimal representation, for example "16# 02:426A". + ///
+ public ApiDiagnosticBuffer_EntryEvent Event { get; set; } + + /// + /// Check whether properties match + /// + /// ApiDiagnosticBuffer_Entry + /// Returns true if the ApiDiagnosticBuffer_Entries are the same + public override bool Equals(object obj) + { + var structure = obj as ApiDiagnosticBuffer_Entry; + if (structure == null) { return false; } + if ((structure.Short_Text == null) != (this.Short_Text == null)) + { + return false; + } + if ((structure.Long_Text == null) != (this.Long_Text == null)) + { + return false; + } + if ((structure.Help_Text == null) != (this.Help_Text == null)) + { + return false; + } + return structure.Timestamp == this.Timestamp && + structure.Status == this.Status && + (structure.Long_Text ?? "") == (this.Long_Text ?? "") && + (structure.Short_Text ?? "") == (this.Short_Text ?? "") && + (structure.Help_Text ?? "") == (this.Help_Text ?? "") && + structure.Event.Equals(this.Event); + } + /// + /// GetHashCode for DiagnosticBufferEvent + /// + /// hashcode for the DiagnosticBufferEvent + public override int GetHashCode() + { + return (Timestamp, Status, Long_Text ?? "", Short_Text ?? "", Help_Text ?? "", Event.GetHashCode()).GetHashCode(); + } + /// + /// ToString for ApiDiagnosticBuffer_Entry + /// + /// ApiDiagnosticBuffer_Entry as a multiline string + public override string ToString() + { + return ToString(NullValueHandling.Ignore); + } + /// + /// ToString for ApiDiagnosticBuffer_Entry + /// + /// Defines if null values should be ignored + /// ApiDiagnosticBuffer_Entry as a multiline string + public string ToString(NullValueHandling nullValueHandling) + { + JsonSerializerSettings options = new JsonSerializerSettings() + { + NullValueHandling = nullValueHandling, + }; + string result = JsonConvert.SerializeObject(this, Formatting.Indented, options); + return result; + } + } +} diff --git a/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_EntryEvent.cs b/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_EntryEvent.cs new file mode 100644 index 0000000..1f10334 --- /dev/null +++ b/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_EntryEvent.cs @@ -0,0 +1,64 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; + +namespace Siemens.Simatic.S7.Webserver.API.Models.ApiDiagnosticBuffer +{ + /// + /// Containes the Textlist_Id and Text_Id of a diagnosticbuffer entry event. + /// + public class ApiDiagnosticBuffer_EntryEvent + { + /// + /// The text list ID of the event. + /// + public int Textlist_Id { get; set; } + /// + /// The text ID of the event. + /// + public int Text_Id { get; set; } + /// + /// Check wether properties match + /// + /// ApiDiagnosticBuffer_EntryEvent + /// Returns true if the DiagnosticBufferEvents are the same + public override bool Equals(object obj) + { + var structure = obj as ApiDiagnosticBuffer_EntryEvent; + if (structure == null) { return false; } + return structure.Textlist_Id == this.Textlist_Id && + structure.Text_Id == this.Text_Id; + } + /// + /// GetHashCode for DiagnosticBufferEvent + /// + /// hashcode for the DiagnosticBufferEvent + public override int GetHashCode() + { + return (Textlist_Id, Text_Id).GetHashCode(); + } + /// + /// ToString for ApiDiagnosticBuffer_EntryEvent + /// + /// ApiDiagnosticBuffer_EntryEvent as a multiline string + public override string ToString() + { + return ToString(NullValueHandling.Ignore); + } + /// + /// ToString for ApiDiagnosticBuffer_EntryEvent + /// + /// Defines if null values should be ignored + /// ApiDiagnosticBuffer_EntryEvent as a multiline string + public string ToString(NullValueHandling nullValueHandling) + { + JsonSerializerSettings options = new JsonSerializerSettings() + { + NullValueHandling = nullValueHandling, + }; + string result = JsonConvert.SerializeObject(this, Formatting.Indented, options); + return result; + } + } +} diff --git a/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_RequestFilters.cs b/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_RequestFilters.cs new file mode 100644 index 0000000..c678e5a --- /dev/null +++ b/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_RequestFilters.cs @@ -0,0 +1,25 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Enums; +using System.Collections.Generic; + +namespace Siemens.Simatic.S7.Webserver.API.Models.ApiDiagnosticBuffer +{ + /// + /// Optional parameter for ApiDiagnostucBuffer request + /// + public class ApiDiagnosticBuffer_RequestFilters + { + /// + /// The mode if the attributes shall either be included or excluded. Can be either include or exclude. + /// + public ApiBrowseFilterMode Mode { get; set; } + /// + /// If the entries object is not present in the request, then all parameters must be returned in the response.
+ /// If present, the user has the option to include or exclude certain attributes, see mode parameter.
+ /// Possible array entries are: "short_text", "long_text", "help_text" + ///
+ public List Attributes { get; set; } + } +} diff --git a/src/Webserver.API/Models/ApiError.cs b/src/Webserver.API/Models/ApiError.cs index dda6e37..b7ee79b 100644 --- a/src/Webserver.API/Models/ApiError.cs +++ b/src/Webserver.API/Models/ApiError.cs @@ -2,11 +2,7 @@ // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models { diff --git a/src/Webserver.API/Models/ApiFailsafeRuntimeGroup.cs b/src/Webserver.API/Models/ApiFailsafeRuntimeGroup.cs new file mode 100644 index 0000000..2ce4caa --- /dev/null +++ b/src/Webserver.API/Models/ApiFailsafeRuntimeGroup.cs @@ -0,0 +1,70 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Siemens.Simatic.S7.Webserver.API.Services.Converters.JsonConverters; +using System; +using System.Linq; + +namespace Siemens.Simatic.S7.Webserver.API.Models +{ + /// + /// Represents a Failsafe Runtime Group on the PLC + /// + public class ApiFailsafeRuntimeGroup + { + /// + /// The name of the F-runtime group. + /// + public string Name { get; set; } + /// + /// The signature of the runtime group, encoded as array of 4 elements to represent the 32-bit signature. + /// + public string Signature { get; set; } + /// + /// The current cycle time. + /// + [JsonConverter(typeof(TimeSpanISO8601Converter))] + public TimeSpan Cycle_time_current { get; set; } + /// + /// The maximum cycle time. + /// + [JsonConverter(typeof(TimeSpanISO8601Converter))] + public TimeSpan Cycle_time_Max { get; set; } + /// + /// The current runtime. + /// + [JsonConverter(typeof(TimeSpanISO8601Converter))] + public TimeSpan Runtime_current { get; set; } + /// + /// The maximum runtime. + /// + [JsonConverter(typeof(TimeSpanISO8601Converter))] + public TimeSpan Runtime_max { get; set; } + + /// + /// Compares object and this + /// + /// Object to compare + /// True if input object and this match + public override bool Equals(object obj) + { + return obj is ApiFailsafeRuntimeGroup group && + Name == group.Name && + Enumerable.SequenceEqual(Signature, group.Signature) && + Cycle_time_current.Equals(group.Cycle_time_current) && + Cycle_time_Max.Equals(group.Cycle_time_Max) && + Runtime_current.Equals(group.Runtime_current) && + Runtime_max.Equals(group.Runtime_max); + } + + /// + /// GetHashCode() + /// + /// Hash code + public override int GetHashCode() + { + return (Name, Signature, Cycle_time_current, Cycle_time_Max, Runtime_current, Runtime_max).GetHashCode(); + } + } +} diff --git a/src/Webserver.API/Models/ApiFileResource.cs b/src/Webserver.API/Models/ApiFileResource.cs index dcc7961..2f8ab7b 100644 --- a/src/Webserver.API/Models/ApiFileResource.cs +++ b/src/Webserver.API/Models/ApiFileResource.cs @@ -7,7 +7,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; namespace Siemens.Simatic.S7.Webserver.API.Models { diff --git a/src/Webserver.API/Models/ApiLanguage.cs b/src/Webserver.API/Models/ApiLanguage.cs new file mode 100644 index 0000000..b339cef --- /dev/null +++ b/src/Webserver.API/Models/ApiLanguage.cs @@ -0,0 +1,18 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System.Globalization; + +namespace Siemens.Simatic.S7.Webserver.API.Models +{ + /// + /// Class containing one language (culture info) + /// + public class ApiLanguage + { + /// + /// Language with built-in CultureInfo class + /// + public CultureInfo Language { get; set; } + } +} diff --git a/src/Webserver.API/Models/ApiPasswordExpiration.cs b/src/Webserver.API/Models/ApiPasswordExpiration.cs new file mode 100644 index 0000000..d1844a6 --- /dev/null +++ b/src/Webserver.API/Models/ApiPasswordExpiration.cs @@ -0,0 +1,44 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Models +{ + /// + /// Holds password expiration information. + /// + public class ApiPasswordExpiration + { + /// + /// The UTC timestamp, when the user password will expire. + /// + public DateTime Timestamp { get; set; } + + /// + /// Indicates to the user if the warning threshold for the password has been reached. + /// + public bool Warning { get; set; } + + /// + /// Compares this to input object + /// + /// Object to compare to + /// True if objects are the same + public override bool Equals(object obj) + { + return obj is ApiPasswordExpiration expiration && + Timestamp == expiration.Timestamp && + Warning == expiration.Warning; + } + + /// + /// Get Hash Code of PasswordExpiraton object + /// + /// Hash Code + public override int GetHashCode() + { + return (Timestamp, Warning).GetHashCode(); + } + } +} diff --git a/src/Webserver.API/Models/ApiPasswordPolicy.cs b/src/Webserver.API/Models/ApiPasswordPolicy.cs new file mode 100644 index 0000000..c5b0f8e --- /dev/null +++ b/src/Webserver.API/Models/ApiPasswordPolicy.cs @@ -0,0 +1,62 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Models +{ + /// + /// A set of criteria defined for passwords. + /// + public class ApiPasswordPolicy + { + /// + /// Minimum length of passwords + /// + public int Min_password_length { get; set; } + /// + /// Maximum length of passwords + /// + public int Max_password_length { get; set; } + /// + /// Minimum number of digits required in a password + /// + public int Min_digits { get; set; } + /// + /// Minimum number of special characters required in a password + /// + public int Min_special_characters { get; set; } + /// + /// If true, the password must contain uppercase letters. + /// + public bool Requires_uppercase_characters { get; set; } + /// + /// If true, the password must contain lowercase letters. + /// + public bool Requires_lowercase_characters { get; set; } + + /// + /// Check if incoming object is the same as this + /// + /// Object to check + /// True if they match + public override bool Equals(object obj) + { + return obj is ApiPasswordPolicy policy && + Min_password_length == policy.Min_password_length && + Max_password_length == policy.Max_password_length && + Min_digits == policy.Min_digits && + Min_special_characters == policy.Min_special_characters && + Requires_uppercase_characters == policy.Requires_uppercase_characters && + Requires_lowercase_characters == policy.Requires_lowercase_characters; + } + + /// + /// Get hashcode of object + /// + /// Hashcode + public override int GetHashCode() + { + return (Min_special_characters, Min_password_length, Min_digits, Max_password_length, Requires_uppercase_characters, Requires_lowercase_characters).GetHashCode(); + } + } +} diff --git a/src/Webserver.API/Models/ApiPlcProgramBrowseCodeBlocksData.cs b/src/Webserver.API/Models/ApiPlcProgramBrowseCodeBlocksData.cs new file mode 100644 index 0000000..caf709a --- /dev/null +++ b/src/Webserver.API/Models/ApiPlcProgramBrowseCodeBlocksData.cs @@ -0,0 +1,113 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Models +{ + /// + /// ApiPlcProgramBrowseCodeBlocksData: Data class representing a code block value in the ApiPlcProgramBrowseCodeBlocksRequest response. + /// + public class ApiPlcProgramBrowseCodeBlocksData : IEquatable + { + /// + /// Function to Memberwise clone an ApiPlcProgramData to another Object. + /// + /// + public ApiPlcProgramBrowseCodeBlocksData ShallowCopy() + { + return (ApiPlcProgramBrowseCodeBlocksData) this.MemberwiseClone(); + } + + /// + /// Name of the code block. + /// + [JsonProperty("name")] + public string Name { get; set; } + + /// + /// Number of the code block. + /// + [JsonProperty("block_number")] + public ushort BlockNumber { get; set; } + + /// + /// Type of the code block. + /// + [JsonProperty("block_type")] + public string BlockType { get; set; } + + /// + /// Constructor. + /// + [JsonConstructor] + public ApiPlcProgramBrowseCodeBlocksData(string name, ushort blockNumber, string blockType) + { + Name = name; + BlockNumber = blockNumber; + BlockType = blockType; + } + + /// + /// Returns the Name with Quotes => $"\"{Name}\"" + /// + /// + public string GetNameWithQuotes() + { + return $"\"{Name}\""; + } + + /// + /// return the Serialized Object + /// + /// Json Object String of the Data + public string GetObjectString() + { + return JsonConvert.SerializeObject(this, new JsonSerializerSettings() + { + ContractResolver = new CamelCasePropertyNamesContractResolver(), + NullValueHandling = NullValueHandling.Ignore + }); + } + + /// + /// Call GetNameWithQuotes for debugging comfort! + /// + /// Name with quotes + public override string ToString() + { + return GetNameWithQuotes(); + } + + /// + /// Check the object for equality. + /// + /// + /// + public override bool Equals(object obj) + { + return Equals(obj as ApiPlcProgramBrowseCodeBlocksData); + } + + /// + /// Check the object for equality. + /// + /// + /// + public virtual bool Equals(ApiPlcProgramBrowseCodeBlocksData obj) + { + return !(obj is null) && (obj.Name == Name) && (obj.BlockNumber == BlockNumber) && (obj.BlockType == BlockType); + } + + /// + /// Return the object's hash code. + /// + /// HashCode + public override int GetHashCode() + { + return (Name, BlockNumber, BlockType).GetHashCode(); + } + } +} diff --git a/src/Webserver.API/Models/ApiPlcProgramData.cs b/src/Webserver.API/Models/ApiPlcProgramData.cs index f6748b9..e022277 100644 --- a/src/Webserver.API/Models/ApiPlcProgramData.cs +++ b/src/Webserver.API/Models/ApiPlcProgramData.cs @@ -1,15 +1,13 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using Siemens.Simatic.S7.Webserver.API.Enums; using Siemens.Simatic.S7.Webserver.API.Exceptions; +using System; +using System.Collections.Generic; +using System.Linq; namespace Siemens.Simatic.S7.Webserver.API.Models { @@ -47,12 +45,16 @@ public ApiPlcProgramData ShallowCopy() /// /// ApiPlcProgramDataType => helper class to determine the TIA DataTypes and map them to the byte size,... /// - public ApiPlcProgramDataType Datatype { get { return dataType; } - set { + public ApiPlcProgramDataType Datatype + { + get { return dataType; } + set + { if (value == ApiPlcProgramDataType.None) throw new ApiInvalidResponseException("Api PlcProgramDataType:" + value.ToString() + " was invalid!"); dataType = value; - } } + } + } private List _arrayDimensions; /// @@ -97,7 +99,7 @@ public List BuildChildrenFromArrayDimensions(ListJson Object String of the Data public string GetObjectString() { - return JsonConvert.SerializeObject(this, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver() - , NullValueHandling = NullValueHandling.Ignore }); + return JsonConvert.SerializeObject(this, new JsonSerializerSettings() + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + , + NullValueHandling = NullValueHandling.Ignore + }); } /// diff --git a/src/Webserver.API/Models/ApiPlcProgramDataArrayIndexer.cs b/src/Webserver.API/Models/ApiPlcProgramDataArrayIndexer.cs index 708336c..8383353 100644 --- a/src/Webserver.API/Models/ApiPlcProgramDataArrayIndexer.cs +++ b/src/Webserver.API/Models/ApiPlcProgramDataArrayIndexer.cs @@ -1,11 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models { @@ -46,5 +41,5 @@ public override int GetHashCode() return (Start_index, Count).GetHashCode(); } } - + } diff --git a/src/Webserver.API/Models/ApiPlcProgramDataTypes/ApiDateAndTime.cs b/src/Webserver.API/Models/ApiPlcProgramDataTypes/ApiDateAndTime.cs index 46f9be4..62033ff 100644 --- a/src/Webserver.API/Models/ApiPlcProgramDataTypes/ApiDateAndTime.cs +++ b/src/Webserver.API/Models/ApiPlcProgramDataTypes/ApiDateAndTime.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.ApiPlcProgramDataTypes { @@ -18,7 +14,9 @@ public class ApiDateAndTime /// /// Year of the Date And Time Tag /// - public int Year { get + public int Year + { + get { return _year; } @@ -32,7 +30,9 @@ public int Year { get /// /// Month of the Date And Time Tag /// - public int Month {get + public int Month + { + get { return _month; } @@ -46,7 +46,9 @@ public int Month {get /// /// Day of the Date And Time Tag /// - public int Day { get + public int Day + { + get { return _day; } @@ -60,7 +62,9 @@ public int Day { get /// /// Hour of the Date And Time Tag /// - public int Hour { get + public int Hour + { + get { return _hour; } @@ -74,7 +78,9 @@ public int Hour { get /// /// Minute of the Date And Time Tag /// - public int Minute { get + public int Minute + { + get { return _minute; } @@ -88,7 +94,9 @@ public int Minute { get /// /// Second of the Date And Time Tag /// - public double Second { get + public double Second + { + get { return _second; } @@ -120,8 +128,8 @@ public ApiDateAndTime() /// hour to set /// minute to set /// second to set - public ApiDateAndTime(int year, int month, int day, int hour, int minute, double second) - : this((new DateTime(year, month, day, hour, minute, (int)second)).AddMilliseconds((second-(int)second)*1000)) + public ApiDateAndTime(int year, int month, int day, int hour, int minute, double second) + : this((new DateTime(year, month, day, hour, minute, (int)second)).AddMilliseconds((second - (int)second) * 1000)) { } @@ -129,7 +137,7 @@ public ApiDateAndTime(int year, int month, int day, int hour, int minute, double /// Represents the biggest possible value of ApiDateAndTime. This field is constant. /// public static readonly ApiDateAndTime MaxValue = new ApiDateAndTime() { _year = 2089, _month = 12, _day = 31, _hour = 23, _minute = 59, _second = 59.999 }; - + /// /// Represents the smallest possible value of ApiDateAndTime. This field is constant. @@ -147,7 +155,7 @@ public ApiDateAndTime(DateTime dateTime) this._day = dateTime.Day; this._hour = dateTime.Hour; this._minute = dateTime.Minute; - this._second = dateTime.Second + ((double)dateTime.Millisecond/1000); + this._second = dateTime.Second + ((double)dateTime.Millisecond / 1000); CheckValidity(nameof(dateTime)); } diff --git a/src/Webserver.API/Models/ApiPlcProgramDataTypes/ApiS5Time.cs b/src/Webserver.API/Models/ApiPlcProgramDataTypes/ApiS5Time.cs index 935883c..3f2abba 100644 --- a/src/Webserver.API/Models/ApiPlcProgramDataTypes/ApiS5Time.cs +++ b/src/Webserver.API/Models/ApiPlcProgramDataTypes/ApiS5Time.cs @@ -2,10 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.ApiPlcProgramDataTypes { @@ -18,13 +14,15 @@ public class ApiS5Time /// /// Base of the displayment in the response /// - public int Basis { get + public int Basis + { + get { return _basis; } set { - if(value == 10 || value == 100||value == 1000|| value == 10000) + if (value == 10 || value == 100 || value == 1000 || value == 10000) { _basis = value; } @@ -39,13 +37,15 @@ public int Basis { get /// /// Value of the requested var /// - public int Value { get + public int Value + { + get { return _value; } set { - if(value >= 0 && value <= 999) + if (value >= 0 && value <= 999) { _value = value; } @@ -111,17 +111,17 @@ public ApiS5Time(TimeSpan timeSpan) Basis = 10; Value = (int)(timeSpan.TotalMilliseconds / (double)Basis); } - else if(timeSpan >= TimeSpan.FromSeconds(10) && timeSpan < TimeSpan.FromSeconds(100)) + else if (timeSpan >= TimeSpan.FromSeconds(10) && timeSpan < TimeSpan.FromSeconds(100)) { Basis = 100; Value = (int)((timeSpan.TotalMilliseconds / (double)Basis)); } - else if(timeSpan >= TimeSpan.FromSeconds(100) && timeSpan < TimeSpan.FromSeconds(1000)) + else if (timeSpan >= TimeSpan.FromSeconds(100) && timeSpan < TimeSpan.FromSeconds(1000)) { Basis = 1000; Value = (int)(timeSpan.TotalMilliseconds / (double)Basis); } - else if(timeSpan >= TimeSpan.FromSeconds(1000) && timeSpan < TimeSpan.FromSeconds(10000)) + else if (timeSpan >= TimeSpan.FromSeconds(1000) && timeSpan < TimeSpan.FromSeconds(10000)) { Basis = 10000; Value = (int)(timeSpan.TotalMilliseconds / (double)Basis); @@ -130,7 +130,7 @@ public ApiS5Time(TimeSpan timeSpan) { throw new ArgumentOutOfRangeException(nameof(timeSpan)); } - if(GetTimeSpan() != timeSpan) + if (GetTimeSpan() != timeSpan) { throw new ArgumentOutOfRangeException(nameof(timeSpan)); } @@ -161,7 +161,7 @@ public bool Equals(ApiS5Time other) /// public override int GetHashCode() { - return (Basis,Value).GetHashCode(); + return (Basis, Value).GetHashCode(); } } } diff --git a/src/Webserver.API/Models/ApiQuantityStructure.cs b/src/Webserver.API/Models/ApiQuantityStructure.cs new file mode 100644 index 0000000..786debc --- /dev/null +++ b/src/Webserver.API/Models/ApiQuantityStructure.cs @@ -0,0 +1,59 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Models +{ + /// + /// This method returns a variety of quantity structure information of the webserver. + /// + public class ApiQuantityStructure + { + /// + /// The size of the HTTP request body of a JSON-RPC request in bytes. + /// + public long Webapi_Max_Http_Request_Body_Size { get; set; } + /// + /// The number of parallel requests to the JSON-RPC endpoint. + /// + public int Webapi_Max_Parallel_Requests { get; set; } + /// + /// The number of parallel user sessions using the JSON-RPC endpoint. + /// + public int Webapi_Max_Parallel_User_Sessions { get; set; } + + /// + /// Check whether properties match + /// + /// Object to check + /// Returns true if the ApiQuantityStructures are the same + public override bool Equals(object obj) + { + var structure = obj as ApiQuantityStructure; + return structure != null && + structure.Webapi_Max_Parallel_User_Sessions == this.Webapi_Max_Parallel_User_Sessions && + structure.Webapi_Max_Parallel_Requests == this.Webapi_Max_Parallel_Requests && + structure.Webapi_Max_Http_Request_Body_Size == this.Webapi_Max_Http_Request_Body_Size; + } + + /// + /// GetHashCode for SequenceEqual etc. + /// + /// hashcode for the ApiQuantityStructures + public override int GetHashCode() + { + return (Webapi_Max_Http_Request_Body_Size, Webapi_Max_Parallel_Requests, Webapi_Max_Parallel_User_Sessions).GetHashCode(); + } + + /// + /// ToString for ApiQuantityStructures + /// + /// Formatted string + public override string ToString() + { + return $"{nameof(Webapi_Max_Http_Request_Body_Size)}: {Webapi_Max_Http_Request_Body_Size} | " + + $"{nameof(Webapi_Max_Parallel_Requests)}: {Webapi_Max_Parallel_Requests} | " + + $"{nameof(Webapi_Max_Parallel_User_Sessions)}: {Webapi_Max_Parallel_User_Sessions}"; + } + } +} diff --git a/src/Webserver.API/Models/ApiSyslog/ApiPlcSyslog.cs b/src/Webserver.API/Models/ApiSyslog/ApiPlcSyslog.cs new file mode 100644 index 0000000..26f46d0 --- /dev/null +++ b/src/Webserver.API/Models/ApiSyslog/ApiPlcSyslog.cs @@ -0,0 +1,82 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using System.Collections.Generic; +using System.Linq; + +namespace Siemens.Simatic.S7.Webserver.API.Models.ApiSyslog +{ + /// + /// Content of the PLC-internal syslog ring buffer + /// + public class ApiPlcSyslog + { + /// + /// Holds an array of objects where each object represents a single syslog message of the PLC-internal syslog ring buffer. + /// + public List Entries { get; set; } + /// + /// This attribute contains the total number of insertions into the syslog buffer since PLC booted up. + /// + public uint Count_Total { get; set; } + /// + /// This attribute contains the number of insertions into the syslog buffer that were lost,
+ /// meaning the number of the entries which were overwritten by new entries, and which were not saved to a syslog server. + ///
+ public uint Count_Lost { get; set; } + + /// + /// Check whether properties match + /// + /// + /// Returns true if the ApiSyslogs are the same + public override bool Equals(object obj) + { + return obj is ApiPlcSyslog syslog && + Entries.SequenceEqual(syslog.Entries) && + Count_Total == syslog.Count_Total && + Count_Lost == syslog.Count_Lost; + } + + /// + /// GetHashCode for ApiSyslog + /// + /// The hash code of the apiSyslog + public override int GetHashCode() + { + int EntriesHashCode = 0; + if (Entries != null) + { + foreach (var entry in Entries) + { + EntriesHashCode ^= entry.GetHashCode(); + } + } + return (EntriesHashCode, Count_Total, Count_Lost).GetHashCode(); + } + + /// + /// ToString for ApiPlcSyslog + /// + /// ApiPlcSyslog as a multiline string + public override string ToString() + { + return ToString(NullValueHandling.Ignore); + } + /// + /// ToString for ApiPlcSyslog + /// + /// Defines if null values should be ignored + /// ApiPlcSyslog as a multiline string + public string ToString(NullValueHandling nullValueHandling) + { + JsonSerializerSettings options = new JsonSerializerSettings() + { + NullValueHandling = nullValueHandling, + }; + string result = JsonConvert.SerializeObject(this, Formatting.Indented, options); + return result; + } + } +} diff --git a/src/Webserver.API/Models/ApiSyslog/ApiPlcSyslog_Entry.cs b/src/Webserver.API/Models/ApiSyslog/ApiPlcSyslog_Entry.cs new file mode 100644 index 0000000..29a5895 --- /dev/null +++ b/src/Webserver.API/Models/ApiSyslog/ApiPlcSyslog_Entry.cs @@ -0,0 +1,49 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Models.ApiSyslog +{ + /// + /// A single syslog message of the PLC-internal syslog ring buffer + /// + public class ApiPlcSyslog_Entry + { + /// + /// A raw syslog entry as defined in the RFC. + /// + public string Raw { get; set; } + /// + /// Check whether properties match + /// + /// + /// Returns true if the ApiSyslog_Entries are the same + public override bool Equals(object obj) + { + var structure = obj as ApiPlcSyslog_Entry; + if (structure is null) + { + return false; + } + return structure.Raw == this.Raw; + } + + /// + /// GetHashCode for ApiSyslog_Entry + /// + /// The hash code of the ApiSyslog_Entry + public override int GetHashCode() + { + return Raw.GetHashCode(); + } + + /// + /// ToString for ApiSyslog_Entry + /// + /// Raw + public override string ToString() + { + return Raw; + } + } +} diff --git a/src/Webserver.API/Models/ApiTicket.cs b/src/Webserver.API/Models/ApiTicket.cs index efb7b31..06a1915 100644 --- a/src/Webserver.API/Models/ApiTicket.cs +++ b/src/Webserver.API/Models/ApiTicket.cs @@ -1,15 +1,11 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Enums; +using Siemens.Simatic.S7.Webserver.API.Exceptions; using System; using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Xml; -using Siemens.Simatic.S7.Webserver.API.Enums; -using Siemens.Simatic.S7.Webserver.API.Exceptions; namespace Siemens.Simatic.S7.Webserver.API.Models { @@ -24,27 +20,32 @@ public class ApiTicket /// /// 28 byte string! /// - public string Id { get { return id; } - set { + public string Id + { + get { return id; } + set + { if (value.Length != 28) throw new ApiInvalidTicketIdValueException($"- given string:{value}"); else id = value; - } } + } + } private ApiTicketState state; /// /// ApiTicketState - None is not a valid State! there are no Stateless Tickets (so far) /// - public ApiTicketState State { + public ApiTicketState State + { get { return state; } set { - if(value == ApiTicketState.None) + if (value == ApiTicketState.None) { throw new Exception($"{value.ToString()} is not an expected value for ApiTicketState!"); } @@ -70,7 +71,7 @@ public ApiTicketProvider Provider } set { - if(value == ApiTicketProvider.None) + if (value == ApiTicketProvider.None) { //throw new ApiException(new Responses.ApiErrorModel() { Error = new ApiError() { } }) throw new Exception($"{value.ToString()} is not an expected value for ApiTicketProvider!"); diff --git a/src/Webserver.API/Models/ApiWebAppData.cs b/src/Webserver.API/Models/ApiWebAppData.cs index d102a54..0d943a1 100644 --- a/src/Webserver.API/Models/ApiWebAppData.cs +++ b/src/Webserver.API/Models/ApiWebAppData.cs @@ -4,11 +4,7 @@ using Newtonsoft.Json; using Siemens.Simatic.S7.Webserver.API.Enums; using Siemens.Simatic.S7.Webserver.API.Exceptions; -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models { @@ -41,13 +37,15 @@ public ApiWebAppData ShallowCopy() /// /// State of ApiWebApp => Enabled/Disabled, None is not valid! /// - public ApiWebAppState State { get + public ApiWebAppState State + { + get { return state; } set { - if(value == ApiWebAppState.None) + if (value == ApiWebAppState.None) { throw new ApiInvalidResponseException($"Returned from api was:{value.ToString()} - which is not valid! contact Siemens"); } diff --git a/src/Webserver.API/Models/ApiWebAppDataSaveSetting.cs b/src/Webserver.API/Models/ApiWebAppDataSaveSetting.cs index ddc55d6..bf726af 100644 --- a/src/Webserver.API/Models/ApiWebAppDataSaveSetting.cs +++ b/src/Webserver.API/Models/ApiWebAppDataSaveSetting.cs @@ -3,11 +3,6 @@ // SPDX-License-Identifier: MIT using Newtonsoft.Json; using Newtonsoft.Json.Serialization; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models { @@ -69,7 +64,7 @@ public ApiWebAppDataSaveSetting() /// will be used to determine wether a directory will be created /// for saving in case it does not yet exist and is provided via DirectoryPath /// Setting for the Serialization - public ApiWebAppDataSaveSetting(string directoryPath, string configurationName, + public ApiWebAppDataSaveSetting(string directoryPath, string configurationName, bool checkConsistency, bool createDirectoryIfNotExists, JsonSerializerSettings jsonSerializerSetting) { DirectoryPath = directoryPath; diff --git a/src/Webserver.API/Models/ApiWebAppResource.cs b/src/Webserver.API/Models/ApiWebAppResource.cs index 2b0025d..b597147 100644 --- a/src/Webserver.API/Models/ApiWebAppResource.cs +++ b/src/Webserver.API/Models/ApiWebAppResource.cs @@ -4,10 +4,6 @@ using Siemens.Simatic.S7.Webserver.API.Enums; using Siemens.Simatic.S7.Webserver.API.Exceptions; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models { @@ -46,7 +42,8 @@ public ApiWebAppResource ShallowCopy() /// /// Resource Visibility - (plc uses to) determine wether a user is allowed to access the Resource (has cookie with according rights) /// - public ApiWebAppResourceVisibility Visibility { + public ApiWebAppResourceVisibility Visibility + { get { return visibility; @@ -100,9 +97,9 @@ public bool Equals(ApiWebAppResource other) string lastModified = this.Last_modified.ToString(); string otherLastModified = other.Last_modified.ToString(); - if(IgnoreBOMDifference.HasValue && IgnoreBOMDifference == true) + if (IgnoreBOMDifference.HasValue && IgnoreBOMDifference == true) { - bool toReturn = (this.Name == other.Name && ((this.Size == (other.Size - 3)) || (this.Size == other.Size) || (this.Size == (other.Size +3))) && this.Media_type == other.Media_type + bool toReturn = (this.Name == other.Name && ((this.Size == (other.Size - 3)) || (this.Size == other.Size) || (this.Size == (other.Size + 3))) && this.Media_type == other.Media_type && this.Visibility == other.Visibility && (lastModified == otherLastModified) && this.Etag == other.Etag); return toReturn; } @@ -111,7 +108,7 @@ public bool Equals(ApiWebAppResource other) return this.Name == other.Name && (this.Size == other.Size) && this.Media_type == other.Media_type && this.Visibility == other.Visibility && (lastModified == otherLastModified) && this.Etag == other.Etag; } - + } /// diff --git a/src/Webserver.API/Models/FailsafeParameters/FailsafeHardware.cs b/src/Webserver.API/Models/FailsafeParameters/FailsafeHardware.cs new file mode 100644 index 0000000..1bc6ebe --- /dev/null +++ b/src/Webserver.API/Models/FailsafeParameters/FailsafeHardware.cs @@ -0,0 +1,108 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Siemens.Simatic.S7.Webserver.API.Services.Converters.JsonConverters; +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Models.FailsafeParameters +{ + /// + /// Base class for Failsafe Hardware Types + /// + [JsonConverter(typeof(FailsafeHardwareConverter))] + public class FailsafeHardware + { + } + + /// + /// Failsafe CPU + /// + public class FailsafeCPU : FailsafeHardware + { + /// + /// The timestamp of the last failsafe program modification. + /// + public DateTime Last_f_program_modification { get; set; } + /// + /// The collective signature encoded as string containing a hexadecimal representation of the 32-bit signature. + /// + public string Collective_signature { get; set; } + + /// + /// The remaining was introduced with Safety system version V2.4. Older versions do not support the remaining time. + /// The version can be configured in the TIA Portal Safety Administration. + /// + [JsonConverter(typeof(TimeSpanISO8601Converter))] + public TimeSpan? Remaining_time { get; set; } + + /// + /// Checks if the incoming object is the same as this + /// + /// Object to check + /// True if they are the same object + public override bool Equals(object obj) + { + return obj is FailsafeCPU cpu && + Last_f_program_modification == cpu.Last_f_program_modification && + Remaining_time == cpu.Remaining_time && + Collective_signature == cpu.Collective_signature; + } + + /// + /// Hash code + /// + /// (LastFProgramModification, CollectiveSignature).GetHashCode() + public override int GetHashCode() + { + return (Last_f_program_modification, Collective_signature, Remaining_time).GetHashCode(); + } + } + + /// + /// Failsafe Module + /// + public class FailsafeModule : FailsafeHardware + { + /// + /// F-monitoring time. + /// + [JsonConverter(typeof(TimeSpanISO8601Converter))] + public TimeSpan F_monitoring_time { get; set; } + /// + /// Contains the F-source address. + /// + public int F_source_address { get; set; } + /// + /// Contains the F-destination address + /// + public int F_destination_address { get; set; } + /// + /// The F-Par CRC encoded as string containing a hexadecimal representation of the 32-bit signature. + /// + public string F_par_crc { get; set; } + + /// + /// Checks if the incoming object is the same as this + /// + /// Object to check + /// True if they are the same object + public override bool Equals(object obj) + { + return obj is FailsafeModule module && + F_monitoring_time.Equals(module.F_monitoring_time) && + F_source_address == module.F_source_address && + F_destination_address == module.F_destination_address && + F_par_crc == module.F_par_crc; + } + + /// + /// Hash code + /// + /// (FMonitoringTime, FParCrc, FDestinationAddress, FSourceAddress).GetHashCode() + public override int GetHashCode() + { + return (F_monitoring_time, F_par_crc, F_destination_address, F_source_address).GetHashCode(); + } + } +} diff --git a/src/Webserver.API/Models/HttpClientAndWebAppCookie.cs b/src/Webserver.API/Models/HttpClientAndWebAppCookie.cs index ffc3403..fe7bf9e 100644 --- a/src/Webserver.API/Models/HttpClientAndWebAppCookie.cs +++ b/src/Webserver.API/Models/HttpClientAndWebAppCookie.cs @@ -1,12 +1,8 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; using System.Collections.Generic; -using System.Linq; using System.Net.Http; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models { diff --git a/src/Webserver.API/Models/HttpClientConnectionConfiguration.cs b/src/Webserver.API/Models/HttpClientConnectionConfiguration.cs index a0ca0e7..acafe6a 100644 --- a/src/Webserver.API/Models/HttpClientConnectionConfiguration.cs +++ b/src/Webserver.API/Models/HttpClientConnectionConfiguration.cs @@ -1,15 +1,8 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using Siemens.Simatic.S7.Webserver.API.Models.Requests; -using Siemens.Simatic.S7.Webserver.API.Services.IdGenerator; -using Siemens.Simatic.S7.Webserver.API.Services.RequestHandling; using System; using System.Collections.Generic; -using System.Linq; -using System.Net.Http.Headers; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models { @@ -78,7 +71,7 @@ public HttpClientConnectionConfiguration ShallowCopy() /// Defaults to false /// Defaults to false /// Defaults to true - public HttpClientConnectionConfiguration(string baseAddress, string username, string password, + public HttpClientConnectionConfiguration(string baseAddress, string username, string password, TimeSpan timeOut, bool connectionClose, bool allowAutoRedirect, bool discardPasswordAfterConnect) { this.BaseAddress = baseAddress; diff --git a/src/Webserver.API/Models/IApiWebAppData.cs b/src/Webserver.API/Models/IApiWebAppData.cs index 591ad5b..09e87ae 100644 --- a/src/Webserver.API/Models/IApiWebAppData.cs +++ b/src/Webserver.API/Models/IApiWebAppData.cs @@ -1,8 +1,8 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System.Collections.Generic; using Siemens.Simatic.S7.Webserver.API.Enums; +using System.Collections.Generic; namespace Siemens.Simatic.S7.Webserver.API.Models { diff --git a/src/Webserver.API/Models/Requests/ApiRequest.cs b/src/Webserver.API/Models/Requests/ApiRequest.cs index 8560868..e317950 100644 --- a/src/Webserver.API/Models/Requests/ApiRequest.cs +++ b/src/Webserver.API/Models/Requests/ApiRequest.cs @@ -2,12 +2,8 @@ // // SPDX-License-Identifier: MIT using Newtonsoft.Json; -using Siemens.Simatic.S7.Webserver.API.Models; using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Requests { @@ -23,7 +19,7 @@ public class ApiRequest : ApiBaseRequest, IApiRequest, IApiBaseRequestThe required JsonRpc /// The required ID /// Optional parameters for those Api Request where it is possible (e.g. Files.Rename) - public ApiRequest(string method, string jsonRpc, string id, Dictionary requestParams = null) + public ApiRequest(string method, string jsonRpc, string id, Dictionary requestParams = null) : base(method, jsonRpc, id, requestParams) { } @@ -42,7 +38,7 @@ public class ApiRequestIntId : ApiBaseRequest, IApiRequestIntId, IApiBaseRe /// The required JsonRpc /// The required ID as an Integer /// Optional parameters for those Api Request where it is possible (e.g. Files.Rename) - public ApiRequestIntId(string method, string jsonRpc, int id, Dictionary requestParams = null) + public ApiRequestIntId(string method, string jsonRpc, int id, Dictionary requestParams = null) : base(method, jsonRpc, id, requestParams) { } diff --git a/src/Webserver.API/Models/Requests/IApiRequest.cs b/src/Webserver.API/Models/Requests/IApiRequest.cs index 693f1df..c61b391 100644 --- a/src/Webserver.API/Models/Requests/IApiRequest.cs +++ b/src/Webserver.API/Models/Requests/IApiRequest.cs @@ -1,12 +1,7 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using Siemens.Simatic.S7.Webserver.API.Models; -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Requests { diff --git a/src/Webserver.API/Models/Responses/ApiAlarmsBrowseResponse.cs b/src/Webserver.API/Models/Responses/ApiAlarmsBrowseResponse.cs new file mode 100644 index 0000000..b327177 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiAlarmsBrowseResponse.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Models.AlarmsBrowse; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// Response to an ApiAlarms.Browse request + /// + public class ApiAlarmsBrowseResponse : ApiResultResponse + { + } +} diff --git a/src/Webserver.API/Models/Responses/ApiArrayOfApiClassResponse.cs b/src/Webserver.API/Models/Responses/ApiArrayOfApiClassResponse.cs index fd26f82..8502848 100644 --- a/src/Webserver.API/Models/Responses/ApiArrayOfApiClassResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiArrayOfApiClassResponse.cs @@ -1,19 +1,14 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using Siemens.Simatic.S7.Webserver.API.Models; -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { /// /// ApiResponse (Jsonrpc,id) with a List of ApiClasses /// - public class ApiArrayOfApiClassResponse : ApiResultResponse > + public class ApiArrayOfApiClassResponse : ApiResultResponse> { } } diff --git a/src/Webserver.API/Models/Responses/ApiBrowseFilesResponse.cs b/src/Webserver.API/Models/Responses/ApiBrowseFilesResponse.cs index ad14c50..fb971fc 100644 --- a/src/Webserver.API/Models/Responses/ApiBrowseFilesResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiBrowseFilesResponse.cs @@ -2,9 +2,6 @@ // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; -using System; -using System.Collections.Generic; -using System.Text; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { diff --git a/src/Webserver.API/Models/Responses/ApiBrowseTicketsResponse.cs b/src/Webserver.API/Models/Responses/ApiBrowseTicketsResponse.cs index 7397ae7..f630e2e 100644 --- a/src/Webserver.API/Models/Responses/ApiBrowseTicketsResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiBrowseTicketsResponse.cs @@ -1,13 +1,7 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using Siemens.Simatic.S7.Webserver.API.Models; using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { diff --git a/src/Webserver.API/Models/Responses/ApiBulkResponse.cs b/src/Webserver.API/Models/Responses/ApiBulkResponse.cs index 28c436e..d85fbdf 100644 --- a/src/Webserver.API/Models/Responses/ApiBulkResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiBulkResponse.cs @@ -1,11 +1,8 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { diff --git a/src/Webserver.API/Models/Responses/ApiDiagnosticBufferBrowseResponse.cs b/src/Webserver.API/Models/Responses/ApiDiagnosticBufferBrowseResponse.cs new file mode 100644 index 0000000..aca3a3b --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiDiagnosticBufferBrowseResponse.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// Response to an ApiDiagnosticBuffer.Browse request + /// + public class ApiDiagnosticBufferBrowseResponse : ApiResultResponse + { + } +} diff --git a/src/Webserver.API/Models/Responses/ApiDoubleResponse.cs b/src/Webserver.API/Models/Responses/ApiDoubleResponse.cs index 16464a7..a4eaac9 100644 --- a/src/Webserver.API/Models/Responses/ApiDoubleResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiDoubleResponse.cs @@ -1,11 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { diff --git a/src/Webserver.API/Models/Responses/ApiErrorModel.cs b/src/Webserver.API/Models/Responses/ApiErrorModel.cs index 97b2a10..9d0f9aa 100644 --- a/src/Webserver.API/Models/Responses/ApiErrorModel.cs +++ b/src/Webserver.API/Models/Responses/ApiErrorModel.cs @@ -1,9 +1,9 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; using Siemens.Simatic.S7.Webserver.API.Enums; using Siemens.Simatic.S7.Webserver.API.Exceptions; +using System; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { @@ -90,12 +90,38 @@ public void ThrowAccordingException(string apiRequestString, string responseStri throw new ApiInvalidETagException(new ApiException(this, apiRequestString)); case ApiErrorCode.ResourceContentHasBeenCorrupted: throw new ApiResourceContentHasBeenCorruptedException(new ApiException(this, apiRequestString)); + case ApiErrorCode.InvalidAlarmId: + throw new ApiInvalidAlarmIdException(new ApiException(this, apiRequestString)); + case ApiErrorCode.InvalidAlarmsBrowseParameters: + throw new ApiInvalidAlarmsBrowseParametersException(new ApiException(this, apiRequestString)); case ApiErrorCode.PLCNotInStop: throw new ApiPLCNotInStopException(new ApiException(this, apiRequestString)); case ApiErrorCode.MethodNotFound: throw new ApiMethodNotFoundException(new ApiException(this, apiRequestString)); case ApiErrorCode.InvalidParams: throw new ApiInvalidParametersException(new ApiException(this, apiRequestString)); + case ApiErrorCode.PasswordExpired: + throw new ApiPasswordExpiredException(new ApiException(this, apiRequestString)); + case ApiErrorCode.PasswordChangeNotAccepted: + throw new ApiPasswordChangeNotAcceptedException(new ApiException(this, apiRequestString)); + case ApiErrorCode.NewPasswordDoesNotFollowPolicy: + throw new ApiNewPasswordDoesNotFollowPolicyException(new ApiException(this, apiRequestString)); + case ApiErrorCode.NewPasswordMatchesOldPassword: + throw new ApiNewPasswordMatchesOldPasswordException(new ApiException(this, apiRequestString)); + case ApiErrorCode.PartnerNotAccessible: + throw new ApiPartnerNotAccessibleException(new ApiException(this, apiRequestString)); + case ApiErrorCode.NoServiceDataResources: + throw new ApiNoServiceDataResourcesException(new ApiException(this, apiRequestString)); + case ApiErrorCode.InvalidHwId: + throw new ApiInvalidHwIdException(new ApiException(this, apiRequestString)); + case ApiErrorCode.InvalidTimestamp: + throw new ApiInvalidTimestampException(new ApiException(this, apiRequestString)); + case ApiErrorCode.TimestampOutOfRange: + throw new ApiTimestampOutOfRangeException(new ApiException(this, apiRequestString)); + case ApiErrorCode.InvalidTimeRule: + throw new ApiInvalidTimeRuleException(new ApiException(this, apiRequestString)); + case ApiErrorCode.InvalidUTCOffset: + throw new ApiInvalidUTCOffsetException(new ApiException(this, apiRequestString)); default: throw new ApiException(this, apiRequestString); diff --git a/src/Webserver.API/Models/Responses/ApiFailsafeReadParametersResponse.cs b/src/Webserver.API/Models/Responses/ApiFailsafeReadParametersResponse.cs new file mode 100644 index 0000000..4dae3bf --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiFailsafeReadParametersResponse.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// Response containing Failsafe ReadParameters result + /// + public class ApiFailsafeReadParametersResponse : ApiResultResponse + { + } +} diff --git a/src/Webserver.API/Models/Responses/ApiFailsafeReadRuntimeGroupsResponse.cs b/src/Webserver.API/Models/Responses/ApiFailsafeReadRuntimeGroupsResponse.cs new file mode 100644 index 0000000..21844cd --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiFailsafeReadRuntimeGroupsResponse.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// Response containing Failsafe.ReadRuntimeGroups result + /// + public class ApiFailsafeReadRuntimeGroupsResponse : ApiResultResponse + { + } +} diff --git a/src/Webserver.API/Models/Responses/ApiGetAuthenticationModeResponse.cs b/src/Webserver.API/Models/Responses/ApiGetAuthenticationModeResponse.cs new file mode 100644 index 0000000..64a6f5d --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiGetAuthenticationModeResponse.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// Response of Api.GetAuthenticationMode + /// + public class ApiGetAuthenticationModeResponse : ApiResultResponse + { + } +} diff --git a/src/Webserver.API/Models/Responses/ApiGetPasswordPolicyResponse.cs b/src/Webserver.API/Models/Responses/ApiGetPasswordPolicyResponse.cs new file mode 100644 index 0000000..7e42b42 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiGetPasswordPolicyResponse.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// Response of Api.GetPasswordPolicy + /// + public class ApiGetPasswordPolicyResponse : ApiResultResponse + { + } +} diff --git a/src/Webserver.API/Models/Responses/ApiGetQuantityStructuresResponse.cs b/src/Webserver.API/Models/Responses/ApiGetQuantityStructuresResponse.cs new file mode 100644 index 0000000..738bc1e --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiGetQuantityStructuresResponse.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// ApiResponse (Jsonrpc,id) with an Api Quantity Structure object + /// + public class ApiGetQuantityStructuresResponse : ApiResultResponse + { + + } +} diff --git a/src/Webserver.API/Models/Responses/ApiLoginResponse.cs b/src/Webserver.API/Models/Responses/ApiLoginResponse.cs index 5af39e2..1716de8 100644 --- a/src/Webserver.API/Models/Responses/ApiLoginResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiLoginResponse.cs @@ -2,11 +2,6 @@ // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { @@ -15,6 +10,6 @@ namespace Siemens.Simatic.S7.Webserver.API.Models.Responses /// public class ApiLoginResponse : ApiResultResponse { - + } } diff --git a/src/Webserver.API/Models/Responses/ApiPlcProgramBrowseCodeBlocksResponse.cs b/src/Webserver.API/Models/Responses/ApiPlcProgramBrowseCodeBlocksResponse.cs new file mode 100644 index 0000000..da58dbf --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiPlcProgramBrowseCodeBlocksResponse.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System.Collections.Generic; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// ApiPlcProgramBrowseCodeBlocksResponse (Jsonrpc,id) with a List of ApiPlcProgramBrowseCodeBlocksData + /// + public class ApiPlcProgramBrowseCodeBlocksResponse : ApiResultResponse> + { + } +} diff --git a/src/Webserver.API/Models/Responses/ApiPlcProgramBrowseResponse.cs b/src/Webserver.API/Models/Responses/ApiPlcProgramBrowseResponse.cs index 87f5486..e95f304 100644 --- a/src/Webserver.API/Models/Responses/ApiPlcProgramBrowseResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiPlcProgramBrowseResponse.cs @@ -1,12 +1,7 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using Siemens.Simatic.S7.Webserver.API.Models; -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { diff --git a/src/Webserver.API/Models/Responses/ApiPlcReadModeSelectorStateResponse.cs b/src/Webserver.API/Models/Responses/ApiPlcReadModeSelectorStateResponse.cs new file mode 100644 index 0000000..2ef0fbf --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiPlcReadModeSelectorStateResponse.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// ApiResponse (Jsonrpc,id) with Mode Selector State + /// + public class ApiPlcReadModeSelectorStateResponse : ApiResultResponse + { + + } +} diff --git a/src/Webserver.API/Models/Responses/ApiPlcReadSystemTimeResult.cs b/src/Webserver.API/Models/Responses/ApiPlcReadSystemTimeResult.cs index c99b9f2..56d8e14 100644 --- a/src/Webserver.API/Models/Responses/ApiPlcReadSystemTimeResult.cs +++ b/src/Webserver.API/Models/Responses/ApiPlcReadSystemTimeResult.cs @@ -2,9 +2,6 @@ // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; -using System; -using System.Collections.Generic; -using System.Text; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { diff --git a/src/Webserver.API/Models/Responses/ApiPlcReadTimeSettingsResponse.cs b/src/Webserver.API/Models/Responses/ApiPlcReadTimeSettingsResponse.cs index 5f72f4c..f5fc4c4 100644 --- a/src/Webserver.API/Models/Responses/ApiPlcReadTimeSettingsResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiPlcReadTimeSettingsResponse.cs @@ -2,9 +2,6 @@ // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; -using System; -using System.Collections.Generic; -using System.Text; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { diff --git a/src/Webserver.API/Models/Responses/ApiReadLanguagesResponse.cs b/src/Webserver.API/Models/Responses/ApiReadLanguagesResponse.cs new file mode 100644 index 0000000..94d92da --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiReadLanguagesResponse.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// Response of Project.ReadLanguages + /// + public class ApiReadLanguagesResponse : ApiResultResponse + { + + } +} diff --git a/src/Webserver.API/Models/Responses/ApiReadOperatingModeResponse.cs b/src/Webserver.API/Models/Responses/ApiReadOperatingModeResponse.cs index b051aa0..78b3ed9 100644 --- a/src/Webserver.API/Models/Responses/ApiReadOperatingModeResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiReadOperatingModeResponse.cs @@ -3,11 +3,6 @@ // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; using Siemens.Simatic.S7.Webserver.API.Exceptions; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { @@ -19,9 +14,10 @@ public class ApiReadOperatingModeResponse : ApiResultResponse /// ApiPlcOperatingMode Result => Only accept valid Plc Operating Modes! ///
- public override ApiPlcOperatingMode Result { + public override ApiPlcOperatingMode Result + { get => base.Result; - set + set { if (value == ApiPlcOperatingMode.None || value == ApiPlcOperatingMode.Unknown) throw new ApiInvalidResponseException($"ApiPlcOperatingmode returned from api was:{value.ToString()} - which is not valid! contact Siemens"); diff --git a/src/Webserver.API/Models/Responses/ApiResultResponse.cs b/src/Webserver.API/Models/Responses/ApiResultResponse.cs index 98d1247..f710e02 100644 --- a/src/Webserver.API/Models/Responses/ApiResultResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiResultResponse.cs @@ -1,18 +1,13 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { /// /// Generally an ApiResponse contains "Id" and "JsonRpc" /// - public class ApiResultResponse : BaseApiResponse //BaseResultObject => dann wären Properties von BaseResultObject verfügbar + public class ApiResultResponse : BaseApiResponse { /// /// The (requested) Result the Api has responded with diff --git a/src/Webserver.API/Models/Responses/ApiSingleStringResponse.cs b/src/Webserver.API/Models/Responses/ApiSingleStringResponse.cs index 64c292d..18b097c 100644 --- a/src/Webserver.API/Models/Responses/ApiSingleStringResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiSingleStringResponse.cs @@ -1,12 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using Siemens.Simatic.S7.Webserver.API.Exceptions; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { diff --git a/src/Webserver.API/Models/Responses/ApiSyslogBrowseResponse.cs b/src/Webserver.API/Models/Responses/ApiSyslogBrowseResponse.cs new file mode 100644 index 0000000..cad83d7 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiSyslogBrowseResponse.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// Response to ApiSyslogBrowse request + /// + public class ApiSyslogBrowseResponse : ApiResultResponse + { + } +} diff --git a/src/Webserver.API/Models/Responses/ApiTicketIdResponse.cs b/src/Webserver.API/Models/Responses/ApiTicketIdResponse.cs index 0e5a32b..8cab8d3 100644 --- a/src/Webserver.API/Models/Responses/ApiTicketIdResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiTicketIdResponse.cs @@ -1,14 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using Siemens.Simatic.S7.Webserver.API.Models.Requests; -using Siemens.Simatic.S7.Webserver.API.Services.RequestHandling; -using Siemens.Simatic.S7.Webserver.API.StaticHelpers; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { @@ -31,9 +23,9 @@ public ApiTicketIdResponse() : base() /// public ApiTicketIdResponse(ApiSingleStringResponse singleStringResponse) : base() { - this.Id = string.Copy(singleStringResponse.Id); - this.JsonRpc = string.Copy(singleStringResponse.JsonRpc); - this.Result = string.Copy(singleStringResponse.Result); + this.Id = singleStringResponse.Id; + this.JsonRpc = singleStringResponse.JsonRpc; + this.Result = singleStringResponse.Result; } } } diff --git a/src/Webserver.API/Models/Responses/ApiTrueOnSuccessResponse.cs b/src/Webserver.API/Models/Responses/ApiTrueOnSuccessResponse.cs index 673e3d2..919cd4f 100644 --- a/src/Webserver.API/Models/Responses/ApiTrueOnSuccessResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiTrueOnSuccessResponse.cs @@ -2,11 +2,6 @@ // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Exceptions; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { @@ -18,7 +13,8 @@ public class ApiTrueOnSuccessResponse : ApiResultResponse /// /// True on SuccessResponse: Only Accept "true" /// - public override bool Result { + public override bool Result + { get => base.Result; set { if (value) @@ -29,7 +25,7 @@ public override bool Result { { throw new ApiInvalidResponseException($"Server responded with \"{value}\" for a true on success response!?"); } - + } } } diff --git a/src/Webserver.API/Models/Responses/ApiTrueWithResourceResponse.cs b/src/Webserver.API/Models/Responses/ApiTrueWithResourceResponse.cs index 660fcdd..13c34a1 100644 --- a/src/Webserver.API/Models/Responses/ApiTrueWithResourceResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiTrueWithResourceResponse.cs @@ -1,12 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Siemens.Simatic.S7.Webserver.API.Models; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { diff --git a/src/Webserver.API/Models/Responses/ApiTrueWithWebAppResponse.cs b/src/Webserver.API/Models/Responses/ApiTrueWithWebAppResponse.cs index 25be999..53bb8a7 100644 --- a/src/Webserver.API/Models/Responses/ApiTrueWithWebAppResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiTrueWithWebAppResponse.cs @@ -1,12 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using Siemens.Simatic.S7.Webserver.API.Models; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { diff --git a/src/Webserver.API/Models/Responses/ApiWebAppBrowseResourcesResponse.cs b/src/Webserver.API/Models/Responses/ApiWebAppBrowseResourcesResponse.cs index fccaa3e..f96759e 100644 --- a/src/Webserver.API/Models/Responses/ApiWebAppBrowseResourcesResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiWebAppBrowseResourcesResponse.cs @@ -2,11 +2,6 @@ // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { diff --git a/src/Webserver.API/Models/Responses/ApiWebAppBrowseResponse.cs b/src/Webserver.API/Models/Responses/ApiWebAppBrowseResponse.cs index 0ac6ed7..97ef3b9 100644 --- a/src/Webserver.API/Models/Responses/ApiWebAppBrowseResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiWebAppBrowseResponse.cs @@ -2,11 +2,6 @@ // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { diff --git a/src/Webserver.API/Models/Responses/ApiWebServerGetReadDefaultPageResponse.cs b/src/Webserver.API/Models/Responses/ApiWebServerGetReadDefaultPageResponse.cs new file mode 100644 index 0000000..84c30c8 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiWebServerGetReadDefaultPageResponse.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// ApiWebServerGetReadDefaultPageResponse: containing the default page result + /// + public class ApiWebServerGetReadDefaultPageResponse : ApiResultResponse + { + } +} diff --git a/src/Webserver.API/Models/Responses/BaseApiResponse.cs b/src/Webserver.API/Models/Responses/BaseApiResponse.cs index 44e9adf..d208de0 100644 --- a/src/Webserver.API/Models/Responses/BaseApiResponse.cs +++ b/src/Webserver.API/Models/Responses/BaseApiResponse.cs @@ -1,11 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses { diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiFailsafeReadParametersResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiFailsafeReadParametersResult.cs new file mode 100644 index 0000000..c765e4e --- /dev/null +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiFailsafeReadParametersResult.cs @@ -0,0 +1,31 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Siemens.Simatic.S7.Webserver.API.Enums; +using Siemens.Simatic.S7.Webserver.API.Models.FailsafeParameters; +using Siemens.Simatic.S7.Webserver.API.Services.Converters.JsonConverters; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults +{ + /// + /// Result containing Failsafe.ReadParameters objects + /// + public class ApiFailsafeReadParametersResult + { + /// + /// The status if the safety mode is enabled or not. + /// + [JsonConverter(typeof(EnabledDisabledConverter))] + public bool Safety_mode { get; set; } + /// + /// The type defines if the requested hardware identifier represents either the safety PLC itself or another failsafe module. + /// + public ApiFailsafeHardwareType Type { get; set; } + /// + /// If the requested hardware identifier represents the safety PLC itself and the PLC has a safety program,this object must be present using data structure 'FailsafeCPU'
+ /// If the requested hardware identifier represents any other safety module than the Safety PLC itself, this object must be present using data structure 'FailsafeModule' + ///
+ public FailsafeHardware Parameters { get; set; } + } +} diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiFailsafeReadRuntimeGroupsResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiFailsafeReadRuntimeGroupsResult.cs new file mode 100644 index 0000000..d6e89bd --- /dev/null +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiFailsafeReadRuntimeGroupsResult.cs @@ -0,0 +1,18 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System.Collections.Generic; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults +{ + /// + /// Result containing runtime groups + /// + public class ApiFailsafeReadRuntimeGroupsResult + { + /// + /// List of runtime groups. The list may be empty if no runtime groups exist. + /// + public List Groups { get; set; } + } +} diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiGetAuthenticationModeResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiGetAuthenticationModeResult.cs new file mode 100644 index 0000000..b5f0683 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiGetAuthenticationModeResult.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Enums; +using System.Collections.Generic; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults +{ + /// + /// A class containing a list of authentication modes + /// + public class ApiGetAuthenticationModeResult + { + /// + /// A list of authentication modes + /// + public List Authentication_modes { get; set; } + } +} diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiGetPasswordPolicyResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiGetPasswordPolicyResult.cs new file mode 100644 index 0000000..f531c32 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiGetPasswordPolicyResult.cs @@ -0,0 +1,17 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults +{ + /// + /// Result of Api.GetPasswordPolicy + /// + public class ApiGetPasswordPolicyResult + { + /// + /// Currently configured password policy + /// + public ApiPasswordPolicy Password_policy { get; set; } + } +} diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadModeSelectorStateResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadModeSelectorStateResult.cs new file mode 100644 index 0000000..dfe1b02 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadModeSelectorStateResult.cs @@ -0,0 +1,18 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Enums; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults +{ + /// + /// Plc.ReadModeSelectorState result containing the mode selector enum + /// + public class ApiPlcReadModeSelectorStateResult + { + /// + /// The state of the mode selector switch of the PLC + /// + public ApiPlcModeSelectorState Mode_Selector { get; set; } + } +} diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadSystemTimeResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadSystemTimeResult.cs index 0a15cec..844a47d 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadSystemTimeResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadSystemTimeResult.cs @@ -2,8 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Text; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults { diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadTimeSettingsResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadTimeSettingsResult.cs index c743d7b..ec6d3f7 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadTimeSettingsResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadTimeSettingsResult.cs @@ -1,224 +1,53 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Siemens.Simatic.S7.Webserver.API.Models.TimeSettings; +using Siemens.Simatic.S7.Webserver.API.Services.Converters.JsonConverters; using System; -using System.Collections.Generic; -using System.Text; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults { /// - /// Plc.ApiPlcReadTimeSettingsResult result + /// Result of Plc.ReadTimeSettings /// public class ApiPlcReadTimeSettingsResult { /// /// Offset to the current time => Utc_offset + daylight savings time offset if currently applied /// - public int Current_offset { get; set; } - - - /// - /// ISO formatted Offset to the current time => Utc_offset + daylight savings time offset if currently applied - /// - public string ISO_Current_offset - { - get - { - return IsoFormatter.SetISOFormat(Current_offset); - } - } + [JsonConverter(typeof(TimeSpanISO8601Converter))] + public TimeSpan Current_offset { get; set; } /// /// fixed offset to utc /// - public int Utc_offset { get; set; } - - - /// - /// ISO formatted offset to utc - /// - public string ISO_Utc_offset - { - get - { - return IsoFormatter.SetISOFormat(Utc_offset); - } - } + [JsonConverter(typeof(TimeSpanISO8601Converter))] + public TimeSpan Utc_offset { get; set; } /// - /// Current Daylight savings rule + /// (Optional) Current Daylight savings rule /// - public DaylightSavingsRule Rule { get; set; } //optional + public DaylightSavingsRule Rule { get; set; } /// - /// Can be used to comfortly get the current time for a given timestampf of a Plc.ReadSystemTime result + /// Can be used to comfortly get the current time for a given timestamp of a Plc.ReadSystemTime result /// /// Timestamp of result of Plc.ReadSystemTime (UTC) - /// + /// Return current time based on an input plc time, plus the current offset from this time setting. public DateTime GetCurrentTime(DateTime plcReadSystemTimeResult) { - return (plcReadSystemTimeResult + TimeSpan.FromMinutes(Current_offset)); + return (plcReadSystemTimeResult + Current_offset); } /// /// Can be used to comfortly get the current time for a given Plc.ReadSystemTime result /// /// Result of Plc.ReadSystemTime (UTC) - /// + /// Return current time based on a read system time result, plus the current offset from this time setting. public DateTime GetCurrentTime(ApiPlcReadSystemTimeResult plcReadSystemTimeResult) { - return (plcReadSystemTimeResult.Timestamp + TimeSpan.FromMinutes(Current_offset)); - } - } - - /// - /// Daylight savings rule - /// - public class DaylightSavingsRule - { - /// - /// Start of Standard time - /// - public StandardTimeConfiguration Std { get; set; } - - /// - /// Start of Daylight saving time - /// - public DaylightSavingsTimeConfiguration Dst { get; set; } - - /// - /// (Name, Has_children, Db_number, Datatype, Array_dimensions, Max_length, Address, Area, Read_only) Equal!; - /// - /// - /// - public override bool Equals(object obj) => Equals(obj as DaylightSavingsRule); - - /// - /// Equals => (Name,Has_children,Db_number, Datatype, Array_dimensions, Max_length, Address, Area, Read_only, Value, Children) - /// - /// - /// - public bool Equals(DaylightSavingsRule obj) - { - if (obj is null) - return false; - var toReturn = this.Std.Equals(obj.Std); - toReturn &= this.Dst.Equals(obj.Dst); - return toReturn; - } - - /// - /// (Name, Has_children, Db_number, Datatype, Array_dimensions, Max_length, Address, Area, Read_only).GetHashCode(); - /// - /// - public override int GetHashCode() - { - return (Std, Dst).GetHashCode(); - } - } - - /// - /// Standard time configuration containing the start date of the standard time - /// - public class StandardTimeConfiguration - { - /// - /// PlcDate of the StartTime of the standard time or daylight savings time - /// - public PlcDate Start { get; set; } - - /// - /// PlcDate to determine the start of the standard or daylight savings time configuration - /// - public class PlcDate - { - /// - /// Minute - /// - public int Minute { get; set; } - /// - /// Hour - /// - public int Hour { get; set; } - /// - /// Week in month; - /// Speciality: Week 5 always stands for the last Week in the according month. - /// - public int Week { get; set; } - /// - /// Month - /// - public int Month { get; set; } - /// - /// first three letters of the according day of week (lowercase) - /// - public string Day_of_week { get; set; } - } - } - - /// - /// Daylight savings time configuration containing the start date of the daylight savings time and the offset during the daylight savings time - /// - public class DaylightSavingsTimeConfiguration : StandardTimeConfiguration - { - /// - /// Offset during the daylight savings time - /// - public int Offset { get; set; } - - /// - /// ISO formatted Offset during the daylight savings time - /// - public string ISO_Offset - { - get - { - return IsoFormatter.SetISOFormat(Offset); - } - } - } - - /// - /// Helper class for get the ISO formatted offsets. - /// - public static class IsoFormatter - { - /// - /// Get the ISO formatted offset - /// - /// - /// - /// ISO formatted offset if minutes and/or hours bigger than 0 - otherwise "" - public static string SetISOFormat(int minute = 0, int hour = 0) - { - string iso = ""; - if (hour > 0 || minute > 0) - { - iso = "PT"; - if (minute >= 60) - { - hour += (minute / 60); - if (minute % 60 == 0) - { - minute = 0; - } - else - { - minute = (minute % 60); - } - } - if (hour > 0) - { - iso += hour + "H"; - } - - if (minute > 0) - { - iso += minute + "M"; - } - } - return iso; + return (plcReadSystemTimeResult.Timestamp + Current_offset); } } } \ No newline at end of file diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiReadLanguagesResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiReadLanguagesResult.cs new file mode 100644 index 0000000..9de4053 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiReadLanguagesResult.cs @@ -0,0 +1,18 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using System.Collections.Generic; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults +{ + /// + /// Read Langzages result containing a List of ApiLanguageResults + /// + public class ApiReadLanguagesResult + { + /// + /// List containing languages (CultureInfo) wrapped in an ApiLanguageResult + /// + public List Languages { get; set; } + } +} diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiTokenResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiTokenResult.cs index bacc157..0b867df 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/ApiTokenResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiTokenResult.cs @@ -1,27 +1,38 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Siemens.Simatic.S7.Webserver.API.Services.Converters.JsonConverters; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults { /// - /// ApiTokenResult: Containing a Token and optional a Web_application_cookie. + /// ApiTokenResult: Containing a Token and an optional Web_application_cookie. + /// May also contain password_expiration information if the authentication mode is "local" and is enabled on the PLC. /// public class ApiTokenResult { /// /// Token given from the Api (used to authenticate in headers as "X-Auth-Token" /// - public string Token; + public string Token { get; set; } /// /// Not c# conform wording to match Api Response behaviour /// - public string Web_application_cookie; + public string Web_application_cookie { get; set; } + + /// + /// Holds password expiration information if local authentication mode is used, + /// and password expiration is enabled on the PLC. + /// + public ApiPasswordExpiration Password_expiration { get; set; } + + /// + /// The inactivity duration after which a log out (using the API method Api.Logout) will be automatically performed. + /// + [JsonConverter(typeof(TimeSpanISO8601Converter))] + public TimeSpan Runtime_timeout { get; set; } } } diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiWebAppBrowseResourcesResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiWebAppBrowseResourcesResult.cs index 967dc24..b4f6e3c 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/ApiWebAppBrowseResourcesResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiWebAppBrowseResourcesResult.cs @@ -1,13 +1,7 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using Siemens.Simatic.S7.Webserver.API.Models; -using Siemens.Simatic.S7.Webserver.API.Models.Responses; -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults { diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiWebAppBrowseResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiWebAppBrowseResult.cs index 51e938b..e5bc505 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/ApiWebAppBrowseResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiWebAppBrowseResult.cs @@ -1,12 +1,7 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using Siemens.Simatic.S7.Webserver.API.Models; -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults { diff --git a/src/Webserver.API/Models/Responses/ResponseResults/WebServerDefaultPageResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/WebServerDefaultPageResult.cs new file mode 100644 index 0000000..d936446 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ResponseResults/WebServerDefaultPageResult.cs @@ -0,0 +1,17 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults +{ + /// + /// Result of a WebServer.ReadDefaultPage request + /// + public class WebServerDefaultPageResult + { + /// + /// Default page's name given from the Api + /// + public string Default_page; + } +} diff --git a/src/Webserver.API/Models/TimeSettings/DaylightSavingsRule.cs b/src/Webserver.API/Models/TimeSettings/DaylightSavingsRule.cs new file mode 100644 index 0000000..4c94026 --- /dev/null +++ b/src/Webserver.API/Models/TimeSettings/DaylightSavingsRule.cs @@ -0,0 +1,91 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Models.TimeSettings +{ + /// + /// Daylight savings rule + /// + public class DaylightSavingsRule + { + /// + /// Start of Standard time + /// + public StandardTimeConfiguration Std { get; set; } + /// + /// Start of Daylight saving time + /// + public DaylightSavingsTimeConfiguration Dst { get; set; } + + /// + /// Constructor to create a daylight-savings rule using STD and DST objects + /// + /// Represents the standard time configuration + /// Represents the daylight-savings time configuration + [JsonConstructor] + public DaylightSavingsRule(StandardTimeConfiguration std, DaylightSavingsTimeConfiguration dst) + { + this.Std = std; + this.Dst = dst; + } + + /// + /// Constructor to create a daylight-savings rule -- this will also create the STD and DST objects + /// + /// The starting time of the standard time + /// The starting time of the daylight-savings time + /// The offset of daylight savings time from the standard time + public DaylightSavingsRule(PlcDate stdStart, PlcDate dstStart, TimeSpan dstTimeOffset) + { + this.Std = new StandardTimeConfiguration(stdStart); + this.Dst = new DaylightSavingsTimeConfiguration(dstStart, dstTimeOffset); + } + + /// + /// Mixed constructor to create a daylight-savings rule: needs an STD object, but creates the DST object on it's own. + /// + /// The standard time configuration + /// The starting time of the daylight-savings time + /// The offset of daylight savings time from the standard time + public DaylightSavingsRule(StandardTimeConfiguration std, PlcDate dstStart, TimeSpan dstTimeOffset) + { + this.Std = std; + this.Dst = new DaylightSavingsTimeConfiguration(dstStart, dstTimeOffset); + } + + /// + /// Mixed constructor to create a daylight-savings rule: creates the STD object on it's own, but expects a DST object. + /// + /// The starting time of the standard time + /// The daylight-savings time configuration + public DaylightSavingsRule(PlcDate stdStart, DaylightSavingsTimeConfiguration dst) + { + this.Std = new StandardTimeConfiguration(stdStart); + this.Dst = dst; + } + + /// + /// Get HashCode of DaylightSavingsRule + /// + /// Hashcode + public override int GetHashCode() + { + return (Std, Dst).GetHashCode(); + } + + /// + /// Checks if the input object is the same as this DaylightSavingsRule + /// + /// Object to check + /// True if this and obj is the same + public override bool Equals(object obj) + { + return obj is DaylightSavingsRule rule && + Std.Equals(rule.Std) && + Dst.Equals(rule.Dst); + } + } +} diff --git a/src/Webserver.API/Models/TimeSettings/DaylightSavingsTimeConfiguration.cs b/src/Webserver.API/Models/TimeSettings/DaylightSavingsTimeConfiguration.cs new file mode 100644 index 0000000..cba4a25 --- /dev/null +++ b/src/Webserver.API/Models/TimeSettings/DaylightSavingsTimeConfiguration.cs @@ -0,0 +1,71 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Siemens.Simatic.S7.Webserver.API.Services.Converters.JsonConverters; +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Models.TimeSettings +{ + /// + /// Daylight savings time configuration containing the start date of the daylight savings time and the offset during the daylight savings time + /// + public class DaylightSavingsTimeConfiguration : StandardTimeConfiguration + { + private TimeSpan _offset; + /// + /// Offset during the daylight savings time + /// + [JsonConverter(typeof(TimeSpanISO8601Converter))] + public TimeSpan Offset + { + get + { + return _offset; + } + set + { + if (value.TotalMinutes >= -180 && value.TotalMinutes <= 180) + { + _offset = value; + } + else + { + throw new ArgumentOutOfRangeException($"Valid values of {nameof(Offset)} are between -180 and 180 minutes. Input value was {value}"); + } + } + } + + /// + /// Constructor to create a DST object + /// + /// The starting time of the daylight-savings time + /// The offset of daylight savings time from the standard time + public DaylightSavingsTimeConfiguration(PlcDate start, TimeSpan timeOffset) : base(start) + { + this.Offset = timeOffset; + } + + /// + /// Checks whether incoming object is same as this DST + /// + /// Object to check + /// True if they're the same + public override bool Equals(object obj) + { + return obj is DaylightSavingsTimeConfiguration configuration && + base.Equals(obj) && + Start.Equals(configuration.Start) && + Offset.Equals(configuration.Offset); + } + + /// + /// (Offset, Start).GetHashCode() + /// + /// Hashcode + public override int GetHashCode() + { + return (Offset, Start).GetHashCode(); + } + } +} diff --git a/src/Webserver.API/Models/TimeSettings/PlcDate.cs b/src/Webserver.API/Models/TimeSettings/PlcDate.cs new file mode 100644 index 0000000..bb10a2c --- /dev/null +++ b/src/Webserver.API/Models/TimeSettings/PlcDate.cs @@ -0,0 +1,146 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Enums; +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Models.TimeSettings +{ + /// + /// PlcDate to determine the start of the standard or daylight savings time configuration + /// + public class PlcDate + { + private int _minute; + /// + /// Minute + /// + public int Minute + { + get + { + return _minute; + } + set + { + if (value >= 0 && value <= 59) + { + _minute = value; + } + else + { + throw new ArgumentOutOfRangeException($"Valid values of {nameof(Minute)} are 0 through 59. Input value was {value}"); + } + } + } + private int _hour; + /// + /// Hour + /// + public int Hour + { + get + { + return _hour; + } + set + { + if (value >= 0 && value <= 23) + { + _hour = value; + } + else + { + throw new ArgumentOutOfRangeException($"Valid values of {nameof(Hour)} are 0 through 23. Input value was {value}"); + } + } + } + private int _week; + /// + /// Week in month; + /// Speciality: Week 5 always stands for the last Week in the according month. + /// + public int Week + { + get + { + return _week; + } + set + { + if (value >= 1 && value <= 5) + { + _week = value; + } + else + { + throw new ArgumentOutOfRangeException($"Valid values of {nameof(Week)} are 1 through 5. Input value was {value}"); + } + } + } + private int _month; + /// + /// Month + /// + public int Month + { + get + { + return _month; + } + set + { + if (value >= 1 && value <= 12) + { + _month = value; + } + else + { + throw new ArgumentOutOfRangeException($"Valid values of {nameof(Month)} are 1 through 12. Input value was {value}"); + } + } + } + /// + /// First three letters of the according day of week + /// + public ApiDayOfWeek Day_of_week { get; set; } + /// + /// Constructor to create PlcDate object + /// + /// Month, from 1 to 12 + /// Week, from 1 to 5 + /// Weekday, 1 to 7 + /// Hour, 0 to 24 + /// Minute, 0 to 60 + public PlcDate(int month, int week, ApiDayOfWeek day_of_week, int hour, int minute) + { + Minute = minute; + Hour = hour; + Week = week; + Month = month; + Day_of_week = day_of_week; + } + /// + /// Checks whether incoming object is same as this PlcDate + /// + /// Object to check + /// True if they're the same + public override bool Equals(object obj) + { + return obj is PlcDate date && + Minute == date.Minute && + Hour == date.Hour && + Week == date.Week && + Month == date.Month && + Day_of_week == date.Day_of_week; + } + /// + /// Get HashCode of PlcDate + /// + /// Hashcode + public override int GetHashCode() + { + return (Minute, Hour, Week, Month, Day_of_week).GetHashCode(); + } + } +} diff --git a/src/Webserver.API/Models/TimeSettings/StandardTimeConfiguration.cs b/src/Webserver.API/Models/TimeSettings/StandardTimeConfiguration.cs new file mode 100644 index 0000000..e85d3bf --- /dev/null +++ b/src/Webserver.API/Models/TimeSettings/StandardTimeConfiguration.cs @@ -0,0 +1,45 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Models.TimeSettings +{ + /// + /// Standard time configuration containing the start date of the standard time + /// + public class StandardTimeConfiguration + { + /// + /// PlcDate of the StartTime of the standard time or daylight savings time + /// + public PlcDate Start { get; set; } + /// + /// Constructor to create an STD object + /// + /// The starting time of the standard time + public StandardTimeConfiguration(PlcDate start) + { + Start = start; + } + + /// + /// Checks whether incoming object is same as this STD + /// + /// Object to check + /// True if they're the same + public override bool Equals(object obj) + { + return obj is StandardTimeConfiguration configuration && + Start.Equals(configuration.Start); + } + + /// + /// Get HashCode of StandardTime + /// + /// Hashcode + public override int GetHashCode() + { + return Start.GetHashCode(); + } + } +} diff --git a/src/Webserver.API/Services/ApiStandardServiceFactory.cs b/src/Webserver.API/Services/ApiStandardServiceFactory.cs index 34302a3..3cdc444 100644 --- a/src/Webserver.API/Services/ApiStandardServiceFactory.cs +++ b/src/Webserver.API/Services/ApiStandardServiceFactory.cs @@ -13,10 +13,10 @@ using Siemens.Simatic.S7.Webserver.API.Services.Ticketing; using Siemens.Simatic.S7.Webserver.API.Services.WebApp; using System; -using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Services @@ -63,18 +63,17 @@ public ApiStandardServiceFactory(IIdGenerator idGenerator, IApiRequestParameterC _apiWebAppResourceBuilder = apiWebAppResourceBuilder ?? throw new ArgumentNullException(nameof(apiWebAppResourceBuilder)); } - - /// /// Get an httpclient using standard values for /// /// ip address or dns name of your plc /// username to login with /// password to login with + /// Cancellation token to cancel pending requests. /// an authorized httpclient (client with header value x-auth-token set) - public async Task GetHttpClientAsync(string baseAddress, string username, string password) + public async Task GetHttpClientAsync(string baseAddress, string username, string password, CancellationToken cancellationToken = default(CancellationToken)) { - return await GetHttpClientAsync(GetConnectionConfiguration(baseAddress, username, password)); + return await GetHttpClientAsync(GetConnectionConfiguration(baseAddress, username, password), cancellationToken); } /// @@ -108,10 +107,11 @@ public HttpClientConnectionConfiguration GetConnectionConfiguration(string baseA /// username to login with /// password to login with /// bool used to determine if the response should include a valid application cookie value for protected pages access + /// Cancellation token to cancel pending requests. /// an authorized httpclient (client with header value x-auth-token set) and the according webappcookie - public async Task GetHttpClientAsync(string baseAddress, string username, string password, bool include_web_application_cookie) + public async Task GetHttpClientAsync(string baseAddress, string username, string password, bool include_web_application_cookie, CancellationToken cancellationToken = default(CancellationToken)) { - return await GetHttpClientAsync(GetConnectionConfiguration(baseAddress, username, password), include_web_application_cookie); + return await GetHttpClientAsync(GetConnectionConfiguration(baseAddress, username, password), include_web_application_cookie, cancellationToken); } /// @@ -130,8 +130,9 @@ public HttpClientAndWebAppCookie GetHttpClient(string baseAddress, string userna /// /// Connection Configuration which should contains the base address, username, passwort etc. /// bool used to determine if the response should include a valid application cookie value for protected pages access + /// Cancellation token to cancel pending requests. /// an authorized httpclient (client with header value x-auth-token set) and the according webappcookie - public async Task GetHttpClientAsync(HttpClientConnectionConfiguration connectionConfiguration, bool include_web_application_cookie) + public async Task GetHttpClientAsync(HttpClientConnectionConfiguration connectionConfiguration, bool include_web_application_cookie, CancellationToken cancellationToken = default(CancellationToken)) { HttpClientHandler httpClientHandler = new HttpClientHandler() { @@ -166,7 +167,7 @@ public async Task GetHttpClientAsync(HttpClientConnec request_body.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); // send the request and check for errors - var response = await httpClient.PostAsync("api/jsonrpc", request_body); + var response = await httpClient.PostAsync("api/jsonrpc", request_body, cancellationToken); _apiResponseChecker.CheckHttpResponseForErrors(response, apiLoginRequestString); var respString = await response.Content.ReadAsStringAsync(); _apiResponseChecker.CheckResponseStringForErros(respString, apiLoginRequestString); @@ -204,9 +205,10 @@ public HttpClientAndWebAppCookie GetHttpClient(HttpClientConnectionConfiguration /// Get an httpclient using the given /// /// Connection Configuration which should contains the base address, username, passwort etc. + /// Token used to cancel requests without waiting for the response /// an authorized httpclient (client with header value x-auth-token set) /// - public async Task GetHttpClientAsync(HttpClientConnectionConfiguration connectionConfiguration) + public async Task GetHttpClientAsync(HttpClientConnectionConfiguration connectionConfiguration, CancellationToken cancellationToken = default(CancellationToken)) { HttpClientHandler httpClientHandler = new HttpClientHandler() { @@ -240,7 +242,7 @@ public async Task GetHttpClientAsync(HttpClientConnectionConfigurati ByteArrayContent request_body = new ByteArrayContent(byteArr); request_body.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); // send the request - var response = await httpClient.PostAsync("api/jsonrpc", request_body); + var response = await httpClient.PostAsync("api/jsonrpc", request_body, cancellationToken); _apiResponseChecker.CheckHttpResponseForErrors(response, apiLoginRequestString); var respString = await response.Content.ReadAsStringAsync(); _apiResponseChecker.CheckResponseStringForErros(respString, apiLoginRequestString); @@ -278,9 +280,9 @@ public HttpClient GetHttpClient(HttpClientConnectionConfiguration connectionConf /// username to login with /// password to login with /// A usable and authenticated - public async Task GetApiHttpClientRequestHandlerAsync(string baseAddress, string username, string password) + public async Task GetApiHttpClientRequestHandlerAsync(string baseAddress, string username, string password, CancellationToken cancellationToken = default(CancellationToken)) { - var httpClient = await GetHttpClientAsync(baseAddress, username, password); + var httpClient = await GetHttpClientAsync(baseAddress, username, password, cancellationToken); return new ApiHttpClientRequestHandler(httpClient, _apiRequestFactory, _apiResponseChecker); } @@ -305,6 +307,18 @@ public async Task GetApiHttpClientRequestHandlerAsync(HttpCl return new ApiHttpClientRequestHandler(httpClient, _apiRequestFactory, _apiResponseChecker); } + /// + /// Get an using the given + /// + /// Connection configuration to use + /// Cancellation token to cancel pending requests. + /// A usable and authenticated + public async Task GetApiHttpClientRequestHandlerAsync(HttpClientConnectionConfiguration connectionConfiguration, CancellationToken cancellationToken = default(CancellationToken)) + { + var httpClient = await GetHttpClientAsync(connectionConfiguration, cancellationToken); + return new ApiHttpClientRequestHandler(httpClient, _apiRequestFactory, _apiResponseChecker); + } + /// /// Get an using the given /// diff --git a/src/Webserver.API/Services/Backup/ApiBackupHandler.cs b/src/Webserver.API/Services/Backup/ApiBackupHandler.cs index a044150..ebbcd55 100644 --- a/src/Webserver.API/Services/Backup/ApiBackupHandler.cs +++ b/src/Webserver.API/Services/Backup/ApiBackupHandler.cs @@ -2,14 +2,14 @@ // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Exceptions; -using Siemens.Simatic.S7.Webserver.API.Services.RequestHandling; using Siemens.Simatic.S7.Webserver.API.Services.HelperHandlers; +using Siemens.Simatic.S7.Webserver.API.Services.RequestHandling; +using Siemens.Simatic.S7.Webserver.API.Services.Ticketing; using System; using System.IO; -using System.Linq; using System.Net.Http; +using System.Threading; using System.Threading.Tasks; -using Siemens.Simatic.S7.Webserver.API.Services.Ticketing; namespace Siemens.Simatic.S7.Webserver.API.Services.Backup { @@ -40,14 +40,14 @@ public ApiBackupHandler(IApiRequestHandler apiRequestHandler, IApiTicketHandler /// choose wether you want to replace an existing file or add another file with that name to you download directory in case one already exists /// FileInfo /// - public async Task DownloadBackupAsync(string pathToDownloadDirectory = null, string backupName = null, bool overwriteExistingFile = false) + public async Task DownloadBackupAsync(string pathToDownloadDirectory = null, string backupName = null, bool overwriteExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)) { if (pathToDownloadDirectory != null && !Directory.Exists(pathToDownloadDirectory)) { throw new DirectoryNotFoundException($"the given directory at {Environment.NewLine}{pathToDownloadDirectory}{Environment.NewLine} has not been found!"); } - var ticket = (await ApiRequestHandler.PlcCreateBackupAsync()).Result; - return (await ApiTicketHandler.HandleDownloadAsync(ticket, pathToDownloadDirectory, backupName, null, overwriteExistingFile)).File_Downloaded; + var ticket = (await ApiRequestHandler.PlcCreateBackupAsync(cancellationToken)).Result; + return (await ApiTicketHandler.HandleDownloadAsync(ticket, pathToDownloadDirectory, backupName, null, overwriteExistingFile, cancellationToken)).File_Downloaded; } /// @@ -70,21 +70,21 @@ public FileInfo DownloadBackup(string pathToDownloadDirectory = null, string bac /// timeout for the waithandler => plc to be up again after reboot, etc. - defaults to 3 minutes /// Task /// File at restorefilepath has not been found - public async Task RestoreBackupAsync(string restoreFilePath, string userName, string password, TimeSpan? timeOut = null) + public async Task RestoreBackupAsync(string restoreFilePath, string userName, string password, TimeSpan? timeOut = null, CancellationToken cancellationToken = default(CancellationToken)) { var timeToWait = timeOut ?? TimeSpan.FromMinutes(3); - if(restoreFilePath == null) + if (restoreFilePath == null) { throw new ArgumentNullException(nameof(restoreFilePath)); } - if(!File.Exists(restoreFilePath)) + if (!File.Exists(restoreFilePath)) { throw new FileNotFoundException($"the given file at {Environment.NewLine}{restoreFilePath}{Environment.NewLine} has not been found!"); } - string ticketResponse = (await ApiRequestHandler.PlcRestoreBackupAsync(password)).Result; + string ticketResponse = (await ApiRequestHandler.PlcRestoreBackupAsync(password, cancellationToken)).Result; try { - await ApiTicketHandler.HandleUploadAsync(ticketResponse, restoreFilePath); + await ApiTicketHandler.HandleUploadAsync(ticketResponse, restoreFilePath, cancellationToken); } // HttpRequestException is okay since during the upload the plc will power cycle and not "successfully answer" the request catch (ApiTicketingEndpointUploadException e) @@ -92,15 +92,13 @@ public async Task RestoreBackupAsync(string restoreFilePath, string userName, st if (e.InnerException != null || !(e.InnerException is HttpRequestException)) throw; } - //var ticket = await ApiRequestHandler.ApiBrowseTicketsAsync(); - var waitHandler = new WaitHandler(timeToWait); WaitForPlcReboot(waitHandler); - await ApiRequestHandler.ReLoginAsync(userName, password); - ticketResponse = (await ApiRequestHandler.PlcRestoreBackupAsync(password)).Result; - await ApiTicketHandler.HandleUploadAsync(ticketResponse, restoreFilePath); + await ApiRequestHandler.ReLoginAsync(userName, password, cancellationToken: cancellationToken); + ticketResponse = (await ApiRequestHandler.PlcRestoreBackupAsync(password, cancellationToken)).Result; + await ApiTicketHandler.HandleUploadAsync(ticketResponse, restoreFilePath, cancellationToken); WaitForPlcReboot(waitHandler); - await ApiRequestHandler.ReLoginAsync(userName, password); + await ApiRequestHandler.ReLoginAsync(userName, password, cancellationToken: cancellationToken); } /// diff --git a/src/Webserver.API/Services/Backup/IApiBackupHandler.cs b/src/Webserver.API/Services/Backup/IApiBackupHandler.cs index a11e851..5354109 100644 --- a/src/Webserver.API/Services/Backup/IApiBackupHandler.cs +++ b/src/Webserver.API/Services/Backup/IApiBackupHandler.cs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: MIT using System; using System.IO; +using System.Threading; using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Services.Backup @@ -27,7 +28,7 @@ public interface IApiBackupHandler /// will default to the backup name suggested by the plc /// choose wether you want to replace an existing file or add another file with that name to you download directory in case one already exists /// FileInfo - Task DownloadBackupAsync(string pathToDownloadDirectory = null, string backupName = null, bool overwriteExistingFile = false); + Task DownloadBackupAsync(string pathToDownloadDirectory = null, string backupName = null, bool overwriteExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)); /// /// Will send a Downloadresource, Downloadticket and Closeticket request to the API /// @@ -45,6 +46,6 @@ public interface IApiBackupHandler /// path to the file to be restored /// timeout for the waithandler => plc to be up again after reboot, etc. /// Task/void - Task RestoreBackupAsync(string restoreFilePath, string userName, string password, TimeSpan? timeOut = null); + Task RestoreBackupAsync(string restoreFilePath, string userName, string password, TimeSpan? timeOut = null, CancellationToken cancellationToken = default(CancellationToken)); } } \ No newline at end of file diff --git a/src/Webserver.API/Services/Converters/JsonConverters/EnabledDisabledConverter.cs b/src/Webserver.API/Services/Converters/JsonConverters/EnabledDisabledConverter.cs new file mode 100644 index 0000000..0e6d106 --- /dev/null +++ b/src/Webserver.API/Services/Converters/JsonConverters/EnabledDisabledConverter.cs @@ -0,0 +1,48 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Services.Converters.JsonConverters +{ + /// + /// Converts string "enabled" (true) or "disabled" (false) into a bool, or vice versa + /// + public class EnabledDisabledConverter : JsonConverter + { + /// + /// Deserializes string "enabled" (true) or "disabled" (false) into a bool + /// + /// Deserialized bool value + public override bool? ReadJson(JsonReader reader, Type objectType, bool? existingValue, bool hasExistingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.String) + { + string value = reader.Value.ToString().ToLower(); + if (value == "enabled") + { + return true; + } + else if (value == "disabled") + { + return false; + } + } + return null; + } + + /// + /// Serializes bool into "enabled" (true) or "disabled" (false) + /// + public override void WriteJson(JsonWriter writer, bool? value, JsonSerializer serializer) + { + if (value.HasValue) + { + string boolAsString = value.Value ? "enabled" : "disabled"; + writer.WriteValue(boolAsString); + } + else writer.WriteNull(); + } + } +} diff --git a/src/Webserver.API/Services/Converters/JsonConverters/FailsafeHardwareConverter.cs b/src/Webserver.API/Services/Converters/JsonConverters/FailsafeHardwareConverter.cs new file mode 100644 index 0000000..311439e --- /dev/null +++ b/src/Webserver.API/Services/Converters/JsonConverters/FailsafeHardwareConverter.cs @@ -0,0 +1,57 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Siemens.Simatic.S7.Webserver.API.Models.FailsafeParameters; +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Services.Converters.JsonConverters +{ + /// + /// Decides which derived class to use when deserializing/serializing parameters of Failsafe.ReadParameters + /// + public class FailsafeHardwareConverter : JsonConverter + { + /// + /// Read FailsafeHardware from json + /// + /// A FailsafeHardware object: either a CPU or a Module if the parameters are correct + public override FailsafeHardware ReadJson(JsonReader reader, Type objectType, FailsafeHardware existingValue, bool hasExistingValue, JsonSerializer serializer) + { + var jObject = JObject.Load(reader); + if (jObject["collective_signature"] != null) + { + var fCPU = new FailsafeCPU(); + serializer.Populate(jObject.CreateReader(), fCPU); + return fCPU; + } + else if (jObject["f_par_crc"] != null) + { + var fModule = new FailsafeModule(); + serializer.Populate(jObject.CreateReader(), fModule); + return fModule; + } + + var baseHW = new FailsafeHardware(); + serializer.Populate(jObject.CreateReader(), baseHW); + return baseHW; + } + /// + /// Writes to json + /// + public override void WriteJson(JsonWriter writer, FailsafeHardware value, JsonSerializer serializer) + { + JObject jObject = JObject.FromObject(value); + if (value is FailsafeCPU CPU) + { + jObject = JObject.FromObject(CPU); + } + else if (value is FailsafeModule module) + { + jObject = JObject.FromObject(module); + } + jObject.WriteTo(writer); + } + } +} diff --git a/src/Webserver.API/Services/Converters/JsonConverters/TimeSpanISO8601Converter.cs b/src/Webserver.API/Services/Converters/JsonConverters/TimeSpanISO8601Converter.cs new file mode 100644 index 0000000..dbcca76 --- /dev/null +++ b/src/Webserver.API/Services/Converters/JsonConverters/TimeSpanISO8601Converter.cs @@ -0,0 +1,68 @@ +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using System; +using System.Xml; + +namespace Siemens.Simatic.S7.Webserver.API.Services.Converters.JsonConverters +{ + /// + /// A JsonConverter that converts a TimeSpan into an ISO8601 duration + /// + public class TimeSpanISO8601Converter : JsonConverter + { + /// + /// Writes to Json + /// + public override void WriteJson(JsonWriter writer, TimeSpan value, JsonSerializer serializer) + { + writer.WriteValue(value.ToISO8601Duration()); + } + /// + /// Reads from json + /// + public override TimeSpan ReadJson(JsonReader reader, Type objectType, TimeSpan existingValue, bool hasExistingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.String) + { + var durationString = reader.Value.ToString(); + return TimeSpanExtensions.ISO8601DurationToTimeSpan(durationString); + } + + throw new JsonSerializationException("Expected string value for TimeSpan."); + } + /// + /// Can it read from json + /// + public override bool CanRead => true; + /// + /// Can it write to json + /// + public override bool CanWrite => true; + } + /// + /// Extensions for TimeSpan object + /// + public static class TimeSpanExtensions + { + /// + /// Converts TimeSpan into ISO8601 duration string + /// + /// TimeSpan to convert + /// Duration as ISO8601 string + public static string ToISO8601Duration(this TimeSpan ts) + { + return XmlConvert.ToString(ts); + } + /// + /// Converts an ISO8601 duration string into a TimeSpan object + /// + /// A string that is an ISO8601 duration, eg.: PT3H + /// New TimeSpan object with the input duration + public static TimeSpan ISO8601DurationToTimeSpan(string iso8601Duration) + { + return XmlConvert.ToTimeSpan(iso8601Duration); + } + } +} diff --git a/src/Webserver.API/Services/FileHandling/ApiDirectoryBuilder.cs b/src/Webserver.API/Services/FileHandling/ApiDirectoryBuilder.cs index c8a872c..98479e7 100644 --- a/src/Webserver.API/Services/FileHandling/ApiDirectoryBuilder.cs +++ b/src/Webserver.API/Services/FileHandling/ApiDirectoryBuilder.cs @@ -4,12 +4,10 @@ using Newtonsoft.Json; using Siemens.Simatic.S7.Webserver.API.Exceptions; using Siemens.Simatic.S7.Webserver.API.Models; -using Siemens.Simatic.S7.Webserver.API.Services.FileParser; using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; namespace Siemens.Simatic.S7.Webserver.API.Services.FileHandling { @@ -54,7 +52,7 @@ public ApiDirectoryBuilder(string pathToLocalDirectory, IApiFileResourceBuilder /// public ApiFileResource Build(string configFilePath) { - if(!File.Exists(configFilePath)) + if (!File.Exists(configFilePath)) { throw new FileNotFoundException(configFilePath); } @@ -73,7 +71,7 @@ public ApiFileResource Build(string configFilePath) /// public ApiFileResource Build(ApiDirectoryBuilderConfiguration parseConfiguration) { - if(!Directory.Exists(PathToLocalDirectory)) + if (!Directory.Exists(PathToLocalDirectory)) { throw new DirectoryNotFoundException(PathToLocalDirectory); } @@ -97,11 +95,11 @@ public ApiFileResource Build(ApiDirectoryBuilderConfiguration parseConfiguration { PathToLocalDirectory = PathToLocalDirectory, State = Enums.ApiFileResourceState.Active, - Type = Enums.ApiFileResourceType.Dir, + Type = Enums.ApiFileResourceType.Dir, Last_Modified = dirInf.LastWriteTime, Name = dirInf.Name, }; - + resource.Parents = new List(); // get resources in Directory @@ -119,7 +117,7 @@ public ApiFileResource Build(ApiDirectoryBuilderConfiguration parseConfiguration { throw new ApiDirectoryParserException("Missing parameter 'Type' or Type was invalid => 'None' or 0 ", serializationException); } - throw serializationException; + throw; } } diff --git a/src/Webserver.API/Services/FileHandling/ApiDirectoryBuilderConfiguration.cs b/src/Webserver.API/Services/FileHandling/ApiDirectoryBuilderConfiguration.cs index d9eab08..8f501f4 100644 --- a/src/Webserver.API/Services/FileHandling/ApiDirectoryBuilderConfiguration.cs +++ b/src/Webserver.API/Services/FileHandling/ApiDirectoryBuilderConfiguration.cs @@ -1,9 +1,7 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; using System.Collections.Generic; -using System.Text; namespace Siemens.Simatic.S7.Webserver.API.Services.FileHandling { diff --git a/src/Webserver.API/Services/FileHandling/ApiDirectoryHandler.cs b/src/Webserver.API/Services/FileHandling/ApiDirectoryHandler.cs index eb5ff6c..9d68d21 100644 --- a/src/Webserver.API/Services/FileHandling/ApiDirectoryHandler.cs +++ b/src/Webserver.API/Services/FileHandling/ApiDirectoryHandler.cs @@ -1,16 +1,16 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using Newtonsoft.Json.Serialization; using Newtonsoft.Json; +using Siemens.Simatic.S7.Webserver.API.Exceptions; +using Siemens.Simatic.S7.Webserver.API.Models; using Siemens.Simatic.S7.Webserver.API.Services.RequestHandling; using System; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; -using Siemens.Simatic.S7.Webserver.API.Models; -using Siemens.Simatic.S7.Webserver.API.Exceptions; namespace Siemens.Simatic.S7.Webserver.API.Services.FileHandling { @@ -41,16 +41,16 @@ public ApiDirectoryHandler(IApiRequestHandler apiRequestHandler, IApiFileHandler /// the function will only upload the resource and its direct sub-resources /// /// - e.g. from parsed directory - public async Task DeployAsync(ApiFileResource resource) + public async Task DeployAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)) { if (resource.Type == Enums.ApiFileResourceType.File) { - await ApiFileHandler.DeployFileAsync(resource); + await ApiFileHandler.DeployFileAsync(resource, cancellationToken); } else { var dirName = resource.GetVarNameForMethods(); - await ApiRequestHandler.FilesCreateDirectoryAsync(dirName); + await ApiRequestHandler.FilesCreateDirectoryAsync(dirName, cancellationToken); foreach (var subres in resource.Resources) { await DeployAsync(subres); @@ -72,24 +72,24 @@ public async Task DeployAsync(ApiFileResource resource) /// /// the resource to delete /// Task for deletion - public async Task DeleteAsync(ApiFileResource resource) + public async Task DeleteAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)) { if (resource.Type == Enums.ApiFileResourceType.File) { var resName = resource.GetVarNameForMethods(); try { - await ApiRequestHandler.FilesDeleteAsync(resName); + await ApiRequestHandler.FilesDeleteAsync(resName, cancellationToken); } catch (ApiEntityDoesNotExistException) { } } else { - if(resource.Resources != null) + if (resource.Resources != null) { foreach (var file in resource.Resources) { - await DeleteAsync(file); + await DeleteAsync(file, cancellationToken); } } else @@ -99,10 +99,10 @@ public async Task DeleteAsync(ApiFileResource resource) var dirName = resource.GetVarNameForMethods(); try { - await ApiRequestHandler.FilesDeleteDirectoryAsync(dirName); + await ApiRequestHandler.FilesDeleteDirectoryAsync(dirName, cancellationToken); } catch (ApiEntityDoesNotExistException) { } - + } } @@ -118,12 +118,12 @@ public void Delete(ApiFileResource resource) ///
/// resouce to be browsed /// A resource containing everything that is present underneath - public async Task BrowseAndBuildResourceAsync(ApiFileResource resource) + public async Task BrowseAndBuildResourceAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)) { // should we clone here? var res = (ApiFileResource)resource.Clone(); res.Resources = new List(); - var browseResponse = await ApiRequestHandler.FilesBrowseAsync(resource.GetVarNameForMethods()); + var browseResponse = await ApiRequestHandler.FilesBrowseAsync(resource.GetVarNameForMethods(), cancellationToken); if (resource.Type == Enums.ApiFileResourceType.Dir) { res.Resources = browseResponse.Result.Resources; @@ -137,7 +137,7 @@ public async Task BrowseAndBuildResourceAsync(ApiFileResource r foreach (var subRes in res.Resources) { subRes.Parents = parentsForChildren; - var toAdd = await BrowseAndBuildResourceAsync(subRes); + var toAdd = await BrowseAndBuildResourceAsync(subRes, cancellationToken); toAdd.Parents = parentsForChildren; toSet.Add(toAdd); } @@ -161,16 +161,16 @@ public ApiFileResource BrowseAndBuildResource(ApiFileResource resource) /// the resource to be updated /// the resource returned by browsing the plc - make sure the sub-Nodes are present (!) /// Task to update the resource - public async Task UpdateResourceAsync(ApiFileResource resource, ApiFileResource browsedResource) + public async Task UpdateResourceAsync(ApiFileResource resource, ApiFileResource browsedResource, CancellationToken cancellationToken = default(CancellationToken)) { if (browsedResource.Type != resource.Type) { - await DeleteAsync(browsedResource); - await DeployAsync(resource); + await DeleteAsync(browsedResource, cancellationToken); + await DeployAsync(resource, cancellationToken); } if (resource.Type == Enums.ApiFileResourceType.File) { - await UpdateFileResourceAsync(resource, browsedResource); + await UpdateFileResourceAsync(resource, browsedResource, cancellationToken); } else { @@ -183,9 +183,9 @@ public async Task UpdateResourceAsync(ApiFileResource resource, ApiFileResource } else { - var browseResult = await ApiRequestHandler.FilesBrowseAsync(subResource.GetVarNameForMethods()); + var browseResult = await ApiRequestHandler.FilesBrowseAsync(subResource.GetVarNameForMethods(), cancellationToken); match.Resources = browseResult.Result.Resources; - await UpdateResourceAsync(subResource, match); + await UpdateResourceAsync(subResource, match, cancellationToken); } } } @@ -205,7 +205,7 @@ public void UpdateResource(ApiFileResource resource, ApiFileResource browsedReso /// the file to be updated /// the file returned by browsing the plc /// Task to update the File - public async Task UpdateFileResourceAsync(ApiFileResource resource, ApiFileResource browsedResource) + public async Task UpdateFileResourceAsync(ApiFileResource resource, ApiFileResource browsedResource, CancellationToken cancellationToken = default(CancellationToken)) { if (resource.Type != Enums.ApiFileResourceType.File) { @@ -218,8 +218,8 @@ public async Task UpdateFileResourceAsync(ApiFileResource resource, ApiFileResou // compare if an update is necessary if (!resource.Equals(browsedResource)) { - await ApiRequestHandler.FilesDeleteAsync(resource.GetVarNameForMethods()); - await ApiFileHandler.DeployFileAsync(resource); + await ApiRequestHandler.FilesDeleteAsync(resource.GetVarNameForMethods(), cancellationToken); + await ApiFileHandler.DeployFileAsync(resource, cancellationToken); } } @@ -244,7 +244,7 @@ public void UpdateFileResource(ApiFileResource resource, ApiFileResource browsed /// optional parameter: /// used to determine wether the DirectoryHandler should retry a upload and compare of the resources found or give up right away (default) /// - public async Task DeployOrUpdateAsync(ApiFileResource resource, int amountOfTriesForResourceDeployment = 1) + public async Task DeployOrUpdateAsync(ApiFileResource resource, int amountOfTriesForResourceDeployment = 1, CancellationToken cancellationToken = default(CancellationToken)) { if (amountOfTriesForResourceDeployment < 1) { @@ -252,14 +252,14 @@ public async Task DeployOrUpdateAsync(ApiFileResource resource, int amountOfTrie } try { - var browsedResource = await BrowseAndBuildResourceAsync(resource); + var browsedResource = await BrowseAndBuildResourceAsync(resource, cancellationToken); int tries = 0; while (!browsedResource.Equals(resource) && tries < amountOfTriesForResourceDeployment) { - await UpdateResourceAsync(resource, browsedResource); + await UpdateResourceAsync(resource, browsedResource, cancellationToken); tries++; // make sure the browsedResource now is Equal to the one we have - for a directory this means all subNodes are also equal, they are not browsed during the "standard" BRowse - browsedResource = await BrowseAndBuildResourceAsync(resource); + browsedResource = await BrowseAndBuildResourceAsync(resource, cancellationToken); resource.Resources = resource.Resources.OrderBy(el => el.Type).ThenBy(el => el.Size).ToList(); browsedResource.Resources = browsedResource.Resources.OrderBy(el => el.Type).ThenBy(el => el.Size).ToList(); } @@ -285,9 +285,9 @@ public async Task DeployOrUpdateAsync(ApiFileResource resource, int amountOfTrie throw new InvalidOperationException(errorMessage.ToString()); } } - catch(ApiEntityDoesNotExistException) + catch (ApiEntityDoesNotExistException) { - await DeployAsync(resource); + await DeployAsync(resource, cancellationToken); } } /// diff --git a/src/Webserver.API/Services/FileHandling/ApiFileHandler.cs b/src/Webserver.API/Services/FileHandling/ApiFileHandler.cs index a7a06ec..201f24a 100644 --- a/src/Webserver.API/Services/FileHandling/ApiFileHandler.cs +++ b/src/Webserver.API/Services/FileHandling/ApiFileHandler.cs @@ -2,15 +2,11 @@ // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models; -using Siemens.Simatic.S7.Webserver.API.Models.Responses; using Siemens.Simatic.S7.Webserver.API.Services.RequestHandling; using Siemens.Simatic.S7.Webserver.API.Services.Ticketing; using System; using System.IO; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Net.Http.Headers; +using System.Threading; using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Services.FileHandling @@ -50,14 +46,14 @@ public ApiFileHandler(IApiRequestHandler apiRequestHandler, IApiTicketHandler ap /// will default to Downloads but will determine path from -DESKTOP-, replaced "Desktop" by "Downloads" /// choose wether you want to replace an existing file or add another file with that name to you download directory in case one already exists /// FileInfo - public async Task DownloadFileAsync(string resource, string pathToDownloadDirectory = null, bool overwriteExistingFile = false) + public async Task DownloadFileAsync(string resource, string pathToDownloadDirectory = null, bool overwriteExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)) { if (pathToDownloadDirectory != null && !Directory.Exists(pathToDownloadDirectory)) { throw new DirectoryNotFoundException($"the given directory at {Environment.NewLine}{pathToDownloadDirectory}{Environment.NewLine} has not been found!"); } - var ticketId = (await ApiRequestHandler.FilesDownloadAsync(resource)).Result; - return (await ApiTicketHandler.HandleDownloadAsync(ticketId, pathToDownloadDirectory, overwriteExistingFile)).File_Downloaded; + var ticketId = (await ApiRequestHandler.FilesDownloadAsync(resource, cancellationToken)).Result; + return (await ApiTicketHandler.HandleDownloadAsync(ticketId, pathToDownloadDirectory, overwriteExistingFile, cancellationToken)).File_Downloaded; } /// @@ -79,14 +75,14 @@ public FileInfo DownloadFile(string resource, string pathToDownloadDirectory = n /// choose wether you want to replace an existing file or add another file with that name to you download directory in case one already exists /// FileInfo /// - public async Task DataLogs_DownloadAndClearAsync(string resource, string pathToDownloadDirectory = null, bool overwriteExistingFile = false) + public async Task DataLogs_DownloadAndClearAsync(string resource, string pathToDownloadDirectory = null, bool overwriteExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)) { if (pathToDownloadDirectory != null && !Directory.Exists(pathToDownloadDirectory)) { throw new DirectoryNotFoundException($"the given directory at {Environment.NewLine}{pathToDownloadDirectory}{Environment.NewLine} has not been found!"); } - var ticketId = (await ApiRequestHandler.DatalogsDownloadAndClearAsync(resource)).Result; - return (await ApiTicketHandler.HandleDownloadAsync(ticketId, pathToDownloadDirectory, overwriteExistingFile)).File_Downloaded; + var ticketId = (await ApiRequestHandler.DatalogsDownloadAndClearAsync(resource, cancellationToken)).Result; + return (await ApiTicketHandler.HandleDownloadAsync(ticketId, pathToDownloadDirectory, overwriteExistingFile, cancellationToken)).File_Downloaded; } /// @@ -106,10 +102,10 @@ public FileInfo DataLogs_DownloadAndClear(string resource, string pathToDownload /// resource name on the PLC File API endpoint /// path to the local file to upload /// Task to upload the file - public async Task DeployFileAsync(string resource, string filePath) + public async Task DeployFileAsync(string resource, string filePath, CancellationToken cancellationToken = default(CancellationToken)) { - var ticket = await ApiRequestHandler.FilesCreateAsync(resource); - await ApiTicketHandler.HandleUploadAsync(ticket.Result, filePath); + var ticket = await ApiRequestHandler.FilesCreateAsync(resource, cancellationToken); + await ApiTicketHandler.HandleUploadAsync(ticket.Result, filePath, cancellationToken); } /// /// Upload a resource to the File API @@ -123,13 +119,13 @@ public void DeployFile(string resource, string filePath) /// Upload a resource to the File API /// /// resource to upload - filepath built via the ResourcePathResolver, name on PLC File Api built via GetVarNameForMethods() - public async Task DeployFileAsync(ApiFileResource resource) + public async Task DeployFileAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)) { var varNameForMethods = resource.GetVarNameForMethods(); var accordingFile = Path.Combine(resource.PathToLocalDirectory, resource.Name); - await DeployFileAsync(varNameForMethods, accordingFile); + await DeployFileAsync(varNameForMethods, accordingFile, cancellationToken); } - + /// /// Upload a resource to the File API diff --git a/src/Webserver.API/Services/FileHandling/ApiFileResourceBuilder.cs b/src/Webserver.API/Services/FileHandling/ApiFileResourceBuilder.cs index 9d455d6..2f77a62 100644 --- a/src/Webserver.API/Services/FileHandling/ApiFileResourceBuilder.cs +++ b/src/Webserver.API/Services/FileHandling/ApiFileResourceBuilder.cs @@ -3,9 +3,7 @@ // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models; using System; -using System.Collections.Generic; using System.IO; -using System.Text; namespace Siemens.Simatic.S7.Webserver.API.Services.FileHandling { diff --git a/src/Webserver.API/Services/FileHandling/IApiDirectoryHandler.cs b/src/Webserver.API/Services/FileHandling/IApiDirectoryHandler.cs index 242bf83..6eef028 100644 --- a/src/Webserver.API/Services/FileHandling/IApiDirectoryHandler.cs +++ b/src/Webserver.API/Services/FileHandling/IApiDirectoryHandler.cs @@ -2,6 +2,7 @@ // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models; +using System.Threading; using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Services.FileHandling @@ -22,7 +23,7 @@ public interface IApiDirectoryHandler /// /// resouce to be browsed /// A resource containing everything that is present underneath - Task BrowseAndBuildResourceAsync(ApiFileResource resource); + Task BrowseAndBuildResourceAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Delete the given resource (and all its sub-resources) /// @@ -33,7 +34,7 @@ public interface IApiDirectoryHandler /// /// the resource to delete /// Task for deletion - Task DeleteAsync(ApiFileResource resource); + Task DeleteAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// make very sure the given resource contains all the data: /// Resources @@ -51,7 +52,7 @@ public interface IApiDirectoryHandler /// the function will only upload the resource and its direct sub-resources /// /// - e.g. from parsed directory - Task DeployAsync(ApiFileResource resource); + Task DeployAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// make very sure the given resource contains all the data: /// Resources @@ -79,14 +80,14 @@ public interface IApiDirectoryHandler /// optional parameter: /// used to determine wether the DirectoryHandler should retry a upload and compare of the resources found or give up right away (default) /// - Task DeployOrUpdateAsync(ApiFileResource resource, int amountOfTriesForResourceDeployment = 1); + Task DeployOrUpdateAsync(ApiFileResource resource, int amountOfTriesForResourceDeployment = 1, CancellationToken cancellationToken = default(CancellationToken)); /// /// Update the given File Resource when necessary /// /// the file to be updated /// the file returned by browsing the plc /// Task to update the File - Task UpdateFileResourceAsync(ApiFileResource resource, ApiFileResource browsedResource); + Task UpdateFileResourceAsync(ApiFileResource resource, ApiFileResource browsedResource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Update the given File Resource when necessary /// @@ -100,13 +101,13 @@ public interface IApiDirectoryHandler /// the resource to be updated /// the resource returned by browsing the plc - make sure the sub-Nodes are present (!) /// Task to update the resource - Task UpdateResourceAsync(ApiFileResource resource, ApiFileResource browsedResource); + Task UpdateResourceAsync(ApiFileResource resource, ApiFileResource browsedResource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Update the given Resource - and SubResources, when necessary /// /// the resource to be updated /// the resource returned by browsing the plc - make sure the sub-Nodes are present (!) void UpdateResource(ApiFileResource resource, ApiFileResource browsedResource); - + } } \ No newline at end of file diff --git a/src/Webserver.API/Services/FileHandling/IApiFileHandler.cs b/src/Webserver.API/Services/FileHandling/IApiFileHandler.cs index 9a56389..5e1c433 100644 --- a/src/Webserver.API/Services/FileHandling/IApiFileHandler.cs +++ b/src/Webserver.API/Services/FileHandling/IApiFileHandler.cs @@ -2,12 +2,8 @@ // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models; -using Siemens.Simatic.S7.Webserver.API.Models.Responses; -using System; -using System.Collections.Generic; using System.IO; -using System.Net.Http.Headers; -using System.Text; +using System.Threading; using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Services.FileHandling @@ -24,7 +20,7 @@ public interface IApiFileHandler /// will default to Downloads but will determine path from -DESKTOP-, replaced "Desktop" by "Downloads" /// choose wether you want to replace an existing file or add another file with that name to you download directory in case one already exists /// FileInfo - Task DownloadFileAsync(string resource, string pathToDownloadDirectory = null, bool overrideExistingFile = false); + Task DownloadFileAsync(string resource, string pathToDownloadDirectory = null, bool overrideExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a Downloadresource, Downloadticket and Closeticket request to the API. Creates a file ticket which the client can use to retrieve a file from the PLC. @@ -41,14 +37,14 @@ public interface IApiFileHandler /// Path of the file relative to the memory card root. /// Path of the file to upload /// Task - Task DeployFileAsync(string resource, string filePath); + Task DeployFileAsync(string resource, string filePath, CancellationToken cancellationToken = default(CancellationToken)); /// /// Creates a file on the PLC : creates a file ticket which the client can use to transfer a file to the PLC. This is referred to as "uploading" a file to the PLC. /// /// Path of the file relative to the memory card root. /// Path of the file to upload - /// void + /// void void DeployFile(string resource, string filePath); /// @@ -56,7 +52,7 @@ public interface IApiFileHandler /// /// Path of the file relative to the memory card root. /// Task - Task DeployFileAsync(ApiFileResource resource); + Task DeployFileAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Creates a file on the PLC : creates a file ticket which the client can use to transfer a file to the PLC. This is referred to as "uploading" a file to the PLC. @@ -73,7 +69,7 @@ public interface IApiFileHandler /// will default to Downloads but will determine path from -DESKTOP-, replaced "Desktop" by "Downloads" /// choose wether you want to replace an existing file or add another file with that name to you download directory in case one already exists /// FileInfo - Task DataLogs_DownloadAndClearAsync(string resource, string pathToDownloadDirectory = null, bool overrideExistingFile = false); + Task DataLogs_DownloadAndClearAsync(string resource, string pathToDownloadDirectory = null, bool overrideExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)); /// /// Download and clear a datalog on the PLC. Creates a file ticket which the client can use to retrieve a data log from the PLC and clear it upon completion. diff --git a/src/Webserver.API/Services/FileHandling/IApiFileResourceBuilder.cs b/src/Webserver.API/Services/FileHandling/IApiFileResourceBuilder.cs index 6053581..586a1cb 100644 --- a/src/Webserver.API/Services/FileHandling/IApiFileResourceBuilder.cs +++ b/src/Webserver.API/Services/FileHandling/IApiFileResourceBuilder.cs @@ -16,7 +16,7 @@ public interface IApiFileResourceBuilder /// Path to the File/Directory to build the resource from /// the ApiFileResource ApiFileResource BuildResourceFromFile(string resourcePath); - + ///// Local Directory Path - used to determine the filename (Path!) } } \ No newline at end of file diff --git a/src/Webserver.API/Services/FileParser/ApiWebAppConfigParser.cs b/src/Webserver.API/Services/FileParser/ApiWebAppConfigParser.cs index 3facc0b..ef0df38 100644 --- a/src/Webserver.API/Services/FileParser/ApiWebAppConfigParser.cs +++ b/src/Webserver.API/Services/FileParser/ApiWebAppConfigParser.cs @@ -6,13 +6,10 @@ using Siemens.Simatic.S7.Webserver.API.Exceptions; using Siemens.Simatic.S7.Webserver.API.Models; using Siemens.Simatic.S7.Webserver.API.Services.WebApp; -using Siemens.Simatic.S7.Webserver.API.StaticHelpers; using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Services.FileParser { @@ -94,17 +91,17 @@ public ApiWebAppData Parse() webApp.ApplicationResources = RecursiveGetResources(PathToWebAppDirectory, webApp); return webApp; } - catch(Newtonsoft.Json.JsonSerializationException serializationException) + catch (Newtonsoft.Json.JsonSerializationException serializationException) { - if(serializationException.Message.Contains("Error setting value to 'State'")) + if (serializationException.Message.Contains("Error setting value to 'State'")) { throw new ApiWebAppConfigParserException("Missing parameter 'State' or State was invalid => 'None' or 0 ", serializationException); } - if(serializationException.Message.Contains("Error setting value to 'Type'")) + if (serializationException.Message.Contains("Error setting value to 'Type'")) { throw new ApiWebAppConfigParserException("Missing parameter 'Type' or Type was invalid => 'None' or 0 ", serializationException); } - throw serializationException; + throw; } } diff --git a/src/Webserver.API/Services/IApiServiceFactory.cs b/src/Webserver.API/Services/IApiServiceFactory.cs index 0f4becb..e85fcdc 100644 --- a/src/Webserver.API/Services/IApiServiceFactory.cs +++ b/src/Webserver.API/Services/IApiServiceFactory.cs @@ -1,8 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System.Net.Http; -using System.Threading.Tasks; using Siemens.Simatic.S7.Webserver.API.Models; using Siemens.Simatic.S7.Webserver.API.Services.Backup; using Siemens.Simatic.S7.Webserver.API.Services.FileHandling; @@ -10,6 +8,9 @@ using Siemens.Simatic.S7.Webserver.API.Services.PlcProgram; using Siemens.Simatic.S7.Webserver.API.Services.RequestHandling; using Siemens.Simatic.S7.Webserver.API.Services.WebApp; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Services { @@ -39,13 +40,27 @@ public interface IApiServiceFactory /// A usable and authenticated Task GetApiHttpClientRequestHandlerAsync(HttpClientConnectionConfiguration connectionConfiguration); /// + /// Get an using the given + /// + /// Connection configuration to use + /// Cancellation token to cancel pending requests. + /// A usable and authenticated + Task GetApiHttpClientRequestHandlerAsync(HttpClientConnectionConfiguration connectionConfiguration, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Get an httpclient using the given + /// + /// Connection Configuration which should contains the base address, username, passwort etc. + /// Token used to cancel requests without waiting for the response + /// an authorized httpclient (client with header value x-auth-token set) + Task GetHttpClientAsync(HttpClientConnectionConfiguration connectionConfiguration, CancellationToken cancellationToken = default(CancellationToken)); + /// /// Get an /// /// ip address or dns name of your plc /// username to login with /// password to login with /// A usable and authenticated - Task GetApiHttpClientRequestHandlerAsync(string baseAddress, string username, string password); + Task GetApiHttpClientRequestHandlerAsync(string baseAddress, string username, string password, CancellationToken cancellationToken = default(CancellationToken)); /// /// Get A resourceHandler with the given requestHandler and the set resourcebuilder /// @@ -96,23 +111,22 @@ public interface IApiServiceFactory /// an authorized httpclient (client with header value x-auth-token set) and the according webappcookie HttpClientAndWebAppCookie GetHttpClient(string baseAddress, string username, string password, bool include_web_application_cookie); /// - /// Get an httpclient using the given - /// - /// an authorized httpclient (client with header value x-auth-token set) - Task GetHttpClientAsync(HttpClientConnectionConfiguration connectionConfiguration); - /// /// Get an httpclient and a webappcookie (for accessing userdefined web pages) using the given /// + /// Connection Configuration which should contains the base address, username, passwort etc. + /// bool used to determine if the response should include a valid application cookie value for protected pages access + /// Cancellation token to cancel pending requests. /// an authorized httpclient (client with header value x-auth-token set) and the according webappcookie - Task GetHttpClientAsync(HttpClientConnectionConfiguration connectionConfiguration, bool include_web_application_cookie); + Task GetHttpClientAsync(HttpClientConnectionConfiguration connectionConfiguration, bool include_web_application_cookie, CancellationToken cancellationToken = default(CancellationToken)); /// /// Get an httpclient /// /// ip address or dns name of your plc /// username to login with /// password to login with + /// Cancellation token to cancel pending requests. /// an authorized httpclient (client with header value x-auth-token set) - Task GetHttpClientAsync(string baseAddress, string username, string password); + Task GetHttpClientAsync(string baseAddress, string username, string password, CancellationToken cancellationToken = default(CancellationToken)); /// /// Get an httpclient and a webappcookie (for accessing userdefined web pages) /// @@ -120,8 +134,9 @@ public interface IApiServiceFactory /// username to login with /// password to login with /// bool used to determine if the response should include a valid application cookie value for protected pages access + /// Cancellation token to cancel pending requests. /// an authorized httpclient (client with header value x-auth-token set) and the according webappcookie - Task GetHttpClientAsync(string baseAddress, string username, string password, bool include_web_application_cookie); + Task GetHttpClientAsync(string baseAddress, string username, string password, bool include_web_application_cookie, CancellationToken cancellationToken = default(CancellationToken)); /// /// Get A apiPlcProgramHandler with the given requestHandler and the set apiRequestFactory /// diff --git a/src/Webserver.API/Services/IdGenerator/CharSetIdGenerator.cs b/src/Webserver.API/Services/IdGenerator/CharSetIdGenerator.cs index 74dd53a..a73d7d9 100644 --- a/src/Webserver.API/Services/IdGenerator/CharSetIdGenerator.cs +++ b/src/Webserver.API/Services/IdGenerator/CharSetIdGenerator.cs @@ -1,13 +1,10 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using Siemens.Simatic.S7.Webserver.API.Models.Requests; using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Threading; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Services.IdGenerator { @@ -50,7 +47,7 @@ public CharSetIdGenerator() DeterminedThreadSleepTime = DetermineThreadSleepTime(); ThreadSleepTime = DeterminedThreadSleepTime; } - + /// /// Create a charsetgenerator with userdefined values /// @@ -70,7 +67,7 @@ public CharSetIdGenerator(string charSet, int length) : this() /// charset to be used /// time to sleep after generate calls /// Length of the Id to be generated - public CharSetIdGenerator(string charSet, TimeSpan threadSleepTime, + public CharSetIdGenerator(string charSet, TimeSpan threadSleepTime, int length) : this() { ThreadSleepTime = threadSleepTime; @@ -106,7 +103,7 @@ private void CheckLength(int length) public TimeSpan DetermineThreadSleepTime() { List MillisecondsDetermined = new List(); - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { DateTime start = DateTime.Now; var generated = Generate(); @@ -119,9 +116,9 @@ public TimeSpan DetermineThreadSleepTime() MillisecondsDetermined.Add(end - start); } TimeSpan result = TimeSpan.FromSeconds(0); - foreach(var element in MillisecondsDetermined) + foreach (var element in MillisecondsDetermined) { - if(element > result) + if (element > result) { result = element; } diff --git a/src/Webserver.API/Services/IdGenerator/GUIDGenerator.cs b/src/Webserver.API/Services/IdGenerator/GUIDGenerator.cs index b186ff3..3c02013 100644 --- a/src/Webserver.API/Services/IdGenerator/GUIDGenerator.cs +++ b/src/Webserver.API/Services/IdGenerator/GUIDGenerator.cs @@ -2,9 +2,6 @@ // // SPDX-License-Identifier: MIT using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; namespace Siemens.Simatic.S7.Webserver.API.Services.IdGenerator { @@ -38,7 +35,7 @@ public GUIDGenerator() /// public GUIDGenerator(int length) : this() { - if(length <= 0 || length > DefaultLength) + if (length <= 0 || length > DefaultLength) { throw new ArgumentOutOfRangeException(nameof(length)); } diff --git a/src/Webserver.API/Services/IdGenerator/IIdGenerator.cs b/src/Webserver.API/Services/IdGenerator/IIdGenerator.cs index dbf4c3d..f69dd41 100644 --- a/src/Webserver.API/Services/IdGenerator/IIdGenerator.cs +++ b/src/Webserver.API/Services/IdGenerator/IIdGenerator.cs @@ -1,7 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; namespace Siemens.Simatic.S7.Webserver.API.Services.IdGenerator { diff --git a/src/Webserver.API/Services/PlcProgram/ApiPlcProgramHandler.cs b/src/Webserver.API/Services/PlcProgram/ApiPlcProgramHandler.cs index 33db0df..79e2c32 100644 --- a/src/Webserver.API/Services/PlcProgram/ApiPlcProgramHandler.cs +++ b/src/Webserver.API/Services/PlcProgram/ApiPlcProgramHandler.cs @@ -5,12 +5,10 @@ using Siemens.Simatic.S7.Webserver.API.Models; using Siemens.Simatic.S7.Webserver.API.Models.Requests; using Siemens.Simatic.S7.Webserver.API.Models.Responses; -using Siemens.Simatic.S7.Webserver.API.Services.IdGenerator; using Siemens.Simatic.S7.Webserver.API.Services.RequestHandling; using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; @@ -42,9 +40,9 @@ public ApiPlcProgramHandler(IApiRequestHandler asyncRequestHandler, IApiRequestF /// Mode for PlcProgramBrowse function /// the db/structure of which the children should be browsed /// ApiResultResponse of List of ApiPlcProgramData containing the children of the given var - public async Task PlcProgramBrowseSetChildrenAndParentsAsync(ApiPlcProgramBrowseMode plcProgramBrowseMode, ApiPlcProgramData var) + public async Task PlcProgramBrowseSetChildrenAndParentsAsync(ApiPlcProgramBrowseMode plcProgramBrowseMode, ApiPlcProgramData var, CancellationToken cancellationToken = default(CancellationToken)) { - var response = await _apiRequestHandler.PlcProgramBrowseAsync(plcProgramBrowseMode, var); + var response = await _apiRequestHandler.PlcProgramBrowseAsync(plcProgramBrowseMode, var, cancellationToken); if (plcProgramBrowseMode == ApiPlcProgramBrowseMode.Children) { response.Result.ForEach(el => @@ -87,7 +85,8 @@ public ApiPlcProgramBrowseResponse PlcProgramBrowseSetChildrenAndParents(ApiPlcP /// Struct of which the Children should be Read by Bulk Request /// Mode in which the child values should be read - defaults to simple (easy user handling) /// The Struct containing the Children with their according Values - public async Task PlcProgramReadStructByChildValuesAsync(ApiPlcProgramData structToRead, ApiPlcProgramReadOrWriteMode childrenReadMode = ApiPlcProgramReadOrWriteMode.Simple) + public async Task PlcProgramReadStructByChildValuesAsync(ApiPlcProgramData structToRead, ApiPlcProgramReadOrWriteMode childrenReadMode = ApiPlcProgramReadOrWriteMode.Simple + , CancellationToken cancellationToken = default(CancellationToken)) { var toReturn = structToRead.ShallowCopy(); toReturn.Children = new List(structToRead.Children); @@ -95,14 +94,14 @@ public async Task PlcProgramReadStructByChildValuesAsync(ApiP toReturn.Parents = new List(structToRead.Parents); if (toReturn.Children == null || toReturn.Children.Count == 0) { - await PlcProgramBrowseSetChildrenAndParentsAsync(ApiPlcProgramBrowseMode.Children, toReturn); + await PlcProgramBrowseSetChildrenAndParentsAsync(ApiPlcProgramBrowseMode.Children, toReturn, cancellationToken); } List requests = new List(); foreach (var child in toReturn.Children) { if (!child.Datatype.IsSupportedByPlcProgramReadOrWrite()) { - await PlcProgramReadStructByChildValuesAsync(child, childrenReadMode); + await PlcProgramReadStructByChildValuesAsync(child, childrenReadMode, cancellationToken); } else if (child.ArrayElements?.Count != 0) { @@ -110,7 +109,7 @@ public async Task PlcProgramReadStructByChildValuesAsync(ApiP { if (!child.Datatype.IsSupportedByPlcProgramReadOrWrite()) { - await PlcProgramReadStructByChildValuesAsync(arrayElement, childrenReadMode); + await PlcProgramReadStructByChildValuesAsync(arrayElement, childrenReadMode, cancellationToken); } else { @@ -132,7 +131,7 @@ public async Task PlcProgramReadStructByChildValuesAsync(ApiP requests = _requestFactory.GetApiBulkRequestWithUniqueIds(requests).ToList(); if (requests.Count > 0) { - var childvalues = await _apiRequestHandler.ApiBulkAsync(requests); + var childvalues = await _apiRequestHandler.ApiBulkAsync(requests, cancellationToken); foreach (var childval in childvalues.SuccessfulResponses) { var accordingRequest = requests.First(el => el.Id == childval.Id); @@ -161,7 +160,7 @@ public ApiPlcProgramData PlcProgramReadStructByChildValues(ApiPlcProgramData str /// Struct of which the Children should be written by Bulk Request /// Mode in which the child values should be written - defaults to simple (easy user handling) /// The Struct containing the Children with their according Values - public async Task PlcProgramWriteStructByChildValuesAsync(ApiPlcProgramData structToWrite, ApiPlcProgramReadOrWriteMode childrenWriteMode = ApiPlcProgramReadOrWriteMode.Simple) + public async Task PlcProgramWriteStructByChildValuesAsync(ApiPlcProgramData structToWrite, ApiPlcProgramReadOrWriteMode childrenWriteMode = ApiPlcProgramReadOrWriteMode.Simple, CancellationToken cancellationToken = default(CancellationToken)) { var toReturn = structToWrite.ShallowCopy(); if (toReturn.Children == null || toReturn.Children.Count == 0) @@ -174,7 +173,7 @@ public async Task PlcProgramWriteStructByChildValuesAsync(ApiPl requests.Add(_requestFactory.GetApiPlcProgramWriteRequest(child.GetVarNameForMethods(), child.Value, childrenWriteMode)); } requests = _requestFactory.GetApiBulkRequestWithUniqueIds(requests).ToList(); - return await _apiRequestHandler.ApiBulkAsync(requests); + return await _apiRequestHandler.ApiBulkAsync(requests, cancellationToken); } /// diff --git a/src/Webserver.API/Services/PlcProgram/IApiPlcProgramHandler.cs b/src/Webserver.API/Services/PlcProgram/IApiPlcProgramHandler.cs index b35097a..8ad2626 100644 --- a/src/Webserver.API/Services/PlcProgram/IApiPlcProgramHandler.cs +++ b/src/Webserver.API/Services/PlcProgram/IApiPlcProgramHandler.cs @@ -1,11 +1,11 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Threading.Tasks; using Siemens.Simatic.S7.Webserver.API.Enums; using Siemens.Simatic.S7.Webserver.API.Models; using Siemens.Simatic.S7.Webserver.API.Models.Responses; +using System.Threading; +using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Services.PlcProgram { @@ -29,7 +29,7 @@ public interface IApiPlcProgramHandler /// Mode for PlcProgramBrowse function /// the db/structure of which the children should be browsed /// ApiResultResponse of List of ApiPlcProgramData containing the children of the given var - Task PlcProgramBrowseSetChildrenAndParentsAsync(ApiPlcProgramBrowseMode plcProgramBrowseMode, ApiPlcProgramData var); + Task PlcProgramBrowseSetChildrenAndParentsAsync(ApiPlcProgramBrowseMode plcProgramBrowseMode, ApiPlcProgramData var, CancellationToken cancellationToken = default(CancellationToken)); /// /// Method to comfortably read all Children of a struct using a Bulk Request /// @@ -43,7 +43,7 @@ public interface IApiPlcProgramHandler /// Struct of which the Children should be Read by Bulk Request /// Mode in which the child values should be read - defaults to simple (easy user handling) /// The Struct containing the Children with their according Values - Task PlcProgramReadStructByChildValuesAsync(ApiPlcProgramData structToRead, ApiPlcProgramReadOrWriteMode childrenReadMode = ApiPlcProgramReadOrWriteMode.Simple); + Task PlcProgramReadStructByChildValuesAsync(ApiPlcProgramData structToRead, ApiPlcProgramReadOrWriteMode childrenReadMode = ApiPlcProgramReadOrWriteMode.Simple, CancellationToken cancellationToken = default(CancellationToken)); /// /// Method to comfortably write all Children of a struct using a Bulk Request /// @@ -57,6 +57,6 @@ public interface IApiPlcProgramHandler /// Struct of which the Children should be written by Bulk Request /// Mode in which the child values should be written - defaults to simple (easy user handling) /// The Struct containing the Children with their according Values - Task PlcProgramWriteStructByChildValuesAsync(ApiPlcProgramData structToWrite, ApiPlcProgramReadOrWriteMode childrenWriteMode = ApiPlcProgramReadOrWriteMode.Simple); + Task PlcProgramWriteStructByChildValuesAsync(ApiPlcProgramData structToWrite, ApiPlcProgramReadOrWriteMode childrenWriteMode = ApiPlcProgramReadOrWriteMode.Simple, CancellationToken cancellationToken = default(CancellationToken)); } } \ No newline at end of file diff --git a/src/Webserver.API/Services/RequestHandling/ApiHttpClientRequestHandler.cs b/src/Webserver.API/Services/RequestHandling/ApiHttpClientRequestHandler.cs index 89b4c41..7aec347 100644 --- a/src/Webserver.API/Services/RequestHandling/ApiHttpClientRequestHandler.cs +++ b/src/Webserver.API/Services/RequestHandling/ApiHttpClientRequestHandler.cs @@ -1,2426 +1,2596 @@ -// Copyright (c) 2023, Siemens AG -// -// SPDX-License-Identifier: MIT -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; -using Siemens.Simatic.S7.Webserver.API.Enums; -using Siemens.Simatic.S7.Webserver.API.Exceptions; -using Siemens.Simatic.S7.Webserver.API.Models; -using Siemens.Simatic.S7.Webserver.API.Models.Requests; -using Siemens.Simatic.S7.Webserver.API.Models.Responses; -using Siemens.Simatic.S7.Webserver.API.StaticHelpers; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net.Http; -using System.Text; -using System.Threading.Tasks; -using System.Xml; - -namespace Siemens.Simatic.S7.Webserver.API.Services.RequestHandling -{ - /// - /// Request Handlerusing the Microsoft.Net.HttpClient to send the requests to the API - /// - public class ApiHttpClientRequestHandler : IApiRequestHandler - { - private readonly HttpClient _httpClient; - private readonly IApiRequestFactory _apiRequestFactory; - private readonly IApiResponseChecker _apiResponseChecker; - - /// - /// Should prob not be changed! - /// appilication/json for requests to the jsonrpc api endpoint - /// - public string ContentType => "application/json"; - - /// - /// Should prob not be changed! - /// Encoding.UTF8 - /// - public Encoding Encoding => Encoding.UTF8; - - /// - /// Should prob not be changed! - /// api/jsonrpc endpoint of plc - /// +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using Siemens.Simatic.S7.Webserver.API.Enums; +using Siemens.Simatic.S7.Webserver.API.Exceptions; +using Siemens.Simatic.S7.Webserver.API.Models; +using Siemens.Simatic.S7.Webserver.API.Models.AlarmsBrowse; +using Siemens.Simatic.S7.Webserver.API.Models.ApiDiagnosticBuffer; +using Siemens.Simatic.S7.Webserver.API.Models.Requests; +using Siemens.Simatic.S7.Webserver.API.Models.Responses; +using Siemens.Simatic.S7.Webserver.API.Models.TimeSettings; +using Siemens.Simatic.S7.Webserver.API.StaticHelpers; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Xml; + +namespace Siemens.Simatic.S7.Webserver.API.Services.RequestHandling +{ + /// + /// Request Handlerusing the Microsoft.Net.HttpClient to send the requests to the API + /// + public class ApiHttpClientRequestHandler : IApiRequestHandler + { + private readonly HttpClient _httpClient; + private readonly IApiRequestFactory _apiRequestFactory; + private readonly IApiResponseChecker _apiResponseChecker; + + /// + /// Should prob not be changed! + /// appilication/json for requests to the jsonrpc api endpoint + /// + public string ContentType => "application/json"; + + /// + /// Should prob not be changed! + /// Encoding.UTF8 + /// + public Encoding Encoding => Encoding.UTF8; + + /// + /// Should prob not be changed! + /// api/jsonrpc endpoint of plc + /// public string JsonRpcApi => "api/jsonrpc"; - /// - /// The ApiHttpClientRequestHandler will Send Post Requests, - /// before sending the Request it'll remove those Parameters that have the value null for their keys - /// (keep in mind when using - when not using the ApiRequestFactory) - /// - /// authorized httpClient with set Header: 'X-Auth-Token' - /// - /// response checker for the requestfactory and requesthandler... - public ApiHttpClientRequestHandler(HttpClient httpClient, IApiRequestFactory apiRequestFactory, IApiResponseChecker apiResponseChecker) - { - this._httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient)); - this._apiRequestFactory = apiRequestFactory ?? throw new ArgumentNullException(nameof(apiRequestFactory)); - this._apiResponseChecker = apiResponseChecker ?? throw new ArgumentNullException(nameof(apiResponseChecker)); - } - - /// - /// only use this function if you know how to build up apiRequests on your own! - /// will remove those Params that have the value Null and send the request using the HttpClient. - /// - /// Api Request to send to the plc (Json Serialized - null properties are deleted) - /// string: response from thePLC - public async Task SendPostRequestAsync(IApiRequest apiRequest) - { - if (apiRequest.Params != null) - { - apiRequest.Params = apiRequest.Params - .Where(el => el.Value != null) - .ToDictionary(x => x.Key, x => x.Value); - } - string apiRequestString = JsonConvert.SerializeObject(apiRequest, new JsonSerializerSettings() - { NullValueHandling = NullValueHandling.Ignore, ContractResolver = new CamelCasePropertyNamesContractResolver() }); - byte[] byteArr = Encoding.GetBytes(apiRequestString); - return await SendPostRequestAsync(apiRequestString); - } - - - - /// - /// only use this function if you know how to build up apiRequests on your own! - /// will remove those Params that have the value Null and send the request using the HttpClient. - /// - /// Api Request to send to the plc (Json Serialized - null properties are deleted) - /// string: response from thePLC - public string SendPostRequest(IApiRequest apiRequest) => SendPostRequestAsync(apiRequest).GetAwaiter().GetResult(); - - /// - /// only use this function if you know how to build up apiRequests on your own! - /// will remove those Params that have the value Null and send the request using the HttpClient. - /// - /// Api Request to send to the plc (Json Serialized - null properties are deleted) - /// string: response from thePLC - public async Task SendPostRequestAsync(IApiRequestIntId apiRequestWithIntId) - { - if (apiRequestWithIntId.Params != null) - { - apiRequestWithIntId.Params = apiRequestWithIntId.Params - .Where(el => el.Value != null) - .ToDictionary(x => x.Key, x => x.Value); - } - string apiRequestString = JsonConvert.SerializeObject(apiRequestWithIntId, new JsonSerializerSettings() - { NullValueHandling = NullValueHandling.Ignore, ContractResolver = new CamelCasePropertyNamesContractResolver() }); - byte[] byteArr = Encoding.GetBytes(apiRequestString); - return await SendPostRequestAsync(apiRequestString); - } - - /// - /// only use this function if you know how to build up apiRequests on your own! - /// will remove those Params that have the value Null and send the request using the HttpClient. - /// - /// Api Request to send to the plc (Json Serialized - null properties are deleted) - /// string: response from thePLC - public string SendPostRequest(IApiRequestIntId apiRequestWithIntId) => SendPostRequestAsync(apiRequestWithIntId).GetAwaiter().GetResult(); - - /// - /// only use this function if you know how to build up apiRequests on your own! - /// will remove those Params that have the value Null and send the request using the HttpClient. - /// - /// further information about the Api requeest the user tried to send (or was trying to send) - /// string: response from thePLC - public async Task SendPostRequestAsync(string apiRequestString) - { - byte[] byteArr = Encoding.GetBytes(apiRequestString); - ByteArrayContent request_body = new ByteArrayContent(byteArr); - request_body.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(ContentType); - var response = await _httpClient.PostAsync(JsonRpcApi, request_body); - _apiResponseChecker.CheckHttpResponseForErrors(response, apiRequestString); - var responseString = await response.Content.ReadAsStringAsync(); - _apiResponseChecker.CheckResponseStringForErros(responseString, apiRequestString); - return responseString; - } - - /// - /// only use this function if you know how to build up apiRequests on your own! - /// will remove those Params that have the value Null and send the request using the HttpClient. - /// - /// further information about the Api requeest the user tried to send (or was trying to send) - /// string: response from thePLC - public async Task> SendPostRequestAsyncFileName(string apiRequestString) - { - List result = new List(); - byte[] byteArr = Encoding.GetBytes(apiRequestString); - ByteArrayContent request_body = new ByteArrayContent(byteArr); - request_body.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(ContentType); - var response = await _httpClient.PostAsync(JsonRpcApi, request_body); - _apiResponseChecker.CheckHttpResponseForErrors(response, apiRequestString); - var responseString = await response.Content.ReadAsStringAsync(); - _apiResponseChecker.CheckResponseStringForErros(responseString, apiRequestString); - result.Add(responseString); - //result.Add(response.Content.Headers.ContentDisposition.FileName); - return result; - } - - /// - /// only use this function if you know how to build up apiRequests on your own! - /// will remove those Params that have the value Null and send the request using the HttpClient. - /// - /// further information about the Api requeest the user tried to send (or was trying to send) - /// string: response from thePLC - public string SendPostRequest(string apiRequestString) => SendPostRequestAsync(apiRequestString).GetAwaiter().GetResult(); - - /// - /// Send an Api.Browse Request using the Request from the ApiRequestFactory - /// - /// An Array of ApiClass (and Id,Jsonrpc) - public async Task ApiBrowseAsync() - { - var req = _apiRequestFactory.GetApiBrowseRequest(); - var responseString = await SendPostRequestAsync(req); - var arrOfApiClassResponse = JsonConvert.DeserializeObject(responseString); - if (arrOfApiClassResponse.Result.Count == 0) - { - throw new ApiInvalidResponseException("Api.Browse returned an empty array!"); - } - return arrOfApiClassResponse; - } - /// - /// Send an Api.Browse Request using the Request from the ApiRequestFactory - /// - /// An Array of ApiClass (and Id,Jsonrpc) - public ApiArrayOfApiClassResponse ApiBrowse() => ApiBrowseAsync().GetAwaiter().GetResult(); - - /// - /// Send an Api.BrowseTickets Request using the Request from the ApiRequestFactory - /// - /// ticket to be browsed (null to browse all) - /// BrowseTickets Response containing: Max_Tickets:uint, Tickets:Array of Ticket - public async Task ApiBrowseTicketsAsync(string ticketId = null) - { - var req = _apiRequestFactory.GetApiBrowseTicketsRequest(ticketId); - var responseString = await SendPostRequestAsync(req); - var arrOfApiClassResponse = JsonConvert.DeserializeObject(responseString); - return arrOfApiClassResponse; - } - - /// - /// Send an Api.BrowseTickets Request using the Request from the ApiRequestFactory - /// - /// ticket to be browsed (null to browse all) - /// BrowseTickets Response containing: Max_Tickets:uint, Tickets:Array of Ticket - - public ApiBrowseTicketsResponse ApiBrowseTickets(string ticketId = null) => ApiBrowseTicketsAsync(ticketId).GetAwaiter().GetResult(); - - /// - /// Send an Api.BrowseTickets Request using the Request from the ApiRequestFactory - /// - /// ticket to be browsed (null to browse all) - /// BrowseTickets Response containing: Max_Tickets:uint, Tickets:Array of Ticket - public async Task ApiBrowseTicketsAsync(ApiTicket ticket) => await ApiBrowseTicketsAsync(ticket.Id); - /// - /// Send an Api.BrowseTickets Request using the Request from the ApiRequestFactory - /// - /// ticket to be browsed (null to browse all) - /// BrowseTickets Response containing: Max_Tickets:uint, Tickets:Array of Ticket - public ApiBrowseTicketsResponse ApiBrowseTickets(ApiTicket ticket) => ApiBrowseTicketsAsync(ticket).GetAwaiter().GetResult(); - - /// - /// Send an Api.CloseTicket Request using the Request from the ApiRequestFactory - /// - /// ticket id (28 chars) - /// True to indicate Success - public async Task ApiCloseTicketAsync(string ticketId) - { - var req = _apiRequestFactory.GetApiCloseTicketRequest(ticketId); - var responseString = await SendPostRequestAsync(req); - var apiTrueOnSuccessResponse = JsonConvert.DeserializeObject(responseString); - return apiTrueOnSuccessResponse; - } - - /// - /// Send an Api.CloseTicket Request using the Request from the ApiRequestFactory - /// - /// ticket id (28 chars) - public ApiTrueOnSuccessResponse ApiCloseTicket(string ticketId) => ApiCloseTicketAsync(ticketId).GetAwaiter().GetResult(); - - /// - /// Send an Api.CloseTicket Request using the Request from the ApiRequestFactory - /// - /// ticket containing ticket id (28 chars) - /// True to indicate Success - public async Task ApiCloseTicketAsync(ApiTicket ticket) => await ApiCloseTicketAsync(ticket.Id); - - /// - /// Send an Api.CloseTicket Request using the Request from the ApiRequestFactory - /// - /// ticket containing ticket id (28 chars) - /// True to indicate Success - public ApiTrueOnSuccessResponse ApiCloseTicket(ApiTicket ticket) => ApiCloseTicketAsync(ticket).GetAwaiter().GetResult(); - - /// - /// Send an Api.GetCertificateUrl Request using the Request from the ApiRequestFactory - /// - /// ApiSingleStringResponse that contians the URL to the certificate - public async Task ApiGetCertificateUrlAsync() - { - var req = _apiRequestFactory.GetApiGetCertificateUrlRequest(); - string response = await SendPostRequestAsync(req); - if (!response.Contains("/MiniWebCA_Cer.crt")) - Console.WriteLine("unexpected response: " + response + " for Api.GetCertificateUrl!"); - return JsonConvert.DeserializeObject(response); - } - /// - /// Send an Api.GetCertificateUrl Request using the Request from the ApiRequestFactory - /// - /// ApiSingleStringResponse that contians the URL to the certificate - public ApiSingleStringResponse ApiGetCertificateUrl() => ApiGetCertificateUrlAsync().GetAwaiter().GetResult(); - - /// - /// Send an Api.GetPermissions Request using the Request from the ApiRequestFactory - /// - /// Array of ApiClass (in this case permissions) - public async Task ApiGetPermissionsAsync() - { - var req = _apiRequestFactory.GetApiGetPermissionsRequest(); - string response = await SendPostRequestAsync(req); - return JsonConvert.DeserializeObject(response); - } - /// - /// Send an Api.GetPermissions Request using the Request from the ApiRequestFactory - /// - /// Array of ApiClass (in this case permissions) - public ApiArrayOfApiClassResponse ApiGetPermissions() => ApiGetPermissionsAsync().GetAwaiter().GetResult(); - - /// - /// Send an Api.Logout Request using the Request from the ApiRequestFactory - /// - /// True to indicate success - public async Task ApiLogoutAsync() - { - var req = _apiRequestFactory.GetApiLogoutRequest(); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); - _httpClient.DefaultRequestHeaders.Remove("X-Auth-Token"); - return responseObj; - } - /// - /// Send an Api.Logout Request using the Request from the ApiRequestFactory - /// - /// True to indicate success - public ApiTrueOnSuccessResponse ApiLogout() => ApiLogoutAsync().GetAwaiter().GetResult(); - - /// - /// Send an Api.Ping Request using the Request from the ApiRequestFactory - /// - /// ApiSingleStringResponse - an Id that'll stay the same for the users session - public async Task ApiPingAsync() - { - var req = _apiRequestFactory.GetApiPingRequest(); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); - return responseObj; - } - /// - /// Send an Api.Ping Request using the Request from the ApiRequestFactory - /// - /// ApiSingleStringResponse - an Id that'll stay the same for the users session - public ApiSingleStringResponse ApiPing() => ApiPingAsync().GetAwaiter().GetResult(); - - /// - /// Send an Api.Version Request using the Request from the ApiRequestFactory - /// - /// a double that contains the value for the current ApiVersion - public async Task ApiVersionAsync() - { - var req = _apiRequestFactory.GetApiVersionRequest(); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); - return responseObj; - } - /// - /// Send an Api.Version Request using the Request from the ApiRequestFactory - /// - /// a double that contains the value for the current ApiVersion - public ApiDoubleResponse ApiVersion() => ApiVersionAsync().GetAwaiter().GetResult(); - - /// - /// Send a Plc.ReadOperatingMode Request using the Request from the ApiRequestFactory - /// - /// The current Plc OperatingMode - public async Task PlcReadOperatingModeAsync() - { - var req = _apiRequestFactory.GetApiPlcReadOperatingModeRequest(); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); - return responseObj; - } - /// - /// Send a Plc.ReadOperatingMode Request using the Request from the ApiRequestFactory - /// - /// The current Plc OperatingMode - public ApiReadOperatingModeResponse PlcReadOperatingMode() => PlcReadOperatingModeAsync().GetAwaiter().GetResult(); - - /// - /// Send a Plc.RequestChangeOperatingMode Request using the Request from the ApiRequestFactory - /// Method to change the plc operating mode - /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. - /// - /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. - public async Task PlcRequestChangeOperatingModeAsync(ApiPlcOperatingMode plcOperatingMode) - { - var req = _apiRequestFactory.GetApiPlcRequestChangeOperatingModeRequest(plcOperatingMode); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); - return responseObj; - } - /// - /// Send a Plc.RequestChangeOperatingMode Request using the Request from the ApiRequestFactory - /// Method to change the plc operating mode - /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. - /// - /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. - public ApiTrueOnSuccessResponse PlcRequestChangeOperatingMode(ApiPlcOperatingMode plcOperatingMode) - => PlcRequestChangeOperatingModeAsync(plcOperatingMode).GetAwaiter().GetResult(); - - /// - /// Send a PlcProgram.Browse Request using the Request from the ApiRequestFactory - /// - /// - /// Name of the variable to browse (symbolic) - /// • if "mode" ="var" this Attribut is required. The Browse-Method - /// searches for the variable to find the metadata of it. - /// • if "mode" = "children", this attribute is optional. The Browse-Method - /// searches for the variable and returns a list of child elements and metadata. - /// - /// Name der zu durchsuchenden Variable - /// • Wenn "mode" ="var", ist dieses Attribut erforderlich.Die Browse-Methode - /// sucht nach der Variable, um die Metadaten der Variable zu finden. - /// • Wenn "mode" = "children", ist dieses Attribut optional. Die Browse-Methode - /// sucht die Variable und liefert eine Liste an Kind-Variablen und Metadaten. - /// - /// PlcProgramBrowseResponse: An Array of ApiPlcProgramData - public async Task PlcProgramBrowseAsync(ApiPlcProgramBrowseMode plcProgramBrowseMode, string var = null) - { - var req = _apiRequestFactory.GetApiPlcProgramBrowseRequest(plcProgramBrowseMode, var); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); - return responseObj; - } - /// - /// Send a PlcProgram.Browse Request using the Request from the ApiRequestFactory - /// - /// - /// Name of the variable to browse (symbolic) - /// • if "mode" ="var" this Attribut is required. The Browse-Method - /// searches for the variable to find the metadata of it. - /// • if "mode" = "children", this attribute is optional. The Browse-Method - /// searches for the variable and returns a list of child elements and metadata. - /// - /// Name der zu durchsuchenden Variable - /// • Wenn "mode" ="var", ist dieses Attribut erforderlich.Die Browse-Methode - /// sucht nach der Variable, um die Metadaten der Variable zu finden. - /// • Wenn "mode" = "children", ist dieses Attribut optional. Die Browse-Methode - /// sucht die Variable und liefert eine Liste an Kind-Variablen und Metadaten. - /// - /// PlcProgramBrowseResponse: An Array of ApiPlcProgramData - public ApiPlcProgramBrowseResponse PlcProgramBrowse(ApiPlcProgramBrowseMode plcProgramBrowseMode, string var = null) => PlcProgramBrowseAsync(plcProgramBrowseMode, var).GetAwaiter().GetResult(); - - /// - /// Send a PlcProgram.Browse Request using the Request from the ApiRequestFactory - /// - /// - /// Name of the variable to browse (symbolic) - /// • if "mode" ="var" this Attribut is required. The Browse-Method - /// searches for the variable to find the metadata of it. - /// • if "mode" = "children", this attribute is optional. The Browse-Method - /// searches for the variable and returns a list of child elements and metadata. - /// - /// Name der zu durchsuchenden Variable - /// • Wenn "mode" ="var", ist dieses Attribut erforderlich.Die Browse-Methode - /// sucht nach der Variable, um die Metadaten der Variable zu finden. - /// • Wenn "mode" = "children", ist dieses Attribut optional. Die Browse-Methode - /// sucht die Variable und liefert eine Liste an Kind-Variablen und Metadaten. - /// - /// PlcProgramBrowseResponse: An Array of ApiPlcProgramData - public async Task PlcProgramBrowseAsync(ApiPlcProgramBrowseMode plcProgramBrowseMode, ApiPlcProgramData var) - { - string varName = var.GetVarNameForMethods(); - return await PlcProgramBrowseAsync(plcProgramBrowseMode, varName); - } - /// - /// Send a PlcProgram.Browse Request using the Request from the ApiRequestFactory - /// - /// - /// Name of the variable to browse (symbolic) - /// • if "mode" ="var" this Attribut is required. The Browse-Method - /// searches for the variable to find the metadata of it. - /// • if "mode" = "children", this attribute is optional. The Browse-Method - /// searches for the variable and returns a list of child elements and metadata. - /// - /// Name der zu durchsuchenden Variable - /// • Wenn "mode" ="var", ist dieses Attribut erforderlich.Die Browse-Methode - /// sucht nach der Variable, um die Metadaten der Variable zu finden. - /// • Wenn "mode" = "children", ist dieses Attribut optional. Die Browse-Methode - /// sucht die Variable und liefert eine Liste an Kind-Variablen und Metadaten. - /// - /// PlcProgramBrowseResponse: An Array of ApiPlcProgramData - public ApiPlcProgramBrowseResponse PlcProgramBrowse(ApiPlcProgramBrowseMode plcProgramBrowseMode, ApiPlcProgramData var) => PlcProgramBrowseAsync(plcProgramBrowseMode, var).GetAwaiter().GetResult(); + /// + /// The ApiHttpClientRequestHandler will Send Post Requests, + /// before sending the Request it'll remove those Parameters that have the value null for their keys + /// (keep in mind when using - when not using the ApiRequestFactory) + /// + /// authorized httpClient with set Header: 'X-Auth-Token' + /// + /// response checker for the requestfactory and requesthandler... + public ApiHttpClientRequestHandler(HttpClient httpClient, IApiRequestFactory apiRequestFactory, IApiResponseChecker apiResponseChecker) + { + this._httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient)); + this._apiRequestFactory = apiRequestFactory ?? throw new ArgumentNullException(nameof(apiRequestFactory)); + this._apiResponseChecker = apiResponseChecker ?? throw new ArgumentNullException(nameof(apiResponseChecker)); + } + + /// + /// only use this function if you know how to build up apiRequests on your own! + /// will remove those Params that have the value Null and send the request using the HttpClient. + /// + /// Api Request to send to the plc (Json Serialized - null properties are deleted) + /// Cancellation token to cancel pending requests. + /// string: response from thePLC + public async Task SendPostRequestAsync(IApiRequest apiRequest, CancellationToken cancellationToken = default(CancellationToken)) + { + if (apiRequest.Params != null) + { + apiRequest.Params = apiRequest.Params + .Where(el => el.Value != null) + .ToDictionary(x => x.Key, x => x.Value); + } + string apiRequestString = JsonConvert.SerializeObject(apiRequest, new JsonSerializerSettings() + { NullValueHandling = NullValueHandling.Ignore, ContractResolver = new CamelCasePropertyNamesContractResolver() }); + byte[] byteArr = Encoding.GetBytes(apiRequestString); + return await SendPostRequestAsync(apiRequestString, cancellationToken); + } + + + + /// + /// only use this function if you know how to build up apiRequests on your own! + /// will remove those Params that have the value Null and send the request using the HttpClient. + /// + /// Api Request to send to the plc (Json Serialized - null properties are deleted) + /// string: response from thePLC + public string SendPostRequest(IApiRequest apiRequest) => SendPostRequestAsync(apiRequest).GetAwaiter().GetResult(); + + /// + /// only use this function if you know how to build up apiRequests on your own! + /// will remove those Params that have the value Null and send the request using the HttpClient. + /// + /// Api Request to send to the plc (Json Serialized - null properties are deleted) + /// Cancellation token to cancel pending requests. + /// string: response from thePLC + public async Task SendPostRequestAsync(IApiRequestIntId apiRequestWithIntId, CancellationToken cancellationToken = default(CancellationToken)) + { + if (apiRequestWithIntId.Params != null) + { + apiRequestWithIntId.Params = apiRequestWithIntId.Params + .Where(el => el.Value != null) + .ToDictionary(x => x.Key, x => x.Value); + } + string apiRequestString = JsonConvert.SerializeObject(apiRequestWithIntId, new JsonSerializerSettings() + { NullValueHandling = NullValueHandling.Ignore, ContractResolver = new CamelCasePropertyNamesContractResolver() }); + byte[] byteArr = Encoding.GetBytes(apiRequestString); + return await SendPostRequestAsync(apiRequestString, cancellationToken); + } + + /// + /// only use this function if you know how to build up apiRequests on your own! + /// will remove those Params that have the value Null and send the request using the HttpClient. + /// + /// Api Request to send to the plc (Json Serialized - null properties are deleted) + /// string: response from thePLC + public string SendPostRequest(IApiRequestIntId apiRequestWithIntId) => SendPostRequestAsync(apiRequestWithIntId).GetAwaiter().GetResult(); + + /// + /// only use this function if you know how to build up apiRequests on your own! + /// will remove those Params that have the value Null and send the request using the HttpClient. + /// + /// further information about the Api requeest the user tried to send (or was trying to send) + /// Cancellation token to cancel pending requests. + /// string: response from thePLC + public async Task SendPostRequestAsync(string apiRequestString, CancellationToken cancellationToken = default(CancellationToken)) + { + byte[] byteArr = Encoding.GetBytes(apiRequestString); + ByteArrayContent request_body = new ByteArrayContent(byteArr); + request_body.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(ContentType); + var response = await _httpClient.PostAsync(JsonRpcApi, request_body, cancellationToken); + _apiResponseChecker.CheckHttpResponseForErrors(response, apiRequestString); +#if NET6_0_OR_GREATER + var responseString = await response.Content.ReadAsStringAsync(cancellationToken); +#else + var responseString = await response.Content.ReadAsStringAsync(); +#endif + _apiResponseChecker.CheckResponseStringForErros(responseString, apiRequestString); + return responseString; + } + + /// + /// only use this function if you know how to build up apiRequests on your own! + /// will remove those Params that have the value Null and send the request using the HttpClient. + /// + /// further information about the Api requeest the user tried to send (or was trying to send) + /// string: response from thePLC + public async Task> SendPostRequestAsyncFileName(string apiRequestString, CancellationToken cancellationToken = default(CancellationToken)) + { + List result = new List(); + byte[] byteArr = Encoding.GetBytes(apiRequestString); + ByteArrayContent request_body = new ByteArrayContent(byteArr); + request_body.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(ContentType); + var response = await _httpClient.PostAsync(JsonRpcApi, request_body); + _apiResponseChecker.CheckHttpResponseForErrors(response, apiRequestString); + var responseString = await response.Content.ReadAsStringAsync(); + _apiResponseChecker.CheckResponseStringForErros(responseString, apiRequestString); + result.Add(responseString); + //result.Add(response.Content.Headers.ContentDisposition.FileName); + return result; + } + + /// + /// only use this function if you know how to build up apiRequests on your own! + /// will remove those Params that have the value Null and send the request using the HttpClient. + /// + /// further information about the Api requeest the user tried to send (or was trying to send) + /// string: response from thePLC + public string SendPostRequest(string apiRequestString) => SendPostRequestAsync(apiRequestString).GetAwaiter().GetResult(); + + /// + /// Send an Api.Browse Request using the Request from the ApiRequestFactory + /// + /// Cancellation token to cancel pending requests. + /// An Array of ApiClass (and Id,Jsonrpc) + public async Task ApiBrowseAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiBrowseRequest(); + var responseString = await SendPostRequestAsync(req, cancellationToken); + var arrOfApiClassResponse = JsonConvert.DeserializeObject(responseString); + if (arrOfApiClassResponse.Result.Count == 0) + { + throw new ApiInvalidResponseException("Api.Browse returned an empty array!"); + } + return arrOfApiClassResponse; + } + /// + /// Send an Api.Browse Request using the Request from the ApiRequestFactory + /// + /// An Array of ApiClass (and Id,Jsonrpc) + public ApiArrayOfApiClassResponse ApiBrowse() => ApiBrowseAsync().GetAwaiter().GetResult(); + + /// + /// Send an Api.BrowseTickets Request using the Request from the ApiRequestFactory + /// + /// Cancellation token to cancel pending requests. + /// BrowseTickets Response containing: Max_Tickets:uint, Tickets:Array of Ticket + public async Task ApiBrowseTicketsAsync(CancellationToken cancellationToken) => await ApiBrowseTicketsAsync((string)null, cancellationToken); + + /// + /// Send an Api.BrowseTickets Request using the Request from the ApiRequestFactory + /// + /// ticket to be browsed (null to browse all) + /// Cancellation token to cancel pending requests. + /// BrowseTickets Response containing: Max_Tickets:uint, Tickets:Array of Ticket + public async Task ApiBrowseTicketsAsync(string ticketId = null, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiBrowseTicketsRequest(ticketId); + var responseString = await SendPostRequestAsync(req, cancellationToken); + var arrOfApiClassResponse = JsonConvert.DeserializeObject(responseString); + return arrOfApiClassResponse; + } + + /// + /// Send an Api.BrowseTickets Request using the Request from the ApiRequestFactory + /// + /// ticket to be browsed (null to browse all) + /// BrowseTickets Response containing: Max_Tickets:uint, Tickets:Array of Ticket + + public ApiBrowseTicketsResponse ApiBrowseTickets(string ticketId = null) => ApiBrowseTicketsAsync(ticketId).GetAwaiter().GetResult(); + + /// + /// Send an Api.BrowseTickets Request using the Request from the ApiRequestFactory + /// + /// ticket to be browsed (null to browse all) + /// Cancellation token to cancel pending requests. + /// BrowseTickets Response containing: Max_Tickets:uint, Tickets:Array of Ticket + public async Task ApiBrowseTicketsAsync(ApiTicket ticket, CancellationToken cancellationToken = default(CancellationToken)) => await ApiBrowseTicketsAsync(ticket.Id, cancellationToken); + + /// + /// Send an Api.BrowseTickets Request using the Request from the ApiRequestFactory + /// + /// ticket to be browsed (null to browse all) + /// BrowseTickets Response containing: Max_Tickets:uint, Tickets:Array of Ticket + public ApiBrowseTicketsResponse ApiBrowseTickets(ApiTicket ticket) => ApiBrowseTicketsAsync(ticket).GetAwaiter().GetResult(); + + /// + /// Send an Api.CloseTicket Request using the Request from the ApiRequestFactory + /// + /// ticket id (28 chars) + /// Cancellation token to cancel pending requests. + /// True to indicate Success + public async Task ApiCloseTicketAsync(string ticketId, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiCloseTicketRequest(ticketId); + var responseString = await SendPostRequestAsync(req, cancellationToken); + var apiTrueOnSuccessResponse = JsonConvert.DeserializeObject(responseString); + return apiTrueOnSuccessResponse; + } + + /// + /// Send an Api.CloseTicket Request using the Request from the ApiRequestFactory + /// + /// ticket id (28 chars) + public ApiTrueOnSuccessResponse ApiCloseTicket(string ticketId) => ApiCloseTicketAsync(ticketId).GetAwaiter().GetResult(); + + /// + /// Send an Api.CloseTicket Request using the Request from the ApiRequestFactory + /// + /// ticket containing ticket id (28 chars) + /// Cancellation token to cancel pending requests. + /// True to indicate Success + public async Task ApiCloseTicketAsync(ApiTicket ticket, CancellationToken cancellationToken = default(CancellationToken)) => await ApiCloseTicketAsync(ticket.Id); + + /// + /// Send an Api.CloseTicket Request using the Request from the ApiRequestFactory + /// + /// ticket containing ticket id (28 chars) + /// True to indicate Success + public ApiTrueOnSuccessResponse ApiCloseTicket(ApiTicket ticket) => ApiCloseTicketAsync(ticket).GetAwaiter().GetResult(); + + /// + /// Send an Api.ChangePassword request + /// + /// The user account for which the password shall be changed + /// The current password for the user + /// The new password for the user + /// True if changing password for the user was successful + public async Task ApiChangePasswordAsync(string username, string currentPassword, string newPassword, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiChangePasswordRequest(username, currentPassword, newPassword); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + /// + /// Send an Api.ChangePassword request + /// + /// The user account for which the password shall be changed + /// The current password for the user + /// The new password for the user + /// True if changing password for the user was successful + public ApiTrueOnSuccessResponse ApiChangePassword(string username, string currentPassword, string newPassword) => + ApiChangePasswordAsync(username, currentPassword, newPassword).GetAwaiter().GetResult(); + /// + /// Send an Api.GetCertificateUrl Request using the Request from the ApiRequestFactory + /// + /// ApiSingleStringResponse that contians the URL to the certificate + public async Task ApiGetCertificateUrlAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiGetCertificateUrlRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + if (!response.Contains("/MiniWebCA_Cer.crt")) + Console.WriteLine("unexpected response: " + response + " for Api.GetCertificateUrl!"); + return JsonConvert.DeserializeObject(response); + } + /// + /// Send an Api.GetCertificateUrl Request using the Request from the ApiRequestFactory + /// + /// ApiSingleStringResponse that contians the URL to the certificate + public ApiSingleStringResponse ApiGetCertificateUrl() => ApiGetCertificateUrlAsync().GetAwaiter().GetResult(); + + /// + /// Send an Api.GetPermissions Request using the Request from the ApiRequestFactory + /// + /// Cancellation token to cancel pending requests. + /// Array of ApiClass (in this case permissions) + public async Task ApiGetPermissionsAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiGetPermissionsRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + /// + /// Send an Api.GetQuantityStructures Request using the Request from the ApiRequestFactory + /// + /// Api Quantity Structure object + public async Task ApiGetQuantityStructuresAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiGetQuantityStructuresRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + + /// + /// Send an Api.GetQuantityStructures Request + /// + /// A QuantityStructure object + public ApiGetQuantityStructuresResponse ApiGetQuantityStructures() => ApiGetQuantityStructuresAsync().GetAwaiter().GetResult(); + + /// + /// Send an Api.GetPermissions Request using the Request from the ApiRequestFactory + /// + /// Array of ApiClass (in this case permissions) + public ApiArrayOfApiClassResponse ApiGetPermissions() => ApiGetPermissionsAsync().GetAwaiter().GetResult(); + + /// + /// Send an Api.Logout Request using the Request from the ApiRequestFactory + /// + /// Cancellation token to cancel pending requests. + /// True to indicate success + public async Task ApiLogoutAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiLogoutRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + _httpClient.DefaultRequestHeaders.Remove("X-Auth-Token"); + return responseObj; + } + /// + /// Send an Api.Logout Request using the Request from the ApiRequestFactory + /// + /// True to indicate success + public ApiTrueOnSuccessResponse ApiLogout() => ApiLogoutAsync().GetAwaiter().GetResult(); + + /// + /// Send an Api.Ping Request using the Request from the ApiRequestFactory + /// + /// ApiSingleStringResponse - an Id that'll stay the same for the users session + public async Task ApiPingAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiPingRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + /// + /// Send an Api.Ping Request using the Request from the ApiRequestFactory + /// + /// ApiSingleStringResponse - an Id that'll stay the same for the users session + public ApiSingleStringResponse ApiPing() => ApiPingAsync().GetAwaiter().GetResult(); + + /// + /// Send an Api.Version Request using the Request from the ApiRequestFactory + /// + /// a double that contains the value for the current ApiVersion + public async Task ApiVersionAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiVersionRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + /// + /// Send an Api.Version Request using the Request from the ApiRequestFactory + /// + /// a double that contains the value for the current ApiVersion + public ApiDoubleResponse ApiVersion() => ApiVersionAsync().GetAwaiter().GetResult(); + + /// + /// Perform a service data download on the corresponding module with hwid + /// + /// The HWID of a node (module) for which a service data file can be downloaded + /// Ticket to use for downloading the service data + public async Task ModulesDownloadServiceDataAsync(ApiPlcHwId hwid, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetModulesDownloadServiceData(hwid); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + /// + /// Perform a service data download on the corresponding module with hwid + /// + /// The HWID of a node (module) for which a service data file can be downloaded + /// Ticket to use for downloading the service data + public ApiTicketIdResponse ModulesDownloadServiceData(ApiPlcHwId hwid) => + ModulesDownloadServiceDataAsync(hwid).GetAwaiter().GetResult(); + + /// + /// Send a Plc.ReadOperatingMode Request using the Request from the ApiRequestFactory + /// + /// The current Plc OperatingMode + public async Task PlcReadOperatingModeAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiPlcReadOperatingModeRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + /// + /// Send a Plc.ReadOperatingMode Request using the Request from the ApiRequestFactory + /// + /// The current Plc OperatingMode + public ApiReadOperatingModeResponse PlcReadOperatingMode() => PlcReadOperatingModeAsync().GetAwaiter().GetResult(); + + /// + /// Send a Plc.RequestChangeOperatingMode Request using the Request from the ApiRequestFactory + /// Method to change the plc operating mode + /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. + /// + /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. + public async Task PlcRequestChangeOperatingModeAsync(ApiPlcOperatingMode plcOperatingMode, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiPlcRequestChangeOperatingModeRequest(plcOperatingMode); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + /// + /// Send a Plc.RequestChangeOperatingMode Request using the Request from the ApiRequestFactory + /// Method to change the plc operating mode + /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. + /// + /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. + public ApiTrueOnSuccessResponse PlcRequestChangeOperatingMode(ApiPlcOperatingMode plcOperatingMode) + => PlcRequestChangeOperatingModeAsync(plcOperatingMode).GetAwaiter().GetResult(); + + /// + /// Send a PlcProgram.Browse Request using the Request from the ApiRequestFactory + /// + /// + /// Name of the variable to browse (symbolic) + /// • if "mode" ="var" this Attribut is required. The Browse-Method + /// searches for the variable to find the metadata of it. + /// • if "mode" = "children", this attribute is optional. The Browse-Method + /// searches for the variable and returns a list of child elements and metadata. + /// + /// Name der zu durchsuchenden Variable + /// • Wenn "mode" ="var", ist dieses Attribut erforderlich.Die Browse-Methode + /// sucht nach der Variable, um die Metadaten der Variable zu finden. + /// • Wenn "mode" = "children", ist dieses Attribut optional. Die Browse-Methode + /// sucht die Variable und liefert eine Liste an Kind-Variablen und Metadaten. + /// + /// PlcProgramBrowseResponse: An Array of ApiPlcProgramData + public async Task PlcProgramBrowseAsync(ApiPlcProgramBrowseMode plcProgramBrowseMode, string var = null, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiPlcProgramBrowseRequest(plcProgramBrowseMode, var); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + /// + /// Send a PlcProgram.Browse Request using the Request from the ApiRequestFactory + /// + /// + /// Name of the variable to browse (symbolic) + /// • if "mode" ="var" this Attribut is required. The Browse-Method + /// searches for the variable to find the metadata of it. + /// • if "mode" = "children", this attribute is optional. The Browse-Method + /// searches for the variable and returns a list of child elements and metadata. + /// + /// Name der zu durchsuchenden Variable + /// • Wenn "mode" ="var", ist dieses Attribut erforderlich.Die Browse-Methode + /// sucht nach der Variable, um die Metadaten der Variable zu finden. + /// • Wenn "mode" = "children", ist dieses Attribut optional. Die Browse-Methode + /// sucht die Variable und liefert eine Liste an Kind-Variablen und Metadaten. + /// + /// PlcProgramBrowseResponse: An Array of ApiPlcProgramData + public ApiPlcProgramBrowseResponse PlcProgramBrowse(ApiPlcProgramBrowseMode plcProgramBrowseMode, string var = null) => PlcProgramBrowseAsync(plcProgramBrowseMode, var).GetAwaiter().GetResult(); + + /// + /// Send a PlcProgram.Browse Request using the Request from the ApiRequestFactory + /// + /// + /// Name of the variable to browse (symbolic) + /// • if "mode" ="var" this Attribut is required. The Browse-Method + /// searches for the variable to find the metadata of it. + /// • if "mode" = "children", this attribute is optional. The Browse-Method + /// searches for the variable and returns a list of child elements and metadata. + /// + /// Name der zu durchsuchenden Variable + /// • Wenn "mode" ="var", ist dieses Attribut erforderlich.Die Browse-Methode + /// sucht nach der Variable, um die Metadaten der Variable zu finden. + /// • Wenn "mode" = "children", ist dieses Attribut optional. Die Browse-Methode + /// sucht die Variable und liefert eine Liste an Kind-Variablen und Metadaten. + /// + /// PlcProgramBrowseResponse: An Array of ApiPlcProgramData + public async Task PlcProgramBrowseAsync(ApiPlcProgramBrowseMode plcProgramBrowseMode, ApiPlcProgramData var, CancellationToken cancellationToken = default(CancellationToken)) + { + string varName = var.GetVarNameForMethods(); + return await PlcProgramBrowseAsync(plcProgramBrowseMode, varName, cancellationToken); + } + /// + /// Send a PlcProgram.Browse Request using the Request from the ApiRequestFactory + /// + /// + /// Name of the variable to browse (symbolic) + /// • if "mode" ="var" this Attribut is required. The Browse-Method + /// searches for the variable to find the metadata of it. + /// • if "mode" = "children", this attribute is optional. The Browse-Method + /// searches for the variable and returns a list of child elements and metadata. + /// + /// Name der zu durchsuchenden Variable + /// • Wenn "mode" ="var", ist dieses Attribut erforderlich.Die Browse-Methode + /// sucht nach der Variable, um die Metadaten der Variable zu finden. + /// • Wenn "mode" = "children", ist dieses Attribut optional. Die Browse-Methode + /// sucht die Variable und liefert eine Liste an Kind-Variablen und Metadaten. + /// + /// PlcProgramBrowseResponse: An Array of ApiPlcProgramData + public ApiPlcProgramBrowseResponse PlcProgramBrowse(ApiPlcProgramBrowseMode plcProgramBrowseMode, ApiPlcProgramData var) => PlcProgramBrowseAsync(plcProgramBrowseMode, var).GetAwaiter().GetResult(); + + /// + /// Send a PlcProgram.Browse request for the code blocks. + /// + /// ApiPlcProgramBrowseCodeBlocksResponse: A collection of ApiPlcProgramBrowseCodeBlocksData objects. + public ApiPlcProgramBrowseCodeBlocksResponse PlcProgramBrowseCodeBlocks() => PlcProgramBrowseCodeBlocksAsync().GetAwaiter().GetResult(); + + /// + /// Send a PlcProgram.Browse request for the code blocks. + /// + /// Cancellation token to cancel pending requests. + /// ApiPlcProgramBrowseCodeBlocksResponse: A collection of ApiPlcProgramBrowseCodeBlocksData objects. + public async Task PlcProgramBrowseCodeBlocksAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiPlcProgramBrowseCodeBlocksRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + + /// + /// Send a PlcProgram.DownloadProfilingData request. + /// + /// ApiSingleStringResponse: Object containing the ticket ID for the data download. + public ApiSingleStringResponse PlcProgramDownloadProfilingData() => PlcProgramDownloadProfilingDataAsync().GetAwaiter().GetResult(); + + /// + /// Send a PlcProgram.DownloadProfilingData request. + /// + /// Cancellation token to cancel pending requests. + /// ApiSingleStringResponse: Object containing the ticket ID for the data download. + public async Task PlcProgramDownloadProfilingDataAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiPlcProgramDownloadProfilingDataRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + + /// + /// Send a PlcProgram.Read Request using the Request from the ApiRequestFactory + /// + /// Name of the variable to be read + /// + /// Name der zu lesenden Variable + /// + /// this parameter is optional and defaults to "simple": + /// "simple" will get the variable values according to the presentation of the manual - "supported Datatypes" + /// "raw" : will get the variable values according to the presentation of the manual "raw" + /// + /// Aufzählung, die das Antwortformat für diese Methode festlegt: + /// • "simple": liefert Variablenwerte gemäß der Darstellung + /// "simple" in Kapitel "Unterstützte Datentypen (Seite 162)" + /// • "raw": liefert Variablenwerte gemäß der Darstellung "raw" + /// in Kapitel "Unterstützte Datentypen" + /// ApiPlcProgramReadResponse: object with the value for the variables value to be read + public async Task> PlcProgramReadAsync(string var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiPlcProgramReadRequest(var, plcProgramReadMode); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject>(response); + return responseObj; + } + /// + /// Send a PlcProgram.Read Request using the Request from the ApiRequestFactory + /// + /// Name of the variable to be read + /// + /// Name der zu lesenden Variable + /// + /// this parameter is optional and defaults to "simple": + /// "simple" will get the variable values according to the presentation of the manual - "supported Datatypes" + /// "raw" : will get the variable values according to the presentation of the manual "raw" + /// + /// Aufzählung, die das Antwortformat für diese Methode festlegt: + /// • "simple": liefert Variablenwerte gemäß der Darstellung + /// "simple" in Kapitel "Unterstützte Datentypen (Seite 162)" + /// • "raw": liefert Variablenwerte gemäß der Darstellung "raw" + /// in Kapitel "Unterstützte Datentypen" + /// ApiPlcProgramReadResponse: object with the value for the variables value to be read + public ApiResultResponse PlcProgramRead(ApiPlcProgramData var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null) => PlcProgramReadAsync(var, plcProgramReadMode).GetAwaiter().GetResult(); + + /// + /// Send a PlcProgram.Browse Request using the Request from the ApiRequestFactory + /// This function will build up the name with quotes from the parents given with the ApiPlcProgramDataand call PlcProgramRead + /// + /// + /// Name of the variable to be read + /// Name der zu lesenden Variable + /// + /// this parameter is optional and defaults to "simple": + /// "simple" will get the variable values according to the presentation of the manual - "supported Datatypes" + /// "raw" : will get the variable values according to the presentation of the manual "raw" + /// + /// Aufzählung, die das Antwortformat für diese Methode festlegt: + /// • "simple": liefert Variablenwerte gemäß der Darstellung + /// "simple" in Kapitel "Unterstützte Datentypen (Seite 162)" + /// • "raw": liefert Variablenwerte gemäß der Darstellung "raw" + /// in Kapitel "Unterstützte Datentypen" + /// ApiPlcProgramReadResponse: object with the value for the variables value to be read + /// will be thrown if a ApiPlcProgramDatathat is an array will be given without an index + public async Task> PlcProgramReadAsync(ApiPlcProgramData var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null, CancellationToken cancellationToken = default(CancellationToken)) + { + //RequestParameterChecker.CheckPlcProgramReadOrWriteDataType(var.Datatype, true); + string varName = var.GetVarNameForMethods(); + return await PlcProgramReadAsync(varName, plcProgramReadMode, cancellationToken); + } + /// + /// Send a PlcProgram.Browse Request using the Request from the ApiRequestFactory + /// This function will build up the name with quotes from the parents given with the ApiPlcProgramDataand call PlcProgramRead + /// + /// + /// Name of the variable to be read + /// Name der zu lesenden Variable + /// + /// this parameter is optional and defaults to "simple": + /// "simple" will get the variable values according to the presentation of the manual - "supported Datatypes" + /// "raw" : will get the variable values according to the presentation of the manual "raw" + /// + /// Aufzählung, die das Antwortformat für diese Methode festlegt: + /// • "simple": liefert Variablenwerte gemäß der Darstellung + /// "simple" in Kapitel "Unterstützte Datentypen (Seite 162)" + /// • "raw": liefert Variablenwerte gemäß der Darstellung "raw" + /// in Kapitel "Unterstützte Datentypen" + /// ApiPlcProgramReadResponse: object with the value for the variables value to be read + /// will be thrown if a ApiPlcProgramDatathat is an array will be given without an index + public ApiResultResponse PlcProgramRead(string var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null) => PlcProgramReadAsync(var, plcProgramReadMode).GetAwaiter().GetResult(); + + /// + /// Send a PlcProgram.Write Request using the Request from the ApiRequestFactory + /// This function will build up the name with quotes from the parents given with the ApiPlcProgramDataand call PlcProgramWrite + /// + /// + /// Name of the variable to be read + /// Name der zu lesenden Variable + /// + /// + /// true to indicate success + /// will be thrown if a ApiPlcProgramDatathat is an array will be given without an index + public async Task PlcProgramWriteAsync(ApiPlcProgramData var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null, CancellationToken cancellationToken = default(CancellationToken)) + { + string varName = var.GetVarNameForMethods(); + // ApiRequestFactory.CheckPlcProgramReadOrWriteDataType(var.Datatype); will also be called by GetApiPlcProgramWriteValueToBeSet! + var writeVal = _apiRequestFactory.GetApiPlcProgramWriteValueToBeSet(var.Datatype, valueToBeSet); + return await PlcProgramWriteAsync(varName, writeVal, plcProgramWriteMode, cancellationToken); + } + /// + /// Send a PlcProgram.Write Request using the Request from the ApiRequestFactory + /// This function will build up the name with quotes from the parents given with the ApiPlcProgramDataand call PlcProgramWrite + /// + /// + /// Name of the variable to be read + /// Name der zu lesenden Variable + /// + /// + /// true to indicate success + /// will be thrown if a ApiPlcProgramDatathat is an array will be given without an index + public ApiTrueOnSuccessResponse PlcProgramWrite(ApiPlcProgramData var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null) + => PlcProgramWriteAsync(var, valueToBeSet, plcProgramWriteMode).GetAwaiter().GetResult(); + + /// + /// Send a PlcProgram.Write Request using the Request from the ApiRequestFactory + /// + /// + /// Name of the variable to be read + /// Name der zu lesenden Variable + /// + /// + /// true to indicate success + /// will be thrown if a ApiPlcProgramDatathat is an array will be given without an index + public async Task PlcProgramWriteAsync(string var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiPlcProgramWriteRequest(var, valueToBeSet, plcProgramWriteMode); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + /// + /// Send a PlcProgram.Write Request using the Request from the ApiRequestFactory + /// + /// + /// Name of the variable to be read + /// Name der zu lesenden Variable + /// + /// + /// true to indicate success + /// will be thrown if a ApiPlcProgramDatathat is an array will be given without an index + public ApiTrueOnSuccessResponse PlcProgramWrite(string var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null) + => PlcProgramWriteAsync(var, valueToBeSet, plcProgramWriteMode).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.Browse Request using the Request from the ApiRequestFactory + /// + /// webappdata that should be requested + /// ApiWebAppBrowseResponse: Containing WebAppBrowseResult: Max_Applications:uint, + /// Applications: Array of ApiWebAppdata containing one element: the webappdata that has been requested + public async Task WebAppBrowseAsync(ApiWebAppData webAppData, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppBrowseAsync(webAppData.Name, cancellationToken); + } + /// + /// Send a WebApp.Browse Request using the Request from the ApiRequestFactory + /// + /// webappdata that should be requested + /// ApiWebAppBrowseResponse: Containing WebAppBrowseResult: Max_Applications:uint, + /// Applications: Array of ApiWebAppdata containing one element: the webappdata that has been requested + public ApiWebAppBrowseResponse WebAppBrowse(ApiWebAppData webAppData) => WebAppBrowseAsync(webAppData).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.Browse Request using the Request from the ApiRequestFactory + /// + /// webapp name in case only one is requested + /// ApiWebAppBrowseResponse: Containing WebAppBrowseResult: Max_Applications:uint, + /// Applications: Array of ApiWebAppdata containing one element: the webappdata that has been requested + public async Task WebAppBrowseAsync(string webAppName = null, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebAppBrowseRequest(webAppName); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + /// + /// Send a WebApp.Browse Request using the Request from the ApiRequestFactory + /// + /// webapp name in case only one is requested + /// ApiWebAppBrowseResponse: Containing WebAppBrowseResult: Max_Applications:uint, + /// Applications: Array of ApiWebAppdata containing one element: the webappdata that has been requested + public ApiWebAppBrowseResponse WebAppBrowse(string webAppName = null) => WebAppBrowseAsync(webAppName).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.BrowseResources Request using the Request from the ApiRequestFactory + /// Will return the Api Response "straight away" + /// A user can use the List of ApiWebAppResources to set those to an ApiWebAppData + /// (care to also add those who are protected to the protected resources in case you want to do that) + /// + /// WebApp name to browse resources of + /// If given only that resource will be inside the array (in case it exists) + /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, + /// Resources:Array of ApiWebAppResource (only 1 if one is requested) + public async Task WebAppBrowseResourcesAsync(string webAppName, string resourceName = null, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebAppBrowseResourcesRequest(webAppName, resourceName); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + /// + /// Send a WebApp.BrowseResources Request using the Request from the ApiRequestFactory + /// Will return the Api Response "straight away" + /// A user can use the List of ApiWebAppResources to set those to an ApiWebAppData + /// (care to also add those who are protected to the protected resources in case you want to do that) + /// + /// WebApp name to browse resources of + /// If given only that resource will be inside the array (in case it exists) + /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, + /// Resources:Array of ApiWebAppResource (only 1 if one is requested) + public ApiWebAppBrowseResourcesResponse WebAppBrowseResources(string webAppName, string resourceName = null) => WebAppBrowseResourcesAsync(webAppName, resourceName).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.BrowseResources Request using the Request from the ApiRequestFactory + /// Will return the Api Response "straight away" + /// A user can use the List of ApiWebAppResources to set those to an ApiWebAppData + /// (care to also add those who are protected to the protected resources in case you want to do that) + /// + /// WebApp.Name to browse resources of + /// If given only that resource will be inside the array (in case it exists) + /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, + /// Resources:Array of ApiWebAppResource (only 1 if one is requested) + public async Task WebAppBrowseResourcesAsync(ApiWebAppData webApp, string resourceName = null, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppBrowseResourcesAsync(webApp.Name, resourceName, cancellationToken); + } + /// + /// Send a WebApp.BrowseResources Request using the Request from the ApiRequestFactory + /// Will return the Api Response "straight away" + /// A user can use the List of ApiWebAppResources to set those to an ApiWebAppData + /// (care to also add those who are protected to the protected resources in case you want to do that) + /// + /// WebApp.Name to browse resources of + /// If given only that resource will be inside the array (in case it exists) + /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, + /// Resources:Array of ApiWebAppResource (only 1 if one is requested) + public ApiWebAppBrowseResourcesResponse WebAppBrowseResources(ApiWebAppData webApp, string resourceName = null) => WebAppBrowseResourcesAsync(webApp, resourceName).GetAwaiter().GetResult(); + /// + /// Send a WebApp.BrowseResources Request using the Request from the ApiRequestFactory + /// Will return the Api Response "straight away" + /// A user can use the List of ApiWebAppResources to set those to an ApiWebAppData + /// (care to also add those who are protected to the protected resources in case you want to do that) + /// + /// WebApp Name to browse resources of + /// resource.Name to browse for + /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, + /// Resources:Array of ApiWebAppResource (only 1 if one is requested) + public async Task WebAppBrowseResourcesAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppBrowseResourcesAsync(webAppName, resource.Name, cancellationToken); + } + /// + /// Send a WebApp.BrowseResources Request using the Request from the ApiRequestFactory + /// Will return the Api Response "straight away" + /// A user can use the List of ApiWebAppResources to set those to an ApiWebAppData + /// (care to also add those who are protected to the protected resources in case you want to do that) + /// + /// WebApp Name to browse resources of + /// resource.Name to browse for + /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, + /// Resources:Array of ApiWebAppResource (only 1 if one is requested) + public ApiWebAppBrowseResourcesResponse WebAppBrowseResources(string webAppName, ApiWebAppResource resource) => WebAppBrowseResourcesAsync(webAppName, resource).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.BrowseResources Request using the Request from the ApiRequestFactory + /// Will return the Api Response "straight away" + /// A user can use the List of ApiWebAppResources to set those to an ApiWebAppData + /// (care to also add those who are protected to the protected resources in case you want to do that) + /// + /// webApp.Name to browse resources of + /// resource.Name to browse for + /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, + /// Resources:Array of ApiWebAppResource (only 1 if one is requested) + public async Task WebAppBrowseResourcesAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppBrowseResourcesAsync(webApp.Name, resource.Name, cancellationToken); + } + /// + /// Send a WebApp.BrowseResources Request using the Request from the ApiRequestFactory + /// Will return the Api Response "straight away" + /// A user can use the List of ApiWebAppResources to set those to an ApiWebAppData + /// (care to also add those who are protected to the protected resources in case you want to do that) + /// + /// webApp.Name to browse resources of + /// resource.Name to browse for + /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, + /// Resources:Array of ApiWebAppResource (only 1 if one is requested) + public ApiWebAppBrowseResourcesResponse WebAppBrowseResources(ApiWebAppData webApp, ApiWebAppResource resource) => WebAppBrowseResourcesAsync(webApp, resource).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.Create Request using the Request from the ApiRequestFactory + /// + /// webapp name for the app to be created + /// optional parameter: state the webapp should be in + /// true to indicate success + public async Task WebAppCreateAsync(string webAppName, ApiWebAppState? apiWebAppState = null, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebAppCreateRequest(webAppName, apiWebAppState); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + /// + /// Send a WebApp.Create Request using the Request from the ApiRequestFactory + /// + /// webapp name for the app to be created + /// optional parameter: state the webapp should be in + /// true to indicate success + public ApiTrueOnSuccessResponse WebAppCreate(string webAppName, ApiWebAppState? apiWebAppState = null) => WebAppCreateAsync(webAppName, apiWebAppState).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.Create Request using the Request from the ApiRequestFactory + /// + /// containing information about name and state for the app to be created + /// true to indicate success + public async Task WebAppCreateAsync(ApiWebAppData webApp, CancellationToken cancellationToken = default(CancellationToken)) + { + // ApiRequestFactory.CheckState(webApp.State); will be called in WebAppCreate in Factory.GetApiWebAppCreateRequest + return await WebAppCreateAsync(webApp.Name, webApp.State, cancellationToken); + } + /// + /// Send a WebApp.Create Request using the Request from the ApiRequestFactory + /// + /// containing information about name and state for the app to be created + /// true to indicate success + public ApiTrueOnSuccessResponse WebAppCreate(ApiWebAppData webApp) => WebAppCreateAsync(webApp).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.CreateResource Request using the Request from the ApiRequestFactory + /// + /// name of the webapp to create the resource on + /// resource name to be created with (typically provided with extension) + /// resource media type - see MIMEType.mapping + /// Be sure to provide the RFC3339 format! + /// resource visibility (protect your confidential data) + /// you can provide an etag as identification,... for your resource + /// TicketId for the Ticketing Endpoint to perform the Upload on + public async Task WebAppCreateResourceAsync(string webAppName, string resourceName, string media_type, + string last_modified, ApiWebAppResourceVisibility? apiWebAppResourceVisibility = null, string etag = null, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebAppCreateResourceRequest(webAppName, resourceName, media_type, + last_modified, apiWebAppResourceVisibility, etag); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + /// + /// Send a WebApp.CreateResource Request using the Request from the ApiRequestFactory + /// + /// name of the webapp to create the resource on + /// resource name to be created with (typically provided with extension) + /// resource media type - see MIMEType.mapping + /// Be sure to provide the RFC3339 format! + /// resource visibility (protect your confidential data) + /// you can provide an etag as identification,... for your resource + /// TicketId for the Ticketing Endpoint to perform the Upload on + public ApiTicketIdResponse WebAppCreateResource(string webAppName, string resourceName, string media_type, string last_modified, ApiWebAppResourceVisibility? apiWebAppResourceVisibility = null, string etag = null) + => WebAppCreateResourceAsync(webAppName, resourceName, media_type, last_modified, apiWebAppResourceVisibility, etag).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.CreateResource Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp to create the resource on + /// resource name to be created with (typically provided with extension) + /// resource media type - see MIMEType.mapping + /// Be sure to provide the RFC3339 format! + /// resource visibility (protect your confidential data) + /// you can provide an etag as identification,... for your resource + /// TicketId for the Ticketing Endpoint to perform the Upload on + public async Task WebAppCreateResourceAsync(ApiWebAppData webApp, string resourceName, string media_type, + string last_modified, ApiWebAppResourceVisibility? apiWebAppResourceVisibility = null, string etag = null, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppCreateResourceAsync(webApp.Name, resourceName, media_type, last_modified, apiWebAppResourceVisibility, etag, cancellationToken); + } + /// + /// Send a WebApp.CreateResource Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp to create the resource on + /// resource name to be created with (typically provided with extension) + /// resource media type - see MIMEType.mapping + /// Be sure to provide the RFC3339 format! + /// resource visibility (protect your confidential data) + /// you can provide an etag as identification,... for your resource + /// TicketId for the Ticketing Endpoint to perform the Upload on + public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, string resourceName, string media_type, string last_modified, ApiWebAppResourceVisibility? apiWebAppResourceVisibility = null, string etag = null) + => WebAppCreateResourceAsync(webApp, resourceName, media_type, last_modified, apiWebAppResourceVisibility, etag).GetAwaiter().GetResult(); + /// + /// Send a WebApp.CreateResource Request using the Request from the ApiRequestFactory + /// + /// name of the webapp to create the resource on + /// resource containing all the information: + /// Name: name to be created with (typically provided with extension) + /// Media_type: resource media type - see MIMEType.mapping + /// Last_modified: Be sure to provide the RFC3339 format! + /// Visibility: resource visibility (protect your confidential data) + /// Etag: you can provide an etag as identification,... for your resource + /// TicketId for the Ticketing Endpoint to perform the Upload on + public async Task WebAppCreateResourceAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppCreateResourceAsync(webAppName, resource.Name, resource.Media_type, + resource.Last_modified.ToString(DateTimeFormatting.ApiDateTimeFormat), resource.Visibility, resource.Etag, cancellationToken); + } + /// + /// Send a WebApp.CreateResource Request using the Request from the ApiRequestFactory + /// + /// name of the webapp to create the resource on + /// resource containing all the information: + /// Name: name to be created with (typically provided with extension) + /// Media_type: resource media type - see MIMEType.mapping + /// Last_modified: Be sure to provide the RFC3339 format! + /// Visibility: resource visibility (protect your confidential data) + /// Etag: you can provide an etag as identification,... for your resource + /// TicketId for the Ticketing Endpoint to perform the Upload on + public ApiTicketIdResponse WebAppCreateResource(string webAppName, ApiWebAppResource resource) => WebAppCreateResourceAsync(webAppName, resource).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.CreateResource Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp to create the resource on + /// resource containing all the information: + /// Name: name to be created with (typically provided with extension) + /// Media_type: resource media type - see MIMEType.mapping + /// Last_modified: Be sure to provide the RFC3339 format! + /// Visibility: resource visibility (protect your confidential data) + /// Etag: you can provide an etag as identification,... for your resource + /// TicketId for the Ticketing Endpoint to perform the Upload on + public async Task WebAppCreateResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppCreateResourceAsync(webApp.Name, resource.Name, resource.Media_type, + resource.Last_modified.ToString(DateTimeFormatting.ApiDateTimeFormat), resource.Visibility, resource.Etag, cancellationToken); + } + /// + /// Send a WebApp.CreateResource Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp to create the resource on + /// resource containing all the information: + /// Name: name to be created with (typically provided with extension) + /// Media_type: resource media type - see MIMEType.mapping + /// Last_modified: Be sure to provide the RFC3339 format! + /// Visibility: resource visibility (protect your confidential data) + /// Etag: you can provide an etag as identification,... for your resource + /// TicketId for the Ticketing Endpoint to perform the Upload on + public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, ApiWebAppResource resource) => WebAppCreateResourceAsync(webApp, resource).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.Delete Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp to delete + /// true to indicate success + public async Task WebAppDeleteAsync(string webAppName, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebAppDeleteRequest(webAppName); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + /// + /// Send a WebApp.Delete Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp to delete + /// true to indicate success + public ApiTrueOnSuccessResponse WebAppDelete(string webAppName) => WebAppDeleteAsync(webAppName).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.Delete Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp to delete + /// true to indicate success + public async Task WebAppDeleteAsync(ApiWebAppData webApp, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppDeleteAsync(webApp.Name, cancellationToken); + } + /// + /// Send a WebApp.Delete Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp to delete + /// true to indicate success + public ApiTrueOnSuccessResponse WebAppDelete(ApiWebAppData webApp) => WebAppDeleteAsync(webApp).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.DeleteRespource Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that contains the resource + /// Name of the resource to delete + /// true to indicate success + public async Task WebAppDeleteResourceAsync(string webAppName, string resourceName, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebAppDeleteResourceRequest(webAppName, resourceName); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + /// + /// Send a WebApp.DeleteRespource Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that contains the resource + /// Name of the resource to delete + /// true to indicate success + public ApiTrueOnSuccessResponse WebAppDeleteResource(string webAppName, string resourceName) => WebAppDeleteResourceAsync(webAppName, resourceName).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.DeleteRespource Request using the Request from the ApiRequestFactory + /// + /// webapp.Name of the webapp that contains the resource + /// Name of the resource to delete + /// true to indicate success + public async Task WebAppDeleteResourceAsync(ApiWebAppData webApp, string resourceName, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppDeleteResourceAsync(webApp.Name, resourceName, cancellationToken); + } + /// + /// Send a WebApp.DeleteRespource Request using the Request from the ApiRequestFactory + /// + /// webapp.Name of the webapp that contains the resource + /// Name of the resource to delete + /// true to indicate success + public ApiTrueOnSuccessResponse WebAppDeleteResource(ApiWebAppData webApp, string resourceName) => WebAppDeleteResourceAsync(webApp, resourceName).GetAwaiter().GetResult(); + /// + /// Send a WebApp.DeleteRespource Request using the Request from the ApiRequestFactory + /// + /// webapp.Name of the webapp that contains the resource + /// Name of the resource to delete + /// true to indicate success + public ApiTrueOnSuccessResponse WebAppDeleteResource(string webAppName, ApiWebAppResource resource) => WebAppDeleteResourceAsync(webAppName, resource).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.DeleteRespource Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resource.Name of the resource to delete + /// true to indicate success + public async Task WebAppDeleteResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppDeleteResourceAsync(webApp.Name, resource.Name, cancellationToken); + } + /// + /// Send a WebApp.DeleteRespource Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resource.Name of the resource to delete + /// true to indicate success + public ApiTrueOnSuccessResponse WebAppDeleteResource(ApiWebAppData webApp, ApiWebAppResource resource) => WebAppDeleteResourceAsync(webApp, resource).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.DeleteRespource Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that contains the resource + /// resource.Name of the resource to delete + /// true to indicate success + public async Task WebAppDeleteResourceAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppDeleteResourceAsync(webAppName, resource.Name, cancellationToken); + } + + /// + /// Send a WebApp.DownloadResource Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that contains the resource + /// Name of the resource to download + /// Ticket id for Ticketing Endpoint to trigger the download on + public async Task WebAppDownloadResourceAsync(string webAppName, string resourceName, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebAppDownloadResourceRequest(webAppName, resourceName); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + /// + /// Send a WebApp.DownloadResource Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that contains the resource + /// Name of the resource to download + /// Ticket id for Ticketing Endpoint to trigger the download on + public ApiTicketIdResponse WebAppDownloadResource(string webAppName, string resourceName) => WebAppDownloadResourceAsync(webAppName, resourceName).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.DownloadResource Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// Name of the resource to download + /// Ticket id for Ticketing Endpoint to trigger the download on + public async Task WebAppDownloadResourceAsync(ApiWebAppData webApp, string resourceName, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppDownloadResourceAsync(webApp.Name, resourceName, cancellationToken); + } + /// + /// Send a WebApp.DownloadResource Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// Name of the resource to download + /// Ticket id for Ticketing Endpoint to trigger the download on + public ApiTicketIdResponse WebAppDownloadResource(ApiWebAppData webApp, string resourceName) => WebAppDownloadResourceAsync(webApp, resourceName).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.DownloadResource Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resource.Name of the resource to download + /// Ticket id for Ticketing Endpoint to trigger the download on + public async Task WebAppDownloadResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppDownloadResourceAsync(webApp.Name, resource.Name, cancellationToken); + } + /// + /// Send a WebApp.DownloadResource Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resource.Name of the resource to download + /// Ticket id for Ticketing Endpoint to trigger the download on + public ApiTicketIdResponse WebAppDownloadResource(ApiWebAppData webApp, ApiWebAppResource resource) => WebAppDownloadResourceAsync(webApp, resource).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.DownloadResource Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that contains the resource + /// resource.Name of the resource to download + /// Ticket id for Ticketing Endpoint to trigger the download on + public async Task WebAppDownloadResourceAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppDownloadResourceAsync(webAppName, resource.Name, cancellationToken); + } + /// + /// Send a WebApp.DownloadResource Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that contains the resource + /// resource.Name of the resource to download + /// Ticket id for Ticketing Endpoint to trigger the download on + public ApiTicketIdResponse WebAppDownloadResource(string webAppName, ApiWebAppResource resource) => WebAppDownloadResourceAsync(webAppName, resource).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.Rename Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that should be renamed + /// New name for the WebApp + /// This function will return the TrueOnSuccessResponse and a WebApp that only has the information: + /// name which equals the newname + public async Task WebAppRenameAsync(string webAppName, string newWebAppName, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebAppRenameRequest(webAppName, newWebAppName); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = new ApiTrueWithWebAppResponse(); + responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); + if (responseObj.TrueOnSuccesResponse.Result) + { + responseObj.NewWebApp = new ApiWebAppData() { Name = newWebAppName }; + } + return responseObj; + } + /// + /// Send a WebApp.Rename Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that should be renamed + /// New name for the WebApp + /// This function will return the TrueOnSuccessResponse and a WebApp that only has the information: + /// name which equals the newname + public ApiTrueWithWebAppResponse WebAppRename(string webAppName, string newWebAppName) => WebAppRenameAsync(webAppName, newWebAppName).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.Rename Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that should be renamed + /// New name for the WebApp + /// This function will return the TrueOnSuccessResponse and a copy of the given WebApp that has the change: + /// name which equals the newname + public async Task WebAppRenameAsync(ApiWebAppData webApp, string newWebAppName, CancellationToken cancellationToken = default(CancellationToken)) + { + var resp = await WebAppRenameAsync(webApp.Name, newWebAppName, cancellationToken); + resp.NewWebApp = webApp.ShallowCopy(); + resp.NewWebApp.Name = newWebAppName; + return resp; + } + /// + /// Send a WebApp.Rename Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that should be renamed + /// New name for the WebApp + /// This function will return the TrueOnSuccessResponse and a copy of the given WebApp that has the change: + /// name which equals the newname + public ApiTrueWithWebAppResponse WebAppRename(ApiWebAppData webApp, string newWebAppName) => WebAppRenameAsync(webApp, newWebAppName).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.RenameResource Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that contains the resource + /// Name of the resource that should be renamed + /// New name for the resource + /// This function will return the TrueOnSuccessResponse and a Resource that only has the information: + /// name which equals the newname + public async Task WebAppRenameResourceAsync(string webAppName, string resourceName, + string newResourceName, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebAppRenameResourceRequest(webAppName, resourceName, newResourceName); + string response = await SendPostRequestAsync(req, cancellationToken); + ApiTrueWithResourceResponse responseObj = new ApiTrueWithResourceResponse(); + responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); + if (responseObj.TrueOnSuccesResponse.Result) + { + responseObj.NewResource = new ApiWebAppResource() { Name = newResourceName }; + } + return responseObj; + } + /// + /// Send a WebApp.RenameResource Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that contains the resource + /// Name of the resource that should be renamed + /// New name for the resource + /// This function will return the TrueOnSuccessResponse and a Resource that only has the information: + /// name which equals the newname + public ApiTrueWithResourceResponse WebAppRenameResource(string webAppName, string resourceName, string newResourceName) + => WebAppRenameResourceAsync(webAppName, resourceName, newResourceName).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.RenameResource Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// Name of the resource that should be renamed + /// New name for the resource + /// This function will return the TrueOnSuccessResponse and a Resource that only has the information: + /// name which equals the newname + public async Task WebAppRenameResourceAsync(ApiWebAppData webApp, string resourceName, + string newResourceName, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppRenameResourceAsync(webApp.Name, resourceName, newResourceName, cancellationToken); + } + /// + /// Send a WebApp.RenameResource Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// Name of the resource that should be renamed + /// New name for the resource + /// This function will return the TrueOnSuccessResponse and a Resource that only has the information: + /// name which equals the newname + public ApiTrueWithResourceResponse WebAppRenameResource(ApiWebAppData webApp, string resourceName, string newResourceName) + => WebAppRenameResourceAsync(webApp, resourceName, newResourceName).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.RenameResource Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resource.Name of the resource that should be renamed + /// New name for the resource + /// This function will return the TrueOnSuccessResponse and a copy of the Resource given that has the following change: + /// name which equals the newname + public async Task WebAppRenameResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, + string newResourceName, CancellationToken cancellationToken = default(CancellationToken)) + { + var basicResp = await WebAppRenameResourceAsync(webApp.Name, resource.Name, newResourceName, cancellationToken); + basicResp.NewResource = resource.ShallowCopy(); + basicResp.NewResource.Name = newResourceName; + return basicResp; + } + /// + /// Send a WebApp.RenameResource Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resource.Name of the resource that should be renamed + /// New name for the resource + /// This function will return the TrueOnSuccessResponse and a copy of the Resource given that has the following change: + /// name which equals the newname + public ApiTrueWithResourceResponse WebAppRenameResource(ApiWebAppData webApp, ApiWebAppResource resource, string newResourceName) + => WebAppRenameResourceAsync(webApp, resource, newResourceName).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.RenameResource Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that contains the resource + /// resource.Name of the resource that should be renamed + /// New name for the resource + /// This function will return the TrueOnSuccessResponse and a copy of the Resource given that has the following change: + /// name which equals the newname + public async Task WebAppRenameResourceAsync(string webAppName, ApiWebAppResource resource, + string newResourceName, CancellationToken cancellationToken = default(CancellationToken)) + { + var basicResp = await WebAppRenameResourceAsync(webAppName, resource.Name, newResourceName, cancellationToken); + basicResp.NewResource = resource.ShallowCopy(); + basicResp.NewResource.Name = newResourceName; + return basicResp; + } + /// + /// Send a WebApp.RenameResource Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that contains the resource + /// resource.Name of the resource that should be renamed + /// New name for the resource + /// This function will return the TrueOnSuccessResponse and a copy of the Resource given that has the following change: + /// name which equals the newname + public ApiTrueWithResourceResponse WebAppRenameResource(string webAppName, ApiWebAppResource resource, string newResourceName) + => WebAppRenameResourceAsync(webAppName, resource, newResourceName).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetDefaultPage Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that the default page should be set for + /// Name of the resource that should be the webapps default page + /// This function will return the TrueOnSuccessResponse and webapp containing only the information: + /// Name: which equals the webAppName + /// Default_Page: which equals the resourceName + /// + public async Task WebAppSetDefaultPageAsync(string webAppName, string resourceName, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebAppSetDefaultPageRequest(webAppName, resourceName ?? ""); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = new ApiTrueWithWebAppResponse(); + responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); + if (responseObj.TrueOnSuccesResponse.Result) + { + responseObj.NewWebApp = new ApiWebAppData() { Name = webAppName, Default_page = (resourceName == "" ? null : resourceName) }; + } + return responseObj; + } + /// + /// Send a WebApp.SetDefaultPage Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that the default page should be set for + /// Name of the resource that should be the webapps default page + /// This function will return the TrueOnSuccessResponse and webapp containing only the information: + /// Name: which equals the webAppName + /// Default_Page: which equals the resourceName + /// + public ApiTrueWithWebAppResponse WebAppSetDefaultPage(string webAppName, string resourceName) => WebAppSetDefaultPageAsync(webAppName, resourceName).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetDefaultPage Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that the default page should be set for + /// Name of the resource that should be the webapps default page + /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: + /// Default_Page: which equals the resourceName + /// + public async Task WebAppSetDefaultPageAsync(ApiWebAppData webApp, string resourceName, CancellationToken cancellationToken = default(CancellationToken)) + { + var resp = await WebAppSetDefaultPageAsync(webApp.Name, resourceName, cancellationToken); + resp.NewWebApp = webApp.ShallowCopy(); + resp.NewWebApp.Default_page = (resourceName == "" ? null : resourceName); + return resp; + } + /// + /// Send a WebApp.SetDefaultPage Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that the default page should be set for + /// Name of the resource that should be the webapps default page + /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: + /// Default_Page: which equals the resourceName + /// + public ApiTrueWithWebAppResponse WebAppSetDefaultPage(ApiWebAppData webApp, string resourceName) => WebAppSetDefaultPageAsync(webApp, resourceName).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetDefaultPage Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that the default page should be set for + /// resource.Name of the resource that should be the webapps default page + /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: + /// Default_Page: which equals the resource.Name + /// + public async Task WebAppSetDefaultPageAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) + { + var resp = await WebAppSetDefaultPageAsync(webApp.Name, resource.Name, cancellationToken); + resp.NewWebApp = webApp.ShallowCopy(); + resp.NewWebApp.Default_page = (resource.Name == "" ? null : resource.Name); + return resp; + } + /// + /// Send a WebApp.SetDefaultPage Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that the default page should be set for + /// resource.Name of the resource that should be the webapps default page + /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: + /// Default_Page: which equals the resource.Name + /// + public ApiTrueWithWebAppResponse WebAppSetDefaultPage(ApiWebAppData webApp, ApiWebAppResource resource) => WebAppSetDefaultPageAsync(webApp, resource).GetAwaiter().GetResult(); + /// + /// Send a WebApp.SetDefaultPage Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that the default page should be set for + /// resource.Name of the resource that should be the webapps default page + /// This function will return the TrueOnSuccessResponse and webapp containing only the information: + /// Name: which equals the webAppName + /// Default_Page: which equals the resourceName + /// + public async Task WebAppSetDefaultPageAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppSetDefaultPageAsync(webAppName, resource.Name, cancellationToken); + } + /// + /// Send a WebApp.SetDefaultPage Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that the default page should be set for + /// resource.Name of the resource that should be the webapps default page + /// This function will return the TrueOnSuccessResponse and webapp containing only the information: + /// Name: which equals the webAppName + /// Default_Page: which equals the resourceName + /// + public ApiTrueWithWebAppResponse WebAppSetDefaultPage(string webAppName, ApiWebAppResource resource) => WebAppSetDefaultPageAsync(webAppName, resource).GetAwaiter().GetResult(); - /// - /// Send a PlcProgram.Read Request using the Request from the ApiRequestFactory - /// - /// Name of the variable to be read - /// - /// Name der zu lesenden Variable - /// - /// this parameter is optional and defaults to "simple": - /// "simple" will get the variable values according to the presentation of the manual - "supported Datatypes" - /// "raw" : will get the variable values according to the presentation of the manual "raw" - /// - /// Aufzählung, die das Antwortformat für diese Methode festlegt: - /// • "simple": liefert Variablenwerte gemäß der Darstellung - /// "simple" in Kapitel "Unterstützte Datentypen (Seite 162)" - /// • "raw": liefert Variablenwerte gemäß der Darstellung "raw" - /// in Kapitel "Unterstützte Datentypen" - /// ApiPlcProgramReadResponse: object with the value for the variables value to be read - public async Task> PlcProgramReadAsync(string var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null) - { - var req = _apiRequestFactory.GetApiPlcProgramReadRequest(var, plcProgramReadMode); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject>(response); - return responseObj; - } - /// - /// Send a PlcProgram.Read Request using the Request from the ApiRequestFactory - /// - /// Name of the variable to be read - /// - /// Name der zu lesenden Variable - /// - /// this parameter is optional and defaults to "simple": - /// "simple" will get the variable values according to the presentation of the manual - "supported Datatypes" - /// "raw" : will get the variable values according to the presentation of the manual "raw" - /// - /// Aufzählung, die das Antwortformat für diese Methode festlegt: - /// • "simple": liefert Variablenwerte gemäß der Darstellung - /// "simple" in Kapitel "Unterstützte Datentypen (Seite 162)" - /// • "raw": liefert Variablenwerte gemäß der Darstellung "raw" - /// in Kapitel "Unterstützte Datentypen" - /// ApiPlcProgramReadResponse: object with the value for the variables value to be read - public ApiResultResponse PlcProgramRead(ApiPlcProgramData var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null) => PlcProgramReadAsync(var, plcProgramReadMode).GetAwaiter().GetResult(); - - /// - /// Send a PlcProgram.Browse Request using the Request from the ApiRequestFactory - /// This function will build up the name with quotes from the parents given with the ApiPlcProgramDataand call PlcProgramRead - /// - /// - /// Name of the variable to be read - /// Name der zu lesenden Variable - /// - /// this parameter is optional and defaults to "simple": - /// "simple" will get the variable values according to the presentation of the manual - "supported Datatypes" - /// "raw" : will get the variable values according to the presentation of the manual "raw" - /// - /// Aufzählung, die das Antwortformat für diese Methode festlegt: - /// • "simple": liefert Variablenwerte gemäß der Darstellung - /// "simple" in Kapitel "Unterstützte Datentypen (Seite 162)" - /// • "raw": liefert Variablenwerte gemäß der Darstellung "raw" - /// in Kapitel "Unterstützte Datentypen" - /// ApiPlcProgramReadResponse: object with the value for the variables value to be read - /// will be thrown if a ApiPlcProgramDatathat is an array will be given without an index - public async Task> PlcProgramReadAsync(ApiPlcProgramData var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null) - { - //RequestParameterChecker.CheckPlcProgramReadOrWriteDataType(var.Datatype, true); - string varName = var.GetVarNameForMethods(); - return await PlcProgramReadAsync(varName, plcProgramReadMode); - } - /// - /// Send a PlcProgram.Browse Request using the Request from the ApiRequestFactory - /// This function will build up the name with quotes from the parents given with the ApiPlcProgramDataand call PlcProgramRead - /// - /// - /// Name of the variable to be read - /// Name der zu lesenden Variable - /// - /// this parameter is optional and defaults to "simple": - /// "simple" will get the variable values according to the presentation of the manual - "supported Datatypes" - /// "raw" : will get the variable values according to the presentation of the manual "raw" - /// - /// Aufzählung, die das Antwortformat für diese Methode festlegt: - /// • "simple": liefert Variablenwerte gemäß der Darstellung - /// "simple" in Kapitel "Unterstützte Datentypen (Seite 162)" - /// • "raw": liefert Variablenwerte gemäß der Darstellung "raw" - /// in Kapitel "Unterstützte Datentypen" - /// ApiPlcProgramReadResponse: object with the value for the variables value to be read - /// will be thrown if a ApiPlcProgramDatathat is an array will be given without an index - public ApiResultResponse PlcProgramRead(string var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null) => PlcProgramReadAsync(var, plcProgramReadMode).GetAwaiter().GetResult(); - - /// - /// Send a PlcProgram.Write Request using the Request from the ApiRequestFactory - /// This function will build up the name with quotes from the parents given with the ApiPlcProgramDataand call PlcProgramWrite - /// - /// - /// Name of the variable to be read - /// Name der zu lesenden Variable - /// - /// - /// true to indicate success - /// will be thrown if a ApiPlcProgramDatathat is an array will be given without an index - public async Task PlcProgramWriteAsync(ApiPlcProgramData var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null) - { - string varName = var.GetVarNameForMethods(); - // ApiRequestFactory.CheckPlcProgramReadOrWriteDataType(var.Datatype); will also be called by GetApiPlcProgramWriteValueToBeSet! - var writeVal = _apiRequestFactory.GetApiPlcProgramWriteValueToBeSet(var.Datatype, valueToBeSet); - return await PlcProgramWriteAsync(varName, writeVal, plcProgramWriteMode); - } - /// - /// Send a PlcProgram.Write Request using the Request from the ApiRequestFactory - /// This function will build up the name with quotes from the parents given with the ApiPlcProgramDataand call PlcProgramWrite - /// - /// - /// Name of the variable to be read - /// Name der zu lesenden Variable - /// - /// - /// true to indicate success - /// will be thrown if a ApiPlcProgramDatathat is an array will be given without an index - public ApiTrueOnSuccessResponse PlcProgramWrite(ApiPlcProgramData var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null) - => PlcProgramWriteAsync(var, valueToBeSet, plcProgramWriteMode).GetAwaiter().GetResult(); - - /// - /// Send a PlcProgram.Write Request using the Request from the ApiRequestFactory - /// - /// - /// Name of the variable to be read - /// Name der zu lesenden Variable - /// - /// - /// true to indicate success - /// will be thrown if a ApiPlcProgramDatathat is an array will be given without an index - public async Task PlcProgramWriteAsync(string var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null) - { - var req = _apiRequestFactory.GetApiPlcProgramWriteRequest(var, valueToBeSet, plcProgramWriteMode); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); - return responseObj; - } - /// - /// Send a PlcProgram.Write Request using the Request from the ApiRequestFactory - /// - /// - /// Name of the variable to be read - /// Name der zu lesenden Variable - /// - /// - /// true to indicate success - /// will be thrown if a ApiPlcProgramDatathat is an array will be given without an index - public ApiTrueOnSuccessResponse PlcProgramWrite(string var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null) - => PlcProgramWriteAsync(var, valueToBeSet, plcProgramWriteMode).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.Browse Request using the Request from the ApiRequestFactory - /// - /// webappdata that should be requested - /// ApiWebAppBrowseResponse: Containing WebAppBrowseResult: Max_Applications:uint, - /// Applications: Array of ApiWebAppdata containing one element: the webappdata that has been requested - public async Task WebAppBrowseAsync(ApiWebAppData webAppData) - { - return await WebAppBrowseAsync(webAppData.Name); - } - /// - /// Send a WebApp.Browse Request using the Request from the ApiRequestFactory - /// - /// webappdata that should be requested - /// ApiWebAppBrowseResponse: Containing WebAppBrowseResult: Max_Applications:uint, - /// Applications: Array of ApiWebAppdata containing one element: the webappdata that has been requested - public ApiWebAppBrowseResponse WebAppBrowse(ApiWebAppData webAppData) => WebAppBrowseAsync(webAppData).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.Browse Request using the Request from the ApiRequestFactory - /// - /// webapp name in case only one is requested - /// ApiWebAppBrowseResponse: Containing WebAppBrowseResult: Max_Applications:uint, - /// Applications: Array of ApiWebAppdata containing one element: the webappdata that has been requested - public async Task WebAppBrowseAsync(string webAppName = null) - { - var req = _apiRequestFactory.GetApiWebAppBrowseRequest(webAppName); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); - return responseObj; - } - /// - /// Send a WebApp.Browse Request using the Request from the ApiRequestFactory - /// - /// webapp name in case only one is requested - /// ApiWebAppBrowseResponse: Containing WebAppBrowseResult: Max_Applications:uint, - /// Applications: Array of ApiWebAppdata containing one element: the webappdata that has been requested - public ApiWebAppBrowseResponse WebAppBrowse(string webAppName = null) => WebAppBrowseAsync(webAppName).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.BrowseResources Request using the Request from the ApiRequestFactory - /// Will return the Api Response "straight away" - /// A user can use the List of ApiWebAppResources to set those to an ApiWebAppData - /// (care to also add those who are protected to the protected resources in case you want to do that) - /// - /// WebApp name to browse resources of - /// If given only that resource will be inside the array (in case it exists) - /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, - /// Resources:Array of ApiWebAppResource (only 1 if one is requested) - public async Task WebAppBrowseResourcesAsync(string webAppName, string resourceName = null) - { - var req = _apiRequestFactory.GetApiWebAppBrowseResourcesRequest(webAppName, resourceName); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); - return responseObj; - } - /// - /// Send a WebApp.BrowseResources Request using the Request from the ApiRequestFactory - /// Will return the Api Response "straight away" - /// A user can use the List of ApiWebAppResources to set those to an ApiWebAppData - /// (care to also add those who are protected to the protected resources in case you want to do that) - /// - /// WebApp name to browse resources of - /// If given only that resource will be inside the array (in case it exists) - /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, - /// Resources:Array of ApiWebAppResource (only 1 if one is requested) - public ApiWebAppBrowseResourcesResponse WebAppBrowseResources(string webAppName, string resourceName = null) => WebAppBrowseResourcesAsync(webAppName, resourceName).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.BrowseResources Request using the Request from the ApiRequestFactory - /// Will return the Api Response "straight away" - /// A user can use the List of ApiWebAppResources to set those to an ApiWebAppData - /// (care to also add those who are protected to the protected resources in case you want to do that) - /// - /// WebApp.Name to browse resources of - /// If given only that resource will be inside the array (in case it exists) - /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, - /// Resources:Array of ApiWebAppResource (only 1 if one is requested) - public async Task WebAppBrowseResourcesAsync(ApiWebAppData webApp, string resourceName = null) - { - return await WebAppBrowseResourcesAsync(webApp.Name, resourceName); - } - /// - /// Send a WebApp.BrowseResources Request using the Request from the ApiRequestFactory - /// Will return the Api Response "straight away" - /// A user can use the List of ApiWebAppResources to set those to an ApiWebAppData - /// (care to also add those who are protected to the protected resources in case you want to do that) - /// - /// WebApp.Name to browse resources of - /// If given only that resource will be inside the array (in case it exists) - /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, - /// Resources:Array of ApiWebAppResource (only 1 if one is requested) - public ApiWebAppBrowseResourcesResponse WebAppBrowseResources(ApiWebAppData webApp, string resourceName = null) => WebAppBrowseResourcesAsync(webApp, resourceName).GetAwaiter().GetResult(); - /// - /// Send a WebApp.BrowseResources Request using the Request from the ApiRequestFactory - /// Will return the Api Response "straight away" - /// A user can use the List of ApiWebAppResources to set those to an ApiWebAppData - /// (care to also add those who are protected to the protected resources in case you want to do that) - /// - /// WebApp Name to browse resources of - /// resource.Name to browse for - /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, - /// Resources:Array of ApiWebAppResource (only 1 if one is requested) - public async Task WebAppBrowseResourcesAsync(string webAppName, ApiWebAppResource resource) - { - return await WebAppBrowseResourcesAsync(webAppName, resource.Name); - } - /// - /// Send a WebApp.BrowseResources Request using the Request from the ApiRequestFactory - /// Will return the Api Response "straight away" - /// A user can use the List of ApiWebAppResources to set those to an ApiWebAppData - /// (care to also add those who are protected to the protected resources in case you want to do that) - /// - /// WebApp Name to browse resources of - /// resource.Name to browse for - /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, - /// Resources:Array of ApiWebAppResource (only 1 if one is requested) - public ApiWebAppBrowseResourcesResponse WebAppBrowseResources(string webAppName, ApiWebAppResource resource) => WebAppBrowseResourcesAsync(webAppName, resource).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.BrowseResources Request using the Request from the ApiRequestFactory - /// Will return the Api Response "straight away" - /// A user can use the List of ApiWebAppResources to set those to an ApiWebAppData - /// (care to also add those who are protected to the protected resources in case you want to do that) - /// - /// webApp.Name to browse resources of - /// resource.Name to browse for - /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, - /// Resources:Array of ApiWebAppResource (only 1 if one is requested) - public async Task WebAppBrowseResourcesAsync(ApiWebAppData webApp, ApiWebAppResource resource) - { - return await WebAppBrowseResourcesAsync(webApp.Name, resource.Name); - } - /// - /// Send a WebApp.BrowseResources Request using the Request from the ApiRequestFactory - /// Will return the Api Response "straight away" - /// A user can use the List of ApiWebAppResources to set those to an ApiWebAppData - /// (care to also add those who are protected to the protected resources in case you want to do that) - /// - /// webApp.Name to browse resources of - /// resource.Name to browse for - /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, - /// Resources:Array of ApiWebAppResource (only 1 if one is requested) - public ApiWebAppBrowseResourcesResponse WebAppBrowseResources(ApiWebAppData webApp, ApiWebAppResource resource) => WebAppBrowseResourcesAsync(webApp, resource).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.Create Request using the Request from the ApiRequestFactory - /// - /// webapp name for the app to be created - /// optional parameter: state the webapp should be in - /// true to indicate success - public async Task WebAppCreateAsync(string webAppName, ApiWebAppState? apiWebAppState = null) - { - var req = _apiRequestFactory.GetApiWebAppCreateRequest(webAppName, apiWebAppState); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); - return responseObj; - } - /// - /// Send a WebApp.Create Request using the Request from the ApiRequestFactory - /// - /// webapp name for the app to be created - /// optional parameter: state the webapp should be in - /// true to indicate success - public ApiTrueOnSuccessResponse WebAppCreate(string webAppName, ApiWebAppState? apiWebAppState = null) => WebAppCreateAsync(webAppName, apiWebAppState).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.Create Request using the Request from the ApiRequestFactory - /// - /// containing information about name and state for the app to be created - /// true to indicate success - public async Task WebAppCreateAsync(ApiWebAppData webApp) - { - // ApiRequestFactory.CheckState(webApp.State); will be called in WebAppCreate in Factory.GetApiWebAppCreateRequest - return await WebAppCreateAsync(webApp.Name, webApp.State); - } - /// - /// Send a WebApp.Create Request using the Request from the ApiRequestFactory - /// - /// containing information about name and state for the app to be created - /// true to indicate success - public ApiTrueOnSuccessResponse WebAppCreate(ApiWebAppData webApp) => WebAppCreateAsync(webApp).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.CreateResource Request using the Request from the ApiRequestFactory - /// - /// name of the webapp to create the resource on - /// resource name to be created with (typically provided with extension) - /// resource media type - see MIMEType.mapping - /// Be sure to provide the RFC3339 format! - /// resource visibility (protect your confidential data) - /// you can provide an etag as identification,... for your resource - /// TicketId for the Ticketing Endpoint to perform the Upload on - public async Task WebAppCreateResourceAsync(string webAppName, string resourceName, string media_type, - string last_modified, ApiWebAppResourceVisibility? apiWebAppResourceVisibility = null, string etag = null) - { - var req = _apiRequestFactory.GetApiWebAppCreateResourceRequest(webAppName, resourceName, media_type, - last_modified, apiWebAppResourceVisibility, etag); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); - return responseObj; - } - /// - /// Send a WebApp.CreateResource Request using the Request from the ApiRequestFactory - /// - /// name of the webapp to create the resource on - /// resource name to be created with (typically provided with extension) - /// resource media type - see MIMEType.mapping - /// Be sure to provide the RFC3339 format! - /// resource visibility (protect your confidential data) - /// you can provide an etag as identification,... for your resource - /// TicketId for the Ticketing Endpoint to perform the Upload on - public ApiTicketIdResponse WebAppCreateResource(string webAppName, string resourceName, string media_type, string last_modified, ApiWebAppResourceVisibility? apiWebAppResourceVisibility = null, string etag = null) - => WebAppCreateResourceAsync(webAppName, resourceName, media_type, last_modified, apiWebAppResourceVisibility, etag).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.CreateResource Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp to create the resource on - /// resource name to be created with (typically provided with extension) - /// resource media type - see MIMEType.mapping - /// Be sure to provide the RFC3339 format! - /// resource visibility (protect your confidential data) - /// you can provide an etag as identification,... for your resource - /// TicketId for the Ticketing Endpoint to perform the Upload on - public async Task WebAppCreateResourceAsync(ApiWebAppData webApp, string resourceName, string media_type, - string last_modified, ApiWebAppResourceVisibility? apiWebAppResourceVisibility = null, string etag = null) - { - return await WebAppCreateResourceAsync(webApp.Name, resourceName, media_type, last_modified, apiWebAppResourceVisibility, etag); - } - /// - /// Send a WebApp.CreateResource Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp to create the resource on - /// resource name to be created with (typically provided with extension) - /// resource media type - see MIMEType.mapping - /// Be sure to provide the RFC3339 format! - /// resource visibility (protect your confidential data) - /// you can provide an etag as identification,... for your resource - /// TicketId for the Ticketing Endpoint to perform the Upload on - public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, string resourceName, string media_type, string last_modified, ApiWebAppResourceVisibility? apiWebAppResourceVisibility = null, string etag = null) - => WebAppCreateResourceAsync(webApp, resourceName, media_type, last_modified, apiWebAppResourceVisibility, etag).GetAwaiter().GetResult(); - /// - /// Send a WebApp.CreateResource Request using the Request from the ApiRequestFactory - /// - /// name of the webapp to create the resource on - /// resource containing all the information: - /// Name: name to be created with (typically provided with extension) - /// Media_type: resource media type - see MIMEType.mapping - /// Last_modified: Be sure to provide the RFC3339 format! - /// Visibility: resource visibility (protect your confidential data) - /// Etag: you can provide an etag as identification,... for your resource - /// TicketId for the Ticketing Endpoint to perform the Upload on - public async Task WebAppCreateResourceAsync(string webAppName, ApiWebAppResource resource) - { - return await WebAppCreateResourceAsync(webAppName, resource.Name, resource.Media_type, - resource.Last_modified.ToString(DateTimeFormatting.ApiDateTimeFormat), resource.Visibility, resource.Etag); - } - /// - /// Send a WebApp.CreateResource Request using the Request from the ApiRequestFactory - /// - /// name of the webapp to create the resource on - /// resource containing all the information: - /// Name: name to be created with (typically provided with extension) - /// Media_type: resource media type - see MIMEType.mapping - /// Last_modified: Be sure to provide the RFC3339 format! - /// Visibility: resource visibility (protect your confidential data) - /// Etag: you can provide an etag as identification,... for your resource - /// TicketId for the Ticketing Endpoint to perform the Upload on - public ApiTicketIdResponse WebAppCreateResource(string webAppName, ApiWebAppResource resource) => WebAppCreateResourceAsync(webAppName, resource).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.CreateResource Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp to create the resource on - /// resource containing all the information: - /// Name: name to be created with (typically provided with extension) - /// Media_type: resource media type - see MIMEType.mapping - /// Last_modified: Be sure to provide the RFC3339 format! - /// Visibility: resource visibility (protect your confidential data) - /// Etag: you can provide an etag as identification,... for your resource - /// TicketId for the Ticketing Endpoint to perform the Upload on - public async Task WebAppCreateResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource) - { - return await WebAppCreateResourceAsync(webApp.Name, resource.Name, resource.Media_type, - resource.Last_modified.ToString(DateTimeFormatting.ApiDateTimeFormat), resource.Visibility, resource.Etag); - } - /// - /// Send a WebApp.CreateResource Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp to create the resource on - /// resource containing all the information: - /// Name: name to be created with (typically provided with extension) - /// Media_type: resource media type - see MIMEType.mapping - /// Last_modified: Be sure to provide the RFC3339 format! - /// Visibility: resource visibility (protect your confidential data) - /// Etag: you can provide an etag as identification,... for your resource - /// TicketId for the Ticketing Endpoint to perform the Upload on - public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, ApiWebAppResource resource) => WebAppCreateResourceAsync(webApp, resource).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.Delete Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp to delete - /// true to indicate success - public async Task WebAppDeleteAsync(string webAppName) - { - var req = _apiRequestFactory.GetApiWebAppDeleteRequest(webAppName); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); - return responseObj; - } - /// - /// Send a WebApp.Delete Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp to delete - /// true to indicate success - public ApiTrueOnSuccessResponse WebAppDelete(string webAppName) => WebAppDeleteAsync(webAppName).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.Delete Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp to delete - /// true to indicate success - public async Task WebAppDeleteAsync(ApiWebAppData webApp) - { - return await WebAppDeleteAsync(webApp.Name); - } - /// - /// Send a WebApp.Delete Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp to delete - /// true to indicate success - public ApiTrueOnSuccessResponse WebAppDelete(ApiWebAppData webApp) => WebAppDeleteAsync(webApp).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.DeleteRespource Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that contains the resource - /// Name of the resource to delete - /// true to indicate success - public async Task WebAppDeleteResourceAsync(string webAppName, string resourceName) - { - var req = _apiRequestFactory.GetApiWebAppDeleteResourceRequest(webAppName, resourceName); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); - return responseObj; - } - /// - /// Send a WebApp.DeleteRespource Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that contains the resource - /// Name of the resource to delete - /// true to indicate success - public ApiTrueOnSuccessResponse WebAppDeleteResource(string webAppName, string resourceName) => WebAppDeleteResourceAsync(webAppName, resourceName).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.DeleteRespource Request using the Request from the ApiRequestFactory - /// - /// webapp.Name of the webapp that contains the resource - /// Name of the resource to delete - /// true to indicate success - public async Task WebAppDeleteResourceAsync(ApiWebAppData webApp, string resourceName) - { - return await WebAppDeleteResourceAsync(webApp.Name, resourceName); - } - /// - /// Send a WebApp.DeleteRespource Request using the Request from the ApiRequestFactory - /// - /// webapp.Name of the webapp that contains the resource - /// Name of the resource to delete - /// true to indicate success - public ApiTrueOnSuccessResponse WebAppDeleteResource(ApiWebAppData webApp, string resourceName) => WebAppDeleteResourceAsync(webApp, resourceName).GetAwaiter().GetResult(); - /// - /// Send a WebApp.DeleteRespource Request using the Request from the ApiRequestFactory - /// - /// webapp.Name of the webapp that contains the resource - /// Name of the resource to delete - /// true to indicate success - public ApiTrueOnSuccessResponse WebAppDeleteResource(string webAppName, ApiWebAppResource resource) => WebAppDeleteResourceAsync(webAppName, resource).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.DeleteRespource Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resource.Name of the resource to delete - /// true to indicate success - public async Task WebAppDeleteResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource) - { - return await WebAppDeleteResourceAsync(webApp.Name, resource.Name); - } - /// - /// Send a WebApp.DeleteRespource Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resource.Name of the resource to delete - /// true to indicate success - public ApiTrueOnSuccessResponse WebAppDeleteResource(ApiWebAppData webApp, ApiWebAppResource resource) => WebAppDeleteResourceAsync(webApp, resource).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.DeleteRespource Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that contains the resource - /// resource.Name of the resource to delete - /// true to indicate success - public async Task WebAppDeleteResourceAsync(string webAppName, ApiWebAppResource resource) - { - return await WebAppDeleteResourceAsync(webAppName, resource.Name); - } - - /// - /// Send a WebApp.DownloadResource Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that contains the resource - /// Name of the resource to download - /// Ticket id for Ticketing Endpoint to trigger the download on - public async Task WebAppDownloadResourceAsync(string webAppName, string resourceName) - { - var req = _apiRequestFactory.GetApiWebAppDownloadResourceRequest(webAppName, resourceName); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); - return responseObj; - } - /// - /// Send a WebApp.DownloadResource Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that contains the resource - /// Name of the resource to download - /// Ticket id for Ticketing Endpoint to trigger the download on - public ApiTicketIdResponse WebAppDownloadResource(string webAppName, string resourceName) => WebAppDownloadResourceAsync(webAppName, resourceName).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.DownloadResource Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// Name of the resource to download - /// Ticket id for Ticketing Endpoint to trigger the download on - public async Task WebAppDownloadResourceAsync(ApiWebAppData webApp, string resourceName) - { - return await WebAppDownloadResourceAsync(webApp.Name, resourceName); - } - /// - /// Send a WebApp.DownloadResource Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// Name of the resource to download - /// Ticket id for Ticketing Endpoint to trigger the download on - public ApiTicketIdResponse WebAppDownloadResource(ApiWebAppData webApp, string resourceName) => WebAppDownloadResourceAsync(webApp, resourceName).GetAwaiter().GetResult(); + /// + /// Send a WebApp.SetNotAuthorizedPage Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that the not authorized page should be set for + /// Name of the resource that should be the webapps not authorized page + /// This function will return the TrueOnSuccessResponse and webapp containing only the information: + /// Name: which equals webAppName + /// Not_authorized_page: which equals the resourceName + /// + public async Task WebAppSetNotAuthorizedPageAsync(string webAppName, string resourceName, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebAppSetNotAuthorizedPageRequest(webAppName, resourceName ?? ""); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = new ApiTrueWithWebAppResponse(); + responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); + if (responseObj.TrueOnSuccesResponse.Result) + { + responseObj.NewWebApp = new ApiWebAppData() { Name = webAppName, Not_authorized_page = (resourceName == "" ? null : resourceName) }; + } + return responseObj; + } + /// + /// Send a WebApp.SetNotAuthorizedPage Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that the not authorized page should be set for + /// Name of the resource that should be the webapps not authorized page + /// This function will return the TrueOnSuccessResponse and webapp containing only the information: + /// Name: which equals webAppName + /// Not_authorized_page: which equals the resourceName + /// + public ApiTrueWithWebAppResponse WebAppSetNotAuthorizedPage(string webAppName, string resourceName) => WebAppSetNotAuthorizedPageAsync(webAppName, resourceName).GetAwaiter().GetResult(); + /// + /// Send a WebApp.SetNotAuthorizedPage Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that the not authorized page should be set for + /// Name of the resource that should be the webapps not authorized page + /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: + /// Not_authorized_page: which equals the resourceName + /// + public async Task WebAppSetNotAuthorizedPageAsync(ApiWebAppData webApp, string resourceName, CancellationToken cancellationToken = default(CancellationToken)) + { + var resp = await WebAppSetNotAuthorizedPageAsync(webApp.Name, resourceName, cancellationToken); + resp.NewWebApp = webApp.ShallowCopy(); + resp.NewWebApp.Not_authorized_page = (resourceName == "" ? null : resourceName); + return resp; + } + /// + /// Send a WebApp.SetNotAuthorizedPage Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that the not authorized page should be set for + /// Name of the resource that should be the webapps not authorized page + /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: + /// Not_authorized_page: which equals the resourceName + /// + public ApiTrueWithWebAppResponse WebAppSetNotAuthorizedPage(ApiWebAppData webApp, string resourceName) => WebAppSetNotAuthorizedPageAsync(webApp, resourceName).GetAwaiter().GetResult(); + /// + /// Send a WebApp.SetNotAuthorizedPage Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that the not authorized page should be set for + /// resource.Name of the resource that should be the webapps not authorized page + /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: + /// Not_authorized_page: which equals the resourceName + /// + public async Task WebAppSetNotAuthorizedPageAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) + { + var resp = await WebAppSetNotAuthorizedPageAsync(webApp.Name, resource.Name, cancellationToken); + resp.NewWebApp = webApp.ShallowCopy(); + resp.NewWebApp.Not_authorized_page = (resource.Name == "" ? null : resource.Name); + return resp; + } + /// + /// Send a WebApp.SetNotAuthorizedPage Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that the not authorized page should be set for + /// resource.Name of the resource that should be the webapps not authorized page + /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: + /// Not_authorized_page: which equals the resourceName + /// + public ApiTrueWithWebAppResponse WebAppSetNotAuthorizedPage(ApiWebAppData webApp, ApiWebAppResource resource) => WebAppSetNotAuthorizedPageAsync(webApp, resource).GetAwaiter().GetResult(); - /// - /// Send a WebApp.DownloadResource Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resource.Name of the resource to download - /// Ticket id for Ticketing Endpoint to trigger the download on - public async Task WebAppDownloadResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource) - { - return await WebAppDownloadResourceAsync(webApp.Name, resource.Name); - } - /// - /// Send a WebApp.DownloadResource Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resource.Name of the resource to download - /// Ticket id for Ticketing Endpoint to trigger the download on - public ApiTicketIdResponse WebAppDownloadResource(ApiWebAppData webApp, ApiWebAppResource resource) => WebAppDownloadResourceAsync(webApp, resource).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.DownloadResource Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that contains the resource - /// resource.Name of the resource to download - /// Ticket id for Ticketing Endpoint to trigger the download on - public async Task WebAppDownloadResourceAsync(string webAppName, ApiWebAppResource resource) - { - return await WebAppDownloadResourceAsync(webAppName, resource.Name); - } - /// - /// Send a WebApp.DownloadResource Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that contains the resource - /// resource.Name of the resource to download - /// Ticket id for Ticketing Endpoint to trigger the download on - public ApiTicketIdResponse WebAppDownloadResource(string webAppName, ApiWebAppResource resource) => WebAppDownloadResourceAsync(webAppName, resource).GetAwaiter().GetResult(); + /// + /// Send a WebApp.SetNotAuthorizedPage Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that the not authorized page should be set for + /// resource.Name of the resource that should be the webapps not authorized page + /// This function will return the TrueOnSuccessResponse and webapp containing only the information: + /// Name: which equals webAppName + /// Not_authorized_page: which equals the resource.Name + /// + public async Task WebAppSetNotAuthorizedPageAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppSetNotAuthorizedPageAsync(webAppName, resource.Name, cancellationToken); + } + /// + /// Send a WebApp.SetNotAuthorizedPage Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that the not authorized page should be set for + /// resource.Name of the resource that should be the webapps not authorized page + /// This function will return the TrueOnSuccessResponse and webapp containing only the information: + /// Name: which equals webAppName + /// Not_authorized_page: which equals the resource.Name + /// + public ApiTrueWithWebAppResponse WebAppSetNotAuthorizedPage(string webAppName, ApiWebAppResource resource) => WebAppSetNotAuthorizedPageAsync(webAppName, resource).GetAwaiter().GetResult(); - /// - /// Send a WebApp.Rename Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that should be renamed - /// New name for the WebApp - /// This function will return the TrueOnSuccessResponse and a WebApp that only has the information: - /// name which equals the newname - public async Task WebAppRenameAsync(string webAppName, string newWebAppName) - { - var req = _apiRequestFactory.GetApiWebAppRenameRequest(webAppName, newWebAppName); - string response = await SendPostRequestAsync(req); - var responseObj = new ApiTrueWithWebAppResponse(); - responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); - if (responseObj.TrueOnSuccesResponse.Result) - { - responseObj.NewWebApp = new ApiWebAppData() { Name = newWebAppName }; - } - return responseObj; - } - /// - /// Send a WebApp.Rename Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that should be renamed - /// New name for the WebApp - /// This function will return the TrueOnSuccessResponse and a WebApp that only has the information: - /// name which equals the newname - public ApiTrueWithWebAppResponse WebAppRename(string webAppName, string newWebAppName) => WebAppRenameAsync(webAppName, newWebAppName).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.Rename Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that should be renamed - /// New name for the WebApp - /// This function will return the TrueOnSuccessResponse and a copy of the given WebApp that has the change: - /// name which equals the newname - public async Task WebAppRenameAsync(ApiWebAppData webApp, string newWebAppName) - { - var resp = await WebAppRenameAsync(webApp.Name, newWebAppName); - resp.NewWebApp = webApp.ShallowCopy(); - resp.NewWebApp.Name = newWebAppName; - return resp; - } - /// - /// Send a WebApp.Rename Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that should be renamed - /// New name for the WebApp - /// This function will return the TrueOnSuccessResponse and a copy of the given WebApp that has the change: - /// name which equals the newname - public ApiTrueWithWebAppResponse WebAppRename(ApiWebAppData webApp, string newWebAppName) => WebAppRenameAsync(webApp, newWebAppName).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.RenameResource Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that contains the resource - /// Name of the resource that should be renamed - /// New name for the resource - /// This function will return the TrueOnSuccessResponse and a Resource that only has the information: - /// name which equals the newname - public async Task WebAppRenameResourceAsync(string webAppName, string resourceName, - string newResourceName) - { - var req = _apiRequestFactory.GetApiWebAppRenameResourceRequest(webAppName, resourceName, newResourceName); - string response = await SendPostRequestAsync(req); - ApiTrueWithResourceResponse responseObj = new ApiTrueWithResourceResponse(); - responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); - if (responseObj.TrueOnSuccesResponse.Result) - { - responseObj.NewResource = new ApiWebAppResource() { Name = newResourceName }; - } - return responseObj; - } - /// - /// Send a WebApp.RenameResource Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that contains the resource - /// Name of the resource that should be renamed - /// New name for the resource - /// This function will return the TrueOnSuccessResponse and a Resource that only has the information: - /// name which equals the newname - public ApiTrueWithResourceResponse WebAppRenameResource(string webAppName, string resourceName, string newResourceName) - => WebAppRenameResourceAsync(webAppName, resourceName, newResourceName).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.RenameResource Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// Name of the resource that should be renamed - /// New name for the resource - /// This function will return the TrueOnSuccessResponse and a Resource that only has the information: - /// name which equals the newname - public async Task WebAppRenameResourceAsync(ApiWebAppData webApp, string resourceName, - string newResourceName) - { - return await WebAppRenameResourceAsync(webApp.Name, resourceName, newResourceName); - } - /// - /// Send a WebApp.RenameResource Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// Name of the resource that should be renamed - /// New name for the resource - /// This function will return the TrueOnSuccessResponse and a Resource that only has the information: - /// name which equals the newname - public ApiTrueWithResourceResponse WebAppRenameResource(ApiWebAppData webApp, string resourceName, string newResourceName) - => WebAppRenameResourceAsync(webApp, resourceName, newResourceName).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.RenameResource Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resource.Name of the resource that should be renamed - /// New name for the resource - /// This function will return the TrueOnSuccessResponse and a copy of the Resource given that has the following change: - /// name which equals the newname - public async Task WebAppRenameResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, - string newResourceName) - { - var basicResp = await WebAppRenameResourceAsync(webApp.Name, resource.Name, newResourceName); - basicResp.NewResource = resource.ShallowCopy(); - basicResp.NewResource.Name = newResourceName; - return basicResp; - } - /// - /// Send a WebApp.RenameResource Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resource.Name of the resource that should be renamed - /// New name for the resource - /// This function will return the TrueOnSuccessResponse and a copy of the Resource given that has the following change: - /// name which equals the newname - public ApiTrueWithResourceResponse WebAppRenameResource(ApiWebAppData webApp, ApiWebAppResource resource, string newResourceName) - => WebAppRenameResourceAsync(webApp, resource, newResourceName).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.RenameResource Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that contains the resource - /// resource.Name of the resource that should be renamed - /// New name for the resource - /// This function will return the TrueOnSuccessResponse and a copy of the Resource given that has the following change: - /// name which equals the newname - public async Task WebAppRenameResourceAsync(string webAppName, ApiWebAppResource resource, - string newResourceName) - { - var basicResp = await WebAppRenameResourceAsync(webAppName, resource.Name, newResourceName); - basicResp.NewResource = resource.ShallowCopy(); - basicResp.NewResource.Name = newResourceName; - return basicResp; - } - /// - /// Send a WebApp.RenameResource Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that contains the resource - /// resource.Name of the resource that should be renamed - /// New name for the resource - /// This function will return the TrueOnSuccessResponse and a copy of the Resource given that has the following change: - /// name which equals the newname - public ApiTrueWithResourceResponse WebAppRenameResource(string webAppName, ApiWebAppResource resource, string newResourceName) - => WebAppRenameResourceAsync(webAppName, resource, newResourceName).GetAwaiter().GetResult(); + /// + /// Send a WebApp.SetNotFoundPage Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that the not found page should be set for + /// Name of the resource that should be the webapps not found page + /// This function will return the TrueOnSuccessResponse and webapp containing only the information: + /// Name: which equals the webAppName + /// Not_found_page: which equals the resourceName + /// + public async Task WebAppSetNotFoundPageAsync(string webAppName, string resourceName, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebAppSetNotFoundPageRequest(webAppName, resourceName ?? ""); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = new ApiTrueWithWebAppResponse(); + responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); + if (responseObj.TrueOnSuccesResponse.Result) + { + responseObj.NewWebApp = new ApiWebAppData() { Name = webAppName, Not_found_page = (resourceName == "" ? null : resourceName) }; + } + return responseObj; + } + /// + /// Send a WebApp.SetNotFoundPage Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that the not found page should be set for + /// Name of the resource that should be the webapps not found page + /// This function will return the TrueOnSuccessResponse and webapp containing only the information: + /// Name: which equals the webAppName + /// Not_found_page: which equals the resourceName + /// + public ApiTrueWithWebAppResponse WebAppSetNotFoundPage(string webAppName, string resourceName) => WebAppSetNotFoundPageAsync(webAppName, resourceName).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetNotFoundPage Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that the not found page should be set for + /// Name of the resource that should be the webapps not found page + /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: + /// Not_found_page: which equals the resourceName + /// + public async Task WebAppSetNotFoundPageAsync(ApiWebAppData webApp, string resourceName, CancellationToken cancellationToken = default(CancellationToken)) + { + var resp = await WebAppSetNotFoundPageAsync(webApp.Name, resourceName, cancellationToken); + resp.NewWebApp = webApp.ShallowCopy(); + resp.NewWebApp.Not_found_page = (resourceName == "" ? null : resourceName); + return resp; + } + /// + /// Send a WebApp.SetNotFoundPage Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that the not found page should be set for + /// Name of the resource that should be the webapps not found page + /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: + /// Not_found_page: which equals the resourceName + /// + public ApiTrueWithWebAppResponse WebAppSetNotFoundPage(ApiWebAppData webApp, string resourceName) => WebAppSetNotFoundPageAsync(webApp, resourceName).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetNotFoundPage Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that the not found page should be set for + /// resource.Name of the resource that should be the webapps not found page + /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: + /// Not_found_page: which equals the resource.Name + /// + public async Task WebAppSetNotFoundPageAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) + { + var resp = await WebAppSetNotFoundPageAsync(webApp.Name, resource.Name, cancellationToken); + resp.NewWebApp = webApp.ShallowCopy(); + resp.NewWebApp.Not_found_page = (resource.Name == "" ? null : resource.Name); + return resp; + } + /// + /// Send a WebApp.SetNotFoundPage Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that the not found page should be set for + /// resource.Name of the resource that should be the webapps not found page + /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: + /// Not_found_page: which equals the resource.Name + /// + public ApiTrueWithWebAppResponse WebAppSetNotFoundPage(ApiWebAppData webApp, ApiWebAppResource resource) => WebAppSetNotFoundPageAsync(webApp, resource).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetNotFoundPage Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that the not found page should be set for + /// resource.Name of the resource that should be the webapps not found page + /// This function will return the TrueOnSuccessResponse and webapp containing only the information: + /// Name: which equals the webAppName + /// Not_found_page: which equals the resource.Name + /// + public async Task WebAppSetNotFoundPageAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppSetNotFoundPageAsync(webAppName, resource.Name, cancellationToken); + } + /// + /// Send a WebApp.SetNotFoundPage Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that the not found page should be set for + /// resource.Name of the resource that should be the webapps not found page + /// This function will return the TrueOnSuccessResponse and webapp containing only the information: + /// Name: which equals the webAppName + /// Not_found_page: which equals the resource.Name + /// + public ApiTrueWithWebAppResponse WebAppSetNotFoundPage(string webAppName, ApiWebAppResource resource) => WebAppSetNotFoundPageAsync(webAppName, resource).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetState Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that the state should be set for + /// State the WebApp should have + /// This function will return the TrueOnSuccessResponse and webapp containing only the information: + /// Name: which equals the webAppName + /// State: which equals the state + /// + public async Task WebAppSetStateAsync(string webAppName, ApiWebAppState apiWebAppState, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebAppSetStateRequest(webAppName, apiWebAppState); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = new ApiTrueWithWebAppResponse(); + responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); + if (responseObj.TrueOnSuccesResponse.Result) + { + responseObj.NewWebApp = new ApiWebAppData() { Name = webAppName, State = apiWebAppState }; + } + return responseObj; + } + + /// + /// Send a WebApp.SetState Request using the Request from the ApiRequestFactory + /// + /// Name of the webapp that the state should be set for + /// State the WebApp should have + /// This function will return the TrueOnSuccessResponse and webapp containing only the information: + /// Name: which equals the webAppName + /// State: which equals the state + /// + public ApiTrueWithWebAppResponse WebAppSetState(string webAppName, ApiWebAppState newApiWebAppState) + => WebAppSetStateAsync(webAppName, newApiWebAppState).GetAwaiter().GetResult(); + + /// + /// Send a WebServer.SetDefaultPage Request using the Request from the ApiRequestFactory + /// + /// + /// This function will return the TrueOnSuccessResponse + public async Task WebServerSetDefaultPageAsync(string defaultPage, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebserverSetDefaultPageRequest(defaultPage); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + + /// + /// Send a WebServer.SetDefaultPage Request using the Request from the ApiRequestFactory + /// + /// + /// + ApiTrueOnSuccessResponse IApiRequestHandler.WebServerSetDefaultPage(string defaultPage) + => WebServerSetDefaultPageAsync(defaultPage).GetAwaiter().GetResult(); + + /// + /// Send a WebServer.ReadDefaultPage Request using the Request from the ApiRequestFactory + /// + /// Returns the default page in a response object + public async Task WebServerGetReadDefaultPageAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebserverReadDefaultPageRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + + /// + /// Send a WebServer.ReadDefaultPage Request using the Request from the ApiRequestFactory + /// + /// Returns the default page in a response object + public ApiWebServerGetReadDefaultPageResponse WebServerGetReadDefaultPage() + => WebServerGetReadDefaultPageAsync().GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetState Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that state should be set for + /// State the WebApp should have + /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: + /// State: which equals the state + /// + public async Task WebAppSetStateAsync(ApiWebAppData webApp, ApiWebAppState apiWebAppState, CancellationToken cancellationToken = default(CancellationToken)) + { + var resp = await WebAppSetStateAsync(webApp.Name, apiWebAppState, cancellationToken); + resp.NewWebApp = webApp.ShallowCopy(); + resp.NewWebApp.State = apiWebAppState; + return resp; + } + + /// + /// Send a WebApp.SetState Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that state should be set for + /// State the WebApp should have + /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: + /// State: which equals the state + /// + public ApiTrueWithWebAppResponse WebAppSetState(ApiWebAppData webApp, ApiWebAppState newApiWebAppState) + => WebAppSetStateAsync(webApp, newApiWebAppState).GetAwaiter().GetResult(); - /// - /// Send a WebApp.SetDefaultPage Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that the default page should be set for - /// Name of the resource that should be the webapps default page - /// This function will return the TrueOnSuccessResponse and webapp containing only the information: - /// Name: which equals the webAppName - /// Default_Page: which equals the resourceName - /// - public async Task WebAppSetDefaultPageAsync(string webAppName, string resourceName) - { - var req = _apiRequestFactory.GetApiWebAppSetDefaultPageRequest(webAppName, resourceName ?? ""); - string response = await SendPostRequestAsync(req); - var responseObj = new ApiTrueWithWebAppResponse(); - responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); - if (responseObj.TrueOnSuccesResponse.Result) - { - responseObj.NewWebApp = new ApiWebAppData() { Name = webAppName, Default_page = (resourceName == "" ? null : resourceName) }; - } - return responseObj; - } - /// - /// Send a WebApp.SetDefaultPage Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that the default page should be set for - /// Name of the resource that should be the webapps default page - /// This function will return the TrueOnSuccessResponse and webapp containing only the information: - /// Name: which equals the webAppName - /// Default_Page: which equals the resourceName - /// - public ApiTrueWithWebAppResponse WebAppSetDefaultPage(string webAppName, string resourceName) => WebAppSetDefaultPageAsync(webAppName, resourceName).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetDefaultPage Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that the default page should be set for - /// Name of the resource that should be the webapps default page - /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: - /// Default_Page: which equals the resourceName - /// - public async Task WebAppSetDefaultPageAsync(ApiWebAppData webApp, string resourceName) - { - var resp = await WebAppSetDefaultPageAsync(webApp.Name, resourceName); - resp.NewWebApp = webApp.ShallowCopy(); - resp.NewWebApp.Default_page = (resourceName == "" ? null : resourceName); - return resp; - } - /// - /// Send a WebApp.SetDefaultPage Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that the default page should be set for - /// Name of the resource that should be the webapps default page - /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: - /// Default_Page: which equals the resourceName - /// - public ApiTrueWithWebAppResponse WebAppSetDefaultPage(ApiWebAppData webApp, string resourceName) => WebAppSetDefaultPageAsync(webApp, resourceName).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetDefaultPage Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that the default page should be set for - /// resource.Name of the resource that should be the webapps default page - /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: - /// Default_Page: which equals the resource.Name - /// - public async Task WebAppSetDefaultPageAsync(ApiWebAppData webApp, ApiWebAppResource resource) - { - var resp = await WebAppSetDefaultPageAsync(webApp.Name, resource.Name); - resp.NewWebApp = webApp.ShallowCopy(); - resp.NewWebApp.Default_page = (resource.Name == "" ? null : resource.Name); - return resp; - } - /// - /// Send a WebApp.SetDefaultPage Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that the default page should be set for - /// resource.Name of the resource that should be the webapps default page - /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: - /// Default_Page: which equals the resource.Name - /// - public ApiTrueWithWebAppResponse WebAppSetDefaultPage(ApiWebAppData webApp, ApiWebAppResource resource) => WebAppSetDefaultPageAsync(webApp, resource).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetDefaultPage Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that the default page should be set for - /// resource.Name of the resource that should be the webapps default page - /// This function will return the TrueOnSuccessResponse and webapp containing only the information: - /// Name: which equals the webAppName - /// Default_Page: which equals the resourceName - /// - public async Task WebAppSetDefaultPageAsync(string webAppName, ApiWebAppResource resource) - { - return await WebAppSetDefaultPageAsync(webAppName, resource.Name); - } - /// - /// Send a WebApp.SetDefaultPage Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that the default page should be set for - /// resource.Name of the resource that should be the webapps default page - /// This function will return the TrueOnSuccessResponse and webapp containing only the information: - /// Name: which equals the webAppName - /// Default_Page: which equals the resourceName - /// - public ApiTrueWithWebAppResponse WebAppSetDefaultPage(string webAppName, ApiWebAppResource resource) => WebAppSetDefaultPageAsync(webAppName, resource).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetNotAuthorizedPage Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that the not authorized page should be set for - /// Name of the resource that should be the webapps not authorized page - /// This function will return the TrueOnSuccessResponse and webapp containing only the information: - /// Name: which equals webAppName - /// Not_authorized_page: which equals the resourceName - /// - public async Task WebAppSetNotAuthorizedPageAsync(string webAppName, string resourceName) - { - var req = _apiRequestFactory.GetApiWebAppSetNotAuthorizedPageRequest(webAppName, resourceName ?? ""); - string response = await SendPostRequestAsync(req); - var responseObj = new ApiTrueWithWebAppResponse(); - responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); - if (responseObj.TrueOnSuccesResponse.Result) - { - responseObj.NewWebApp = new ApiWebAppData() { Name = webAppName, Not_authorized_page = (resourceName == "" ? null : resourceName) }; - } - return responseObj; - } - /// - /// Send a WebApp.SetNotAuthorizedPage Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that the not authorized page should be set for - /// Name of the resource that should be the webapps not authorized page - /// This function will return the TrueOnSuccessResponse and webapp containing only the information: - /// Name: which equals webAppName - /// Not_authorized_page: which equals the resourceName - /// - public ApiTrueWithWebAppResponse WebAppSetNotAuthorizedPage(string webAppName, string resourceName) => WebAppSetNotAuthorizedPageAsync(webAppName, resourceName).GetAwaiter().GetResult(); - /// - /// Send a WebApp.SetNotAuthorizedPage Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that the not authorized page should be set for - /// Name of the resource that should be the webapps not authorized page - /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: - /// Not_authorized_page: which equals the resourceName - /// - public async Task WebAppSetNotAuthorizedPageAsync(ApiWebAppData webApp, string resourceName) - { - var resp = await WebAppSetNotAuthorizedPageAsync(webApp.Name, resourceName); - resp.NewWebApp = webApp.ShallowCopy(); - resp.NewWebApp.Not_authorized_page = (resourceName == "" ? null : resourceName); - return resp; - } - /// - /// Send a WebApp.SetNotAuthorizedPage Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that the not authorized page should be set for - /// Name of the resource that should be the webapps not authorized page - /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: - /// Not_authorized_page: which equals the resourceName - /// - public ApiTrueWithWebAppResponse WebAppSetNotAuthorizedPage(ApiWebAppData webApp, string resourceName) => WebAppSetNotAuthorizedPageAsync(webApp, resourceName).GetAwaiter().GetResult(); - /// - /// Send a WebApp.SetNotAuthorizedPage Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that the not authorized page should be set for - /// resource.Name of the resource that should be the webapps not authorized page - /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: - /// Not_authorized_page: which equals the resourceName - /// - public async Task WebAppSetNotAuthorizedPageAsync(ApiWebAppData webApp, ApiWebAppResource resource) - { - var resp = await WebAppSetNotAuthorizedPageAsync(webApp.Name, resource.Name); - resp.NewWebApp = webApp.ShallowCopy(); - resp.NewWebApp.Not_authorized_page = (resource.Name == "" ? null : resource.Name); - return resp; - } - /// - /// Send a WebApp.SetNotAuthorizedPage Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that the not authorized page should be set for - /// resource.Name of the resource that should be the webapps not authorized page - /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: - /// Not_authorized_page: which equals the resourceName - /// - public ApiTrueWithWebAppResponse WebAppSetNotAuthorizedPage(ApiWebAppData webApp, ApiWebAppResource resource) => WebAppSetNotAuthorizedPageAsync(webApp, resource).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetNotAuthorizedPage Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that the not authorized page should be set for - /// resource.Name of the resource that should be the webapps not authorized page - /// This function will return the TrueOnSuccessResponse and webapp containing only the information: - /// Name: which equals webAppName - /// Not_authorized_page: which equals the resource.Name - /// - public async Task WebAppSetNotAuthorizedPageAsync(string webAppName, ApiWebAppResource resource) - { - return await WebAppSetNotAuthorizedPageAsync(webAppName, resource.Name); - } - /// - /// Send a WebApp.SetNotAuthorizedPage Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that the not authorized page should be set for - /// resource.Name of the resource that should be the webapps not authorized page - /// This function will return the TrueOnSuccessResponse and webapp containing only the information: - /// Name: which equals webAppName - /// Not_authorized_page: which equals the resource.Name - /// - public ApiTrueWithWebAppResponse WebAppSetNotAuthorizedPage(string webAppName, ApiWebAppResource resource) => WebAppSetNotAuthorizedPageAsync(webAppName, resource).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetNotFoundPage Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that the not found page should be set for - /// Name of the resource that should be the webapps not found page - /// This function will return the TrueOnSuccessResponse and webapp containing only the information: - /// Name: which equals the webAppName - /// Not_found_page: which equals the resourceName - /// - public async Task WebAppSetNotFoundPageAsync(string webAppName, string resourceName) - { - var req = _apiRequestFactory.GetApiWebAppSetNotFoundPageRequest(webAppName, resourceName ?? ""); - string response = await SendPostRequestAsync(req); - var responseObj = new ApiTrueWithWebAppResponse(); - responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); - if (responseObj.TrueOnSuccesResponse.Result) - { - responseObj.NewWebApp = new ApiWebAppData() { Name = webAppName, Not_found_page = (resourceName == "" ? null : resourceName) }; - } - return responseObj; - } - /// - /// Send a WebApp.SetNotFoundPage Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that the not found page should be set for - /// Name of the resource that should be the webapps not found page - /// This function will return the TrueOnSuccessResponse and webapp containing only the information: - /// Name: which equals the webAppName - /// Not_found_page: which equals the resourceName - /// - public ApiTrueWithWebAppResponse WebAppSetNotFoundPage(string webAppName, string resourceName) => WebAppSetNotFoundPageAsync(webAppName, resourceName).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetNotFoundPage Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that the not found page should be set for - /// Name of the resource that should be the webapps not found page - /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: - /// Not_found_page: which equals the resourceName - /// - public async Task WebAppSetNotFoundPageAsync(ApiWebAppData webApp, string resourceName) - { - var resp = await WebAppSetNotFoundPageAsync(webApp.Name, resourceName); - resp.NewWebApp = webApp.ShallowCopy(); - resp.NewWebApp.Not_found_page = (resourceName == "" ? null : resourceName); - return resp; - } - /// - /// Send a WebApp.SetNotFoundPage Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that the not found page should be set for - /// Name of the resource that should be the webapps not found page - /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: - /// Not_found_page: which equals the resourceName - /// - public ApiTrueWithWebAppResponse WebAppSetNotFoundPage(ApiWebAppData webApp, string resourceName) => WebAppSetNotFoundPageAsync(webApp, resourceName).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetNotFoundPage Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that the not found page should be set for - /// resource.Name of the resource that should be the webapps not found page - /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: - /// Not_found_page: which equals the resource.Name - /// - public async Task WebAppSetNotFoundPageAsync(ApiWebAppData webApp, ApiWebAppResource resource) - { - var resp = await WebAppSetNotFoundPageAsync(webApp.Name, resource.Name); - resp.NewWebApp = webApp.ShallowCopy(); - resp.NewWebApp.Not_found_page = (resource.Name == "" ? null : resource.Name); - return resp; - } - /// - /// Send a WebApp.SetNotFoundPage Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that the not found page should be set for - /// resource.Name of the resource that should be the webapps not found page - /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: - /// Not_found_page: which equals the resource.Name - /// - public ApiTrueWithWebAppResponse WebAppSetNotFoundPage(ApiWebAppData webApp, ApiWebAppResource resource) => WebAppSetNotFoundPageAsync(webApp, resource).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetNotFoundPage Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that the not found page should be set for - /// resource.Name of the resource that should be the webapps not found page - /// This function will return the TrueOnSuccessResponse and webapp containing only the information: - /// Name: which equals the webAppName - /// Not_found_page: which equals the resource.Name - /// - public async Task WebAppSetNotFoundPageAsync(string webAppName, ApiWebAppResource resource) - { - return await WebAppSetNotFoundPageAsync(webAppName, resource.Name); - } - /// - /// Send a WebApp.SetNotFoundPage Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that the not found page should be set for - /// resource.Name of the resource that should be the webapps not found page - /// This function will return the TrueOnSuccessResponse and webapp containing only the information: - /// Name: which equals the webAppName - /// Not_found_page: which equals the resource.Name - /// - public ApiTrueWithWebAppResponse WebAppSetNotFoundPage(string webAppName, ApiWebAppResource resource) => WebAppSetNotFoundPageAsync(webAppName, resource).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetState Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that the state should be set for - /// State the WebApp should have - /// This function will return the TrueOnSuccessResponse and webapp containing only the information: - /// Name: which equals the webAppName - /// State: which equals the state - /// - public async Task WebAppSetStateAsync(string webAppName, ApiWebAppState apiWebAppState) - { - var req = _apiRequestFactory.GetApiWebAppSetStateRequest(webAppName, apiWebAppState); - string response = await SendPostRequestAsync(req); - var responseObj = new ApiTrueWithWebAppResponse(); - responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); - if (responseObj.TrueOnSuccesResponse.Result) - { - responseObj.NewWebApp = new ApiWebAppData() { Name = webAppName, State = apiWebAppState }; - } - return responseObj; - } - /// - /// Send a WebApp.SetState Request using the Request from the ApiRequestFactory - /// - /// Name of the webapp that the state should be set for - /// State the WebApp should have - /// This function will return the TrueOnSuccessResponse and webapp containing only the information: - /// Name: which equals the webAppName - /// State: which equals the state - /// - public ApiTrueWithWebAppResponse WebAppSetState(string webAppName, ApiWebAppState newApiWebAppState) - => WebAppSetStateAsync(webAppName, newApiWebAppState).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetState Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that state should be set for - /// State the WebApp should have - /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: - /// State: which equals the state - /// - public async Task WebAppSetStateAsync(ApiWebAppData webApp, ApiWebAppState apiWebAppState) - { - var resp = await WebAppSetStateAsync(webApp.Name, apiWebAppState); - resp.NewWebApp = webApp.ShallowCopy(); - resp.NewWebApp.State = apiWebAppState; - return resp; - } - /// - /// Send a WebApp.SetState Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that state should be set for - /// State the WebApp should have - /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: - /// State: which equals the state - /// - public ApiTrueWithWebAppResponse WebAppSetState(ApiWebAppData webApp, ApiWebAppState newApiWebAppState) - => WebAppSetStateAsync(webApp, newApiWebAppState).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceETag Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resourceName of the resource that the etag should be set for - /// Etag value the resource should have - /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// Etag: which equals the newEtagValue - /// + /// + /// Send a WebApp.SetResourceETag Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resourceName of the resource that the etag should be set for + /// Etag value the resource should have + /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// Etag: which equals the newEtagValue + /// public async Task WebAppSetResourceETagAsync(string webAppName, string resourceName, - string newETagValue) - { - var req = _apiRequestFactory.GetApiSetResourceETagRequest(webAppName, resourceName, newETagValue ?? ""); - string response = await SendPostRequestAsync(req); - var responseObj = new ApiTrueWithResourceResponse(); - responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); - if (responseObj.TrueOnSuccesResponse.Result) - { - responseObj.NewResource = new ApiWebAppResource() { Name = resourceName, Etag = (newETagValue == "" ? null : newETagValue) }; - } - return responseObj; - } - /// - /// Send a WebApp.SetResourceETag Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resourceName of the resource that the etag should be set for - /// Etag value the resource should have - /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// Etag: which equals the newEtagValue - /// - public ApiTrueWithResourceResponse WebAppSetResourceETag(string webAppName, string resourceName, string newETagValue) - => WebAppSetResourceETagAsync(webAppName, resourceName, newETagValue).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceETag Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resourceName of the resource that the etag should be set for - /// Etag value the resource should have - /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// Etag: which equals the newEtagValue - /// + string newETagValue, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiSetResourceETagRequest(webAppName, resourceName, newETagValue ?? ""); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = new ApiTrueWithResourceResponse(); + responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); + if (responseObj.TrueOnSuccesResponse.Result) + { + responseObj.NewResource = new ApiWebAppResource() { Name = resourceName, Etag = (newETagValue == "" ? null : newETagValue) }; + } + return responseObj; + } + /// + /// Send a WebApp.SetResourceETag Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resourceName of the resource that the etag should be set for + /// Etag value the resource should have + /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// Etag: which equals the newEtagValue + /// + public ApiTrueWithResourceResponse WebAppSetResourceETag(string webAppName, string resourceName, string newETagValue) + => WebAppSetResourceETagAsync(webAppName, resourceName, newETagValue).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetResourceETag Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resourceName of the resource that the etag should be set for + /// Etag value the resource should have + /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// Etag: which equals the newEtagValue + /// public async Task WebAppSetResourceETagAsync(ApiWebAppData webApp, string resourceName, - string newETagValue) - { - return await WebAppSetResourceETagAsync(webApp.Name, resourceName, newETagValue); - } - /// - /// Send a WebApp.SetResourceETag Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resourceName of the resource that the etag should be set for - /// Etag value the resource should have - /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// Etag: which equals the newEtagValue - /// - public ApiTrueWithResourceResponse WebAppSetResourceETag(ApiWebAppData webApp, string resourceName, string newETagValue) - => WebAppSetResourceETagAsync(webApp, resourceName, newETagValue).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceETag Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resource.Name of the resource that the etag should be set for - /// Etag value the resource should have - /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// Etag: which equals the newEtagValue - /// + string newETagValue, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppSetResourceETagAsync(webApp.Name, resourceName, newETagValue, cancellationToken); + } + /// + /// Send a WebApp.SetResourceETag Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resourceName of the resource that the etag should be set for + /// Etag value the resource should have + /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// Etag: which equals the newEtagValue + /// + public ApiTrueWithResourceResponse WebAppSetResourceETag(ApiWebAppData webApp, string resourceName, string newETagValue) + => WebAppSetResourceETagAsync(webApp, resourceName, newETagValue).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetResourceETag Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resource.Name of the resource that the etag should be set for + /// Etag value the resource should have + /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// Etag: which equals the newEtagValue + /// public async Task WebAppSetResourceETagAsync(ApiWebAppData webApp, ApiWebAppResource resource, - string newETagValue) - { - var basicResp = await WebAppSetResourceETagAsync(webApp.Name, resource.Name, newETagValue); - basicResp.NewResource = resource.ShallowCopy(); - basicResp.NewResource.Etag = (newETagValue == "" ? null : newETagValue); - return basicResp; - - } - /// - /// Send a WebApp.SetResourceETag Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resource.Name of the resource that the etag should be set for - /// Etag value the resource should have - /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// Etag: which equals the newEtagValue - /// - public ApiTrueWithResourceResponse WebAppSetResourceETag(ApiWebAppData webApp, ApiWebAppResource resource, string newETagValue) - => WebAppSetResourceETagAsync(webApp, resource, newETagValue).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceETag Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resource.Name of the resource that the etag should be set for - /// Etag value the resource should have - /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// Etag: which equals the newEtagValue - /// + string newETagValue, CancellationToken cancellationToken = default(CancellationToken)) + { + var basicResp = await WebAppSetResourceETagAsync(webApp.Name, resource.Name, newETagValue, cancellationToken); + basicResp.NewResource = resource.ShallowCopy(); + basicResp.NewResource.Etag = (newETagValue == "" ? null : newETagValue); + return basicResp; + + } + /// + /// Send a WebApp.SetResourceETag Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resource.Name of the resource that the etag should be set for + /// Etag value the resource should have + /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// Etag: which equals the newEtagValue + /// + public ApiTrueWithResourceResponse WebAppSetResourceETag(ApiWebAppData webApp, ApiWebAppResource resource, string newETagValue) + => WebAppSetResourceETagAsync(webApp, resource, newETagValue).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetResourceETag Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resource.Name of the resource that the etag should be set for + /// Etag value the resource should have + /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// Etag: which equals the newEtagValue + /// public async Task WebAppSetResourceETagAsync(string webAppName, ApiWebAppResource resource, - string newETagValue) - { - var basicResp = await WebAppSetResourceETagAsync(webAppName, resource.Name, newETagValue); - basicResp.NewResource = resource.ShallowCopy(); - basicResp.NewResource.Etag = (newETagValue == "" ? null : newETagValue); - return basicResp; - } - /// - /// Send a WebApp.SetResourceETag Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resource.Name of the resource that the etag should be set for - /// Etag value the resource should have - /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// Etag: which equals the newEtagValue - /// - public ApiTrueWithResourceResponse WebAppSetResourceETag(string webAppName, ApiWebAppResource resource, string newETagValue) - => WebAppSetResourceETagAsync(webAppName, resource, newETagValue).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceMediaType Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resourceName of the resource that the Media_type should be set for - /// MediaType value the resource should have - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// MediaType: which equals the newMediaType - /// + string newETagValue, CancellationToken cancellationToken = default(CancellationToken)) + { + var basicResp = await WebAppSetResourceETagAsync(webAppName, resource.Name, newETagValue, cancellationToken); + basicResp.NewResource = resource.ShallowCopy(); + basicResp.NewResource.Etag = (newETagValue == "" ? null : newETagValue); + return basicResp; + } + /// + /// Send a WebApp.SetResourceETag Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resource.Name of the resource that the etag should be set for + /// Etag value the resource should have + /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// Etag: which equals the newEtagValue + /// + public ApiTrueWithResourceResponse WebAppSetResourceETag(string webAppName, ApiWebAppResource resource, string newETagValue) + => WebAppSetResourceETagAsync(webAppName, resource, newETagValue).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetResourceMediaType Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resourceName of the resource that the Media_type should be set for + /// MediaType value the resource should have + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// MediaType: which equals the newMediaType + /// public async Task WebAppSetResourceMediaTypeAsync(string webAppName, string resourceName, - string newMediaType) - { - var req = _apiRequestFactory.GetApiSetResourceMediaTypeRequest(webAppName, resourceName, newMediaType); - string response = await SendPostRequestAsync(req); - var responseObj = new ApiTrueWithResourceResponse(); - responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); - if (responseObj.TrueOnSuccesResponse.Result) - { - responseObj.NewResource = new ApiWebAppResource() { Name = resourceName, Media_type = newMediaType }; - } - return responseObj; - } - /// - /// Send a WebApp.SetResourceMediaType Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resourceName of the resource that the Media_type should be set for - /// MediaType value the resource should have - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// MediaType: which equals the newMediaType - /// - public ApiTrueWithResourceResponse WebAppSetResourceMediaType(string webAppName, string resourceName, string newMediaType) - => WebAppSetResourceMediaTypeAsync(webAppName, resourceName, newMediaType).GetAwaiter().GetResult(); - - - /// - /// Send a WebApp.SetResourceMediaType Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resourceName of the resource that the Media_type should be set for - /// MediaType value the resource should have - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// MediaType: which equals the newMediaType - /// + string newMediaType, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiSetResourceMediaTypeRequest(webAppName, resourceName, newMediaType); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = new ApiTrueWithResourceResponse(); + responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); + if (responseObj.TrueOnSuccesResponse.Result) + { + responseObj.NewResource = new ApiWebAppResource() { Name = resourceName, Media_type = newMediaType }; + } + return responseObj; + } + /// + /// Send a WebApp.SetResourceMediaType Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resourceName of the resource that the Media_type should be set for + /// MediaType value the resource should have + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// MediaType: which equals the newMediaType + /// + public ApiTrueWithResourceResponse WebAppSetResourceMediaType(string webAppName, string resourceName, string newMediaType) + => WebAppSetResourceMediaTypeAsync(webAppName, resourceName, newMediaType).GetAwaiter().GetResult(); + + + /// + /// Send a WebApp.SetResourceMediaType Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resourceName of the resource that the Media_type should be set for + /// MediaType value the resource should have + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// MediaType: which equals the newMediaType + /// public async Task WebAppSetResourceMediaTypeAsync(ApiWebAppData webApp, string resourceName, - string newMediaType) - { - return await WebAppSetResourceMediaTypeAsync(webApp.Name, resourceName, newMediaType); - } - /// - /// Send a WebApp.SetResourceMediaType Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resourceName of the resource that the Media_type should be set for - /// MediaType value the resource should have - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// MediaType: which equals the newMediaType - /// - public ApiTrueWithResourceResponse WebAppSetResourceMediaType(ApiWebAppData webApp, string resourceName, string newMediaType) - => WebAppSetResourceMediaTypeAsync(webApp, resourceName, newMediaType).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceMediaType Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resource.Name of the resource that the Media_type should be set for - /// MediaType value the resource should have - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// MediaType: which equals the newMediaType - /// + string newMediaType, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppSetResourceMediaTypeAsync(webApp.Name, resourceName, newMediaType, cancellationToken); + } + /// + /// Send a WebApp.SetResourceMediaType Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resourceName of the resource that the Media_type should be set for + /// MediaType value the resource should have + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// MediaType: which equals the newMediaType + /// + public ApiTrueWithResourceResponse WebAppSetResourceMediaType(ApiWebAppData webApp, string resourceName, string newMediaType) + => WebAppSetResourceMediaTypeAsync(webApp, resourceName, newMediaType).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetResourceMediaType Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resource.Name of the resource that the Media_type should be set for + /// MediaType value the resource should have + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// MediaType: which equals the newMediaType + /// public async Task WebAppSetResourceMediaTypeAsync(ApiWebAppData webApp, ApiWebAppResource resource, - string newMediaType) - { - var basicResp = await WebAppSetResourceMediaTypeAsync(webApp.Name, resource.Name, newMediaType); - basicResp.NewResource = resource.ShallowCopy(); - basicResp.NewResource.Media_type = newMediaType; - return basicResp; - } - /// - /// Send a WebApp.SetResourceMediaType Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resource.Name of the resource that the Media_type should be set for - /// MediaType value the resource should have - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// MediaType: which equals the newMediaType - /// - public ApiTrueWithResourceResponse WebAppSetResourceMediaType(ApiWebAppData webApp, ApiWebAppResource resource, string newMediaType) - => WebAppSetResourceMediaTypeAsync(webApp, resource, newMediaType).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceMediaType Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resource.Name of the resource that the Media_type should be set for - /// MediaType value the resource should have - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// MediaType: which equals the newMediaType - /// + string newMediaType, CancellationToken cancellationToken = default(CancellationToken)) + { + var basicResp = await WebAppSetResourceMediaTypeAsync(webApp.Name, resource.Name, newMediaType, cancellationToken); + basicResp.NewResource = resource.ShallowCopy(); + basicResp.NewResource.Media_type = newMediaType; + return basicResp; + } + /// + /// Send a WebApp.SetResourceMediaType Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resource.Name of the resource that the Media_type should be set for + /// MediaType value the resource should have + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// MediaType: which equals the newMediaType + /// + public ApiTrueWithResourceResponse WebAppSetResourceMediaType(ApiWebAppData webApp, ApiWebAppResource resource, string newMediaType) + => WebAppSetResourceMediaTypeAsync(webApp, resource, newMediaType).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetResourceMediaType Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resource.Name of the resource that the Media_type should be set for + /// MediaType value the resource should have + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// MediaType: which equals the newMediaType + /// public async Task WebAppSetResourceMediaTypeAsync(string webAppName, ApiWebAppResource resource, - string newMediaType) - { - var basicResp = await WebAppSetResourceMediaTypeAsync(webAppName, resource.Name, newMediaType); - basicResp.NewResource = resource.ShallowCopy(); - basicResp.NewResource.Media_type = newMediaType; - return basicResp; - } - /// - /// Send a WebApp.SetResourceMediaType Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resource.Name of the resource that the Media_type should be set for - /// MediaType value the resource should have - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// MediaType: which equals the newMediaType - /// - public ApiTrueWithResourceResponse WebAppSetResourceMediaType(string webAppName, ApiWebAppResource resource, string newMediaType) - => WebAppSetResourceMediaTypeAsync(webAppName, resource, newMediaType).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resourceName of the resource that the Last_modified should be set for - /// ModificationTime - Last_modified value the resource should have - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// Last_Modified: which equals the newModificationTime - /// + string newMediaType, CancellationToken cancellationToken = default(CancellationToken)) + { + var basicResp = await WebAppSetResourceMediaTypeAsync(webAppName, resource.Name, newMediaType, cancellationToken); + basicResp.NewResource = resource.ShallowCopy(); + basicResp.NewResource.Media_type = newMediaType; + return basicResp; + } + /// + /// Send a WebApp.SetResourceMediaType Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resource.Name of the resource that the Media_type should be set for + /// MediaType value the resource should have + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// MediaType: which equals the newMediaType + /// + public ApiTrueWithResourceResponse WebAppSetResourceMediaType(string webAppName, ApiWebAppResource resource, string newMediaType) + => WebAppSetResourceMediaTypeAsync(webAppName, resource, newMediaType).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resourceName of the resource that the Last_modified should be set for + /// ModificationTime - Last_modified value the resource should have + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// Last_Modified: which equals the newModificationTime + /// public async Task WebAppSetResourceModificationTimeAsync(string webAppName, string resourceName, - string newModificationTime) - { - var req = _apiRequestFactory.GetApiSetResourceModificationTimeRequest(webAppName, resourceName, newModificationTime); - string response = await SendPostRequestAsync(req); - var responseObj = new ApiTrueWithResourceResponse(); - responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); - responseObj.NewResource = new ApiWebAppResource() - { Name = resourceName, Last_modified = XmlConvert.ToDateTime(newModificationTime, XmlDateTimeSerializationMode.Utc) }; - return responseObj; - } - /// - /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resourceName of the resource that the Last_modified should be set for - /// ModificationTime - Last_modified value the resource should have - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// Last_Modified: which equals the newModificationTime - /// - public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(string webAppName, string resourceName, string newModificationTime) - => WebAppSetResourceModificationTimeAsync(webAppName, resourceName, newModificationTime).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resourceName of the resource that the Last_modified should be set for - /// ModificationTime - Last_modified value the resource should have - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// Last_Modified: which equals the newModificationTime - /// + string newModificationTime, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiSetResourceModificationTimeRequest(webAppName, resourceName, newModificationTime); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = new ApiTrueWithResourceResponse(); + responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); + responseObj.NewResource = new ApiWebAppResource() + { Name = resourceName, Last_modified = XmlConvert.ToDateTime(newModificationTime, XmlDateTimeSerializationMode.Utc) }; + return responseObj; + } + /// + /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resourceName of the resource that the Last_modified should be set for + /// ModificationTime - Last_modified value the resource should have + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// Last_Modified: which equals the newModificationTime + /// + public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(string webAppName, string resourceName, string newModificationTime) + => WebAppSetResourceModificationTimeAsync(webAppName, resourceName, newModificationTime).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resourceName of the resource that the Last_modified should be set for + /// ModificationTime - Last_modified value the resource should have + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// Last_Modified: which equals the newModificationTime + /// public async Task WebAppSetResourceModificationTimeAsync(ApiWebAppData webApp, string resourceName, - string newModificationTime) - { - return await WebAppSetResourceModificationTimeAsync(webApp.Name, resourceName, newModificationTime); - } - /// - /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resourceName of the resource that the Last_modified should be set for - /// ModificationTime - Last_modified value the resource should have - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// Last_Modified: which equals the newModificationTime - /// - public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(ApiWebAppData webApp, string resourceName, string newModificationTime) - => WebAppSetResourceModificationTimeAsync(webApp, resourceName, newModificationTime).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resource.Name of the resource that the Last_modified should be set for - /// ModificationTime - Last_modified value the resource should have - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// Last_Modified: which equals the newModificationTime - /// + string newModificationTime, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppSetResourceModificationTimeAsync(webApp.Name, resourceName, newModificationTime, cancellationToken); + } + /// + /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resourceName of the resource that the Last_modified should be set for + /// ModificationTime - Last_modified value the resource should have + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// Last_Modified: which equals the newModificationTime + /// + public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(ApiWebAppData webApp, string resourceName, string newModificationTime) + => WebAppSetResourceModificationTimeAsync(webApp, resourceName, newModificationTime).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resource.Name of the resource that the Last_modified should be set for + /// ModificationTime - Last_modified value the resource should have + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// Last_Modified: which equals the newModificationTime + /// public async Task WebAppSetResourceModificationTimeAsync(ApiWebAppData webApp, ApiWebAppResource resource, - string newModificationTime) - { - var basicResp = await WebAppSetResourceModificationTimeAsync(webApp.Name, resource.Name, newModificationTime); - var last_mod = basicResp.NewResource.Last_modified; - basicResp.NewResource = resource.ShallowCopy(); - basicResp.NewResource.Last_modified = last_mod; - return basicResp; - } - /// - /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resource.Name of the resource that the Last_modified should be set for - /// ModificationTime - Last_modified value the resource should have - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// Last_Modified: which equals the newModificationTime - /// - public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(ApiWebAppData webApp, ApiWebAppResource resource, string newModificationTime) - => WebAppSetResourceModificationTimeAsync(webApp, resource, newModificationTime).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resourceName of the resource that the Last_modified should be set for - /// ModificationTime - Last_modified value the resource should have - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// Last_Modified: which equals the newModificationTime - /// + string newModificationTime, CancellationToken cancellationToken = default(CancellationToken)) + { + var basicResp = await WebAppSetResourceModificationTimeAsync(webApp.Name, resource.Name, newModificationTime, cancellationToken); + var last_mod = basicResp.NewResource.Last_modified; + basicResp.NewResource = resource.ShallowCopy(); + basicResp.NewResource.Last_modified = last_mod; + return basicResp; + } + /// + /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resource.Name of the resource that the Last_modified should be set for + /// ModificationTime - Last_modified value the resource should have + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// Last_Modified: which equals the newModificationTime + /// + public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(ApiWebAppData webApp, ApiWebAppResource resource, string newModificationTime) + => WebAppSetResourceModificationTimeAsync(webApp, resource, newModificationTime).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resourceName of the resource that the Last_modified should be set for + /// ModificationTime - Last_modified value the resource should have + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// Last_Modified: which equals the newModificationTime + /// public async Task WebAppSetResourceModificationTimeAsync(string webAppName, string resourceName, - DateTime newModificationTime) - { + DateTime newModificationTime, CancellationToken cancellationToken = default(CancellationToken)) + { return await WebAppSetResourceModificationTimeAsync(webAppName, resourceName, - newModificationTime.ToString(DateTimeFormatting.ApiDateTimeFormat)); - } - /// - /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resourceName of the resource that the Last_modified should be set for - /// ModificationTime - Last_modified value the resource should have - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// Last_Modified: which equals the newModificationTime - /// - public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(string webAppName, string resourceName, DateTime newModificationTime) - => WebAppSetResourceModificationTimeAsync(webAppName, resourceName, newModificationTime).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resourceName of the resource that the Last_modified should be set for - /// ModificationTime - Last_modified value the resource should have - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// Last_Modified: which equals the newModificationTime - /// - public async Task WebAppSetResourceModificationTimeAsync(ApiWebAppData webApp, string resourceName, - DateTime newModificationTime) - { + newModificationTime.ToString(DateTimeFormatting.ApiDateTimeFormat), cancellationToken); + } + /// + /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resourceName of the resource that the Last_modified should be set for + /// ModificationTime - Last_modified value the resource should have + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// Last_Modified: which equals the newModificationTime + /// + public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(string webAppName, string resourceName, DateTime newModificationTime) + => WebAppSetResourceModificationTimeAsync(webAppName, resourceName, newModificationTime).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resourceName of the resource that the Last_modified should be set for + /// ModificationTime - Last_modified value the resource should have + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// Last_Modified: which equals the newModificationTime + /// + public async Task WebAppSetResourceModificationTimeAsync(ApiWebAppData webApp, string resourceName, + DateTime newModificationTime, CancellationToken cancellationToken = default(CancellationToken)) + { return await WebAppSetResourceModificationTimeAsync(webApp.Name, resourceName, - newModificationTime.ToString(DateTimeFormatting.ApiDateTimeFormat)); - } - /// - /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resourceName of the resource that the Last_modified should be set for - /// ModificationTime - Last_modified value the resource should have - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// Last_Modified: which equals the newModificationTime - /// - public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(ApiWebAppData webApp, string resourceName, DateTime newModificationTime) - => WebAppSetResourceModificationTimeAsync(webApp, resourceName, newModificationTime).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resource.Name of the resource that the Last_modified should be set for - /// ModificationTime - Last_modified value the resource should have - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// Last_Modified: which equals the newModificationTime - /// + newModificationTime.ToString(DateTimeFormatting.ApiDateTimeFormat), cancellationToken); + } + /// + /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resourceName of the resource that the Last_modified should be set for + /// ModificationTime - Last_modified value the resource should have + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// Last_Modified: which equals the newModificationTime + /// + public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(ApiWebAppData webApp, string resourceName, DateTime newModificationTime) + => WebAppSetResourceModificationTimeAsync(webApp, resourceName, newModificationTime).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resource.Name of the resource that the Last_modified should be set for + /// ModificationTime - Last_modified value the resource should have + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// Last_Modified: which equals the newModificationTime + /// public async Task WebAppSetResourceModificationTimeAsync(ApiWebAppData webApp, ApiWebAppResource resource, - DateTime newModificationTime) - { + DateTime newModificationTime, CancellationToken cancellationToken = default(CancellationToken)) + { var basicResp = await WebAppSetResourceModificationTimeAsync(webApp.Name, resource.Name, - newModificationTime.ToString(DateTimeFormatting.ApiDateTimeFormat)); - var last_mod = basicResp.NewResource.Last_modified; - basicResp.NewResource = resource.ShallowCopy(); - basicResp.NewResource.Last_modified = last_mod; - return basicResp; - } - /// - /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resource.Name of the resource that the Last_modified should be set for - /// ModificationTime - Last_modified value the resource should have - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// Last_Modified: which equals the newModificationTime - /// - public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(ApiWebAppData webApp, ApiWebAppResource resource, DateTime newModificationTime) - => WebAppSetResourceModificationTimeAsync(webApp, resource, newModificationTime).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resource.Name of the resource that the Last_modified should be set for - /// ModificationTime - Last_modified value the resource should have - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// Last_Modified: which equals the newModificationTime - /// + newModificationTime.ToString(DateTimeFormatting.ApiDateTimeFormat), cancellationToken); + var last_mod = basicResp.NewResource.Last_modified; + basicResp.NewResource = resource.ShallowCopy(); + basicResp.NewResource.Last_modified = last_mod; + return basicResp; + } + /// + /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resource.Name of the resource that the Last_modified should be set for + /// ModificationTime - Last_modified value the resource should have + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// Last_Modified: which equals the newModificationTime + /// + public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(ApiWebAppData webApp, ApiWebAppResource resource, DateTime newModificationTime) + => WebAppSetResourceModificationTimeAsync(webApp, resource, newModificationTime).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resource.Name of the resource that the Last_modified should be set for + /// ModificationTime - Last_modified value the resource should have + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// Last_Modified: which equals the newModificationTime + /// public async Task WebAppSetResourceModificationTimeAsync(string webAppName, ApiWebAppResource resource, - DateTime newModificationTime) - { + DateTime newModificationTime, CancellationToken cancellationToken = default(CancellationToken)) + { var basicResp = await WebAppSetResourceModificationTimeAsync(webAppName, resource.Name, - newModificationTime.ToString(DateTimeFormatting.ApiDateTimeFormat)); - var last_mod = basicResp.NewResource.Last_modified; - basicResp.NewResource = resource.ShallowCopy(); - basicResp.NewResource.Last_modified = last_mod; - return basicResp; - } - /// - /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resource.Name of the resource that the Last_modified should be set for - /// ModificationTime - Last_modified value the resource should have - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// Last_Modified: which equals the newModificationTime - /// - public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(string webAppName, ApiWebAppResource resource, DateTime newModificationTime) - => WebAppSetResourceModificationTimeAsync(webAppName, resource, newModificationTime).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resource.Name of the resource that the Last_modified should be set for - /// ModificationTime - Last_modified value the resource should have - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// Last_Modified: which equals the newModificationTime - /// + newModificationTime.ToString(DateTimeFormatting.ApiDateTimeFormat), cancellationToken); + var last_mod = basicResp.NewResource.Last_modified; + basicResp.NewResource = resource.ShallowCopy(); + basicResp.NewResource.Last_modified = last_mod; + return basicResp; + } + /// + /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resource.Name of the resource that the Last_modified should be set for + /// ModificationTime - Last_modified value the resource should have + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// Last_Modified: which equals the newModificationTime + /// + public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(string webAppName, ApiWebAppResource resource, DateTime newModificationTime) + => WebAppSetResourceModificationTimeAsync(webAppName, resource, newModificationTime).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resource.Name of the resource that the Last_modified should be set for + /// ModificationTime - Last_modified value the resource should have + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// Last_Modified: which equals the newModificationTime + /// public async Task WebAppSetResourceModificationTimeAsync(string webAppName, ApiWebAppResource resource, - string newModificationTime) - { - var basicResp = await WebAppSetResourceModificationTimeAsync(webAppName, resource.Name, newModificationTime); - var last_mod = basicResp.NewResource.Last_modified; - basicResp.NewResource = resource.ShallowCopy(); - basicResp.NewResource.Last_modified = last_mod; - return basicResp; - } - /// - /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resource.Name of the resource that the Last_modified should be set for - /// ModificationTime - Last_modified value the resource should have - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// Last_Modified: which equals the newModificationTime - /// - public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(string webAppName, ApiWebAppResource resource, string newModificationTime) - => WebAppSetResourceModificationTimeAsync(webAppName, resource, newModificationTime).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceVisibility Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resourceName of the resource that the Visibility should be set for - /// Visibility value the resource should have - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// Visibility: which equals the newVisibility - /// + string newModificationTime, CancellationToken cancellationToken = default(CancellationToken)) + { + var basicResp = await WebAppSetResourceModificationTimeAsync(webAppName, resource.Name, newModificationTime, cancellationToken); + var last_mod = basicResp.NewResource.Last_modified; + basicResp.NewResource = resource.ShallowCopy(); + basicResp.NewResource.Last_modified = last_mod; + return basicResp; + } + /// + /// Send a WebApp.SetResourceModificationTime Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resource.Name of the resource that the Last_modified should be set for + /// ModificationTime - Last_modified value the resource should have + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// Last_Modified: which equals the newModificationTime + /// + public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(string webAppName, ApiWebAppResource resource, string newModificationTime) + => WebAppSetResourceModificationTimeAsync(webAppName, resource, newModificationTime).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetResourceVisibility Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resourceName of the resource that the Visibility should be set for + /// Visibility value the resource should have + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// Visibility: which equals the newVisibility + /// public async Task WebAppSetResourceVisibilityAsync(string webAppName, string resourceName, - ApiWebAppResourceVisibility newResourceVisibility) - { - var req = _apiRequestFactory.GetApiSetResourceVisibilityRequest(webAppName, resourceName, newResourceVisibility); - string response = await SendPostRequestAsync(req); - var responseObj = new ApiTrueWithResourceResponse(); - responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); - if (responseObj.TrueOnSuccesResponse.Result) - { - responseObj.NewResource = new ApiWebAppResource() { Name = resourceName, Visibility = newResourceVisibility }; - } - return responseObj; - } - /// - /// Send a WebApp.SetResourceVisibility Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resourceName of the resource that the Visibility should be set for - /// Visibility value the resource should have - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// Visibility: which equals the newVisibility - /// - public ApiTrueWithResourceResponse WebAppSetResourceVisibility(string webAppName, string resourceName, ApiWebAppResourceVisibility newResourceVisibility) - => WebAppSetResourceVisibilityAsync(webAppName, resourceName, newResourceVisibility).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceVisibility Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resourceName of the resource that the Visibility should be set for - /// Visibility value the resource should have - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// Visibility: which equals the newResourceVisibility - /// + ApiWebAppResourceVisibility newResourceVisibility, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiSetResourceVisibilityRequest(webAppName, resourceName, newResourceVisibility); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = new ApiTrueWithResourceResponse(); + responseObj.TrueOnSuccesResponse = JsonConvert.DeserializeObject(response); + if (responseObj.TrueOnSuccesResponse.Result) + { + responseObj.NewResource = new ApiWebAppResource() { Name = resourceName, Visibility = newResourceVisibility }; + } + return responseObj; + } + /// + /// Send a WebApp.SetResourceVisibility Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resourceName of the resource that the Visibility should be set for + /// Visibility value the resource should have + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// Visibility: which equals the newVisibility + /// + public ApiTrueWithResourceResponse WebAppSetResourceVisibility(string webAppName, string resourceName, ApiWebAppResourceVisibility newResourceVisibility) + => WebAppSetResourceVisibilityAsync(webAppName, resourceName, newResourceVisibility).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetResourceVisibility Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resourceName of the resource that the Visibility should be set for + /// Visibility value the resource should have + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// Visibility: which equals the newResourceVisibility + /// public async Task WebAppSetResourceVisibilityAsync(ApiWebAppData webApp, string resourceName, - ApiWebAppResourceVisibility newResourceVisibility) - { - return await WebAppSetResourceVisibilityAsync(webApp.Name, resourceName, newResourceVisibility); - } - /// - /// Send a WebApp.SetResourceVisibility Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resourceName of the resource that the Visibility should be set for - /// Visibility value the resource should have - /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: - /// Name: which equals the resourceName - /// Visibility: which equals the newResourceVisibility - /// - public ApiTrueWithResourceResponse WebAppSetResourceVisibility(ApiWebAppData webApp, string resourceName, ApiWebAppResourceVisibility newResourceVisibility) - => WebAppSetResourceVisibilityAsync(webApp, resourceName, newResourceVisibility).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceVisibility Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resource.Name of the resource that the Visibility should be set for - /// Visibility value the resource should have - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// Visibility: which equals the newResourceVisibility - /// + ApiWebAppResourceVisibility newResourceVisibility, CancellationToken cancellationToken = default(CancellationToken)) + { + return await WebAppSetResourceVisibilityAsync(webApp.Name, resourceName, newResourceVisibility, cancellationToken); + } + /// + /// Send a WebApp.SetResourceVisibility Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resourceName of the resource that the Visibility should be set for + /// Visibility value the resource should have + /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: + /// Name: which equals the resourceName + /// Visibility: which equals the newResourceVisibility + /// + public ApiTrueWithResourceResponse WebAppSetResourceVisibility(ApiWebAppData webApp, string resourceName, ApiWebAppResourceVisibility newResourceVisibility) + => WebAppSetResourceVisibilityAsync(webApp, resourceName, newResourceVisibility).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetResourceVisibility Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resource.Name of the resource that the Visibility should be set for + /// Visibility value the resource should have + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// Visibility: which equals the newResourceVisibility + /// public async Task WebAppSetResourceVisibilityAsync(ApiWebAppData webApp, ApiWebAppResource resource, - ApiWebAppResourceVisibility newResourceVisibility) - { - var basicResp = await WebAppSetResourceVisibilityAsync(webApp.Name, resource.Name, newResourceVisibility); - basicResp.NewResource = resource.ShallowCopy(); - basicResp.NewResource.Visibility = newResourceVisibility; - return basicResp; - } - /// - /// Send a WebApp.SetResourceVisibility Request using the Request from the ApiRequestFactory - /// - /// webApp.Name of the webapp that contains the resource - /// resource.Name of the resource that the Visibility should be set for - /// Visibility value the resource should have - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// Visibility: which equals the newResourceVisibility - /// - public ApiTrueWithResourceResponse WebAppSetResourceVisibility(ApiWebAppData webApp, ApiWebAppResource resource, ApiWebAppResourceVisibility newResourceVisibility) - => WebAppSetResourceVisibilityAsync(webApp, resource, newResourceVisibility).GetAwaiter().GetResult(); - - /// - /// Send a WebApp.SetResourceVisibility Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resource.Name of the resource that the Visibility should be set for - /// Visibility value the resource should have - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// Visibility: which equals the newResourceVisibility - /// + ApiWebAppResourceVisibility newResourceVisibility, CancellationToken cancellationToken = default(CancellationToken)) + { + var basicResp = await WebAppSetResourceVisibilityAsync(webApp.Name, resource.Name, newResourceVisibility, cancellationToken); + basicResp.NewResource = resource.ShallowCopy(); + basicResp.NewResource.Visibility = newResourceVisibility; + return basicResp; + } + /// + /// Send a WebApp.SetResourceVisibility Request using the Request from the ApiRequestFactory + /// + /// webApp.Name of the webapp that contains the resource + /// resource.Name of the resource that the Visibility should be set for + /// Visibility value the resource should have + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// Visibility: which equals the newResourceVisibility + /// + public ApiTrueWithResourceResponse WebAppSetResourceVisibility(ApiWebAppData webApp, ApiWebAppResource resource, ApiWebAppResourceVisibility newResourceVisibility) + => WebAppSetResourceVisibilityAsync(webApp, resource, newResourceVisibility).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetResourceVisibility Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resource.Name of the resource that the Visibility should be set for + /// Visibility value the resource should have + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// Visibility: which equals the newResourceVisibility + /// public async Task WebAppSetResourceVisibilityAsync(string webAppName, ApiWebAppResource resource, - ApiWebAppResourceVisibility newResourceVisibility) - { - var basicResp = await WebAppSetResourceVisibilityAsync(webAppName, resource.Name, newResourceVisibility); - basicResp.NewResource = resource.ShallowCopy(); - basicResp.NewResource.Visibility = newResourceVisibility; - return basicResp; - } - /// - /// Send a WebApp.SetResourceVisibility Request using the Request from the ApiRequestFactory - /// - /// webAppName of the webapp that contains the resource - /// resource.Name of the resource that the Visibility should be set for - /// Visibility value the resource should have - /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: - /// Visibility: which equals the newResourceVisibility - /// - public ApiTrueWithResourceResponse WebAppSetResourceVisibility(string webAppName, ApiWebAppResource resource, ApiWebAppResourceVisibility newResourceVisibility) - => WebAppSetResourceVisibilityAsync(webAppName, resource, newResourceVisibility).GetAwaiter().GetResult(); - - /// - /// Function to get the ByteArray and the HTTP response Requested by a Ticket (e.g. DownloadResource) - /// + ApiWebAppResourceVisibility newResourceVisibility, CancellationToken cancellationToken = default(CancellationToken)) + { + var basicResp = await WebAppSetResourceVisibilityAsync(webAppName, resource.Name, newResourceVisibility, cancellationToken); + basicResp.NewResource = resource.ShallowCopy(); + basicResp.NewResource.Visibility = newResourceVisibility; + return basicResp; + } + /// + /// Send a WebApp.SetResourceVisibility Request using the Request from the ApiRequestFactory + /// + /// webAppName of the webapp that contains the resource + /// resource.Name of the resource that the Visibility should be set for + /// Visibility value the resource should have + /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: + /// Visibility: which equals the newResourceVisibility + /// + public ApiTrueWithResourceResponse WebAppSetResourceVisibility(string webAppName, ApiWebAppResource resource, ApiWebAppResourceVisibility newResourceVisibility) + => WebAppSetResourceVisibilityAsync(webAppName, resource, newResourceVisibility).GetAwaiter().GetResult(); + + /// + /// Function to get the ByteArray and the HTTP response Requested by a Ticket (e.g. DownloadResource) + /// /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=+ticketId + /// Cancellation token to cancel pending requests. /// HTTP response - public async Task DownloadTicketAndGetResponseAsync(string ticketId) - { - var request_body = new ByteArrayContent(new byte[0]); - request_body.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"); - var response = await _httpClient.PostAsync($"/api/ticket?id={ticketId}", request_body); + public async Task DownloadTicketAndGetResponseAsync(string ticketId, CancellationToken cancellationToken = default(CancellationToken)) + { + var request_body = new ByteArrayContent(new byte[0]); + request_body.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"); + var response = await _httpClient.PostAsync($"/api/ticket?id={ticketId}", request_body, cancellationToken); response.EnsureSuccessStatusCode(); return response; } /// - /// Function to get the ByteArray and the HTTP response Requested by a Ticket (e.g. DownloadResource) - /// + /// Function to get the ByteArray and the HTTP response Requested by a Ticket (e.g. DownloadResource) + /// /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=+ticketId /// HTTP response public HttpResponseMessage DownloadTicketAndGetResponse(string ticketId) => DownloadTicketAndGetResponseAsync(ticketId).GetAwaiter().GetResult(); /// - /// Function to get the ByteArray and the HTTP response Requested by a Ticket (e.g. DownloadResource) - /// + /// Function to get the ByteArray and the HTTP response Requested by a Ticket (e.g. DownloadResource) + /// /// The Ticket - will be used to send the request to the endpoint /api/ticket?id=+ticketId + /// Cancellation token to cancel pending requests. /// HTTP response - public async Task DownloadTicketAndGetResponseAsync(ApiTicket ticket) - => await DownloadTicketAndGetResponseAsync(ticket.Id); - + public async Task DownloadTicketAndGetResponseAsync(ApiTicket ticket, CancellationToken cancellationToken = default(CancellationToken)) + => await DownloadTicketAndGetResponseAsync(ticket.Id, cancellationToken); + /// - /// Function to get the ByteArray and the HTTP response Requested by a Ticket (e.g. DownloadResource) - /// + /// Function to get the ByteArray and the HTTP response Requested by a Ticket (e.g. DownloadResource) + /// /// The Ticket - will be used to send the request to the endpoint /api/ticket?id=+ticketId /// HTTP response public HttpResponseMessage DownloadTicketAndGetResponse(ApiTicket ticket) => DownloadTicketAndGetResponseAsync(ticket).GetAwaiter().GetResult(); - - /// - /// Function to get the ByteArray Requested by a Ticket (e.g. DownloadResource) - /// - /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=+ticketId - /// Bytearray given from the PLC - public async Task DownloadTicketAsync(string ticketId) - { - var response = await DownloadTicketAndGetResponseAsync(ticketId); + + /// + /// Function to get the ByteArray Requested by a Ticket (e.g. DownloadResource) + /// + /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=+ticketId + /// Cancellation token to cancel pending requests. + /// Bytearray given from the PLC + public async Task DownloadTicketAsync(string ticketId, CancellationToken cancellationToken = default(CancellationToken)) + { + var response = await DownloadTicketAndGetResponseAsync(ticketId, cancellationToken); return await response.Content.ReadAsByteArrayAsync(); - } - - /// - /// Function to get the ByteArray Requested by a Ticket (e.g. DownloadResource) - /// - /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=+ticketId - /// Bytearray given from the PLC + } + + /// + /// Function to get the ByteArray Requested by a Ticket (e.g. DownloadResource) + /// + /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=+ticketId + /// Bytearray given from the PLC public byte[] DownloadTicket(string ticketId) => DownloadTicketAsync(ticketId).GetAwaiter().GetResult(); - /// - /// Function to get the ByteArray Requested by a Ticket (e.g. DownloadResource) - /// - /// The Ticket - will be used to send the request to the endpoint /api/ticket?id=+ticketId - /// Bytearray given from the PLC - public async Task DownloadTicketAsync(ApiTicket ticket) - => await DownloadTicketAsync(ticket.Id); - - /// - /// Function to get the ByteArray Requested by a Ticket (e.g. DownloadResource) - /// - /// The Ticket - will be used to send the request to the endpoint /api/ticket?id=+ticketId - /// Bytearray given from the PLC + /// + /// Function to get the ByteArray Requested by a Ticket (e.g. DownloadResource) + /// + /// The Ticket - will be used to send the request to the endpoint /api/ticket?id=+ticketId + /// Cancellation token to cancel pending requests. + /// Bytearray given from the PLC + public async Task DownloadTicketAsync(ApiTicket ticket, CancellationToken cancellationToken = default(CancellationToken)) + => await DownloadTicketAsync(ticket.Id, cancellationToken); + + /// + /// Function to get the ByteArray Requested by a Ticket (e.g. DownloadResource) + /// + /// The Ticket - will be used to send the request to the endpoint /api/ticket?id=+ticketId + /// Bytearray given from the PLC public byte[] DownloadTicket(ApiTicket ticket) => DownloadTicketAsync(ticket).GetAwaiter().GetResult(); - /// - /// Function to send the ByteArrayContent for a Ticket (e.g. CreateResource) - /// MediaTypeHeaderValue: application/octet-stream - /// - /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId - /// ByteArray that should be sent to the plc Ticketing Endpoint - /// Task/void - public async Task UploadTicketAsync(string ticketId, ByteArrayContent data) - { - data.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"); - try - { - var response = await _httpClient.PostAsync($"/api/ticket?id={ticketId}", data); - response.EnsureSuccessStatusCode(); - } - catch (Exception e) - { - throw new ApiTicketingEndpointUploadException(ticketId, e); - } - } - /// - /// Function to send the ByteArrayContent for a Ticket (e.g. CreateResource) - /// MediaTypeHeaderValue: application/octet-stream - /// - /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId - /// ByteArray that should be sent to the plc Ticketing Endpoint - /// Task/void + /// + /// Function to send the ByteArrayContent for a Ticket (e.g. CreateResource) + /// MediaTypeHeaderValue: application/octet-stream + /// + /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId + /// ByteArray that should be sent to the plc Ticketing Endpoint + /// Task/void + public async Task UploadTicketAsync(string ticketId, ByteArrayContent data, CancellationToken cancellationToken = default(CancellationToken)) + { + data.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"); + try + { + var response = await _httpClient.PostAsync($"/api/ticket?id={ticketId}", data, cancellationToken); + response.EnsureSuccessStatusCode(); + } + catch (Exception e) + { + throw new ApiTicketingEndpointUploadException(ticketId, e); + } + } + /// + /// Function to send the ByteArrayContent for a Ticket (e.g. CreateResource) + /// MediaTypeHeaderValue: application/octet-stream + /// + /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId + /// ByteArray that should be sent to the plc Ticketing Endpoint + /// Task/void public void UploadTicket(string ticketId, ByteArrayContent data) => UploadTicketAsync(ticketId, data).GetAwaiter().GetResult(); - /// - /// Function to send the ByteArrayContent for a Ticket (e.g. CreateResource) - /// MediaTypeHeaderValue: application/octet-stream - /// - /// The Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId - /// ByteArray that should be sent to the plc Ticketing Endpoint - /// Task/void - public async Task UploadTicketAsync(ApiTicket ticket, ByteArrayContent data) - => await UploadTicketAsync(ticket.Id, data); - - /// - /// Function to send the ByteArrayContent for a Ticket (e.g. CreateResource) - /// MediaTypeHeaderValue: application/octet-stream - /// - /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId - /// ByteArray that should be sent to the plc Ticketing Endpoint - /// Task/void - public void UploadTicket(ApiTicket ticket, ByteArrayContent data) - => UploadTicketAsync(ticket, data).GetAwaiter().GetResult(); - - /// - /// Function to Read and send the ByteArrayContent for a file with the Ticketing Endpoint Ticket (e.g. CreateResource) - /// MediaTypeHeaderValue: application/octet-stream - /// - /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId - /// File Bytes will be Read and saved into ByteArrayContent - then sent to the ticketing Endpoint - /// Task/void - public async Task UploadTicketAsync(string ticketId, string pathToFile) - { - if (!File.Exists(pathToFile)) - { - throw new FileNotFoundException($"file at: {pathToFile} not found!"); - } - var fileContent = new ByteArrayContent(File.ReadAllBytes(pathToFile)); - await UploadTicketAsync(ticketId, fileContent); - } - /// - /// Function to Read and send the ByteArrayContent for a file with the Ticketing Endpoint Ticket (e.g. CreateResource) - /// MediaTypeHeaderValue: application/octet-stream - /// - /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId - /// File Bytes will be Read and saved into ByteArrayContent - then sent to the ticketing Endpoint - /// Task/void - public void UploadTicket(string ticketId, string pathToFile) => UploadTicketAsync(ticketId, pathToFile).GetAwaiter().GetResult(); - - /// - /// Function to Read and send the ByteArrayContent for a file with the Ticketing Endpoint Ticket (e.g. CreateResource) - /// MediaTypeHeaderValue: application/octet-stream - /// - /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId - /// File Bytes will be Read and saved into ByteArrayContent - then sent to the ticketing Endpoint - /// Task/void - public async Task UploadTicketAsync(string ticketId, FileInfo pathToFile) - => await UploadTicketAsync(ticketId, pathToFile.FullName); - /// - /// Function to Read and send the ByteArrayContent for a file with the Ticketing Endpoint Ticket (e.g. CreateResource) - /// MediaTypeHeaderValue: application/octet-stream - /// - /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId - /// File Bytes will be Read and saved into ByteArrayContent - then sent to the ticketing Endpoint - /// Task/void - public void UploadTicket(string ticketId, FileInfo pathToFile) - => UploadTicketAsync(ticketId, pathToFile).GetAwaiter().GetResult(); - + /// + /// Function to send the ByteArrayContent for a Ticket (e.g. CreateResource) + /// MediaTypeHeaderValue: application/octet-stream + /// + /// The Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId + /// ByteArray that should be sent to the plc Ticketing Endpoint + /// Task/void + public async Task UploadTicketAsync(ApiTicket ticket, ByteArrayContent data, CancellationToken cancellationToken = default(CancellationToken)) + => await UploadTicketAsync(ticket.Id, data, cancellationToken); + + /// + /// Function to send the ByteArrayContent for a Ticket (e.g. CreateResource) + /// MediaTypeHeaderValue: application/octet-stream + /// + /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId + /// ByteArray that should be sent to the plc Ticketing Endpoint + /// Task/void + public void UploadTicket(ApiTicket ticket, ByteArrayContent data) + => UploadTicketAsync(ticket, data).GetAwaiter().GetResult(); + + /// + /// Function to Read and send the ByteArrayContent for a file with the Ticketing Endpoint Ticket (e.g. CreateResource) + /// MediaTypeHeaderValue: application/octet-stream + /// + /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId + /// File Bytes will be Read and saved into ByteArrayContent - then sent to the ticketing Endpoint + /// Task/void + public async Task UploadTicketAsync(string ticketId, string pathToFile, CancellationToken cancellationToken = default(CancellationToken)) + { + if (!File.Exists(pathToFile)) + { + throw new FileNotFoundException($"file at: {pathToFile} not found!"); + } + var fileContent = new ByteArrayContent(File.ReadAllBytes(pathToFile)); + await UploadTicketAsync(ticketId, fileContent, cancellationToken); + } + /// + /// Function to Read and send the ByteArrayContent for a file with the Ticketing Endpoint Ticket (e.g. CreateResource) + /// MediaTypeHeaderValue: application/octet-stream + /// + /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId + /// File Bytes will be Read and saved into ByteArrayContent - then sent to the ticketing Endpoint + /// Task/void + public void UploadTicket(string ticketId, string pathToFile) => UploadTicketAsync(ticketId, pathToFile).GetAwaiter().GetResult(); + + /// + /// Function to Read and send the ByteArrayContent for a file with the Ticketing Endpoint Ticket (e.g. CreateResource) + /// MediaTypeHeaderValue: application/octet-stream + /// + /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId + /// File Bytes will be Read and saved into ByteArrayContent - then sent to the ticketing Endpoint + /// Task/void + public async Task UploadTicketAsync(string ticketId, FileInfo pathToFile, CancellationToken cancellationToken = default(CancellationToken)) + => await UploadTicketAsync(ticketId, pathToFile.FullName, cancellationToken); + /// + /// Function to Read and send the ByteArrayContent for a file with the Ticketing Endpoint Ticket (e.g. CreateResource) + /// MediaTypeHeaderValue: application/octet-stream + /// + /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId + /// File Bytes will be Read and saved into ByteArrayContent - then sent to the ticketing Endpoint + /// Task/void + public void UploadTicket(string ticketId, FileInfo pathToFile) + => UploadTicketAsync(ticketId, pathToFile).GetAwaiter().GetResult(); + /// /// Function to Read and send the ByteArrayContent for a file with the Ticketing Endpoint Ticket (e.g. CreateResource) /// MediaTypeHeaderValue: application/octet-stream @@ -2428,8 +2598,8 @@ public void UploadTicket(string ticketId, FileInfo pathToFile) /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId /// File Bytes will be Read and saved into ByteArrayContent - then sent to the ticketing Endpoint /// Task/void - public async Task UploadTicketAsync(ApiTicket ticket, string pathToFile) - => await UploadTicketAsync(ticket.Id, pathToFile); + public async Task UploadTicketAsync(ApiTicket ticket, string pathToFile, CancellationToken cancellationToken = default(CancellationToken)) + => await UploadTicketAsync(ticket.Id, pathToFile, cancellationToken); /// /// Function to Read and send the ByteArrayContent for a file with the Ticketing Endpoint Ticket (e.g. CreateResource) @@ -2447,8 +2617,8 @@ public async Task UploadTicketAsync(ApiTicket ticket, string pathToFile) /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId /// File Bytes will be Read and saved into ByteArrayContent - then sent to the ticketing Endpoint /// Task/void - public async Task UploadTicketAsync(ApiTicket ticket, FileInfo pathToFile) - => await UploadTicketAsync(ticket, pathToFile.FullName); + public async Task UploadTicketAsync(ApiTicket ticket, FileInfo pathToFile, CancellationToken cancellationToken = default(CancellationToken)) + => await UploadTicketAsync(ticket, pathToFile.FullName, cancellationToken); /// /// Function to Read and send the ByteArrayContent for a file with the Ticketing Endpoint Ticket (e.g. CreateResource) /// MediaTypeHeaderValue: application/octet-stream @@ -2457,135 +2627,177 @@ public async Task UploadTicketAsync(ApiTicket ticket, FileInfo pathToFile) /// File Bytes will be Read and saved into ByteArrayContent - then sent to the ticketing Endpoint /// Task/void public void UploadTicket(ApiTicket ticket, FileInfo pathToFile) - => UploadTicketAsync(ticket, pathToFile).GetAwaiter().GetResult(); - - /// - /// Send a Api.Login Request using the Request from the ApiRequestFactory - /// - /// Username to login with - /// Password for the user to login with - /// Used to determine wether or not a WebApplicationCookie should be included in the Response (Result) - /// ApiLoginResponse: contains ApiTokenResult: Token(auth token string) and if requested Web_application_cookie - public async Task ApiLoginAsync(string userName, string password, bool? includeWebApplicationCookie = null) - { - var req = _apiRequestFactory.GetApiLoginRequest(userName, password, includeWebApplicationCookie); - string response = await SendPostRequestAsync(req); - var responseObj = new ApiLoginResponse(); - responseObj = JsonConvert.DeserializeObject(response); - if(!string.IsNullOrEmpty(responseObj.Result.Token)) + => UploadTicketAsync(ticket, pathToFile).GetAwaiter().GetResult(); + + /// + /// Send a Api.Login Request using the Request from the ApiRequestFactory + /// + /// Username to login with + /// Password for the user to login with + /// Used to determine wether or not a WebApplicationCookie should be included in the Response (Result) + /// ApiLoginResponse: contains ApiTokenResult: Token(auth token string) and if requested Web_application_cookie + public async Task ApiLoginAsync(string userName, string password, bool? includeWebApplicationCookie = null, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiLoginRequest(userName, password, includeWebApplicationCookie); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = new ApiLoginResponse(); + responseObj = JsonConvert.DeserializeObject(response); + if (!string.IsNullOrEmpty(responseObj.Result.Token)) { - if(_httpClient.DefaultRequestHeaders.Any(x => x.Key.Contains("X-Auth-Token"))) + if (_httpClient.DefaultRequestHeaders.Any(x => x.Key.Contains("X-Auth-Token"))) { _httpClient.DefaultRequestHeaders.Remove("X-Auth-Token"); } _httpClient.DefaultRequestHeaders.Add("X-Auth-Token", responseObj.Result.Token); - } - return responseObj; - } - /// - /// Send a Api.Login Request using the Request from the ApiRequestFactory - /// - /// Username to login with - /// Password for the user to login with - /// Used to determine wether or not a WebApplicationCookie should be included in the Response (Result) - /// ApiLoginResponse: contains ApiTokenResult: Token(auth token string) and if requested Web_application_cookie - public ApiLoginResponse ApiLogin(string userName, string password, bool? includeWebApplicationCookie = null) => ApiLoginAsync(userName, password, includeWebApplicationCookie).GetAwaiter().GetResult(); - - /// - /// Send an Api Bulk Request - /// - /// Api Requests to be sent as Bulk - /// List of ApiResultResponses with Result as object - not "directly" casted to the expected Result type - public async Task ApiBulkAsync(IEnumerable apiRequests) - { - if ((apiRequests.GroupBy(el => el.Id).Count() != apiRequests.Count())) - { - throw new ArgumentException($"{nameof(apiRequests)} contains multiple requests with the same Id!"); - } - foreach (var apiRequest in apiRequests) - { - if (apiRequest.Params != null) - { - apiRequest.Params = apiRequest.Params - .Where(el => el.Value != null) - .ToDictionary(x => x.Key, x => x.Value); - } - } - string apiRequestString = JsonConvert.SerializeObject(apiRequests, new JsonSerializerSettings() - { NullValueHandling = NullValueHandling.Ignore, ContractResolver = new CamelCasePropertyNamesContractResolver() }); - byte[] byteArr = Encoding.GetBytes(apiRequestString); - ByteArrayContent request_body = new ByteArrayContent(byteArr); - request_body.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(ContentType); - var response = await _httpClient.PostAsync(JsonRpcApi, request_body); - _apiResponseChecker.CheckHttpResponseForErrors(response, apiRequestString); - var responseString = await response.Content.ReadAsStringAsync(); - ApiBulkResponse bulkResponse = new ApiBulkResponse(); - var errorResponses = JsonConvert.DeserializeObject>(responseString) - .Where(el => el.Error != null); - bulkResponse.ErrorResponses = errorResponses; - var successfulResponses = JsonConvert.DeserializeObject>>(responseString) - .Where(el => el.Result != null); - bulkResponse.SuccessfulResponses = successfulResponses; - if (bulkResponse.ContainsErrors) - { - throw new ApiBulkRequestException(bulkResponse); - } - return bulkResponse; - } - /// - /// Send an Api Bulk Request - /// - /// Api Requests to be sent as Bulk - /// List of ApiResultResponses with Result as object - not "directly" casted to the expected Result type - public ApiBulkResponse ApiBulk(IEnumerable apiRequests) => ApiBulkAsync(apiRequests).GetAwaiter().GetResult(); - - /// - /// Send a Plc.ReadSystemTime Request - /// - /// Current Plc Utc System Time - public async Task PlcReadSystemTimeAsync() - { - var req = _apiRequestFactory.GetApiPlcReadSystemTimeRequest(); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); - return responseObj; - } - - /// - /// Send a Plc.ReadSystemTime Request - /// - /// Current Plc Utc System Time - public ApiPlcReadSystemTimeResponse PlcReadSystemTime() => PlcReadSystemTimeAsync().GetAwaiter().GetResult(); - - /// - /// Send a Plc.ReadTimeSettings Request - /// - /// Current Plc Time Settings - public async Task PlcReadTimeSettingsAsync() - { - var req = _apiRequestFactory.GetApiPlcReadTimeSettingsRequest(); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); - return responseObj; - } - - /// - /// Send a Plc.ReadTimeSettings Request - /// - /// Current Plc Time Settings + } + return responseObj; + } + /// + /// Send a Api.Login Request using the Request from the ApiRequestFactory + /// + /// Username to login with + /// Password for the user to login with + /// Used to determine wether or not a WebApplicationCookie should be included in the Response (Result) + /// ApiLoginResponse: contains ApiTokenResult: Token(auth token string) and if requested Web_application_cookie + public ApiLoginResponse ApiLogin(string userName, string password, bool? includeWebApplicationCookie = null) => ApiLoginAsync(userName, password, includeWebApplicationCookie).GetAwaiter().GetResult(); + + /// + /// Send an Api Bulk Request + /// + /// Api Requests to be sent as Bulk + /// List of ApiResultResponses with Result as object - not "directly" casted to the expected Result type + public async Task ApiBulkAsync(IEnumerable apiRequests, CancellationToken cancellationToken = default(CancellationToken)) + { + if ((apiRequests.GroupBy(el => el.Id).Count() != apiRequests.Count())) + { + throw new ArgumentException($"{nameof(apiRequests)} contains multiple requests with the same Id!"); + } + foreach (var apiRequest in apiRequests) + { + if (apiRequest.Params != null) + { + apiRequest.Params = apiRequest.Params + .Where(el => el.Value != null) + .ToDictionary(x => x.Key, x => x.Value); + } + } + string apiRequestString = JsonConvert.SerializeObject(apiRequests, new JsonSerializerSettings() + { NullValueHandling = NullValueHandling.Ignore, ContractResolver = new CamelCasePropertyNamesContractResolver() }); + byte[] byteArr = Encoding.GetBytes(apiRequestString); + ByteArrayContent request_body = new ByteArrayContent(byteArr); + request_body.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(ContentType); + var response = await _httpClient.PostAsync(JsonRpcApi, request_body, cancellationToken); + _apiResponseChecker.CheckHttpResponseForErrors(response, apiRequestString); + var responseString = await response.Content.ReadAsStringAsync(); + ApiBulkResponse bulkResponse = new ApiBulkResponse(); + var errorResponses = JsonConvert.DeserializeObject>(responseString) + .Where(el => el.Error != null); + bulkResponse.ErrorResponses = errorResponses; + var successfulResponses = JsonConvert.DeserializeObject>>(responseString) + .Where(el => el.Result != null); + bulkResponse.SuccessfulResponses = successfulResponses; + if (bulkResponse.ContainsErrors) + { + throw new ApiBulkRequestException(bulkResponse); + } + return bulkResponse; + } + /// + /// Send an Api Bulk Request + /// + /// Api Requests to be sent as Bulk + /// List of ApiResultResponses with Result as object - not "directly" casted to the expected Result type + public ApiBulkResponse ApiBulk(IEnumerable apiRequests) => ApiBulkAsync(apiRequests).GetAwaiter().GetResult(); + + /// + /// Send a Plc.ReadSystemTime Request + /// + /// Current Plc Utc System Time + public async Task PlcReadSystemTimeAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiPlcReadSystemTimeRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + + /// + /// Send a Plc.ReadSystemTime Request + /// + /// Current Plc Utc System Time + public ApiPlcReadSystemTimeResponse PlcReadSystemTime() => PlcReadSystemTimeAsync().GetAwaiter().GetResult(); + + /// + /// Send an Plc.SetSystemTime Request + /// + /// The timestamp of the system time to be set + /// True if time was set successfully + public async Task PlcSetSystemTimeAsync(DateTime timestamp, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiPlcSetSystemTimeRequest(timestamp); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + /// + /// Send an Plc.SetSystemTime Request + /// + /// The timestamp of the system time to be set + /// True if time was set successfully + public ApiTrueOnSuccessResponse PlcSetSystemTime(DateTime timestamp) => + PlcSetSystemTimeAsync(timestamp).GetAwaiter().GetResult(); + + /// + /// Send a Plc.ReadTimeSettings Request + /// + /// Current Plc Time Settings + public async Task PlcReadTimeSettingsAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiPlcReadTimeSettingsRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + + /// + /// Send a Plc.ReadTimeSettings Request + /// + /// Current Plc Time Settings public ApiPlcReadTimeSettingsResponse PlcReadTimeSettings() => PlcReadTimeSettingsAsync().GetAwaiter().GetResult(); + /// + /// Send a Plc.SetTimeSettings Request with parameters + /// + /// The time zone offset from the UTC time in hours + /// (Optional) Represents the settings for daylight-savings. If there is no daylight-savings rule configured, the utcOffset is applied to calculate the local time + /// True if the settings are applied successfully + public async Task PlcSetTimeSettingsAsync(TimeSpan utcOffset, DaylightSavingsRule daylightSavings = null, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiPlcSetTimeSettingsRequest(utcOffset, daylightSavings); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + + /// + /// Send a Plc.SetTimeSettings Request with parameters + /// + /// The time zone offset from the UTC time in hours + /// (Optional) Represents the settings for daylight-savings. If there is no daylight-savings rule configured, the utcOffset is applied to calculate the local time + /// True if the settings are applied successfully + public ApiTrueOnSuccessResponse PlcSetTimeSettings(TimeSpan utcOffset, DaylightSavingsRule daylightSavings = null) => + PlcSetTimeSettingsAsync(utcOffset, daylightSavings = null).GetAwaiter().GetResult(); /// /// Send a Files.Browse Request /// /// Path of the directory or file relative to the memory card root to fetch the entry list. /// The resource name must start with a "/". The parameter may be omitted.In that case, it will default to "/". /// Browsed resources (files/dir/...) - public async Task FilesBrowseAsync(string resource = null) + public async Task FilesBrowseAsync(string resource = null, CancellationToken cancellationToken = default(CancellationToken)) { var req = _apiRequestFactory.GetApiFilesBrowseRequest(string.IsNullOrEmpty(resource) ? "/" : resource); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); return responseObj; } @@ -2602,7 +2814,8 @@ public async Task FilesBrowseAsync(string resource = nul /// /// resource to browse: file/dir/... /// Browsed resources (files/dir/...) - public async Task FilesBrowseAsync(ApiFileResource resource) => await FilesBrowseAsync(resource.GetVarNameForMethods()); + public async Task FilesBrowseAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)) + => await FilesBrowseAsync(resource.GetVarNameForMethods(), cancellationToken); /// /// Send a Files.Browse Request @@ -2617,11 +2830,11 @@ public async Task FilesBrowseAsync(string resource = nul /// /// Path of the file relative to the memory card root. /// Ticket ID. - public async Task FilesDownloadAsync(string resource) + public async Task FilesDownloadAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)) { var req = _apiRequestFactory.GetApiFilesDownloadRequest(resource); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); return responseObj; } @@ -2638,12 +2851,12 @@ public async Task FilesDownloadAsync(string resource) /// /// Path of the file relative to the memory card root. /// Ticket ID. - public async Task FilesCreateAsync(string resource) + public async Task FilesCreateAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)) { var req = _apiRequestFactory.GetApiFilesCreateRequest(resource); - string response = await SendPostRequestAsync(req); - var singleStringResp = JsonConvert.DeserializeObject(response); - var responseObj = new ApiTicketIdResponse(singleStringResp); + string response = await SendPostRequestAsync(req, cancellationToken); + var singleStringResp = JsonConvert.DeserializeObject(response); + var responseObj = new ApiTicketIdResponse(singleStringResp); return responseObj; } @@ -2659,8 +2872,8 @@ public async Task FilesCreateAsync(string resource) /// /// FileInfo for informations about the file to the memory card root. /// Ticket ID. - public async Task FilesCreateAsync(FileInfo resource) - => await FilesCreateAsync(resource.FullName); + public async Task FilesCreateAsync(FileInfo resource, CancellationToken cancellationToken = default(CancellationToken)) + => await FilesCreateAsync(resource.FullName, cancellationToken); /// /// Send a Files.Create request @@ -2675,11 +2888,11 @@ public async Task FilesCreateAsync(FileInfo resource) /// Current path of file/folder /// New path of file/folder /// True if the file or folder is renamed successfully - public async Task FilesRenameAsync(string resource, string new_resource) + public async Task FilesRenameAsync(string resource, string new_resource, CancellationToken cancellationToken = default(CancellationToken)) { var req = _apiRequestFactory.GetApiFilesRenameRequest(resource, new_resource); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); return responseObj; } @@ -2696,11 +2909,11 @@ public async Task FilesRenameAsync(string resource, st /// /// Path of the file relative to the memory card root. /// True if the file is deleted successfully - public async Task FilesDeleteAsync(string resource) + public async Task FilesDeleteAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)) { var req = _apiRequestFactory.GetApiFilesDeleteRequest(resource); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); return responseObj; } @@ -2716,11 +2929,11 @@ public async Task FilesDeleteAsync(string resource) /// /// Path of the file relative to the memory card root. /// True if the directory is created successfully - public async Task FilesCreateDirectoryAsync(string resource) + public async Task FilesCreateDirectoryAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)) { var req = _apiRequestFactory.GetApiFilesCreateDirectoryRequest(resource); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); return responseObj; } @@ -2737,11 +2950,11 @@ public async Task FilesCreateDirectoryAsync(string res /// /// DirectoryInfo for informations about the file to the memory card root. /// True if the directory is created successfully - public async Task FilesCreateDirectoryAsync(DirectoryInfo resource) + public async Task FilesCreateDirectoryAsync(DirectoryInfo resource, CancellationToken cancellationToken = default(CancellationToken)) { var req = _apiRequestFactory.GetApiFilesCreateDirectoryRequest(resource.FullName); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); return responseObj; } @@ -2757,10 +2970,10 @@ public async Task FilesCreateDirectoryAsync(DirectoryI /// /// The resource to create /// True if the directory is created successfully - public async Task FilesCreateDirectoryAsync(ApiFileResource resource) + public async Task FilesCreateDirectoryAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)) { var varNameForMethods = resource.GetVarNameForMethods(); - return await FilesCreateDirectoryAsync(varNameForMethods); + return await FilesCreateDirectoryAsync(varNameForMethods, cancellationToken); } @@ -2777,11 +2990,11 @@ public ApiTrueOnSuccessResponse FilesCreateDirectory(ApiFileResource resource) /// /// Path of the file relative to the memory card root. /// True if the directory is deleted successfully - public async Task FilesDeleteDirectoryAsync(string resource) + public async Task FilesDeleteDirectoryAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)) { var req = _apiRequestFactory.GetApiFilesDeleteDirectoryRequest(resource); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); return responseObj; } @@ -2797,11 +3010,11 @@ public async Task FilesDeleteDirectoryAsync(string res ///
/// Path of the file relative to the memory card root. /// Ticket ID. - public async Task DatalogsDownloadAndClearAsync(string resource) + public async Task DatalogsDownloadAndClearAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)) { var req = _apiRequestFactory.GetApiDatalogsDownloadAndClearRequest(resource); - string response = await SendPostRequestAsync(req); - var responseObj = JsonConvert.DeserializeObject(response); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); return responseObj; } @@ -2816,10 +3029,10 @@ public async Task DatalogsDownloadAndClearAsync(string reso /// Send Plc.CreateBackup Request ///
/// Ticket ID. - public async Task PlcCreateBackupAsync() + public async Task PlcCreateBackupAsync(CancellationToken cancellationToken = default(CancellationToken)) { var req = _apiRequestFactory.GetPlcCreateBackupRequest(); - string response = await SendPostRequestAsync(req); + string response = await SendPostRequestAsync(req, cancellationToken); var responseObj = JsonConvert.DeserializeObject(response); return responseObj; } @@ -2835,10 +3048,10 @@ public async Task PlcCreateBackupAsync() /// /// /// - public async Task PlcRestoreBackupAsync(string password = null) + public async Task PlcRestoreBackupAsync(string password = null, CancellationToken cancellationToken = default(CancellationToken)) { var req = _apiRequestFactory.GetPlcRestoreBackupRequest(password); - string response = await SendPostRequestAsync(req); + string response = await SendPostRequestAsync(req, cancellationToken); var responseObj = JsonConvert.DeserializeObject(response); return responseObj; } @@ -2857,10 +3070,10 @@ public async Task PlcRestoreBackupAsync(string password = n /// /// /// - public async Task ReLoginAsync(string userName, string password, bool? includeWebApplicationCookie = null) + public async Task ReLoginAsync(string userName, string password, bool? includeWebApplicationCookie = null, CancellationToken cancellationToken = default(CancellationToken)) { - await ApiLogoutAsync(); - return await ApiLoginAsync(userName, password, includeWebApplicationCookie); + await ApiLogoutAsync(cancellationToken); + return await ApiLoginAsync(userName, password, includeWebApplicationCookie, cancellationToken); } /// @@ -2877,10 +3090,10 @@ public async Task ReLoginAsync(string userName, string passwor /// /// the resource that shall be deleted. /// True if the file is deleted successfully - public async Task FilesDeleteAsync(ApiFileResource resource) + public async Task FilesDeleteAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)) { var varNameForMethods = resource.GetVarNameForMethods(); - return await FilesDeleteAsync(varNameForMethods); + return await FilesDeleteAsync(varNameForMethods, cancellationToken); } /// @@ -2897,13 +3110,12 @@ public ApiTrueOnSuccessResponse FilesDelete(ApiFileResource resource) /// /// the directory to delete. /// True if the directory is deleted successfully - public async Task FilesDeleteDirectoryAsync(ApiFileResource resource) + public async Task FilesDeleteDirectoryAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)) { var varNameForMethods = resource.GetVarNameForMethods(); - return await FilesDeleteDirectoryAsync(varNameForMethods); + return await FilesDeleteDirectoryAsync(varNameForMethods, cancellationToken); } - /// /// Send a Files.DeleteDirectory Request /// @@ -2911,5 +3123,237 @@ public async Task FilesDeleteDirectoryAsync(ApiFileRes /// True if the directory is deleted successfully public ApiTrueOnSuccessResponse FilesDeleteDirectory(ApiFileResource resource) => FilesDeleteDirectoryAsync(resource).GetAwaiter().GetResult(); - } -} + + /// + /// Send a Failsafe.ReadParameters request + /// + /// The hardware identifier from which the parameters shall be read + /// Response with Failsafe parameters + public async Task FailsafeReadParametersAsync(uint hwid, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetFailsafeReadParametersRequest(hwid); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + + /// + /// Send a Failsafe.ReadParameters request + /// + /// The hardware identifier from which the parameters shall be read + /// Response with Failsafe parameters + public ApiFailsafeReadParametersResponse FailsafeReadParameters(uint hwid) => + FailsafeReadParametersAsync(hwid).GetAwaiter().GetResult(); + + /// + /// Send a Failsafe.ReadRuntimeGroups request + /// + /// Response with Runtime Groups + public async Task FailsafeReadRuntimeGroupsAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetFailsafeReadRuntimeGroupsRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + + /// + /// Send a Failsafe.ReadRuntimeGroups request + /// + /// Response with Runtime Groups + public ApiFailsafeReadRuntimeGroupsResponse FailsafeReadRuntimeGroups() => FailsafeReadRuntimeGroupsAsync().GetAwaiter().GetResult(); + + /// + /// Send an Api.GetPasswordPolicy request + /// + /// ApiGetPasswordPolicy response + public async Task ApiGetPasswordPolicyAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiGetPasswordPolicyRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + + /// + /// Send an Api.GetPasswordPolicy request + /// + /// ApiGetPasswordPolicy response + public ApiGetPasswordPolicyResponse ApiGetPasswordPolicy() => ApiGetPasswordPolicyAsync().GetAwaiter().GetResult(); + + /// + /// Send an Api.GetAuthenticationMode request + /// + /// A response containing the authentication modes + public async Task ApiGetAuthenticationModeAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiGetAuthenticationModeRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + + /// + /// Send an Api.GetAuthenticationMode request + /// + /// A response containing the authentication modes + public ApiGetAuthenticationModeResponse ApiGetAuthenticationMode() => ApiGetAuthenticationModeAsync().GetAwaiter().GetResult(); + + /// + /// Send a Project.ReadLanguages Request + /// + /// Languages Response containing a list of languages + public async Task ProjectReadLanguagesAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiProjectReadLanguagesRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject(response); + return responseObj; + } + + /// + /// Send a Project.ReadLanguages Request + /// + /// Languages Response containing a list of languages + public ApiReadLanguagesResponse ProjectReadLanguages() => ProjectReadLanguagesAsync().GetAwaiter().GetResult(); + + /// + /// Send a Plc.ReadModeSelectorState request + /// + /// In an R/H system, a PLC with ID 1 (primary) or 2 (backup). For standard PLCs, enum value 0 (StandardPLC) is required. + /// Mode Selector state + public async Task PlcReadModeSelectorStateAsync(ApiPlcRedundancyId rhid, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiPlcReadModeSelectorStateRequest(rhid); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + + /// + /// Send a Plc.ReadModeSelectorState request + /// + /// In an R/H system, a PLC with ID 1 (primary) or 2 (backup). For standard PLCs, enum value 0 (StandardPLC) is required. + /// Mode Selector state + public ApiPlcReadModeSelectorStateResponse PlcReadModeSelectorState(ApiPlcRedundancyId rhid) => + PlcReadModeSelectorStateAsync(rhid).GetAwaiter().GetResult(); + + /// + /// This API method allows the user to read content of the PLC-internal syslog ring buffer. + /// + /// (optional) The Redundancy ID parameter must be present when the request is executed on an R/H PLC.
+ /// In this case it must either have a value of 1 or 2, otherwise it is null. + /// (optional) The maximum number of syslog entries to be requested. Default value: 50
+ /// A count of 0 will omit any syslog entries from the response and only return the attributes last_modified, count_total and count_lost. + /// Optionally allows the user to provide the id of an entry as a starting point for the returned entries array.
+ /// This allows the user to traverse through the syslog buffer using multiple API calls. + /// ApiSyslogBrowseResponse + public async Task ApiSyslogBrowseAsync(ApiPlcRedundancyId? redundancy_id = null, uint? count = null, uint? first = null, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiSyslogBrowseRequest(redundancy_id, count, first); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + /// + /// This API method allows the user to read content of the PLC-internal syslog ring buffer. + /// + /// (optional) The Redundancy ID parameter must be present when the request is executed on an R/H PLC.
+ /// In this case it must either have a value of 1 or 2, otherwise it is null. + /// (optional) The maximum number of syslog entries to be requested. Default value: 50
+ /// A count of 0 will omit any syslog entries from the response and only return the attributes last_modified, count_total and count_lost. + /// Optionally allows the user to provide the id of an entry as a starting point for the returned entries array.
+ /// This allows the user to traverse through the syslog buffer using multiple API calls. + /// ApiSyslogBrowseResponse + public ApiSyslogBrowseResponse ApiSyslogBrowse(ApiPlcRedundancyId? redundancy_id = null, uint? count = null, uint? first = null) => ApiSyslogBrowseAsync(redundancy_id, count, first).GetAwaiter().GetResult(); + + /// + /// This method allows the user to acknowledge a single alarm.
+ /// This method will always return true, even when nothing is acknowledged. + ///
+ /// The Acknowledgement ID of the alarm which shall be acknowledged.
+ /// The acknowledgement ID can be found in the alarm object that was returned by method Alarms.Browse. + /// ApiTrueOnSuccessResponse + public async Task AlarmsAcknowledgeAsync(string id, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiAlarmsAcknowledgeRequest(id); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + /// + /// This method allows the user to acknowledge a single alarm.
+ /// This method will always return true, even when nothing is acknowledged. + ///
+ /// The Acknowledgement ID of the alarm which shall be acknowledged.
+ /// The acknowledgement ID can be found in the alarm object that was returned by method Alarms.Browse. + /// ApiTrueOnSuccessResponse + public ApiTrueOnSuccessResponse AlarmsAcknowledge(string id) => AlarmsAcknowledgeAsync(id).GetAwaiter().GetResult(); + + /// + /// Send a Alarms.Browse request + /// + /// ApiAlarmsBrowseResponse + /// The language in which the texts should be returned. + /// If the language is valid, then the response must contain the texts in the requested language.
+ /// An empty string shall be treated the same as an invalid language string. + /// + /// (optional) The maximum number of alarm entries to be requested.
+ /// When not provided, the plc will return with the default amount: 50.
+ /// The maximum possible count is 5000.
+ /// A count of 0 must omit any alarm entries from the response and must only return the attributes last_modified, count_max and count_current. + /// + /// (optional) The CPU alarm ID for which the user wants to return the data. If this is provided, no count parameter can be provided as filter. + /// (optional) Optional object that contains parameters to filter the response. + public async Task ApiAlarmsBrowseAsync(CultureInfo language, int? count = null, string alarm_id = null, ApiAlarms_RequestFilters filters = null, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiAlarmsBrowseRequest(language, count, alarm_id, filters); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + + /// + /// Send a Alarms.Browse request + /// + /// ApiAlarmsBrowseResponse + /// The language in which the texts should be returned. + /// If the language is valid, then the response must contain the texts in the requested language.
+ /// An empty string shall be treated the same as an invalid language string. + /// + /// (optional) The maximum number of alarm entries to be requested.
+ /// When not provided, the plc will return with the default amount: 50.
+ /// The maximum possible count is 5000.
+ /// A count of 0 must omit any alarm entries from the response and must only return the attributes last_modified, count_max and count_current. + /// + /// (optional) The CPU alarm ID for which the user wants to return the data. If this is provided, no count parameter can be provided as filter. + /// (optional) Optional object that contains parameters to filter the response. + public ApiAlarmsBrowseResponse ApiAlarmsBrowse(CultureInfo language, int? count = null, string alarm_id = null, ApiAlarms_RequestFilters filters = null) => ApiAlarmsBrowseAsync(language, count, alarm_id, filters).GetAwaiter().GetResult(); + + /// + /// Send a DiagnosticBuffer.Browse request + /// + /// The language in which the texts should be returned. If the language is valid, then the response must contain the texts in the requested language.An empty string shall be treated the same as an invalid language string. + /// (optional) The maximum number of diagnostic buffer entries to be requested. Default value: 50. A count of 0 will omit any diagnostic buffer entries from the response + /// (optional) ApiDiagnosticBufferBrowse_RequestFilters representing various filtering possibilities. + /// ApiDiagnosticBufferBrowseResponse + public async Task ApiDiagnosticBufferBrowseAsync(CultureInfo language, uint? count = null, ApiDiagnosticBuffer_RequestFilters filters = null, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiDiagnosticBufferBrowseRequest(language, count, filters); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + /// + /// Send a DiagnosticBuffer.Browse request + /// + /// The language in which the texts should be returned. If the language is valid, then the response must contain the texts in the requested language.An empty string shall be treated the same as an invalid language string. + /// (optional) The maximum number of diagnostic buffer entries to be requested. Default value: 50. A count of 0 will omit any diagnostic buffer entries from the response + /// (optional) ApiDiagnosticBufferBrowse_RequestFilters representing various filtering possibilities. + /// ApiDiagnosticBufferBrowseResponse + public ApiDiagnosticBufferBrowseResponse ApiDiagnosticBufferBrowse(CultureInfo language, uint? count = null, ApiDiagnosticBuffer_RequestFilters filters = null) => ApiDiagnosticBufferBrowseAsync(language, count, filters).GetAwaiter().GetResult(); + + /// + /// Cancel the outstanding requests of the HttpClient + /// + public void CancelPendingRequests() + { + _httpClient.CancelPendingRequests(); + } + } +} diff --git a/src/Webserver.API/Services/RequestHandling/ApiRequestFactory.cs b/src/Webserver.API/Services/RequestHandling/ApiRequestFactory.cs index 6bf36f9..b55ffaf 100644 --- a/src/Webserver.API/Services/RequestHandling/ApiRequestFactory.cs +++ b/src/Webserver.API/Services/RequestHandling/ApiRequestFactory.cs @@ -1,668 +1,818 @@ -// Copyright (c) 2023, Siemens AG -// -// SPDX-License-Identifier: MIT -using Siemens.Simatic.S7.Webserver.API.Enums; -using Siemens.Simatic.S7.Webserver.API.Models.Requests; -using Siemens.Simatic.S7.Webserver.API.Services.IdGenerator; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Siemens.Simatic.S7.Webserver.API.Services.RequestHandling -{ - /// - /// Api Request Factory => Will perform the according ParameterChecks (RequestParameterChecker) and return the requested IApiRequest - /// Will per default provide a Request with jsonrpc 2.0 and an id with 8 random chars, unless set differently - /// - public class ApiRequestFactory : IApiRequestFactory - { - private readonly IIdGenerator RequestIdGenerator; - - private readonly IApiRequestParameterChecker RequestParameterChecker; - - /// - /// Bool to determine wether to use local checks for Request Parameters or not - /// - public bool PerformCheck { get; set; } = true; - - /// - /// JsonRpc Version - /// - public const string JsonRpcVersion = "2.0"; - - /// - /// C'tor with optional requestGenerator parameter - /// - /// RequestGenerator - can be customized - /// parameter checker for the requestfactory - public ApiRequestFactory(IIdGenerator requestGenerator, IApiRequestParameterChecker requestParameterChecker) - { - RequestIdGenerator = requestGenerator ?? throw new ArgumentNullException(nameof(requestGenerator)); - RequestParameterChecker = requestParameterChecker ?? throw new ArgumentNullException(nameof(requestParameterChecker)); - } - - /// - /// get an Api.Browse Request without parameters. - /// - /// ApiBrowseRequest without parameters. - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiBrowseRequest(string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("Api.Browse", jsonRpcReq, idReq); - } - /// - /// get an Api.BrowseTickets request - if a (valid - 28chars) ticketid is provided - return ApiBrowseTickets request with parameter "id" : ticketid - /// - /// optional - if set: has to be 28chars long! - otherwise: InvalidParams! - /// ApiBrowseTickets request - if a (valid - 28chars) ticketid is provided - - /// return ApiBrowseTickets request with parameter "id" : ticketid - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiBrowseTicketsRequest(string ticketId = null, string jsonRpc = null, string id = null) - { - if (!string.IsNullOrEmpty(ticketId)) - { - RequestParameterChecker.CheckTicket(ticketId, PerformCheck); - } - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("Api.BrowseTickets", jsonRpcReq, idReq, string.IsNullOrEmpty(ticketId) ? null : - new Dictionary() { { "id", ticketId } }); - } - /// - /// get an Api.CloseTicket Request - if a (valid - 28chars) ticketid is provided - return Api.CloseTicket request with parameter "id" : ticketid - /// - /// has to be 28chars long! - otherwise: InvalidParams! - /// Api.CloseTicket Request - if a (valid - 28chars) ticketid is provided - return Api.CloseTicket request with parameter "id" : ticketid - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiCloseTicketRequest(string ticketId, string jsonRpc = null, string id = null) - { - RequestParameterChecker.CheckTicket(ticketId, PerformCheck); - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("Api.CloseTicket", jsonRpcReq, idReq, new Dictionary() { { "id", ticketId } }); - } - /// - /// get an Api.GetCertificateUrl Request without parameters - /// - /// Api.GetCertificateUrl Request without parameters - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiGetCertificateUrlRequest(string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("Api.GetCertificateUrl", jsonRpcReq, idReq); - } - /// - /// get an Api.Login Request with the given "user":userName, "password": password, "include_web_application_cookie" : include_web_application_cookie (might be null) - /// - /// - /// - /// bool used to determine if the response should include a valid application cookie value for protected pages access - /// ApiLoginRequest with the given "user":userName, "password": password, "include_web_application_cookie" : include_web_application_cookie (might be null) - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiLoginRequest(string userName, string password, bool? include_web_application_cookie = null, string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - // wenn bspw. username leer ist: request kann nicht gebaut werden -> parameter abprüfen und exceptions schmeißen - return new ApiRequest("Api.Login", jsonRpcReq, idReq, new Dictionary() { { "user", userName }, { "password", password }, - { "include_web_application_cookie", include_web_application_cookie } }); - } - /// - /// get an Api.Logout Request without parameters - /// - /// Api.Logout Request without parameters - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiLogoutRequest(string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("Api.Logout", jsonRpcReq, idReq); - } - /// - /// get an Api.GetPermissions Request without parameters - /// - /// Api.GetPermissions Request without parameters - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiGetPermissionsRequest(string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("Api.GetPermissions", jsonRpcReq, idReq); - } - /// - /// get an Api.Ping Request without parameters - /// - /// Api.Ping Request without parameters - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiPingRequest(string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("Api.Ping", jsonRpcReq, idReq); - } - /// - /// get an PlcProgram.Browse Request with parameter "mode": apiPlcProgramBrowseMode, "var" : var (might be null) - defaults to "" - /// - /// Var or children - /// defaults to "" - /// PlcProgram.Browse Request with parameter "mode": apiPlcProgramBrowseMode, "var" : var (might be null) - defaults to "" - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiPlcProgramBrowseRequest(ApiPlcProgramBrowseMode apiPlcProgramBrowseMode, string var = null, string jsonRpc = null, string id = null) - { - RequestParameterChecker.CheckPlcProgramBrowseMode(apiPlcProgramBrowseMode, PerformCheck); - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("PlcProgram.Browse", jsonRpcReq, idReq, new Dictionary() { { "var", var }, - { "mode", apiPlcProgramBrowseMode.ToString().ToLower() } }); - } - /// - /// get an PlcProgram.Read Request with parameter "var" : var, "mode": apiPlcProgramReadMode (might be null) - defaults to "simple" - /// - /// Variable name requested (including "Parents" seperated by dots) - /// defaults to "simple" - /// PlcProgram.Read Request with parameter "var" : var, "mode": apiPlcProgramReadMode (might be null) - defaults to "simple" - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiPlcProgramReadRequest(string var, ApiPlcProgramReadOrWriteMode? apiPlcProgramReadMode = null, string jsonRpc = null, string id = null) - { - RequestParameterChecker.CheckPlcProgramReadOrWriteMode(apiPlcProgramReadMode, PerformCheck); - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("PlcProgram.Read", jsonRpcReq, idReq, new Dictionary() { { "var", var }, - { "mode", apiPlcProgramReadMode?.ToString().ToLower() } }); - } - /// - /// get an PlcProgram.Write Request with parameter "var" : var, "value":valueToBeSet, "mode": apiPlcProgramReadMode (might be null) - defaults to "simple" - /// - /// Variable name of the var to be written (including "Parents" seperated by dots) - /// value the "var" should have - /// defaults to "simple" - /// PlcProgram.Write Request with parameter "var" : var, "value":valueToBeSet, "mode": apiPlcProgramReadMode (might be null) - defaults to "simple" - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiPlcProgramWriteRequest(string var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? apiPlcProgramWriteMode = null, string jsonRpc = null, string id = null) - { - RequestParameterChecker.CheckPlcProgramReadOrWriteMode(apiPlcProgramWriteMode, PerformCheck); - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("PlcProgram.Write", jsonRpcReq, idReq, new Dictionary() { { "var", var }, - { "mode", apiPlcProgramWriteMode?.ToString().ToLower() }, { "value", valueToBeSet } }); - } - /// - /// "Comfort" function to get the according Type object for a value the user Wants depending on the apiPlcProgramData - /// - /// ApiPlcProgramDataType of the valueWanted - /// value the user wants - /// the value in the correct format for the api (8bytes and string: string, otherwise: object - e.g. int) - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual object GetApiPlcProgramWriteValueToBeSet(ApiPlcProgramDataType apiPlcProgramData, object valueWanted, string jsonRpc = null, string id = null) - { - RequestParameterChecker.CheckPlcProgramReadOrWriteDataType(apiPlcProgramData, PerformCheck); - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - var bytesOfDataType = apiPlcProgramData.GetBytesOfDataType(); - var type = apiPlcProgramData.GetAccordingDataType(); - var objToReturn = (bytesOfDataType == 8 && apiPlcProgramData != ApiPlcProgramDataType.Lreal || type == typeof(string)) ? valueWanted.ToString() : - Convert.ChangeType(valueWanted, type); - return objToReturn; - } - /// - /// get an Plc.ReadOperatingMode Request without parameters - /// - /// Plc.ReadOperatingMode Request without parameters - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiPlcReadOperatingModeRequest(string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("Plc.ReadOperatingMode", jsonRpcReq, idReq); - } - /// - /// get an Plc.CheckPlcRequestChangeOperatingMode Request with parameter "mode": apiPlcOperatingMode - /// - /// Plc Operating mode wanted - /// Plc.CheckPlcRequestChangeOperatingMode Request with parameter "mode": apiPlcOperatingMode - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiPlcRequestChangeOperatingModeRequest(ApiPlcOperatingMode apiPlcOperatingMode, string jsonRpc = null, string id = null) - { - RequestParameterChecker.CheckPlcRequestChangeOperatingMode(apiPlcOperatingMode, PerformCheck); - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("Plc.RequestChangeOperatingMode", jsonRpcReq, idReq, new Dictionary() { - { "mode", apiPlcOperatingMode.ToString().ToLower() } }); - } - /// - /// check new Etag value - /// get an WebApp.SetResourceETag Request with parameter "app_name" : webAppName,"name": resourceName, "etag" : newETagValue - /// - /// Name of the Webapp containing the resource - /// Name of the resource the new Etag value should be set for - /// New Etag value for the resource - /// WebApp.SetResourceETag Request with parameter "app_name" : webAppName,"name": resourceName, "etag" : newETagValue - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiSetResourceETagRequest(string webAppName, string resourceName, string newETagValue, string jsonRpc = null, string id = null) - { - RequestParameterChecker.CheckETag(newETagValue, PerformCheck); - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("WebApp.SetResourceETag", jsonRpcReq, idReq, new Dictionary() { { "app_name", webAppName }, - { "name", resourceName }, { "etag", newETagValue } }); - } - /// - /// check new Media Type name - /// get an WebApp.SetResourceMediaType Request with parameter "app_name" : webAppName,"name": resourceName, "media_type" : newMediaType - /// - /// Name of the Webapp containing the resource - /// Name of the resource the new Mediatype value should be set for - /// New Mediatype value for the resource - /// WebApp.SetResourceMediaType Request with parameter "app_name" : webAppName,"name": resourceName, "media_type" : newMediaType - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiSetResourceMediaTypeRequest(string webAppName, string resourceName, string newMediaType, string jsonRpc = null, string id = null) - { - RequestParameterChecker.CheckMediaType(newMediaType, PerformCheck); - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("WebApp.SetResourceMediaType", jsonRpcReq, idReq, new Dictionary() { { "app_name", webAppName }, - { "name", resourceName }, { "media_type", newMediaType } }); - } - /// - /// check new lastmodified value (rfc3339) - /// get an WebApp.SetResourceModificationTime Request with parameter "app_name" : webAppName,"name": resourceName, "last_modified" : newLastModified - /// - /// Name of the Webapp containing the resource - /// Name of the resource the new Lastmodified value should be set for - /// New Lastmodified value for the resource - /// WebApp.SetResourceModificationTime Request with parameter "app_name" : webAppName,"name": resourceName, "last_modified" : newLastModified - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiSetResourceModificationTimeRequest(string webAppName, string resourceName, string newLastModified, string jsonRpc = null, string id = null) - { - RequestParameterChecker.CheckLastModified(newLastModified, PerformCheck); - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("WebApp.SetResourceModificationTime", jsonRpcReq, idReq, new Dictionary() { { "app_name", webAppName }, - { "name", resourceName }, { "last_modified", newLastModified } }); - } - /// - /// get an WebApp.SetResourceVisibility Request with parameter "app_name" : webAppName,"name": resourceName, "visibility" : apiWebAppResourceVisibility - /// - /// Name of the Webapp containing the resource - /// Name of the resource the new Visibility value should be set for - /// New Visibility value for the resource - /// WebApp.SetResourceVisibility Request with parameter "app_name" : webAppName,"name": resourceName, "visibility" : apiWebAppResourceVisibility - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiSetResourceVisibilityRequest(string webAppName, string resourceName, ApiWebAppResourceVisibility apiWebAppResourceVisibility, string jsonRpc = null, string id = null) - { - RequestParameterChecker.CheckWebAppResourceVisibility(apiWebAppResourceVisibility, PerformCheck); - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("WebApp.SetResourceVisibility", jsonRpcReq, idReq, new Dictionary() { { "app_name", webAppName }, - { "name", resourceName }, { "visibility", apiWebAppResourceVisibility.ToString().ToLower() } }); - } - /// - /// get an Api.Version Request without parameters - /// - /// Api.Version Request without parameters - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiVersionRequest(string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("Api.Version", jsonRpcReq, idReq); - } - /// - /// get an WebApp.Browse Request with parameter "name" : webAppName (optional, might be null) - /// - /// OPTIONAL: name of the webapp you want to browse - /// WebApp.Browse Request with parameter "name" : webAppName (optional, might be null) - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiWebAppBrowseRequest(string webAppName = null, string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("WebApp.Browse", jsonRpcReq, idReq, new Dictionary() { { "name", webAppName } }); - } - /// - /// get an WebApp.BrowseResources Request with parameter "app_name" : webAppName, "name":resourceName (optional, might be null) - /// - /// Name of the Webapp you want to browse the resources of - /// OPTIONAL: name of the resource you want to browse - /// WebApp.BrowseResources Request with parameter "app_name" : webAppName, "name":resourceName (optional, might be null) - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiWebAppBrowseResourcesRequest(string webAppName, string resourceName = null, string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("WebApp.BrowseResources", jsonRpcReq, idReq, new Dictionary() { { "app_name", webAppName }, - { "name", resourceName } }); - } - /// - /// check the request parameters: webAppName, if given WebAppState - /// get an WebApp.Create Request with parameter "name" : webAppName, "state":apiWebAppState (optional, might be null) - /// - /// webappname of the webapp to create - /// OPTIONAL: state the webapp should be in after creation - /// WebApp.Create Request with parameter "name" : webAppName, "state":apiWebAppState (optional, might be null) - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiWebAppCreateRequest(string webAppName, ApiWebAppState? apiWebAppState = null, string jsonRpc = null, string id = null) - { - RequestParameterChecker.CheckWebAppName(webAppName, PerformCheck); - if (apiWebAppState != null) - { - RequestParameterChecker.CheckWebAppState((ApiWebAppState)apiWebAppState, PerformCheck); - } - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("WebApp.Create", jsonRpcReq, idReq, new Dictionary() { { "name", webAppName }, - { "state", apiWebAppState?.ToString().ToLower() } }); - } - /// - /// Check resourceName, MediaType, LastModified, if given: Visibility (None is invalid) - if all are valid: - /// get an WebApp.CreateResource Request with parameter "app_name" : webAppName, "name":resourceName, "media_type":media_type, "last_modified" : last_modified, "visibility":ApiWebAppResourceVisibility (optional, might be null), "etag":etag (optional, might be null) - /// - /// webappname of the webapp the resource should be created in - /// resourcename of the resource to be created - /// mediatype of the resource to be created - /// lastmodified of the resource to be created - /// visibility of the resource to be created - /// etag of the resource to be created - /// WebApp.CreateResource Request with parameter "app_name" : webAppName, "name":resourceName, "media_type":media_type, "last_modified" : last_modified, "visibility":ApiWebAppResourceVisibility (optional, might be null), "etag":etag (optional, might be null) - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Enums; +using Siemens.Simatic.S7.Webserver.API.Models.AlarmsBrowse; +using Siemens.Simatic.S7.Webserver.API.Models.ApiDiagnosticBuffer; +using Siemens.Simatic.S7.Webserver.API.Models.Requests; +using Siemens.Simatic.S7.Webserver.API.Models.TimeSettings; +using Siemens.Simatic.S7.Webserver.API.Services.Converters.JsonConverters; +using Siemens.Simatic.S7.Webserver.API.Services.IdGenerator; +using Siemens.Simatic.S7.Webserver.API.StaticHelpers; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; + +namespace Siemens.Simatic.S7.Webserver.API.Services.RequestHandling +{ + /// + /// Api Request Factory => Will perform the according ParameterChecks (RequestParameterChecker) and return the requested IApiRequest + /// Will per default provide a Request with jsonrpc 2.0 and an id with 8 random chars, unless set differently + /// + public class ApiRequestFactory : IApiRequestFactory + { + private readonly IIdGenerator RequestIdGenerator; + + private readonly IApiRequestParameterChecker RequestParameterChecker; + + /// + /// Bool to determine wether to use local checks for Request Parameters or not + /// + public bool PerformCheck { get; set; } = true; + + /// + /// JsonRpc Version + /// + public const string JsonRpcVersion = "2.0"; + + /// + /// C'tor with optional requestGenerator parameter + /// + /// RequestGenerator - can be customized + /// parameter checker for the requestfactory + public ApiRequestFactory(IIdGenerator requestGenerator, IApiRequestParameterChecker requestParameterChecker) + { + RequestIdGenerator = requestGenerator ?? throw new ArgumentNullException(nameof(requestGenerator)); + RequestParameterChecker = requestParameterChecker ?? throw new ArgumentNullException(nameof(requestParameterChecker)); + } + + /// + /// get an Api.Browse Request without parameters. + /// + /// ApiBrowseRequest without parameters. + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiBrowseRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Api.Browse", jsonRpcReq, idReq); + } + /// + /// get an Api.BrowseTickets request - if a (valid - 28chars) ticketid is provided - return ApiBrowseTickets request with parameter "id" : ticketid + /// + /// optional - if set: has to be 28chars long! - otherwise: InvalidParams! + /// ApiBrowseTickets request - if a (valid - 28chars) ticketid is provided - + /// return ApiBrowseTickets request with parameter "id" : ticketid + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiBrowseTicketsRequest(string ticketId = null, string jsonRpc = null, string id = null) + { + if (!string.IsNullOrEmpty(ticketId)) + { + RequestParameterChecker.CheckTicket(ticketId, PerformCheck); + } + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Api.BrowseTickets", jsonRpcReq, idReq, string.IsNullOrEmpty(ticketId) ? null : + new Dictionary() { { "id", ticketId } }); + } + /// + /// get an Api.CloseTicket Request - if a (valid - 28chars) ticketid is provided - return Api.CloseTicket request with parameter "id" : ticketid + /// + /// has to be 28chars long! - otherwise: InvalidParams! + /// Api.CloseTicket Request - if a (valid - 28chars) ticketid is provided - return Api.CloseTicket request with parameter "id" : ticketid + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiCloseTicketRequest(string ticketId, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckTicket(ticketId, PerformCheck); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Api.CloseTicket", jsonRpcReq, idReq, new Dictionary() { { "id", ticketId } }); + } + + /// + /// Get an Api.ChangePassword request with parameters + /// + /// The user account for which the password shall be changed + /// The current password for the user + /// The new password for the user + /// Request Id + /// JsonRpc to be used + /// an Api.ChangePassword request + public IApiRequest GetApiChangePasswordRequest(string username, string currentPassword, string newPassword, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckUsername(username, PerformCheck); + RequestParameterChecker.CheckPasswords(currentPassword, newPassword, PerformCheck); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Api.ChangePassword", jsonRpcReq, idReq, new Dictionary() + { + { "username", username }, + { "password", currentPassword }, + { "new_password", newPassword } + }); + } + /// + /// Get an Api.GetPasswordPolicy request + /// + /// Request Id + /// JsonRpc to be used + /// An Api.GetPasswordPolicy request + public IApiRequest GetApiGetPasswordPolicyRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Api.GetPasswordPolicy", jsonRpcReq, idReq); + } + + /// + /// Get an Api.GetAuthenticationMode request + /// + /// Request Id + /// JsonRpc to be used + /// An Api.GetAuthenticationMode request + public IApiRequest GetApiGetAuthenticationModeRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Api.GetAuthenticationMode", jsonRpcReq, idReq); + } + + /// + /// get an Api.GetCertificateUrl Request without parameters + /// + /// Api.GetCertificateUrl Request without parameters + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiGetCertificateUrlRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Api.GetCertificateUrl", jsonRpcReq, idReq); + } + /// + /// get an Api.Login Request with the given "user":userName, "password": password, "include_web_application_cookie" : include_web_application_cookie (might be null) + /// + /// + /// + /// bool used to determine if the response should include a valid application cookie value for protected pages access + /// ApiLoginRequest with the given "user":userName, "password": password, "include_web_application_cookie" : include_web_application_cookie (might be null) + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiLoginRequest(string userName, string password, bool? include_web_application_cookie = null, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + // wenn bspw. username leer ist: request kann nicht gebaut werden -> parameter abprüfen und exceptions schmeißen + return new ApiRequest("Api.Login", jsonRpcReq, idReq, new Dictionary() { { "user", userName }, { "password", password }, + { "include_web_application_cookie", include_web_application_cookie } }); + } + /// + /// get an Api.Logout Request without parameters + /// + /// Api.Logout Request without parameters + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiLogoutRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Api.Logout", jsonRpcReq, idReq); + } + /// + /// get an Api.GetPermissions Request without parameters + /// + /// Api.GetPermissions Request without parameters + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiGetPermissionsRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Api.GetPermissions", jsonRpcReq, idReq); + } + /// + /// Get an Api.GetQuantityStructures Request without parameters + /// + /// Api.GetQuantityStructures Request without parameters + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiGetQuantityStructuresRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Api.GetQuantityStructures", jsonRpcReq, idReq); + } + /// + /// get an Api.Ping Request without parameters + /// + /// Api.Ping Request without parameters + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiPingRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Api.Ping", jsonRpcReq, idReq); + } + /// + /// get an PlcProgram.Browse Request with parameter "mode": apiPlcProgramBrowseMode, "var" : var (might be null) - defaults to "" + /// + /// Var or children + /// defaults to "" + /// PlcProgram.Browse Request with parameter "mode": apiPlcProgramBrowseMode, "var" : var (might be null) - defaults to "" + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiPlcProgramBrowseRequest(ApiPlcProgramBrowseMode apiPlcProgramBrowseMode, string var = null, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckPlcProgramBrowseMode(apiPlcProgramBrowseMode, PerformCheck); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("PlcProgram.Browse", jsonRpcReq, idReq, new Dictionary() { { "var", var }, + { "mode", apiPlcProgramBrowseMode.ToString().ToLower() } }); + } + + /// + /// Get a PlcProgram.Browse request for the code blocks (i.e. with parameters "mode":"Children", and "type"=["code_blocks"]). + /// + /// PlcProgram.Browse Request for the code blocks (i.e. with parameters "mode":"Children", and "type"=["code_blocks"]). + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiPlcProgramBrowseCodeBlocksRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("PlcProgram.Browse", jsonRpcReq, idReq, new Dictionary() { + { "mode", ApiPlcProgramBrowseMode.Children.ToString().ToLower() }, + { "type", new string[] {"code_blocks"} } + }); + } + + /// + /// Get a PlcProgram.DownloadProfilingData request. + /// + /// PlcProgram.DownloadProfilingData request. + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiPlcProgramDownloadProfilingDataRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("PlcProgram.DownloadProfilingData", jsonRpcReq, idReq); + } + + /// + /// get an PlcProgram.Read Request with parameter "var" : var, "mode": apiPlcProgramReadMode (might be null) - defaults to "simple" + /// + /// Variable name requested (including "Parents" seperated by dots) + /// defaults to "simple" + /// PlcProgram.Read Request with parameter "var" : var, "mode": apiPlcProgramReadMode (might be null) - defaults to "simple" + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiPlcProgramReadRequest(string var, ApiPlcProgramReadOrWriteMode? apiPlcProgramReadMode = null, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckPlcProgramReadOrWriteMode(apiPlcProgramReadMode, PerformCheck); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("PlcProgram.Read", jsonRpcReq, idReq, new Dictionary() { { "var", var }, + { "mode", apiPlcProgramReadMode?.ToString().ToLower() } }); + } + /// + /// get an PlcProgram.Write Request with parameter "var" : var, "value":valueToBeSet, "mode": apiPlcProgramReadMode (might be null) - defaults to "simple" + /// + /// Variable name of the var to be written (including "Parents" seperated by dots) + /// value the "var" should have + /// defaults to "simple" + /// PlcProgram.Write Request with parameter "var" : var, "value":valueToBeSet, "mode": apiPlcProgramReadMode (might be null) - defaults to "simple" + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiPlcProgramWriteRequest(string var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? apiPlcProgramWriteMode = null, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckPlcProgramReadOrWriteMode(apiPlcProgramWriteMode, PerformCheck); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("PlcProgram.Write", jsonRpcReq, idReq, new Dictionary() { { "var", var }, + { "mode", apiPlcProgramWriteMode?.ToString().ToLower() }, { "value", valueToBeSet } }); + } + /// + /// "Comfort" function to get the according Type object for a value the user Wants depending on the apiPlcProgramData + /// + /// ApiPlcProgramDataType of the valueWanted + /// value the user wants + /// the value in the correct format for the api (8bytes and string: string, otherwise: object - e.g. int) + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual object GetApiPlcProgramWriteValueToBeSet(ApiPlcProgramDataType apiPlcProgramData, object valueWanted, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckPlcProgramReadOrWriteDataType(apiPlcProgramData, PerformCheck); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + var bytesOfDataType = apiPlcProgramData.GetBytesOfDataType(); + var type = apiPlcProgramData.GetAccordingDataType(); + var objToReturn = (bytesOfDataType == 8 && apiPlcProgramData != ApiPlcProgramDataType.Lreal || type == typeof(string)) ? valueWanted.ToString() : + Convert.ChangeType(valueWanted, type); + return objToReturn; + } + /// + /// get an Plc.ReadOperatingMode Request without parameters + /// + /// Plc.ReadOperatingMode Request without parameters + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiPlcReadOperatingModeRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Plc.ReadOperatingMode", jsonRpcReq, idReq); + } + /// + /// get an Plc.CheckPlcRequestChangeOperatingMode Request with parameter "mode": apiPlcOperatingMode + /// + /// Plc Operating mode wanted + /// Plc.CheckPlcRequestChangeOperatingMode Request with parameter "mode": apiPlcOperatingMode + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiPlcRequestChangeOperatingModeRequest(ApiPlcOperatingMode apiPlcOperatingMode, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckPlcRequestChangeOperatingMode(apiPlcOperatingMode, PerformCheck); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Plc.RequestChangeOperatingMode", jsonRpcReq, idReq, new Dictionary() { + { "mode", apiPlcOperatingMode.ToString().ToLower() } }); + } + /// + /// Get a Plc.ReadModeSelectorState Request with redundancy id parameter + /// + /// In an R/H system, a PLC with ID 1 (primary) or 2 (backup). For standard PLCs, enum value 0 (StandardPLC) is required. + /// Request Id + /// JsonRpc to be used + /// Plc.ReadModeSelectorState request with redundancy id parameter + public IApiRequest GetApiPlcReadModeSelectorStateRequest(ApiPlcRedundancyId rhid, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Plc.ReadModeSelectorState", jsonRpcReq, idReq, + rhid == ApiPlcRedundancyId.StandardPLC ? null : new Dictionary() + { + { "redundancy_id", (int)rhid } + }); + } + /// + /// check new Etag value + /// get an WebApp.SetResourceETag Request with parameter "app_name" : webAppName,"name": resourceName, "etag" : newETagValue + /// + /// Name of the Webapp containing the resource + /// Name of the resource the new Etag value should be set for + /// New Etag value for the resource + /// WebApp.SetResourceETag Request with parameter "app_name" : webAppName,"name": resourceName, "etag" : newETagValue + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiSetResourceETagRequest(string webAppName, string resourceName, string newETagValue, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckETag(newETagValue, PerformCheck); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebApp.SetResourceETag", jsonRpcReq, idReq, new Dictionary() { { "app_name", webAppName }, + { "name", resourceName }, { "etag", newETagValue } }); + } + /// + /// check new Media Type name + /// get an WebApp.SetResourceMediaType Request with parameter "app_name" : webAppName,"name": resourceName, "media_type" : newMediaType + /// + /// Name of the Webapp containing the resource + /// Name of the resource the new Mediatype value should be set for + /// New Mediatype value for the resource + /// WebApp.SetResourceMediaType Request with parameter "app_name" : webAppName,"name": resourceName, "media_type" : newMediaType + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiSetResourceMediaTypeRequest(string webAppName, string resourceName, string newMediaType, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckMediaType(newMediaType, PerformCheck); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebApp.SetResourceMediaType", jsonRpcReq, idReq, new Dictionary() { { "app_name", webAppName }, + { "name", resourceName }, { "media_type", newMediaType } }); + } + /// + /// check new lastmodified value (rfc3339) + /// get an WebApp.SetResourceModificationTime Request with parameter "app_name" : webAppName,"name": resourceName, "last_modified" : newLastModified + /// + /// Name of the Webapp containing the resource + /// Name of the resource the new Lastmodified value should be set for + /// New Lastmodified value for the resource + /// WebApp.SetResourceModificationTime Request with parameter "app_name" : webAppName,"name": resourceName, "last_modified" : newLastModified + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiSetResourceModificationTimeRequest(string webAppName, string resourceName, string newLastModified, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckLastModified(newLastModified, PerformCheck); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebApp.SetResourceModificationTime", jsonRpcReq, idReq, new Dictionary() { { "app_name", webAppName }, + { "name", resourceName }, { "last_modified", newLastModified } }); + } + /// + /// get an WebApp.SetResourceVisibility Request with parameter "app_name" : webAppName,"name": resourceName, "visibility" : apiWebAppResourceVisibility + /// + /// Name of the Webapp containing the resource + /// Name of the resource the new Visibility value should be set for + /// New Visibility value for the resource + /// WebApp.SetResourceVisibility Request with parameter "app_name" : webAppName,"name": resourceName, "visibility" : apiWebAppResourceVisibility + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiSetResourceVisibilityRequest(string webAppName, string resourceName, ApiWebAppResourceVisibility apiWebAppResourceVisibility, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckWebAppResourceVisibility(apiWebAppResourceVisibility, PerformCheck); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebApp.SetResourceVisibility", jsonRpcReq, idReq, new Dictionary() { { "app_name", webAppName }, + { "name", resourceName }, { "visibility", apiWebAppResourceVisibility.ToString().ToLower() } }); + } + /// + /// get an Api.Version Request without parameters + /// + /// Api.Version Request without parameters + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiVersionRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Api.Version", jsonRpcReq, idReq); + } + /// + /// get an WebApp.Browse Request with parameter "name" : webAppName (optional, might be null) + /// + /// OPTIONAL: name of the webapp you want to browse + /// WebApp.Browse Request with parameter "name" : webAppName (optional, might be null) + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiWebAppBrowseRequest(string webAppName = null, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebApp.Browse", jsonRpcReq, idReq, new Dictionary() { { "name", webAppName } }); + } + /// + /// get an WebApp.BrowseResources Request with parameter "app_name" : webAppName, "name":resourceName (optional, might be null) + /// + /// Name of the Webapp you want to browse the resources of + /// OPTIONAL: name of the resource you want to browse + /// WebApp.BrowseResources Request with parameter "app_name" : webAppName, "name":resourceName (optional, might be null) + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiWebAppBrowseResourcesRequest(string webAppName, string resourceName = null, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebApp.BrowseResources", jsonRpcReq, idReq, new Dictionary() { { "app_name", webAppName }, + { "name", resourceName } }); + } + /// + /// check the request parameters: webAppName, if given WebAppState + /// get an WebApp.Create Request with parameter "name" : webAppName, "state":apiWebAppState (optional, might be null) + /// + /// webappname of the webapp to create + /// OPTIONAL: state the webapp should be in after creation + /// WebApp.Create Request with parameter "name" : webAppName, "state":apiWebAppState (optional, might be null) + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiWebAppCreateRequest(string webAppName, ApiWebAppState? apiWebAppState = null, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckWebAppName(webAppName, PerformCheck); + if (apiWebAppState != null) + { + RequestParameterChecker.CheckWebAppState((ApiWebAppState)apiWebAppState, PerformCheck); + } + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebApp.Create", jsonRpcReq, idReq, new Dictionary() { { "name", webAppName }, + { "state", apiWebAppState?.ToString().ToLower() } }); + } + /// + /// Check resourceName, MediaType, LastModified, if given: Visibility (None is invalid) - if all are valid: + /// get an WebApp.CreateResource Request with parameter "app_name" : webAppName, "name":resourceName, "media_type":media_type, "last_modified" : last_modified, "visibility":ApiWebAppResourceVisibility (optional, might be null), "etag":etag (optional, might be null) + /// + /// webappname of the webapp the resource should be created in + /// resourcename of the resource to be created + /// mediatype of the resource to be created + /// lastmodified of the resource to be created + /// visibility of the resource to be created + /// etag of the resource to be created + /// WebApp.CreateResource Request with parameter "app_name" : webAppName, "name":resourceName, "media_type":media_type, "last_modified" : last_modified, "visibility":ApiWebAppResourceVisibility (optional, might be null), "etag":etag (optional, might be null) + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion public virtual IApiRequest GetApiWebAppCreateResourceRequest(string webAppName, string resourceName, string media_type, - string last_modified, ApiWebAppResourceVisibility? apiWebAppResourceVisibility = null, string etag = null, string jsonRpc = null, string id = null) - { - RequestParameterChecker.CheckResourceName(resourceName, PerformCheck); - if (apiWebAppResourceVisibility != null) - { - RequestParameterChecker.CheckWebAppResourceVisibility((ApiWebAppResourceVisibility)apiWebAppResourceVisibility, PerformCheck); - } - if (etag != null) - { - RequestParameterChecker.CheckETag(etag, PerformCheck); - } - RequestParameterChecker.CheckMediaType(media_type, PerformCheck); - RequestParameterChecker.CheckLastModified(last_modified, PerformCheck); - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("WebApp.CreateResource", jsonRpcReq, idReq, new Dictionary() { { "app_name", webAppName }, - { "name", resourceName }, { "media_type", media_type }, { "last_modified", last_modified }, - { "visibility", apiWebAppResourceVisibility?.ToString().ToLower() } , { "etag", etag } }); - } - /// - /// get an WebApp.Delete Request with parameter "name" : webAppName - /// - /// Name of the webapp that should be deleted - /// WebApp.Delete Request with parameter "name" : webAppName - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiWebAppDeleteRequest(string webAppName, string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("WebApp.Delete", jsonRpcReq, idReq, new Dictionary() { { "name", webAppName } }); - } - /// - /// get an WebApp.DeleteResource Request with parameter "app_name" : webAppName, "name": resourceName - /// - /// Name of the Webapp containing the resource - /// Name of the resource that should be deleted - /// WebApp.DeleteResource Request with parameter "app_name" : webAppName, "name": resourceName - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiWebAppDeleteResourceRequest(string webAppName, string resourceName, string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("WebApp.DeleteResource", jsonRpcReq, idReq, new Dictionary() { { "app_name", webAppName }, - { "name", resourceName } }); - } - /// - /// get an WebApp.DownloadResource Request with parameter "app_name" : webAppName, "name": resourceName - /// - /// Name of the Webapp containing the resource - /// Name of the resource that should be downloaded - /// WebApp.DownloadResource Request with parameter "app_name" : webAppName, "name": resourceName - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiWebAppDownloadResourceRequest(string webAppName, string resourceName, string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("WebApp.DownloadResource", jsonRpcReq, idReq, new Dictionary() { { "app_name", webAppName }, - { "name", resourceName } }); - } - /// - /// get an WebApp.Rename Request with parameter "name" : webAppName, "new_name": newWebAppName - /// - /// Current name of the Webapp that is to be renamed - /// New name for the Webapp - /// WebApp.Rename Request with parameter "name" : webAppName, "new_name": newWebAppName - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiWebAppRenameRequest(string webAppName, string newWebAppName, string jsonRpc = null, string id = null) - { - RequestParameterChecker.CheckWebAppName(newWebAppName, PerformCheck); - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("WebApp.Rename", jsonRpcReq, idReq, new Dictionary() { { "name", webAppName }, - { "new_name", newWebAppName } }); - } - /// - /// check new resource name, if valid: - /// get an WebApp.RenameResource Request with parameter "app_name" : webAppName, "name" : resourceName, "new_name": newResourceName - /// - /// Name of the Webapp containing the resource - /// Current name of the resource that is to be renamed - /// New name for the resource - /// WebApp.RenameResource Request with parameter "app_name" : webAppName, "name" : resourceName, "new_name": newResourceName - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiWebAppRenameResourceRequest(string webAppName, string resourceName, string newResourceName, string jsonRpc = null, string id = null) - { - RequestParameterChecker.CheckResourceName(newResourceName, PerformCheck); - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("WebApp.RenameResource", jsonRpcReq, idReq, new Dictionary() { { "app_name", webAppName }, - { "name", resourceName }, { "new_name", newResourceName } }); - } - /// - /// get a WebApp.SetDefaultPage Request with parameter "name" : webAppName, "resource_name" : resourceName - /// - /// Name of the Webapp containing the resource - /// Name of the resource that should be the Defaultpage - /// WebApp.SetDefaultPage Request with parameter "name" : webAppName, "resource_name" : resourceName - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiWebAppSetDefaultPageRequest(string webAppName, string resourceName, string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("WebApp.SetDefaultPage", jsonRpcReq, idReq, new Dictionary() { { "name", webAppName }, - { "resource_name", resourceName } }); - } - /// - /// get an WebApp.SetNotAuthorizedPage Request with parameter "name" : webAppName, "resource_name" : resourceName - /// - /// Name of the Webapp containing the resource - /// Name of the resource that should be the Notauthorizedpage - /// WebApp.SetNotAuthorizedPage Request with parameter "name" : webAppName, "resource_name" : resourceName - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiWebAppSetNotAuthorizedPageRequest(string webAppName, string resourceName, string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("WebApp.SetNotAuthorizedPage", jsonRpcReq, idReq, new Dictionary() { { "name", webAppName }, - { "resource_name", resourceName } }); - } - /// - /// get an WebApp.SetNotFoundPage Request with parameter "name" : webAppName, "resource_name" : resourceName - /// - /// Name of the Webapp containing the resource - /// Name of the resource that should be the Notfoundpage - /// WebApp.SetNotFoundPage Request with parameter "name" : webAppName, "resource_name" : resourceName - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiWebAppSetNotFoundPageRequest(string webAppName, string resourceName, string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("WebApp.SetNotFoundPage", jsonRpcReq, idReq, new Dictionary() { { "name", webAppName }, - { "resource_name", resourceName } }); - } - /// - /// check apiwebappstate (none isnt valid) - /// get an WebApp.SetState Request with parameter "name" : webAppName, "state" : apiWebAppState - /// - /// Name of the Webapp the state should be changed for - /// New state for the Webapp - /// WebApp.SetState Request with parameter "name" : webAppName, "state" : apiWebAppState - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiWebAppSetStateRequest(string webAppName, ApiWebAppState apiWebAppState, string jsonRpc = null, string id = null) - { - RequestParameterChecker.CheckWebAppState(apiWebAppState, PerformCheck); - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("WebApp.SetState", jsonRpcReq, idReq, new Dictionary() { { "name", webAppName }, - { "state", apiWebAppState.ToString().ToLower() } }); - } - - /// - /// Method to make sure all requests in the ApiBulk have a unique Id - /// - /// Api Requests to make sure of that the ids are unique - /// timeout for the waithandler => plc to be up again after reboot, etc. - /// A list of api Requests containing unique Ids - public virtual IEnumerable GetApiBulkRequestWithUniqueIds(IEnumerable IApiRequests, TimeSpan? timeOut = null) - { - var requestsToReturn = new List(IApiRequests.ToList()); - var startTime = DateTime.Now; - var ignoreTimeOut = false; - if (timeOut == null) - { - ignoreTimeOut = true; - } + string last_modified, ApiWebAppResourceVisibility? apiWebAppResourceVisibility = null, string etag = null, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckResourceName(resourceName, PerformCheck); + if (apiWebAppResourceVisibility != null) + { + RequestParameterChecker.CheckWebAppResourceVisibility((ApiWebAppResourceVisibility)apiWebAppResourceVisibility, PerformCheck); + } + if (etag != null) + { + RequestParameterChecker.CheckETag(etag, PerformCheck); + } + RequestParameterChecker.CheckMediaType(media_type, PerformCheck); + RequestParameterChecker.CheckLastModified(last_modified, PerformCheck); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebApp.CreateResource", jsonRpcReq, idReq, new Dictionary() { { "app_name", webAppName }, + { "name", resourceName }, { "media_type", media_type }, { "last_modified", last_modified }, + { "visibility", apiWebAppResourceVisibility?.ToString().ToLower() } , { "etag", etag } }); + } + /// + /// get an WebApp.Delete Request with parameter "name" : webAppName + /// + /// Name of the webapp that should be deleted + /// WebApp.Delete Request with parameter "name" : webAppName + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiWebAppDeleteRequest(string webAppName, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebApp.Delete", jsonRpcReq, idReq, new Dictionary() { { "name", webAppName } }); + } + /// + /// get an WebApp.DeleteResource Request with parameter "app_name" : webAppName, "name": resourceName + /// + /// Name of the Webapp containing the resource + /// Name of the resource that should be deleted + /// WebApp.DeleteResource Request with parameter "app_name" : webAppName, "name": resourceName + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiWebAppDeleteResourceRequest(string webAppName, string resourceName, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebApp.DeleteResource", jsonRpcReq, idReq, new Dictionary() { { "app_name", webAppName }, + { "name", resourceName } }); + } + /// + /// get an WebApp.DownloadResource Request with parameter "app_name" : webAppName, "name": resourceName + /// + /// Name of the Webapp containing the resource + /// Name of the resource that should be downloaded + /// WebApp.DownloadResource Request with parameter "app_name" : webAppName, "name": resourceName + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiWebAppDownloadResourceRequest(string webAppName, string resourceName, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebApp.DownloadResource", jsonRpcReq, idReq, new Dictionary() { { "app_name", webAppName }, + { "name", resourceName } }); + } + /// + /// get an WebApp.Rename Request with parameter "name" : webAppName, "new_name": newWebAppName + /// + /// Current name of the Webapp that is to be renamed + /// New name for the Webapp + /// WebApp.Rename Request with parameter "name" : webAppName, "new_name": newWebAppName + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiWebAppRenameRequest(string webAppName, string newWebAppName, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckWebAppName(newWebAppName, PerformCheck); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebApp.Rename", jsonRpcReq, idReq, new Dictionary() { { "name", webAppName }, + { "new_name", newWebAppName } }); + } + /// + /// check new resource name, if valid: + /// get an WebApp.RenameResource Request with parameter "app_name" : webAppName, "name" : resourceName, "new_name": newResourceName + /// + /// Name of the Webapp containing the resource + /// Current name of the resource that is to be renamed + /// New name for the resource + /// WebApp.RenameResource Request with parameter "app_name" : webAppName, "name" : resourceName, "new_name": newResourceName + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiWebAppRenameResourceRequest(string webAppName, string resourceName, string newResourceName, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckResourceName(newResourceName, PerformCheck); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebApp.RenameResource", jsonRpcReq, idReq, new Dictionary() { { "app_name", webAppName }, + { "name", resourceName }, { "new_name", newResourceName } }); + } + /// + /// get a WebApp.SetDefaultPage Request with parameter "name" : webAppName, "resource_name" : resourceName + /// + /// Name of the Webapp containing the resource + /// Name of the resource that should be the Defaultpage + /// WebApp.SetDefaultPage Request with parameter "name" : webAppName, "resource_name" : resourceName + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiWebAppSetDefaultPageRequest(string webAppName, string resourceName, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebApp.SetDefaultPage", jsonRpcReq, idReq, new Dictionary() { { "name", webAppName }, + { "resource_name", resourceName } }); + } + /// + /// get an WebApp.SetNotAuthorizedPage Request with parameter "name" : webAppName, "resource_name" : resourceName + /// + /// Name of the Webapp containing the resource + /// Name of the resource that should be the Notauthorizedpage + /// WebApp.SetNotAuthorizedPage Request with parameter "name" : webAppName, "resource_name" : resourceName + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiWebAppSetNotAuthorizedPageRequest(string webAppName, string resourceName, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebApp.SetNotAuthorizedPage", jsonRpcReq, idReq, new Dictionary() { { "name", webAppName }, + { "resource_name", resourceName } }); + } + /// + /// get an WebApp.SetNotFoundPage Request with parameter "name" : webAppName, "resource_name" : resourceName + /// + /// Name of the Webapp containing the resource + /// Name of the resource that should be the Notfoundpage + /// WebApp.SetNotFoundPage Request with parameter "name" : webAppName, "resource_name" : resourceName + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiWebAppSetNotFoundPageRequest(string webAppName, string resourceName, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebApp.SetNotFoundPage", jsonRpcReq, idReq, new Dictionary() { { "name", webAppName }, + { "resource_name", resourceName } }); + } + /// + /// check apiwebappstate (none isnt valid) + /// get an WebApp.SetState Request with parameter "name" : webAppName, "state" : apiWebAppState + /// + /// Name of the Webapp the state should be changed for + /// New state for the Webapp + /// WebApp.SetState Request with parameter "name" : webAppName, "state" : apiWebAppState + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiWebAppSetStateRequest(string webAppName, ApiWebAppState apiWebAppState, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckWebAppState(apiWebAppState, PerformCheck); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebApp.SetState", jsonRpcReq, idReq, new Dictionary() { { "name", webAppName }, + { "state", apiWebAppState.ToString().ToLower() } }); + } + + /// + /// Method to make sure all requests in the ApiBulk have a unique Id + /// + /// Api Requests to make sure of that the ids are unique + /// timeout for the waithandler => plc to be up again after reboot, etc. + /// A list of api Requests containing unique Ids + public virtual IEnumerable GetApiBulkRequestWithUniqueIds(IEnumerable IApiRequests, TimeSpan? timeOut = null) + { + var requestsToReturn = new List(IApiRequests.ToList()); + var startTime = DateTime.Now; + var ignoreTimeOut = false; + if (timeOut == null) + { + ignoreTimeOut = true; + } while (requestsToReturn.GroupBy(el => el.Id).Count() != requestsToReturn.Count - && (((startTime + timeOut) > DateTime.Now) || ignoreTimeOut)) - { - IApiRequests.Where(el => IApiRequests.Any(el2 => el.Id == el2.Id)) - .ToList().ForEach(el => - { - el.Id = RequestIdGenerator.Generate(); - }); - } - return requestsToReturn; - } - - /// - /// In case you want to "build up" an IApiRequest on your own - /// - /// Api method to be called - /// Api method parameters to be provided - /// jsonrpc version (defaults to 2.0) - /// request id (defaults to a new generated id) - /// An IApiRequest to be sent to the plc - public virtual IApiRequest GetIApiRequest(string method, Dictionary requestParams = null, string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest(method, jsonRpcReq, idReq, requestParams); - } - - /// - /// get an Plc.ReadSystemTime Request - /// - /// Plc.ReadSystemTime Request - /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiPlcReadSystemTimeRequest(string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("Plc.ReadSystemTime", jsonRpcReq, idReq); - } - /// - /// get an Plc.ReadTimeSettings Request - /// - /// Plc.ReadTimeSettings Request - /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiPlcReadTimeSettingsRequest(string jsonRpc = null, string id = null) - { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("Plc.ReadTimeSettings", jsonRpcReq, idReq); - } - - /// - /// Call Equals with obj as IApiRequestFactory - check for Properties - /// - /// to compare - /// wether the two are equal or not - public override bool Equals(object obj) => Equals(obj as ApiRequestFactory); - - /// - /// check for Properties - /// - /// to compare - /// wether the two are equal or not - public bool Equals(ApiRequestFactory obj) - { - var toReturn = this.PerformCheck == obj.PerformCheck; - toReturn &= this.RequestIdGenerator.Equals(obj.RequestIdGenerator); - toReturn &= this.RequestParameterChecker.Equals(obj.RequestParameterChecker); - return toReturn; - } - - /// - /// GetHashCode for SequenceEqual etc. - /// - /// hashcode of the ApiTicket - public override int GetHashCode() - { - var hashCode = 570990538; - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(RequestIdGenerator); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(RequestParameterChecker); - hashCode = hashCode * -1521134295 + PerformCheck.GetHashCode(); - return hashCode; + && (((startTime + timeOut) > DateTime.Now) || ignoreTimeOut)) + { + IApiRequests.Where(el => IApiRequests.Any(el2 => el.Id == el2.Id)) + .ToList().ForEach(el => + { + el.Id = RequestIdGenerator.Generate(); + }); + } + return requestsToReturn; + } + + /// + /// In case you want to "build up" an IApiRequest on your own + /// + /// Api method to be called + /// Api method parameters to be provided + /// jsonrpc version (defaults to 2.0) + /// request id (defaults to a new generated id) + /// An IApiRequest to be sent to the plc + public virtual IApiRequest GetIApiRequest(string method, Dictionary requestParams = null, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest(method, jsonRpcReq, idReq, requestParams); + } + + /// + /// get an Plc.ReadSystemTime Request + /// + /// Plc.ReadSystemTime Request + /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiPlcReadSystemTimeRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Plc.ReadSystemTime", jsonRpcReq, idReq); + } + + /// + /// get an Plc.SetSystemTime Request + /// + /// Plc.SetSystemTime Request + /// The timestamp of the system time to be set + /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) + /// JsonRpc to be used - defaults to JsonRpcVersion + public IApiRequest GetApiPlcSetSystemTimeRequest(DateTime timestamp, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckSystemTimeStamp(timestamp, PerformCheck); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Plc.SetSystemTime", jsonRpcReq, idReq, new Dictionary() { { "timestamp", timestamp.ToString(DateTimeFormatting.ApiDateTimeFormat) } }); + } + /// + /// get an Plc.ReadTimeSettings Request + /// + /// Plc.ReadTimeSettings Request + /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiPlcReadTimeSettingsRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Plc.ReadTimeSettings", jsonRpcReq, idReq); + } + + /// + /// Get an Plc.SetTimeSettings request + /// + /// The time zone offset from the UTC time in hours + /// (Optional) Represents the settings for daylight-savings. If there is no daylight-savings rule configured, the utcOffset is applied to calculate the local time + /// Request Id + /// JsonRpc to be used + /// Plc.SetTimeSettings Request + public IApiRequest GetApiPlcSetTimeSettingsRequest(TimeSpan utcOffset, DaylightSavingsRule daylightSavings = null, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckTimeSettings(utcOffset, daylightSavings, PerformCheck); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Plc.SetTimeSettings", jsonRpcReq, idReq, + new Dictionary() + { + { "utc_offset", utcOffset.ToISO8601Duration() }, + { "rule", daylightSavings } + }); + } + + /// + /// Call Equals with obj as IApiRequestFactory - check for Properties + /// + /// to compare + /// wether the two are equal or not + public override bool Equals(object obj) => Equals(obj as ApiRequestFactory); + + /// + /// check for Properties + /// + /// to compare + /// wether the two are equal or not + public bool Equals(ApiRequestFactory obj) + { + var toReturn = this.PerformCheck == obj.PerformCheck; + toReturn &= this.RequestIdGenerator.Equals(obj.RequestIdGenerator); + toReturn &= this.RequestParameterChecker.Equals(obj.RequestParameterChecker); + return toReturn; + } + + /// + /// GetHashCode for SequenceEqual etc. + /// + /// hashcode of the ApiTicket + public override int GetHashCode() + { + var hashCode = 570990538; + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(RequestIdGenerator); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(RequestParameterChecker); + hashCode = hashCode * -1521134295 + PerformCheck.GetHashCode(); + return hashCode; } /// /// get an Files.Browse Request /// - /// Files.Browse Request - /// directory or file to be browsed - /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) + /// Files.Browse Request + /// directory or file to be browsed + /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) /// JsonRpc to be used - defaults to JsonRpcVersion /// Files.Browse Request public IApiRequest GetApiFilesBrowseRequest(string resource, string jsonRpc = null, string id = null) { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); return new ApiRequest("Files.Browse", jsonRpcReq, idReq, new Dictionary() { { "resource", resource } }); } @@ -676,8 +826,8 @@ public IApiRequest GetApiFilesBrowseRequest(string resource, string jsonRpc = nu /// Files.Download Request public IApiRequest GetApiFilesDownloadRequest(string resource, string jsonRpc = null, string id = null) { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); return new ApiRequest("Files.Download", jsonRpcReq, idReq, new Dictionary() { { "resource", resource } }); } @@ -691,8 +841,8 @@ public IApiRequest GetApiFilesDownloadRequest(string resource, string jsonRpc = /// Files.Create Request public IApiRequest GetApiFilesCreateRequest(string resource, string jsonRpc = null, string id = null) { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); return new ApiRequest("Files.Create", jsonRpcReq, idReq, new Dictionary() { { "resource", resource } }); } @@ -707,8 +857,8 @@ public IApiRequest GetApiFilesCreateRequest(string resource, string jsonRpc = nu /// Files.Rename Request public IApiRequest GetApiFilesRenameRequest(string resource, string new_resource, string jsonRpc = null, string id = null) { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); return new ApiRequest("Files.Rename", jsonRpcReq, idReq, new Dictionary() { { "resource", resource }, {"new_resource", new_resource } }); } @@ -722,8 +872,8 @@ public IApiRequest GetApiFilesRenameRequest(string resource, string new_resource /// Files.Delete Request public IApiRequest GetApiFilesDeleteRequest(string resource, string jsonRpc = null, string id = null) { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); return new ApiRequest("Files.Delete", jsonRpcReq, idReq, new Dictionary() { { "resource", resource } }); } @@ -737,8 +887,8 @@ public IApiRequest GetApiFilesDeleteRequest(string resource, string jsonRpc = nu /// Files.CreateDirectory Request public IApiRequest GetApiFilesCreateDirectoryRequest(string resource, string jsonRpc = null, string id = null) { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); return new ApiRequest("Files.CreateDirectory", jsonRpcReq, idReq, new Dictionary() { { "resource", resource } }); } @@ -752,8 +902,8 @@ public IApiRequest GetApiFilesCreateDirectoryRequest(string resource, string jso /// Files.DeleteDirectory Request public IApiRequest GetApiFilesDeleteDirectoryRequest(string resource, string jsonRpc = null, string id = null) { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); return new ApiRequest("Files.DeleteDirectory", jsonRpcReq, idReq, new Dictionary() { { "resource", resource } }); } @@ -762,13 +912,13 @@ public IApiRequest GetApiFilesDeleteDirectoryRequest(string resource, string jso /// /// get a Plc.CreateBackup Request /// - /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) + /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) /// JsonRpc to be used - defaults to JsonRpcVersion /// Plc.CreateBackup Request public IApiRequest GetPlcCreateBackupRequest(string jsonRpc = null, string id = null) { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); return new ApiRequest("Plc.CreateBackup", jsonRpcReq, idReq); } @@ -776,15 +926,15 @@ public IApiRequest GetPlcCreateBackupRequest(string jsonRpc = null, string id = /// get a Plc.RestoreBackup Request /// /// Password for authentication - /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) + /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) /// JsonRpc to be used - defaults to JsonRpcVersion /// Plc.RetoreBackup Request public IApiRequest GetPlcRestoreBackupRequest(string password, string jsonRpc = null, string id = null) { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); - var pwd= string.IsNullOrEmpty(password) ? string.Empty : password; - var reqParams = new Dictionary() { { "password", password?.ToString() } }; + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + var pwd = string.IsNullOrEmpty(password) ? string.Empty : password; + var reqParams = new Dictionary() { { "password", password?.ToString() } }; return new ApiRequest("Plc.RestoreBackup", jsonRpcReq, idReq, reqParams); } @@ -792,15 +942,216 @@ public IApiRequest GetPlcRestoreBackupRequest(string password, string jsonRpc = /// get a DataLogs.DownloadAndClear Request /// /// Path of the file relative to the memory card root. - /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) + /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) /// JsonRpc to be used - defaults to JsonRpcVersion /// DataLogs.DownloadAndClear Request public IApiRequest GetApiDatalogsDownloadAndClearRequest(string resource, string jsonRpc = null, string id = null) { - string jsonRpcReq = jsonRpc ?? JsonRpcVersion; - string idReq = id ?? RequestIdGenerator.Generate(); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); return new ApiRequest("DataLogs.DownloadAndClear", jsonRpcReq, idReq, new Dictionary() { { "resource", resource } }); } - } -} + + /// + /// Get a Failsafe.ReadParameters Request + /// + /// The hardware identifier from which the parameters shall be read + /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) + /// JsonRpc to be used - defaults to JsonRpcVersion + /// Failsafe.ReadParameters Request + public IApiRequest GetFailsafeReadParametersRequest(uint hwid, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Failsafe.ReadParameters", jsonRpcReq, idReq, new Dictionary() + { { "hwid", hwid } }); + } + + /// + /// Get a Failsafe.ReadRuntimeGroups Request + /// + /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) + /// JsonRpc to be used - defaults to JsonRpcVersion + /// Failsafe.ReadRuntimeGroups Request + public IApiRequest GetFailsafeReadRuntimeGroupsRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Failsafe.ReadRuntimeGroups", jsonRpcReq, idReq); + } + + /// + /// Get a Project.ReadLanguages request without parameters + /// + /// Request Id + /// JsonRpc to be used + /// Project.ReadLanguages request without parameters + public IApiRequest GetApiProjectReadLanguagesRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Project.ReadLanguages", jsonRpcReq, idReq); + } + + /// + /// Get a Modules.DownloadServiceData request + /// + /// The HWID of a node (module) for which a service data file can be downloaded + /// JsonRpc to be used - defaults to JsonRpcVersion + /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) + /// Modules.DownloadServiceData request + public IApiRequest GetModulesDownloadServiceData(ApiPlcHwId hwid, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Modules.DownloadServiceData", jsonRpcReq, idReq, new Dictionary() + { { "hwid", hwid } }); + } + /// + /// Get a WebServer.ReadDefaultPage Request + /// + /// + /// + /// + public IApiRequest GetApiWebserverReadDefaultPageRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebServer.ReadDefaultPage", jsonRpcReq, idReq); + } + + /// + /// Get a WebServer.SetDefaultPage Request + /// + /// + /// + /// + /// + public IApiRequest GetApiWebserverSetDefaultPageRequest(string defaultPage, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebServer.SetDefaultPage", jsonRpcReq, idReq, new Dictionary() { { "default_page", defaultPage } }); + } + + /// + /// Get a Syslog.Browse request + /// + /// (optional) The Redundancy ID parameter must be present when the request is executed on an R/H PLC.
+ /// In this case it must either have a value of 1 or 2, otherwise it is null. + /// (optional) The maximum number of syslog entries to be requested. Default value: 50
+ /// A count of 0 will omit any syslog entries from the response and only return the attributes last_modified, count_total and count_lost. + /// (optional) Allows the user to provide the id of an entry as a starting point for the returned entries array.
+ /// This allows the user to traverse through the syslog buffer using multiple API calls. + /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) + /// JsonRpc to be used - defaults to JsonRpcVersion + /// ApiSyslogBrowse request + public IApiRequest GetApiSyslogBrowseRequest(ApiPlcRedundancyId? redundancy_id = null, uint? count = null, uint? first = null, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + Dictionary requestParams = new Dictionary(); + if (redundancy_id != null && redundancy_id != 0) + { + requestParams.Add("redundancy_id", redundancy_id); + } + if (count != null) + { + requestParams.Add("count", count); + } + if (first != null) + { + requestParams.Add("first", first); + } + return new ApiRequest("Syslog.Browse", jsonRpcReq, idReq, requestParams); + } + + /// + /// Get a Alarms.Acknowledge request + /// + /// ApiAlarmsAcknowledgeRequest + /// Specifies the id of the alarm + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiAlarmsAcknowledgeRequest(string alarmId, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + Dictionary requestParams = new Dictionary() { { "id", alarmId } }; + return new ApiRequest("Alarms.Acknowledge", jsonRpcReq, idReq, requestParams); + } + + /// + /// Get a Alarms.Browse request + /// + /// ApiAlarmsBrowseRequest + /// The language in which the texts should be returned. + /// If the language is valid, then the response must contain the texts in the requested language.
+ /// An empty string shall be treated the same as an invalid language string. + /// + /// (optional) The maximum number of alarm entries to be requested.
+ /// When not provided, the plc will return with the default amount: 50.
+ /// The maximum possible count is 5000.
+ /// A count of 0 must omit any alarm entries from the response and must only return the attributes last_modified, count_max and count_current. + /// + /// (optional) The CPU alarm ID for which the user wants to return the data. If this is provided, no count parameter can be provided as filter. + /// (optional) Optional object that contains parameters to filter the response. + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + public virtual IApiRequest GetApiAlarmsBrowseRequest(CultureInfo language, + int? count = null, + string alarm_id = null, + ApiAlarms_RequestFilters filters = null, + string jsonRpc = null, + string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + Dictionary requestParams = new Dictionary() { { "language", language.Name } }; + if (alarm_id != null) + { + requestParams.Add("alarm_id", alarm_id); + } + //If alarm_id is provided, count can't be provided as filter. + if (count != null && alarm_id == null) + { + requestParams.Add("count", count); + } + if (filters != null) + { + requestParams.Add("filters", filters); + } + return new ApiRequest("Alarms.Browse", jsonRpcReq, idReq, requestParams); + } + + /// + /// Get a DiagnosticBuffer.Browse request + /// + /// Specifies the language of the response + /// Specifies maximum how many diagnosticbuffer entry you will get back + /// ApiDiagnosticBufferBrowse_RequestFilters representing various filtering possibilities. + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + /// ApiDiagnosticBufferBrowseRequest + public virtual IApiRequest GetApiDiagnosticBufferBrowseRequest(CultureInfo language, + uint? count = null, + ApiDiagnosticBuffer_RequestFilters filters = null, + string jsonRpc = null, + string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + Dictionary requestParams = new Dictionary() { { "language", language.Name } }; + if (count != null) + { + requestParams.Add("count", count); + } + if (filters != null) + { + requestParams.Add("filters", filters); + } + return new ApiRequest("DiagnosticBuffer.Browse", jsonRpcReq, idReq, requestParams); + } + } +} diff --git a/src/Webserver.API/Services/RequestHandling/ApiRequestParameterChecker.cs b/src/Webserver.API/Services/RequestHandling/ApiRequestParameterChecker.cs index 0051070..d61d69f 100644 --- a/src/Webserver.API/Services/RequestHandling/ApiRequestParameterChecker.cs +++ b/src/Webserver.API/Services/RequestHandling/ApiRequestParameterChecker.cs @@ -5,12 +5,9 @@ using Siemens.Simatic.S7.Webserver.API.Exceptions; using Siemens.Simatic.S7.Webserver.API.Models; using Siemens.Simatic.S7.Webserver.API.Models.Responses; +using Siemens.Simatic.S7.Webserver.API.Models.TimeSettings; using System; -using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Services.RequestHandling { @@ -26,11 +23,11 @@ public class ApiRequestParameterChecker : IApiRequestParameterChecker /// Bool to determine wether to really perform the check or not public void CheckWebAppState(ApiWebAppState apiWebAppState, bool performCheck) { - if(performCheck) + if (performCheck) { if (apiWebAppState == ApiWebAppState.None) { - throw new ApiInvalidParametersException($"WebApp function shall not be called with state None:{ Environment.NewLine + apiWebAppState.ToString() }" + + throw new ApiInvalidParametersException($"WebApp function shall not be called with state None:{Environment.NewLine + apiWebAppState.ToString()}" + $"{Environment.NewLine}Probably Api would send: ", new ApiException(new ApiErrorModel() { Error = new ApiError() { Code = ApiErrorCode.InvalidParams, Message = "Invalid Params" } })); } } @@ -126,7 +123,7 @@ public void CheckPlcRequestChangeOperatingMode(ApiPlcOperatingMode plcOperatingM { if (plcOperatingMode == ApiPlcOperatingMode.Run || plcOperatingMode == ApiPlcOperatingMode.Stop) return; - throw new ApiInvalidParametersException($"Plc.RequestChangeOperatingMode shall not be called with { Environment.NewLine + plcOperatingMode.ToString().ToLower() }" + + throw new ApiInvalidParametersException($"Plc.RequestChangeOperatingMode shall not be called with {Environment.NewLine + plcOperatingMode.ToString().ToLower()}" + $"{Environment.NewLine}Probably Api would send: ", new ApiException(new ApiErrorModel() { Error = new ApiError() { Code = ApiErrorCode.InvalidParams, Message = "Invalid Params" } })); } } @@ -142,7 +139,7 @@ public void CheckPlcProgramBrowseMode(ApiPlcProgramBrowseMode plcProgramBrowseMo { if (plcProgramBrowseMode == ApiPlcProgramBrowseMode.None) { - throw new ApiInvalidParametersException($"PlcProgram.Browse shall not be called with { Environment.NewLine + plcProgramBrowseMode.ToString().ToLower() }" + + throw new ApiInvalidParametersException($"PlcProgram.Browse shall not be called with {Environment.NewLine + plcProgramBrowseMode.ToString().ToLower()}" + $"{Environment.NewLine}Probably Api would send: ", new ApiException(new ApiErrorModel() { Error = new ApiError() { Code = ApiErrorCode.InvalidParams, Message = "Invalid Params" } })); } } @@ -161,7 +158,7 @@ public void CheckPlcProgramReadOrWriteMode(ApiPlcProgramReadOrWriteMode? apiPlcP { if (apiPlcProgramReadMode == ApiPlcProgramReadOrWriteMode.None) { - throw new ApiInvalidParametersException($"PlcProgram.Read or Write shall not be called with { Environment.NewLine + apiPlcProgramReadMode.ToString().ToLower() }" + + throw new ApiInvalidParametersException($"PlcProgram.Read or Write shall not be called with {Environment.NewLine + apiPlcProgramReadMode.ToString().ToLower()}" + $"{Environment.NewLine}Probably Api would send: ", new ApiException(new ApiErrorModel() { Error = new ApiError() { Code = ApiErrorCode.InvalidParams, Message = "Invalid Params" } })); } } @@ -179,7 +176,7 @@ public void CheckTicket(string ticketId, bool performCheck) { if (ticketId?.Length != 28 && ticketId?.Length != 36) { - throw new ApiInvalidParametersException($"Api Tickets cannot have a length other than 28 bytes!{ Environment.NewLine + ticketId + Environment.NewLine }provide a valid ticket!" + + throw new ApiInvalidParametersException($"Api Tickets cannot have a length other than 28 bytes!{Environment.NewLine + ticketId + Environment.NewLine}provide a valid ticket!" + $"{Environment.NewLine}Probably Api would send: ", new ApiException(new ApiErrorModel() { Error = new ApiError() { Code = ApiErrorCode.InvalidParams, Message = "Invalid Params" } })); } } @@ -194,13 +191,13 @@ public void CheckETag(string etag, bool performCheck) { if (performCheck) { - if(string.IsNullOrEmpty(etag)) + if (string.IsNullOrEmpty(etag)) { // maybe throw here but for now let "the plc decide" } - else if(etag.Length > 128) + else if (etag.Length > 128) { - throw new ApiInvalidETagException($"WebApp.CreateResource shall not be called with \"etag\" { Environment.NewLine + etag } because the value is too long!-max 128 bytes(chars)" + + throw new ApiInvalidETagException($"WebApp.CreateResource shall not be called with \"etag\" {Environment.NewLine + etag} because the value is too long!-max 128 bytes(chars)" + $"{Environment.NewLine}Probably Api would send: ", new ApiException(new ApiErrorModel() { Error = new ApiError() { Code = ApiErrorCode.InvalidParams, Message = "Invalid Params" } })); } } @@ -217,7 +214,7 @@ public void CheckMediaType(string mediaType, bool performCheck) { ; } - // could provide a insanely long list of possible mediaTypes look: https://www.iana.org/assignments/media-types/media-types.xhtml - will not do it until requested! + // could provide a insanely long list of possible mediaTypes look: https://www.iana.org/assignments/media-types/media-types.xhtml - will not do it until requested! } /// @@ -230,7 +227,7 @@ public void CheckWebAppResourceVisibility(ApiWebAppResourceVisibility apiWebAppR if (performCheck) { if (apiWebAppResourceVisibility == ApiWebAppResourceVisibility.None) - throw new ApiInvalidParametersException($"WebApp.CreateResource shall not be called with { Environment.NewLine + apiWebAppResourceVisibility.ToString().ToLower() }" + + throw new ApiInvalidParametersException($"WebApp.CreateResource shall not be called with {Environment.NewLine + apiWebAppResourceVisibility.ToString().ToLower()}" + $"{Environment.NewLine}Probably Api would send: ", new ApiException(new ApiErrorModel() { Error = new ApiError() { Code = ApiErrorCode.InvalidParams, Message = "Invalid Params" } })); } } @@ -255,6 +252,25 @@ public void CheckLastModified(string lastModified, bool performCheck) } } + /// + /// DateTime is only supported from 1970-01-01 to 2554-07-21 23:34:33.709551615 + /// + /// Timestamp to check + /// Bool to determine wether to really perform the check or not + public void CheckSystemTimeStamp(DateTime timestamp, bool performCheck) + { + if (performCheck) + { + var dtMin = new DateTime(1970, 1, 1); + var dtMax = new DateTime(2554, 7, 21, 23, 34, 33, 709); + if (timestamp < dtMin || timestamp > dtMax) + { + throw new ApiTimestampOutOfRangeException($"The given date is unsupported -- it's out of range! Supported range is between 1970-01-01T00:00:00Z and 2554-07-21T23:34:33.709551615Z" + + $"{Environment.NewLine}Probably Api would send: ", new ApiException(new ApiErrorModel() { Error = new ApiError() { Code = ApiErrorCode.TimestampOutOfRange, Message = "The timestamp is not within the allowed range of timestamps" } })); + } + } + } + /// /// Override equals - will always be true since there are no Properties to compare /// @@ -280,5 +296,79 @@ public override int GetHashCode() { return base.GetHashCode(); } + + /// + /// Checks username for Api.ChangePassword (can't be the Anonymous user) + /// + /// Username to check + /// Bool to determine whether to really perform the check or not + public void CheckUsername(string username, bool performCheck) + { + if (performCheck) + { + if (username == null || username == "") + { + throw new ApiInvalidParametersException($"Username can't be empty! {Environment.NewLine}" + + $"{Environment.NewLine}Probably Api would send: ", new ApiException(new ApiErrorModel() { Error = new ApiError() { Code = ApiErrorCode.InvalidParams, Message = "Invalid Params" } })); + } + if (username == "Anonymous") + { + throw new ApiPasswordChangeNotAcceptedException($"Password can not be changed for the Anonymous user! {Environment.NewLine}" + + $"{Environment.NewLine}Probably Api would send: ", new ApiException(new ApiErrorModel() { Error = new ApiError() { Code = ApiErrorCode.PasswordChangeNotAccepted, Message = "The password change cannot be performed" } })); + } + } + } + /// + /// Checks whether current and new password matches + /// + /// Current password of the user + /// New password for the user + /// Bool to determine whether to really perform the check or not + public void CheckPasswords(string currentPassword, string newPassword, bool performCheck) + { + if (performCheck) + { + if (currentPassword == newPassword) + { + throw new ApiNewPasswordMatchesOldPasswordException($"New password can not be the same as current password! {Environment.NewLine}" + + $"{Environment.NewLine}Probably Api would send: ", new ApiException(new ApiErrorModel() { Error = new ApiError() { Code = ApiErrorCode.NewPasswordMatchesOldPassword, Message = "The provided new password is identical with a former password" } })); + } + } + } + + /// + /// Checks whether the TimeSetting parameters are correct + /// + /// The time zone offset from the UTC time in hours + /// Represents the settings for daylight-savings. + /// Bool to determine wether to really perform the check or not + public void CheckTimeSettings(TimeSpan utcOffset, DaylightSavingsRule daylightSavings, bool performCheck) + { + if (performCheck) + { + //the time range of UTC offsets is between UTC+13 and UTC-12, this may change in the future. + //If it contains a precision higher than minutes, it must be considered invalid. + if (utcOffset.Seconds != 0 || utcOffset.Milliseconds != 0 || + utcOffset.TotalHours > 13 || utcOffset.TotalHours < -12) + { + throw new ApiInvalidUTCOffsetException($"The Utc Offset must be between +13hrs and -12hrs. Please do not use seconds and milliseconds." + + $"{Environment.NewLine}Probably Api would send: ", new ApiException(new ApiErrorModel() { Error = new ApiError() { Code = ApiErrorCode.InvalidUTCOffset, Message = "Invalid UTC offset" } })); + } + //allowed value range must be between -180 and +180 (inclusive). + //If it contains a precision higher than minutes, it must be considered invalid. + if (daylightSavings != null) + { + if (daylightSavings.Dst == null || daylightSavings.Std == null || + daylightSavings.Dst.Start == null || daylightSavings.Std.Start == null || + daylightSavings.Dst.Offset.TotalMinutes > 180 || daylightSavings.Dst.Offset.TotalMinutes < -180 || + daylightSavings.Dst.Offset.Seconds != 0 || daylightSavings.Dst.Offset.Milliseconds != 0) + { + throw new ApiInvalidTimeRuleException($"The DaylightSavingsTimeConfiguration TimeOffset must be between +180mins and -180mins. Please do not use seconds and milliseconds." + + $"{Environment.NewLine}Probably Api would send: ", new ApiException(new ApiErrorModel() { Error = new ApiError() { Code = ApiErrorCode.InvalidTimeRule, Message = "Invalid time rule" } })); + } + } + + } + } } } diff --git a/src/Webserver.API/Services/RequestHandling/ApiResponseChecker.cs b/src/Webserver.API/Services/RequestHandling/ApiResponseChecker.cs index 523f421..b937fea 100644 --- a/src/Webserver.API/Services/RequestHandling/ApiResponseChecker.cs +++ b/src/Webserver.API/Services/RequestHandling/ApiResponseChecker.cs @@ -5,11 +5,7 @@ using Siemens.Simatic.S7.Webserver.API.Exceptions; using Siemens.Simatic.S7.Webserver.API.Models.Responses; using System; -using System.Collections.Generic; -using System.Linq; using System.Net.Http; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Services.RequestHandling { @@ -53,7 +49,7 @@ public void CheckResponseStringForErros(string responseString, string apiRequest { // apiErrorModel will be null in case no Error is to be thrown! ApiErrorModel apiErrorModel = JsonConvert.DeserializeObject(responseString); - if(apiErrorModel.Error != null) + if (apiErrorModel.Error != null) { apiErrorModel.ThrowAccordingException(apiRequestString, responseString); } diff --git a/src/Webserver.API/Services/RequestHandling/IApiRequestFactory.cs b/src/Webserver.API/Services/RequestHandling/IApiRequestFactory.cs index adee908..3828e68 100644 --- a/src/Webserver.API/Services/RequestHandling/IApiRequestFactory.cs +++ b/src/Webserver.API/Services/RequestHandling/IApiRequestFactory.cs @@ -2,9 +2,13 @@ // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; +using Siemens.Simatic.S7.Webserver.API.Models.AlarmsBrowse; +using Siemens.Simatic.S7.Webserver.API.Models.ApiDiagnosticBuffer; using Siemens.Simatic.S7.Webserver.API.Models.Requests; +using Siemens.Simatic.S7.Webserver.API.Models.TimeSettings; using System; using System.Collections.Generic; +using System.Globalization; namespace Siemens.Simatic.S7.Webserver.API.Services.RequestHandling { @@ -47,6 +51,30 @@ public interface IApiRequestFactory /// JsonRpc to be used IApiRequest GetApiCloseTicketRequest(string ticketId, string jsonRpc = null, string id = null); /// + /// Get an Api.ChangePassword request with parameters + /// + /// The user account for which the password shall be changed + /// The current password for the user + /// The new password for the user + /// Request Id + /// JsonRpc to be used + /// an Api.ChangePassword request + IApiRequest GetApiChangePasswordRequest(string username, string currentPassword, string newPassword, string jsonRpc = null, string id = null); + /// + /// Get an Api.GetPasswordPolicy request + /// + /// Request Id + /// JsonRpc to be used + /// An Api.GetPasswordPolicy request + IApiRequest GetApiGetPasswordPolicyRequest(string jsonRpc = null, string id = null); + /// + /// Get an Api.GetAuthenticationMode request + /// + /// Request Id + /// JsonRpc to be used + /// An Api.GetAuthenticationMode request + IApiRequest GetApiGetAuthenticationModeRequest(string jsonRpc = null, string id = null); + /// /// get an Api.GetCertificateUrl Request without parameters /// /// Api.GetCertificateUrl Request without parameters @@ -80,6 +108,13 @@ IApiRequest GetApiLoginRequest(string userName, string password, bool? include_w /// JsonRpc to be used IApiRequest GetApiGetPermissionsRequest(string jsonRpc = null, string id = null); /// + /// Get an Api.GetQuantityStructures Request without parameters + /// + /// Api.GetQuantityStructures Request without parameters + /// Request Id + /// JsonRpc to be used + IApiRequest GetApiGetQuantityStructuresRequest(string jsonRpc = null, string id = null); + /// /// get an Api.Ping Request without parameters /// /// Api.Ping Request without parameters @@ -87,6 +122,13 @@ IApiRequest GetApiLoginRequest(string userName, string password, bool? include_w /// JsonRpc to be used IApiRequest GetApiPingRequest(string jsonRpc = null, string id = null); /// + /// Get a Project.ReadLanguages request without parameters + /// + /// Request Id + /// JsonRpc to be used + /// Project.ReadLanguages request without parameters + IApiRequest GetApiProjectReadLanguagesRequest(string jsonRpc = null, string id = null); + /// /// get an PlcProgram.Browse Request with parameter "mode": apiPlcProgramBrowseMode, "var" : var (might be null) /// /// Var or children @@ -95,6 +137,23 @@ IApiRequest GetApiLoginRequest(string userName, string password, bool? include_w /// Request Id /// JsonRpc to be used IApiRequest GetApiPlcProgramBrowseRequest(ApiPlcProgramBrowseMode apiPlcProgramBrowseMode, string var = null, string jsonRpc = null, string id = null); + + /// + /// Get a PlcProgram.Browse request for the code blocks with parameters "mode":"Children", and "type"=["code_blocks"]). + /// + /// PlcProgram.Browse request for the code blocks with parameters "mode":"Children", and "type"=["code_blocks"]). + /// Request Id + /// JsonRpc to be used + IApiRequest GetApiPlcProgramBrowseCodeBlocksRequest(string jsonRpc = null, string id = null); + + /// + /// Get a PlcProgram.DownloadProfilingData request. + /// + /// PlcProgram.DownloadProfilingData request. + /// Request Id + /// JsonRpc to be used + IApiRequest GetApiPlcProgramDownloadProfilingDataRequest(string jsonRpc = null, string id = null); + /// /// get an PlcProgram.Read Request with parameter "var" : var, "mode": apiPlcProgramReadMode (might be null) - /// @@ -139,6 +198,14 @@ IApiRequest GetApiLoginRequest(string userName, string password, bool? include_w /// JsonRpc to be used IApiRequest GetApiPlcRequestChangeOperatingModeRequest(ApiPlcOperatingMode apiPlcOperatingMode, string jsonRpc = null, string id = null); /// + /// Get a Plc.ReadModeSelectorState Request with redundancy id parameter + /// + /// In an R/H system, a PLC with ID 1 (primary) or 2 (backup). For standard PLCs, enum value 0 (StandardPLC) is required. + /// Request Id + /// JsonRpc to be used + /// Plc.ReadModeSelectorState request with redundancy id parameter + IApiRequest GetApiPlcReadModeSelectorStateRequest(ApiPlcRedundancyId rhid, string jsonRpc = null, string id = null); + /// /// check new Etag value /// get an WebApp.SetResourceETag Request with parameter "app_name" : webAppName,"name": resourceName, "etag" : newETagValue /// @@ -330,6 +397,15 @@ IApiRequest GetApiWebAppCreateResourceRequest(string webAppName, string resource /// JsonRpc to be used - defaults to JsonRpcVersion IApiRequest GetApiPlcReadSystemTimeRequest(string jsonRpc = null, string id = null); + /// + /// get an Plc.SetSystemTime Request + /// + /// Plc.SetSystemTime Request + /// The timestamp of the system time to be set + /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) + /// JsonRpc to be used - defaults to JsonRpcVersion + IApiRequest GetApiPlcSetSystemTimeRequest(DateTime timestamp, string jsonRpc = null, string id = null); + /// /// get an Plc.ReadTimeSettings Request /// @@ -337,7 +413,15 @@ IApiRequest GetApiWebAppCreateResourceRequest(string webAppName, string resource /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) /// JsonRpc to be used - defaults to JsonRpcVersion IApiRequest GetApiPlcReadTimeSettingsRequest(string jsonRpc = null, string id = null); - + /// + /// Get an Plc.SetTimeSettings request + /// + /// The time zone offset from the UTC time in hours + /// (Optional) Represents the settings for daylight-savings. If there is no daylight-savings rule configured, the utcOffset is applied to calculate the local time + /// Request Id + /// JsonRpc to be used + /// Plc.SetTimeSettings Request + IApiRequest GetApiPlcSetTimeSettingsRequest(TimeSpan utcOffset, DaylightSavingsRule daylightSavings = null, string jsonRpc = null, string id = null); /// /// get an Files.Browse Request /// @@ -434,6 +518,105 @@ IApiRequest GetApiWebAppCreateResourceRequest(string webAppName, string resource /// Password the Plc.RestoreBackup should be called with /// Plc.CreateBackup Request IApiRequest GetPlcRestoreBackupRequest(string jsonRpc = null, string id = null, string password = null); + + /// + /// Get a Failsafe.ReadParameters Request + /// + /// The hardware identifier from which the parameters shall be read + /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) + /// JsonRpc to be used - defaults to JsonRpcVersion + /// Failsafe.ReadParameters Request + IApiRequest GetFailsafeReadParametersRequest(uint hwid, string jsonRpc = null, string id = null); + + /// + /// Get a Failsafe.ReadRuntimeGroups Request + /// + /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) + /// JsonRpc to be used - defaults to JsonRpcVersion + /// Failsafe.ReadRuntimeGroups Request + IApiRequest GetFailsafeReadRuntimeGroupsRequest(string jsonRpc = null, string id = null); + + /// + /// Get a Modules.DownloadServiceData request + /// + /// The HWID of a node (module) for which a service data file can be downloaded + /// JsonRpc to be used - defaults to JsonRpcVersion + /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) + /// Modules.DownloadServiceData request + IApiRequest GetModulesDownloadServiceData(ApiPlcHwId hwid, string jsonRpc = null, string id = null); + + /// + /// Get a WebServer.ReadDefaultPage Request + /// + /// + /// + /// + IApiRequest GetApiWebserverReadDefaultPageRequest(string jsonRpc = null, string id = null); + + /// + /// get a WebServer.SetDefaultPage Request with parameter "default_page" : default page name + /// examples: "default_page" : "index.html" OR "default_page" : "/~webapp1/index.html" OR "default_page" : "" + /// + /// Name of the desired default page + /// WebApp.SetDefaultPage Request with parameter "default_page" : default page name + /// Request Id + /// JsonRpc to be used + IApiRequest GetApiWebserverSetDefaultPageRequest(string defaultPage, string jsonRpc = null, string id = null); + + /// + /// Get a Syslog.Browse request + /// + /// (optional) The Redundancy ID parameter must be present when the request is executed on an R/H PLC.
+ /// In this case it must either have a value of 1 or 2, otherwise it is null. + /// (optional) The maximum number of syslog entries to be requested. Default value: 50
+ /// A count of 0 will omit any syslog entries from the response and only return the attributes last_modified, count_total and count_lost. + /// (optional) Allows the user to provide the id of an entry as a starting point for the returned entries array.
+ /// This allows the user to traverse through the syslog buffer using multiple API calls. + /// Request Id, defaults to RequestIdGenerator.GetRandomString(8) + /// JsonRpc to be used - defaults to JsonRpcVersion + /// ApiSyslogBrowse request + IApiRequest GetApiSyslogBrowseRequest(ApiPlcRedundancyId? redundancy_id = null, uint? count = null, uint? first = null, string jsonRpc = null, string id = null); + + /// + /// Get a Alarms.Acknowledge request + /// + /// ApiAlarmsAcknowledgeRequest + /// Specifies the id of the alarm + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + IApiRequest GetApiAlarmsAcknowledgeRequest(string alarmId, string jsonRpc = null, string id = null); + + /// + /// Get a Alarms.Browse request + /// + /// ApiAlarmsBrowseRequest + /// The language in which the texts should be returned. + /// If the language is valid, then the response must contain the texts in the requested language.
+ /// An empty string shall be treated the same as an invalid language string. + /// + /// (optional) The maximum number of alarm entries to be requested. Default value: 50
+ /// A count of 0 must omit any alarm entries from the response and must only return the attributes last_modified, count_max and count_current. + /// + /// (optional) The CPU alarm ID for which the user wants to return the data. If this is provided, no other parameters can be provided as filter. + /// (optional) Optional object that contains parameters to filter the response. + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + IApiRequest GetApiAlarmsBrowseRequest(CultureInfo language, int? count = null, string alarm_id = null, ApiAlarms_RequestFilters filters = null, string jsonRpc = null, string id = null); + + /// + /// Get a DiagnosticBuffer.Browse request + /// + /// Specifies the language of the response + /// Specifies maximum how many diagnosticbuffer entry you will get back + /// ApiDiagnosticBufferBrowse_RequestFilters representing various filtering possibilities. + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + /// ApiDiagnosticBufferBrowseRequest + IApiRequest GetApiDiagnosticBufferBrowseRequest(CultureInfo language, + uint? count = null, + ApiDiagnosticBuffer_RequestFilters filters = null, + string jsonRpc = null, + string id = null); } } \ No newline at end of file diff --git a/src/Webserver.API/Services/RequestHandling/IApiRequestHandler.cs b/src/Webserver.API/Services/RequestHandling/IApiRequestHandler.cs index b90c750..52534ae 100644 --- a/src/Webserver.API/Services/RequestHandling/IApiRequestHandler.cs +++ b/src/Webserver.API/Services/RequestHandling/IApiRequestHandler.cs @@ -1,16 +1,21 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Enums; +using Siemens.Simatic.S7.Webserver.API.Models; +using Siemens.Simatic.S7.Webserver.API.Models.AlarmsBrowse; +using Siemens.Simatic.S7.Webserver.API.Models.ApiDiagnosticBuffer; +using Siemens.Simatic.S7.Webserver.API.Models.Requests; +using Siemens.Simatic.S7.Webserver.API.Models.Responses; +using Siemens.Simatic.S7.Webserver.API.Models.TimeSettings; using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Net.Http; using System.Text; +using System.Threading; using System.Threading.Tasks; -using Siemens.Simatic.S7.Webserver.API.Enums; -using Siemens.Simatic.S7.Webserver.API.Models; -using Siemens.Simatic.S7.Webserver.API.Models.Requests; -using Siemens.Simatic.S7.Webserver.API.Models.Responses; namespace Siemens.Simatic.S7.Webserver.API.Services.RequestHandling { @@ -37,25 +42,32 @@ public interface IApiRequestHandler ///
/// an array of ApiResponses /// api Requests to send - Task ApiBulkAsync(IEnumerable apiRequests); - + Task ApiBulkAsync(IEnumerable apiRequests, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send an Api.Browse Request /// /// An Array of ApiClass (and Id,Jsonrpc) - Task ApiBrowseAsync(); + Task ApiBrowseAsync(CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Send an Api.BrowseTickets Request + /// + /// Cancellation token to cancel pending requests. + /// BrowseTickets Response containing: Max_Tickets:uint, Tickets:Array of Ticket + Task ApiBrowseTicketsAsync(CancellationToken cancellationToken); /// /// Send an Api.BrowseTickets Request /// /// ticket id (28 chars) + /// Cancellation token to cancel pending requests. /// BrowseTickets Response containing: Max_Tickets:uint, Tickets:Array of Ticket - Task ApiBrowseTicketsAsync(string ticketId = null); + Task ApiBrowseTicketsAsync(string ticketId = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send an Api.BrowseTickets Request /// /// ticket to be browsed (null to browse all) + /// Cancellation token to cancel pending requests. /// BrowseTickets Response containing: Max_Tickets:uint, Tickets:Array of Ticket - Task ApiBrowseTicketsAsync(ApiTicket ticket); + Task ApiBrowseTicketsAsync(ApiTicket ticket, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send an Api.BrowseTickets Request /// @@ -72,24 +84,53 @@ public interface IApiRequestHandler /// Send an Api.CloseTicket Request /// /// ticket id (28 chars) + /// Cancellation token to cancel pending requests. /// True to indicate Success - Task ApiCloseTicketAsync(string ticketId); + Task ApiCloseTicketAsync(string ticketId, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send an Api.CloseTicket Request /// /// ticket containing ticket id (28 chars) + /// Cancellation token to cancel pending requests. /// True to indicate Success - Task ApiCloseTicketAsync(ApiTicket ticket); + Task ApiCloseTicketAsync(ApiTicket ticket, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Send an Api.ChangePassword request + /// + /// The user account for which the password shall be changed + /// The current password for the user + /// The new password for the user + /// True if changing password for the user was successful + Task ApiChangePasswordAsync(string username, string currentPassword, string newPassword, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Send an Api.ChangePassword request + /// + /// The user account for which the password shall be changed + /// The current password for the user + /// The new password for the user + /// True if changing password for the user was successful + ApiTrueOnSuccessResponse ApiChangePassword(string username, string currentPassword, string newPassword); /// /// Send an Api.GetCertificateUrl Request /// /// ApiSingleStringResponse that contians the URL to the certificate - Task ApiGetCertificateUrlAsync(); + Task ApiGetCertificateUrlAsync(CancellationToken cancellationToken = default(CancellationToken)); /// /// Send an Api.GetPermissions Request /// + /// Cancellation token to cancel pending requests. /// Array of ApiClass (in this case permissions) - Task ApiGetPermissionsAsync(); + Task ApiGetPermissionsAsync(CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Send an Api.GetQuantityStructures Request + /// + /// A QuantityStructure object + Task ApiGetQuantityStructuresAsync(CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Send an Api.GetQuantityStructures Request + /// + /// A QuantityStructure object + ApiGetQuantityStructuresResponse ApiGetQuantityStructures(); /// /// Send a Api.Login Request /// @@ -97,34 +138,37 @@ public interface IApiRequestHandler /// Password for the user to login with /// Used to determine wether or not a WebApplicationCookie should be included in the Response (Result) /// ApiLoginResponse: contains ApiTokenResult: Token(auth token string) and if requested Web_application_cookie - Task ApiLoginAsync(string userName, string password, bool? includeWebApplicationCookie = null); + Task ApiLoginAsync(string userName, string password, bool? includeWebApplicationCookie = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send an Api.Logout Request /// + /// Cancellation token to cancel pending requests. /// True to indicate success - Task ApiLogoutAsync(); + Task ApiLogoutAsync(CancellationToken cancellationToken = default(CancellationToken)); /// /// Send an Api.Ping Request /// /// ApiSingleStringResponse - an Id that'll stay the same for the users session - Task ApiPingAsync(); + Task ApiPingAsync(CancellationToken cancellationToken = default(CancellationToken)); /// /// Send an Api.Version Request /// /// a double that contains the value for the current ApiVersion - Task ApiVersionAsync(); + Task ApiVersionAsync(CancellationToken cancellationToken = default(CancellationToken)); /// /// Function to get the ByteArray Requested by a Ticket (e.g. DownloadResource) /// /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=+ticketId + /// Cancellation token to cancel pending requests. /// Bytearray given from the PLC - Task DownloadTicketAsync(string ticketId); + Task DownloadTicketAsync(string ticketId, CancellationToken cancellationToken = default(CancellationToken)); /// - /// Function to get the ByteArray Requested by a Ticket (e.g. DownloadResource) + /// Function to get the ByteArray Requested by a Ticket (e.g. DownloadResource) /// /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=+ticketId + /// Cancellation token to cancel pending requests. /// HTTp response - Task DownloadTicketAndGetResponseAsync(string ticketId); + Task DownloadTicketAndGetResponseAsync(string ticketId, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a PlcProgram.Browse Request /// @@ -142,7 +186,7 @@ public interface IApiRequestHandler /// sucht die Variable und liefert eine Liste an Kind-Variablen und Metadaten. /// /// PlcProgramBrowseResponse: An Array of ApiPlcProgramData - Task PlcProgramBrowseAsync(ApiPlcProgramBrowseMode plcProgramBrowseMode, string var = null); + Task PlcProgramBrowseAsync(ApiPlcProgramBrowseMode plcProgramBrowseMode, string var = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a PlcProgram.Browse Request /// @@ -160,7 +204,7 @@ public interface IApiRequestHandler /// sucht die Variable und liefert eine Liste an Kind-Variablen und Metadaten. /// /// PlcProgramBrowseResponse: An Array of ApiPlcProgramData - Task PlcProgramBrowseAsync(ApiPlcProgramBrowseMode plcProgramBrowseMode, ApiPlcProgramData var); + Task PlcProgramBrowseAsync(ApiPlcProgramBrowseMode plcProgramBrowseMode, ApiPlcProgramData var, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a PlcProgram.Read Request /// @@ -177,7 +221,7 @@ public interface IApiRequestHandler /// • "raw": liefert Variablenwerte gemäß der Darstellung "raw" /// in Kapitel "Unterstützte Datentypen" /// ApiPlcProgramReadResponse: object with the value for the variables value to be read - Task> PlcProgramReadAsync(ApiPlcProgramData var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null); + Task> PlcProgramReadAsync(ApiPlcProgramData var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a PlcProgram.Read Request /// @@ -193,7 +237,7 @@ public interface IApiRequestHandler /// • "raw": liefert Variablenwerte gemäß der Darstellung "raw" /// in Kapitel "Unterstützte Datentypen" /// ApiPlcProgramReadResponse: object with the value for the variables value to be read - Task> PlcProgramReadAsync(string var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null); + Task> PlcProgramReadAsync(string var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a PlcProgram.Write Request /// This function will build up the name with quotes from the parents given with the ApiPlcProgramDataand call PlcProgramWrite @@ -204,7 +248,7 @@ public interface IApiRequestHandler /// /// /// true to indicate success - Task PlcProgramWriteAsync(ApiPlcProgramData var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null); + Task PlcProgramWriteAsync(ApiPlcProgramData var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a PlcProgram.Write Request /// @@ -214,25 +258,26 @@ public interface IApiRequestHandler /// /// /// true to indicate success - Task PlcProgramWriteAsync(string var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null); + Task PlcProgramWriteAsync(string var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a Plc.ReadOperatingMode Request /// /// The current Plc OperatingMode - Task PlcReadOperatingModeAsync(); + Task PlcReadOperatingModeAsync(CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a Plc.RequestChangeOperatingMode Request /// Method to change the plc operating mode /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. /// /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. - Task PlcRequestChangeOperatingModeAsync(ApiPlcOperatingMode plcOperatingMode); + Task PlcRequestChangeOperatingModeAsync(ApiPlcOperatingMode plcOperatingMode, CancellationToken cancellationToken = default(CancellationToken)); /// /// only use this function if you know how to build up apiRequests on your own! /// /// Api Request to send to the plc + /// Cancellation token to cancel pending requests. /// string: response from thePLC - Task SendPostRequestAsync(IApiRequest apiRequest); + Task SendPostRequestAsync(IApiRequest apiRequest, CancellationToken cancellationToken = default(CancellationToken)); /// /// only use this function if you know how to build up apiRequests on your own! /// @@ -244,8 +289,9 @@ public interface IApiRequestHandler /// will remove those Params that have the value Null and send the request using the HttpClient. /// /// Api Request to send to the plc (Json Serialized - null properties are deleted) + /// Cancellation token to cancel pending requests. /// string: response from thePLC - Task SendPostRequestAsync(IApiRequestIntId apiRequestWithIntId); + Task SendPostRequestAsync(IApiRequestIntId apiRequestWithIntId, CancellationToken cancellationToken = default(CancellationToken)); /// /// only use this function if you know how to build up apiRequests on your own! /// will remove those Params that have the value Null and send the request using the HttpClient. @@ -258,8 +304,9 @@ public interface IApiRequestHandler /// will remove those Params that have the value Null and send the request using the HttpClient. /// /// further information about the Api requeest the user tried to send (or was trying to send) + /// Cancellation token to cancel pending requests. /// string: response from thePLC - Task SendPostRequestAsync(string apiRequestString); + Task SendPostRequestAsync(string apiRequestString, CancellationToken cancellationToken = default(CancellationToken)); /// /// only use this function if you know how to build up apiRequests on your own! /// will remove those Params that have the value Null and send the request using the HttpClient. @@ -273,7 +320,7 @@ public interface IApiRequestHandler /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId /// ByteArray that should be sent to the plc Ticketing Endpoint /// Task/void - Task UploadTicketAsync(string ticketId, ByteArrayContent data); + Task UploadTicketAsync(string ticketId, ByteArrayContent data, CancellationToken cancellationToken = default(CancellationToken)); /// /// Function to Read and send the ByteArrayContent for a file with the Ticketing Endpoint Ticket (e.g. CreateResource) /// MediaTypeHeaderValue: application/octet-stream @@ -281,19 +328,19 @@ public interface IApiRequestHandler /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId /// File Bytes will be Read and saved into ByteArrayContent - then sent to the ticketing Endpoint /// Task/void - Task UploadTicketAsync(string ticketId, string pathToFile); + Task UploadTicketAsync(string ticketId, string pathToFile, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.Browse Request /// /// webapp name in case only one is requested /// ApiWebAppBrowseResponse: Containing WebAppBrowseResult: Max_Applications:uint, Applications: Array of ApiWebAppdata - Task WebAppBrowseAsync(string webAppName = null); + Task WebAppBrowseAsync(string webAppName = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.Browse Request /// /// webappdata that should be requested /// ApiWebAppBrowseResponse: Containing WebAppBrowseResult: Max_Applications:uint, Applications: Array of ApiWebAppdata containing one element: the webappdata that has been requested - Task WebAppBrowseAsync(ApiWebAppData webAppData); + Task WebAppBrowseAsync(ApiWebAppData webAppData, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.BrowseResources Request /// Will return the Api Response "straight away" @@ -302,7 +349,7 @@ public interface IApiRequestHandler /// WebApp.Name to browse resources of /// If given only that resource will be inside the array (in case it exists) /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint,Resources - Task WebAppBrowseResourcesAsync(ApiWebAppData webApp, string resourceName = null); + Task WebAppBrowseResourcesAsync(ApiWebAppData webApp, string resourceName = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.BrowseResources Request /// Will return the Api Response "straight away" @@ -311,7 +358,7 @@ public interface IApiRequestHandler /// WebApp Name to browse resources of /// resource.Name to browse for /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint,Resources - Task WebAppBrowseResourcesAsync(string webAppName, ApiWebAppResource resource); + Task WebAppBrowseResourcesAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.BrowseResources Request /// Will return the Api Response "straight away" @@ -320,7 +367,7 @@ public interface IApiRequestHandler /// webApp.Name to browse resources of /// resource.Name to browse for /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint,Resources:Array of ApiWebAppResource (only 1 if one is requested) - Task WebAppBrowseResourcesAsync(ApiWebAppData webApp, ApiWebAppResource resource); + Task WebAppBrowseResourcesAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.BrowseResources Request /// Will return the Api Response "straight away" @@ -329,20 +376,20 @@ public interface IApiRequestHandler /// WebApp name to browse resources of /// If given only that resource will be inside the array (in case it exists) /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint,Resources - Task WebAppBrowseResourcesAsync(string webAppName, string resourceName = null); + Task WebAppBrowseResourcesAsync(string webAppName, string resourceName = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.Create Request /// /// containing information about name and state for the app to be created /// true to indicate success - Task WebAppCreateAsync(ApiWebAppData webApp); + Task WebAppCreateAsync(ApiWebAppData webApp, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.Create Request /// /// webapp name for the app to be created /// optional parameter: state the webapp should be in /// true to indicate success - Task WebAppCreateAsync(string webAppName, ApiWebAppState? apiWebAppState = null); + Task WebAppCreateAsync(string webAppName, ApiWebAppState? apiWebAppState = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.CreateResource Request /// @@ -354,7 +401,7 @@ public interface IApiRequestHandler /// Visibility: resource visibility (protect your confidential data) /// Etag: you can provide an etag as identification,... for your resource /// TicketId for the Ticketing Endpoint to perform the Upload on - Task WebAppCreateResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource); + Task WebAppCreateResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.CreateResource Request /// @@ -366,7 +413,7 @@ public interface IApiRequestHandler /// Visibility: resource visibility (protect your confidential data) /// Etag: you can provide an etag as identification,... for your resource /// TicketId for the Ticketing Endpoint to perform the Upload on - Task WebAppCreateResourceAsync(string webAppName, ApiWebAppResource resource); + Task WebAppCreateResourceAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.CreateResource Request /// @@ -377,7 +424,7 @@ public interface IApiRequestHandler /// resource visibility (protect your confidential data) /// you can provide an etag as identification,... for your resource /// TicketId for the Ticketing Endpoint to perform the Upload on - Task WebAppCreateResourceAsync(ApiWebAppData webApp, string resourceName, string media_type, string last_modified, ApiWebAppResourceVisibility? apiWebAppResourceVisibility = null, string etag = null); + Task WebAppCreateResourceAsync(ApiWebAppData webApp, string resourceName, string media_type, string last_modified, ApiWebAppResourceVisibility? apiWebAppResourceVisibility = null, string etag = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.CreateResource Request /// @@ -388,75 +435,75 @@ public interface IApiRequestHandler /// resource visibility (protect your confidential data) /// you can provide an etag as identification,... for your resource /// TicketId for the Ticketing Endpoint to perform the Upload on - Task WebAppCreateResourceAsync(string webAppName, string resourceName, string media_type, string last_modified, ApiWebAppResourceVisibility? apiWebAppResourceVisibility = null, string etag = null); + Task WebAppCreateResourceAsync(string webAppName, string resourceName, string media_type, string last_modified, ApiWebAppResourceVisibility? apiWebAppResourceVisibility = null, string etag = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.Delete Request /// /// webApp.Name of the webapp to delete /// true to indicate success - Task WebAppDeleteAsync(ApiWebAppData webApp); + Task WebAppDeleteAsync(ApiWebAppData webApp, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.Delete Request /// /// Name of the webapp to delete /// true to indicate success - Task WebAppDeleteAsync(string webAppName); + Task WebAppDeleteAsync(string webAppName, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.DeleteRespource Request /// /// webApp.Name of the webapp that contains the resource /// resource.Name of the resource to delete /// true to indicate success - Task WebAppDeleteResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource); + Task WebAppDeleteResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.DeleteRespource Request /// /// Name of the webapp that contains the resource /// resource.Name of the resource to delete /// true to indicate success - Task WebAppDeleteResourceAsync(string webAppName, ApiWebAppResource resource); + Task WebAppDeleteResourceAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.DeleteRespource Request /// /// webapp.Name of the webapp that contains the resource /// Name of the resource to delete /// true to indicate success - Task WebAppDeleteResourceAsync(ApiWebAppData webApp, string resourceName); + Task WebAppDeleteResourceAsync(ApiWebAppData webApp, string resourceName, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.DeleteRespource Request /// /// Name of the webapp that contains the resource /// Name of the resource to delete /// true to indicate success - Task WebAppDeleteResourceAsync(string webAppName, string resourceName); + Task WebAppDeleteResourceAsync(string webAppName, string resourceName, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.DownloadResource Request /// /// webApp.Name of the webapp that contains the resource /// resource.Name of the resource to download /// Ticket id for Ticketing Endpoint to trigger the download on - Task WebAppDownloadResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource); + Task WebAppDownloadResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.DownloadResource Request /// /// Name of the webapp that contains the resource /// resource.Name of the resource to download /// Ticket id for Ticketing Endpoint to trigger the download on - Task WebAppDownloadResourceAsync(string webAppName, ApiWebAppResource resource); + Task WebAppDownloadResourceAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.DownloadResource Request /// /// webApp.Name of the webapp that contains the resource /// Name of the resource to download /// Ticket id for Ticketing Endpoint to trigger the download on - Task WebAppDownloadResourceAsync(ApiWebAppData webApp, string resourceName); + Task WebAppDownloadResourceAsync(ApiWebAppData webApp, string resourceName, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.DownloadResource Request /// /// Name of the webapp that contains the resource /// Name of the resource to download /// Ticket id for Ticketing Endpoint to trigger the download on - Task WebAppDownloadResourceAsync(string webAppName, string resourceName); + Task WebAppDownloadResourceAsync(string webAppName, string resourceName, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.Rename Request /// @@ -464,7 +511,7 @@ public interface IApiRequestHandler /// New name for the WebApp /// This function will return the TrueOnSuccessResponse and a copy of the given WebApp that has the change: /// name which equals the newname - Task WebAppRenameAsync(ApiWebAppData webApp, string newWebAppName); + Task WebAppRenameAsync(ApiWebAppData webApp, string newWebAppName, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.Rename Request /// @@ -472,7 +519,7 @@ public interface IApiRequestHandler /// New name for the WebApp /// This function will return the TrueOnSuccessResponse and a WebApp that only has the information: /// name which equals the newname - Task WebAppRenameAsync(string webAppName, string newWebAppName); + Task WebAppRenameAsync(string webAppName, string newWebAppName, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.RenameResource Request /// @@ -481,7 +528,7 @@ public interface IApiRequestHandler /// New name for the resource /// This function will return the TrueOnSuccessResponse and a copy of the Resource given that has the following change: /// name which equals the newname - Task WebAppRenameResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, string newResourceName); + Task WebAppRenameResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, string newResourceName, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.RenameResource Request /// @@ -490,7 +537,7 @@ public interface IApiRequestHandler /// New name for the resource /// This function will return the TrueOnSuccessResponse and a copy of the Resource given that has the following change: /// name which equals the newname - Task WebAppRenameResourceAsync(string webAppName, ApiWebAppResource resource, string newResourceName); + Task WebAppRenameResourceAsync(string webAppName, ApiWebAppResource resource, string newResourceName, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.RenameResource Request /// @@ -499,7 +546,7 @@ public interface IApiRequestHandler /// New name for the resource /// This function will return the TrueOnSuccessResponse and a Resource that only has the information: /// name which equals the newname - Task WebAppRenameResourceAsync(ApiWebAppData webApp, string resourceName, string newResourceName); + Task WebAppRenameResourceAsync(ApiWebAppData webApp, string resourceName, string newResourceName, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.RenameResource Request /// @@ -508,7 +555,7 @@ public interface IApiRequestHandler /// New name for the resource /// This function will return the TrueOnSuccessResponse and a Resource that only has the information: /// name which equals the newname - Task WebAppRenameResourceAsync(string webAppName, string resourceName, string newResourceName); + Task WebAppRenameResourceAsync(string webAppName, string resourceName, string newResourceName, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetDefaultPage Request /// @@ -517,7 +564,7 @@ public interface IApiRequestHandler /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// Default_Page: which equals the resource.Name /// - Task WebAppSetDefaultPageAsync(ApiWebAppData webApp, ApiWebAppResource resource); + Task WebAppSetDefaultPageAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetDefaultPage Request /// @@ -527,7 +574,7 @@ public interface IApiRequestHandler /// Name: which equals the webAppName /// Default_Page: which equals the resourceName /// - Task WebAppSetDefaultPageAsync(string webAppName, ApiWebAppResource resource); + Task WebAppSetDefaultPageAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetDefaultPage Request /// @@ -536,7 +583,7 @@ public interface IApiRequestHandler /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// Default_Page: which equals the resourceName /// - Task WebAppSetDefaultPageAsync(ApiWebAppData webApp, string resourceName); + Task WebAppSetDefaultPageAsync(ApiWebAppData webApp, string resourceName, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetDefaultPage Request /// @@ -546,7 +593,7 @@ public interface IApiRequestHandler /// Name: which equals the webAppName /// Default_Page: which equals the resourceName /// - Task WebAppSetDefaultPageAsync(string webAppName, string resourceName); + Task WebAppSetDefaultPageAsync(string webAppName, string resourceName, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetNotAuthorizedPage Request /// @@ -555,7 +602,7 @@ public interface IApiRequestHandler /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// Not_authorized_page: which equals the resourceName /// - Task WebAppSetNotAuthorizedPageAsync(ApiWebAppData webApp, ApiWebAppResource resource); + Task WebAppSetNotAuthorizedPageAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetNotAuthorizedPage Request /// @@ -565,7 +612,7 @@ public interface IApiRequestHandler /// Name: which equals webAppName /// Not_authorized_page: which equals the resource.Name /// - Task WebAppSetNotAuthorizedPageAsync(string webAppName, ApiWebAppResource resource); + Task WebAppSetNotAuthorizedPageAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetNotAuthorizedPage Request /// @@ -574,7 +621,7 @@ public interface IApiRequestHandler /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// Not_authorized_page: which equals the resourceName /// - Task WebAppSetNotAuthorizedPageAsync(ApiWebAppData webApp, string resourceName); + Task WebAppSetNotAuthorizedPageAsync(ApiWebAppData webApp, string resourceName, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetNotAuthorizedPage Request /// @@ -584,7 +631,7 @@ public interface IApiRequestHandler /// Name: which equals webAppName /// Not_authorized_page: which equals the resourceName /// - Task WebAppSetNotAuthorizedPageAsync(string webAppName, string resourceName); + Task WebAppSetNotAuthorizedPageAsync(string webAppName, string resourceName, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetNotFoundPage Request /// @@ -593,7 +640,7 @@ public interface IApiRequestHandler /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// Not_found_page: which equals the resource.Name /// - Task WebAppSetNotFoundPageAsync(ApiWebAppData webApp, ApiWebAppResource resource); + Task WebAppSetNotFoundPageAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetNotFoundPage Request /// @@ -603,7 +650,7 @@ public interface IApiRequestHandler /// Name: which equals the webAppName /// Not_found_page: which equals the resource.Name /// - Task WebAppSetNotFoundPageAsync(string webAppName, ApiWebAppResource resource); + Task WebAppSetNotFoundPageAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetNotFoundPage Request /// @@ -612,7 +659,7 @@ public interface IApiRequestHandler /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// Not_found_page: which equals the resourceName /// - Task WebAppSetNotFoundPageAsync(ApiWebAppData webApp, string resourceName); + Task WebAppSetNotFoundPageAsync(ApiWebAppData webApp, string resourceName, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetNotFoundPage Request /// @@ -622,7 +669,7 @@ public interface IApiRequestHandler /// Name: which equals the webAppName /// Not_found_page: which equals the resourceName /// - Task WebAppSetNotFoundPageAsync(string webAppName, string resourceName); + Task WebAppSetNotFoundPageAsync(string webAppName, string resourceName, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceETag Request /// @@ -633,7 +680,7 @@ public interface IApiRequestHandler /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Etag: which equals the newEtagValue /// - Task WebAppSetResourceETagAsync(ApiWebAppData webApp, ApiWebAppResource resource, string newETagValue); + Task WebAppSetResourceETagAsync(ApiWebAppData webApp, ApiWebAppResource resource, string newETagValue, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceETag Request /// @@ -644,7 +691,7 @@ public interface IApiRequestHandler /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Etag: which equals the newEtagValue /// - Task WebAppSetResourceETagAsync(string webAppName, ApiWebAppResource resource, string newETagValue); + Task WebAppSetResourceETagAsync(string webAppName, ApiWebAppResource resource, string newETagValue, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceETag Request /// @@ -656,7 +703,7 @@ public interface IApiRequestHandler /// Name: which equals the resourceName /// Etag: which equals the newEtagValue /// - Task WebAppSetResourceETagAsync(ApiWebAppData webApp, string resourceName, string newETagValue); + Task WebAppSetResourceETagAsync(ApiWebAppData webApp, string resourceName, string newETagValue, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceETag Request /// @@ -668,7 +715,7 @@ public interface IApiRequestHandler /// Name: which equals the resourceName /// Etag: which equals the newEtagValue /// - Task WebAppSetResourceETagAsync(string webAppName, string resourceName, string newETagValue); + Task WebAppSetResourceETagAsync(string webAppName, string resourceName, string newETagValue, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceMediaType Request /// @@ -678,7 +725,7 @@ public interface IApiRequestHandler /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// MediaType: which equals the newMediaType /// - Task WebAppSetResourceMediaTypeAsync(ApiWebAppData webApp, ApiWebAppResource resource, string newMediaType); + Task WebAppSetResourceMediaTypeAsync(ApiWebAppData webApp, ApiWebAppResource resource, string newMediaType, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceMediaType Request /// @@ -688,7 +735,7 @@ public interface IApiRequestHandler /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// MediaType: which equals the newMediaType /// - Task WebAppSetResourceMediaTypeAsync(string webAppName, ApiWebAppResource resource, string newMediaType); + Task WebAppSetResourceMediaTypeAsync(string webAppName, ApiWebAppResource resource, string newMediaType, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceMediaType Request /// @@ -699,7 +746,7 @@ public interface IApiRequestHandler /// Name: which equals the resourceName /// MediaType: which equals the newMediaType /// - Task WebAppSetResourceMediaTypeAsync(ApiWebAppData webApp, string resourceName, string newMediaType); + Task WebAppSetResourceMediaTypeAsync(ApiWebAppData webApp, string resourceName, string newMediaType, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceMediaType Request /// @@ -710,7 +757,7 @@ public interface IApiRequestHandler /// Name: which equals the resourceName /// MediaType: which equals the newMediaType /// - Task WebAppSetResourceMediaTypeAsync(string webAppName, string resourceName, string newMediaType); + Task WebAppSetResourceMediaTypeAsync(string webAppName, string resourceName, string newMediaType, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceModificationTime Request /// @@ -720,7 +767,7 @@ public interface IApiRequestHandler /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Last_Modified: which equals the newModificationTime /// - Task WebAppSetResourceModificationTimeAsync(ApiWebAppData webApp, ApiWebAppResource resource, string newModificationTime); + Task WebAppSetResourceModificationTimeAsync(ApiWebAppData webApp, ApiWebAppResource resource, string newModificationTime, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceModificationTime Request /// @@ -730,7 +777,7 @@ public interface IApiRequestHandler /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Last_Modified: which equals the newModificationTime /// - Task WebAppSetResourceModificationTimeAsync(string webAppName, ApiWebAppResource resource, string newModificationTime); + Task WebAppSetResourceModificationTimeAsync(string webAppName, ApiWebAppResource resource, string newModificationTime, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceModificationTime Request /// @@ -741,7 +788,7 @@ public interface IApiRequestHandler /// Name: which equals the resourceName /// Last_Modified: which equals the newModificationTime /// - Task WebAppSetResourceModificationTimeAsync(ApiWebAppData webApp, string resourceName, string newModificationTime); + Task WebAppSetResourceModificationTimeAsync(ApiWebAppData webApp, string resourceName, string newModificationTime, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceModificationTime Request /// @@ -752,7 +799,7 @@ public interface IApiRequestHandler /// Name: which equals the resourceName /// Last_Modified: which equals the newModificationTime /// - Task WebAppSetResourceModificationTimeAsync(string webAppName, string resourceName, string newModificationTime); + Task WebAppSetResourceModificationTimeAsync(string webAppName, string resourceName, string newModificationTime, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceModificationTime Request /// @@ -763,7 +810,7 @@ public interface IApiRequestHandler /// Name: which equals the resourceName /// Last_Modified: which equals the newModificationTime /// - Task WebAppSetResourceModificationTimeAsync(string webAppName, string resourceName, DateTime newModificationTime); + Task WebAppSetResourceModificationTimeAsync(string webAppName, string resourceName, DateTime newModificationTime, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceModificationTime Request /// @@ -773,7 +820,7 @@ public interface IApiRequestHandler /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Last_Modified: which equals the newModificationTime /// - Task WebAppSetResourceModificationTimeAsync(string webAppName, ApiWebAppResource resource, DateTime newModificationTime); + Task WebAppSetResourceModificationTimeAsync(string webAppName, ApiWebAppResource resource, DateTime newModificationTime, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceModificationTime Request /// @@ -784,7 +831,7 @@ public interface IApiRequestHandler /// Name: which equals the resourceName /// Last_Modified: which equals the newModificationTime /// - Task WebAppSetResourceModificationTimeAsync(ApiWebAppData webApp, string resourceName, DateTime newModificationTime); + Task WebAppSetResourceModificationTimeAsync(ApiWebAppData webApp, string resourceName, DateTime newModificationTime, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceModificationTime Request /// @@ -794,7 +841,7 @@ public interface IApiRequestHandler /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Last_Modified: which equals the newModificationTime /// - Task WebAppSetResourceModificationTimeAsync(ApiWebAppData webApp, ApiWebAppResource resource, DateTime newModificationTime); + Task WebAppSetResourceModificationTimeAsync(ApiWebAppData webApp, ApiWebAppResource resource, DateTime newModificationTime, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceVisibility Request /// @@ -804,7 +851,7 @@ public interface IApiRequestHandler /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Visibility: which equals the newResourceVisibility /// - Task WebAppSetResourceVisibilityAsync(ApiWebAppData webApp, ApiWebAppResource resource, ApiWebAppResourceVisibility newResourceVisibility); + Task WebAppSetResourceVisibilityAsync(ApiWebAppData webApp, ApiWebAppResource resource, ApiWebAppResourceVisibility newResourceVisibility, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceVisibility Request /// @@ -814,7 +861,7 @@ public interface IApiRequestHandler /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Visibility: which equals the newResourceVisibility /// - Task WebAppSetResourceVisibilityAsync(string webAppName, ApiWebAppResource resource, ApiWebAppResourceVisibility newResourceVisibility); + Task WebAppSetResourceVisibilityAsync(string webAppName, ApiWebAppResource resource, ApiWebAppResourceVisibility newResourceVisibility, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceVisibility Request /// @@ -825,7 +872,7 @@ public interface IApiRequestHandler /// Name: which equals the resourceName /// Visibility: which equals the newResourceVisibility /// - Task WebAppSetResourceVisibilityAsync(ApiWebAppData webApp, string resourceName, ApiWebAppResourceVisibility newResourceVisibility); + Task WebAppSetResourceVisibilityAsync(ApiWebAppData webApp, string resourceName, ApiWebAppResourceVisibility newResourceVisibility, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetResourceVisibility Request /// @@ -836,7 +883,7 @@ public interface IApiRequestHandler /// Name: which equals the resourceName /// Visibility: which equals the newVisibility /// - Task WebAppSetResourceVisibilityAsync(string webAppName, string resourceName, ApiWebAppResourceVisibility newResourceVisibility); + Task WebAppSetResourceVisibilityAsync(string webAppName, string resourceName, ApiWebAppResourceVisibility newResourceVisibility, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.SetState Request /// @@ -845,7 +892,8 @@ public interface IApiRequestHandler /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// State: which equals the state /// - Task WebAppSetStateAsync(ApiWebAppData webApp, ApiWebAppState apiWebAppState); + Task WebAppSetStateAsync(ApiWebAppData webApp, ApiWebAppState apiWebAppState, CancellationToken cancellationToken = default(CancellationToken)); + /// /// Send a WebApp.SetState Request /// @@ -855,7 +903,33 @@ public interface IApiRequestHandler /// Name: which equals the webAppName /// State: which equals the state /// - Task WebAppSetStateAsync(string webAppName, ApiWebAppState apiWebAppState); + Task WebAppSetStateAsync(string webAppName, ApiWebAppState apiWebAppState, CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send a WebServer.ReadDefaultPage request + /// + /// Returns an ApiWebServerGetReadDefaultPageResponse object + ApiWebServerGetReadDefaultPageResponse WebServerGetReadDefaultPage(); + + /// + /// Send a WebServer.ReadDefaultPage request + /// + /// Returns an ApiWebServerGetReadDefaultPageResponse object + Task WebServerGetReadDefaultPageAsync(CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send a WebServer.SetDefaultPage request + /// + /// Name of the default page + /// Returns a TrueOnSuccessResponse + Task WebServerSetDefaultPageAsync(string defaultPage, CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send a WebServer.SetDefaultPage request + /// + /// Name of the default page + /// Returns a TrueOnSuccessResponse + ApiTrueOnSuccessResponse WebServerSetDefaultPage(string defaultPage); /// /// Send an ApiBulk Request @@ -868,7 +942,7 @@ public interface IApiRequestHandler /// /// An Array of ApiClass (and Id,Jsonrpc) ApiArrayOfApiClassResponse ApiBrowse(); - + /// /// Send an Api.CloseTicket Request /// @@ -921,6 +995,28 @@ public interface IApiRequestHandler /// Bytearray given from the PLC byte[] DownloadTicket(string ticketId); /// + /// Send a Project.ReadLanguages Request + /// + /// Languages Response containing a list of languages + Task ProjectReadLanguagesAsync(CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Send a Project.ReadLanguages Request + /// + /// Languages Response containing a list of languages + ApiReadLanguagesResponse ProjectReadLanguages(); + /// + /// Perform a service data download on the corresponding module with hwid + /// + /// The HWID of a node (module) for which a service data file can be downloaded + /// Ticket to use for downloading the service data + Task ModulesDownloadServiceDataAsync(ApiPlcHwId hwid, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Perform a service data download on the corresponding module with hwid + /// + /// The HWID of a node (module) for which a service data file can be downloaded + /// Ticket to use for downloading the service data + ApiTicketIdResponse ModulesDownloadServiceData(ApiPlcHwId hwid); + /// /// Send a PlcProgram.Browse Request /// /// @@ -956,6 +1052,33 @@ public interface IApiRequestHandler /// /// PlcProgramBrowseResponse: An Array of ApiPlcProgramData ApiPlcProgramBrowseResponse PlcProgramBrowse(ApiPlcProgramBrowseMode plcProgramBrowseMode, ApiPlcProgramData var); + + /// + /// Send a PlcProgram.Browse request for the code blocks. + /// + /// Cancellation token to cancel pending requests. + /// ApiPlcProgramBrowseCodeBlocksResponse: A collection of ApiPlcProgramBrowseCodeBlocksData objects. + Task PlcProgramBrowseCodeBlocksAsync(CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send a PlcProgram.Browse request for the code blocks. + /// + /// ApiPlcProgramBrowseCodeBlocksResponse: A collection of ApiPlcProgramBrowseCodeBlocksData objects. + ApiPlcProgramBrowseCodeBlocksResponse PlcProgramBrowseCodeBlocks(); + + /// + /// Send a PlcProgram.DownloadProfilingData request. + /// + /// Cancellation token to cancel pending requests. + /// ApiSingleStringResponse: Object containing the ticket ID for the data download. + Task PlcProgramDownloadProfilingDataAsync(CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send a PlcProgram.DownloadProfilingData request. + /// + /// ApiSingleStringResponse: Object containing the ticket ID for the data download. + ApiSingleStringResponse PlcProgramDownloadProfilingData(); + /// /// Send a PlcProgram.Read Request /// @@ -1024,6 +1147,18 @@ public interface IApiRequestHandler /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. ApiTrueOnSuccessResponse PlcRequestChangeOperatingMode(ApiPlcOperatingMode plcOperatingMode); /// + /// Send a Plc.ReadModeSelectorState request + /// + /// In an R/H system, a PLC with ID 1 (primary) or 2 (backup). For standard PLCs, enum value 0 (StandardPLC) is required. + /// Mode Selector state + Task PlcReadModeSelectorStateAsync(ApiPlcRedundancyId rhid, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Send a Plc.ReadModeSelectorState request + /// + /// In an R/H system, a PLC with ID 1 (primary) or 2 (backup). For standard PLCs, enum value 0 (StandardPLC) is required. + /// Mode Selector state + ApiPlcReadModeSelectorStateResponse PlcReadModeSelectorState(ApiPlcRedundancyId rhid); + /// /// Function to send the ByteArrayContent for a Ticket (e.g. CreateResource) /// MediaTypeHeaderValue: application/octet-stream /// @@ -1618,7 +1753,7 @@ public interface IApiRequestHandler /// Send a Plc.ReadSystemTime Request /// /// Current Plc Utc System Time - Task PlcReadSystemTimeAsync(); + Task PlcReadSystemTimeAsync(CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a Plc.ReadSystemTime Request @@ -1626,25 +1761,51 @@ public interface IApiRequestHandler /// Current Plc Utc System Time ApiPlcReadSystemTimeResponse PlcReadSystemTime(); + /// + /// Send an Plc.SetSystemTime Request + /// + /// The timestamp of the system time to be set + /// True if time was set successfully + Task PlcSetSystemTimeAsync(DateTime timestamp, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Send an Plc.SetSystemTime Request + /// + /// The timestamp of the system time to be set + /// True if time was set successfully + ApiTrueOnSuccessResponse PlcSetSystemTime(DateTime timestamp); + /// /// Send a Plc.ReadTimeSettings Request /// /// Current Plc Time Settings - Task PlcReadTimeSettingsAsync(); + Task PlcReadTimeSettingsAsync(CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a Plc.ReadTimeSettings Request /// /// Current Plc Time Settings ApiPlcReadTimeSettingsResponse PlcReadTimeSettings(); - + /// + /// Send a Plc.SetTimeSettings Request with parameters + /// + /// The time zone offset from the UTC time in hours + /// (Optional) Represents the settings for daylight-savings. If there is no daylight-savings rule configured, the utcOffset is applied to calculate the local time + /// True if the settings are applied successfully + Task PlcSetTimeSettingsAsync(TimeSpan utcOffset, DaylightSavingsRule daylightSavings = null, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Send a Plc.SetTimeSettings Request with parameters + /// + /// The time zone offset from the UTC time in hours + /// (Optional) Represents the settings for daylight-savings. If there is no daylight-savings rule configured, the utcOffset is applied to calculate the local time + /// True if the settings are applied successfully + ApiTrueOnSuccessResponse PlcSetTimeSettings(TimeSpan utcOffset, DaylightSavingsRule daylightSavings = null); /// /// Send a Files.Browse Request /// /// Path of the directory or file relative to the memory card root to fetch the entry list. /// The resource name must start with a "/". The parameter may be omitted.In that case, it will default to "/". /// Browsed resources (files/dir/...) - Task FilesBrowseAsync(string resource = null); + Task FilesBrowseAsync(string resource = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a Files.Browse Request @@ -1659,7 +1820,7 @@ public interface IApiRequestHandler /// /// resource to browse. /// Browsed resources (files/dir/...) - Task FilesBrowseAsync(ApiFileResource resource); + Task FilesBrowseAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a Files.Browse Request @@ -1673,7 +1834,7 @@ public interface IApiRequestHandler /// /// Path of the file relative to the memory card root. /// Ticket ID - Task FilesDownloadAsync(string resource ); + Task FilesDownloadAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -1688,7 +1849,7 @@ public interface IApiRequestHandler /// /// Path of the file relative to the memory card root. /// Ticket ID - Task FilesCreateAsync(string resource); + Task FilesCreateAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a Files.Create Request @@ -1703,7 +1864,7 @@ public interface IApiRequestHandler /// /// FileInfo for informations about the file to the memory card root. /// Ticket ID - Task FilesCreateAsync(FileInfo resource); + Task FilesCreateAsync(FileInfo resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a Files.Create Request @@ -1718,7 +1879,7 @@ public interface IApiRequestHandler /// Current path of file/folder /// New path of file/folder /// True if the file or folder is renamed successfully - Task FilesRenameAsync(string resource, string new_resource); + Task FilesRenameAsync(string resource, string new_resource, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -1734,7 +1895,7 @@ public interface IApiRequestHandler /// /// Path of the file relative to the memory card root. /// True if the file is deleted successfully - Task FilesDeleteAsync(string resource); + Task FilesDeleteAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a Files.Delete Request @@ -1748,7 +1909,7 @@ public interface IApiRequestHandler /// /// the resource that shall be deleted. /// True if the file is deleted successfully - Task FilesDeleteAsync(ApiFileResource resource); + Task FilesDeleteAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a Files.Delete Request @@ -1762,7 +1923,7 @@ public interface IApiRequestHandler /// /// Path of the file relative to the memory card root. /// True if the directory is created successfully - Task FilesCreateDirectoryAsync(string resource); + Task FilesCreateDirectoryAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -1778,7 +1939,7 @@ public interface IApiRequestHandler /// /// Path of the file relative to the memory card root. /// True if the directory is created successfully - Task FilesCreateDirectoryAsync(DirectoryInfo resource); + Task FilesCreateDirectoryAsync(DirectoryInfo resource, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -1793,7 +1954,7 @@ public interface IApiRequestHandler /// /// The resource to create /// True if the directory is created successfully - Task FilesCreateDirectoryAsync(ApiFileResource resource); + Task FilesCreateDirectoryAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -1808,7 +1969,7 @@ public interface IApiRequestHandler /// /// Path of the file relative to the memory card root. /// True if the directory is deleted successfully - Task FilesDeleteDirectoryAsync(string resource); + Task FilesDeleteDirectoryAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a Files.DeleteDirectory Request @@ -1822,7 +1983,7 @@ public interface IApiRequestHandler /// /// the directory to delete. /// True if the directory is deleted successfully - Task FilesDeleteDirectoryAsync(ApiFileResource resource); + Task FilesDeleteDirectoryAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a Files.DeleteDirectory Request @@ -1836,7 +1997,7 @@ public interface IApiRequestHandler /// /// Resource name of data log to retrieve, including the path. /// True if the resource is downloaded and deleted successfully - Task DatalogsDownloadAndClearAsync(string resource); + Task DatalogsDownloadAndClearAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -1850,7 +2011,7 @@ public interface IApiRequestHandler /// Send a Plc.CreateBackup request /// /// ticket id - Task PlcCreateBackupAsync(); + Task PlcCreateBackupAsync(CancellationToken cancellationToken = default(CancellationToken)); /// @@ -1863,7 +2024,7 @@ public interface IApiRequestHandler /// Send a Plc.RestoreBackup request /// /// ticket id - Task PlcRestoreBackupAsync(string password = ""); + Task PlcRestoreBackupAsync(string password = "", CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a Plc.RestoreBackup request @@ -1874,13 +2035,157 @@ public interface IApiRequestHandler /// /// Re-login to the plc, set the header again in the connected service (e.g.HttpClient)! /// - Task ReLoginAsync(string userName, string password, bool? includeWebApplicationCookie = null); + Task ReLoginAsync(string userName, string password, bool? includeWebApplicationCookie = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Re-login to the plc, set the header again in the connected service (e.g.HttpClient)! /// ApiLoginResponse ReLogin(string userName, string password, bool? includeWebApplicationCookie = null); + /// + /// Send a Failsafe.ReadParameters request + /// + /// The hardware identifier from which the parameters shall be read + /// Response with Failsafe parameters + Task FailsafeReadParametersAsync(uint hwid, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Send a Failsafe.ReadParameters request + /// + /// The hardware identifier from which the parameters shall be read + /// Response with Failsafe parameters + ApiFailsafeReadParametersResponse FailsafeReadParameters(uint hwid); + + /// + /// Send a Failsafe.ReadRuntimeGroups request + /// + /// Response with Runtime Groups + Task FailsafeReadRuntimeGroupsAsync(CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send a Failsafe.ReadRuntimeGroups request + /// + /// Response with Runtime Groups + ApiFailsafeReadRuntimeGroupsResponse FailsafeReadRuntimeGroups(); + /// + /// Send an Api.GetPasswordPolicy request + /// + /// ApiGetPasswordPolicy response + Task ApiGetPasswordPolicyAsync(CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send an Api.GetPasswordPolicy request + /// + /// ApiGetPasswordPolicy response + ApiGetPasswordPolicyResponse ApiGetPasswordPolicy(); + + /// + /// Send an Api.GetAuthenticationMode request + /// + /// A response containing the authentication modes + Task ApiGetAuthenticationModeAsync(CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send an Api.GetAuthenticationMode request + /// + /// A response containing the authentication modes + ApiGetAuthenticationModeResponse ApiGetAuthenticationMode(); + + /// + /// This API method allows the user to read content of the PLC-internal syslog ring buffer. + /// + /// (optional) The Redundancy ID parameter must be present when the request is executed on an R/H PLC.
+ /// In this case it must either have a value of 1 or 2, otherwise it is null. + /// (optional) The maximum number of syslog entries to be requested. Default value: 50
+ /// A count of 0 will omit any syslog entries from the response and only return the attributes last_modified, count_total and count_lost. + /// Optionally allows the user to provide the id of an entry as a starting point for the returned entries array.
+ /// This allows the user to traverse through the syslog buffer using multiple API calls. + /// ApiSyslogBrowseResponse + Task ApiSyslogBrowseAsync(ApiPlcRedundancyId? redundancy_id = null, uint? count = null, uint? first = null, CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// This API method allows the user to read content of the PLC-internal syslog ring buffer. + /// + /// (optional) The Redundancy ID parameter must be present when the request is executed on an R/H PLC.
+ /// In this case it must either have a value of 1 or 2, otherwise it is null. + /// (optional) The maximum number of syslog entries to be requested. Default value: 50
+ /// A count of 0 will omit any syslog entries from the response and only return the attributes last_modified, count_total and count_lost. + /// Optionally allows the user to provide the id of an entry as a starting point for the returned entries array.
+ /// This allows the user to traverse through the syslog buffer using multiple API calls. + /// ApiSyslogBrowseResponse + ApiSyslogBrowseResponse ApiSyslogBrowse(ApiPlcRedundancyId? redundancy_id = null, uint? count = null, uint? first = null); + + /// + /// This method allows the user to acknowledge a single alarm.
+ /// This method will always return true, even when nothing is acknowledged. + ///
+ /// The Acknowledgement ID of the alarm which shall be acknowledged.
+ /// The acknowledgement ID can be found in the alarm object that was returned by method Alarms.Browse. + /// ApiTrueOnSuccessResponse + Task AlarmsAcknowledgeAsync(string id, CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// This method allows the user to acknowledge a single alarm.
+ /// This method will always return true, even when nothing is acknowledged. + ///
+ /// The Acknowledgement ID of the alarm which shall be acknowledged.
+ /// The acknowledgement ID can be found in the alarm object that was returned by method Alarms.Browse. + /// ApiTrueOnSuccessResponse + ApiTrueOnSuccessResponse AlarmsAcknowledge(string id); + + /// + /// Send a Alarms.Browse request + /// + /// ApiAlarmsBrowseResponse + /// The language in which the texts should be returned. + /// If the language is valid, then the response must contain the texts in the requested language.
+ /// An empty string shall be treated the same as an invalid language string. + /// + /// (optional) The maximum number of alarm entries to be requested. Default value: 50
+ /// A count of 0 must omit any alarm entries from the response and must only return the attributes last_modified, count_max and count_current. + /// + /// (optional) The CPU alarm ID for which the user wants to return the data. If this is provided, no other parameters can be provided as filter. + /// (optional) Optional object that contains parameters to filter the response. + Task ApiAlarmsBrowseAsync(CultureInfo language, int? count = null, string alarm_id = null, ApiAlarms_RequestFilters filters = null, CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send a Alarms.Browse request + /// + /// ApiAlarmsBrowseResponse + /// The language in which the texts should be returned. + /// If the language is valid, then the response must contain the texts in the requested language.
+ /// An empty string shall be treated the same as an invalid language string. + /// + /// (optional) The maximum number of alarm entries to be requested. Default value: 50
+ /// A count of 0 must omit any alarm entries from the response and must only return the attributes last_modified, count_max and count_current. + /// + /// (optional) The CPU alarm ID for which the user wants to return the data. If this is provided, no other parameters can be provided as filter. + /// (optional) Optional object that contains parameters to filter the response. + ApiAlarmsBrowseResponse ApiAlarmsBrowse(CultureInfo language, int? count = null, string alarm_id = null, ApiAlarms_RequestFilters filters = null); + + /// + /// Send a DiagnosticBuffer.Browse request + /// + /// The language in which the texts should be returned. If the language is valid, then the response must contain the texts in the requested language.An empty string shall be treated the same as an invalid language string. + /// (optional) The maximum number of diagnostic buffer entries to be requested. Default value: 50. A count of 0 will omit any diagnostic buffer entries from the response + /// (optional) ApiDiagnosticBufferBrowse_RequestFilters representing various filtering possibilities. + /// ApiDiagnosticBufferBrowseResponse + Task ApiDiagnosticBufferBrowseAsync(CultureInfo language, + uint? count = null, + ApiDiagnosticBuffer_RequestFilters filters = null, + CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Send a DiagnosticBuffer.Browse request + /// + /// The language in which the texts should be returned. If the language is valid, then the response must contain the texts in the requested language.An empty string shall be treated the same as an invalid language string. + /// (optional) The maximum number of diagnostic buffer entries to be requested. Default value: 50. A count of 0 will omit any diagnostic buffer entries from the response + /// (optional) ApiDiagnosticBufferBrowse_RequestFilters representing various filtering possibilities. + /// ApiDiagnosticBufferBrowseResponse + ApiDiagnosticBufferBrowseResponse ApiDiagnosticBufferBrowse(CultureInfo language, uint? count = null, ApiDiagnosticBuffer_RequestFilters filters = null); + + /// + /// Cancel the outstanding Requests + /// + void CancelPendingRequests(); } } \ No newline at end of file diff --git a/src/Webserver.API/Services/RequestHandling/IApiRequestParameterChecker.cs b/src/Webserver.API/Services/RequestHandling/IApiRequestParameterChecker.cs index 41e438c..f8e76ab 100644 --- a/src/Webserver.API/Services/RequestHandling/IApiRequestParameterChecker.cs +++ b/src/Webserver.API/Services/RequestHandling/IApiRequestParameterChecker.cs @@ -2,6 +2,8 @@ // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; +using Siemens.Simatic.S7.Webserver.API.Models.TimeSettings; +using System; namespace Siemens.Simatic.S7.Webserver.API.Services.RequestHandling { @@ -82,5 +84,31 @@ public interface IApiRequestParameterChecker /// Name of the Web Application /// Bool to determine wether to really perform the check or not void CheckWebAppName(string webAppName, bool performCheck); + /// + /// Checks username for Api.ChangePassword (can't be the Anonymous user) + /// + /// Username to check + /// Bool to determine whether to really perform the check or not + void CheckUsername(string username, bool performCheck); + /// + /// Checks whether current and new password matches + /// + /// Current password of the user + /// New password for the user + /// Bool to determine whether to really perform the check or not + void CheckPasswords(string currentPassword, string newPassword, bool performCheck); + /// + /// DateTime is only supported from 1970-01-01 to 2554-07-21 23:34:33.709551615 + /// + /// Timestamp to check + /// Bool to determine wether to really perform the check or not + void CheckSystemTimeStamp(DateTime timestamp, bool performCheck); + /// + /// Checks whether the TimeSetting parameters are correct + /// + /// The time zone offset from the UTC time in hours + /// Represents the settings for daylight-savings. + /// Bool to determine wether to really perform the check or not + void CheckTimeSettings(TimeSpan utcOffset, DaylightSavingsRule daylightSavings, bool performCheck); } } \ No newline at end of file diff --git a/src/Webserver.API/Services/ServerCertificateCallback.cs b/src/Webserver.API/Services/ServerCertificateCallback.cs index 6eca456..859ff71 100644 --- a/src/Webserver.API/Services/ServerCertificateCallback.cs +++ b/src/Webserver.API/Services/ServerCertificateCallback.cs @@ -14,15 +14,17 @@ namespace Siemens.Simatic.S7.Webserver.API.Services /// Provides access to custom server certificate callback for handling SSL errors. ///
public class ServerCertificateCallback - { + { /// /// Gets or sets custom server certificate callback. /// - public static Func? CertificateCallback +#nullable enable + public static Func? CertificateCallback { get; set; - } + } +#nullable disable } } #endif \ No newline at end of file diff --git a/src/Webserver.API/Services/Ticketing/ApiTicketHandler.cs b/src/Webserver.API/Services/Ticketing/ApiTicketHandler.cs index de357d3..51f6214 100644 --- a/src/Webserver.API/Services/Ticketing/ApiTicketHandler.cs +++ b/src/Webserver.API/Services/Ticketing/ApiTicketHandler.cs @@ -8,9 +8,7 @@ using System; using System.IO; using System.Linq; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Runtime.InteropServices.ComTypes; +using System.Threading; using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Services.Ticketing @@ -43,11 +41,11 @@ public ApiTicketHandler(IApiRequestHandler apiRequestHandler) ApiRequestHandler = apiRequestHandler; } - private async Task CheckTicketAsync(string ticketId, bool performCheck) + private async Task CheckTicketAsync(string ticketId, bool performCheck, CancellationToken cancellationToken = default(CancellationToken)) { if (performCheck) { - var brTicketsResp = await ApiRequestHandler.ApiBrowseTicketsAsync(ticketId); + var brTicketsResp = await ApiRequestHandler.ApiBrowseTicketsAsync(ticketId, cancellationToken); var ticket = brTicketsResp.Result.Tickets.First(); if (ticket.State != Enums.ApiTicketState.Completed) { @@ -103,17 +101,18 @@ private async Task HandleWriteFileAndCheckAsync(string ticketId, byte /// ID of the ticket to perform the download for /// Path for the file to be downloaded /// wether or not to overwrite an existing file + /// Cancellation token to cancel pending requests. /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - public async Task HandleDownloadAsync(string ticketId, string filePath, bool overwriteExistingFile = false) + public async Task HandleDownloadAsync(string ticketId, string filePath, bool overwriteExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)) { var dirPath = filePath.Substring(0, filePath.LastIndexOf(@"\") + 1); if (!Directory.Exists(dirPath)) { throw new DirectoryNotFoundException($"the given directory at {Environment.NewLine}{dirPath}{Environment.NewLine} has not been found!"); } - var content = await ApiRequestHandler.DownloadTicketAsync(ticketId); + var content = await ApiRequestHandler.DownloadTicketAsync(ticketId, cancellationToken); return await HandleWriteFileAndCheckAsync(ticketId, content, filePath, overwriteExistingFile); } @@ -134,11 +133,12 @@ public ApiTicket HandleDownload(string ticketId, string filePath, bool overwrite ///
/// ID of the ticket to perform the download for /// Path to the download directory + /// Cancellation token to cancel pending requests. /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - public async Task HandleDownloadAsync(string ticketId, string pathToDownloadDirectory) - => await HandleDownloadAsync(ticketId, pathToDownloadDirectory, null, null, false); + public async Task HandleDownloadAsync(string ticketId, string pathToDownloadDirectory, CancellationToken cancellationToken = default(CancellationToken)) + => await HandleDownloadAsync(ticketId, pathToDownloadDirectory, null, null, false, cancellationToken); /// /// Handler method to get the fileinfo and download the content into a file. /// @@ -148,18 +148,19 @@ public async Task HandleDownloadAsync(string ticketId, string pathToD /// Given Download Directory does not exist /// File has no content public ApiTicket HandleDownload(string ticketId, string pathToDownloadDirectory) - => HandleDownloadAsync(ticketId, pathToDownloadDirectory).GetAwaiter().GetResult(); + => HandleDownloadAsync(ticketId, pathToDownloadDirectory, default(CancellationToken)).GetAwaiter().GetResult(); /// /// Handler method to get the fileinfo and download the content into a file. /// /// The ticket to perform the download for /// Path to the download directory + /// Cancellation token to cancel pending requests. /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - public async Task HandleDownloadAsync(ApiTicket ticket, string pathToDownloadDirectory) - => await HandleDownloadAsync(ticket.Id, pathToDownloadDirectory); + public async Task HandleDownloadAsync(ApiTicket ticket, string pathToDownloadDirectory, CancellationToken cancellationToken = default(CancellationToken)) + => await HandleDownloadAsync(ticket.Id, pathToDownloadDirectory, cancellationToken); /// /// Handler method to get the fileinfo and download the content into a file. /// @@ -169,17 +170,18 @@ public async Task HandleDownloadAsync(ApiTicket ticket, string pathTo /// Given Download Directory does not exist /// File has no content public ApiTicket HandleDownload(ApiTicket ticket, string pathToDownloadDirectory) - => HandleDownloadAsync(ticket, pathToDownloadDirectory).GetAwaiter().GetResult(); + => HandleDownloadAsync(ticket, pathToDownloadDirectory, default(CancellationToken)).GetAwaiter().GetResult(); /// /// Handler method to get the fileinfo and download the content into a file. /// /// ID of the ticket to perform the download for /// Path to the download directory + /// Cancellation token to cancel pending requests. /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - public async Task HandleDownloadAsync(string ticketId, DirectoryInfo pathToDownloadDirectory) - => await HandleDownloadAsync(ticketId, pathToDownloadDirectory.FullName); + public async Task HandleDownloadAsync(string ticketId, DirectoryInfo pathToDownloadDirectory, CancellationToken cancellationToken = default(CancellationToken)) + => await HandleDownloadAsync(ticketId, pathToDownloadDirectory.FullName, cancellationToken); /// /// Handler method to get the fileinfo and download the content into a file. /// @@ -189,18 +191,41 @@ public async Task HandleDownloadAsync(string ticketId, DirectoryInfo /// Given Download Directory does not exist /// File has no content public ApiTicket HandleDownload(string ticketId, DirectoryInfo pathToDownloadDirectory) - => HandleDownloadAsync(ticketId, pathToDownloadDirectory).GetAwaiter().GetResult(); - + + /* Unmerged change from project 'Webserver.API (netstandard2.0)' + Before: + => HandleDownloadAsync(ticketId, pathToDownloadDirectory).GetAwaiter().GetResult(); + + /// + After: + => HandleDownloadAsync(ticketId, pathToDownloadDirectory).GetAwaiter().GetResult(); + + /// + */ + + /* Unmerged change from project 'Webserver.API (net6.0)' + Before: + => HandleDownloadAsync(ticketId, pathToDownloadDirectory).GetAwaiter().GetResult(); + + /// + After: + => HandleDownloadAsync(ticketId, pathToDownloadDirectory).GetAwaiter().GetResult(); + + /// + */ + => HandleDownloadAsync(ticketId, pathToDownloadDirectory, default(CancellationToken)).GetAwaiter().GetResult(); + /// /// Handler method to get the fileinfo and download the content into a file. /// /// The ticket to perform the download for /// Path to the download directory + /// Cancellation token to cancel pending requests. /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - public async Task HandleDownloadAsync(ApiTicket ticket, DirectoryInfo pathToDownloadDirectory) - => await HandleDownloadAsync(ticket.Id, pathToDownloadDirectory); + public async Task HandleDownloadAsync(ApiTicket ticket, DirectoryInfo pathToDownloadDirectory, CancellationToken cancellationToken = default(CancellationToken)) + => await HandleDownloadAsync(ticket.Id, pathToDownloadDirectory, cancellationToken); /// /// Handler method to get the fileinfo and download the content into a file. /// @@ -210,7 +235,7 @@ public async Task HandleDownloadAsync(ApiTicket ticket, DirectoryInfo /// Given Download Directory does not exist /// File has no content public ApiTicket HandleDownload(ApiTicket ticket, DirectoryInfo pathToDownloadDirectory) - => HandleDownloadAsync(ticket, pathToDownloadDirectory).GetAwaiter().GetResult(); + => HandleDownloadAsync(ticket, pathToDownloadDirectory, default(CancellationToken)).GetAwaiter().GetResult(); /// /// Handler method to get the fileinfo and download the content into a file. @@ -218,11 +243,12 @@ public ApiTicket HandleDownload(ApiTicket ticket, DirectoryInfo pathToDownloadDi /// ID of the ticket to perform the download for /// Path for the file to be downloaded /// wether or not to overwrite an existing file + /// Cancellation token to cancel pending requests. /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - public async Task HandleDownloadAsync(string ticketId, FileInfo filePath, bool overwriteExistingFile) - => await HandleDownloadAsync(ticketId, filePath.FullName, overwriteExistingFile); + public async Task HandleDownloadAsync(string ticketId, FileInfo filePath, bool overwriteExistingFile, CancellationToken cancellationToken = default(CancellationToken)) + => await HandleDownloadAsync(ticketId, filePath.FullName, overwriteExistingFile, cancellationToken); /// /// Handler method to get the fileinfo and download the content into a file. @@ -242,11 +268,12 @@ public ApiTicket HandleDownload(string ticketId, FileInfo filePath, bool overwri /// Ticket to perform the download for /// Path for the file to be downloaded /// wether or not to overwrite an existing file + /// Cancellation token to cancel pending requests. /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - public async Task HandleDownloadAsync(ApiTicket ticket, string filePath, bool overwriteExistingFile) - => await HandleDownloadAsync(ticket.Id, filePath, overwriteExistingFile); + public async Task HandleDownloadAsync(ApiTicket ticket, string filePath, bool overwriteExistingFile, CancellationToken cancellationToken = default(CancellationToken)) + => await HandleDownloadAsync(ticket.Id, filePath, overwriteExistingFile, cancellationToken); /// /// Handler method to get the fileinfo and download the content into a file. @@ -266,11 +293,12 @@ public ApiTicket HandleDownload(ApiTicket ticket, string filePath, bool overwrit /// Ticket to perform the download for /// Path for the file to be downloaded /// wether or not to overwrite an existing file + /// Cancellation token to cancel pending requests. /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - public async Task HandleDownloadAsync(ApiTicket ticket, FileInfo filePath, bool overwriteExistingFile) - => await HandleDownloadAsync(ticket.Id, filePath, overwriteExistingFile); + public async Task HandleDownloadAsync(ApiTicket ticket, FileInfo filePath, bool overwriteExistingFile, CancellationToken cancellationToken = default(CancellationToken)) + => await HandleDownloadAsync(ticket.Id, filePath, overwriteExistingFile, cancellationToken); /// /// Handler method to get the fileinfo and download the content into a file. @@ -290,12 +318,13 @@ public ApiTicket HandleDownload(ApiTicket ticket, FileInfo filePath, bool overwr /// ID of the ticket to perform the download for /// Path to the download directory /// wether or not to overwrite an existing file + /// Cancellation token to cancel pending requests. /// file name for the file to be downloaded /// file extension for the file to be downloaded /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - public async Task HandleDownloadAsync(string ticketId, string pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, bool overwriteExistingFile = false) + public async Task HandleDownloadAsync(string ticketId, string pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, bool overwriteExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)) { var success = false; try @@ -310,7 +339,11 @@ public async Task HandleDownloadAsync(string ticketId, string pathToD var suggestedFileName = response.Content.Headers.ContentDisposition.FileName.Replace("\"", "").Replace("-", "_").Replace(":", "_").Replace(" ", "_"); string usedFilename = fileName ?? suggestedFileName; string usedFileExtension = fileExtension ?? (Path.HasExtension(usedFilename) ? "" : Path.GetExtension(suggestedFileName)); +#if NET6_0_OR_GREATER + var content = await response.Content.ReadAsByteArrayAsync(cancellationToken); +#else var content = await response.Content.ReadAsByteArrayAsync(); +#endif string path = Path.Combine(usedPathToDownloadDirectory, usedFilename + usedFileExtension); uint counter = 0; var firstPath = path; @@ -342,9 +375,9 @@ public async Task HandleDownloadAsync(string ticketId, string pathToD } finally { - if(!success) + if (!success) { - await ApiRequestHandler.ApiCloseTicketAsync(ticketId); + await ApiRequestHandler.ApiCloseTicketAsync(ticketId, cancellationToken); } } } @@ -369,13 +402,14 @@ public ApiTicket HandleDownload(string ticketId, string pathToDownloadDirectory /// Ticket to perform the download for /// Path to the download directory /// wether or not to overwrite an existing file + /// Cancellation token to cancel pending requests. /// file name for the file to be downloaded /// file extension for the file to be downloaded /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - public async Task HandleDownloadAsync(ApiTicket ticket, string pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, bool overwriteExistingFile = false) - => await HandleDownloadAsync(ticket.Id, pathToDownloadDirectory, fileName, fileExtension, overwriteExistingFile); + public async Task HandleDownloadAsync(ApiTicket ticket, string pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, bool overwriteExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)) + => await HandleDownloadAsync(ticket.Id, pathToDownloadDirectory, fileName, fileExtension, overwriteExistingFile, cancellationToken); /// /// Handler method to get the fileinfo and download the content into a file. @@ -397,13 +431,14 @@ public ApiTicket HandleDownload(ApiTicket ticket, string pathToDownloadDirectory /// ID of the ticket to perform the download for /// Path to the download directory /// wether or not to overwrite an existing file + /// Cancellation token to cancel pending requests. /// file name for the file to be downloaded /// file extension for the file to be downloaded /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - public async Task HandleDownloadAsync(string ticketId, DirectoryInfo pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, bool overwriteExistingFile = false) - => await HandleDownloadAsync(ticketId, pathToDownloadDirectory.FullName, fileName, fileExtension, overwriteExistingFile); + public async Task HandleDownloadAsync(string ticketId, DirectoryInfo pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, bool overwriteExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)) + => await HandleDownloadAsync(ticketId, pathToDownloadDirectory.FullName, fileName, fileExtension, overwriteExistingFile, cancellationToken); /// /// Handler method to get the fileinfo and download the content into a file. @@ -425,13 +460,14 @@ public ApiTicket HandleDownload(string ticketId, DirectoryInfo pathToDownloadDir /// Ticket to perform the download for /// Path to the download directory /// wether or not to overwrite an existing file + /// Cancellation token to cancel pending requests. /// file name for the file to be downloaded /// file extension for the file to be downloaded /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - public async Task HandleDownloadAsync(ApiTicket ticket, DirectoryInfo pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, bool overwriteExistingFile = false) - => await HandleDownloadAsync(ticket.Id, pathToDownloadDirectory.FullName, fileName, fileExtension, overwriteExistingFile); + public async Task HandleDownloadAsync(ApiTicket ticket, DirectoryInfo pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, bool overwriteExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)) + => await HandleDownloadAsync(ticket.Id, pathToDownloadDirectory.FullName, fileName, fileExtension, overwriteExistingFile, cancellationToken); /// /// Handler method to get the fileinfo and download the content into a file. @@ -452,13 +488,14 @@ public ApiTicket HandleDownload(ApiTicket ticket, DirectoryInfo pathToDownloadDi /// /// ID of the ticket to perform the upload for /// Path for the file to be uploaded + /// Cancellation token to cancel pending requests. /// The Ticket for that the Upload has been performed - public async Task HandleUploadAsync(string ticketId, string filePath) + public async Task HandleUploadAsync(string ticketId, string filePath, CancellationToken cancellationToken = default(CancellationToken)) { try { await ApiRequestHandler.UploadTicketAsync(ticketId, filePath); - return await CheckTicketAsync(ticketId, CheckAfterUpload); + return await CheckTicketAsync(ticketId, CheckAfterUpload, cancellationToken); } finally { @@ -480,9 +517,10 @@ public ApiTicket HandleUpload(string ticketId, string filePath) /// /// The ticket to perform the upload for /// Path for the file to be uploaded + /// Cancellation token to cancel pending requests. /// The Ticket for that the Upload has been performed - public async Task HandleUploadAsync(ApiTicket ticket, string filePath) - => await HandleUploadAsync(ticket.Id, filePath); + public async Task HandleUploadAsync(ApiTicket ticket, string filePath, CancellationToken cancellationToken = default(CancellationToken)) + => await HandleUploadAsync(ticket.Id, filePath, cancellationToken); /// /// Handle the Ticket Upload @@ -498,9 +536,10 @@ public ApiTicket HandleUpload(ApiTicket ticket, string filePath) /// /// ID of the ticket to perform the upload for /// Path for the file to be uploaded + /// Cancellation token to cancel pending requests. /// The Ticket for that the Upload has been performed - public async Task HandleUploadAsync(string ticketId, FileInfo filePath) - => await HandleUploadAsync(ticketId, filePath.FullName); + public async Task HandleUploadAsync(string ticketId, FileInfo filePath, CancellationToken cancellationToken = default(CancellationToken)) + => await HandleUploadAsync(ticketId, filePath.FullName, cancellationToken); /// /// Handle the Ticket Upload @@ -516,9 +555,10 @@ public ApiTicket HandleUpload(string ticketId, FileInfo filePath) /// /// The ticket to perform the upload for /// Path for the file to be uploaded + /// Cancellation token to cancel pending requests. /// The Ticket for that the Upload has been performed - public async Task HandleUploadAsync(ApiTicket ticket, FileInfo filePath) - => await HandleUploadAsync(ticket.Id, filePath); + public async Task HandleUploadAsync(ApiTicket ticket, FileInfo filePath, CancellationToken cancellationToken = default(CancellationToken)) + => await HandleUploadAsync(ticket.Id, filePath, cancellationToken); /// /// Handle the Ticket Upload @@ -529,6 +569,6 @@ public async Task HandleUploadAsync(ApiTicket ticket, FileInfo filePa public ApiTicket HandleUpload(ApiTicket ticket, FileInfo filePath) => HandleUploadAsync(ticket, filePath).GetAwaiter().GetResult(); - + } } diff --git a/src/Webserver.API/Services/Ticketing/IApiTicketHandler.cs b/src/Webserver.API/Services/Ticketing/IApiTicketHandler.cs index 66218dc..19a4052 100644 --- a/src/Webserver.API/Services/Ticketing/IApiTicketHandler.cs +++ b/src/Webserver.API/Services/Ticketing/IApiTicketHandler.cs @@ -5,7 +5,7 @@ using Siemens.Simatic.S7.Webserver.API.Models; using System; using System.IO; -using System.Linq; +using System.Threading; using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Services.Ticketing @@ -32,40 +32,44 @@ public interface IApiTicketHandler /// /// ID of the ticket to perform the download for /// Path to the download directory + /// Cancellation token to cancel pending requests. /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - Task HandleDownloadAsync(string ticketId, string pathToDownloadDirectory); + Task HandleDownloadAsync(string ticketId, string pathToDownloadDirectory, CancellationToken cancellationToken = default(CancellationToken)); /// /// Handler method to get the fileinfo and download the content into a file. /// /// The ticket to perform the download for /// Path to the download directory + /// Cancellation token to cancel pending requests. /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - Task HandleDownloadAsync(ApiTicket ticket, string pathToDownloadDirectory); + Task HandleDownloadAsync(ApiTicket ticket, string pathToDownloadDirectory, CancellationToken cancellationToken = default(CancellationToken)); /// /// Handler method to get the fileinfo and download the content into a file. /// /// ID of the ticket to perform the download for /// Path to the download directory + /// Cancellation token to cancel pending requests. /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - Task HandleDownloadAsync(string ticketId, DirectoryInfo pathToDownloadDirectory); + Task HandleDownloadAsync(string ticketId, DirectoryInfo pathToDownloadDirectory, CancellationToken cancellationToken = default(CancellationToken)); /// /// Handler method to get the fileinfo and download the content into a file. /// /// The ticket to perform the download for /// Path to the download directory + /// Cancellation token to cancel pending requests. /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - Task HandleDownloadAsync(ApiTicket ticket, DirectoryInfo pathToDownloadDirectory); + Task HandleDownloadAsync(ApiTicket ticket, DirectoryInfo pathToDownloadDirectory, CancellationToken cancellationToken = default(CancellationToken)); /// /// Handler method to get the fileinfo and download the content into a file. @@ -73,10 +77,11 @@ public interface IApiTicketHandler /// ID of the ticket to perform the download for /// Path for the file to be downloaded /// wether or not to overwrite an existing file + /// Cancellation token to cancel pending requests. /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - Task HandleDownloadAsync(string ticketId, string filePath, bool overwriteExistingFile); + Task HandleDownloadAsync(string ticketId, string filePath, bool overwriteExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)); /// /// Handler method to get the fileinfo and download the content into a file. @@ -95,10 +100,11 @@ public interface IApiTicketHandler /// ID of the ticket to perform the download for /// Path for the file to be downloaded /// wether or not to overwrite an existing file + /// Cancellation token to cancel pending requests. /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - Task HandleDownloadAsync(string ticketId, FileInfo filePath, bool overwriteExistingFile); + Task HandleDownloadAsync(string ticketId, FileInfo filePath, bool overwriteExistingFile, CancellationToken cancellationToken = default(CancellationToken)); /// /// Handler method to get the fileinfo and download the content into a file. @@ -117,10 +123,11 @@ public interface IApiTicketHandler /// Ticket to perform the download for /// Path for the file to be downloaded /// wether or not to overwrite an existing file + /// Cancellation token to cancel pending requests. /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - Task HandleDownloadAsync(ApiTicket ticket, string filePath, bool overwriteExistingFile); + Task HandleDownloadAsync(ApiTicket ticket, string filePath, bool overwriteExistingFile, CancellationToken cancellationToken = default(CancellationToken)); /// /// Handler method to get the fileinfo and download the content into a file. @@ -139,10 +146,11 @@ public interface IApiTicketHandler /// Ticket to perform the download for /// Path for the file to be downloaded /// wether or not to overwrite an existing file + /// Cancellation token to cancel pending requests. /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - Task HandleDownloadAsync(ApiTicket ticket, FileInfo filePath, bool overwriteExistingFile); + Task HandleDownloadAsync(ApiTicket ticket, FileInfo filePath, bool overwriteExistingFile, CancellationToken cancellationToken = default(CancellationToken)); /// /// Handler method to get the fileinfo and download the content into a file. @@ -161,14 +169,15 @@ public interface IApiTicketHandler /// ID of the ticket to perform the download for /// Path to the download directory /// wether or not to overwrite an existing file + /// Cancellation token to cancel pending requests. /// file name for the file to be downloaded /// file extension for the file to be downloaded /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - Task HandleDownloadAsync(string ticketId, string pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, bool overwriteExistingFile = false); + Task HandleDownloadAsync(string ticketId, string pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, bool overwriteExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)); - /// + /// /// Handler method to get the fileinfo and download the content into a file. /// /// ID of the ticket to perform the download for @@ -228,12 +237,13 @@ public interface IApiTicketHandler /// Ticket to perform the download for /// Path to the download directory /// wether or not to overwrite an existing file + /// Cancellation token to cancel pending requests. /// file name for the file to be downloaded /// file extension for the file to be downloaded /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - Task HandleDownloadAsync(ApiTicket ticket, string pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, bool overwriteExistingFile = false); + Task HandleDownloadAsync(ApiTicket ticket, string pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, bool overwriteExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)); /// /// Handler method to get the fileinfo and download the content into a file. @@ -254,12 +264,13 @@ public interface IApiTicketHandler /// ID of the ticket to perform the download for /// Path to the download directory /// wether or not to overwrite an existing file + /// Cancellation token to cancel pending requests. /// file name for the file to be downloaded /// file extension for the file to be downloaded /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - Task HandleDownloadAsync(string ticketId, DirectoryInfo pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, bool overwriteExistingFile = false); + Task HandleDownloadAsync(string ticketId, DirectoryInfo pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, bool overwriteExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)); /// /// Handler method to get the fileinfo and download the content into a file. @@ -280,12 +291,13 @@ public interface IApiTicketHandler /// Ticket to perform the download for /// Path to the download directory /// wether or not to overwrite an existing file + /// Cancellation token to cancel pending requests. /// file name for the file to be downloaded /// file extension for the file to be downloaded /// The Ticket for that the Download has been performed /// Given Download Directory does not exist /// File has no content - Task HandleDownloadAsync(ApiTicket ticket, DirectoryInfo pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, bool overwriteExistingFile = false); + Task HandleDownloadAsync(ApiTicket ticket, DirectoryInfo pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, bool overwriteExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)); /// /// Handler method to get the fileinfo and download the content into a file. @@ -305,8 +317,9 @@ public interface IApiTicketHandler /// /// ID of the ticket to perform the upload for /// Path for the file to be uploaded + /// Cancellation token to cancel pending requests. /// The Ticket for that the Upload has been performed - Task HandleUploadAsync(string ticketId, string filePath); + Task HandleUploadAsync(string ticketId, string filePath, CancellationToken cancellationToken = default(CancellationToken)); /// /// Handle the Ticket Upload @@ -321,8 +334,9 @@ public interface IApiTicketHandler /// /// The ticket to perform the upload for /// Path for the file to be uploaded + /// Cancellation token to cancel pending requests. /// The Ticket for that the Upload has been performed - Task HandleUploadAsync(ApiTicket ticket, string filePath); + Task HandleUploadAsync(ApiTicket ticket, string filePath, CancellationToken cancellationToken = default(CancellationToken)); /// /// Handle the Ticket Upload @@ -337,8 +351,9 @@ public interface IApiTicketHandler /// /// ID of the ticket to perform the upload for /// Path for the file to be uploaded + /// Cancellation token to cancel pending requests. /// The Ticket for that the Upload has been performed - Task HandleUploadAsync(string ticketId, FileInfo filePath); + Task HandleUploadAsync(string ticketId, FileInfo filePath, CancellationToken cancellationToken = default(CancellationToken)); /// /// Handle the Ticket Upload @@ -353,8 +368,9 @@ public interface IApiTicketHandler /// /// The ticket to perform the upload for /// Path for the file to be uploaded + /// Cancellation token to cancel pending requests. /// The Ticket for that the Upload has been performed - Task HandleUploadAsync(ApiTicket ticket, FileInfo filePath); + Task HandleUploadAsync(ApiTicket ticket, FileInfo filePath, CancellationToken cancellationToken = default(CancellationToken)); /// /// Handle the Ticket Upload diff --git a/src/Webserver.API/Services/WebApp/ApiResourceHandler.cs b/src/Webserver.API/Services/WebApp/ApiResourceHandler.cs index 98abdef..ba4660a 100644 --- a/src/Webserver.API/Services/WebApp/ApiResourceHandler.cs +++ b/src/Webserver.API/Services/WebApp/ApiResourceHandler.cs @@ -2,14 +2,13 @@ // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; -using Siemens.Simatic.S7.Webserver.API.Exceptions; using Siemens.Simatic.S7.Webserver.API.Models; using Siemens.Simatic.S7.Webserver.API.Services.RequestHandling; using Siemens.Simatic.S7.Webserver.API.Services.Ticketing; using Siemens.Simatic.S7.Webserver.API.StaticHelpers; using System; using System.IO; -using System.Linq; +using System.Threading; using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Services.WebApp @@ -48,14 +47,14 @@ public ApiResourceHandler(IApiRequestHandler apiRequestHandler, IApiWebAppResour /// optionally: /// , /// Task - public async Task DeployResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource) + public async Task DeployResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) { string path = webApp.PathToWebAppDirectory + @"\" + resource.Name.Replace("/", "\\"); if (!File.Exists(path)) throw new FileNotFoundException($"file at: {path} has not been found - did you set the webApp PathToWebAppDirectory correctly? given: {Environment.NewLine + webApp.PathToWebAppDirectory}"); - var ticketIdResponse = await ApiRequestHandler.WebAppCreateResourceAsync(webApp.Name, resource.Name, resource.Media_type, resource.Last_modified.ToString(DateTimeFormatting.ApiDateTimeFormat), resource.Visibility, resource.Etag); + var ticketIdResponse = await ApiRequestHandler.WebAppCreateResourceAsync(webApp.Name, resource.Name, resource.Media_type, resource.Last_modified.ToString(DateTimeFormatting.ApiDateTimeFormat), resource.Visibility, resource.Etag, cancellationToken); string ticketId = ticketIdResponse.Result; - await ApiTicketHandler.HandleUploadAsync(ticketId, path); + await ApiTicketHandler.HandleUploadAsync(ticketId, path, cancellationToken); } /// /// make sure to set the before calling this method! @@ -79,10 +78,10 @@ public void DeployResource(ApiWebAppData webApp, ApiWebAppResource resource) /// filepath to the resource that should be deployed! /// Visibility for the resource that shall be set! defaults to public /// - public async Task DeployResourceAsync(ApiWebAppData webApp, string pathToResource, ApiWebAppResourceVisibility visibility = ApiWebAppResourceVisibility.Public) + public async Task DeployResourceAsync(ApiWebAppData webApp, string pathToResource, ApiWebAppResourceVisibility visibility = ApiWebAppResourceVisibility.Public, CancellationToken cancellationToken = default(CancellationToken)) { var resource = ApiWebAppResourceBuilder.BuildResourceFromFile(pathToResource, webApp.PathToWebAppDirectory, visibility); - await DeployResourceAsync(webApp, resource); + await DeployResourceAsync(webApp, resource, cancellationToken); } /// /// make sure to set the before calling this method! @@ -105,11 +104,11 @@ public void DeployResource(ApiWebAppData webApp, string pathToResource, ApiWebAp /// in case you want to set a specific fileExtension (normally included in filename) /// choose wether you want to replace an existing file or add another file with that name to you download directory in case one already exists /// Task/void - public async Task DownloadResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, bool overrideExistingFile = false, string pathToDownloadDirectory = null, string fileName = null, string fileExtension = null) + public async Task DownloadResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, bool overrideExistingFile = false, string pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, CancellationToken cancellationToken = default(CancellationToken)) { - var ticketId = (await ApiRequestHandler.WebAppDownloadResourceAsync(webApp, resource)).Result; + var ticketId = (await ApiRequestHandler.WebAppDownloadResourceAsync(webApp, resource, cancellationToken)).Result; string fileNameToUse = fileName ?? resource.Name; - return (await ApiTicketHandler.HandleDownloadAsync(ticketId, pathToDownloadDirectory, fileNameToUse, fileExtension, overrideExistingFile)).File_Downloaded; + return (await ApiTicketHandler.HandleDownloadAsync(ticketId, pathToDownloadDirectory, fileNameToUse, fileExtension, overrideExistingFile, cancellationToken)).File_Downloaded; } /// /// Will send a Downloadresource, Downloadticket and Closeticket request to the API diff --git a/src/Webserver.API/Services/WebApp/ApiWebAppDataSaver.cs b/src/Webserver.API/Services/WebApp/ApiWebAppDataSaver.cs index 8a1eb2d..a103016 100644 --- a/src/Webserver.API/Services/WebApp/ApiWebAppDataSaver.cs +++ b/src/Webserver.API/Services/WebApp/ApiWebAppDataSaver.cs @@ -2,13 +2,10 @@ // // SPDX-License-Identifier: MIT using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; using Siemens.Simatic.S7.Webserver.API.Exceptions; using Siemens.Simatic.S7.Webserver.API.Models; using System; -using System.Collections.Generic; using System.IO; -using System.Text; namespace Siemens.Simatic.S7.Webserver.API.Services.WebApp { @@ -35,7 +32,7 @@ public ApiWebAppDataSaver(ApiWebAppDataSaveSetting apiWebAppSaveSetting) /// the ApiWebAppData that should be saved public void Save(IApiWebAppData apiWebApp) { - if(apiWebApp == null) + if (apiWebApp == null) { throw new ArgumentNullException(nameof(apiWebApp)); } @@ -50,7 +47,7 @@ public void Save(IApiWebAppData apiWebApp) } if (!Directory.Exists(dirToSaveTo)) { - if(!ApiWebAppSaveSetting.CreateDirectoryIfNotExists) + if (!ApiWebAppSaveSetting.CreateDirectoryIfNotExists) { throw new DirectoryNotFoundException($"the given directory at {Environment.NewLine}{dirToSaveTo}{Environment.NewLine} has not been found!"); } @@ -61,7 +58,7 @@ public void Save(IApiWebAppData apiWebApp) } var configString = JsonConvert.SerializeObject(apiWebApp, ApiWebAppSaveSetting.JsonSerializerSetting); - string fileNameToSave = ApiWebAppSaveSetting.ConfigurationName.EndsWith(".json") ? + string fileNameToSave = ApiWebAppSaveSetting.ConfigurationName.EndsWith(".json") ? ApiWebAppSaveSetting.ConfigurationName : ApiWebAppSaveSetting.ConfigurationName + ".json"; using (StreamWriter sw = File.CreateText(Path.Combine(dirToSaveTo, fileNameToSave))) { diff --git a/src/Webserver.API/Services/WebApp/ApiWebAppDeployer.cs b/src/Webserver.API/Services/WebApp/ApiWebAppDeployer.cs index b5a923b..b79e8bc 100644 --- a/src/Webserver.API/Services/WebApp/ApiWebAppDeployer.cs +++ b/src/Webserver.API/Services/WebApp/ApiWebAppDeployer.cs @@ -8,6 +8,7 @@ using Siemens.Simatic.S7.Webserver.API.Services.RequestHandling; using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Services.WebApp @@ -47,26 +48,24 @@ public ApiWebAppDeployer(IApiRequestHandler apiRequestHandler, IApiResourceHandl /// PathToWebAppDirectory /// /// - e.g. from parsed webappdirectory - public async Task DeployAsync(ApiWebAppData webApp) + public async Task DeployAsync(ApiWebAppData webApp, CancellationToken cancellationToken = default(CancellationToken)) { - var res = await ApiRequestHandler.WebAppCreateAsync(webApp.Name); + var res = await ApiRequestHandler.WebAppCreateAsync(webApp, cancellationToken); foreach (var r in webApp.ApplicationResources) { - await ApiResourceHandler.DeployResourceAsync(webApp, r); + await ApiResourceHandler.DeployResourceAsync(webApp, r, cancellationToken); } if (webApp.Not_authorized_page != null) { - await ApiRequestHandler.WebAppSetNotAuthorizedPageAsync(webApp.Name, webApp.Not_authorized_page); + await ApiRequestHandler.WebAppSetNotAuthorizedPageAsync(webApp.Name, webApp.Not_authorized_page, cancellationToken); } - if (webApp.Not_found_page != null) { - await ApiRequestHandler.WebAppSetNotFoundPageAsync(webApp.Name, webApp.Not_found_page); - + await ApiRequestHandler.WebAppSetNotFoundPageAsync(webApp.Name, webApp.Not_found_page, cancellationToken); } if (webApp.Default_page != null) { - await ApiRequestHandler.WebAppSetDefaultPageAsync(webApp.Name, webApp.Default_page); + await ApiRequestHandler.WebAppSetDefaultPageAsync(webApp.Name, webApp.Default_page, cancellationToken); } } @@ -102,9 +101,9 @@ public async Task DeployAsync(ApiWebAppData webApp) /// optional parameter: /// used to determine wether the deployer should retry a upload and compare of the resources found or give up right away (default) /// - public async Task DeployOrUpdateAsync(ApiWebAppData webApp, int amountOfTriesForResourceDeployment = 1) + public async Task DeployOrUpdateAsync(ApiWebAppData webApp, int amountOfTriesForResourceDeployment = 1, CancellationToken cancellationToken = default(CancellationToken)) { - var webApps = await ApiRequestHandler.WebAppBrowseAsync(); + var webApps = await ApiRequestHandler.WebAppBrowseAsync(cancellationToken: cancellationToken); if (!webApps.Result.Applications.Any(el => el.Name == webApp.Name)) { await DeployAsync(webApp); @@ -112,15 +111,15 @@ public async Task DeployOrUpdateAsync(ApiWebAppData webApp, int amountOfTriesFor else { // check for changes! - var browseResourcesResponse = await ApiRequestHandler.WebAppBrowseResourcesAsync(webApp.Name); + var browseResourcesResponse = await ApiRequestHandler.WebAppBrowseResourcesAsync(webApp, cancellationToken: cancellationToken); var browsedResources = browseResourcesResponse.Result.Resources; var appOrdered = webApp.ApplicationResources.OrderBy(el => el.Name).ToList(); var browsedOrdered = browsedResources.OrderBy(el => el.Name).ToList(); // set the IgnoreBOMDifference for all resources that have it set on the app and are found on the plc! var appOnBrowsed = browsedOrdered.Where(el => appOrdered.Any(el2 => el.Name == el2.Name)).ToList(); - foreach(var res in appOnBrowsed) + foreach (var res in appOnBrowsed) { - var res2 = appOrdered.FirstOrDefault(resource => resource.Name == res.Name) + var res2 = appOrdered.FirstOrDefault(resource => resource.Name == res.Name) ?? throw new NullReferenceException("resource is not on app but expected to be!!!"); res.IgnoreBOMDifference = res2.IgnoreBOMDifference; } @@ -135,7 +134,7 @@ public async Task DeployOrUpdateAsync(ApiWebAppData webApp, int amountOfTriesFor // elements that should further be deleted but are not found in the comparison before! var elemsToFurtherdelete = (browsedOrdered.Where(el => appExceptBrowsed .Any(el2 => el2.Name == el.Name && !(browsedExceptApp.Any(el3 => el3.Name == el2.Name))))).ToList(); - if(elemsToFurtherdelete.Count != 0) + if (elemsToFurtherdelete.Count != 0) { throw new Exception("Comparison insufficient!"); } @@ -154,7 +153,7 @@ public async Task DeployOrUpdateAsync(ApiWebAppData webApp, int amountOfTriesFor Console.WriteLine($"Upload for resource: {r.Name} failed for the {(tries + 1).ToString()}. time!"); } } - browseResourcesResponse = await ApiRequestHandler.WebAppBrowseResourcesAsync(webApp.Name); + browseResourcesResponse = await ApiRequestHandler.WebAppBrowseResourcesAsync(webApp, cancellationToken: cancellationToken); browsedResources = browseResourcesResponse.Result.Resources; browsedOrdered = browsedResources.OrderBy(el => el.Name).ToList(); browsedExceptApp = browsedOrdered.Except(appOrdered).ToList(); @@ -172,28 +171,28 @@ public async Task DeployOrUpdateAsync(ApiWebAppData webApp, int amountOfTriesFor throw new ApiResourceDeploymentFailedException($"Resources found that should were not expected to be on the app:{browsedThatShouldntBe}" + $"Resources that were expected to be on the app but aren't:{missing}"); } - var browsedWebAppResp = await ApiRequestHandler.WebAppBrowseAsync(webApp.Name); + var browsedWebAppResp = await ApiRequestHandler.WebAppBrowseAsync(webApp, cancellationToken); ApiWebAppData browsedWebApp = browsedWebAppResp.Result.Applications.First(); if (!browsedWebApp.Equals(webApp)) { // webapp data is not the same if (browsedWebApp.Not_authorized_page != webApp.Not_authorized_page) { - await ApiRequestHandler.WebAppSetNotAuthorizedPageAsync(webApp.Name, webApp.Not_authorized_page); + await ApiRequestHandler.WebAppSetNotAuthorizedPageAsync(webApp.Name, webApp.Not_authorized_page, cancellationToken); } if (browsedWebApp.Not_found_page != webApp.Not_found_page) { - await ApiRequestHandler.WebAppSetNotFoundPageAsync(webApp.Name, webApp.Not_found_page); + await ApiRequestHandler.WebAppSetNotFoundPageAsync(webApp.Name, webApp.Not_found_page, cancellationToken); } if (browsedWebApp.Default_page != webApp.Default_page) { - await ApiRequestHandler.WebAppSetDefaultPageAsync(webApp.Name, webApp.Default_page); + await ApiRequestHandler.WebAppSetDefaultPageAsync(webApp.Name, webApp.Default_page, cancellationToken); } if (browsedWebApp.State != webApp.State) { - await ApiRequestHandler.WebAppSetStateAsync(webApp.Name, webApp.State); + await ApiRequestHandler.WebAppSetStateAsync(webApp.Name, webApp.State, cancellationToken); } - browsedWebAppResp = await ApiRequestHandler.WebAppBrowseAsync(webApp.Name); + browsedWebAppResp = await ApiRequestHandler.WebAppBrowseAsync(webApp, cancellationToken); browsedWebApp = browsedWebAppResp.Result.Applications.First(); if (!browsedWebApp.Equals(webApp)) { diff --git a/src/Webserver.API/Services/WebApp/IApiResourceHandler.cs b/src/Webserver.API/Services/WebApp/IApiResourceHandler.cs index 99eee2f..d41d797 100644 --- a/src/Webserver.API/Services/WebApp/IApiResourceHandler.cs +++ b/src/Webserver.API/Services/WebApp/IApiResourceHandler.cs @@ -4,6 +4,7 @@ using Siemens.Simatic.S7.Webserver.API.Enums; using Siemens.Simatic.S7.Webserver.API.Models; using System.IO; +using System.Threading; using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Services.WebApp @@ -47,7 +48,7 @@ public interface IApiResourceHandler /// optionally: /// etag, visibility /// - Task DeployResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource); + Task DeployResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// make sure to set the webapp PathToWebAppDirectory before calling this method! /// Will send a Createresource, Uploadticket and Closeticket request to the API @@ -56,7 +57,7 @@ public interface IApiResourceHandler /// filepath to the resource that should be deployed! /// Visibility for the resource that shall be set! /// - Task DeployResourceAsync(ApiWebAppData webApp, string pathToResource, ApiWebAppResourceVisibility visibility = ApiWebAppResourceVisibility.Public); + Task DeployResourceAsync(ApiWebAppData webApp, string pathToResource, ApiWebAppResourceVisibility visibility = ApiWebAppResourceVisibility.Public, CancellationToken cancellationToken = default(CancellationToken)); /// /// Will send a Downloadresource, Downloadticket and Closeticket request to the API /// @@ -78,6 +79,6 @@ public interface IApiResourceHandler /// in case you want to set a specific fileExtension (normally included in filename) /// choose wether you want to replace an existing file or add another file with that name to you download directory in case one already exists /// task/void - Task DownloadResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, bool overrideExistingFile = false, string pathToDownloadDirectory = null, string fileName = null, string fileExtension = null); + Task DownloadResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, bool overrideExistingFile = false, string pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, CancellationToken cancellationToken = default(CancellationToken)); } } \ No newline at end of file diff --git a/src/Webserver.API/Services/WebApp/IApiWebAppDeployer.cs b/src/Webserver.API/Services/WebApp/IApiWebAppDeployer.cs index e3746db..75be4ad 100644 --- a/src/Webserver.API/Services/WebApp/IApiWebAppDeployer.cs +++ b/src/Webserver.API/Services/WebApp/IApiWebAppDeployer.cs @@ -2,6 +2,7 @@ // // SPDX-License-Identifier: MITusing System.Threading.Tasks; using Siemens.Simatic.S7.Webserver.API.Models; +using System.Threading; using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.Services.WebApp @@ -26,7 +27,7 @@ public interface IApiWebAppDeployer /// PathToWebAppDirectory /// /// - e.g. from parsed webappdirectory - Task DeployAsync(ApiWebAppData webApp); + Task DeployAsync(ApiWebAppData webApp, CancellationToken cancellationToken = default(CancellationToken)); /// /// make very sure the given webapp contains all the data: /// Name @@ -58,6 +59,6 @@ public interface IApiWebAppDeployer /// optional parameter: /// used to determine wether the deployer should retry a upload and compare of the resources found or give up right away /// - Task DeployOrUpdateAsync(ApiWebAppData webApp, int amountOfTriesForResourceDeployment = 1); + Task DeployOrUpdateAsync(ApiWebAppData webApp, int amountOfTriesForResourceDeployment = 1, CancellationToken cancellationToken = default(CancellationToken)); } } \ No newline at end of file diff --git a/src/Webserver.API/StaticHelpers/DateTimeFormat.cs b/src/Webserver.API/StaticHelpers/DateTimeFormat.cs index 2e55eaf..fadfeec 100644 --- a/src/Webserver.API/StaticHelpers/DateTimeFormat.cs +++ b/src/Webserver.API/StaticHelpers/DateTimeFormat.cs @@ -1,12 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using Newtonsoft.Json.Converters; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Siemens.Simatic.S7.Webserver.API.StaticHelpers { diff --git a/src/Webserver.API/Webserver.API.csproj b/src/Webserver.API/Webserver.API.csproj index f6206da..1494cd8 100644 --- a/src/Webserver.API/Webserver.API.csproj +++ b/src/Webserver.API/Webserver.API.csproj @@ -25,15 +25,15 @@ all runtime; build; native; contentfiles; analyzers - - + + - + \ No newline at end of file diff --git a/tests/Webserver.API.UnitTests/ApiBulkTests.cs b/tests/Webserver.API.UnitTests/ApiBulkTests.cs index bf7f724..6d59044 100644 --- a/tests/Webserver.API.UnitTests/ApiBulkTests.cs +++ b/tests/Webserver.API.UnitTests/ApiBulkTests.cs @@ -9,7 +9,6 @@ using System.Collections.Generic; using System.Linq; using System.Net.Http; -using System.Text; using System.Threading.Tasks; namespace Webserver.API.UnitTests @@ -29,12 +28,12 @@ public void ApiBulk_RequestsSameId_ThrowsArgumentException() TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); var requests = new List(); - for(int i = 0; i < 100; i++) + for (int i = 0; i < 100; i++) { requests.Add(new ApiRequest("", "2.0", i.ToString())); } requests.Add(new ApiRequest("Api.Ping", "2.0", "10")); - Assert.ThrowsAsync(async() => await TestHandler.ApiBulkAsync(requests)); + Assert.ThrowsAsync(async () => await TestHandler.ApiBulkAsync(requests)); } [Test] diff --git a/tests/Webserver.API.UnitTests/ApiDirectoryBuilderTests.cs b/tests/Webserver.API.UnitTests/ApiDirectoryBuilderTests.cs index 4fbf70d..66c0f7a 100644 --- a/tests/Webserver.API.UnitTests/ApiDirectoryBuilderTests.cs +++ b/tests/Webserver.API.UnitTests/ApiDirectoryBuilderTests.cs @@ -1,13 +1,11 @@ -using NUnit.Framework; +// Copyright (c) 2023, Siemens AG +// +// SPDX-License-Identifier: MIT +using NUnit.Framework; using Siemens.Simatic.S7.Webserver.API.Enums; using Siemens.Simatic.S7.Webserver.API.Services.FileHandling; -using System; -using System.CodeDom; -using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Webserver.API.UnitTests { @@ -164,7 +162,7 @@ public void T007_DirectoryWithDirAndFiles_Built() fs.Close(); } var fileInfo = new FileInfo(filePath); - + var dirPath2 = Path.Combine(localTmpDirectory, "temp"); var dirInfo2 = Directory.CreateDirectory(dirPath2); var fileName2 = "file2.txt"; diff --git a/tests/Webserver.API.UnitTests/ApiRequestTests.cs b/tests/Webserver.API.UnitTests/ApiRequestTests.cs index 68d649d..df5eb12 100644 --- a/tests/Webserver.API.UnitTests/ApiRequestTests.cs +++ b/tests/Webserver.API.UnitTests/ApiRequestTests.cs @@ -8,8 +8,11 @@ using Siemens.Simatic.S7.Webserver.API.Enums; using Siemens.Simatic.S7.Webserver.API.Exceptions; using Siemens.Simatic.S7.Webserver.API.Models; +using Siemens.Simatic.S7.Webserver.API.Models.ApiDiagnosticBuffer; +using Siemens.Simatic.S7.Webserver.API.Models.FailsafeParameters; using Siemens.Simatic.S7.Webserver.API.Models.Requests; using Siemens.Simatic.S7.Webserver.API.Models.Responses; +using Siemens.Simatic.S7.Webserver.API.Models.TimeSettings; using Siemens.Simatic.S7.Webserver.API.Services.PlcProgram; using Siemens.Simatic.S7.Webserver.API.Services.RequestHandling; using Siemens.Simatic.S7.Webserver.API.StaticHelpers; @@ -174,10 +177,31 @@ public async Task T004_01_ApiGetPermissions_Admin_AllPermissions() var client = new HttpClient(mockHttp); client.BaseAddress = new Uri($"https://{Ip.ToString()}"); TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); - List expRes = new List() { new ApiClass() { Name = "read_diagnostics" }, new ApiClass() { Name = "read_value" }, new ApiClass() { Name = "write_value" }, new ApiClass() { Name = "acknowledge_alarms" }, new ApiClass() { Name = "firmware_update" }, new ApiClass() { Name = "open_user_pages" }, new ApiClass() { Name = "read_file" }, new ApiClass() { Name = "write_file" }, new ApiClass() { Name = "change_operating_mode" }, new ApiClass() { Name = "flash_leds" }, new ApiClass() { Name = "backup_plc" }, new ApiClass() { Name = "restore_plc" }, new ApiClass() { Name = "manage_user_pages" } }; + List expRes = new List() { + new ApiClass() { Name = "read_diagnostics" }, + new ApiClass() { Name = "read_value" }, + new ApiClass() { Name = "write_value" }, + new ApiClass() { Name = "acknowledge_alarms" }, + new ApiClass() { Name = "open_user_pages" }, + new ApiClass() { Name = "read_file" }, + new ApiClass() { Name = "write_file" }, + new ApiClass() { Name = "change_operating_mode" }, + new ApiClass() { Name = "flash_leds" }, + new ApiClass() { Name = "backup_plc" }, + new ApiClass() { Name = "restore_plc" }, + new ApiClass() { Name = "failsafe_admin" }, //only when PLC is failsafe + new ApiClass() { Name = "manage_user_pages" }, + new ApiClass() { Name = "update_firmware" }, + new ApiClass() { Name = "change_time_settings" }, + new ApiClass() { Name = "download_service_data" }, + new ApiClass() { Name = "change_webserver_default_page" }, + new ApiClass() { Name = "read_watch_table_value" }, + new ApiClass() { Name = "write_watch_table_value" }, + new ApiClass() { Name = "read_syslog" } + }; + var resp = await TestHandler.ApiGetPermissionsAsync(); - if (resp.Result == expRes) - Assert.Fail("correct server response but not correctly given to user with true!"); + Assert.That(resp.Result.SequenceEqual(expRes), $"Permission don't match, missing: {string.Join(",", expRes.Except(resp.Result))}{string.Join(",", resp.Result.Except(expRes))}"); } /// @@ -197,8 +221,7 @@ public async Task T004_02_ApiGetPermissions_None_NoPermissions() TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); List expRes = new List(); var resp = await TestHandler.ApiGetPermissionsAsync(); - if (resp.Result == expRes) - Assert.Fail("correct server response but not correctly given to user with true!"); + Assert.That(resp.Result.SequenceEqual(expRes), $"Permission don't match, missing: {string.Join(",", expRes.Except(resp.Result))}{string.Join(",", resp.Result.Except(expRes))}"); } /// @@ -533,6 +556,36 @@ public async Task T007_05_ApiLogin_ValidToken_TokenReturnedAndCookie() Assert.Fail("token is empty or null altough server returned with!"); } + /// + /// Unit test for Api.Login that returns every possible value + /// + /// + [Test] + public async Task T007_06_ApiLogin_ValidToken_WithEverything() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.LoginWorkedWithPasswordExpirationInformation); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var req = ApiRequestFactory.GetApiLoginRequest("Anonymous", "", true); + var res = JsonConvert.DeserializeObject(await TestHandler.SendPostRequestAsync(req)); + if (string.IsNullOrEmpty(res.Result.Token)) + Assert.Fail("token is empty or null altough server returned with!"); + if (string.IsNullOrEmpty(res.Result.Web_application_cookie)) + Assert.Fail("token is empty or null altough server returned with!"); + Assert.That(res.Result.Runtime_timeout == TimeSpan.FromMinutes(30), + "Timeout should be 30 minutes for this response!"); + Assert.That(res.Result.Password_expiration != null, + "Password expiration should be present!"); + Assert.That(res.Result.Password_expiration.Timestamp == new DateTime(2023, 7, 7, 14, 28, 3), + "The timestamp of the expiration doesn't match!"); + Assert.That(!res.Result.Password_expiration.Warning); + } + /// /// /// @@ -1490,7 +1543,7 @@ public async Task T021_01_ApiWebAppCreateResource_valid_works() TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); var resp = await TestHandler.WebAppCreateResourceAsync("customerExampleManualAdjusted", "someresName", "text/html", "2020-08-24T07:08:06.000Z"); } - + /// @@ -2313,23 +2366,11 @@ public async Task T038_01_PlcReadTimeSettings_Rule_Works() TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); var timeSettings = await TestHandler.PlcReadTimeSettingsAsync(); var result = timeSettings.Result; - Assert.AreEqual(result.Current_offset, 0); - //Assert.AreEqual(result.Utc_offset, 0); - //var rule = result.Rule; - //var dst = rule.Dst; - //Assert.AreEqual(dst.Offset, 60); - //var dstStart = dst.Start; - //Assert.AreEqual(dstStart.Day_of_week, "sun"); - //Assert.AreEqual(dstStart.Hour, 1); - //Assert.AreEqual(dstStart.Minute, 0); - //Assert.AreEqual(dstStart.Month, 3); - //Assert.AreEqual(dstStart.Week, 5); - //var stdStart = rule.Std.Start; - //Assert.AreEqual(stdStart.Day_of_week, "sun"); - //Assert.AreEqual(stdStart.Hour, 2); - //Assert.AreEqual(stdStart.Minute, 0); - //Assert.AreEqual(stdStart.Month, 10); - //Assert.AreEqual(stdStart.Week, 5); + var dst = new DaylightSavingsTimeConfiguration(new PlcDate(3, 5, ApiDayOfWeek.Sun, 1, 0), new TimeSpan(0, 60, 0)); + var sdt = new StandardTimeConfiguration(new PlcDate(10, 5, ApiDayOfWeek.Sun, 2, 0)); + var expectedRule = new DaylightSavingsRule(sdt, dst); + Assert.AreEqual(TimeSpan.Zero, result.Current_offset, "Current offset is not equal to expected value!"); + Assert.AreEqual(expectedRule, result.Rule, "Time setting rule doesn't match!"); } /// @@ -2349,8 +2390,8 @@ public async Task T038_02_PlcReadTimeSettings_NoRule_Works() TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); var timeSettings = await TestHandler.PlcReadTimeSettingsAsync(); var result = timeSettings.Result; - Assert.AreEqual(result.Current_offset, 0); - Assert.AreEqual(result.Utc_offset, 0); + Assert.AreEqual(TimeSpan.Zero, result.Current_offset); + Assert.AreEqual(TimeSpan.Zero, result.Utc_offset); var rule = result.Rule; Assert.AreEqual(null, rule); } @@ -2636,5 +2677,479 @@ public async Task T051_01_ApiDataLogsDownloadAndClear_Works() Assert.AreEqual(expectedResult, result.Result, "The tickets are not identical."); } + /// + /// Testcase for ApiSyslog.Browse request + /// + /// + [Test] + public async Task T052_ApiSyslogBrowse_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.SyslogResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = (await TestHandler.ApiSyslogBrowseAsync()).Result; + Assert.Multiple(() => + { + Assert.AreEqual(5, result.Count_Total, "result Count_Total is not the expected value!"); + Assert.AreEqual(1, result.Count_Lost, "result Count_Lost is not the expected value!"); + Assert.AreEqual(2, result.Entries.Count, "result Entries.Count is not the expected value!"); + Assert.AreEqual("I am a syslog, no need to question it!", result.Entries[0].Raw, "result Entries[0].Raw is not the expected value!"); + Assert.AreEqual("I am a syslog, too. But the previous syslog is an impostor!", result.Entries[1].Raw, "result Entries[1].Raw is not the expected value!"); + }); + } + /// + /// TestCase for Failsafe.ReadParameters with CPU params + /// + /// + [Test] + public async Task T053_01_ApiFailsafeReadParameters_CPU_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.FailsafeReadParametersCPUResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = await TestHandler.FailsafeReadParametersAsync(50); + var fs = new FailsafeCPU(); + fs.Last_f_program_modification = new DateTime(2012, 4, 23, 18, 25, 43, 510); + fs.Collective_signature = "BC7C0410"; + fs.Remaining_time = new TimeSpan(2, 33, 0); + Assert.That(result.Result.Safety_mode); + Assert.AreEqual(ApiFailsafeHardwareType.F_cpu, result.Result.Type); + Assert.That(result.Result.Parameters is FailsafeCPU); + Assert.That(result.Result.Parameters.Equals(fs)); + } + + /// + /// TestCase for Failsafe.ReadParameters with Module params + /// + /// + [Test] + public async Task T053_02_ApiFailsafeReadParameters_Module_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.FailsafeReadParametersModuleResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = await TestHandler.FailsafeReadParametersAsync(50); + var fs = new FailsafeModule(); + fs.F_monitoring_time = TimeSpan.FromMilliseconds(542); + fs.F_destination_address = 123; + fs.F_source_address = 321; + fs.F_par_crc = "DBB32A1A"; + Assert.That(result.Result.Safety_mode); + Assert.AreEqual(ApiFailsafeHardwareType.F_module, result.Result.Type); + Assert.That(result.Result.Parameters is FailsafeModule); + Assert.That(result.Result.Parameters.Equals(fs)); + } + + /// + /// TestCase for Failsafe.ReadRuntimeGroups + /// + /// + [Test] + public async Task T054_ApiFailsafeReadRuntimeGroups_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.FailsafeReadRuntimeGroupsResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = await TestHandler.FailsafeReadRuntimeGroupsAsync(); + var noRemaining = new ApiFailsafeRuntimeGroup(); + noRemaining.Name = "F-runtime group 1"; + noRemaining.Signature = "E70AFF00"; + noRemaining.Cycle_time_current = TimeSpan.FromMilliseconds(550); + noRemaining.Cycle_time_Max = TimeSpan.FromMilliseconds(600); + noRemaining.Runtime_current = TimeSpan.FromMilliseconds(40); + noRemaining.Runtime_max = TimeSpan.FromMilliseconds(200); + var withRemaining = new ApiFailsafeRuntimeGroup(); + withRemaining.Name = "RTG_2"; + withRemaining.Signature = "CBA57022"; + withRemaining.Cycle_time_current = TimeSpan.FromMilliseconds(110); + withRemaining.Cycle_time_Max = TimeSpan.FromMilliseconds(200); + withRemaining.Runtime_current = TimeSpan.FromMilliseconds(50); + withRemaining.Runtime_max = TimeSpan.FromMilliseconds(80); + Assert.IsTrue(result.Result.Groups[0].Equals(noRemaining), "The groups don't match!"); + Assert.IsTrue(result.Result.Groups[1].Equals(withRemaining), "The groups don't match!"); + } + + /// + /// TestCase for Api.ChangePassword + /// + /// + [Test] + public async Task T055_ApiChangePassword_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.TrueOnSuccess); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = await TestHandler.ApiChangePasswordAsync("Admin", "adminpw", "newadminpw"); + Assert.IsTrue(result.Result, "Changing passwords not possible!"); + } + + /// + /// TestCase for Api.GetPasswordPolicy + /// + /// + [Test] + public async Task T056_ApiGetPasswordPolicy_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.ApiGetPasswordPolicy); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = await TestHandler.ApiGetPasswordPolicyAsync(); + var expectedResult = new ApiPasswordPolicy(); + expectedResult.Requires_lowercase_characters = true; + expectedResult.Requires_uppercase_characters = true; + expectedResult.Min_password_length = 8; + expectedResult.Max_password_length = 120; + expectedResult.Min_digits = 1; + expectedResult.Min_special_characters = 0; + Assert.AreEqual(expectedResult, result.Result.Password_policy, "Password policies dont match"); + } + + /// + /// TestCase for Api.GetAuthenticationMode with 3 modes + /// + /// + [Test] + public async Task T057_ApiGetAuthenticationMode_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.ApiGetAuthenticationModeMany); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = await TestHandler.ApiGetAuthenticationModeAsync(); + var expectedResult = new List(); + expectedResult.Add(ApiAuthenticationMode.Local); + expectedResult.Add(ApiAuthenticationMode.Static); + expectedResult.Add(ApiAuthenticationMode.Disabled); + Assert.AreEqual(expectedResult.Count, result.Result.Authentication_modes.Count, "Authentication modes count don't match!"); + Assert.That(expectedResult.SequenceEqual(result.Result.Authentication_modes), "Order of authetication modes is different!"); + } + + /// + /// TestCase for Project.ReadLanguages with 4 languages + /// + /// + [Test] + public async Task T058_ProjectReadLanguages_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.ProjectReadLanguagesMany); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = await TestHandler.ProjectReadLanguagesAsync(); + var expectedResult = new List(); + expectedResult.Add(new CultureInfo("en-US")); + expectedResult.Add(new CultureInfo("en-GB")); + expectedResult.Add(new CultureInfo("es-BR")); + expectedResult.Add(new CultureInfo("ne-IN")); + Assert.AreEqual(expectedResult.Count, result.Result.Languages.Select(x => x.Language).Count(), "Languages don't match"); + Assert.That(expectedResult.SequenceEqual(result.Result.Languages.Select(x => x.Language)), "The order of languages are different, or they don't contain the same languages."); + } + + /// + /// TestCase for Plc.ReadModeSelectorState with Standard PLC + /// + /// + [Test] + public async Task T059_01_ApiPlcReadModeSelectorState_Standard_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.PlcReadModeSelectorStateRun); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var res = await TestHandler.PlcReadModeSelectorStateAsync(ApiPlcRedundancyId.StandardPLC); + Assert.AreEqual(ApiPlcModeSelectorState.Run, res.Result.Mode_Selector, "Plc Mode Selector state is not in run mode!"); + } + + /// + /// TestCase for Plc.ReadModeSelectorState with RH PLC system + /// + /// + [Test] + public async Task T059_02_ApiPlcReadModeSelectorState_RH_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.PlcReadModeSelectorStateNoSwitch); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var res = await TestHandler.PlcReadModeSelectorStateAsync(ApiPlcRedundancyId.RedundancyId_1); + Assert.AreEqual(ApiPlcModeSelectorState.NoSwitch, res.Result.Mode_Selector, "Plc Mode Selector state is not in noswitch mode!"); + } + + /// + /// TestCase for Modules.DownloadServiceData + /// + /// + [Test] + public async Task T060_ApiModulesDownloadServiceData_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.TicketResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = await TestHandler.ModulesDownloadServiceDataAsync(ApiPlcHwId.StandardPLC); + var expectedResult = "dlBvEAfpgSVBfwlU7Py5TsVbmRTq"; + Assert.AreEqual(expectedResult, result.Result, "The tickets are not identical."); + } + + /// + /// TestCase for Alarms.Acknowledge + /// + /// + [Test] + public async Task T061_ApiAlarmsAcknowledge_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.AlarmsAcknowledge); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = await TestHandler.AlarmsAcknowledgeAsync("/"); + Assert.AreEqual(true, result.Result, "The response should always contain true, but it doesn't."); + } + /// + /// TestCase for Plc.SetSystemTime + /// + /// + [Test] + public async Task T062_PlcSetSystemTime_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.PlcSetSystemTime); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = await TestHandler.PlcSetSystemTimeAsync(new DateTime(2010, 10, 10)); + Assert.IsTrue(result.Result, "The time was not set successfully!"); + } + + /// + /// TestCase for Plc.SetTimeSettings, both offset and rule object + /// + /// + [Test] + public async Task T063_01_ApiPlcSetTimeSettings_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.PlcSetTimeSettingsAll); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + + var offset = new TimeSpan(8, 0, 0); + var dst = new DaylightSavingsTimeConfiguration(new PlcDate(12, 5, ApiDayOfWeek.Sun, 3, 0), new TimeSpan(0, 60, 0)); + var sdt = new StandardTimeConfiguration(new PlcDate(1, 1, ApiDayOfWeek.Mon, 23, 31)); + DaylightSavingsRule dsr = new DaylightSavingsRule(sdt, dst); + + var result = await TestHandler.PlcSetTimeSettingsAsync(offset, dsr); + Assert.IsTrue(result.Result, "Couldn't set time settings!"); + } + + /// + /// TestCase for Plc.SetTimeSettings + /// + /// + [Test] + public async Task T063_02_ApiPlcSetTimeSettingsNoRule_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.PlcSetTimeSettingsNoRule); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + + var offset = new TimeSpan(8, 0, 0); + + var result = await TestHandler.PlcSetTimeSettingsAsync(offset); + Assert.IsTrue(result.Result, "Couldn't set time settings!"); + } + + /// + /// TestCase for Api.GetQuantityStructures + /// + /// + [Test] + public async Task T064_ApiGetQuantityStructures() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.QuantityStructuresResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = await TestHandler.ApiGetQuantityStructuresAsync(); + var expectedResult = new ApiQuantityStructure(); + expectedResult.Webapi_Max_Http_Request_Body_Size = 131072; + expectedResult.Webapi_Max_Parallel_User_Sessions = 100; + expectedResult.Webapi_Max_Parallel_Requests = 4; + Assert.That(result.Result.Equals(expectedResult), "Quantity Structure is not as expected!"); + } + /// + /// TestCase for WebServer.SetDefaultPage + /// + /// + [Test] + public async Task T065_WebServerSetDefaultPage_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.TrueOnSuccess); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = await TestHandler.WebServerSetDefaultPageAsync("index.html"); + Assert.IsTrue(result.Result, "The result is not true."); + } + /// + /// TestCase for WebServer.ReadDefaultPage + /// + /// + [Test] + public async Task T066_WebServerReadDefaultPage_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.DefaultPageResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = await TestHandler.WebServerGetReadDefaultPageAsync(); + var expectedResult = "/~teszt2/index.html"; + Assert.AreEqual(expectedResult, result.Result.Default_page, "The result is not the expected."); + } + + /// + /// TestCase for ApiAlarmsBrowse + /// + /// + [Test] + public async Task T067_ApiAlarmsBrowse_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.ApiAlarmsBrowseResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = (await TestHandler.ApiAlarmsBrowseAsync(new CultureInfo("en-US"))).Result; + Assert.Multiple(() => + { + Assert.AreEqual(2, result.Entries.Count, "result.Entries.Count"); + Assert.AreEqual("9947888669857743000", result.Entries[0].Id, "result.Entries[0].Id"); + Assert.AreEqual(512, result.Entries[0].Alarm_Number, "result.Entries[0].Alarm_Number"); + Assert.AreEqual(ApiObjectDirectoryStatus.Incoming, result.Entries[0].Status, "result.Entries[0].Status"); + Assert.AreEqual(new DateTime(2012, 1, 1, 1, 1, 42, 47), result.Entries[0].Timestamp, "result.Entries[0].Timestamp"); + Assert.AreEqual(ApiAlarmAcknowledgementState.Not_Acknowledged, result.Entries[0].Acknowledgement.State, "result.Entries[0].Acknowledgement.State"); + Assert.AreEqual("#1, 1", result.Entries[0].Alarm_Text, "result.Entries[0].Alarm_Text"); + Assert.AreEqual("#1, 0", result.Entries[0].Info_Text, "result.Entries[0].Info_Text"); + Assert.AreEqual(false, result.Entries[0].Text_Inconsistent, "result.Entries[0].Text_Inconsistent"); + Assert.AreEqual(new DateTime(2012, 1, 1, 1, 1, 42, 99), result.Last_Modified, "result.Last_Modified"); + Assert.AreEqual(51, result.Count_Current, "result.Count_Current"); + Assert.AreEqual(500, result.Count_Max, "result.Count_Max"); + Assert.AreEqual("en-US", result.Language, "result.Language"); + }); + } + + /// + /// TestCase for DiagnosticBuffer.Browse method + /// + /// + [Test] + public async Task T068_ApiDiagnosticBufferBrowse_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.DiagnosticBufferBrowseResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = (await TestHandler.ApiDiagnosticBufferBrowseAsync(new CultureInfo("en-US"))).Result; + DateTime expected = new DateTime(2023, 06, 07, 18, 25, 43); //2023-06-07T18:25:43.514678531Z + expected = expected.AddTicks(5146785); + Assert.Multiple(() => + { + Assert.AreEqual(2, result.Entries.Count, "result.Entries.Count"); + Assert.AreEqual(ApiObjectDirectoryStatus.Outgoing, result.Entries[0].Status, "result.Entries[0].Status"); + Assert.AreEqual("Boot up - CPU changes from OFF to STOP (initialization) mode", result.Entries[0].Short_Text, "result.Entries[0].Short_Text"); + Assert.AreEqual("LONG TEXT", result.Entries[1].Long_Text, "result.Entries[1].Long_Text"); + Assert.AreEqual(3, result.Entries[1].Event.Textlist_Id, "result.Entries[1].Event.Textlist_Id"); + Assert.AreEqual(26315, result.Entries[1].Event.Text_Id, "result.Entries[1].Event.Text_Id"); + Assert.AreEqual(expected, result.Last_Modified, "result.Last_Modified"); + Assert.AreEqual(1234, result.Count_Current, "result.Count_Current"); + Assert.AreEqual(3200, result.Count_Max, "result.Count_Max"); + Assert.AreEqual("en-US", result.Language, "result.Language"); + }); + } } } diff --git a/tests/Webserver.API.UnitTests/ApiWebAppDataSaverTests.cs b/tests/Webserver.API.UnitTests/ApiWebAppDataSaverTests.cs index 579391c..fdf545d 100644 --- a/tests/Webserver.API.UnitTests/ApiWebAppDataSaverTests.cs +++ b/tests/Webserver.API.UnitTests/ApiWebAppDataSaverTests.cs @@ -8,12 +8,7 @@ using Siemens.Simatic.S7.Webserver.API.Exceptions; using Siemens.Simatic.S7.Webserver.API.Models; using Siemens.Simatic.S7.Webserver.API.Services.WebApp; -using System; -using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Webserver.API.UnitTests { diff --git a/tests/Webserver.API.UnitTests/EnumTests.cs b/tests/Webserver.API.UnitTests/EnumTests.cs index 27f20f0..3b102d1 100644 --- a/tests/Webserver.API.UnitTests/EnumTests.cs +++ b/tests/Webserver.API.UnitTests/EnumTests.cs @@ -7,8 +7,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Webserver.API.UnitTests { @@ -38,7 +36,7 @@ public void GetAccordingDataType_Valid_AsExpected() CheckRange_AccordingDataType(Enumerable.Range(0, 1), typeof(object)); // check db independent from none - I know this could be 0,2 and 1 line instead of two. CheckRange_AccordingDataType(Enumerable.Range(1, 1), typeof(object)); - CheckRange_AccordingDataType(Enumerable.Range(67, (81-67+1)), typeof(object)); + CheckRange_AccordingDataType(Enumerable.Range(67, (81 - 67 + 1)), typeof(object)); } [Test] @@ -46,7 +44,7 @@ public void GetBytesOfDataType_valid_AsExpected() { CheckRange_BytesOfDataType(Enumerable.Range(65, 1), 256); CheckRange_BytesOfDataType(Enumerable.Range(66, 1), 512); - CheckRange_BytesOfDataType(Enumerable.Range(2, 6-2+1), 1); + CheckRange_BytesOfDataType(Enumerable.Range(2, 6 - 2 + 1), 1); CheckRange_BytesOfDataType(Enumerable.Range(7, 45 - 7 + 1), 2); CheckRange_BytesOfDataType(Enumerable.Range(46, 57 - 46 + 1), 4); CheckRange_BytesOfDataType(Enumerable.Range(58, 64 - 58 + 1), 8); diff --git a/tests/Webserver.API.UnitTests/ExtensionTests.cs b/tests/Webserver.API.UnitTests/ExtensionTests.cs index b98f6dd..3dd8bbf 100644 --- a/tests/Webserver.API.UnitTests/ExtensionTests.cs +++ b/tests/Webserver.API.UnitTests/ExtensionTests.cs @@ -7,8 +7,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Webserver.API.UnitTests { @@ -19,7 +17,7 @@ public class ExtensionTests : Base public void MakeSureNoIdIsContainedTwice_EnoughTime_Works() { var requests = new List(); - for(int i = 0; i< 500;i++) + for (int i = 0; i < 500; i++) { requests.Add(new ApiRequest("", "", "1")); } @@ -28,7 +26,7 @@ public void MakeSureNoIdIsContainedTwice_EnoughTime_Works() var charSetGen = ReqIdGenerator as CharSetIdGenerator; Console.WriteLine($"Determined ThreadSleepTime:{charSetGen.ThreadSleepTime}"); } - if(ReqIdGenerator is GUIDGenerator) + if (ReqIdGenerator is GUIDGenerator) { var guidGen = ReqIdGenerator as GUIDGenerator; Console.WriteLine($"Determined DefaultLength:{guidGen.DefaultLength}"); diff --git a/tests/Webserver.API.UnitTests/FileParserTests.cs b/tests/Webserver.API.UnitTests/FileParserTests.cs index 1071513..9337a7f 100644 --- a/tests/Webserver.API.UnitTests/FileParserTests.cs +++ b/tests/Webserver.API.UnitTests/FileParserTests.cs @@ -6,16 +6,11 @@ using NUnit.Framework; using Siemens.Simatic.S7.Webserver.API.Enums; using Siemens.Simatic.S7.Webserver.API.Exceptions; -using Siemens.Simatic.S7.Webserver.API.Services.FileParser; using Siemens.Simatic.S7.Webserver.API.Models; +using Siemens.Simatic.S7.Webserver.API.Services.FileParser; using Siemens.Simatic.S7.Webserver.API.Services.WebApp; -using Siemens.Simatic.S7.Webserver.API.StaticHelpers; using System; -using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Webserver.API.UnitTests { @@ -68,7 +63,7 @@ public void InvalidApplicationsExceptionThrown() { Directory.Delete(dirPath, true); } - + } [Test] @@ -77,7 +72,7 @@ public void ValidApplicationAsExpected() string dirPath = Path.Combine(CurrentExeDir.FullName, "tmp"); try { - if(!Directory.Exists(dirPath)) + if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); } @@ -96,12 +91,12 @@ public void ValidApplicationAsExpected() sw.Write(serializedAppString); }; var app = parser.Parse(); - if(app.PathToWebAppDirectory != dirPath) + if (app.PathToWebAppDirectory != dirPath) { Assert.Fail($"Path to WebApp Directory not set as expected!:{Environment.NewLine}" + $"{app.PathToWebAppDirectory}"); } - if(app.DirectoriesToIgnoreForUpload == null || app.DirectoriesToIgnoreForUpload.Count != 0) + if (app.DirectoriesToIgnoreForUpload == null || app.DirectoriesToIgnoreForUpload.Count != 0) { Assert.Fail($"DirectroiesToIgnore dont default to empty List!:{Environment.NewLine}" + $"{app.DirectoriesToIgnoreForUpload}"); @@ -126,7 +121,7 @@ public void ValidApplicationAsExpected() Assert.Fail($"ApplicationResources dont default to empty List!:{Environment.NewLine}" + $"{app.ApplicationResources}"); } - if(app.Default_page != null) + if (app.Default_page != null) { Assert.Fail($"Defaultpage doesnt default to null!:{Environment.NewLine}" + $"{app.Default_page}"); diff --git a/tests/Webserver.API.UnitTests/IdGeneratorTests.cs b/tests/Webserver.API.UnitTests/IdGeneratorTests.cs index 0a542a8..32e0314 100644 --- a/tests/Webserver.API.UnitTests/IdGeneratorTests.cs +++ b/tests/Webserver.API.UnitTests/IdGeneratorTests.cs @@ -4,10 +4,6 @@ using NUnit.Framework; using Siemens.Simatic.S7.Webserver.API.Services.IdGenerator; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Webserver.API.UnitTests { @@ -18,13 +14,16 @@ class IdGeneratorTests : Base public void GUIDGenerator_InvalidLength_ThrowsArgumentOutOfRangeException() { var reqIdGen = new GUIDGenerator(); - Assert.Throws(() => { + Assert.Throws(() => + { var reqIdGen2 = new GUIDGenerator(reqIdGen.DefaultLength + 1); - }); - Assert.Throws(() => { + }); + Assert.Throws(() => + { var reqIdGen2 = new GUIDGenerator(0); }); - Assert.Throws(() => { + Assert.Throws(() => + { var reqIdGen2 = new GUIDGenerator(-3); }); } @@ -33,16 +32,20 @@ public void GUIDGenerator_InvalidLength_ThrowsArgumentOutOfRangeException() public void CharSetIdGenerator_InvalidLengthOrCharSet_ThrowsArgumentOutOfRangeException() { var reqIdGen = new CharSetIdGenerator(); - Assert.Throws(() => { + Assert.Throws(() => + { var reqIdGen2 = new CharSetIdGenerator(null, 1); }); - Assert.Throws(() => { + Assert.Throws(() => + { var reqIdGen2 = new CharSetIdGenerator("", 1); }); - Assert.Throws(() => { + Assert.Throws(() => + { var reqIdGen2 = new CharSetIdGenerator("a", 0); }); - Assert.Throws(() => { + Assert.Throws(() => + { var reqIdGen2 = new CharSetIdGenerator("a", -10); }); } diff --git a/tests/Webserver.API.UnitTests/MIMETypeTests.cs b/tests/Webserver.API.UnitTests/MIMETypeTests.cs index f8588b5..fd1f40d 100644 --- a/tests/Webserver.API.UnitTests/MIMETypeTests.cs +++ b/tests/Webserver.API.UnitTests/MIMETypeTests.cs @@ -2,13 +2,7 @@ // // SPDX-License-Identifier: MIT using NUnit.Framework; -using Siemens.Simatic.S7.Webserver.API.StaticHelpers; -using System; -using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Web; namespace Webserver.API.UnitTests { @@ -18,7 +12,7 @@ public class MIMETypeTests public void GetMIMEType_Defaults_ApplicationOctetStream() { var res = MimeMapping.MimeUtility.GetMimeMapping(""); - if(res != "application/octet-stream") + if (res != "application/octet-stream") { Assert.Fail(); } @@ -29,7 +23,7 @@ public void GetMIMEType_HTML_textHtml() { var res = MimeMapping.MimeUtility.GetMimeMapping(".html"); if (res != "text/html") - { + { Assert.Fail(); } } diff --git a/tests/Webserver.API.UnitTests/ModelTests.cs b/tests/Webserver.API.UnitTests/ModelTests.cs index 1e45ba5..3f5c2fb 100644 --- a/tests/Webserver.API.UnitTests/ModelTests.cs +++ b/tests/Webserver.API.UnitTests/ModelTests.cs @@ -3,16 +3,15 @@ // SPDX-License-Identifier: MIT using NUnit.Framework; using Siemens.Simatic.S7.Webserver.API.Enums; -using Siemens.Simatic.S7.Webserver.API.Exceptions; using Siemens.Simatic.S7.Webserver.API.Models; +using Siemens.Simatic.S7.Webserver.API.Models.AlarmsBrowse; +using Siemens.Simatic.S7.Webserver.API.Models.ApiDiagnosticBuffer; using Siemens.Simatic.S7.Webserver.API.Models.ApiPlcProgramDataTypes; -using Siemens.Simatic.S7.Webserver.API.Services.WebApp; +using Siemens.Simatic.S7.Webserver.API.Models.ApiSyslog; +using Siemens.Simatic.S7.Webserver.API.Models.TimeSettings; using System; using System.Collections.Generic; -using System.IO; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Webserver.API.UnitTests { @@ -23,7 +22,7 @@ public void ApiWebAppResource_NullEqualAndSequenceEqual_AsExpected() { var resource = new ApiWebAppResource(); resource = null; - if(resource == null) + if (resource == null) { ; } @@ -31,7 +30,7 @@ public void ApiWebAppResource_NullEqualAndSequenceEqual_AsExpected() { Assert.Fail("ResourcNullEqualAndSequenceEqual - resource not null altough its null!"); } - if(resource != null) + if (resource != null) { Assert.Fail("ResourcNullEqualAndSequenceEqual - resource not null altough its null!"); } @@ -40,7 +39,7 @@ public void ApiWebAppResource_NullEqualAndSequenceEqual_AsExpected() { Assert.Fail("ResourcNullEqualAndSequenceEqual - resource null altough its not null!"); } - if(!resource.Equals(null)) + if (!resource.Equals(null)) { ; } @@ -111,7 +110,7 @@ public void WebApp_NullEqualAndSequenceEqual_AsExpected() [Test] public void ApiS5Time_NullEqualAndSequenceEqual_AsExpected() { - var s5Time = new ApiS5Time(10,1); + var s5Time = new ApiS5Time(10, 1); s5Time = null; if (s5Time == null) { @@ -125,7 +124,7 @@ public void ApiS5Time_NullEqualAndSequenceEqual_AsExpected() { Assert.Fail("S5TimeNullEqualAndSequenceEqual - s5Time not null altough its null!"); } - s5Time = new ApiS5Time(10,1); + s5Time = new ApiS5Time(10, 1); if (s5Time.Equals(null)) { Assert.Fail("ResourcNullEqualAndSequenceEqual - s5Time not null altough its null!"); @@ -138,7 +137,7 @@ public void ApiS5Time_NullEqualAndSequenceEqual_AsExpected() { Assert.Fail("ResourcNullEqualAndSequenceEqual - s5Time not null altough its null!"); } - var s5Time2 = new ApiS5Time(10,1); + var s5Time2 = new ApiS5Time(10, 1); Assert.That(s5Time.Equals(s5Time2)); List s5Times = new List() { @@ -158,15 +157,15 @@ public void ApiS5TimeEqualAndOperatorsCheck() { var s5Time = new ApiS5Time(10, 1); var secondS5Time = new ApiS5Time(10, 1); - if(!s5Time.Equals(secondS5Time)) + if (!s5Time.Equals(secondS5Time)) { Assert.Fail("same values S5time are not equal!"); } - if(s5Time == secondS5Time) + if (s5Time == secondS5Time) { Assert.Fail("unexpectedly s5Time == secondS5Time"); } - if(!(s5Time != secondS5Time)) + if (!(s5Time != secondS5Time)) { Assert.Fail("unexpectedly s5Time != secondS5Time is false"); } @@ -191,7 +190,7 @@ public void ApiDateAndTime_MinMaxVal() Assert.Fail("MaxValue unexpected!"); } var MinValDT = ApiDateAndTime.MinValue.GetDateTime(); - if (MinValDT != new DateTime(1990, 1,1,0,0,0)) + if (MinValDT != new DateTime(1990, 1, 1, 0, 0, 0)) { Assert.Fail("MinValue unexpected!"); } @@ -215,7 +214,7 @@ public void ApiDateAndTimeEqualAndOperatorsCheck() { Assert.Fail("unexpectedly ApiDateAndTime != secondDateAndTime is false"); } - dateAndTime = new ApiDateAndTime() {Second = 2 }; + dateAndTime = new ApiDateAndTime() { Second = 2 }; if (dateAndTime.Equals(secondDateAndTime)) { Assert.Fail("other values ApiDateAndTime are equal!"); @@ -263,7 +262,7 @@ public void ApiDateAndTime_ValuesAreAsExpected() { Assert.Fail($"Unexpected date: {myDate}"); } - if(!myDate.Equals(ApiDateAndTime.MinValue)) + if (!myDate.Equals(ApiDateAndTime.MinValue)) { Assert.Fail($"Unexpectedly dates dont match: {myDate} and {ApiDateAndTime.MinValue}"); } @@ -280,7 +279,7 @@ public void ApiDateAndTime_ValuesAreAsExpected() Assert.Fail($"Unexpectedly dates dont match: {myDate} and {ApiDateAndTime.MinValue}"); } var anotherDt = new ApiDateAndTime(new DateTime(2022, 12, 31, 23, 59, 59).AddMilliseconds(999)); - if(!anotherDt.Equals(myDate)) + if (!anotherDt.Equals(myDate)) { Assert.Fail($"Unexpectedly dates dont match: {myDate} and {anotherDt}"); } @@ -304,39 +303,47 @@ public void ApiDateAndTime_ValuesAreAsExpected() [Test] public void ApiDateAndTime_InvalidValuesNotAccepted() { - Assert.Throws(() => new ApiDateAndTime(1989,1,1,0,0,0)); + Assert.Throws(() => new ApiDateAndTime(1989, 1, 1, 0, 0, 0)); Assert.Throws(() => new ApiDateAndTime(new DateTime(1930, 1, 1))); Assert.Throws(() => new ApiDateAndTime(new DateTime(2300, 1, 1))); Assert.Throws(() => new ApiDateAndTime(new DateTime(2090, 1, 1))); - Assert.Throws(() => { - var mydT = new ApiDateAndTime(2020, 1, 1, 0,0, 0.0); + Assert.Throws(() => + { + var mydT = new ApiDateAndTime(2020, 1, 1, 0, 0, 0.0); mydT.Year = 2090; }); - Assert.Throws(() => { + Assert.Throws(() => + { var mydT = new ApiDateAndTime(2020, 1, 1, 0, 0, 0.0); mydT.Year = 1989; }); - Assert.Throws(() => { + Assert.Throws(() => + { var mydT = new ApiDateAndTime(2020, 1, 1, 0, 0, 0.0); mydT.Month = 13; }); - Assert.Throws(() => { + Assert.Throws(() => + { var mydT = new ApiDateAndTime(2020, 1, 1, 0, 0, 0.0); mydT.Month = -1; }); - Assert.Throws(() => { + Assert.Throws(() => + { var mydT = new ApiDateAndTime(2020, 1, 1, 0, 0, 0.0); mydT.Day = 32; }); - Assert.Throws(() => { + Assert.Throws(() => + { var mydT = new ApiDateAndTime(2020, 1, 1, 0, 0, 0.0); mydT.Day = -1; }); - Assert.Throws(() => { + Assert.Throws(() => + { var mydT = new ApiDateAndTime(2020, 1, 1, 0, 0, 0.0); mydT.Second = 61; }); - Assert.Throws(() => { + Assert.Throws(() => + { var mydT = new ApiDateAndTime(2020, 1, 1, 0, 0, 0.0); mydT.Second = -1; }); @@ -345,7 +352,7 @@ public void ApiDateAndTime_InvalidValuesNotAccepted() [Test] public void ApiS5Time_ValuesAreAsExpected() { - var myS5Time = new ApiS5Time(10,0); + var myS5Time = new ApiS5Time(10, 0); if (myS5Time.GetTimeSpan() != TimeSpan.FromMilliseconds(0)) { Assert.Fail($"Unexpected myS5Time: {myS5Time}"); @@ -355,7 +362,7 @@ public void ApiS5Time_ValuesAreAsExpected() Assert.Fail($"Unexpectedly dates dont match: {myS5Time} and {ApiDateAndTime.MinValue}"); } var secondS5Time = new ApiS5Time(TimeSpan.FromMilliseconds(0)); - if(!myS5Time.Equals(secondS5Time)) + if (!myS5Time.Equals(secondS5Time)) { Assert.Fail($"Unexpectedly dates dont match: {myS5Time} and {secondS5Time}"); } @@ -723,7 +730,7 @@ public void HttpClientConnectionConfiguration_NullEqualAndSequenceEqual_AsExpect { Assert.Fail($"{nameof(HttpClientConnectionConfiguration)} not null altough its null!"); } - var httpClientConnectionConfiguration2 = new HttpClientConnectionConfiguration(null, null, null,TimeSpan.Zero,false,false,false); + var httpClientConnectionConfiguration2 = new HttpClientConnectionConfiguration(null, null, null, TimeSpan.Zero, false, false, false); Assert.That(httpClientConnectionConfiguration2.Equals(httpClientConnectionConfiguration)); List httpClientConnections = new List() { @@ -737,5 +744,299 @@ public void HttpClientConnectionConfiguration_NullEqualAndSequenceEqual_AsExpect }; Assert.That(httpClientConnections.SequenceEqual(httpClientConnections2)); } + + [Test] + public void PlcDate_InvalidValuesNotAccepted() + { + Assert.Throws(() => new PlcDate(0, 1, ApiDayOfWeek.Sun, 12, 43)); + Assert.Throws(() => new PlcDate(13, 1, ApiDayOfWeek.Mon, 12, 43)); + Assert.Throws(() => new PlcDate(1, 0, ApiDayOfWeek.Tue, 12, 43)); + Assert.Throws(() => new PlcDate(12, 6, ApiDayOfWeek.Wed, 12, 43)); + Assert.Throws(() => new PlcDate(1, 1, ApiDayOfWeek.Thu, -1, 43)); + Assert.Throws(() => new PlcDate(12, 5, ApiDayOfWeek.Fri, 24, 43)); + Assert.Throws(() => new PlcDate(1, 1, ApiDayOfWeek.Sat, 0, -1)); + Assert.Throws(() => new PlcDate(12, 5, ApiDayOfWeek.Sun, 23, 60)); + } + + [Test] + public void PlcDate_EqualsCheck() + { + var equalsPD1 = new PlcDate(11, 5, ApiDayOfWeek.Sun, 2, 24); + var equalsPD2 = new PlcDate(11, 5, ApiDayOfWeek.Sun, 2, 24); + var notEqualsPD1 = new PlcDate(12, 5, ApiDayOfWeek.Sun, 2, 24); + + Assert.IsTrue(equalsPD1.Equals(equalsPD2)); + Assert.IsTrue(equalsPD2.Equals(equalsPD1)); + + Assert.IsFalse(equalsPD1.Equals(notEqualsPD1)); + Assert.IsFalse(equalsPD2.Equals(notEqualsPD1)); + } + + [Test] + public void DaylightSavingTimeConfiguration_InvalidValuesNotAccepted() + { + Assert.Throws(() => new DaylightSavingsTimeConfiguration(new PlcDate(11, 1, ApiDayOfWeek.Sun, 12, 43), + TimeSpan.FromMinutes(-181))); + Assert.Throws(() => new DaylightSavingsTimeConfiguration(new PlcDate(11, 1, ApiDayOfWeek.Sun, 12, 43), + TimeSpan.FromMinutes(181))); + } + + [Test] + public void DaylightSavingTimeConfiguration_EqualsCheck() + { + var equalsPD1 = new PlcDate(11, 5, ApiDayOfWeek.Sun, 2, 24); + var equalsPD2 = new PlcDate(11, 5, ApiDayOfWeek.Sun, 2, 24); + var notEqualsPD2 = new PlcDate(10, 5, ApiDayOfWeek.Wed, 22, 10); + + var equalsDST1 = new DaylightSavingsTimeConfiguration(equalsPD1, TimeSpan.FromMinutes(60)); + var equalsDST2 = new DaylightSavingsTimeConfiguration(equalsPD2, TimeSpan.FromMinutes(60)); + var notequalsDST1 = new DaylightSavingsTimeConfiguration(notEqualsPD2, TimeSpan.FromMinutes(60)); + var notequalsDST2 = new DaylightSavingsTimeConfiguration(equalsPD1, TimeSpan.FromMinutes(120)); + + Assert.IsTrue(equalsDST1.Equals(equalsDST2)); + Assert.IsTrue(equalsDST2.Equals(equalsDST1)); + + Assert.IsFalse(equalsDST1.Equals(notequalsDST1)); + Assert.IsFalse(equalsDST2.Equals(notequalsDST2)); + } + + [Test] + public void StandardTimeConfiguration_EqualsCheck() + { + var equalsPD1 = new PlcDate(11, 5, ApiDayOfWeek.Sun, 2, 24); + var equalsPD2 = new PlcDate(11, 5, ApiDayOfWeek.Sun, 2, 24); + var notEqualsPD2 = new PlcDate(10, 5, ApiDayOfWeek.Wed, 22, 10); + + var equalsSTD1 = new StandardTimeConfiguration(equalsPD1); + var equalsSTD2 = new StandardTimeConfiguration(equalsPD2); + var notequalsSTD1 = new StandardTimeConfiguration(notEqualsPD2); + + Assert.IsTrue(equalsSTD1.Equals(equalsSTD2)); + Assert.IsTrue(equalsSTD2.Equals(equalsSTD1)); + + Assert.IsFalse(equalsSTD1.Equals(notequalsSTD1)); + } + + [Test] + public void ApiSyslog_EqualsCheck() + { + List apiSyslog_Entries = new List() { new ApiPlcSyslog_Entry() { Raw = "hello word" } }; + List apiSyslog_Entries_other = new List() { new ApiPlcSyslog_Entry() { Raw = "goodbye word" } }; + ApiPlcSyslog equal1 = new ApiPlcSyslog() { Count_Lost = 5, Count_Total = 100, Entries = apiSyslog_Entries }; + ApiPlcSyslog equal2 = new ApiPlcSyslog() { Count_Lost = 5, Count_Total = 100, Entries = apiSyslog_Entries }; + ApiPlcSyslog not_equal1 = new ApiPlcSyslog() { Count_Lost = 4, Count_Total = 100, Entries = apiSyslog_Entries }; + ApiPlcSyslog not_equal2 = new ApiPlcSyslog() { Count_Lost = 5, Count_Total = 99, Entries = apiSyslog_Entries }; + ApiPlcSyslog not_equal3 = new ApiPlcSyslog() { Count_Lost = 5, Count_Total = 100, Entries = apiSyslog_Entries_other }; + Assert.True(equal1.Equals(equal2), $"{equal1.ToString()} \nnot equal\n{equal2.ToString()}"); + Assert.True(equal2.Equals(equal1), $"{equal2.ToString()} \nnot equal\n{equal1.ToString()}"); + Assert.False(equal1.Equals(not_equal1), $"{equal1.ToString()} \nequal\n{not_equal1.ToString()}"); + Assert.False(equal1.Equals(not_equal2), $"{equal1.ToString()} \nequal\n{not_equal2.ToString()}"); + Assert.False(equal1.Equals(not_equal3), $"{equal1.ToString()} \nequal\n{not_equal3.ToString()}"); + } + [Test] + public void ApiSyslog_Entry_EqualsCheck() + { + ApiPlcSyslog_Entry equal1 = new ApiPlcSyslog_Entry() { Raw = "random text" }; + ApiPlcSyslog_Entry equal2 = new ApiPlcSyslog_Entry() { Raw = "random text" }; + ApiPlcSyslog_Entry not_equal1 = new ApiPlcSyslog_Entry() { Raw = "random txet" }; + Assert.True(equal1.Equals(equal2), $"{equal1.ToString()} \nnot equal\n{equal2.ToString()}"); + Assert.True(equal2.Equals(equal1), $"{equal2.ToString()} \nnot equal\n{equal1.ToString()}"); + Assert.False(equal1.Equals(not_equal1), $"{equal1.ToString()} \nequal\n{not_equal1.ToString()}"); + } + [Test] + public void ApiSyslog_HashCodeCheck() + { + List apiSyslog_Entries = new List() { new ApiPlcSyslog_Entry() { Raw = "hello word" } }; + List apiSyslog_Entries_other = new List() { new ApiPlcSyslog_Entry() { Raw = "goodbye word" } }; + ApiPlcSyslog equal1 = new ApiPlcSyslog() { Count_Lost = 5, Count_Total = 100, Entries = apiSyslog_Entries }; + ApiPlcSyslog equal2 = new ApiPlcSyslog() { Count_Lost = 5, Count_Total = 100, Entries = apiSyslog_Entries }; + ApiPlcSyslog not_equal1 = new ApiPlcSyslog() { Count_Lost = 4, Count_Total = 100, Entries = apiSyslog_Entries }; + ApiPlcSyslog not_equal2 = new ApiPlcSyslog() { Count_Lost = 5, Count_Total = 101, Entries = apiSyslog_Entries }; + ApiPlcSyslog not_equal3 = new ApiPlcSyslog() { Count_Lost = 5, Count_Total = 100, Entries = apiSyslog_Entries_other }; + Assert.AreEqual(equal1.GetHashCode(), equal1.GetHashCode(), $"equal1.GetHashCode() not equal equal1.GetHashCode()"); + Assert.AreEqual(equal1.GetHashCode(), equal2.GetHashCode(), $"equal1.GetHashCode() not equal equal2.GetHashCode()"); + Assert.False(equal1.GetHashCode() == not_equal1.GetHashCode(), $"equal1.GetHashCode() equal not_equal1.GetHashCode()"); + Assert.False(equal1.GetHashCode() == not_equal2.GetHashCode(), $"equal1.GetHashCode() equal not_equal2.GetHashCode()"); + Assert.False(equal1.GetHashCode() == not_equal3.GetHashCode(), $"equal1.GetHashCode() equal not_equal3.GetHashCode()"); + } + [Test] + public void ApiSyslog_Entry_HashCodeCheck() + { + ApiPlcSyslog_Entry equal1 = new ApiPlcSyslog_Entry() { Raw = "random text" }; + ApiPlcSyslog_Entry equal2 = new ApiPlcSyslog_Entry() { Raw = "random text" }; + ApiPlcSyslog_Entry not_equal1 = new ApiPlcSyslog_Entry() { Raw = "random txet" }; + Assert.AreEqual(equal1.GetHashCode(), equal1.GetHashCode(), $"equal1.GetHashCode() not equal equal1.GetHashCode()"); + Assert.AreEqual(equal1.GetHashCode(), equal2.GetHashCode(), $"equal1.GetHashCode() not equal equal2.GetHashCode()"); + Assert.False(equal1.GetHashCode() == not_equal1.GetHashCode(), $"equal1.GetHashCode() equal not_equal1.GetHashCode()"); + } + + [Test] + public void ApiAlarms_EqualsCheck() + { + ApiAlarms equal1 = new ApiAlarms() { Count_Current = 10, Count_Max = 1000, Language = "en-US", Last_Modified = new DateTime(2023, 6, 15, 10, 33, 24, 123) }; + ApiAlarms equal2 = new ApiAlarms() { Count_Current = 10, Count_Max = 1000, Language = "en-US", Last_Modified = new DateTime(2023, 6, 15, 10, 33, 24, 123) }; + ApiAlarms not_equal = new ApiAlarms() { Count_Current = 11, Count_Max = 1000, Language = "en-US", Last_Modified = new DateTime(2023, 6, 15, 10, 33, 24, 123) }; + Assert.True(equal1.Equals(equal2), $"{equal1.ToString()} not equal\n{equal2.ToString()}"); + Assert.True(equal2.Equals(equal1), $"{equal2.ToString()} not equal\n{equal1.ToString()}"); + Assert.False(equal1.Equals(not_equal), $"{equal1.ToString()} equal\n{equal2.ToString()}"); + } + + [Test] + public void ApiAlarms_Entry_EqualsCheck() + { + ApiAlarms_Entry equal1 = new ApiAlarms_Entry() + { + Id = "1", + Alarm_Number = 518, + Status = ApiObjectDirectoryStatus.Incoming, + Timestamp = new DateTime(2023, 6, 15, 10, 33, 24, 123), + Producer = "hardcoded_testcase", + Hwid = null, + Alarm_Text = "hi", + Info_Text = "word", + Text_Inconsistent = false + }; + ApiAlarms_Entry equal2 = new ApiAlarms_Entry() + { + Id = "1", + Alarm_Number = 518, + Status = ApiObjectDirectoryStatus.Incoming, + Timestamp = new DateTime(2023, 6, 15, 10, 33, 24, 123), + Producer = "hardcoded_testcase", + Hwid = null, + Alarm_Text = "hi", + Info_Text = "word", + Text_Inconsistent = false + }; + ApiAlarms_Entry not_equal = new ApiAlarms_Entry() + { + Id = "1", + Alarm_Number = 519, + Status = ApiObjectDirectoryStatus.Incoming, + Timestamp = new DateTime(2023, 6, 15, 10, 33, 24, 123), + Producer = "hardcoded_testcase", + Hwid = null, + Alarm_Text = "hi", + Info_Text = "word", + Text_Inconsistent = false + }; + Assert.True(equal1.Equals(equal2), $"{equal1.ToString()} not equal\n{equal2.ToString()}"); + Assert.True(equal2.Equals(equal1), $"{equal2.ToString()} not equal\n{equal1.ToString()}"); + Assert.False(equal1.Equals(not_equal), $"{equal1.ToString()} equal\n{equal2.ToString()}"); + } + + [Test] + public void ApiAlarms_EntryAcknowledgement_EqualsCheck() + { + ApiAlarms_EntryAcknowledgement equal1 = new ApiAlarms_EntryAcknowledgement() { State = ApiAlarmAcknowledgementState.Not_Acknowledged }; + ApiAlarms_EntryAcknowledgement equal2 = new ApiAlarms_EntryAcknowledgement() { State = ApiAlarmAcknowledgementState.Not_Acknowledged }; + ApiAlarms_EntryAcknowledgement not_equal = new ApiAlarms_EntryAcknowledgement() { State = ApiAlarmAcknowledgementState.Acknowledged, Timestamp = new DateTime(2023, 6, 15, 10, 33, 24, 123) }; + Assert.True(equal1.Equals(equal2), $"{equal1.ToString()} \nnot equal\n{equal2.ToString()}"); + Assert.True(equal2.Equals(equal1), $"{equal2.ToString()} \nnot equal\n{equal1.ToString()}"); + Assert.False(equal1.Equals(not_equal), $"{equal1.ToString()} \nequal\n{equal2.ToString()}"); + } + + [Test] + public void ApiDiagnosticBuffer_EqualsCheck() + { + ApiDiagnosticBuffer equals1 = new ApiDiagnosticBuffer() { Count_Current = 10, Count_Max = 2400, Language = "en-US", Last_Modified = new DateTime(2023, 6, 15, 10, 33, 24, 123) }; + ApiDiagnosticBuffer equals2 = new ApiDiagnosticBuffer() { Count_Current = 10, Count_Max = 2400, Language = "en-US", Last_Modified = new DateTime(2023, 6, 15, 10, 33, 24, 123) }; + ApiDiagnosticBuffer not_equals1 = new ApiDiagnosticBuffer() { Count_Current = 11, Count_Max = 2400, Language = "en-US", Last_Modified = new DateTime(2023, 6, 15, 10, 33, 24, 123) }; + ApiDiagnosticBuffer not_equals2 = new ApiDiagnosticBuffer() { Count_Current = 10, Count_Max = 1400, Language = "en-US", Last_Modified = new DateTime(2023, 6, 15, 10, 33, 24, 123) }; + ApiDiagnosticBuffer not_equals3 = new ApiDiagnosticBuffer() { Count_Current = 10, Count_Max = 2400, Language = "hun", Last_Modified = new DateTime(2023, 6, 15, 10, 33, 24, 123) }; + ApiDiagnosticBuffer not_equals4 = new ApiDiagnosticBuffer() { Count_Current = 10, Count_Max = 2400, Language = "en-US", Last_Modified = new DateTime(2021, 6, 15, 10, 33, 24, 123) }; + Assert.That(equals1.Equals(equals2), $"{equals1.ToString()} not equal to\n {equals2.ToString()}"); + Assert.That(equals2.Equals(equals1), $"{equals2.ToString()} not equal to\n {equals1.ToString()}"); + Assert.False(equals1.Equals(not_equals1), $"{equals1.ToString()} equal to\n {not_equals1.ToString()}"); + Assert.False(equals1.Equals(not_equals2), $"{equals1.ToString()} equal to\n {not_equals2.ToString()}"); + Assert.False(equals1.Equals(not_equals3), $"{equals1.ToString()} equal to\n {not_equals3.ToString()}"); + Assert.False(equals1.Equals(not_equals4), $"{equals1.ToString()} equal to\n {not_equals4.ToString()}"); + } + [Test] + public void ApiDiagnosticBuffer_Entry_EqualsCheck() + { + ApiDiagnosticBuffer_Entry equals1 = new ApiDiagnosticBuffer_Entry() + { + Event = new ApiDiagnosticBuffer_EntryEvent() { Textlist_Id = 2, Text_Id = 5 }, + Timestamp = new DateTime(2023, 6, 15, 10, 33, 24, 123), + Status = ApiObjectDirectoryStatus.Incoming, + Long_Text = "long text", + Short_Text = "short text", + Help_Text = "help text" + }; + ApiDiagnosticBuffer_Entry equals2 = new ApiDiagnosticBuffer_Entry() + { + Event = new ApiDiagnosticBuffer_EntryEvent() { Textlist_Id = 2, Text_Id = 5 }, + Timestamp = new DateTime(2023, 6, 15, 10, 33, 24, 123), + Status = ApiObjectDirectoryStatus.Incoming, + Long_Text = "long text", + Short_Text = "short text", + Help_Text = "help text" + }; + ApiDiagnosticBuffer_Entry not_equals1 = new ApiDiagnosticBuffer_Entry() + { + Event = new ApiDiagnosticBuffer_EntryEvent() { Textlist_Id = 2, Text_Id = 5 }, + Timestamp = new DateTime(2021, 6, 15, 10, 33, 24, 123), + Status = ApiObjectDirectoryStatus.Incoming, + Long_Text = "long text", + Short_Text = "short text", + Help_Text = "help text" + }; + ApiDiagnosticBuffer_Entry not_equals2 = new ApiDiagnosticBuffer_Entry() + { + Event = new ApiDiagnosticBuffer_EntryEvent() { Textlist_Id = 2, Text_Id = 5 }, + Timestamp = new DateTime(2023, 6, 15, 10, 33, 24, 123), + Status = ApiObjectDirectoryStatus.Outgoing, + Long_Text = "long text", + Short_Text = "short text", + Help_Text = "help text" + }; + ApiDiagnosticBuffer_Entry not_equals3 = new ApiDiagnosticBuffer_Entry() + { + Event = new ApiDiagnosticBuffer_EntryEvent() { Textlist_Id = 2, Text_Id = 5 }, + Timestamp = new DateTime(2023, 6, 15, 10, 33, 24, 123), + Status = ApiObjectDirectoryStatus.Incoming, + Long_Text = "long text2", + Short_Text = "short text", + Help_Text = "help text" + }; + ApiDiagnosticBuffer_Entry not_equals4 = new ApiDiagnosticBuffer_Entry() + { + Event = new ApiDiagnosticBuffer_EntryEvent() { Textlist_Id = 2, Text_Id = 5 }, + Timestamp = new DateTime(2023, 6, 15, 10, 33, 24, 123), + Status = ApiObjectDirectoryStatus.Incoming, + Long_Text = "long text", + Short_Text = "short text2", + Help_Text = "help text" + }; + ApiDiagnosticBuffer_Entry not_equals5 = new ApiDiagnosticBuffer_Entry() + { + Event = new ApiDiagnosticBuffer_EntryEvent() { Textlist_Id = 2, Text_Id = 5 }, + Timestamp = new DateTime(2023, 6, 15, 10, 33, 24, 123), + Status = ApiObjectDirectoryStatus.Incoming, + Long_Text = "long text", + Short_Text = "short text", + Help_Text = "help text2" + }; + Assert.That(equals1.Equals(equals2), $"{equals1.ToString()} not equal to\n {equals2.ToString()}"); + Assert.That(equals2.Equals(equals1), $"{equals2.ToString()} not equal to\n {equals1.ToString()}"); + Assert.False(equals1.Equals(not_equals1), $"{equals1.ToString()} equal to\n {not_equals1.ToString()}"); + Assert.False(equals1.Equals(not_equals2), $"{equals1.ToString()} equal to\n {not_equals2.ToString()}"); + Assert.False(equals1.Equals(not_equals3), $"{equals1.ToString()} equal to\n {not_equals3.ToString()}"); + Assert.False(equals1.Equals(not_equals4), $"{equals1.ToString()} equal to\n {not_equals4.ToString()}"); + Assert.False(equals1.Equals(not_equals5), $"{equals1.ToString()} equal to\n {not_equals5.ToString()}"); + } + [Test] + public void ApiDiagnosticBuffer_EntryEvent_EqualsCheck() + { + ApiDiagnosticBuffer_EntryEvent equals1 = new ApiDiagnosticBuffer_EntryEvent() { Textlist_Id = 2, Text_Id = 5 }; + ApiDiagnosticBuffer_EntryEvent equals2 = new ApiDiagnosticBuffer_EntryEvent() { Textlist_Id = 2, Text_Id = 5 }; + ApiDiagnosticBuffer_EntryEvent not_equals1 = new ApiDiagnosticBuffer_EntryEvent() { Textlist_Id = 1, Text_Id = 5 }; + ApiDiagnosticBuffer_EntryEvent not_equals2 = new ApiDiagnosticBuffer_EntryEvent() { Textlist_Id = 2, Text_Id = 6 }; + Assert.That(equals1.Equals(equals2), $"{equals1.ToString()} \n not equal to\n {equals2.ToString()}"); + Assert.That(equals2.Equals(equals1), $"{equals2.ToString()} \n not equal to\n {equals1.ToString()}"); + Assert.False(equals1.Equals(not_equals1), $"{equals1.ToString()} \n equal to\n {not_equals1.ToString()}"); + Assert.False(equals1.Equals(not_equals2), $"{equals1.ToString()} \n equal to\n {not_equals2.ToString()}"); + } } } diff --git a/tests/Webserver.API.UnitTests/RequestFactoryTests.cs b/tests/Webserver.API.UnitTests/RequestFactoryTests.cs index 956de7f..ad25820 100644 --- a/tests/Webserver.API.UnitTests/RequestFactoryTests.cs +++ b/tests/Webserver.API.UnitTests/RequestFactoryTests.cs @@ -2,12 +2,6 @@ // // SPDX-License-Identifier: MIT using NUnit.Framework; -using Siemens.Simatic.S7.Webserver.API.Models.Requests; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Webserver.API.UnitTests { @@ -24,12 +18,12 @@ public class RequestFactoryTests : Base [Test] public void DefaultValueCheckerTrue() { - if(ApiRequestFactory.PerformCheck == false) + if (ApiRequestFactory.PerformCheck == false) { Assert.Fail("Perform Check by default is false!"); } ApiRequestFactory.PerformCheck = false; - if(ApiRequestFactory.PerformCheck) + if (ApiRequestFactory.PerformCheck) { Assert.Fail("Perform Check cannot be edited!"); } diff --git a/tests/Webserver.API.UnitTests/RequestParameterCheckerTests.cs b/tests/Webserver.API.UnitTests/RequestParameterCheckerTests.cs index c805636..546c678 100644 --- a/tests/Webserver.API.UnitTests/RequestParameterCheckerTests.cs +++ b/tests/Webserver.API.UnitTests/RequestParameterCheckerTests.cs @@ -4,14 +4,10 @@ using NUnit.Framework; using Siemens.Simatic.S7.Webserver.API.Enums; using Siemens.Simatic.S7.Webserver.API.Exceptions; -using Siemens.Simatic.S7.Webserver.API.Models.Requests; +using Siemens.Simatic.S7.Webserver.API.Models.TimeSettings; using Siemens.Simatic.S7.Webserver.API.Services.RequestHandling; -using Siemens.Simatic.S7.Webserver.API.StaticHelpers; using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Webserver.API.UnitTests { @@ -48,7 +44,7 @@ public void CheckWebAppName() { var requestParameterChecker = new ApiRequestParameterChecker(); var invalidLength = ""; - Assert.Throws(() => + Assert.Throws(() => requestParameterChecker.CheckWebAppName(invalidLength, true)); requestParameterChecker.CheckWebAppName(invalidLength, false); for (int i = 0; i <= 100; i++) @@ -59,7 +55,7 @@ public void CheckWebAppName() requestParameterChecker.CheckWebAppName(invalidLength, true)); requestParameterChecker.CheckWebAppName(invalidLength, false); var invalidChars = "$!{}/ÄÖÜ~"; - foreach(var invChar in invalidChars) + foreach (var invChar in invalidChars) { Assert.Throws(() => requestParameterChecker.CheckWebAppName(invChar.ToString(), true)); @@ -98,7 +94,7 @@ public void CheckPlcProgramReadOrWriteDataType() List types = new List() // many more! { ApiPlcProgramDataType.Struct, ApiPlcProgramDataType.Cref, ApiPlcProgramDataType.Error_struct }; - foreach(var unsuppType in types) + foreach (var unsuppType in types) { Assert.Throws(() => requestParameterChecker.CheckPlcProgramReadOrWriteDataType(unsuppType, true)); @@ -206,8 +202,9 @@ public void CheckTicket() public void CheckETag() { var requestParameterChecker = new ApiRequestParameterChecker(); - List invEtags = new List() { - + List invEtags = new List() + { + }; var invTag = ""; for (int i = 0; i <= 128; i++) @@ -223,7 +220,7 @@ public void CheckETag() } List validEtags = new List() { "a", "", null }; var validTag = ""; - for(int i = 0; i < 128; i++) + for (int i = 0; i < 128; i++) { validTag += "a"; } @@ -256,5 +253,82 @@ public void CheckVisibility() requestParameterChecker.CheckWebAppResourceVisibility(vis, false); } } + + [Test] + public void CheckUsername() + { + var requestParameterChecker = new ApiRequestParameterChecker(); + Assert.Throws(() => + requestParameterChecker.CheckUsername("", true)); + Assert.Throws(() => + requestParameterChecker.CheckUsername("Anonymous", true)); + } + + [Test] + public void CheckPassword() + { + var requestParameterChecker = new ApiRequestParameterChecker(); + Assert.Throws(() => + requestParameterChecker.CheckPasswords("password", "password", true)); + } + + [Test] + public void CheckTimeStamp() + { + var requestParameterChecker = new ApiRequestParameterChecker(); + var dtNotInRange = new DateTime(1969, 12, 31, 23, 59, 59, 999); + var dtNotInRange2 = new DateTime(2554, 07, 21, 23, 34, 34, 999); + Assert.Throws(() => + requestParameterChecker.CheckSystemTimeStamp(dtNotInRange, true)); + Assert.Throws(() => + requestParameterChecker.CheckSystemTimeStamp(dtNotInRange2, true)); + requestParameterChecker.CheckSystemTimeStamp(new DateTime(2023, 07, 21, 23, 34, 34, 999), true); + } + + [Test] + public void CheckTimeSettings() + { + var requestParameterChecker = new ApiRequestParameterChecker(); + var offsetOK = new TimeSpan(8, 0, 0); + var offsetHasSeconds = new TimeSpan(8, 0, 0, 29); + var offsetHasMs = new TimeSpan(8, 0, 0, 0, 333); + var offsetMinWrong = new TimeSpan(-12, -1, 0); + var offsetMaxWrong = new TimeSpan(13, 1, 0); + Assert.Throws(() => + requestParameterChecker.CheckTimeSettings(offsetHasSeconds, null, true)); + Assert.Throws(() => + requestParameterChecker.CheckTimeSettings(offsetHasMs, null, true)); + Assert.Throws(() => + requestParameterChecker.CheckTimeSettings(offsetMinWrong, null, true)); + Assert.Throws(() => + requestParameterChecker.CheckTimeSettings(offsetMaxWrong, null, true)); + + var dstOK = new DaylightSavingsTimeConfiguration(new PlcDate(12, 5, ApiDayOfWeek.Sun, 3, 0), new TimeSpan(0, 60, 0)); + var dstHasSeconds = new DaylightSavingsTimeConfiguration(new PlcDate(12, 5, ApiDayOfWeek.Sun, 3, 0), new TimeSpan(0, 60, 22)); + var dstHasMs = new DaylightSavingsTimeConfiguration(new PlcDate(12, 5, ApiDayOfWeek.Sun, 3, 0), new TimeSpan(0, 0, 60, 0, 566)); + var sdtOK = new StandardTimeConfiguration(new PlcDate(1, 1, ApiDayOfWeek.Mon, 23, 31)); + var dstNoStart = new DaylightSavingsTimeConfiguration(null, new TimeSpan(0, 60, 0)); + var sdtNoStart = new StandardTimeConfiguration(null); + + DaylightSavingsRule dsrOK = new DaylightSavingsRule(sdtOK, dstOK); + DaylightSavingsRule dsrNoDST = new DaylightSavingsRule(sdtOK, null); + DaylightSavingsRule dsrDSTNoStart = new DaylightSavingsRule(sdtOK, dstNoStart); + DaylightSavingsRule dsrDSTSeconds = new DaylightSavingsRule(sdtOK, dstHasSeconds); + DaylightSavingsRule dsrDSTMs = new DaylightSavingsRule(sdtOK, dstHasMs); + DaylightSavingsRule dsrSDTNoStart = new DaylightSavingsRule(sdtNoStart, dstOK); + + Assert.Throws(() => + requestParameterChecker.CheckTimeSettings(offsetOK, dsrNoDST, true)); + Assert.Throws(() => + requestParameterChecker.CheckTimeSettings(offsetOK, dsrDSTNoStart, true)); + Assert.Throws(() => + requestParameterChecker.CheckTimeSettings(offsetOK, dsrSDTNoStart, true)); + Assert.Throws(() => + requestParameterChecker.CheckTimeSettings(offsetOK, dsrDSTSeconds, true)); + Assert.Throws(() => + requestParameterChecker.CheckTimeSettings(offsetOK, dsrDSTMs, true)); + + requestParameterChecker.CheckTimeSettings(offsetOK, dsrOK, true); + } } } diff --git a/tests/Webserver.API.UnitTests/ResponseCheckerTest.cs b/tests/Webserver.API.UnitTests/ResponseCheckerTest.cs index e5d16ae..b3f142b 100644 --- a/tests/Webserver.API.UnitTests/ResponseCheckerTest.cs +++ b/tests/Webserver.API.UnitTests/ResponseCheckerTest.cs @@ -2,12 +2,6 @@ // // SPDX-License-Identifier: MIT using NUnit.Framework; -using Siemens.Simatic.S7.Webserver.API.StaticHelpers; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Webserver.API.UnitTests { diff --git a/tests/Webserver.API.UnitTests/ResponseStrings.cs b/tests/Webserver.API.UnitTests/ResponseStrings.cs index f53e5bc..95963a4 100644 --- a/tests/Webserver.API.UnitTests/ResponseStrings.cs +++ b/tests/Webserver.API.UnitTests/ResponseStrings.cs @@ -1,11 +1,6 @@ // Copyright (c) 2023, Siemens AG // // SPDX-License-Identifier: MIT -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Webserver.API.UnitTests { @@ -13,7 +8,7 @@ public static class ResponseStrings { public const string InternalError = "{\"jsonrpc\":\"2.0\",\"id\":\"1agr7a8j\",\"error\":{\"code\":1,\"message\":\"Internal error\"}}"; public const string PermissionDenied = "{\"jsonrpc\":\"2.0\",\"id\":\"j8higif\",\"error\":{\"code\":2,\"message\":\"Permission denied\"}}"; - + public const string ApiBrowseResponse = "{\"jsonrpc\":\"2.0\",\"id\":\"gczcqn3i\",\"result\":[{\"name\":\"Api.Browse\"},{\"name\":\"Api.CloseTicket\"},{\"name\":\"Api.GetCertificateUrl\"},{\"name\":\"Api.GetPermissions\"},{\"name\":\"Api.BrowseTickets\"},{\"name\":\"Api.Login\"},{\"name\":\"Api.Logout\"},{\"name\":\"Api.Ping\"},{\"name\":\"Api.Version\"},{\"name\":\"Plc.ReadOperatingMode\"},{\"name\":\"Plc.RequestChangeOperatingMode\"},{\"name\":\"PlcProgram.Browse\"},{\"name\":\"PlcProgram.Read\"},{\"name\":\"PlcProgram.Write\"},{\"name\":\"WebApp.Browse\"},{\"name\":\"WebApp.BrowseResources\"},{\"name\":\"WebApp.Create\"},{\"name\":\"WebApp.CreateResource\"},{\"name\":\"WebApp.Delete\"},{\"name\":\"WebApp.DeleteResource\"},{\"name\":\"WebApp.DownloadResource\"},{\"name\":\"WebApp.Rename\"},{\"name\":\"WebApp.RenameResource\"},{\"name\":\"WebApp.SetDefaultPage\"},{\"name\":\"WebApp.SetNotAuthorizedPage\"},{\"name\":\"WebApp.SetNotFoundPage\"},{\"name\":\"WebApp.SetResourceETag\"},{\"name\":\"WebApp.SetResourceMediaType\"},{\"name\":\"WebApp.SetResourceModificationTime\"},{\"name\":\"WebApp.SetResourceVisibility\"},{\"name\":\"WebApp.SetState\"}]}"; public const string ApiBulkResponse = "[{\"jsonrpc\":\"2.0\",\"id\":\"Y3NWJ09P\",\"result\":\"run\"},{\"jsonrpc\":\"2.0\",\"id\":\"Y3NWJ09P\",\"result\":[{\"name\":\"DataTypes\",\"has_children\":true,\"db_number\":1,\"datatype\":\"datablock\"},{\"name\":\"DataTypesClassic\",\"has_children\":true,\"db_number\":2,\"datatype\":\"datablock\"},{\"name\":\"DataTypesInstance\",\"has_children\":true,\"db_number\":3,\"datatype\":\"datablock\"},{\"name\":\"SpecialVariables\",\"has_children\":true,\"db_number\":4,\"datatype\":\"datablock\"},{\"name\":\"Get_Name_DB\",\"has_children\":true,\"db_number\":5,\"datatype\":\"datablock\"},{\"name\":\"DataLogWrite_DB_MODE2\",\"has_children\":true,\"db_number\":6,\"datatype\":\"datablock\"},{\"name\":\"DataLogCreate_DB_MODE2\",\"has_children\":true,\"db_number\":7,\"datatype\":\"datablock\"},{\"name\":\"DataLogClose_DB_MODE1\",\"has_children\":true,\"db_number\":8,\"datatype\":\"datablock\"},{\"name\":\"DataLogDelete_DB_MODE2\",\"has_children\":true,\"db_number\":9,\"datatype\":\"datablock\"},{\"name\":\"Alarms_DB\",\"has_children\":true,\"db_number\":10,\"datatype\":\"datablock\"},{\"name\":\"OptionHandling_DB\",\"has_children\":true,\"db_number\":11,\"datatype\":\"datablock\"},{\"name\":\"DataLogsDB\",\"has_children\":true,\"db_number\":12,\"datatype\":\"datablock\"},{\"name\":\"DataLogCreate_DB_MODE1\",\"has_children\":true,\"db_number\":13,\"datatype\":\"datablock\"},{\"name\":\"DataLogDelete_DB_MODE1\",\"has_children\":true,\"db_number\":14,\"datatype\":\"datablock\"},{\"name\":\"OptionHandling_ET200_DB\",\"has_children\":true,\"db_number\":16,\"datatype\":\"datablock\"},{\"name\":\"DataLogOpen_DB_MODE2\",\"has_children\":true,\"db_number\":20,\"datatype\":\"datablock\"},{\"name\":\"DataLogClose_DB_MODE2\",\"has_children\":true,\"db_number\":21,\"datatype\":\"datablock\"},{\"name\":\"TRACE_INIT_DB\",\"has_children\":true,\"db_number\":27,\"datatype\":\"datablock\"},{\"name\":\"DB 333\",\"has_children\":true,\"db_number\":333,\"datatype\":\"datablock\"},{\"name\":\"TRACE_DB\",\"has_children\":true,\"db_number\":4710,\"datatype\":\"datablock\"},{\"name\":\"Clock_Byte\",\"address\":\"%MB0\",\"area\":\"M\",\"datatype\":\"byte\"},{\"name\":\"Clock_10Hz\",\"address\":\"%M0.0\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_5Hz\",\"address\":\"%M0.1\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_2.5Hz\",\"address\":\"%M0.2\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_2Hz\",\"address\":\"%M0.3\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_1.25Hz\",\"address\":\"%M0.4\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_1Hz\",\"address\":\"%M0.5\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_0.625Hz\",\"address\":\"%M0.6\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_0.5Hz\",\"address\":\"%M0.7\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"FirstScan\",\"address\":\"%M1.0\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"DiagStatusUpdate\",\"address\":\"%M1.1\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"RET_VAL\",\"address\":\"%MW333\",\"area\":\"M\",\"datatype\":\"int\"},{\"name\":\"WWW_Ret\",\"address\":\"%MW334\",\"area\":\"M\",\"datatype\":\"int\"},{\"name\":\"AlwaysTRUE\",\"address\":\"%M1.2\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"AlwaysFALSE\",\"address\":\"%M1.3\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Bool\",\"address\":\"%M200.0\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Byte\",\"address\":\"%MB201\",\"area\":\"M\",\"datatype\":\"byte\"},{\"name\":\"Char\",\"address\":\"%MB202\",\"area\":\"M\",\"datatype\":\"char\"},{\"name\":\"Date\",\"address\":\"%MW203\",\"area\":\"M\",\"datatype\":\"date\"},{\"name\":\"DInt\",\"address\":\"%MD205\",\"area\":\"M\",\"datatype\":\"dint\"},{\"name\":\"DWord\",\"address\":\"%MD209\",\"area\":\"M\",\"datatype\":\"dword\"},{\"name\":\"Int\",\"address\":\"%MW213\",\"area\":\"M\",\"datatype\":\"int\"},{\"name\":\"LDT\",\"address\":\"P#M215.0\",\"area\":\"M\",\"datatype\":\"ldt\"},{\"name\":\"LInt\",\"address\":\"P#M223.0\",\"area\":\"M\",\"datatype\":\"lint\"},{\"name\":\"LReal\",\"address\":\"P#M231.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"LTime\",\"address\":\"P#M239.0\",\"area\":\"M\",\"datatype\":\"ltime\"},{\"name\":\"LTime_Of_Day\",\"address\":\"P#M247.0\",\"area\":\"M\",\"datatype\":\"ltime_of_day\"},{\"name\":\"LWord\",\"address\":\"P#M255.0\",\"area\":\"M\",\"datatype\":\"lword\"},{\"name\":\"Real\",\"address\":\"%MD263\",\"area\":\"M\",\"datatype\":\"real\"},{\"name\":\"S5Time\",\"address\":\"%MW267\",\"area\":\"M\",\"datatype\":\"s5time\"},{\"name\":\"SInt\",\"address\":\"%MB269\",\"area\":\"M\",\"datatype\":\"sint\"},{\"name\":\"Time\",\"address\":\"%MD270\",\"area\":\"M\",\"datatype\":\"time\"},{\"name\":\"Time_Of_Day\",\"address\":\"%MD274\",\"area\":\"M\",\"datatype\":\"time_of_day\"},{\"name\":\"UDInt\",\"address\":\"%MD278\",\"area\":\"M\",\"datatype\":\"udint\"},{\"name\":\"UInt\",\"address\":\"%MW282\",\"area\":\"M\",\"datatype\":\"uint\"},{\"name\":\"ULInt\",\"address\":\"P#M284.0\",\"area\":\"M\",\"datatype\":\"ulint\"},{\"name\":\"USInt\",\"address\":\"%MB292\",\"area\":\"M\",\"datatype\":\"usint\"},{\"name\":\"WChar\",\"address\":\"%MW293\",\"area\":\"M\",\"datatype\":\"wchar\"},{\"name\":\"Word\",\"address\":\"%MW295\",\"area\":\"M\",\"datatype\":\"word\"},{\"name\":\"Merker\",\"address\":\"%M100.0\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Length20 10000000001\",\"address\":\"%M300.0\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Length50 10000000001000000000100000000010000000001\",\"address\":\"%M300.1\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Length100 000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001\",\"address\":\"%M300.2\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"MiXeDcAsEs\",\"address\":\"%M300.3\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"?=)(/&%$§!°ß0987654321^+*#-_.:,;<>\",\"address\":\"%M300.4\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"turbine_speed\",\"address\":\"P#M310.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"turbine_speed_override\",\"address\":\"%M318.0\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"turbine_max_speed\",\"address\":\"P#M336.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"turbine_max_acceleration\",\"address\":\"P#M344.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"turbine_max_jerk\",\"address\":\"P#M352.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"turbineNumber\",\"address\":\"P#M360.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"turbine_speed_sp\",\"address\":\"P#M368.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"IBool\",\"address\":\"%I100.0\",\"area\":\"I\",\"datatype\":\"bool\"},{\"name\":\"IByte\",\"address\":\"%IB101\",\"area\":\"I\",\"datatype\":\"byte\"},{\"name\":\"IWord\",\"address\":\"%IW102\",\"area\":\"I\",\"datatype\":\"word\"},{\"name\":\"IDWord\",\"address\":\"%ID104\",\"area\":\"I\",\"datatype\":\"dword\"},{\"name\":\"IInt\",\"address\":\"%IW108\",\"area\":\"I\",\"datatype\":\"int\"},{\"name\":\"QBool\",\"address\":\"%Q100.0\",\"area\":\"Q\",\"datatype\":\"bool\"},{\"name\":\"QByte\",\"address\":\"%QB101\",\"area\":\"Q\",\"datatype\":\"byte\"},{\"name\":\"QWord\",\"address\":\"%QW102\",\"area\":\"Q\",\"datatype\":\"word\"},{\"name\":\"QDWord\",\"address\":\"%QD104\",\"area\":\"Q\",\"datatype\":\"dword\"},{\"name\":\"QInt\",\"address\":\"%QW108\",\"area\":\"Q\",\"datatype\":\"int\"},{\"name\":\"Timer\",\"address\":\"%T0\",\"area\":\"T\",\"datatype\":\"s5time\"},{\"name\":\"Counter\",\"address\":\"%C0\",\"area\":\"C\",\"datatype\":\"word\"}]},{\"jsonrpc\":\"2.0\",\"id\":\"Y3NWJ09P\",\"result\":\"/MiniWebCA_Cer.crt\"},{\"jsonrpc\":\"2.0\",\"id\":\"Y3NWJ09P\",\"result\":[{\"name\":\"read_diagnostics\"},{\"name\":\"read_value\"},{\"name\":\"write_value\"},{\"name\":\"acknowledge_alarms\"},{\"name\":\"firmware_update\"},{\"name\":\"open_user_pages\"},{\"name\":\"read_file\"},{\"name\":\"write_file\"},{\"name\":\"change_operating_mode\"},{\"name\":\"flash_leds\"},{\"name\":\"backup_plc\"},{\"name\":\"restore_plc\"},{\"name\":\"manage_user_pages\"}]}]"; @@ -24,22 +19,29 @@ public static class ResponseStrings public const string TrueOnSuccess = "{\"jsonrpc\":\"2.0\",\"id\":\"y9vz5kb9\",\"result\":true}"; + public const string ApiGetAuthenticationModeMany = "{\"jsonrpc\":\"2.0\",\"id\":\"eebdd95f-96ed-418e-bd41-785056c4d016\",\"result\":{\"authentication_modes\":[\"local\",\"static\",\"disabled\"]}}"; + public const string CertificateUrl = "{\"jsonrpc\":\"2.0\",\"id\":\"rgkz2p1k\",\"result\":\"/MiniWebCA_Cer.crt\"}"; + public const string ApiGetPasswordPolicy = "{\"jsonrpc\": \"2.0\",\"id\": 3,\"result\": {\"password_policy\":{\"min_password_length\": 8,\"max_password_length\": 120,\"min_digits\": 1,\"min_special_characters\": 0,\"requires_uppercase_characters\": true,\"requires_lowercase_characters\": true}}}"; + public const string FilesBrowseTestFolder = "{\"jsonrpc\":\"2.0\",\"id\":\"aacxzpaa\",\"result\":{\"resources\":[{\"name\":\"pre3.png\",\"type\":\"file\",\"size\":20511,\"last_modified\":\"2022-03-02T15:28:25Z\"},{\"name\":\"uploadfromdev.png\",\"type\":\"file\",\"size\":110308,\"last_modified\":\"2022-03-02T15:28:17Z\"}]}}"; public const string GetPermissionsNone = "{\"jsonrpc\":\"2.0\",\"id\":\"gzxxwxb7\",\"result\":[]}"; - public const string GetPermissionsAdmin = "{\"jsonrpc\":\"2.0\",\"id\":\"20l4dkoo\",\"result\":[{\"name\":\"read_diagnostics\"},{\"name\":\"read_value\"},{\"name\":\"write_value\"},{\"name\":\"acknowledge_alarms\"},{\"name\":\"firmware_update\"},{\"name\":\"open_user_pages\"},{\"name\":\"read_file\"},{\"name\":\"write_file\"},{\"name\":\"change_operating_mode\"},{\"name\":\"flash_leds\"},{\"name\":\"backup_plc\"},{\"name\":\"restore_plc\"},{\"name\":\"manage_user_pages\"}]}"; + public const string GetPermissionsAdmin = "{\"jsonrpc\":\"2.0\",\"id\":\"20l4dkoo\",\"result\":[{\"name\":\"read_diagnostics\"},{\"name\":\"read_value\"},{\"name\":\"write_value\"},{\"name\":\"acknowledge_alarms\"},{\"name\":\"open_user_pages\"},{\"name\":\"read_file\"},{\"name\":\"write_file\"},{\"name\":\"change_operating_mode\"},{\"name\":\"flash_leds\"},{\"name\":\"backup_plc\"},{\"name\":\"restore_plc\"},{\"name\":\"failsafe_admin\"},{\"name\":\"manage_user_pages\"},{\"name\":\"update_firmware\"},{\"name\":\"change_time_settings\"},{\"name\":\"download_service_data\"},{\"name\":\"change_webserver_default_page\"},{\"name\":\"read_watch_table_value\"},{\"name\":\"write_watch_table_value\"},{\"name\":\"read_syslog\"}]}"; + - public const string LoginFailed = "{\"jsonrpc\":\"2.0\",\"id\":\"a36jhe04\",\"error\":{\"code\":100,\"message\":\"Login Failed\"}}"; public const string AlreadyAuthenticated = "{\"error\":{\"code\":101,\"message\":\"Already Authenticated\"},\"id\":\"VLKYOCY5\",\"jsonrpc\":\"2.0\"}"; public const string LoginWorked = "{\"jsonrpc\":\"2.0\",\"id\":\"0m9gsoug\",\"result\":{\"token\":\"G8ejtdxTZ6fz8AIuwDG.tWf+6Cou\"}}"; + public const string LoginWorkedWithPasswordExpirationInformation = "{\"jsonrpc\":\"2.0\",\"id\":4,\"result\":{\"token\":\"e7J5x570t0ru5yU7B3b+BdURqGgy\",\"web_application_cookie\":\"N.e2CWV+CAB8mx+q7bi9v0dIEyYX\",\"runtime_timeout\":\"PT30M\",\"password_expiration\":{\"timestamp\":\"2023-07-07T14:28:03Z\",\"warning\":false}}}"; public const string LoginWorkedWithWebAppCookie = "{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{\"token\":\"BXPfTG4MUxZqL3MqyLzIFzxCPwOV\",\"web_application_cookie\":\"N.e2CWV+CAB8mx+q7bi9v0dIEyYX\"}}"; public const string NoResources = "{\"jsonrpc\":\"2.0\",\"id\":\"d6jhjsjq\",\"error\":{\"code\":4,\"message\":\"No Resources\"}}"; + public const string ProjectReadLanguagesMany = "{\"jsonrpc\":\"2.0\",\"id\":\"5f95240c-8a3e-4c03-b34d-a2d5ee4582d4\",\"result\":{\"languages\":[{\"language\":\"en-US\"},{\"language\":\"en-GB\"},{\"language\":\"es-BR\"},{\"language\":\"ne-IN\"}]}}"; + public const string PlcProgramBrowseAll = "{\"jsonrpc\":\"2.0\",\"id\":\"jc0qvjz4\",\"result\":[{\"name\":\"TRACE_DB\",\"has_children\":true,\"db_number\":4710,\"datatype\":\"datablock\"},{\"name\":\"DataLogCreate_DB_MODE1\",\"has_children\":true,\"db_number\":13,\"datatype\":\"datablock\"},{\"name\":\"DataLogClose_DB_MODE1\",\"has_children\":true,\"db_number\":8,\"datatype\":\"datablock\"},{\"name\":\"DataLogDelete_DB_MODE1\",\"has_children\":true,\"db_number\":14,\"datatype\":\"datablock\"},{\"name\":\"DataLogCreate_DB_MODE2\",\"has_children\":true,\"db_number\":7,\"datatype\":\"datablock\"},{\"name\":\"DataLogOpen_DB_MODE2\",\"has_children\":true,\"db_number\":20,\"datatype\":\"datablock\"},{\"name\":\"DataLogWrite_DB_MODE2\",\"has_children\":true,\"db_number\":6,\"datatype\":\"datablock\"},{\"name\":\"DataLogClose_DB_MODE2\",\"has_children\":true,\"db_number\":21,\"datatype\":\"datablock\"},{\"name\":\"DataLogDelete_DB_MODE2\",\"has_children\":true,\"db_number\":9,\"datatype\":\"datablock\"},{\"name\":\"DataLogsDB\",\"has_children\":true,\"db_number\":12,\"datatype\":\"datablock\"},{\"name\":\"OptionHandling_DB\",\"has_children\":true,\"db_number\":11,\"datatype\":\"datablock\"},{\"name\":\"OptionHandling_ET200_DB\",\"has_children\":true,\"db_number\":16,\"datatype\":\"datablock\"},{\"name\":\"TRACE_INIT_DB\",\"has_children\":true,\"db_number\":27,\"datatype\":\"datablock\"},{\"name\":\"DataTypesInstance\",\"has_children\":true,\"db_number\":3,\"datatype\":\"datablock\"},{\"name\":\"Alarms_DB\",\"has_children\":true,\"db_number\":10,\"datatype\":\"datablock\"},{\"name\":\"Get_Name_DB\",\"has_children\":true,\"db_number\":5,\"datatype\":\"datablock\"},{\"name\":\"DataTypes\",\"has_children\":true,\"db_number\":1,\"datatype\":\"datablock\"},{\"name\":\"DataTypesClassic\",\"has_children\":true,\"db_number\":2,\"datatype\":\"datablock\"},{\"name\":\"SpecialVariables\",\"has_children\":true,\"db_number\":4,\"datatype\":\"datablock\"},{\"name\":\"DB 333\",\"has_children\":true,\"db_number\":333,\"datatype\":\"datablock\"},{\"name\":\"Main_Safety_RTG1_DB\",\"read_only\":true,\"has_children\":true,\"db_number\":15,\"datatype\":\"datablock\"},{\"name\":\"F_SystemInfo_DB\",\"read_only\":true,\"has_children\":true,\"db_number\":30001,\"datatype\":\"datablock\"},{\"name\":\"RTG1SysInfo\",\"read_only\":true,\"has_children\":true,\"db_number\":30000,\"datatype\":\"datablock\"},{\"name\":\"RTG2SysInfo\",\"read_only\":true,\"has_children\":true,\"db_number\":30002,\"datatype\":\"datablock\"},{\"name\":\"DB15_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30003,\"datatype\":\"datablock\"},{\"name\":\"DB17_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30004,\"datatype\":\"datablock\"},{\"name\":\"FB32770_IDB_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30005,\"datatype\":\"datablock\"},{\"name\":\"FB32770_IDB2_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30006,\"datatype\":\"datablock\"},{\"name\":\"FB32771_IDB_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30007,\"datatype\":\"datablock\"},{\"name\":\"FB32771_IDB2_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30008,\"datatype\":\"datablock\"},{\"name\":\"FB32772_IDB_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30009,\"datatype\":\"datablock\"},{\"name\":\"FB32772_IDB2_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30010,\"datatype\":\"datablock\"},{\"name\":\"FB32773_IDB_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30011,\"datatype\":\"datablock\"},{\"name\":\"FB32773_IDB2_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30012,\"datatype\":\"datablock\"},{\"name\":\"FOB_RTG1_GCTX_DB\",\"read_only\":true,\"has_children\":true,\"db_number\":30013,\"datatype\":\"datablock\"},{\"name\":\"FB6_C_GCTX_DB\",\"read_only\":true,\"has_children\":true,\"db_number\":30014,\"datatype\":\"datablock\"},{\"name\":\"FOB_RTG2_GCTX_DB\",\"read_only\":true,\"has_children\":true,\"db_number\":30015,\"datatype\":\"datablock\"},{\"name\":\"FB0_C_GCTX_DB\",\"read_only\":true,\"has_children\":true,\"db_number\":30016,\"datatype\":\"datablock\"},{\"name\":\"Main_Safety_RTG2_DB\",\"read_only\":true,\"has_children\":true,\"db_number\":17,\"datatype\":\"datablock\"},{\"name\":\"Clock_Byte\",\"address\":\"%MB0\",\"area\":\"M\",\"datatype\":\"byte\"},{\"name\":\"Clock_10Hz\",\"address\":\"%M0.0\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_5Hz\",\"address\":\"%M0.1\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_2.5Hz\",\"address\":\"%M0.2\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_2Hz\",\"address\":\"%M0.3\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_1.25Hz\",\"address\":\"%M0.4\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_1Hz\",\"address\":\"%M0.5\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_0.625Hz\",\"address\":\"%M0.6\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_0.5Hz\",\"address\":\"%M0.7\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"FirstScan\",\"address\":\"%M1.0\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"DiagStatusUpdate\",\"address\":\"%M1.1\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"RET_VAL\",\"address\":\"%MW333\",\"area\":\"M\",\"datatype\":\"int\"},{\"name\":\"WWW_Ret\",\"address\":\"%MW334\",\"area\":\"M\",\"datatype\":\"int\"},{\"name\":\"AlwaysTRUE\",\"address\":\"%M1.2\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"AlwaysFALSE\",\"address\":\"%M1.3\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Bool\",\"address\":\"%M200.0\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Byte\",\"address\":\"%MB201\",\"area\":\"M\",\"datatype\":\"byte\"},{\"name\":\"Char\",\"address\":\"%MB202\",\"area\":\"M\",\"datatype\":\"char\"},{\"name\":\"Date\",\"address\":\"%MW203\",\"area\":\"M\",\"datatype\":\"date\"},{\"name\":\"DInt\",\"address\":\"%MD205\",\"area\":\"M\",\"datatype\":\"dint\"},{\"name\":\"DWord\",\"address\":\"%MD209\",\"area\":\"M\",\"datatype\":\"dword\"},{\"name\":\"Int\",\"address\":\"%MW213\",\"area\":\"M\",\"datatype\":\"int\"},{\"name\":\"LDT\",\"address\":\"P#M215.0\",\"area\":\"M\",\"datatype\":\"ldt\"},{\"name\":\"LInt\",\"address\":\"P#M223.0\",\"area\":\"M\",\"datatype\":\"lint\"},{\"name\":\"LReal\",\"address\":\"P#M231.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"LTime\",\"address\":\"P#M239.0\",\"area\":\"M\",\"datatype\":\"ltime\"},{\"name\":\"LTime_Of_Day\",\"address\":\"P#M247.0\",\"area\":\"M\",\"datatype\":\"ltime_of_day\"},{\"name\":\"LWord\",\"address\":\"P#M255.0\",\"area\":\"M\",\"datatype\":\"lword\"},{\"name\":\"Real\",\"address\":\"%MD263\",\"area\":\"M\",\"datatype\":\"real\"},{\"name\":\"S5Time\",\"address\":\"%MW267\",\"area\":\"M\",\"datatype\":\"s5time\"},{\"name\":\"SInt\",\"address\":\"%MB269\",\"area\":\"M\",\"datatype\":\"sint\"},{\"name\":\"Time\",\"address\":\"%MD270\",\"area\":\"M\",\"datatype\":\"time\"},{\"name\":\"Time_Of_Day\",\"address\":\"%MD274\",\"area\":\"M\",\"datatype\":\"time_of_day\"},{\"name\":\"UDInt\",\"address\":\"%MD278\",\"area\":\"M\",\"datatype\":\"udint\"},{\"name\":\"UInt\",\"address\":\"%MW282\",\"area\":\"M\",\"datatype\":\"uint\"},{\"name\":\"ULInt\",\"address\":\"P#M284.0\",\"area\":\"M\",\"datatype\":\"ulint\"},{\"name\":\"USInt\",\"address\":\"%MB292\",\"area\":\"M\",\"datatype\":\"usint\"},{\"name\":\"WChar\",\"address\":\"%MW293\",\"area\":\"M\",\"datatype\":\"wchar\"},{\"name\":\"Word\",\"address\":\"%MW295\",\"area\":\"M\",\"datatype\":\"word\"},{\"name\":\"Merker\",\"address\":\"%M100.0\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Length20 10000000001\",\"address\":\"%M300.0\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Length50 10000000001000000000100000000010000000001\",\"address\":\"%M300.1\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Length100 000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001\",\"address\":\"%M300.2\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"MiXeDcAsEs\",\"address\":\"%M300.3\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"?=)(/&%$§!°ß0987654321^+*#-_.:,;<>\",\"address\":\"%M300.4\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"turbine_speed\",\"address\":\"P#M310.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"turbine_speed_override\",\"address\":\"%M318.0\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"turbine_max_speed\",\"address\":\"P#M336.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"turbine_max_acceleration\",\"address\":\"P#M344.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"turbine_max_jerk\",\"address\":\"P#M352.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"turbineNumber\",\"address\":\"P#M360.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"turbine_speed_sp\",\"address\":\"P#M368.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"IBool\",\"address\":\"%I100.0\",\"area\":\"I\",\"datatype\":\"bool\"},{\"name\":\"IByte\",\"address\":\"%IB101\",\"area\":\"I\",\"datatype\":\"byte\"},{\"name\":\"IWord\",\"address\":\"%IW102\",\"area\":\"I\",\"datatype\":\"word\"},{\"name\":\"IDWord\",\"address\":\"%ID104\",\"area\":\"I\",\"datatype\":\"dword\"},{\"name\":\"IInt\",\"address\":\"%IW108\",\"area\":\"I\",\"datatype\":\"int\"},{\"name\":\"QBool\",\"address\":\"%Q100.0\",\"area\":\"Q\",\"datatype\":\"bool\"},{\"name\":\"QByte\",\"address\":\"%QB101\",\"area\":\"Q\",\"datatype\":\"byte\"},{\"name\":\"QWord\",\"address\":\"%QW102\",\"area\":\"Q\",\"datatype\":\"word\"},{\"name\":\"QDWord\",\"address\":\"%QD104\",\"area\":\"Q\",\"datatype\":\"dword\"},{\"name\":\"QInt\",\"address\":\"%QW108\",\"area\":\"Q\",\"datatype\":\"int\"},{\"name\":\"Timer\",\"address\":\"%T0\",\"area\":\"T\",\"datatype\":\"s5time\"},{\"name\":\"Counter\",\"address\":\"%C0\",\"area\":\"C\",\"datatype\":\"word\"}]}"; public const string PlcProgramBrowseDataTypes = "{\"jsonrpc\":\"2.0\",\"id\":\"h4sxre28\",\"result\":[{\"name\":\"Bool\",\"db_number\":1,\"datatype\":\"bool\"},{\"name\":\"Byte\",\"db_number\":1,\"datatype\":\"byte\"},{\"name\":\"Char\",\"db_number\":1,\"datatype\":\"char\"},{\"name\":\"DInt\",\"db_number\":1,\"datatype\":\"dint\"},{\"name\":\"DWord\",\"db_number\":1,\"datatype\":\"dword\"},{\"name\":\"Date\",\"db_number\":1,\"datatype\":\"date\"},{\"name\":\"Int\",\"db_number\":1,\"datatype\":\"int\"},{\"name\":\"LInt\",\"db_number\":1,\"datatype\":\"lint\"},{\"name\":\"LReal\",\"db_number\":1,\"datatype\":\"lreal\"},{\"name\":\"LTime\",\"db_number\":1,\"datatype\":\"ltime\"},{\"name\":\"LWord\",\"db_number\":1,\"datatype\":\"lword\"},{\"name\":\"Real\",\"db_number\":1,\"datatype\":\"real\"},{\"name\":\"String\",\"db_number\":1,\"max_length\":254,\"datatype\":\"string\"},{\"name\":\"Time\",\"db_number\":1,\"datatype\":\"time\"},{\"name\":\"UDInt\",\"db_number\":1,\"datatype\":\"udint\"},{\"name\":\"UInt\",\"db_number\":1,\"datatype\":\"uint\"},{\"name\":\"ULInt\",\"db_number\":1,\"datatype\":\"ulint\"},{\"name\":\"USInt\",\"db_number\":1,\"datatype\":\"usint\"},{\"name\":\"WChar\",\"db_number\":1,\"datatype\":\"wchar\"},{\"name\":\"WString\",\"db_number\":1,\"max_length\":254,\"datatype\":\"wstring\"},{\"name\":\"Word\",\"db_number\":1,\"datatype\":\"word\"},{\"name\":\"AOM_IDENT\",\"db_number\":1,\"datatype\":\"aom_ident\"},{\"name\":\"ArrayBool\",\"db_number\":1,\"datatype\":\"bool\",\"array_dimensions\":[{\"start_index\":0,\"count\":2}]},{\"name\":\"CONN_ANY\",\"db_number\":1,\"datatype\":\"conn_any\"},{\"name\":\"CONN_OUC\",\"db_number\":1,\"datatype\":\"conn_ouc\"},{\"name\":\"CONN_PRG\",\"db_number\":1,\"datatype\":\"conn_prg\"},{\"name\":\"CONN_R_ID\",\"db_number\":1,\"datatype\":\"conn_r_id\"},{\"name\":\"CREF\",\"has_children\":true,\"db_number\":1,\"datatype\":\"cref\"},{\"name\":\"DB_ANY\",\"db_number\":1,\"datatype\":\"db_any\"},{\"name\":\"DB_DYN\",\"db_number\":1,\"datatype\":\"db_dyn\"},{\"name\":\"DB_WWW\",\"db_number\":1,\"datatype\":\"db_www\"},{\"name\":\"Date_And_Time\",\"db_number\":1,\"datatype\":\"date_and_time\"},{\"name\":\"EVENT_ANY\",\"db_number\":1,\"datatype\":\"event_any\"},{\"name\":\"EVENT_ATT\",\"db_number\":1,\"datatype\":\"event_att\"},{\"name\":\"EVENT_HWINT\",\"db_number\":1,\"datatype\":\"event_hwint\"},{\"name\":\"ErrorStruct\",\"has_children\":true,\"db_number\":1,\"datatype\":\"error_struct\"},{\"name\":\"HW_ANY\",\"db_number\":1,\"datatype\":\"hw_any\"},{\"name\":\"HW_DEVICE\",\"db_number\":1,\"datatype\":\"hw_device\"},{\"name\":\"HW_DPMASTER\",\"db_number\":1,\"datatype\":\"hw_dpmaster\"},{\"name\":\"HW_DPSLAVE\",\"db_number\":1,\"datatype\":\"hw_dpslave\"},{\"name\":\"HW_HSC\",\"db_number\":1,\"datatype\":\"hw_hsc\"},{\"name\":\"HW_IEPORT\",\"db_number\":1,\"datatype\":\"hw_ieport\"},{\"name\":\"HW_INTERFACE\",\"db_number\":1,\"datatype\":\"hw_interface\"},{\"name\":\"HW_IO\",\"db_number\":1,\"datatype\":\"hw_io\"},{\"name\":\"HW_IOSYSTEM\",\"db_number\":1,\"datatype\":\"hw_iosystem\"},{\"name\":\"HW_MODULE\",\"db_number\":1,\"datatype\":\"hw_module\"},{\"name\":\"HW_PTO\",\"db_number\":1,\"datatype\":\"hw_pto\"},{\"name\":\"HW_PWM\",\"db_number\":1,\"datatype\":\"hw_pwm\"},{\"name\":\"HW_SUBMODULE\",\"db_number\":1,\"datatype\":\"hw_submodule\"},{\"name\":\"IEC_COUNTER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_counter\"},{\"name\":\"IEC_DCOUNTER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_dcounter\"},{\"name\":\"IEC_LCOUNTER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_lcounter\"},{\"name\":\"IEC_LTIMER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_ltimer\"},{\"name\":\"IEC_SCOUNTER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_scounter\"},{\"name\":\"IEC_TIMER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_timer\"},{\"name\":\"IEC_UCOUNTER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_ucounter\"},{\"name\":\"IEC_UDCOUNTER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_udcounter\"},{\"name\":\"IEC_ULCOUNTER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_ulcounter\"},{\"name\":\"IEC_USCOUNTER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_uscounter\"},{\"name\":\"LDT\",\"db_number\":1,\"datatype\":\"ldt\"},{\"name\":\"NREF\",\"has_children\":true,\"db_number\":1,\"datatype\":\"nref\"},{\"name\":\"OB_ANY\",\"db_number\":1,\"datatype\":\"ob_any\"},{\"name\":\"OB_ATT\",\"db_number\":1,\"datatype\":\"ob_att\"},{\"name\":\"OB_CYCLIC\",\"db_number\":1,\"datatype\":\"ob_cyclic\"},{\"name\":\"OB_DELAY\",\"db_number\":1,\"datatype\":\"ob_delay\"},{\"name\":\"OB_DIAG\",\"db_number\":1,\"datatype\":\"ob_diag\"},{\"name\":\"OB_HWINT\",\"db_number\":1,\"datatype\":\"ob_hwint\"},{\"name\":\"OB_PCYCLE\",\"db_number\":1,\"datatype\":\"ob_pcycle\"},{\"name\":\"OB_STARTUP\",\"db_number\":1,\"datatype\":\"ob_startup\"},{\"name\":\"OB_TIMEERROR\",\"db_number\":1,\"datatype\":\"ob_timeerror\"},{\"name\":\"OB_TOD\",\"db_number\":1,\"datatype\":\"ob_tod\"},{\"name\":\"PIP\",\"db_number\":1,\"datatype\":\"pip\"},{\"name\":\"PORT\",\"db_number\":1,\"datatype\":\"port\"},{\"name\":\"RTM\",\"db_number\":1,\"datatype\":\"rtm_id\"},{\"name\":\"S5Time\",\"db_number\":1,\"datatype\":\"s5time\"},{\"name\":\"SInt\",\"db_number\":1,\"datatype\":\"sint\"},{\"name\":\"Struct1L\",\"has_children\":true,\"db_number\":1,\"datatype\":\"struct\"},{\"name\":\"Time_Of_Day\",\"db_number\":1,\"datatype\":\"time_of_day\"},{\"name\":\"LTime_Of_Day\",\"db_number\":1,\"datatype\":\"ltime_of_day\"},{\"name\":\"DTL\",\"has_children\":true,\"db_number\":1,\"datatype\":\"dtl\"},{\"name\":\"ArrayChar\",\"db_number\":1,\"datatype\":\"char\",\"array_dimensions\":[{\"start_index\":0,\"count\":2}]},{\"name\":\"ArrayInt\",\"db_number\":1,\"datatype\":\"int\",\"array_dimensions\":[{\"start_index\":0,\"count\":2}]},{\"name\":\"ArrayReal\",\"db_number\":1,\"datatype\":\"real\",\"array_dimensions\":[{\"start_index\":0,\"count\":2}]},{\"name\":\"ArrayString\",\"db_number\":1,\"max_length\":254,\"datatype\":\"string\",\"array_dimensions\":[{\"start_index\":0,\"count\":2}]},{\"name\":\"ArrayNeg\",\"db_number\":1,\"datatype\":\"bool\",\"array_dimensions\":[{\"start_index\":-1,\"count\":3}]},{\"name\":\"Struct2L\",\"has_children\":true,\"db_number\":1,\"datatype\":\"struct\"},{\"name\":\"Struct3L\",\"has_children\":true,\"db_number\":1,\"datatype\":\"struct\"},{\"name\":\"Struct4L\",\"has_children\":true,\"db_number\":1,\"datatype\":\"struct\"},{\"name\":\"Struct5L\",\"has_children\":true,\"db_number\":1,\"datatype\":\"struct\"},{\"name\":\"ArrayTest\",\"db_number\":1,\"datatype\":\"bool\",\"array_dimensions\":[{\"start_index\":0,\"count\":2}]},{\"name\":\"Enum1\",\"db_number\":1,\"datatype\":\"int\"},{\"name\":\"Enum2\",\"db_number\":1,\"datatype\":\"int\"},{\"name\":\"Enum3\",\"db_number\":1,\"datatype\":\"int\"},{\"name\":\"ArrayMax\",\"db_number\":1,\"datatype\":\"bool\",\"array_dimensions\":[{\"start_index\":0,\"count\":20000}]},{\"name\":\"ArrayMulti\",\"db_number\":1,\"datatype\":\"bool\",\"array_dimensions\":[{\"start_index\":0,\"count\":2},{\"start_index\":0,\"count\":2}]},{\"name\":\"StructArray\",\"has_children\":true,\"db_number\":1,\"datatype\":\"struct\"},{\"name\":\"StructDataTypes\",\"has_children\":true,\"db_number\":1,\"datatype\":\"struct\"},{\"name\":\"ArrayDate\",\"db_number\":1,\"datatype\":\"date\",\"array_dimensions\":[{\"start_index\":0,\"count\":2}]},{\"name\":\"ArrayDateAndTime\",\"db_number\":1,\"datatype\":\"date_and_time\",\"array_dimensions\":[{\"start_index\":0,\"count\":2}]},{\"name\":\"ArrayWord\",\"db_number\":1,\"datatype\":\"word\",\"array_dimensions\":[{\"start_index\":0,\"count\":4}]},{\"name\":\"ArrayWString\",\"db_number\":1,\"max_length\":254,\"datatype\":\"wstring\",\"array_dimensions\":[{\"start_index\":0,\"count\":3}]},{\"name\":\"ArrayMultiBigger\",\"db_number\":1,\"datatype\":\"bool\",\"array_dimensions\":[{\"start_index\":0,\"count\":7},{\"start_index\":0,\"count\":7}]},{\"name\":\"ArrayBoolSeven\",\"db_number\":1,\"datatype\":\"bool\",\"array_dimensions\":[{\"start_index\":0,\"count\":7}]}]}"; public const string PlcProgramBrowseDataTypesDTL = "{\"jsonrpc\":\"2.0\",\"id\":\"usqa2aig\",\"result\":[{\"name\":\"YEAR\",\"db_number\":1,\"datatype\":\"uint\"},{\"name\":\"MONTH\",\"db_number\":1,\"datatype\":\"usint\"},{\"name\":\"DAY\",\"db_number\":1,\"datatype\":\"usint\"},{\"name\":\"WEEKDAY\",\"db_number\":1,\"datatype\":\"usint\"},{\"name\":\"HOUR\",\"db_number\":1,\"datatype\":\"usint\"},{\"name\":\"MINUTE\",\"db_number\":1,\"datatype\":\"usint\"},{\"name\":\"SECOND\",\"db_number\":1,\"datatype\":\"usint\"},{\"name\":\"NANOSECOND\",\"db_number\":1,\"datatype\":\"udint\"}]}"; @@ -62,12 +64,20 @@ public static class ResponseStrings public const string PlcReadOpModeStopFwUpdate = "{\"jsonrpc\":\"2.0\",\"id\":\"z2fq1haj\",\"result\":\"stop_fwupdate\"}"; public const string PlcReadSystemTime = "{\"jsonrpc\":\"2.0\",\"id\":\"hqrs30u\",\"result\":{\"timestamp\":\"2022-03-01T17:02:04.23829595Z\"}}"; - public const string PlcReadTimeSettings = "{\"jsonrpc\":\"2.0\",\"id\":\"ya3ih0h\",\"result\":{\"current_offset\":0,\"utc_offset\":0,\"rule\":{\"std\":{\"start\":{\"minute\":0,\"hour\":2,\"day_of_week\":\"sun\",\"week\":5,\"month\":10}},\"dst\":{\"offset\":60,\"start\":{\"minute\":0,\"hour\":1,\"day_of_week\":\"sun\",\"week\":5,\"month\":3}}}}}"; - public const string PlcReadTimeSettingsNoRule = "{\"jsonrpc\":\"2.0\",\"id\":\"ya3ih0h\",\"result\":{\"current_offset\":0,\"utc_offset\":0}}"; + public const string PlcReadTimeSettings = "{\"jsonrpc\":\"2.0\",\"id\":\"ya3ih0h\",\"result\":{\"current_offset\":\"PT0H\",\"utc_offset\":\"PT0H\",\"rule\":{\"std\":{\"start\":{\"minute\":0,\"hour\":2,\"day_of_week\":\"sun\",\"week\":5,\"month\":10}},\"dst\":{\"offset\":\"PT1H\",\"start\":{\"minute\":0,\"hour\":1,\"day_of_week\":\"sun\",\"week\":5,\"month\":3}}}}}"; + public const string PlcReadTimeSettingsNoRule = "{\"jsonrpc\":\"2.0\",\"id\":\"ya3ih0h\",\"result\":{\"current_offset\":\"PT0H\",\"utc_offset\":\"PT0H\"}}"; + + public const string PlcSetTimeSettingsAll = "{\"jsonrpc\":\"2.0\",\"id\":\"b1zpkl8\",\"result\":true}"; + public const string PlcSetTimeSettingsNoRule = "{\"jsonrpc\":\"2.0\",\"id\":\"he7l9iu\",\"result\":true}"; + + public const string PlcSetSystemTime = "{\"jsonrpc\":\"2.0\",\"id\":\"rert5h2i\",\"result\":true}"; public const string PlcReadOpModeInvUnknown = "{\"jsonrpc\":\"2.0\",\"id\":\"z2fq1haj\",\"result\":\"unknown\"}"; public const string PlcReadOpModeInvNone = "{\"jsonrpc\":\"2.0\",\"id\":\"z2fq1haj\",\"result\":\"none\"}"; + public const string PlcReadModeSelectorStateRun = "{\"jsonrpc\":\"2.0\",\"id\":\"wec40ht3\",\"result\":{\"mode_selector\":\"run\"}}"; + public const string PlcReadModeSelectorStateNoSwitch = "{\"jsonrpc\":\"2.0\",\"id\":\"wec40ht3\",\"result\":{\"mode_selector\":\"no_switch\"}}"; + public const string InvalidParams = "{\"jsonrpc\":\"2.0\",\"id\":\"ukzrjyw\",\"error\":{\"code\":-32602,\"message\":\"Invalid Params\"}}"; public const string SystemIsBusy = "{\"jsonrpc\":\"2.0\",\"id\":\"bfabc04c\",\"error\":{\"code\":3,\"message\":\"System is busy\"}}"; @@ -80,10 +90,10 @@ public static class ResponseStrings public const string BrowseTicketsNoTickets = "{\"jsonrpc\":\"2.0\",\"id\":\"vt2too26\",\"result\":{\"max_tickets\":4,\"tickets\":[]}}"; public const string BrowseTicketsTwoTickets = "{\"jsonrpc\":\"2.0\",\"id\":\"fe3mm1xm\",\"result\":{\"max_tickets\":4,\"tickets\":[{\"id\":\"d0BybdSvFyGAmacL9sJwPEP10GMK\",\"date_created\":\"2020-12-09T14:51:31.879Z\",\"provider\":\"WebApp.CreateResource\",\"state\":\"failed\",\"data\":{}},{\"id\":\"SJGaQ+LN2n7PjiV5.XbZoAJelxdJ\",\"date_created\":\"2020-12-09T14:31:35.17Z\",\"provider\":\"WebApp.DownloadResource\",\"state\":\"created\",\"data\":{}}]}}"; - public const string TicketStatusCreated = "{\"jsonrpc\":\"2.0\",\"id\":\"tchpgtcr\",\"result\":{\"max_tickets\":4,\"tickets\":[{\"id\":\"SJGaQ+LN2n7PjiV5.XbZoAJelxdJ\",\"date_created\":\"2020-12-09T14:31:35.17Z\",\"provider\":\"WebApp.DownloadResource\",\"state\":\"created\",\"data\":{}}]}}"; - public const string TicketStatusActive = "{\"jsonrpc\":\"2.0\",\"id\":\"49pg9hsf\",\"result\":{\"max_tickets\":4,\"tickets\":[{\"id\":\"SJGaQ+LN2n7PjiV5.XbZoAJelxdJ\",\"date_created\":\"2020-12-09T14:31:35.17Z\",\"provider\":\"WebApp.DownloadResource\",\"state\":\"active\",\"data\":{}}]}}"; + public const string TicketStatusCreated = "{\"jsonrpc\":\"2.0\",\"id\":\"tchpgtcr\",\"result\":{\"max_tickets\":4,\"tickets\":[{\"id\":\"SJGaQ+LN2n7PjiV5.XbZoAJelxdJ\",\"date_created\":\"2020-12-09T14:31:35.17Z\",\"provider\":\"WebApp.DownloadResource\",\"state\":\"created\",\"data\":{}}]}}"; + public const string TicketStatusActive = "{\"jsonrpc\":\"2.0\",\"id\":\"49pg9hsf\",\"result\":{\"max_tickets\":4,\"tickets\":[{\"id\":\"SJGaQ+LN2n7PjiV5.XbZoAJelxdJ\",\"date_created\":\"2020-12-09T14:31:35.17Z\",\"provider\":\"WebApp.DownloadResource\",\"state\":\"active\",\"data\":{}}]}}"; public const string TicketStatusCompleted = "{\"jsonrpc\":\"2.0\",\"id\":\"rm9lvtw\",\"result\":{\"max_tickets\":4,\"tickets\":[{\"id\":\"oRQB2kxLMMzDMPvQ8DlN8HqlDNTi\",\"date_created\":\"2020-12-09T14:48:40.67Z\",\"provider\":\"WebApp.CreateResource\",\"state\":\"completed\",\"data\":{}}]}}"; - public const string TicketStatusFailed = "{\"jsonrpc\":\"2.0\",\"id\":\"fe3mm1xm\",\"result\":{\"max_tickets\":4,\"tickets\":[{\"id\":\"d0BybdSvFyGAmacL9sJwPEP10GMK\",\"date_created\":\"2020-12-09T14:51:31.879Z\",\"provider\":\"WebApp.CreateResource\",\"state\":\"failed\",\"data\":{}}]}}"; + public const string TicketStatusFailed = "{\"jsonrpc\":\"2.0\",\"id\":\"fe3mm1xm\",\"result\":{\"max_tickets\":4,\"tickets\":[{\"id\":\"d0BybdSvFyGAmacL9sJwPEP10GMK\",\"date_created\":\"2020-12-09T14:51:31.879Z\",\"provider\":\"WebApp.CreateResource\",\"state\":\"failed\",\"data\":{}}]}}"; public const string WebAppAlreadyExists = "{\"jsonrpc\":\"2.0\",\"id\":\"f7dyz7hm\",\"error\":{\"code\":500,\"message\":\"Application name already exists\"}}"; public const string WebAppLimitReached = "{\"jsonrpc\":\"2.0\",\"id\":\"nayr44k2r\",\"error\":{\"code\":502,\"message\":\"Application limit reached\"}}"; @@ -107,8 +117,25 @@ public static class ResponseStrings public const string WebAppResourceContentIsNotReady = "{\"error\":{\"code\":504,\"message\":\"Resource content is not ready\"},\"id\":\"i1Z2FMNG\",\"jsonRpc\":\"2.0\"}"; public const string PlcCreateBackupSucceeded = "{\"jsonrpc\":\"2.0\",\"id\":\"mkCqtF2j\",\"result\":\"dlBvEAfpgSVBfwlU7Py5TsVbmRTq\"}"; - + public const string TicketResponse = "{\"jsonrpc\":\"2.0\",\"id\":\"mkCqtF2j\",\"result\":\"dlBvEAfpgSVBfwlU7Py5TsVbmRTq\"}"; + public const string FailsafeReadParametersCPUResponse = "{\"jsonrpc\":\"2.0\",\"id\":5,\"result\":{\"safety_mode\":\"enabled\",\"type\":\"f_cpu\",\"parameters\":{\"last_f_program_modification\":\"2012-04-23T18:25:43.510Z\",\"collective_signature\":\"BC7C0410\",\"remaining_time\":\"PT2H33M\"}}}"; + + public const string FailsafeReadParametersModuleResponse = "{\"jsonrpc\":\"2.0\",\"id\":5,\"result\":{\"safety_mode\":\"enabled\",\"type\":\"f_module\",\"parameters\":{\"f_monitoring_time\":\"PT0.542S\",\"f_source_address\":321,\"f_destination_address\":123,\"f_par_crc\":\"DBB32A1A\"}}}"; + + public const string FailsafeReadRuntimeGroupsResponse = "{\"jsonrpc\":\"2.0\",\"id\":5,\"result\":{\"groups\":[{\"name\":\"F-runtime group 1\",\"signature\":\"E70AFF00\",\"cycle_time_current\":\"PT0.550S\",\"cycle_time_max\":\"PT0.600S\",\"runtime_current\":\"PT0.040S\",\"runtime_max\":\"PT0.200S\"},{\"name\":\"RTG_2\",\"signature\":\"CBA57022\",\"cycle_time_current\":\"PT0.110S\",\"cycle_time_max\":\"PT0.200S\",\"runtime_current\":\"PT0.050S\",\"runtime_max\":\"PT0.080S\"}]}}"; + + public const string QuantityStructuresResponse = "{\"jsonrpc\":\"2.0\",\"id\":\"mkCqtF2j\",\"result\":{\"webapi_max_http_request_body_size\":131072,\"webapi_max_parallel_requests\":4,\"webapi_max_parallel_user_sessions\":100}}"; + + public const string DefaultPageResponse = "{\"jsonrpc\":\"2.0\",\"method\":\"WebServer.ReadDefaultPage\",\"result\":{\"default_page\":\"/~teszt2/index.html\"},\"id\":5}"; + + public const string SyslogResponse = "{\"jsonrpc\":\"2.0\",\"id\":\"c6e7ed3c-17f4-42fc-9b3e-c31b506517d2\",\"result\":{\"entries\":[{\"raw\":\"I am a syslog, no need to question it!\"},{\"raw\":\"I am a syslog, too. But the previous syslog is an impostor!\"}],\"count_total\":5,\"count_lost\":1}}"; + + public const string AlarmsAcknowledge = "{\"jsonrpc\":\"2.0\",\"id\":\"mkCqtF2j\",\"result\":true}"; + + public const string ApiAlarmsBrowseResponse = "{\"jsonrpc\": \"2.0\",\"id\": 4,\"result\": {\"entries\": [{\"id\": 9947888669857743000,\"alarm_number\": 512,\"status\": \"incoming\",\"timestamp\": \"2012-01-01T01:01:42.047Z\",\"origin\": \"program_alarm\",\"acknowledgement\": {\"state\": \"not_acknowledged\"},\"alarm_text\": \"#1, 1\",\"info_text\": \"#1, 0\",\"text_inconsistent\": false},{\"id\": 9947888669857808000,\"alarm_number\": 513,\"status\": \"incoming\",\"timestamp\": \"2012-01-01T01:01:42.048Z\",\"origin\": \"program_alarm\",\"alarm_text\": \"#2, 1\",\"info_text\": \"#2, 0\",\"text_inconsistent\": false}],\"last_modified\": \"2012-01-01T01:01:42.099Z\",\"count_current\": 51,\"count_max\": 500,\"language\": \"en-US\"}}"; + + public const string DiagnosticBufferBrowseResponse = "{\"jsonrpc\":\"2.0\",\"id\":\"mkCqtF2j\",\"result\":{\"entries\":[{\"timestamp\": \"2012-04-23T18:25:43.511854547Z\",\"status\": \"outgoing\",\"long_text\": \"CPU info: Boot up memory card type: Program card (external load memory) CPU changes from OFF to STOP (initialization) mode PLC_2 / PLC_2\",\"short_text\": \"Boot up - CPU changes from OFF to STOP (initialization) mode\",\"event\":{\"textlist_id\": 2,\"text_id\": 16385}},{\"timestamp\": \"2023-06-07T18:25:43.511854547Z\",\"status\": \"incoming\",\"long_text\": \"LONG TEXT\",\"short_text\": \"SHORT TEXT\",\"help_text\": \"HELP TEXT\",\"event\":{\"textlist_id\": 3,\"text_id\": 26315}}],\"last_modified\": \"2023-06-07T18:25:43.514678531Z\",\"count_current\": 1234,\"count_max\": 3200,\"language\": \"en-US\"}}"; } } diff --git a/tests/Webserver.API.UnitTests/Webserver.Api.UnitTests.csproj b/tests/Webserver.API.UnitTests/Webserver.Api.UnitTests.csproj index b768bb5..e885974 100644 --- a/tests/Webserver.API.UnitTests/Webserver.Api.UnitTests.csproj +++ b/tests/Webserver.API.UnitTests/Webserver.Api.UnitTests.csproj @@ -20,11 +20,11 @@ all runtime; build; native; contentfiles; analyzers - - + + - + @@ -36,7 +36,7 @@ - + \ No newline at end of file diff --git a/version.json b/version.json index 176e3f0..6aba552 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "2.1", + "version": "2.2", "publicReleaseRefSpec": [ "^refs/heads/main$" ],