How To Make Back Up Of Db Smaller In Ms Sql

 

Hello everybody,

today I want to document one hack that preserved me plenty of space on my hard drive.

Recently I've tried to make back up of production database and was shocked to see that it had almost 200 Gb on my hard drive.  So it made me wonder how can I have smaller backups. 

And here is the solution.

  1. In Microsoft SQL Server Management Studio click on database, and choose new query
  2. enter there following command: sp_configure 'backup compression default', 1
  3. then this: reconfigure WITH OVERRIDE;

After such manipulations I've got back up that had only 27 Gb.

No Comments

 

Add a Comment
 

 

Some Digging In Tables Of Acumatica

 

Hello everybody,

today I want to document one useful sql query that can be beneficial for cases if you need to dig in Acumatica tables, and need quickly to find type of some particular column.

Here it is:

select * from information_schema.columns where table_name = 'SOLine' and COLUMN_NAME like '%OrderQty%'

that sql will let you know all information about column OrderQty.

No Comments

Add a Comment
 

 

Types Of Learning In Ai

 

Hello everybody,

today I want to make a short notice on question that I often receive: what kinds of learning exists in Machine Learning. I want to provide simple answer:

  1. Learning with teacher: questions and answers.
  2. Learning with teacher: just questions
  3. Partial learning: questions, and some of them with answers
  4. Active learning: at which object you'll get an answer

I suppose maybe some variations of this also exists, but as usually ML in one or another way manipulates with those four. 

Consider example of clusterization. You have some data set of values. And you need somehow to group them or in other words find groups of similar objects. This task has two problems: nobody know number of groups. And second one we don't know real clusters. Real clusters that we want to distinguish. That provides the challenge that you by yourself can't evaluate answer from ML algorithm. While reading this example you may wonder who may need such task? I give you few examples:

  • Segmentation of users for mobile network operator or for some e-shop
  • Search for similar users in social networks
  • Serch in genome for similar profiles of expression

Second example can be task of visualization of some group. Imagine that you have some set of data, and want not just to know how much groups you have, but want to have some visual representation of it. 

Third example is search for anomalies. Consider the following scenario. You have successfull web site that has many visitors: tens of thousands. And among them you can have 1 - 2 hackers. Or don't have hackers at all. How to detect them? This is also learning without teacher.

No Comments

 

Add a Comment
 

 

Unit Test Acumatica Pxgraph

 

Hello everybody,

today I want to make another description of how to cover with Unit Tests Graphs in Acumatica. 

First of all I want to say that Acumatica controllers or as Acumatica names them graphs do not have any way to inject any dependency from interface. In such case it can be useful idea to use Microsoft Fakes library. 

So in order to unit test Acumatica code you will have a need to make mix of Acumatica code with Microsoft shims. Imagine that you have following graph declaration:

public class PAllocs : PXGraph<PaymentsAllocation>

