How to deploy WAR file to Web App

How to deploy WAR file to Web App

To deploy a WAR file to App Service, send a POST request to https://clicktime.symantec.com/3BC7LTrhgToTsQqqjsFFuUi7Vc?u=https%3A%2F%2F%253Capp_name%253E.scm.azurewebsites.net%2Fapi%2Fwardeploy. The POST request must contain the .war file in the message body. The deployment credentials for your app are provided in the request by using HTTP BASIC authentication.
For the HTTP BASIC authentication, you need your App Service deployment credentials. To see how to set your deployment credentials, see Set and reset user-level credentials.

With cURL
The following example uses the cURL tool to deploy a .war file. Replace the placeholders , , and . When prompted by cURL, type in the password.
curl -X POST -u –data-binary @”https://clicktime.symantec.com/3BC7LTrhgToTsQqqjsFFuUi7Vc?u=https%3A%2F%2F%253Capp_name%253E.scm.azurewebsites.net%2Fapi%2Fwardeploy

For mor information:
https://docs.microsoft.com/en-us/azure/app-service/deploy-zip#deploy-war-file

You can check the extracted files in SCM:
Azure Portal -> Your Web App -> Advanced Tools -> Go

Debug Console -> CMD

Click the folder name to navigate to D:\home\site\wwwroot -> verify the extracted files

By default, wardeploy deploys to the ROOT app. Optionally, you can simply use the query parameter name to specify the name of the app you want to deploy to: /api/wardeploy?name=NAME_OF_APP. For example, /api/wardeploy?name=myapp will deploy to the /home/site/wwwroot/webapps/myapp directory instead of /home/site/wwwroot/webapps/ROOT.
For more information: https://github.com/projectkudu/kudu/wiki/Deploying-WAR-files-using-wardeploy

HTH. By Jacky. 2019-11-08

Zip deployment for Azure Functions

1
2
CURL Command
curl -k -X POST -u $pythonfuncapptestRG --data-binary @"C:\YourPath\pythoncode.zip" https://pythonfuncapptestrg.scm.yourdomain.com/api/zipdeploy

Powershell command:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Avoiding SSL Warning for invalid certificate
##############################################
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
##############################################
# Force TLs 1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

$username = "`$pythonfuncapptestRG"
$password = "YourPassword"
$filePath = "C:\YourPath\pythoncode.zip"
$apiUrl = "https://pythonfuncapptestrg.scm.yourdomain.com/api/zipdeploy"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username, $password)))
$userAgent = "powershell/1.0"
Invoke-RestMethod -Uri $apiUrl -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -UserAgent $userAgent -Method POST -InFile $filePath -ContentType "application/x-www-form-urlencoded" -Verbose -Debug

For more information:
Zip deployment for Azure Functions
https://docs.microsoft.com/en-us/azure/azure-functions/deployment-zip-push

HTH. 2019-11-5 By Jacky

Service Fabric Rest API to change Service Instance Count

PowerShell to achive it:

1
2
3
4
5
6
$clusterFQDN = "jackysf3.eastasia.cloudapp.azure.com"
$clusterEndpoint = $clusterFQDN+':19000'
$certThumbprint = (Get-ChildItem -Path Cert:\CurrentUser\My | where {$_.Subject -like "*$clusterFQDN*" }).Thumbprint
Connect-ServiceFabricCluster -ConnectionEndpoint $clusterEndpoint -KeepAliveIntervalInSec 10 -X509Credential -ServerCertThumbprint $certThumbprint -FindType FindByThumbprint -FindValue $certThumbprint -StoreLocation CurrentUser -StoreName My

Update-ServiceFabricService -Stateless fabric:/ServiceFabricApp1/Stateless1 -InstanceCount 5

Service Fabric Rest API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static async Task MainAsync()
{
Func<CancellationToken, Task<SecuritySettings>> GetSecurityCredentials = (ct) =>
{
// get the X509Certificate2 either from Certificate store or from file.
var clientCert = new System.Security.Cryptography.X509Certificates.X509Certificate2(@"C:\Users\jchiou\jackysf320191031213903.pfx", "Password01!");
var remoteSecuritySettings = new RemoteX509SecuritySettings(new List<string> { "8AB797576F2EF93574631A6BD7C5B381C86A60C4" });
return Task.FromResult<SecuritySettings>(new X509SecuritySettings(clientCert, remoteSecuritySettings));
};

// create client using ServiceFabricClientBuilder.UseX509Security
var client = new ServiceFabricClientBuilder()
.UseEndpoints(new Uri(@"https://jackysf3.eastasia.cloudapp.azure.com:19080"))
.UseX509Security(GetSecurityCredentials)
.BuildAsync().GetAwaiter().GetResult();

await client.Services.UpdateServiceAsync("ServiceFabricApp1~Stateless1", new StatelessServiceUpdateDescription(instanceCount: 5, defaultMoveCost: Microsoft.ServiceFabric.Common.MoveCost.Zero, flags: "1"));

var serviceDesc = await client.Services.GetServiceDescriptionAsync("ServiceFabricApp1~Stateless1");

}

