Sunday, February 26, 2017

Octopus meets Magento on Windows and Linux

One project that I am working with consists of two parts: 
* Backend job runners, written in C#.NET Full Windows Framework and 
* Frontend web site based on Magento CMS, which is written in PHP

In our team there was already the Windows VPS machine for .NET applications. Also we use Continuous Deployment tool Octopus Deploy, which requires Octopus Server to be installed on Windows OS. 
Magento is working by default with LAMP (Linux Apache MySql PHP) infrastructure and nothing is said about Windows. Some guys use WAMP (Windows Apache MySql PHP) infrastructure, but mixing Apache and IIS is not a good idea. Thus we decided to give a try and run Magento in Windows + PHP + IIS alongside existed .NET applications.

The first thing was to convert many Magento .htaccess files (Apache) to web.config (IIS). This task itself is pretty hard and manual. IIS has auto converting feature for .htaccess => IIS rules web.config, but most of the time IIS failed to do it properly.

The next thing is to make a package containing the whole website for Octopus. We use TeamCity for CI and decided to pack, as usual for .NET, everything in a NuGet package. The trick is that NuPack tool works excellent with .NET dlls, but we finally found how to pack even PHP and .htaccess files.

To do so create .nuspec file in the root of the project:
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
    <!-- Commands: https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Clients/NuGet.CommandLine/Commands/PackCommand.cs -->
    <!-- Schema: https://docs.microsoft.com/en-gb/nuget/schema/nuspec -->
    <metadata>
        <id>MyProject</id>
        <title>Project Title</title>
        <version>1.0.0</version>
        <description>This is a Magento project</description>
        <authors>Your team</authores>
    </metadata>
    <files>
        <file src="**" exclude=".git\**" />
    </files> 
</package> 

The most import thing here is to make the files filter src="**", which includes all kind of types and extensions. The fields "id, version, description, authors" are required.

Then run nuget pack command pointing to our .nuspec file.
nuget pack .nuspec -NoPackageAnalysis -NoDefaultExcludes

 NoPackageAnalysis speeds up the packing, NoDefaultExcludes protects from nuget throwing out special non .NET world files. This can be simply configured in TeamCity NuPack Runner.
The process of packaging takes about 3 minutes as Nuget provides only one level of compression and the project is big (about 40 000 files).

After that you will have your MyProject.nuget file that can be pushed to Octopus (I will skip the details). Another solution is use custom NodeJS package instead of NuGet package.

The next problem was figured out with the help of Octopus. Linux terminal usually swallows the errors from magento setup tool when you run 
php -dmemory_limit=2G bin/magento setup:static-content:deploy

Better to run verbose output '-v' for showing the errors
php -dmemory_limit=2G bin/magento setup:static-content:deploy -v

Gladly Octopus understood the presence of errors even without "-v" argument and refused to continue the deployment. The problem was in the popular Magento theme that we use Sm Market. Bootstrap source code contained import .less rules with wrong file names in Magento/app/design/frontend/Sm/market/web/css/source/bootstrap/_theme.less,
fix it by pointing to the proper file names:
@import "_variables";
@import "_mixins.less";



After a lot of fighting and trying to run Magento in IIS, eventually it was working with (still) a lot of errors and problems due the url rewriting rules and user rights. The time spent on this became too big, so the decision was to move Magento to its Alma mater: Linux machine and Apache. 
However we would like to continue working with awesome Octopus tool. Recently their team added support for Linux OS as tentacles (the server still requires Windows). This was an excellent case for us to give it a try.

Linux

The first step is to follow the guidance Octopus SSH Taget and install mono. Plus mysql, apache, php, etc for Magento.

Then create user "octopus":
sudo useradd -m octopus echo octopus:<the-password-you-want> | sudo chpasswd

We decided not to create a user per app in UAT machine and to run web sites by the octopus user. To do so just add the octopus user to the apache group:
sudo usermod -g apache octopus

