Showing posts with label ubuntu. Show all posts
Showing posts with label ubuntu. Show all posts

Friday, September 21, 2018

Consuming Magento 1.x SOAP v2 API with .NET Core 2.x

As we know Magento 1.x offers by default different ways to consume their API: 
  1. SOAP v1 
  2. SOAP v2 
  3. XML-RPC 
  4. REST 
 In this case we are going to make a console app in .NET Core for consuming SOAP v2. 


Source code of this example can be found in Github.


Please:
Also check the problem list at the bottom of this blog. In my case I had running Magento in my Ubuntu using Docker.
Because I will demonstrate in my local environment, ALL the requests will in HTTP only. 
Be sure you don't have SSL with self signed certificate because it won't work.


Let's go! 

Prerequisites:

1. Be sure that in Magento the setting in: 
       Configuration > Services > Magento Core API
    Option WS-I Compliance is set to "Yes".

2. Be sure to have to have an API user with access to the resource to consume. 
        System > Web Services > SOAP/XML-RPC 




I will skip the part of installing .Net Core and Visual Studio Code because it depends on your system.



Hands on!

1. Create the .Net Core console app called mageSoap.
     a. Let's move to our Workspace and run this command to create the console app
dotnet new console --output mageSoap








    b. Move to the new project a open it with  Visual Studio Code.
cd mageSoap
code .



2. Let's add some dependencies to the project.
    a. Update your mageSoap.csproj like this.
<?xml version="1.0" encoding="utf-8"?>
<project sdk="Microsoft.NET.Sdk">
  <propertygroup>
    <outputtype>Exe</outputtype>
    <targetframework>netcoreapp2.1</targetframework>
  </propertygroup>
  <itemgroup>
    <dotnetclitoolreference include="dotnet-svcutil" version="1.0.3">
  </dotnetclitoolreference></itemgroup>
</project>
    
    b. Restore the project.
dotnet restore


3. Use the Microsoft WCF dotnet-svcutil tool to generate all the classes.
    a. Check that you can consume the service in Magento. 
        Go to :
            http://localhost.com/index.php/api/v2_soap/index/?wsdl=1
        If you got the XML everything is correct.

        Next, search in the XML for node "soap:address location" and check the link.
        It must be something like this:
              http://localhost.com/index.php/api/v2_soap/index/
        Follow that link and check if you don't have any error like:
             SOAP-ERROR: Parsing WSDL: Couldn't load from ...
        If so, go to the Problems section.

    b. Run this command from the terminal
dotnet svcutil  -edb -n "*,mageSoap.ServiceReference" http://localhost.com/index.php/api/v2_soap/index/\?wsdl\=1



   c. This will do two things:
        c.1- Create a folder ServiceReference1 with the file Reference.cs


        c.2- Update your mageSoap.csproj adding more dependencies.

<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <DotNetCliToolReference Include="dotnet-svcutil" Version="1.0.3" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="System.ServiceModel.Duplex" Version="4.4.*" />
    <PackageReference Include="System.ServiceModel.Http" Version="4.4.*" />
    <PackageReference Include="System.ServiceModel.NetTcp" Version="4.4.*" />
    <PackageReference Include="System.ServiceModel.Security" Version="4.4.*" />
  </ItemGroup>
</Project>

     c.3- Restore the project again.
dotnet restore

4. Time to play!!!
    a. Update the Program.cs with the following code:
using System;
using mageSoap.ServiceReference;

namespace mageSoap
{
    class Program
    {
        static void Main(string[] args)
        {
            Mage_Api_Model_Server_Wsi_HandlerPortTypeClient client = new Mage_Api_Model_Server_Wsi_HandlerPortTypeClient();

            //log in Magento API to get the session_id
            loginResponse session = client.loginAsync("userAPI","keyAPI").Result;
            string sessionId = session.result;
            Console.WriteLine("Session ID: " + sessionId);

            //Let's get the status from Order "100000010"
            var response = client.salesOrderInfoAsync(sessionId,"100000010").Result;
            salesOrderEntity order = response.result;
            Console.WriteLine("Status in Order: " + order.status);
        }
    }
}

5. See results
   a. Run from your terminal or F5 in Visual Studio Code
dotnet run mageSoap



6. Congrats. It's done!




Problems:
1. Problem in Magento when auto-consuming the SOAP XML.

SOAP-ERROR: Parsing WSDL: Couldn't load from ...



Solution:
This is because Magento try to auto-consume the XML from the PHP container and the container doesn't find the Web-server container in my case Nginx.
Access to the PHP container and add in the /etc/hosts file the IP of the Web-server container.

If everything is correct we should get a response as this.



References:
https://docs.microsoft.com/en-us/dotnet/core/additional-tools/dotnet-svcutil-guide
https://devdocs.magento.com/guides/m1x/api/soap/sales/salesOrder/sales_order.info.html

Sunday, November 27, 2011

Create your own Debian or Ubuntu repository and certified by your own *.gpg using Reprepo and Python



We are going to work in a Linux environment using tools like Python, Reprepro and GPG key. 

GPG key
With this we can sign our software and guarantee that we are using software from a trusted site.


Reprepro 
Powerful tool for generate  a Debian repository.

Python-pexpect Python's module for work with interactive applications.

Let's make it by step:

1- Create your own *.gpg key. 

TODO

2- Create a folder and name as packages, here we'll place all the *.deb.

mkdir /home/packages
cd /home/packages

3- Create a folder and name it as conf inside it create a file and call it distributions.

mkdir conf
gedit conf/distributions

We'll do this for distribution  lucid and the component main. Also we'll generate the Packages, Release, .gz y .bz2 files.  SignWith is the variable that says who is going to sign .