Make sure to add “Flags” parameter, without it you will get HTTP 200 and nothing change.

Flags indicating whether other properties are set. Each of the associated properties corresponds to a flag, specified below, which, if set, indicate that the property is specified. This property can be a combination of those flags obtained using bitwise ‘OR’ operator. For example, if the provided value is 6 then the flags for ReplicaRestartWaitDuration (2) and QuorumLossWaitDuration (4) are set.

For more information:
https://docs.microsoft.com/en-us/rest/api/servicefabric/sfclient-model-statefulserviceupdatedescription#flags

https://github.com/microsoft/service-fabric-client-dotnet

Enjoy. 2019-11-1 By Jacky

REST-API-to-manage-and-find-data-with-Blob-Index-for-Azure-Storage.-(Preview)

How to get started
To enroll in the Blog Index preview, submit a request to register this feature to your subscription by running the following PowerShell or CLI commands:

Register by using PowerShell

1
2
3
Register-AzProviderFeature -FeatureName BlobIndex -ProviderNamespace Microsoft.Storage

Register-AzResourceProvider -ProviderNamespace Microsoft.Storage

Register by using Azure CLI

1
2
3
az feature register --namespace Microsoft.Storage --name BlobIndex

​az provider register --namespace 'Microsoft.Storage'

After your request is approved, any existing or new General-purpose v2 (GPv2) storage accounts in France Central and France South can leverage Blob Index’s capabilities. As with most previews, we recommend that this feature should not be used for production workloads until it reaches general availability.

For more information:
https://azure.microsoft.com/en-us/blog/manage-and-find-data-with-blob-index-for-azure-storage-now-in-preview/

REST API Sample:
I did a test in my lab and I can use the tag: x-ms-tags: “Date” > ‘2018-06-18’.

My request:

1
2
3
4
5
6
7
GET https://jackyst2.blob.core.windows.net/container1?comp=list&include=tags&restype=container 1.1

x-ms-version: 2019-10-10
x-ms-tags: "Date" > '2018-06-18'
x-ms-date: Wed, 03 Jun 2020 02:39:07 GMT
Authorization: SharedKey jackyst2:yourkey
Host: jackyst2.blob.core.windows.net

For more inforamtion:
https://review.docs.microsoft.com/en-us/azure/storage/blobs/storage-manage-find-blobs?tabs=azure-portal&branch=master#finding-data-using-blob-index-tags

HTH. 2020-June-3 By Jacky

Azure-Function-deletes-files-older-than-30-days

Azure Function deletes files older than 30 days.

Why need it? https://feedback.azure.com/forums/169385-web-apps/suggestions/39782458-web-app-application-logging-blob-retention

Sample Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
using System;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;

namespace DeleteFilesOlderThanXDays
{
public static class DeleteFilesOlderThan30Days
{
[FunctionName("DeleteFilesOlderThan30Days")]
public async static Task Run([TimerTrigger("0 30 3 * * *")]TimerInfo myTimer, ILogger log)
{
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");

string accountName = "Your Storage Account Name";
string accountKey = "Your Account Access Key";

log.LogInformation("Storage Account Name: " + accountName);
var account = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
var blobClient = account.CreateCloudBlobClient();
//change it to your container name
var container = blobClient.GetContainerReference("Your Container Name");

log.LogInformation("Get a list of all blobs in your container");

BlobResultSegment result = await container.ListBlobsSegmentedAsync(null);

log.LogInformation("Iterate each blob");

int segmentSize = 10000;

BlobContinuationToken continuationToken = null;
CloudBlob blob;

try
{
// Call the listing operation and enumerate the result segment.
// When the continuation token is null, the last segment has been returned
// and execution can exit the loop.
do
{
BlobResultSegment resultSegment = await container.ListBlobsSegmentedAsync(string.Empty,
true, BlobListingDetails.Metadata, segmentSize, continuationToken, null, null);

foreach (var blobItem in resultSegment.Results)
{
// A flat listing operation returns only blobs, not virtual directories.
blob = (CloudBlob)blobItem;

// Write out some blob properties.
log.LogInformation("Blob name: {0} {1}", blob.Name, blob.Properties.LastModified);

log.LogInformation("Calculate when LastModified is compared to today");
TimeSpan? diff = DateTime.Today - blob.Properties.LastModified;
// 30 days, you can change it to 90 days and etc.
if (diff?.Days > 30)
{
log.LogInformation("Delete: " + blob.Name);
await blob.DeleteAsync();
}
}

log.LogInformation($"Foreach completed at: {DateTime.Now}");

// Get the continuation token and loop until it is null.
continuationToken = resultSegment.ContinuationToken;

} while (continuationToken != null);
}
catch (StorageException e)
{
log.LogInformation(e.Message);
}

log.LogInformation($"C# Timer trigger function completed at: {DateTime.Now}");
}
}
}

Change “Your Storage Account Name”, “Your Account Access Key”, “Your Container Name”, and Days.

Build and publish it to your Function App.

For more information:
Create a function in Azure that is triggered by a timer
https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-scheduled-function

Timer trigger for Azure Functions
https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer?tabs=csharp