The next point is to give octopus the ability to work with apachectl command (CentOS) without entering password. Create octopus section in sudoers:
sudo visudo -f /etc/sudoers.d/octopus 


and put data:
#Allow octopus to control apache 
octopus     ALL=(ALL) NOPASSWD:/usr/sbin/apachectl
Defaults!/usr/sbin/apachectl !requiretty

Thus octopus will be able to run sudo apachectl restart without entering the password.


Apache

Now the time to set up Apache.
Open /etc/httpd/conf/httpd.conf and comment all Directory settings except the global one restrictions.

If you have Include conf.d/*.conf row then you can create  /etc/httpd/conf.d/magento.conf,
otherwise just put the next lines to etc/httpd/conf/httpd.conf
Include /home/octopus/.octopus/Applications/OctopusServer/Development/YourProjectName/*.conf
Include /home/octopus/.octopus/Applications/OctopusServer/UAT/YourProjectName/*.conf

It means that config files from the above folders will be used by Apache. If you have Apache 2.4+ then it is better to use IncludeOptional directive, which does not throw error if the path does not exist.

The configuration files will be created one per project and will update Apache bindings in the next way:
<VirtualHost *:80>
  ServerName www.sitename.com 
  DocumentRoot /home/octopus/.octopus/Applications/OctopusServer/Development/YourProjectName/1.0.20/
  <Directory /home/octopus/.octopus/Applications/OctopusServer/Development/YourProjectName/1.0.20/> 
       Options Indexes FollowSymLinks MultiViews 
       AllowOverride All 
       Order allow,deny 
       Allow from all 
  </Directory>
</VirtualHost>

If you do not like this approach you can use pm2 tool for starting and stoping processes.

Octopus

Set up Octopus steps
We only need some scripts to run in bash.
(Magento installation scripts with Apache config update are placed at the end of this article)


Install and Upgrade Magento step:


parameters are taken from Octopus Variables:
--magento-directory="#{Octopus.Action[Deploy to Apache].Output.Package.InstallationDirectoryPath}" 
--admin-firstname="#{AdminFirstname}" --admin-lastname="#{AdminLastname}" 
--admin-email="#{AdminEmail}" --admin-user="#{AdminUser}" 
--admin-password="#{AdminPassword}" --base-url="#{BaseUrl}" 
--backend-frontname="#{BackendFrontname}" --db-name="#{DbName}" 
--db-user="#{DbUser}" --db-password="#{DbPassword}"

Update Apache Bindings step:

parameters are also taken from Octopus Variables:
--magento-directory="#{Octopus.Action[Deploy to Apache].Output.Package.InstallationDirectoryPath}" 
--server-name="#{WebsiteName}"


And that is it.
The deploy process works like a charm.


MagentoDeploy.sh


MagentoUpdateApacheBindings.sh




Saturday, February 11, 2017

Can we stop date formatting mess?

What does the next date exactly present?


Most people from over the world will say that it is the 2nd of November 2017. But it is not true for American and Albanian people.

Airbnb for US culture will show the popup with the 11th of February 2017.




















This becomes more entangled when we get Russian, Ukrainian and Kazakstan format DD.MM.YYYY, which is often shortened to DD.MM.YY. For example, the 11th of February 2017 is usually written as 11.02.17.

To make internationalisation more complex some countries (Chine, Lithuania, South Africa) use YYYY-MM-DD or YYYY.MM.DD, which sometimes people like to shorten to YY.MM.DD, and our previous example becomes 17.02.11.

If you think that nothing can be worth, there are countries (Germany, Canada, Sweden, Philippines), which apply different date formats depending on a context.

Requirements

Taking into the account all previous points and preventing likelihood problems the solution of the problem should be:
1) Visible immediately as a static text without any data manipulation (no need to open a popup date editor)
2) A day, a month and a year should be distinguishable from each other
3) The distinguish signs should have the colour of the text and be readable after a monochrome print, e.g. in books and newspapers.
4) The distinguish signs should be simple and built from UTF symbols.

Proposal of a solution

Let us start our visual identification from the shortest amount of time - a day, to the most lasting - a year. The simplest visual effect, that is also very convenient to program or use in draw editors, is underlining. Underlining also works good with all popular charset encodings.

A day gets full width underline = DD;
A month gets a half width underline if the year part is short (YY) = MM; otherwise month has no underline = MM;
A year has no underline = YYYY or YY;

Examples

Our initial confusing date presentation now becomes absolutely clear:


Some people like to trim zeros and write, for example, 7.9.2017. Even this date can be transformed to an obvious presentation: 7.9.2017.

More complex 11.10.12 YY.MM.DD can be transformed to 11.10.12 or to 12.10.11, which is actually the same as  12.10.2012 and 10/12/2012.

And now the bonus for developers and almost anybody who process much data. A common SQL result nowadays says nothing about a date format:

while after our small fix the data is a pleasure to read:

Table of different date formats 

Date Meaning
2/11/2017 The 11th of February 2017
2/11/2017 The 2nd of November 2017
10/3 or 10/03 The 10th of March
01/17 January 2017
2017-12-10 The 10th of December 2017
05/04/03 The 5th of March 2003
05/04/03 The 3rd of March 2005
2/3/2020 The 3rd of February 2020


Happy coding!

Wednesday, October 19, 2016

The evolution of web development

Custom HTML Attributes Are Evil


HTML is itself a static content, and many developers have used the specification <!DOCTYPE >, which points out that it is merely a document.
The dynamic part is represented by JavaScript language. And here arose the problem.

Looking how various programming languages are used to build UI reveals that the language itself is a part of UI blocks. For example, Windows Presentation Framework uses XAML with C# controls:
<Grid Background="#555555" Width="400" Height="300">
    <Button Click="OnButtonClick">Press me</Button>
 </Grid>

Here will be created an instance of Grid class and an instance of Button class. Also it is possible to write logic whatever we like inside custom controls as they are just usual classes:
class Grid {
     public Color Background {get; set;}
     // methods and other UI logic
}
The same is true for Java with Android layouts, and many other languages and platforms.

HTML initially does not provide such idea, it does not link <html-element> to a JavaScript instance. To enhance it we can simply declare HTML elements as objects of JavaScript types:
  class div {
     public string style {get;set;}
     // methods and other UI logic


     render: function(){
         // return real html '<div>'+content+'</div>'
     }
  }
  class MyWindowPopup {
     public boolean fullScreen {get;set;}
     public boolean visible {get;set;}
     // methods and other UI logic

  }

Then it becomes possible to build pages and components in a common way:
   <MyWindowPopup visible="true" fullScreen="false">
     <div>Popup text</div>
   </MyWindowPopup>
Moreover we can advance some property types, e.g. use string[] array instead of string for class property <div class="typeof string[]">.

Then a browser or a server (NodeJS) is simply converts JavaScript to HTML and shows layout to a user. This approach took Facebook team with React and its JSX style.
---------------------------------------

Many other teams try to overcome HTML static nature by putting custom attributes, which seems very strange and inconvenient for me. Angular, Vue.js, Aurelia.js and many other JS frameworks use logic with custom marks (*ngIf, v-if, bind.click):
<div *ngIf="currentHero">Hello, {{currentHero.firstName}}</div>
<div *ngFor="let hero of heroes">{{hero.fullName}}</div>

JavaScript Monopoly


Nowadays JavaScript is the king of UI and there is no alternative.
I think every team that works with Web tried to create a converter from their languages to JavaScript. However this approach produces massive bunch of problems due the nature of languages.

Google created GWT where Java is converter to JavaScript and developers can write kind of UI logic in Java. Also Google tried to apply usage of Dart language in modern browsers and again created conversion to JavaScript.
Microsoft uses aspx controls that can be written in .NET compatible language, Razor views, and TagHelpers in Asp Core, which all finally are converted to JavaScript and HTML. You can find same idea for Elm, Python, PHP and other languages.

The problem is that JavaScript and C#, JavaScript and Java, JavaScript and [your favourite language] are very different beasts.

Javascript is a prototype-based language with first-class functions. There is no even idea of an object instance of a class (class declaration leads again to a function). There are just six types in JavaScript: Object, Number, String, Boolean, Null, and Undefined, plus some object helpers like RegEx. There is no even notion of Integer or Decimal type because JavaScript Number only holds double-precision 64-bit format value. Run in a JS console "0.1 + 0.3" and see what you get, while with Decimal types in C# the result will be "0.4".

Thus, developers restrict their language of choice too much and loose the power of JavaScript. In addition to these points most of the time they loose highlighting and intellisense while producing JavaScript and HTML as a string, e.g. in Asp Core TagHelpers:

     public class IconTextTagHelper : TagHelper
    {
        public string  Glyph { get; set; }
        [HtmlAttributeName("class")]
        public string ClassName { get; set; }

        public override void Process(TagHelperContext context, TagHelperOutput output)

        {
           string classnames = String.IsNullOrWhiteSpace(ClassName) ? "icontext" : "icontext " + ClassName;
                output.TagName = "a";
                output.TagMode = TagMode.StartTagAndEndTag;
                output.Attributes.Add("class", classnames);
                
                output.Content.SetHtmlContent(
                // String, string, string

                   $@"<span>
                          <i class=""icon fa fa-{Glyph ?? ""} icontext__icon""></i>
                          <span class=""icontext__text"">{this.Text}</span>
                      </span>");                     
        }
    }
 A way better solution is to work with JavaScript itself, or even better with TypeScript, which provides static type checking.

Breaking JavaScript Monopoly


To overcome the monopoly of JavaScript the IT community are making an attempt to specify WebAssembly, which later can be supported by browsers vendors.
The idea is very simple:
   Browsers will support agnostic language (through ASTs) that will include many features from modern languages. It will be some kind of Intermediate Language that is used in Java and .NET virtual machines nowadays. It will be faster to parse, faster to transfer, faster to run, it will be in binary format instead of text format of current JavaScript.

Sadly web development progress is very slow.
The web community still tries to build some kind of XAML with its custom components, inline styles, namespaces and modules.
It is 2016 and only now we have Flexbox, which is analogue of StackPanel in WPF for arranging elements horizontally or vertically in a single line. And what about Grid,  without a hack and whistles there is no way to do it in modern CSS, only recently W3C CSS Grid specification has passed from a Draft type to a Candidate Recommendation type.

There are so many bright minds in our realm but the overall picture is appalling.

P.S. JavaScript word is used for convenience, while ECMAScript is the proper notion in some places.

Saturday, October 15, 2016

SPA

It is common nowadays to have the acronym for SPA as a Single Page Application.

Nevertheless the actual meaning is quite different, the page is not single, the page is actually shelled.

SPA approach has the same idea as in a mobile application or a thin desktop client. A user downloads a thin shell for the app: a header, a footer, a body placeholder and possibly sidebars. Then asynchronously this app updates the content for the placeholders, while footer and header is not reloaded.

From a user experience the app is working with several navigation links and many pages. So calling such shelled app layout as a one page sounds misleading.


SPA = Shelled Page Application


Wednesday, October 12, 2016

Application workflow strategy and Staging verbosity

One of the famous app flow strategies is DTAP, which is acronym for Development Testing Acceptance Production.

Let us consider each step in detail, but before this let us make step back and add a source control and a continuous integration step for the full picture.

The scheme represent a de-facto standard in current development process.

Source control
  • holds project source files and likely provides history changes, as project branches and users control management.

Continous integration 

  • a continuous integration tool checks for the source control changes, grabs source files from the source control and builds the projects;
  •  runs unit tests;
  •  produces artifacts (application packages) that are ready for publishing;
  •  publishes the app to Dev server;
  •  for the published app runs smoke tests, which check basic and the most important functionality, e.g. products are displaying and a user can log in and pay for a product;
  • for the published app runs functional tests, which makes in-depth testing of the whole application pretending to be a human tester, e.g. opening Internet Explore browser, opening page with the contact form, filling contact data and submitting it, checking that email is received or was added to a fake queue.
    (Note: most of the time CI tool cannot itself run Smoke or Functional tests as there is a need to have visual APIs in the operating system, which provides ability for example browsers to be installed or other GUI apps. For these purposes special test apps are built with tools  like SelenuimHQ and are placed on a Dev server (or other suitable place with support of reach GUI), while CI tool can be installed in the cloud or a small linux server without rich GUI support. Then CI tool requests from the Smoke/Functional test app to run these tests.
  • finally we can guaranty that the app is almost fully functional on the dev server, otherwise if any of the previous steps are failed the responsible person will be notified about the problem.


Then we have the following steps for the application:


Dev environment

  • holds automatically tested application;

Test environment

  • if you have testers in your team this place is for them;
    the app is tested by testers in isolation from other steps
  • tester makes subtle tests as the app is already tested automatically;
    if there is a bug, then one of the functional test is missing, which should be added by developer in the fix process
  • a CI manager can manually request CI tool to propagate the app to Test server(s) after Dev phase
  • another approach is to automatically propagate the app from Dev phase to Test phase by CI tool when you have versioned app running simultaneously or several Test servers, so that testers will not be interrupted while they are providing tests

Acceptance (also known as UAT/User Acceptance Test) environment
  • holds application that waits for a testing from a stakeholder/ a customer;
  • if there is no tester in your team you can propagate (manually or automatically) the app from Dev to UAT phase with CI tool
  • A stakeholder makes tests and whether accepts or rejects the changes
Note: environment can be presented by different amount of servers and machines. For example Dev, Test and UAT environment can be hold on a one server, or in other case Test environment can be hold on N-servers.



STAGING

Although DTAP model is obviously clear there is another step called Staging. I've phased a lot of confusion with Staging step among developers as there is no single definition for it.
Some people argue that Staging is another name for UAT step.  Other people go further and combine Test step with UAT step and call this combination as Staging. Any of this is definitely valid while you have one concept across your whole team.
Nevertheless personally I prefer to have the notion of Staging as a pre-production step. What does it mean? Let us look at the image from Steve's blog post about staging in Azure.



Staging is an additional step before publishing an app to a production environment.

Staging

  • is propagated from UAT phase after a stakeholder approval
  • holds the app ready to go live in production;
  • has connection settings (database, email server, and so on) the same as in production 
  • CI tool runs Smoke tests to verify critical functionality
  • if needed a stakeholder or a developer can manually verify some special points
After all theses steps are done Staging can be simply swapped with a Production environment, for example for a website by changing routes in a hosting tool (IIS, Nginx, Apache). Thus staging becomes production, while production becomes stale staging, which can be removed or used as a backup. This approach is known as Blue Green deployment.

Saturday, September 3, 2016

Custom unstructured data types and types' reuse


In 1972 three well-known computer scientists wrote a book Structured Programming, where they mentioned about custom unstructured types:
All structured data must in the last analysis be built up from unstructured components, belonging to a primitive or unstructured types. Some of these unstructured types (for example, reals and integers) may be taken as given by programming language or the hardware of the computer. Although these primitive types are theoretically adequate for all purposes, here are strong practical reasons for encouraging a programmer to define his own unstructured types, both to clarify his intentions about the potential range of values of a variable, and the interpretation of each such value; and to permit subsequent design of an efficient representation.
(...) Such a type is said to be an enumeration, and we suggest a standard notation for the name of the type and associating a name with each of its alternative values.
type suit = (club, diamond, heart, spade);
          (...)
type year = 1900 .. 1960; 
type coordinate = 0 .. 1023;
(...) We therefore introduce the convention that a .. b stands for the inline range of values between a and b inclusive. This is known as subrange of the type to which a and b belong, (...)
Ole-Johan Dahl, Edsger W. Dijkstra, C.A.R. Hoare, Structured Programming, A.P.I.C. Studies in Data Processing, No. 8, 1972, p.97

Some of the languages indeed support subrange types, e.g. Ada and Dephi. Nevertheless, modern popular languages like Java and C# do not support unstructured custom subrange types.

In addition to this there is a huge misconception about a type declaration and its actual meaning. For instance, an Array accepts an Integer as index argument with a range [-2^31, 2^31], so we declare support for -1,-2, ... index values. At the same time only non-negative integers are accepted, i.e. [0, 2^31]. For an honest and clear code it should be an Array[NonnegativeInteger].

Moreover, commonly used structured and unstructured types does not limit to numbers. Nowadays an email is always presented as String:
function SendEmail(String email, String emailBody){ ... }

but we actually mean
function SendEmail(EmailAddress email, String emailBody){ ... }

Making an assertion that an instance of the class/structure EmailAddress is always valid we do not need to check the string every time with IsEmail() helper or an attribute of DataAnnotations. It can have a function EmailAddress TryConvert(String email) for convenient conversion from string.

Other common places for apparent improvements:

  • Name checking of a String for a Firstname and a Lastname across whole solution with the same restrictions, probably with no more than 256 special characters and at least 1 character, can be changed to what a programmer really means: class/structure Name.
  • class Description with common rules for contact messages, order's comments, feedback messages, etc.
  • Measures: degrees, coordinates, weight, etc.
  • Date and time Integers up to 2147483648 (2^31) for a year, a month, a day, an hour and a minute look inconvenient for real use and most of the systems after all will throw an exception by taking large numbers for these types.
  • Money There is no a banknote with minus $100 value, but there can be a notion of 100$ debt.

With the help of Design by Contracts most of the checks can be done during compilation time.
For interoperability with other systems custom types should be built up from primitive and simple types, like integers and strings, and be convertible from these types.

Sunday, June 19, 2016

Power of the Market

At first sight this post seems to have nothing in common with IT. On the contrary, IT is a part of the following idea: the less people and enterprises are controlled by a bureau or a government, the more desirable or advantageous position in financial terms they have.

This concept was presented in 1980 by Doc. Milton Friedman in his TV series "Free to choose". He is an economist, winner of the Nobel Prize (so called the Nobel Prize for economic achievements). In his first episode Friedman talks about "The power of the market". Here is the short description of the episode:

Some may be appalled by his ideas, others can be enthusiastic about them. In the early years of the foundation of the USA settlers were free to pursue their own objectives. America was a land of opportunities. People came here from all over the world to settle down in a new place. There were no permits, no tariffs, no red tape to restrict them, and many people thrived on a new market.


To show modern example of a free market Doc. Friedman visits Hong Kong. There are many overcrowded, sticky, hot factories and shops. It might be seen as an appalled place to work, however, for the workers it is the best place they can find at their current position. If they do not agree they can always change their job, nobody forces them to work at these factories. They know that these conditions are not forever, they will find something better after learning new skills. Hong Kong is a special economic zone, there is no duties on imports or exports. The goods are coming to the port from all over the world. Thousands of people try to escape from Communist China, cross the border and come to Hong Kong for the real opportunities, better wages and freedom to speak, freedom to write, freedom to buy what they want. The number of permits to visit Hong Kong is restricted for the Chinese, and consequently many of them risk their lives and die in attempt to get a better life.

Milton states that from the historical point of view "The freer the system has been, the better off the ordinary people have been".

As an example of voluntary collaboration Friedman takes a lead pencil and states that there is not a single person in the world who can make the same pencil. Remarkable? Just watch how he proves this statement in the first episode.

In the second part of the video the leading businessmen (including the Motorola CEO) and the leading politicians (including a Congressman and a Governor of Delaware) discuss Friedman's ideas.

I genuinely recommend to watch this video. Enjoy it!