distributions file

Codename: lucid
Components: main
Architectures: i386 amd64
Description: My repository
SignWith: abelbmartinez@gmail.com
DebIndices: Packages Release . .gz .bz2

4- Make a folder and name it as repository, there we'll have our new repository.

mkdir /home/repository

5- Create a script file and name it as pycrearepo_lucid.py. Copy and paste all the code below.

pycrearepo_lucid.py file

#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
[EN]
This Script generate a DEBIAN repository using the tool 'reprepo'.
It works like this, first get all the *.deb from a folder, then obtain 
the size of all these packages, the list from all the sizes is 
ordered descendent, 'reprepro' interact more stable with 
'python-pexpect' adding packages in this way.

[ES]
Este Script genera un repositorio DEBIAN usando la herremienta 'reprepro'. 
La sintaxis es la siguiente, se obtinen todos los *.deb de una carpeta
luego se obtiene el tamaño de estos paquetes, el listado del tamaño de los
paquetes es ordenado de mayor a menor, ya que 'reprepo' trabaja junto con
'python-pexpect' más estable cuando se le adicionan los paquetes de esta manera.

Created on 04.06.2010

@requires: reprepro, python-pexpect

@author: Abel Bolaños Martínez
@contact: abelbmartinez@gmail.com

@author: Oscar Martínez Lopez 
@contact: oscar.martinez@etecsa.cu

@license: Public Domain
'''

import pexpect
import glob
import os
import time

#packages *.deb
packagesSources = "/home/packages/"
distribution = "lucid"
#repositorio
repoMirror = "/home/repository/"
#private key
gpgKeys = "/home/mirrorGPG/"
#Secret phrase from the private key
keyringPhrase = "yourSecretPhrase"


os.chdir(packagesSources)
#get all the *.deb
listPackages = glob.glob("*.deb")
dictSizePackage = dict()
#dict de {size:package}
for package in listPackages:
    dictSizePackage.update({os.path.getsize(package):package})
#sizes
sizes = dictSizePackage.keys()
#sort
sizes.sort()
#backToFront
sizes.reverse()

for size in sizes:
    time.sleep(1.5)#let's wait for 'reprepro' delete the 'lockfile'
    command = pexpect.spawn("reprepro -b . --gnupghome %s --outdir %s --ask-passphrase --waitforlock 2 --keepunusednewfiles includedeb %s %s" % (gpgKeys,repoMirror,distribution,dictSizePackage[size]))
    print " "
    print "Copying the package %s to repository." % dictSizePackage[size]
    i = command.expect(["Please enter passphrase:","Skipping inclusion of","The lock file './db/lockfile' already exists"],timeout=520) 
    if i==0:
        command.sendline(keyringPhrase) 
        print "Added to repository package %s with succeed." % dictSizePackage[size]
    if i==1:
        print 'Package already %s in the repository, not included.' % dictSizePackage[size]
    if i==2:
        print "Attention !!! : Database is locked now. Execute the Script again if the problem persist YOU must delete the file '%sdb/lockfile' and execute the Script again" % packagesSources

Variables packagesSources, distribution, repoMirror, gpgKeys, keyringPhrase must be filled.

  • packagesSources: path to the packages.
  • distribution: distribution to generate.
  • repoMirror: the new repository path.
  • gpgKeys: path to the GPG key for sign the packages.
  • keyringPhrase: secret key phrase.

6- Completed!
7- At least you must create a package for share your public GPG key. Here you can learn how to make a simple deb package.
8- Publish it to the web and test it.

Monday, August 29, 2011

Creating basic *.deb packages for Debian or Ubuntu

Basic *.deb packages are easy to build, but it can turn more complicated due to the task it should do after or before the install process.

This is a simple  *.deb package.

Name-package_version_architecture/
|
|_DEBIAN/
|      |_control
|
|_Folders that contain the program from the root system/

The folder called DEBIAN is the most important, due to inside it we'll place the scripts for the installation. In this example we only use the control file, which is mandatory in a package.

Let's make this example. Let's say we have this little script called myPC.sh and we want to build it as a package.

Follow this steps:

1.  Make a folder in any place and call it myPC, inside create a folder like this myPC_0.1_all where myPC is the name of the package, 0.1 is the version and all is the architecture, in this example we use all because it doesn't matter if it is i386 or amd64. And the use of the underline(_) is for join the name.

2.  Inside myPC_0.1_all create a folder named as DEBIAN and inside it create a file called control.
Write this in the control file.

Package: myPC
Version: 0.1
Section: MyPrograms
Priority: optional 
Maintainer: Abel Bolaños Martínez <abelbmartinez@gmail.com>
Architecture: all 
Description: My first package
This program show my system name
.
I did it by myself.

The control file has a lot of field but for now we use only these. As you can appreciate we can write in the Description field  an information of our program.

Like this: 

myPC_0.1_all/
|
|_DEBIAN/
        |_control

3.  We want that our script install in /bin folder in our system, that help us to execute the script in any place. So, go to myPC_0.1_all folder and create the bin folder. Inside bin with any text editor create a file called myPC.sh and write this:
uname -a

Save it and open a terminal and change the properties of the file so it can be executed and not modified.
Write this in the terminal:
chmod 755 myPC.sh

We should have something like this:

myPC_0.1_all/
|
|_DEBIAN/
|      |_control
|
|_bin/
     |_myPC.sh

4.  Enough, let's build our package. Open a terminal and placed in myPC folder and type:
dpkg-deb --build myPC_0.1_all/

It's done! you'll see your myPC_0.1_all.deb inside myPC folder.

Now you can install it.