RDP to Raspberry Pi 4

Install the xrdp package to the Raspberry Pi. This package will allow remote desktop on your Raspberry Pi.
sudo apt-get install xrdp

Retrieve the Raspberry Pi’s local IP address you can do that by using the following command.
hostname -I

My Raspberry Pi 4 is ready!!

How to retrieve blob copy status

az storage blob show is the right way to get blob copy status. The command uses “Get Blob Properties” rest operation, which is the recommended approach: https://docs.microsoft.com/en-us/rest/api/storageservices/copy-blob.

It will show the copy properties of the last copy operation.

PS Azure:> az storage blob show –container-name dest1 –account-key “YourAccountKey” –account-name jackyst3 –name “MyVHD.vhd”

{
  "content": "",
  "deleted": false,
  "metadata": {},
  "name": "MyVHD.vhd",
  "properties": {
    "appendBlobCommittedBlockCount": null,
    "blobTier": "Hot",
    "blobTierChangeTime": null,
    "blobTierInferred": true,
    "blobType": "BlockBlob",
    "contentLength": 0,
    "contentRange": null,
    "contentSettings": {
      "cacheControl": null,
      "contentDisposition": null,
      "contentEncoding": null,
      "contentLanguage": null,
      "contentMd5": null,
      "contentType": "application/octet-stream"
    },
    "copy": {
      "completionTime": null,
      "id": "a447e2f4-52bc-43e3-adfb-140c341b1208",
      "progress": "201326592/570770310",
      "source": "https://jackyst2.blob.core.windows.net/test/MyVHD.vhd?sp=r&st=2019-10-03T05:46:48Z&se=2019-10-03T13:46:48Z&spr=https&sv=2018-03-28&sig=nmQMfb6JmbgBdKSCmpifpDIn%2BZGHX9E4PFLWK1Gd%2B%2Bg%3D&sr=b",
      "status": "pending",
      "statusDescription": null
    },
    "creationTime": "2019-10-03T05:47:51+00:00",
    "deletedTime": null,
    "etag": "\"0x8D747C53A6C50CB\"",
    "lastModified": "2019-10-03T05:47:51+00:00",
    "lease": {
      "duration": null,
      "state": "available",
      "status": "unlocked"
    },
    "pageBlobSequenceNumber": null,
    "pageRanges": null,
    "remainingRetentionDays": null,
    "serverEncrypted": true
  },
  "snapshot": null
}
'''

PS Azure:\> az storage blob show --container-name dest1 --account-key "YourAccountKey" --account-name jackyst3  --name "MyVHD.vhd"
```json
{
  "content": "",
  "deleted": false,
  "metadata": {},
  "name": "MyVHD.vhd",
  "properties": {
    "appendBlobCommittedBlockCount": null,
    "blobTier": "Hot",
    "blobTierChangeTime": null,
    "blobTierInferred": true,
    "blobType": "BlockBlob",
    "contentLength": 570770310,
    "contentRange": null,
    "contentSettings": {
      "cacheControl": null,
      "contentDisposition": null,
      "contentEncoding": null,
      "contentLanguage": null,
      "contentMd5": null,
      "contentType": "application/octet-stream"
    },
    "copy": {
      "completionTime": "2019-10-03T05:49:50+00:00",
      "id": "a447e2f4-52bc-43e3-adfb-140c341b1208",
      "progress": "570770310/570770310",
      "source": "https://jackyst2.blob.core.windows.net/test/MyVHD.vhd?sp=r&st=2019-10-03T05:46:48Z&se=2019-10-03T13:46:48Z&spr=https&sv=2018-03-28&sig=nmQMfb6JmbgBdKSCmpifpDIn%2BZGHX9E4PFLWK1Gd%2B%2Bg%3D&sr=b",
      "status": "success",
      "statusDescription": null
    },
    "creationTime": "2019-10-03T05:47:51+00:00",
    "deletedTime": null,
    "etag": "\"0x8D747C58189F762\"",
    "lastModified": "2019-10-03T05:49:50+00:00",
    "lease": {
      "duration": null,
      "state": "available",
      "status": "unlocked"
    },
    "pageBlobSequenceNumber": null,
    "pageRanges": null,
    "remainingRetentionDays": null,
    "serverEncrypted": true
  },
  "snapshot": null
}
'''

For more information:
https://github.com/Azure/azure-cli/issues/1787

HTH. Jacky 2019-10-3

Windows-Server-2019-Docker

Configure Windows Features

Install-WindowsFeature -Name Containers

Uninstall-WindowsFeature Windows-Defender

Restart-Computer -Force

Install Windows Updates

Install Docker on Window Server 2019

Install-Module -Name DockerMsftProvider -Repository PSGallery -Force

Install-Package -Name docker -ProviderName DockerMsftProvider -Force -RequiredVersion 19.03

Start-Service docker

Pull the .NET Core Images

docker pull mcr.microsoft.com/dotnet/core/samples:aspnetapp

docker run -it --rm -p 8000:80 --name aspnetcore_sample mcr.microsoft.com/dotnet/core/samples:aspnetapp