and somewhere in your graph you have method like this:

        [PXButton(Tooltip = "Saves values from grid")]
        [PXUIField(DisplayName = "Save")]
        public virtual IEnumerable Save1(PXAdapter adapter)
        {
            var inputtedPoOrders = this.VendorOrders.Select()
            .ToList().Where(a => a.GetItem<POOrder>().GetExtension<POOrderExt>().AllocatedAmount > 0
            ||
                                    a.GetItem<POOrder>().GetExtension<POOrderExt>().AllocatedAmount < 0
            ).ToList();
 
            string currentDif = this.ReportItemFilter.Current.DifAmt.ToString();
 
            var apPayment = this.ReleasedPayments.Current;
            
            if (apPayment.CuryOrigDocAmt != ReportItemFilter.Current.TargetAmt)
            {
                VendorFilter.Ask("""Choose another item or modify po ords in bottom grid",
                    "Please choose another check or modify Amounts in bottom grid",
                    MessageButtons.OK, MessageIcon.Error);
                return adapter.Get();
            }
 
 
            if (inputtedPoOrders.Count == 0 || currentDif != "0.0000")
            {
                var vfRow = this.VendorFilter.Current;
                this.VendorFilter.Ask(vfRow, "Input at least one row""You should enter at least one Allocation payment, and Diff should be 0.0000",
                    MessageButtons.OK, MessageIcon.Error);
                return adapter.Get();
            }
        }

how to unit test it with Microsoft fakes?

Preparation

As I already mentioned in one of my articles, you'll need to prepare your test solution for creation of needed graphs. First step will be to make app.config in your test solution.

Below goes app.config that you'll need to add to your solution with tests. 

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <sectionGroup name="system.web" type="System.Web.Configuration.SystemWebSectionGroup, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
      <section name="pxaccess" type="PX.Data.PXAccessSection, PX.Data" />
      <section name="pxdatabase" type="PX.Data.PXDatabaseSection, PX.Data" />
      <section name="pxtrace" type="PX.Data.PXTraceSection, PX.Data" />
      <section name="pxtranslate" type="PX.Data.PXTranslationSection, PX.Data" />
      <section name="basicAuth" type="PX.Export.Authentication.BasicAuthenticationSection, PX.Export" />
      <section name="formsAuth" type="PX.Export.Authentication.FormsAuthenticationSection, PX.Export" />
      <section name="multiAuth" type="PX.Export.Authentication.AuthenticationManagerSection, PX.Export" />
      <section name="externalAuth" type="PX.Export.Authentication.ExternalAuthenticationSection, PX.Export" />
      <section name="webDAV" type="PX.Export.WebDAV.WebDAVSection, PX.Export" />
      <section name="activeDirectory" type="PX.Data.Access.ActiveDirectorySection, PX.Data" />
      <section name="attachments" type="PX.Data.EP.DynamicAttachmentSection, PX.Data" />
      <section name="odata" type="PX.Api.OData.ODataConfigurationSection, PX.Api.OData" />
      <section name="fullTrustAssemblies" type="System.Web.Configuration.FullTrustAssembliesSection, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" allowDefinition="MachineToApplication" />
    </sectionGroup>
    <section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
    <section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
  </configSections>
  <connectionStrings>
    <remove name="ProjectX" />
    <add name="ProjectX" providerName="System.Data.SqlClient" connectionString="Data Source=DESKTOP-0EC1M8R;Initial Catalog=MohawkDB;Integrated Security=False;User ID=sa;Password=123" />
  </connectionStrings>
  <location inheritInChildApplications="false">
    <system.web>
      <machineKey validationKey="187C46E676C11D108F5AB1CEAB16A4CABFB1DEF8A77B54045FBAE8556E015744C6A5099963847BD36D3B673752455ABBC4528CF24A0F2EE3F1B3AC49397C0F51" decryptionKey="2134B0CA7E59C637F365F74FA10727B6C2BDC2E9D26ADE2A" validation="SHA1" />
      <trust level="Full" originUrl="" />
      <fullTrustAssemblies />
      <pxdatabase defaultProvider="PXSqlDatabaseProvider">
        <providers>
          <remove name="PXSqlDatabaseProvider" />
          <add name="PXSqlDatabaseProvider" type="PX.Data.PXSqlDatabaseProvider, PX.Data" connectionStringName="ProjectX" companyID="" secureCompanyID="False" />
        </providers>
      </pxdatabase>
      <pxaccess defaultProvider="PXDatabaseAccessProvider">
        <providers>
          <remove name="PXDatabaseAccessProvider" />
          <add name="PXDatabaseAccessProvider" type="PX.Data.PXDBFeatureAccessProvider, PX.Data" applicationName="/" administratorRole="Administrator" />
        </providers>
      </pxaccess>
      <membership defaultProvider="PXActiveDirectorySyncMembershipProvider">
        <providers>
          <remove name="PXActiveDirectorySyncMembershipProvider" />
          <remove name="MySQLMembershipProvider" />
          <add name="PXActiveDirectorySyncMembershipProvider" type="PX.Data.PXActiveDirectorySyncMembershipProvider, PX.Data" mainProviderType="PX.Data.PXDatabaseMembershipProvider" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" applicationName="/" requiresUniqueEmail="false" passwordFormat="Clear" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="1" passwordAttemptWindow="10" passwordStrengthRegularExpression="" />
        </providers>
      </membership>
      <siteMap enabled="true" defaultProvider="PXWizardSiteMapProvider">
        <providers>
          <remove name="PXWikiProvider" />
          <remove name="PXWizardSiteMapProvider" />
          <remove name="PXDatabaseSiteMapProvider" />
          <remove name="MySqlSiteMapProvider" />
          <!-- that can be planted into machine.config by mysql .net connector installation -->
          <remove name="PXOuterSiteMapProvider" />
          <add name="PXDatabaseSiteMapProvider" type="PX.Data.PXDatabaseSiteMapProvider, PX.Data" securityTrimmingEnabled="true" table="PX.SM.SiteMap" />
          <add name="PXWizardSiteMapProvider" type="PX.Objects.WZ.PXWizardSiteMapProvider, PX.Objects" securityTrimmingEnabled="true" />
          <add name="PXWikiProvider" type="PX.Data.PXWikiProvider, PX.Data" securityTrimmingEnabled="true" />
        </providers>
      </siteMap>
    </system.web>
  </location>
</configuration>

so many details in app.config are needed because with shims you can't modify everything in your graph. 

Next goes code, that allows you to create any graph in case if your app.config is ready:

public class GraphCreator<Twhere T : PXGraphnew()
{
    public static T CreateInstance()
    {
        string userName = "admin";
        using (var pxLoginScope = new PXLoginScope(userName, new string[0]))
        {
            var membershipUser = (MembershipUsernull;
 
            membershipUser = Membership.GetUser(pxLoginScope.UserName);
            if (membershipUser != null)
            {
                pxLoginScope.UserName = membershipUser.UserName;
                userName = PXContext.PXIdentity.User.Identity.Name;
                if (pxLoginScope.CompanyName != null)
                {
                    string[] rolesForUser = System.Web.Security.Roles.GetRolesForUser(pxLoginScope.UserName);
                    if (rolesForUser == null || rolesForUser.Length == 0)
                        throw new PXException("You are not allowed to login to the company {0}."new object[1]
                        {
                            (object) pxLoginScope.CompanyName
                        });
                    else if (
                        !Enumerable.Contains<string>((IEnumerable<string>) PXDatabase.AvailableCompanies,
                            pxLoginScope.CompanyName))
                        throw new PXException("You are not allowed to login to the company {0}."new object[1]
                        {
                            (object) pxLoginScope.CompanyName
                        });
                }
                PXLogin.SetBranchID(pxLoginScope.UserName, pxLoginScope.CompanyName, pxLoginScope.Branch);
               
            }
        }
        var gr = PXGraph.CreateInstance<T>();
        return gr;
    }
}

With such preparation you can try to shim and unit test your code. While I should warn you it will not be an easy job.

2 Comments

  • Jonathan said

    Question Yuriy, are you able to integrate your Unit test into a CI/CD tool like TeamCity or something of that nature with this approach?

  • docotor said

    Hi Jonathan, no I didn't try to integrate it with CI/CD. But I suppose it can be great mental exercise. Also I think this is achievable task

Add a Comment
 

 

Stubs Vs Shims Difference

 

Hello everybody,

today I want to mention difference between two kinds of testing. Shim vs Stub. 

Take a look at the following code sample:

// Stub sample
public interface IDependency
{
    void SomeMethod();
}
 
// Take note that class TestTarget allows to inject 
// interface IDependency
 
public class TestTarget
{
    private IDependency _dependency { getset; }
    public TestTarget(IDependency dependency)
    {
        _dependency = dependency;
    }
 
    public void TestMethod()
    {
        _dependency.SomeMethod();
        
    }
}
 
// Shim sample. Take note that class ShimTarget doesn't allow to inject 
// interface as dependency
public class Dep : IDependency
{
    public void SomeMethod()
    {
        
    }
}
 
public class ShimTarget
{
 
    public void TestMethod()
    {
        Dep d = new Dep();
        d.SomeMethod();
    }
}

Take note that class ShimTarget has dependency from class Dep. And you will not be able to mock this dependency with any mocking framework. But class TestTarget allows you to use plenty of mocking frameworks in order to unit test. And if you'll see class similar to ShimTarget then know, you'll most probably need Shims from Microsoft Fakes in order to unit test it. 

No Comments

Add a Comment
 

 

Types Of Screens In Acumatica

 

Hello everybody,

today  I want to describe one more feature of Acumatica: types of screens in Acumatica. In Acumatica majority of screens are the following:

  1. Data Entry pages
  2. Maintenance pages
  3. Inquiery pages
  4. Setup pages
  5. Processing pages
  6. Reports.

Now let's talk in more details about those screens:

Data entry pages

As usually data entry pages located at following icon in the red rectangle.

These pages are the most frequently used pages of the Acumatica. Typically, data entry pages are used for the input of business documents, such as sales orders in a distribution module.

Maintenance pages

As usually maintenance pages located at following icon in the red rectangle.

Maintenance pages are those intended for data entry but used more rarely than the main data entry pages. Typically, maintenance pages are helper pages on which you input data that is used on the data entry and processing pages of the Acumatica. For instance, because you specify a customer for each sales order, you need a page for entering and editing customers. The most appropriate way to classify the customer edit page depends on how frequently the page is used. Because the customer is a helper entity for sales orders, you can consider Customers as maintenance page.

Inquiry pages

As usually inquiry pages located at following icon in the red rectangle.

By using inquiry pages, the user can view data narrowed by the selection criteria they have specified; these pages are similar to reports but designed for online viewing. Typically, an inquiry page consists of a form that provides selection parameters and a grid that lists the retrieved data.

Setup pages

As usually setup pages located at following icon in the red rectangle.

Setup pages

As usually setup pages located at following icon in the red rectangle.

Setup pages provide the configuration parameters for the Acumatica. On every setup page, you set up the consistent configuration for particular functionality of the Acumatica. A set of configuration parameters is stored in a single record in the corresponding setup table of the database. By using a setup page, a user can edit this record: for example, enable or disable a feature, specify default values, or set the initial numbers of documents. Setup pages are used very rarely, usually in the very beginning of application implementation and use.

Processing pages

As usually processing pages located at following icon in the red rectangle

On a processing page, users can invoke an operation on multiple selected records at once. For instance, user need to cancel orders according to some criteria. He has two options: for each order navigate to Sales Orders screen, open proper sales order, press at Actions -> Cancel Order. Another option is to use processing screen. Processing page can automate this process.

User can check (checkboxes in red rectangle) sales orders for cancel, and then click on process button (in blue rectangle there are two buttons: PROCESS and PROCESS ALL).

PROCESS ALL will automatically check all checkboxes and cancel them.

Reports

As usually reports pages located at following icon in the red rectangle

In Acumatica user can create reports and design printable forms of documents.

In Acumatica user can create reports and design printable forms of documents.

Now you have needed knowledge that you can use in order to write super detailed task for your Acumatica developer.

No Comments

Add a Comment
 

 

Types Of Controls In Acumatica

 

Hello everybody,

today I want to describe with some screenshots kind of controls that you can get from Acumatica developer like me or any other Acumatica programmer.

Main purpose of this blog post is the following. Imagine, that you want to write super detailed instructions for Acumatica developers. After reading this article I suppose you'll be able to write instructions to them with any kind of detalization. Or even super detailed.

First of all, I want to point that as usually Acumatica pages consists of two parts: top and bottom. Top part often is named summary, and bottom is considered to be detalization of top. Take a look at following screenshot:

At presented screeshot red part presents summary, and blue part presents details. Also you can notice that details part can contain some tabs, but about them I'll mention later. 

Now let's see other types of controls:

Selector

It can look like this:

In selector Acumatica developer can customize columns that will be displayed. Also list in selector can be changable. In the presented screenshot we can change order of columns, names and content. As usually selectors are used for displaying data from some table in db.  Also selectors can be in used in the grid. One more feature of selectors there are used for navigating between different records. On the screen AR301000 (Invoices and Memos) selector used for navigate between different invoices. Take note also that with selector you can search for needed record. One more feature that often is added to selectors is Autonumbering. It works according to the following scenario. Imagine that needs to create some new entity. In such case he opens needed form, and start to enter values for it. In the field for selector while record is not persisted in database it will be written <New>. And after persisitng to database <New> will be replaced with some generated value. Programmers can generate for you any numbering sequence that follow any kind of logic.

Take a look at screenshot of another selector:

DateTime

As name suggests you can use this kind of controls for entering date time values. It can look like this:

or like this:

and for selecting time it can look like this: 

Dropdown list. 

Some times there is a need to have fixed set of values in combo box. In html environment it is often named select. 

Drop down list can look like this: 

Currency input

For USA customers it is not very needed feature, but for out USA customers currency input is very useful control. It has two presentations: 

and if you click on it you'll see following window: 

Presented screenshot have not many benefits because it has conversion between USD to USD, but for some international compaines it meant a lot. BTW, it is very simple to integrate Acumatica with any currency exchange providers. For example I've created integration with Ukrainian National bank or Belorussian National bank. 

Textbox

Probably the most used and needed control. It can be displayed like this:

Also Acumatica allows to create some filtering for textbox. One of the examples is allow to enter into textbox only numbers. Additional detail. It is possible to program interaction between controls. Most common example display enter in one column some number, enter in another column percentage, press enter and third column show multiplication of first column on second column.

Tabs

In case if you have meny details parts, and don't want to create many screens you can use tabs. Tabs in Acumatica look like this:

Navigation and persistance buttons

Acumatica also has mechanism for navigating via records with navigation buttons. Navigation buttons look like this:

Besides navigation buttons at presented screenshot there are buttons Save, Cancel, Insert, Copy/Paste.

Customizing grid

Grid in Acumatica can have different sets of buttons. Below goes list of different standard options: 

  • Add, Delete, Fit to Screen, and Export buttons to the toolbar. This set is typically used for a grid on a simple edit page that consists of the single grid.
  • Refresh, Add, Delete, Fit to Screen, and Export buttons to the toolbar. This set is typically used for a grid that displays the detail data on a master-detail page
  • Refresh, Fit to Screen, and Export buttons to the toolbar. This set is typically used for grids on inquiry and processing pages
  • Refresh and Fit to Screen buttons to the toolbar
  • Without toolbar.

And some screenshots:

And also Acumatica allows to customize grid with your custom buttons and even with enabling/disabling them depending from condition.

Take a look at following screenshot:

At presented screenshot button Load Documents is enabled, and button View document is disabled. 

Action buttons

Also you can add custom buttons to the top of page. Take a look at another screenshot:

with red rectangle I've highlighted button Release. It was added with some C# code. 

Besides adding just buttons, Acumatica allows to add buttons with menu. It can look like this:

At presented screenshot fragment Reports is button, with three menu items: Invenotry Edit Details, Inventory Register Detailed, Inventory Item Labels.

No Comments

Add a Comment
 

 

How To Override Action Create At Form So301000 Or Sales Orders

 

Hello everybody,

today I want to document one important piece of functionality in Acumatica. Sales order screen. This is very important screen and has many staff. One of the important screens in it is "Sales orders"  screen. From prospective of understanding Acumatica source code of method "Actions" has plenty of food for mind.

Take a look at it's declaration:

                public PXAction<SOOrder> action;
[PXUIField(DisplayName = "Actions", MapEnableRights = PXCacheRights.Select)] [PXButton] protected virtual IEnumerable Action(PXAdapter adapter, [PXInt] [PXIntList(new int[] { 1, 2, 3, 4, 5 }, new string[] { "Create Shipment""Apply Assignment Rules",                 "Create Invoice""Post Invoice to IN""Create Purchase Order" })] int? actionID, [PXDate] DateTime? shipDate, [PXSelector(typeof(INSite.siteCD))] string siteCD, [SOOperation.List] string operation, [PXString()] string ActionName ) {

}

From this declaration alone you can see that in order to have a button with menu items you need to 

  1. Declare member of type PXAction with lower case name ( in case of "Sales order" screen member is named action )
  2. Create method with Uppser case name ( in case of "Sales order" screen method is named Action )
  3. Besides passing PXAdatapter into method pass also in method integer which is attributted with PXInt, PXIntList
  4. Other attributes and their purpose you can figure out by yourself 

Here I want to leave piece of code that allows you to append this method with your own piece of functionality:

public delegate IEnumerable ActionDelegate(PXAdapter adapter, Nullable<Int32> actionID, Nullable<DateTime> shipDate,
   String siteCD, String operation, String ActionDelegateName);
 
[PXOverride]
public IEnumerable Action(PXAdapter adapter, Nullable<Int32> actionID, Nullable<DateTime> shipDate, String siteCD,
    String operation, String ActionName, ActionDelegate baseMethod)
{
    var currentSoOrder = Base.CurrentDocument.Current;
//and other code }

If to summarize, you'll need:

  1. Declare delegate
  2. Declare action

2 Comments

  • Prathyusha said

    I am doing a customization where I have to override 'create shipment' action and change the locationID when saving into SOShipLine table. Can you please let me know how to do it?

  • docotor said

    Hi Prathyusha, I've wrote you an email. Please describe a bit better what you need

Add a Comment
 

 

My Thoughts After Start Of First Indiegogo Campaign

 

Here I want to describe how I felt before starting Indiegogo campaign during it's execution and few minutes after starting Indiegogo campaign.

Initially I want to describe road map to this campaign. I was and still is a happy person whose main job is integration of different enterprise systems. I like such kind of activities because it helps to speed up life inside of company of any size. Imagine that with help of software inside of some small company ( 30 people ) can save around 5 minutes of time daily. Then in one month this company can save 22 * 5 * 30 = 3300 minutes or 55 working hours. It means faster delivery of product, or faster producing of product or faster salary receive or whatever else. Such thoughts always give me some inner satisfaction when I need to write code that improves lives.

Then one day I've meet one guy whose wife died around one year before our meeting. I liked his life experience, his life attitude just some sadness in his voice disturbed me. Later I've discovered that his wife died of skin cancer. And you know, why she died? It wasn't because they lived in third world country. It wasn't because they didn't have medical insurance. At that point of life I started to wonder is it possible to make improvement not just for some companies, but for humankind in general. As to say what is value of fast job, if person live shorter amount of years. Later I had visit to Israel and found that in this country cancer skin rate has quite high percentage.

From my University course I knew that for image classification it is good idea to use neural networks. In order to refresh my knowledge on neural networks I've took two courses on Coursera. One from Geoffrey Hinton and other one from Andre Ng on machine learning and got feeling that I can do device that can make such classification task.

Another question mark that I have for now is how to make such product and stay alive. With full time job it is not an easy assignment to accomplish such product with good quality results. While surfing Internet I heard about Kikstarter and Indiegogo. For me both of those platforms become something like scary points. You may wonder why scary points? I'm scared of disappointment. But not disappointment that I can't make such device as described in campaign, but scared that something that I think is needed to others is really perceived as needed by other people. Before publishing this campaign I decided to ask other people, do they consider some device like this as needed to them. And majority of my friends told me that such kind of device is needed. So, I decided to create campaign at Indiegogo. And now I'm worried about is something that I consider as needed will be perceived as needed by other people. With such thoughts I think I know why some people ( similar to me ) never create any company or startup. They can be afraid of disappointment that something that they consider as important is not important for others.

I even started believe that some mathematicians avoid companies of other people in order not to become disappointed. Disappointed of what? Of fact that math is very interesting topic for mathematician, but not for humankind in general, even if it depends from it greatly.

So, if you consider such device as needed, you can support it via following link.

No Comments

 

Add a Comment
 

Aws Product Categories

 

Hello everybody,

today I want to document few main features of AWS. Below I want to mention AWS Product Categories:

  1. Compute services. Provide you with virtual machines
  2. Storage services. Raw block of content.
  3. Database services. Organized in some way data in organized chunks.
  4. Networking services. Provide with network assets.
  5. Messaging services. Communication between systems.
  6. Content delivery services - cached location for frequently accessed content. 
  7. Deployment and management - allows to pack, secure, monitor AWS apps.

Next goes question, how developer can interact with AWS? As always in two ways: visual tools or through API.

API in turn can be divided into two categories: SOAP/REST/Query or via SDK.

Tools for AWS Developers

  1. Management console - UI at web site
  2. SDK and development centers for Android, iOS, Java, .Net, PHP, Ruby
  3. Amazon Machine Images (AMIs) that come pre-loaded with application environments
  4. Community forums
  5. Documentation

No Comments

Add a Comment