Search This Blog

Sunday, December 5, 2021

C# method to increment version object

 public Version IncrementVersion()  
   {  
     var random = new Random();  
     //for demonstration purposes - this should come as a parameter  
     var version = new Version(random.Next(0, 10), random.Next(0, 10), random.Next(0, 10), random.Next(0, 10));  
     var versionComponents = version.ToString().Split('.');  
     int.TryParse(versionComponents?.LastOrDefault(), out int lastVersionComponent);  
     var incrementedVersion = new Version(version.Major, version.Minor, version.Build, ++lastVersionComponent);  
     Console.WriteLine($"original version: [{version}] incremented version: [{incrementedVersion}]");  
     return incrementedVersion;   
  }  

Tuesday, March 9, 2021

Missing WSMan client and missing liblibpsrpclient in establishing remote sessions using powershell from a docker container

https://github.com/PowerShell/PowerShell/issues/8548#issuecomment-793595858 


FROM mcr.microsoft.com/dotnet/sdk:3.1-buster


RUN apt-get update \

    && apt-get install --no-install-recommends -y \

    # less is required for help in powershell

        less \

    # requied to setup the locale

        locales \

    # required for SSL

        ca-certificates \

        gss-ntlmssp \

        libicu63 \

        libssl1.1 \

        libc6 \

        libgcc1 \

        libgssapi-krb5-2 \

        liblttng-ust0 \

        libstdc++6 \

        zlib1g \

    # PowerShell remoting over SSH dependencies

        openssh-client \

    && apt-get dist-upgrade -y \

    && apt-get clean \

    && rm -rf /var/lib/apt/lists/* \

    # enable en_US.UTF-8 locale

    && sed -i 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/g' /etc/locale.gen \

    # generate locale

    && locale-gen && update-locale

                                               

# https://github.com/PowerShell/PowerShell/issues/8548

RUN apt-get -y install wget

RUN wget "http://http.us.debian.org/debian/pool/main/g/glibc/multiarch-support_2.19-18+deb8u10_amd64.deb"

RUN dpkg -i multiarch-support_2.19-18+deb8u10_amd64.deb

RUN wget "http://security.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.0.0_1.0.1t-1+deb8u12_amd64.deb"

RUN dpkg -i libssl1.0.0_1.0.1t-1+deb8u12_amd64.deb     

#install powershell WSMan.Management module (https://www.bloggingforlogging.com/2020/08/21/wacky-wsman-on-linux/)

RUN pwsh -Command "Install-Module -Name PSWSMan -Force"

RUN pwsh -Command "Install-WSMan"

Sunday, January 10, 2021

Symmetric and Asymmetric Encryption Explained

 https://sectigostore.com/blog/5-differences-between-symmetric-vs-asymmetric-encryption/

Wednesday, December 2, 2020

Easiest and shortest sample to get a c# ILogger instance working

 I am embarrassed but I could not get a working ILogger instance to log to the console. I expected this to be achievable with 3, 4 lines. Tried several different approaches, following different posts/articles, nothing !


Using Serilog, however, gives the desired results, easily.

            var serilog = new LoggerConfiguration()

               .MinimumLevel.Debug()

               .WriteTo.Console()

               .WriteTo.File("Logs\\tests.txt", rollingInterval: RollingInterval.Day)

               .CreateLogger();

            

            var logger = new LoggerFactory().AddSerilog(serilog).CreateLogger<LinuxStartUpAndUpdaterManager>();


For instance, I use the following method in a base class all my test classes inherit from:

        protected ILogger<K> GetLogger<K>()

        {

            var serilog = new LoggerConfiguration()

                            .WriteTo.Console()

                            .WriteTo.File("testLog.txt", rollingInterval: RollingInterval.Day)

                            .CreateLogger();


            //if you need a Microsoft.Extensions.Logging ILogger out of your serilog

            return LoggerFactory.Create((c) =>

            {

                c.AddConsole();

                c.AddSerilog(serilog);

            }).CreateLogger<K>();

        }

Monday, August 31, 2020

Creating Unit Test Fact method code snippet in Visual Studio

Save the following xml file with the .snippet extension.

Afterwards, load it into the Code Snippet Manager in Visual Studio via 

Tools -> Code Snippet Manager -> Import

That's it. Type tt + Tab and the code block between CDATA[...] is inserted.


 <?xml version="1.0" encoding="utf-8"?>

<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">

<CodeSnippet Format="1.0.0">

<Header>

<Title>UT Fact</Title>

<Author>AYK</Author>

<Description>Add Unit Test Fact</Description>

<Shortcut>tt</Shortcut>

</Header>

<Snippet>

<Code Language="CSharp">

<![CDATA[

[Fact]

public async Task ObjectBeingTested_Action_ExpectedResult()

{

                                        //arrange

                                        //act

                                        //assert

}]]>

</Code>

</Snippet>

</CodeSnippet>

</CodeSnippets>

Monday, August 24, 2020

Auto generate class diagram in visual studio 2019

 From StackOverflow:

In Visual Studio 2019, dragging the whole project to an empty class diagram (add new item -> class diagram) will do the job.

Make sure you have the Visual Studio Class Designer component installed.


Why create a .NET Core Worker Service?

From Randy Patterson:

.NET Core 3 introduced a new project template called Worker Service. This template is designed to give you a starting point for cross-platform services. As an alternate use case, it sets up a very nice environment for general console applications that is perfect for containers and microservices.

From Steve J Gordon:

The simple answer is – when and if you need them! If you have a requirement to develop a microservice which has no user interface and which performs long-running work, then a worker service is very likely going to be a good fit.

Remember that a worker service is just a console application under the hood. That console application uses a host to turn the application into something which runs until it is signalled to stop. The host brings with it features like dependency injection that you’ll likely already familiar with. Using the same logging and configuration extensions available in ASP.NET Core makes it easy to develop worker services which should log information and which require some configuration. These requirements are nearly always present when building worker services that will run in the cloud. For example, you will likely need to provide configuration for any external services that your worker service will interact with. A queue URL for example.

Worker services can be used to extract responsibilities from existing ASP.NET Core applications (I cover this in my Pluralsight course) and to design new .NET Core based microservices.

Sunday, August 23, 2020

You are debugging a release build error

From StackOverflow

I went with Sam's suggestion, but after reading the docs here decided to try again. I spotted a build warning stating that some modules were optimized but I had Enable Just My Code set. I then reverted Supress JIT Optimization on module load to its original value (selected) but de-selected Enable Just My Code. I am able to debug now

Sunday, June 21, 2020

Wednesday, January 29, 2020

Importing .shp (shape) GIS files into mySQL db

Steps to import SHP files exported from GIS systems, into mySQL db:

To import GIS data into mySQL, we need to translate the geometry GIS descriptions into sql statements.
This can be achieved by using the opensource shp2mysql utility, along with cygwin1.dll (both in the same folter)

After generating the .sql file, all is left to do is to import it into mysql. I did it using sqlyog: right click in the target database → Import → Execute SQL Script → select the .sql file generated above.

But before doing that, you might do the following:

The table name where the data will be imported is derived from the sql output file name. Make sure you rename it in the Create Table statement, accordingly.

I had to manually fix the .sql file, to overcome the following issues:

  1. shp2mysql will create two columns named ID. I renamed the 2nd one to _ID
  2. my shp2mysql execution generates a 3D representation of each point, and I did not find a 3D syntax for MULTILINESTRING. I ended up replacing all 0.000000000000000 occurrences in the sql file to blank spaces, to fix it.
  3. the generated sql file had a -1 SRS id for each generated gis representation in WKT. mySql stated -1 is invalid, we checked which SRS id was used in our other GIS dbs, figured out it was 0, then I replaced all occurrences of ,-1) with ,0) in my sql file.
  4. shp2mysql will generate the sql file using a deprecated mysql function, GeometryFromText. According to mysql documentation, it was deprecated in mySql 5.7.6. Since my machine has mySql 8, I renamed all occurrences of it to ST_GeomFromText:

GeomFromText() and GeometryFromText() are deprecated as of MySQL 5.7.6 and will be removed in a future MySQL release. Use ST_GeomFromText() and ST_GeometryFromText() instead.

Now the file is valid and free of errors, and you can proceed and run the Execute SQL Script described above.

Sunday, December 15, 2019

Create circle with google map api with mousemove event to enlarge / shrink area

function addCircle_new(lat, lng, radius, alreadyDrawn) {
    function createCircle(lat, lng, radius) {

        var coordinates = new google.maps.LatLng(lat, lng);

        var options = {
            strokeColor: '#910000',
            strokeOpacity: 0.5,
            strokeWeight: 1,
            fillColor: '#FC7341',
            fillOpacity: 0.35,
            map: map,
            center: coordinates,
            radius: radius
        };
        // Add the circle for this city to the map.
        circle = new google.maps.Circle(options);
        return circle;
    }

    var circle;

    if (alreadyDrawn) {
        circle = createCircle(lat, lng, radius * 1000);
        drawObject = circle;
        pois.push(circle);
    }
    else {
        //google.maps.event.removeListener(clickListener);
        google.maps.event.addListenerOnce(map, 'click', function (x) {

            //circle = createCircle(x.latLng.lat(), x.latLng.lng(), radius * 1000);
            circle = createCircle(lat, lng, radius * 1000);

            var clickEventParameters = x;
            var mouseMoveEventParameters;

            var mouseMove = google.maps.event.addListener(map, 'mousemove', function (y) {
                mouseMoveEventParameters = y;

                var xOffset = mouseMoveEventParameters.qa.x - clickEventParameters.qa.x;
                var yOffset = mouseMoveEventParameters.qa.y - clickEventParameters.qa.y;
                var radiusOffset = Math.sqrt(Math.pow(xOffset, 2) + Math.pow(yOffset, 2)) * 100000;

                circle.setRadius(radiusOffset);

            });
            var dblClick = google.maps.event.addListener(map, 'dblclick', function (w) {
                drawObject = circle;
                google.maps.event.removeListener(mouseMove);
                pois.push(circle);

                //clickListener = google.maps.event.addListener(map, 'click', map_MouseClick);
            });
        });

    }
}

Monday, December 9, 2019

Elasticsearch aggregation - show aggregations only + overcome default limitation of aggregated buckets

Elasticsearch aggregation - output showing only aggregated field + overcoming default limitation of aggregated values (in this case, set to 1000)

GET customer_success_reports/_search
{
  "size":0,
    "aggs" : {
        "Country": {
            "composite" : {
              "size": 1000,
                "sources" : [
                    { "country": { "terms" : { "field": "Meta.GeoInfo.Country.keyword","missing_bucket": true } } }
                ]
            }
        }
     }
}


size:0 -> makes the output show the aggregated buckets only instead of the whole documents

Sunday, November 3, 2019

Fixing date field formats to upgrade elastic to version 7

Here is what did, that eventually worked:


  1. The only way I found to EDIT the field format was by creating a new (empty) index, by specifying its mapping. The date fields I replaced (had my json in a text editor and did a "replace all" on each different format to a elastic-7-complying one. In my case, most of my fields were "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis", and I changed them to "8yyyy/MM/dd HH:mm:ss||8yyyy/MM/dd".
  2. Then I issued a _reindex, meaning I copied the contents of each index I had to fix to its corresponding new empty index I created, in the step above, to hold its data, now in a compatible format
  3. At the end of the reindex (do not worry about the "backend connection closed" message, the copy keeps running, check the "Reload Indices" in Index Management), I added an alias to the new index so that new documents being added to the original one are now inserted in the new one (using the _alias api)
  4. If you want the indexes to remain with their original names at the end, you can then copy once again the indexes to a new one, using the original name this time. Be aware that before doing that you must remove the alias you added in step (3), other wise the engine thinks the index already exists (because references to the alias translate into references to the new index).

CAUTION: My dashboards stopped working. I have an open ticket with Elastic's support at the moment waiting for instructions.

At this stage, after doing the above to all indexes that had warnings on date formats, you should reach the stage where you have no warnings left, and are ready for the upgrade.

Tuesday, September 24, 2019

Get Enum Attribute Value in C#

public static string GetEnumAttributeValue(Enum enumValue, Type attributeType, string attributePropertyName)
        {
            /*
             * Extracts a given attribute value from an enum:
             *
             * Ex:
             * public enum X
             * {
                     [MyAttribute(myProp = "aaaa")]
             *       x1,
             *       x2,
             *       [Description("desc")]
             *       x3
             * }
             *
             * Usage:
             *      GetEnumAttribute(X.x1, typeof(MyAttribute), "myProp") returns "aaaa"
             *      GetEnumAttribute(X.x2, typeof(MyAttribute), "myProp") returns string.Empty
             *      GetEnumAttribute(X.x3, typeof(DescriptionAttribute), "Description") returns "desc"
             */

            var attributeObj = enumValue.GetType()?.GetMember(enumValue.ToString())?.FirstOrDefault()?.GetCustomAttributes(attributeType, false)?.FirstOrDefault();

            if (attributeObj == null)
                return string.Empty;
            else
            {
                try
                {
                    var attributeCastedObj = Convert.ChangeType(attributeObj, attributeType);
                    var attributePropertyValue = attributeType.GetProperty(attributePropertyName)?.GetValue(attributeCastedObj);
                    return attributePropertyValue?.ToString() ?? string.Empty;
                }
                catch (Exception ex)
                {
                    return string.Empty;
                }
            }
        }