Quantcast
Channel: PowerBuilder Developer Center
Viewing all 186 articles
Browse latest View live

Web Service Framework - Service Pack#1

$
0
0
Update

 

PB Classic Web Service Framework

 



     I am pleased to announce the release of my the updated(Service Pack #1) Web Service STD Foundation Classes for IIs (STD FC IIs). The updated Web Service IIs framework is solely targeted to helping PowerBuilder Classic developers, develop .Net based Web Services deployed to IIs. The new IIs based framework  - while taking advantage of RAD techniques - employes an MVC (Model, View, Controller) architecture for superior performance, flexibility and extendability. All the frameworks are free and can be downloaded from its STD Foundation Classes SourceForge project website.

     The Web Service framework while greatly improving the PB & Appeon developer's productivity also includes these types of features to help with RAD based projects:

  • Helps the PB developer to Implement "stateless" programming
  • Does DBMS transaction management automatically
  • Manages DataStores for you automatically
  • Manages DB updates for you automatically
  • Facilitates  MVC design & programming
  • Provides Encryption / Decryption servicesProvides extended numerical services (ie: And / Or / Xor / Xand / etc features to PowerScript
  • Provides Result Set generation for any data
  • Provides HTML generation for any data
  • Allows STMP eMail generation
  • and much more!


     The main update (Service Pack #1) to the STD Web Service FC's for IIs includes a new Active Directory NVUO with various methods & properties that enable the WS developer to utilize both the Active Directory client & server entities to enable common login (authentication) and role/group authorization for application functionality security using your organization's Active Directory software.


  
    The following changes were implemented in the FC's SP01 for IIs as follows:

Release 12.1.0 Initial Release ... January 12,  2014 (GA) SP01

 

 

  • Added the "nc_active_directory" NVUO  object that supports MS-Windows, Novell, etc AD Server communications

 

  • New "VE" folder that now contains all the automated framework documentation in web browser format  - Generated by VisualExpert

 

 

Regards ... Chris


PowerBuilder 15 - OData Support!

$
0
0

PowerBuilder 15 is here!  Well, almost...  It's in a "closed" beta, which means that the download is only available to registered SAP customers and employees.  The SCN link above contains a link to the registration page, and SAP is working to migrate all the former Sybase customers' accounts, and provide them the necessary "S" user ids.  In the meantime, we've been given the go-ahead to blog all we want about PB15, and I couldn't be more excited!

 

There are some great new features being planned for PB15, including the following:

 

  • Updated support for the .NET Framework v4.5
  • MSS 2012
  • Oracle 12
  • Windows 8
  • OData Support
  • Dockable Windows
  • 32 and 64 bit deployment

 

This blog post will cover one of the items listed above - the new support for the OData protocol.  In the current beta, this support only exists in the PB.Net IDE, but I've been assured that it will be available in PB Classic by the time v15 goes into General Availability.

 

What is OData?

OData is emerging as the standard for data exchange across the web.  It's essentially a REST-based web service protocol that allows a client application to invoke backend resources over standard HTTP/s.  I know that sounds a lot like SOAP/XML, but there are some key differences between SOAP/XML and REST/OData.  With SOAP, the Web Sevices Definition Language (WSDL) file defines the methods and data structures that can be invoked from an HTTP client.  The WSDL specification for a service is VERY inflexible, and the calls must be structured exactly as specified or they fail. The response payloads are formatted as tightly-structured and verbose XML that must be parsed apart on the client side.  PowerBuilder has had support for SOAP web services for many years, both as a datawindow datasource, and as a non-visual web service proxy class.  PB15 now introduces support for the OData specification as a datawindow source.

 

OData is a relatively new standard, and it provides more dynamic capabilities for querying the backend data sources.  OData has been described as "ODBC for the Web", and that's a fairly accurate analogy.  I wrote a blog post several months ago that covered OData in fairly good detail, so I won't recreate that here.

 

Creating an OData datawindow

The first step in creating a PowerBuilder datawindow that accesses an OData endpoint, is to find a valid OData endpoint!  For this blog, I'll be using a public SAP Netweaver Gateway endpoint on the SAP Developer Center.  That URL is https://sapes1.sapdevcenter.com/sap/opu/odata/sap/ZGWSAMPLE_SRV/  Note: use of the SAP Developer Center does require user registration, which can be found here.

That URL is known as the "Service Root" in OData, and it provides a quick list of all the entities that are exposed through the OData endpoint.  Accessing an entity (essentially doing a "Select * from <entityName>") is as simple as adding the entityName to the end of the service root URL.  For example, to query the SalesOrderCollection entity, change the URL to https://sapes1.sapdevcenter.com/sap/opu/odata/sap/ZGWSAMPLE_SRV/SalesOrderCollection

To retrieve a specific SalesOrder, add its primary key value in parens after the entityname.  https://sapes1.sapdevcenter.com/sap/opu/odata/sap/ZGWSAMPLE_SRV/SalesOrderCollection('0500000001')

 

 

Step 2: Fire up PB.Net and open the Database Profiles dialog.  This is shown below, and you can clearly see the new profile "ODT OData"

 

Screen Shot 2013-12-20 at 10.48.13 AM.png

 

Step 3: Make sure "ODT OData" is the selected node, then click the "New..." button.  That opens the OData Profile Setup dialog.

Give the connection a name, and paste in the Service Root URL into the "URI" field.  Since this particular OData root requires authentication, I've selected "Supply Userid and Password", and filled those values in.  There's a "Test Connection" button on the Preview tabpage.

Click OK to save the new profile.

 

Screen Shot 2013-12-20 at 11.07.25 AM.png

 

Step 4:  Connect to the new datasource, and open the Database Painter (View > Database Painter).  The OData sources behave just like regular databases. Expand the "Tables" folder to see the exposed OData entities.  Drag a table over to the Object Layout pane to examine its structure.  Right-click the table, and select Edit Data > Grid to perform a retrieve and manipulate the data.  All of this is being done through HTTP calls to REST endpoints.

 

Screen Shot 2013-12-20 at 11.22.15 AM.png

 

Build a Datawindow

At this point, since the OData entities look and feel just like regular database tables, creating an actual datawindow should be basic, "PowerBuilder 101"-level stuff.  You'll need a Solution, and a Target, and a PBL (but these should have already been created if you've gotten this far).  The only new wrinkle will be the selection of the Data Source.  The third panel of the File > New > Datawindow dialog shows the new "OData Service" datasource:

 

Screen Shot 2013-12-20 at 11.28.55 AM.png

 

One note: the SQL creation wizard in the datawindow painter allows you to paint JOINs between OData entities, but I don't recommend taking advantage of that...  At this stage of the beta, restrict your use of OData to single-table queries.

 

From this point, the OData entity looks and behaves just like a traditional SQL table or view.  The $metadata document provides all the information about column names, data types, and associations to other entities.  Creating a datawindow from here is basic PB101 material...  I just created a simple tabular datawindow on one of the OData entities, with no retrieval arguments or other filters.

 

Coding the PowerScript

 

The final step is coding the PowerScript that makes the connection to the OData resource.  This can go anywhere in your code, but it's typically found in the application or window Open event scripts.  Here's what my window Open event looks like:

 

// Profile workflowdemo
SQLCA.DBMS = "ODT"
SQLCA.AutoCommit = False
SQLCA.DBParm = "ConnectString='URI=https://sapes1.sapdevcenter.com/sap/opu/odata/IWFND/RMTSAMPLEFLIGHT/;UID={your ID};PWD={your PW}'"

connect using SQLCA;

tab_1.tabpage_1.dw_1.SetTransObject( SQLCA )
tab_1.tabpage_1.dw_1.Retrieve()

 

You now have the full power of the datawindow at your disposal, including the Update() method.  This uses the same buffer architecture to generate HTTP PUTs for INSERT statements, POSTs for UPDATE statements, and DELETEs for DELETE statements.

 

Happy Testing!

-Paul-

PowerBuilder Development on Android

$
0
0
** Hot News **

 

Appeon Mobile 2.0 For PowerBuilder / Android Development!


Round number 1 of Appeon Mobile 2.0 for Android testing has now been successfully completed and the next Beta version V2 is now available for testing today!

Beta2 is the pre-release version, which has several tweaks and functional updates based on the feedback received during the first beta. The Beta2 version is very stable and ready for you to build PowerBuilder applications on either the Web (IE 11 supported), iOS or Android platforms!

As always, Appeon welcomes and appreciates any feedback on their Beta releases. So don’t wait until the final minutes to miss out on this great opportunity to learn this leading edge technology!


New Feature Highlights



Platform features

  • The following J2EE servers are supported in Android Beta 2.0: EAServer, JBoss, JEUS,NetWeaver, WebLogic, WebSphere AS, and WebSphere CE.


API's

  • The general and mobile APIs are extended to support the Android OS and applications.


Appeon

  • Resize PBL provides resizing service to automatically adjust the UI layout to fit with the mobile screen with a few lines of scripts

 

AEM

  • Mobile UI Resizing tool is extended to support Android devices


Appeon Developer:

  • Standalone mobile app package tool that allows users to package the Android application as a standalone APK file.
  • Appeon Workspace customization and package tool allows users to customize the Appeon orkspace, and package Appeon Workspace as a standalone APK file

 

Offline Access:

  • Android applications can run as local application without needing network connection and can read/write the local SQLite and UltraLite database.
 

Training Videos

    How to install Appeon Mobile
    How to develop and configure your mobile app
    How to install the app on your mobile device

For more detailed instructions, you can go to the ‘Android Beta 2.0 Tutorials’ section in Appeon Support Center.


For new beta testers or those having any trouble logging into this system, please contact ibd@appeon.com for a new beta tester account or to reset your account. Keep in mind that if you’ve previously participated in the Appeon Mobile 1.0 Beta Program, your credentials are still valid for logging into the system.


News & Updates

For any news and updates about the Appeon beta program, please stay tuned with Appeon via the Mobile Beta Center.


Regards ... Chris

PowerBuilder Update

$
0
0

Hi Everyone - Happy New Year...although we are nearly 3 weeks into January already!

 

I took a couple of weeks off for the holidays, the longest since 2001, and had a really great break with family. My two oldest kids came home and it was nice to be back together again. 

 

Upon my return, I had hoped that I could update folks on process in place for getting folks who don't have S User IDs into the beta. Although we've tried different options, we still don't have a process that can enable access through the Service Marketplace (SMP) without the an S User ID.

 

While I realize that many of you are frustrated by this, please know that as soon as v15 is available, we will have a trial version for testing. And, being able to provide PowerBuilder 15 beta to any customer with an S User is very different from past betas at SAP.  I am excited that PowerBuilder has been able to help increase access for developers by being the first product to participate in this new model,  and we will continue to play a role in expanding access.

 

I am also excited to announce that Dave Fish will be more involved with PowerBuilder activities, and we are looking forward to working with partners and customers, rebuilding  the community, and finding ways to help PowerBuilder developers leverage the other services and products in SAP.

 

I will keep you updated as more info is available.

 

Sue Dunnell

Product Manager

PowerBuilder Beta testers - please download new license file

$
0
0

Hi Beta testers

 

You should have received an email with a link to download a new license file and a new TEA agreement at the email addressed you used to sign up for the beta.

 

As the first beta license expires today, please replace the license file to continue testing.

 

Thanks and have a great weekend

Sue

Hands-On Workshops at ISUG-TECH Conference!

Charlotte PowerBuilder Conference a Big Hit

$
0
0

The conference, held March 5-7 2014, brought over 70 participants from North America, Australia, and Europe to participate in PowerBuilder specific training and break out sessions.  Although the weather was unsettled at times, the attendees were universal in their praise of the conference content, venue, and the conference organizers. 

 

"Thank you for organizing this event" was a near universal comment.

 

Panelists.jpg

Discussion Panelists Christophe Dufourmantelle of Novalys, Armeen Mazda of Appeon, Sue Dunnell and Dave Fish of SAP

 

Panel_crowd.jpg

Panel discussion drew a large crowd.

 

More pictures are on the Charlotte PowerBuilder Conference group on Facebook

PowerBuilder Conferences: Charlotte Recap, ISUG-Tech coming up

$
0
0

It was great to see so many PowerBuilder folks in Charlotte last week for the 3 day regional user conference. I expected a large turnout from the North Carolina, South Carolina, and Georgia areas but was surprised that customers came from all over the US (Texas, Maine, New Hampshire, Oregon, Washington, Michigan...and more...) as well as Mexico, Australia, and multiple provinces in Canada!  It's more proof that PowerBuilder developers are some of the most committed and loyal out there, and for good reason - their apps work, and they're highly productive using PowerBuilder.

 

It was nice to see so many familiar faces and old friends, as well as hear about how folks are not only still actively using PowerBuilder for their existing apps, but building new applications and modules.  Dave Fish held a few sessions on PowerBuilder as well as an overview of the  River Definition Language .

 

The keynote featured Appeon CEO Armeen Mazda and customers got a close up look at how easy it is to deploy a PowerBuilder app as a native iOS or Android application. Some long time PowerBuilder folks also presented, including Buck Woolley of DW Extreme fame, and Chris Pollach

 

Customer feedback at this event was aligned with what we've been hearing through email and other forums. Top issues include PDF (i.e., SaveAsPDF,) focus on Classic PowerBuilder and moving core .NET functionality into that IDE, and a statement of direction from SAP.

 

Next month, another event, the ISUG-TECH Conference, 2014 will feature PowerBuilder as well as other SAP products, including the launch of ASE 16, and opportunities to learn about SAP's strategic HANA platform. This event will also be another multi-day conference with options for pre-con training. Looking forward to more customer interaction and feedback!


How to use .Net visual controls in PowerBuilder Classic

$
0
0

Using non-visual .Net classes in PowerBuilder Classic is somewhat straightforward.  Provided the assembly (and the classes and methods within it) have been marked as COM Visible, you can run REGASM on them to create OLE registry entries and then use the class through OLE Automation.  I have a video on the SAP D&T Academy that demonstrates the process.

 

Using Net visual controls takes a bit more work.  There is an add-in for Visual Studio Professional called the Microsoft InteropForms Toolkit that essentially puts an ActiveX wrapper around a .Net visual user object that can contain one or more visual controls.  Some observations:

 

  • The toolkit is an add-in for Visual Studio.  As a result, it will only work in the Professional or higher versions of Visual Studio.  The Express versions of VB6 Visual Studio don't support add ins.  Apparently some people have found a way around the limitation, but doing so is beyond the scope of this article.
  • The toolkit only supports the VB.net language.   If you are more comfortable with C#, there are third party utilities that extend the toolkit so that you can use C# instead.  That will not be covered in this article, but you can see Interop Forms Toolkit for C&amp;#35; - Home for one example.
  • The toolkit exposes Windows Forms controls.  However, you can add an ElementHost control to the toolkit control and then use that to host a WPF control.  Once again, that is beyond the scope of this article.

 

I have a video on the SAP D&T Academy as well that covers this technique.  This blog post will look at a different sample implementation than the one used in that video and will include the code used.

 

Note that the code used here was adapted from a CodeProject sample of a stand alone multi-page TIF viewer.  The code was converted from C# to VB.Net and then adapted to function as a single user object with methods rather that a stand alone viewer.

 

So, the first thing we're going to do is fire up Visual Studio.Net and create a new VB6 Interop UserControl.

 

newproject.PNG

Drag a PictureBox control over from the Toolbox onto the user object in the designer and then set the Dock property of the control to Fill.  Since we've only got one control in this user object, this will ensure that the PictureBox will always fill the entire contents of the user control when it's resized.

 

usercontrol.PNG

In the code editor, we're now going to declare some instance variables in the user object that we will use to track a few properties we're interested in the

"VB6 Interop Code" Region, just after the "#If COM_INTEROP_ENABLED Then" declaration.

 

 

    Private _CurrPage As Integer = 0 'defining the current page (its some sort of a counter)    Private _Opened As Boolean = False 'if an image was opened    Private _NumPages As Integer 'the number of pages in the tiff file    Private _FileName As String 'the name of the file that was opened

We want a couple of those to be read only properties as well for the control, so we add those into the "VB6 Properties" Region:

 

    Public ReadOnly Property NumberOfPages() As Integer        Get            Return _NumPages + 1        End Get    End Property    Public ReadOnly Property CurrentPageNumber() As Integer        Get            Return _CurrPage + 1        End Get    End Property

The reason that we're adding 1 to each of these values before returning it is because the mechanism that tracks the page numbers internal to the control is zero index based (the first page is page 0).  We need to adjust that before displaying it to the user who understands page numbers as one index based.

 

Finally, we're going to add some methods into the "VB6 Methods" Region, one of which is internal and the others which we'll be using from PowerBuilder to interact with the control.

 

The first method is the internal method that is used to refresh the image in the control when a TIF is first loaded or the user navigates to a different page:

 

    Private Sub RefreshImage()        Dim myBmp As Image 'a new occurrence of Image for viewing        Dim myImg As Image 'setting the selected tiff        myImg = System.Drawing.Image.FromFile(_FileName) 'setting the image from a file        _NumPages = myImg.GetFrameCount(System.Drawing.Imaging.FrameDimension.Page) - 1 'the first page is 0 so we must correct the number of pages to -1        myImg.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, _CurrPage) 'going to the selected page        myBmp = New Bitmap(myImg, PictureBox1.Width, PictureBox1.Height) 'setting the new page as an image        'Description on Bitmap(SOURCE, X,Y)        PictureBox1.Image = myBmp 'showing the page in the pictureBox1    End Sub

Recreating myImg an _NumPages each time the function is called is perhaps a bit of overkill, but I wasn't interesting in trying to refactor the code, just convert it for this sample.

 

The following function is used to pass a filename from PowerBuilder into the control so that the control will read it and display the first page:

 

    Public Sub OpenFile(ByVal FileName As String)        _FileName = FileName        _CurrPage = 0 'reseting the counter        RefreshImage() 'refreshing and showing the new file        _Opened = True 'a file was opened.    End Sub

This function is used to navigate forward one page in the TIF file:

 

    Public Sub NextPage()        If (_Opened) Then 'the button works if the file is opened. you could go with button.enabled            If (_CurrPage = _NumPages) Then 'if you have reached the last page it ends here                'the "-1" should be there for normalizing the number of pages                _CurrPage = _NumPages            Else                _CurrPage = _CurrPage + 1                RefreshImage()            End If        End If    End Sub

And finally, this function is used to navigate back one page in the TIF file:

 

    Public Sub PriorPage()        If (_opened) Then 'the button works if the file is opened. you could go with button.enabled            If (_CurrPage = 0) Then 'it stops here if you reached the bottom, the first page of the tiff                _CurrPage = 0            Else                _CurrPage = _CurrPage - 1 'if its not the first page, then go to the previous page                RefreshImage() 'refresh the image on the selected page            End If        End If    End Sub

That's a good start.  The user object could obviously be embellished.  For example, offering methods to navigate to a certain page directly, zoom in and out on the displayed image, print one or more pages of the image, etc. could all be added later.

 

Once you compile the project, Visual Studio.Net will create the registry entries that make the user object available as an ActiveX control.  Open up PowerBuilder Classic, open a window control and start to insert an OLE Control onto the window.  In the dialog that appears, select the third tab (Insert Control), and then scroll to the name of the control you created in Visual Studio.net.  In my sample, I give it the rather unimaginative name of "TiffViewerControl.TiffViewerControl"

 

insertOLEControl.PNG

 

In the PowerBuilder window, I added buttons to open a TIF file and display it in the control, to move forward one page and to move backwards one page.  I also have a static text field that display the current page number and number of pages in the document.

 

Note that the functions and properties of the user object do not display in the PowerBuilder IDE.  You end up calling them as methods and properties of the ole control object attribute.  PowerBuilder compiles that without question and only attempts to validate that the references are valid when the code is run.

 

The script in the button that opens a TIF file for display is as follows:

 

Integer li_rc
String ls_pathname, ls_filename
li_rc = GetFileOpenName ( "Select a TIFF file", ls_pathname, ls_filename, "TIF", "TIF Files (*.tif),*.tif" )
IF li_rc = 1 THEN  ole_1.Object.OpenFile ( ls_pathname )  of_displaylocation()
END IF

To move forward one page:

 

ole_1.Object.NextPage()
of_displaylocation()

To move backwards one page:

 

ole_1.Object.PriorPage()
of_displaylocation()

The of_displaylocation function called by all three scripts is the one that populates the static text field with the current and total page numbers:

 

integer  li_currpage
integer  li_numpages
li_currpage = ole_1.Object.CurrentPageNumber
li_numpages = ole_1.Object.NumberOfPages
st_location.text = "Page " + String ( li_currpage ) + " of " + String ( li_numpages )

Finally, I have some code in the resize event of the window so that the user object resizes when the window is resized.

 

ole_1.Resize ( newwidth - 150, newheight - 250 )

With that, we're done.  Run the app, load up a TIF file and start browsing through it.  For this sample, I converted the 142 page PowerBuilder ORCA manual from PDF to TIF.

 

tifviewer.PNG

 

The sample code, both for Visual Studio.Net and for PowerBuilder 12.5 Classic, is available on my Google Drive.

Access your EBFs soon - downloads.sybase.com to be decommissioned

$
0
0

HI Everyone

 

Please make sure to go to the Sybase download site and grab the EBFs you need for Sybase products.

 

As we continue the transition to SAP systems, we will be moving to SAP's Service Marketplace and stop using the Sybase Download page.

 

Please visit the following link to access your EBFs - the text below is what you'll find on the page

 

http://downloads.sybase.com/swd/base.do

 

Sue Dunnell

PowerBuilder Product Manager

 

Please Note
With the transition to SAP support plans and infrastructure you will lose access to the Sybase EBF and Maintenance download site. SAP Service Marketplace does NOT contain patches for older End of Lifed product versions. Should you wish to retain copies of such patches for future use we strongly encourage you to download copies BEFORE you are migrated to SAP support plans and infrastructure. The Sybase EBF and Maintenance download site will be decommissioned at the end of June 2014 after which time no further access will be possible to download such patches.

On the SAP infrastructure only users that have a valid Support Agreement are able to download patches.

It's that time of year....

ISUG Tech Conference 2014 Report

$
0
0

Monday

 

Location

It's good not to be in Las Vegas.  The location in Atlanta is rather convenient.  You can take a MARTA train straight from the airport to a shopping mall close to the hotel and then take a covered walkway from the mall to the hotel.  The one issue though is that things are not well marked.  It seems that the people responsible for signage may be looking at it from the perspective of people that already know the area. I found it quite hard to find my way around when I first arrived.

 

What is interesting about the location is that the area is quite packed during the day (for example when I ran back over to the mall to get lunch) and deserted at night (being the downtown area).  Since most places serve the folks that are working at their offices during the day, large parts of the area close down between 6 and 8PM.  I'd like a location that was a little more active during non-conference hours.

 

Registration

It went quickly.  We received a badge, a small program guide and a copy of the ISUG - TECH journal.  Those of us who were speaking also received a polo shirt.  One thing I noted is that the program guide indicated when the second day of Yakov's workshop was, but forgot to include the first.  Not sure if I'm that upset, because the first day of his session runs concurrent with the 3 sessions I'm doing.

 

Welcome Reception

Held at the lounge at the top of the hotel.  Well attended, though not a lot of food.  Most folks headed out afterwards for a real meal.

 

Tuesday

 

Breakfast

Standard continental breakfast located next to the ballroom where the general sessions are being held. Suggestion for next conference: Have the breakfast and general sessions in the same room.  Let people take a bit more time with breakfast (eating it during the session).

 

Opening Keynote

Also held in a section of the ballroom.  It was actually configured to be quite wide and not very deep, so that everyone was fairly close to the platform.  The first three rows of the middle seating was simply chairs.  The next three rows behind them and all of the seating on the right and left wings was chairs spaced farther apart behind long tables.  I really like having tables and more space. Suggestion for next year:  Provide power outlets at the tables as well.

 

Mike Harrold and Brian Enochs started with a discussion of ISUG-TECH and their role.

 

 

Irfan Kahn ( SVP and General Manager for SAP Database and Technology)  then discussed the HANA platform and noted that the SAP release of ASE was one of the most significant versions in ASE history, so SAP is committed to investing in the non HANA products.

 

 

Richard Plederder (Senior Vice President Development HANA Platform Data Management) then discussed the Real Time Data Platform (note PowerBuilder included in the slide).

 

 

That was followed by a demo of ASE 16 doing linear scaling from 16 to 80 processors.  Then representatives of the China Academy of Railway Sciences discussed how they are using ASE to support their enormous ticket sales (3 billions transactions a day with a peak load of 9.4 million transactions per hour during peak travel season).

 

 

 

Then a discussion of coming features in future versions of ASE including Low Latency (In memory row store with MVCC and compiled queries), Speed ( memory and storage tier with Flash, parallel utilities and lazy decompression), Security (data masking and workload analysis) and Simplicity (heat map for data tiering and real time workload capture).

 

 

For IQ, future enhancements include Reduced TCO (shared nothing on direct attached storage), Real Time Capabilities (In memory scale out) and HANA support (SAP HANA extended storage and near line storage).

 

 

For Replication Server, enhancements include Increase Throughput with reduced latency, Zero Data Loss HA/DR via synchronous replication, Real-time replication into HANA from AP.

 

 

SQL Anywhere enhancements include Newly emerging embedded systems, SAP ecosystem integration and High performance synchronization.

 

 

That was followed by a Q&A session with the speakers.  Richard Plederder mentioned that PowerBuilder is not under his group, but it is proceeding forward and would be covered in the Plenary session.  He also indicated that PowerDesigner is doing well and they are working on an HTML portal version of it that would be discussed later at the conference.

 

Plenary session

About 40 people, including 6 from Appeon's engineering team.  Do to a travel approval SNAFU, Sue wasn't able to make it.  Dave asked how many people had the beta, and only one person (Jeff Gibson who is presenting on it) did.  Dave discussed the SAP release process including the Partner Beta test in Waldorf in May and then the subsequent release.  Dave demonstrated the 64 bit capability and referenced Jeff's session for demonstrations of docking windows, OData, etc.

 

Dave indicated is what Sue would like to see moving forward is a release per year with a few new features rather than large major releases less frequently.  Dave has come back to PowerBuilder as of January.  Is looking to have CodeJam events featuring PowerBuilder at the time of the product release.

 

Dave asked who was using PowerBuilder.Net and got about 6 hands.  He then asked who was doing WPF development and only got 1.

 

New ProcessBitness property on Environment object so you can see whether you're in the IDE (32 bit) or a running app (64 bit).  You will need to add code to test for that and then specify which database driver you want to use, particularly if you want to test the app in the 32 bit IDE but deploy to 64 bit.  If you compile for 64 bit the machine code option is not available.  Dave asked who was doing machine code compiles and only one person (Jeff) raised their hand.

 

Dave then demoed some SAP products that incorporate PowerBuilder technology.  The first was SAP UI5.   You can take your DataWindow SRD files and use them in SAP UI5 and then view them on any device in any browser.

 

 


They are also working on a tool called Web Access Toolkit (WAT) which is a browser based IDE to do development.  It sounds like it will replace App Builder, which is a web based IDE, but focused on mobile development.

 

EAServer is no longer being sold.  It isn't end of life yet, but the only thing in the future is maintenance releases.  They won't go end of life until they decide just how long they will continue to support it.

 

Armeen then demoed Appeon.

 

Lunch

Lunch was located next to the exhibit hall.  The food was largely fried and breaded, and water seemed to be the only beverage served.

 

 

Technical Sessions

How to Develop Native Cross-OS Mobile Apps with PowerBuilder - Armeen Mazda

This is standard workshop for Appeon, though condensed down due to lack of time.  A USB card was handed out with a developer version of Appeon.  Armeen then walked through pre-configuring the users laptops for the install (about 30 minutes) and then the install and configuration of Appeon (another 30 minutes).  The remainder of the time was spend working with the Appeon sample application.  There were about 40 people in the session.

 

Agile Software Engineering (ASE) - An Overview - Dave Fish

I sat through the first half of this session, where Dave went over the basis of Agile development.  I had to leave halfway through to catch the session on PB15 enhancements.  There were about 20 people in the session.

 

What's New in PowerBuilder 15 - Jeff Gibson.

Jeff covered the enhancement coming in PowerBuilder 15, including:

 

  • OData data source
  • 64 bit deployment in PowerBuilder Classic
    • bitness indicator so you can add conditional code so you can debug in IDE (32 bit) and deploy (64 bit) with same code
    • note that in Windows displays two different ODBC panels (one 32 bit and one 64 bit), but the panels display profiles from both
    • note that when you are writing to registry, 32 bit and 64 bit apps write to different areas
  • Windows 8 support
  • .Net 4.5 support
  • Dockable windows
    • MDIDock,  MDIDockHelp
    • OpenSheet:  Docked!   Floating!  TabbedDocument!  TabbedWindow!
    • A  number of new OpenSheet commands to support opening windows into specific areas.
  • Updated Database Drivers
    • Microsoft SQL Server  20122
    • Oracle 12
  • Upgraded Graphic DataWindows in PowerBuilder.Net (perhaps,, Jeff found it in the documentation  at one point and then couldn't find it later)

There were approximately 40 people in his session.  He asked how many people had access to the beta, and only one person did.

 

Sponsor Reception

Mostly drinks, very little food, so I went out to get something to eat and back to my hotel room to work on my demos.

 

Wednesday

 

Breakfast

On the second day it was Quiche, so I decided to find something else and headed off to my first session.

 

Technical Sessions

 

Introducing SAP Mobile Platform (SMP 3.0) - Dave Fish

Best of Breed between Sybase, SAP and Syclo.  Doesn't provide a development tool other than App Builder.  You bring your own tools.  7 people attending.  It does provide an SDK based on Cordova (formerly PhoneGap) so that you don't have to deal directly with device APIs.  Agentry UI framework allows you to create apps with little coding.

 

 

SAP Mobile SDK 3.0 Overview - Tony Woods

Tony gave a bit deeper dive into the mobile SDK provided with SMP.

 

 

Introduction to SAP River - Dave Fish

Dave then discussed River, a tool that uses a definition language to create the data model, business logic and access control logic and then exposes it as OData services that can be called from a number of different clients.  SAP has floated the idea of enabling PowerBuilder to generate the definition language used by River in order to provide a graphical development tool for it.

 

Lunch

It seems my California influenced healthy eating habits don't quite mesh the the meals provided in the South.  I found something else.

 

Introduction to SAP UI 5 - Day One - Dave Fish

This was my only technical session on Wednesday afternoon (some 4 hours or so long, the first of two) and one of my favorites.  It was an intro to SAP UI5, but one that involved hands on coding.  We did about half the coding exercises used jsbin.com, a collaborative javascript coding environment that is entirely browser based.  It does eliminate the need to do the somewhat involved setup of eclipse and configure it for SAP UI5.  However, it doesn't seem to offer a whole lot of help diagnosing coding errors.  We did the rest of the coding exercises (including a music store that plays sample of tunes by pulling the preview from itunes) in SAP UI5 in the eclipse IDE.

 

 

CodeJam

Wednesday evening from 6pm to 11pm was spent at CodeJam.  Another of my favorite events because it involved hand on coding.  (That the served all you can eat pizzas and drinks didn't hurt either, so much for healthy eating!).  This time the tools included HANA Studio and SAP UI5.  There were others as well, but I was only able to get through 4 of the 13 exercises (all involving HANA Studio) in the time allowed.

 

They had us all remoting into our own virtual desktops in Amazon Web Services (AWS) and running the tools from there, which ensured we didn't have very many problems getting the environments configured.  However, given that they took down the instances shortly after CodeJam ended, we don't have any opportunity to play with them further (without going out and setting up our own environment on AWS at least).  I would have liked to have access to the desktop for a few days afterwards to try some of the other exercises that I didn't have a chance to get to.

 

 

Thursday

 

Breakfast

I skipped the conference provided breakfast again, opting for something a bit more health conscious.

 

Technical Sessions

My turn to present.  I did three sessions back to back.

 

  • PowerBuilder.Net Visual Assemblies in Visual Studio.Net
  • COM Callable Wrapped Web Services in PowerBuilder Classic
  • Creation and Consumption of Web Services

It didn't occur to me until that morning that the last two courses should have been presented in reversed order, as the last one would have made a great intro for the second one.

 

Attendance wasn't bad, particularly considering that they were concurrent with the first day of Yakov's workshop.

 

Lunch

This time I did find something to eat at the lunch.  It's also when ISUG held the drawing from the exhibit hall contest.  I was the first winner, and got a second blue ISUG shirt.

 

Introduction to SAP UI 5 - Day Two - Dave Fish

Not much to add, just finishing up the hands on coding exercises.

 

Conference End

And that was it.  Headed through the walkways to the MARTA station, took the MARTA to the airport and then I'm on my way home.

 

Summary

All in all a good experience.  Given that it's the first time in a while that ISUG has done a conference separate from the now defunct TechWave, that word about it got out late, and that there as a PowerBuilder specific conference within 250 miles of the location the prior month, turnout was still pretty good.  It will be interesting to see how much better attended it might be next year as it establishes itself as an annual event, word get out about it sooner and overlap with other regional events might be avoided.  There will also be a new version of PowerBuilder out by then, so there should be a greater opportunity for new session content.

 

PostScript

One note about my food comments.  I'm rather particular.  I made similar complaints about food at TechWave 2010.  At SAP TechEd/TechWave 2011 I never even made it for SAP provided lunch until the last day.

 

I had a similar experience the two times I stopped at Chik-fil-a while I was there in Atlanta (once in the mall, and then later at the airport on the way out).  I asked for grilled rather than fried chicken (it's one of their menu items!) and got a blank stare for a minute, and then told I would have to wait a few minutes because they don't keep the grilled chicken readily available like they do fried.

 

Check this out regarding healthy food (and activities) and conferences:  How To Keep The People Attending Your Conference Alive

 

Also, I'm also a coffee and drink snob.  I skipped the conference provided drinks as well.  I just checked, and I spent over $150 buying coffee, vitamin waters, protein bars and outside meals while at the conference.  It's not unusual for me to bring a cooler with my own food to a conference if it's fairly local or I might buy a cooler and my own food at a grocery store neat the event the day before the conference if it's farther away.

Call for Papers for SAP d-code (formerly TechEd) is now open

$
0
0

d-Code is the SAP's annual IT conference, held in four worldwide locations:( generally China, United States, Europe and India).  This years events are:

 

  • Shanghai: March 13–14, 2014 (already happened)
  • Las Vegas: October 20–24, 2014
  • Berlin: November 11–13, 2014
  • Bangalore: Fall 2014

 

It used to be called TechEd.  See more here about the name change.

 

The call for papers just opened for the Las Vegas event.  It will close on May 26th.

 

The announcement references a graphic that shows the intersection of "track structure" and "hot topics" (which I've linked to here):

 

http://scn.sap.com/servlet/JiveServlet/showImage/38-105989-437331/tracktopic.png

 

I'd suggest that PowerBuilder session would perhaps fit best under "Developer Experience" or "User Experience" as far as "Hot Topics" and "User Experience and User Interface Development" or "Data Management and Modeling" for "Track Structure".  Of course, if you wanted to present on a PowerBuilder/Appeon solution, then "Mobile" would also work as a "Hot Topic" and "Mobile Solution Development" as a "Track Structure".

 

In previous TechEd events, you had to be an ASUG member in order to submit a session.  This year's announcement doesn't specifically mention that, but I'm assuming that is still the case.  Fortunately, if you are an ISUG-TECH Gold Member and reside in the United States or Canada, a complementary membership in ASUG is one of the benefits.  ASUG may have similar reciprocal membership agreements with other regional SAP user groups.  So if you are not located in the United States or Canada but belong to a regional SAP user group where you live, you may want to check with them to see if they have such an agreement with ASUG.

Communication with a smart card from PowerBuilder

$
0
0

We're going to look at using the Smart Card SDK provided in more recent versions of Windows (XP and later).  Earlier versions of Windows had an ActiveX installed called CAPICOM which could be accessed from PowerBuilder through OLE Automation, but that control was removed as of Windows Vista because of security issues.

 

We're going to look at a number of operations:

 

 

Communicating with the card

 

The first step is establish a context for the API calls.  To do that, we need to declare the following local external function for SCardEstablishContext:

 

Function ulong SCardEstablishContext  ( &  Long dwScope, &  long pvReserved1, &  long pvReserved2, &  REF ulong phContext &  ) Library "winscard.dll"

And call it as follows:

 

ulong    rc
rc = scardestablishcontext( SCARD_SCOPE_USER, 0, 0, context )
IF rc = SCARD_S_SUCCESS THEN    Return SUCCESS
ELSE    Return FAILURE
END IF

Where the following are defined as constants.

 

CONSTANT LONG SCARD_S_SUCCESS            = 0
CONSTANT LONG SCARD_SCOPE_USER          = 0

Context (the last argument) should be defined as an instance variable because we will need to release it when we are done making API calls.  We will also be passing a reference to it in many of the API calls.

 

ulong        context

The second step is get a reference to the smart card reader(s) that the user's machine is equipped with.  We do that by declaring the following local external function for the SCardListReaders method in the SDK:

 

Function ulong SCardListReaders  ( &  ulong hContext, &  Long mszGroups, &  REF Blob mszReaders, &  REF Long pcchReaders &  ) Library "winscard.dll" Alias For "SCardListReadersW"

The API defines the second argument as a string.  However, we want to pass a null, and the way we do that with PowerBuilder is by declaring the argument as a long and then passing a zero.  That causes the method to return all readers, rather than just a subset.

 

Once we've declared that we can use the following PowerScript to get an array that contains the name of all smart card readers on the system.  The SDK returns the list as a null terminated array, so we parse the blob we get back and use the String function to pull the names out and put them in an array that PowerBuilder is more comfortable with.

 

ulong                    rc
long                    ll_bufflen = 32000
long                    ll_readerlen
string                    ls_reader = Space ( ll_bufflen )
blob                    buffer
buffer = Blob ( ls_reader )  // Preallocate space in the buffer or the call will fail
rc = SCardListReaders ( context, 0, buffer, ll_bufflen )
IF ll_bufflen > 0 THEN    // BlobMid is messed up.  Len reports Unicode chars, BlobMid acts like ANSI chars    // so we have to double the values we pass to it to get full Unicode characters    //Truncate the buffer to what was actually returned    buffer = BlobMid ( buffer, 1, ( ll_bufflen - 1 ) * 2 )    //Read off the first value (string stops at the null terminator)    ls_reader = String ( buffer )    //Add it to the array    readers[1] = ls_reader    //See if we have any data left    ll_readerlen = ( Len ( ls_reader ) * 2 ) + 3    buffer = BlobMid ( buffer, ll_readerlen )    ll_bufflen = Len ( buffer )    //Loop through for the remaining data    DO WHILE ll_bufflen > 0        ls_reader = String ( buffer )        readers[UpperBound(readers)+1] = ls_reader        ll_readerlen = ( Len ( ls_reader ) * 2 ) + 3        buffer = BlobMid ( buffer, ll_readerlen )        ll_bufflen = Len ( buffer )    LOOP
END IF

If there are no readers, there isn't much further to go.  If there is only one, then you can proceed immediately to check if there is a smart card in it.  If there is more than one reader, you may need to check them all to see which have cards in them, and if more than one do then prompt the user to select the card they want to work with.

 

There is a function in the SDK that can do some of this work for you (SCardUIDlgSelectCard).  It determines what cards are available and prompts the user to select the one they want to work with.  It does require working with an OPENCARDNAME_EX structure though, which is a bit tricky from PowerBuilder.  For a number of reasons, we found that method didn't serve our needs.  As a result, this sample does all of the work without using that method.

 

The third step is to attempt to open a connection to any card(s) in the card reader(s) we've found.  We do that by first declaring the following local external function for the SCardConnect method in the SDK.

 

Function ulong SCardConnect  ( &    Long hContext, &    String szReader, &    Long dwShareMode, &    Long dwPreferredProtocols, &    REF ulong phCard, &    REF ulong pdwActiveProtocol &    ) Library "winscard.dll" Alias For "SCardConnectW"

And then call it in PowerScript as follows:

 

ulong    rc
rc = SCardConnect ( context, &                             reader, &                             SCARD_SHARE_SHARED, &                             SCARD_PROTOCOL_Tx, &                             card, &                             protocol )

Where "reader" is the name of the smart card reader we obtained from the previous step.  The next two arguments are defined constants as follow (along with some other values you might use instead):

 

CONSTANT LONG SCARD_SHARE_EXCLUSIVE    = 1
CONSTANT LONG SCARD_SHARE_SHARED        = 2
CONSTANT LONG SCARD_SHARE_DIRECT        = 3
CONSTANT LONG SCARD_PROTOCOL_T0         = 1
CONSTANT LONG SCARD_PROTOCOL_T1         = 2
CONSTANT LONG SCARD_PROTOCOL_Tx         = 3

Once again, you'll want to save "card" and "protocol" off as instance variables, because you'll need to use them later.

 

protected ulong        card
protected ulong        protocol

The fourth step (assuming we found a card) is to get the card status to ensure that it's ready for us to communicate with it.  We do that using the SCardStatus API function:

 

Function ulong SCardStatus  ( &    ulong hCard, &    REF String szReaderName, &    REF Long pcchReaderLen, &    REF Long pdwState, &    REF Long pdwProtocol, &    REF byte pbAtr[], &    REF Long pcbAtrLen &    ) Library "winscard.dll" Alias For "SCardStatusW"

Which we then call via the following PowerScript:

 

integer    i
ulong    rc
long    pcchReaderLen = 32000
string    szReaderName = Space ( pcchReaderLen )
long    pdwState
long    pdwProtocol
byte     pbAtr[]
long    pcbAtrLen = 32
FOR i = 1 TO pcbAtrLen    pbAtr[i] = Byte ( Space(1) ) // Prepad the buffer
NEXT
rc = SCardStatus( card, &    szReaderName, &    pcchReaderLen, &    pdwState, &    pdwProtocol, &    pbAtr, &    pcbAtrLen )
IF rc = SCARD_S_SUCCESS THEN    CHOOSE CASE pdwState        CASE SCARD_UNKNOWN            status = 'Unknown'        CASE SCARD_ABSENT            status= 'Absent'        CASE SCARD_PRESENT            status= 'Present'        CASE SCARD_SWALLOWED            status= 'Swallowed'        CASE SCARD_POWERED            status= 'Powered'        CASE SCARD_NEGOTIABLE            status= 'Negotiable'        CASE SCARD_SPECIFIC            status= 'Specific'        CASE ELSE            status= 'Not Known'    END CHOOSE    atrbytes = pbAtr    atr = ""    FOR i = 1 TO pcbAtrLen        atr += of_bytetohex ( pbAtr[i] )    NEXT
END IF

Once again, you may want to save off the "status" and the "atr" (Answer to Reset) value.  For ease in using them from PowerBuilder, I've converted them to strings (the ATR being a hex encoded string).

 

The constants for the various possible state values are:

 

CONSTANT LONG SCARD_UNKNOWN               = 0
CONSTANT LONG SCARD_ABSENT                = 1
CONSTANT LONG SCARD_PRESENT               = 2
CONSTANT LONG SCARD_SWALLOWED             = 3
CONSTANT LONG SCARD_POWERED               = 4
CONSTANT LONG SCARD_NEGOTIABLE            = 5
CONSTANT LONG SCARD_SPECIFIC              = 6

And the of_bytetohex function was borrowed from PFC.

 

string    ls_hex=''
char    lch_hex[0 to 15] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', &                            'A', 'B', 'C', 'D', 'E', 'F'}
Do    ls_hex = lch_hex[mod (abyte, 16)] + ls_hex    abyte /= 16
Loop Until abyte = 0
IF Len ( ls_hex ) = 1 THEN    ls_hex = '0' + ls_hex
END IF
Return ls_hex

Now that we're connected to the card, the fifth step is to connect to the specific applet on the smart card we want to work with.  For this, you'll need to have information from the card manufacturer as to the applet IDs you need to communicate with and the specific APDU command syntax they require.  If you are working with US DoD Common Access Cards, a great deal of that information can be obtained from Common Access Card (CAC): Home, particularly Common Access Card (CAC) Security.  The "Test Materials" section contains links for instructions on obtaining test cards and the form to do so.  Also of particular interest on that page are DoD Implementation Guide for CAC Next Generation (NG) and Technical Bulletin: CAC Data Model Change in 144K Dual Interface

Cards

 

We'll need to declare the SCardTransmit API call to send commands to the applet:

 

Function ulong SCardTransmit( &      ulong hCard, &      Long pioSendPci, &     byte pbSendBuffer[], &      Long cbSendLength, &      Long pioRecvPci, &      REF byte pbRecvBuffer[], &      REF long pcbRecvLength &    ) Library "winscard.dll"

The API documentation indicates that the second argument is a SCARD_IO_REQUEST structure, but we're going to use a pointer to that structure that we obtain from the SDK.  The API documentation indicates that the fifth argument is a similar structure, but we're going to declare it as a long and pass 0 to indicate that we're passing null for that value.

 

We create a wrapper function because we're going to be sending a number of commands to the card.  The function takes a byte array as an argument and returns a string with status info.

 

integer    i
ulong        rc
byte        sendBuffer[]
long        pioSendPci
byte         pbRecvBuffer[]
long         pcbRecvLength
long        cbSendLength
byte        getdata[5]
string        respSW1
string        respSW2
cbSendLength = UpperBound ( apdu )
FOR i = 1 TO cbSendLength    sendBuffer[i] = of_hextobyte ( apdu[i] )
NEXT
pcbRecvLength = 2
FOR i = 1 TO pcbRecvLength    pbRecvBuffer[i] = 0 ;
NEXT
pioSendPci = of_getpci()
rc = SCardTransmit ( card, &      pioSendPci, &    sendBuffer, &      cbSendLength, &      0, &      pbRecvBuffer, &     pcbRecvLength )
IF rc <> scard_s_success THEN return ""
respSW1 = of_bytetohex ( pbRecvBuffer[1] )
respSW2 = of_bytetohex ( pbRecvBuffer[2] )
//This means there is more data to come
IF respSW1 = "61" THEN    getdata[1] = of_hextobyte ( "00" )    getdata[2] = of_hextobyte ( "C0" )    getdata[3] = of_hextobyte ( "00" )    getdata[4] = of_hextobyte ( "00" )    getdata[5] = pbRecvBuffer[2]    cbSendLength = 5    pcbRecvLength = pbRecvBuffer[2] + 2 // We need two extra bytes for the status bits    FOR i = 1 TO pcbRecvLength        pbRecvBuffer[i] = 0 ;    NEXT    rc = SCardTransmit ( card, &        pioSendPci, &        getdata, &        cbSendLength, &        0, &        pbRecvBuffer, &        pcbRecvLength )    IF rc <> SCARD_S_SUCCESS THEN Return ""    respSW1 = of_bytetohex ( pbRecvBuffer[pcbRecvLength - 1] )    respSW2 = of_bytetohex ( pbRecvBuffer[pcbRecvLength] )
END IF
Return respSW1 + respSW2

The script uses another method borrowed from PFC (of_hextobyte)  to convert a hex value to a byte:

 

char        lch_char[]
integer    li_byte
int li_dec[48 to 70], li_i, li_len
//Get the decimal code for hexadecimal value of '0' to 'F'
// Whose ASC Value are from 48 to 57 and 65 to 70
For li_i = 48 To 57    li_dec[li_i] = li_i - 48
Next
For li_i = 65 To 70    li_dec[li_i] = li_i - 55
Next
as_hex = upper(as_hex)
lch_char = as_hex
li_len = len (as_hex)
//Convert Hexadecimal data into decimal
For li_i = 1 to li_len    //Make sure only 0's through f's are present    Choose Case lch_char[li_i]        Case '0' to '9', 'A' to 'F'            li_byte = li_byte * 16 + li_dec[asc(lch_char[li_i])]        Case Else            Return li_byte    End Choose
Next
Return li_byte

The of_getpci method is the one that gets a pointer to a LPCSARD_IO_REQUEST structure from the winscard DLL:

 

ulong dllhandle
ulong pci
dllhandle = LoadLibrary ( "WinSCard.dll" )
pci = GetProcAddress ( dllhandle, "g_rgSCardT0Pci" )
FreeLibrary(dllhandle)
return pci

That method in turn relies on external function declarations for three Windows API functions:

 

Function ulong LoadLibrary ( &    string fileName&    ) Library "kernel32.dll" Alias For "LoadLibraryW"
SubRoutine FreeLibrary ( &    ulong dllhandle &    ) Library "kernel32.dll"
Function ulong GetProcAddress ( &    ulong dllhandle, &    string procName &    ) Library "kernel32.dll" Alias For "GetProcAddress;Ansi"

The return value from the SCardTransmit is "9000" if it works.  If the first two characters are "61", it means that the call returns more data than could be returned in the original request.  If that is the case, a second call is made to the function to retrieve the rest of the data.

 

Ok, now we're ready to select the applet.  This is the card specific process, so the following example will only work for US DoD CAC cards.  You will need to consult information from the manufacturer of the card for specific details on how to deal with it.

 

There are two versions of the US DoD CAC card, one in which you need to access an applet ID of 790101 (the first version).  If that fails, we attempt to connect to a container applet ID of 790100 and, if that works, an applet within it through it's object ID of 0101.

 

string    apdu[]
string    respSW
string    emptyarray[]
apdu[1] = "00"
apdu[2] = "A4" // Select
apdu[3] = "04" // By id
apdu[4] = "00" // first record
apdu[5] = "07" // Lenth of data
apdu[6] = "A0" // Applet ID to bit 11
apdu[7] = "00"
apdu[8] = "00"
apdu[9] = "00"
apdu[10] = "79"
apdu[11] = "01"
apdu[12] = "01"
respSW = of_sendapdu ( apdu )
// If we got OK, then it's an old card and we're already good
IF respSW =  SWRESPOK THEN  version = '1'
ELSE    //Otherwise, try using the new card method    //Select the master applet    apdu[12] = "00"    respSW = of_sendapdu ( apdu )    IF respSW <> SWRESPOK THEN        //We don't know what it is        Return FAILURE    END IF    //Reset the array    apdu = emptyarray    apdu[1] = "00" // CLA    apdu[2] = "A4" // INS - select object    apdu[3] = "02" // P1    apdu[4] = "00" // P2 -    apdu[5] = "02" // Lc - length of data    apdu[6] = "01" // file id    apdu[7] = "01"    respSW = of_sendapdu ( apdu )    IF respSW = SWRESPOK THEN        version = '2'    ELSE        //We couldn't select the applet        version = 'Unknown'        Return FAILURE    END IF
END IF
Return SUCCESS

Before we go into specific operations, let's see what we need to do to clean up after ourselves when we're done.  So, for our sixth step we need to disconnect from the card.  To do that, we declare a local external function for the SCardDisconnect method in the SDK:

 

Function ulong SCardDisconnect ( &    ulong hCard, &    long dwDisposition &    ) Library "winscard.dll"

And call it with the following PowerScript:

 

ulong    rc
rc = scarddisconnect( card, SCARD_LEAVE_CARD )
SetNull ( card )
IF rc = SCARD_S_SUCCESS THEN    Return SUCCESS
ELSE    Return FAILURE
END IF

Where SCARD_LEAVE_CARD (and other values you might need to use) are defined as:

 

CONSTANT LONG SCARD_LEAVE_CARD            = 0
CONSTANT LONG SCARD_RESET_CARD            = 1
CONSTANT LONG SCARD_UNPOWER_CARD      = 2

Finally, in our seventh step, we need to release the context that we established in the first step.  We need the SCardReleaseContext SDK method for that:

 

Function ulong SCardReleaseContext( &    ulong hContext &    ) Library "winscard.dll"

And then use the following PowerScript to call it:

 

ulong rc
rc = scardreleasecontext( context )
IF rc = SCARD_S_SUCCESS THEN    Return SUCCESS
ELSE    Return FAILURE
END IF

Validating the user's PIN

 

Now that we know how to connect to the card, we'll look at some specific operations that we might want to perform using it.  One is to have the user validate their PIN so we know that the user is actually the holder of the card.  To do that, we need to send a specific APDU command to the card while we're connected to it.  For US DoD CAC cards, the value is 00 20 00 followed by the length of the PIN buffer ( "08" ) and then the hex encoded PIN right padded to the length of the PIN buffer with FF values.

 

In the following sample, w_pin is a window that is presented to the user into which they enter their PIN.  The return code from the APDU call, if the PIN is invalid, indicates the number of additional attempts the user is allowed to make before the card is automatically locked and the user will need to go to a RAPIDS site to have the card unlocked.

 

int        i
int        chances
int        pinlen
string apdu[]
string    ls_pin
string    respSW
Open ( w_pin )
ls_pin = message.StringParm
// User hit cancel
IF ls_pin = "" THEN Return NO_ACTION
pinlen = Len ( ls_pin )
apdu[1] = "00" // CLA
apdu[2] = "20"  // Verify PIN
apdu[3] = "00" // Not used
apdu[4] = "00" // Not used
apdu[5] = "08" // Indicate length of data, fixed at 8
// Add the PIN to the APDU
FOR i = 1 TO pinlen    apdu[5 + i] = of_bytetohex ( Asc ( Mid ( ls_pin, i, 1 ) ) )
NEXT
// Pad out the rest of the APDU with 0xFF
FOR i = pinlen + 6 TO 13    apdu[i] = "FF"
NEXT
respSW = of_sendapdu ( apdu )
CHOOSE CASE respSW    CASE SWRESPOK        // PIN Verified        Return SUCCESS    CASE PINLOCKED        Return PIN_LOCKED    CASE CACLOCKED        Return CAC_LOCKED    CASE INVALIDDATA        Return INVALID_DATA    CASE PINUNDEFINED        Return PIN_UNDEFINED    CASE ELSE        IF Left ( respSW, 2 ) = PININVALID THEN            chances = Integer ( Right ( respSW, 1 ) )            Return -chances        End If
END CHOOSE

The possible status codes returned from the APDU call are defined as:

 

CONSTANT STRING PININVALID         = "63"
CONSTANT STRING PINLOCKED        = "63C0"
CONSTANT STRING CACLOCKED       = "6983"
CONSTANT STRING INVALIDDATA      = "6984"
CONSTANT STRING PINUNDEFINED   = "6A88"

Reading the certificate Subject Name

 

The other thing we may want to do, once we've verified that the user knows the CAC PIN, is determine who the CAC card says the user is.  To do that, we're going to read the certificate off the card and then determine what the CN value of the Subject Name is. The US DoD stores the user's name and EDI/PI number in the CN value in the following format:  CN=LastName.FirstName.MiddleName.EDI/PI

 

The first step to access the certificate is to establish a cryptography context using the Windows API CryptAcquireContext method:

 

Function ulong CryptAcquireContext ( &    REF ulong hProv, &    ulong pszContainer, &    string pProviderName, &    long dwProvType, &    long dwFlags &    ) Library "advapi32.dll" Alias For "CryptAcquireContextW"

And call it using this PowerScript:

 

ulong    rc
rc = CryptAcquireContext ( &    prov, &    0, &    providername, &    PROV_RSA_FULL, &    0 )

"prov" is a pointer to the cryptography context that is passed by reference returned to us as a result of the call, defined as:

 

ulong        prov

We declared pszContainer as a ulong rather than a string (as in the SDK) because we're passing 0 indicating a null value.  "providername" is also passed by reference as is defined as follows.  However, we don't use the value.

 

string        providername

And PROV_RSA_FULL is defined as:

 

CONSTANT LONG PROV_RSA_FULL                = 1

The second step, once we have the context, we need to call CryptGetUserKey in the Windows API to get a handle to the certificate:

 

Protected Function ulong CryptGetUserKey ( &    ulong hProv, &    long dwKeySpec, &      REF ulong phUserKey &    ) Library "advapi32.dll"

And call it as follows:

 

ulong        rc
rc = CryptGetUserKey ( &  prov, &  AT_KEYEXCHANGE, &  userkey )

Where AT_KEYEXCHANGE is defined as:

 

LONG AT_KEYEXCHANGE   = 1

And "userkey" is passed by referenced and returned to us by the method, defined as:

 

ulong        userkey

The third step is to call CryptGetKeyParam in the Windows API, declared as follows, to get the actual certificate:

 

Function ulong CryptGetKeyParam ( &    ulong hKey, &    long dwParam, &    REF byte pbData[], &    REF long pdwDataLen, &    long dwFlags &    ) Library "advapi32.dll"

And call it as follows:

 

integer    i
ulong        rc
long        certlen
byte        temp[]
//Call it with 0 first to get the size
certlen = 0
rc =  CryptGetKeyParam ( &        userkey, &        KP_CERTIFICATE, &        temp, &        certlen, &        0 )
//Now setup the buffer and call again for that size
FOR i = 1 TO certlen    temp[i] = 0
NEXT
rc =  CryptGetKeyParam ( &        userkey, &        KP_CERTIFICATE, &        temp, &        certlen, &        0 )
certbytes = temp

Where KP_CERTIFICATE is defined as:

 

CONSTANT LONG KP_CERTIFICATE                    = 26

As indicated in the code comments, we call the function once with certlen set to 0 and the function returns the size of the certificate to use.  We then call it a second time with a byte buffer populated to that size to get the certificate data.

 

The fourth step once we have the certificate data is to convert it to a certificate.  To do that, we first have to establish a certificate context using CertCreateCertificateContext in the Windows API:

 

Protected Function ulong CertCreateCertificateContext ( &    long dwCertEncodingType, &    byte pbCertEncoded[], &    long cbCertEncoded &    ) Library "crypt32.dll"

And call it as follows:

 

long    certlen
long    encoding = X509_ASN_ENCODING + PKCS_7_ASN_ENCODING
certlen = UpperBound ( certbytes )
certContextPointer = CertCreateCertificateContext ( &    encoding, &    certbytes, &    certlen )

Where X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are defined as:

 

CONSTANT LONG PKCS_7_ASN_ENCODING       = 65536 // 0x00010000
CONSTANT LONG X509_ASN_ENCODING            = 1

And certContextPointer is defined as:

 

ulong    certcontextpointer

The fifth step is to get the Subject Name off the certificate using the CertGetNameString method in the Windows API:

 

Function ulong CertGetNameString ( &    ulong pCertContext, &    long dwType, &    long dwFlags, &    long pvTypePara, &    REF string pszNameString, &    REF long cchNameString &    ) Library "crypt32.dll" Alias For "CertGetNameStringW"

And call it as follows:

 

ulong        rc
long        subjectlen
string        ls_subject
subjectlen = 256
ls_subject = Space ( subjectlen )
rc = CertGetNameString ( &    certContextPointer, &    CERT_NAME_SIMPLE_DISPLAY_TYPE, &    0, &    0, &    ls_subject, &    subjectlen )

Where CERT_NAME_SIMPLE_DISPLAY_TYPE is defined as:

 

CONSTANT LONG CERT_NAME_SIMPLE_DISPLAY_TYPE = 4

Now that we have the subject name, we need to release the certificate context.  We do that with the CertFreeCertificateContext Windows API function.

 

Function ulong CertFreeCertificateContext (&    ulong pCertContext &    ) Library "crypt32.dll"

Which we call as follows:

 

ulong    rc
rc = CertFreeCertificateContext ( certcontextpointer )

After which we need to release the cryptography context as well using the CryptReleaseContext Windows API function:

 

Function ulong CryptReleaseContext ( &    ulong hProv, &    long dwFlags &    ) Library "advapi32.dll"

And call as follows:

 

ulong rc
rc = CryptReleaseContext ( &    prov, &    0 )

Reading other Certificate Data

 

Once we have a pointer to a CERT_CONTEXT structure, one member of which is a CERT_INFO structure, we can actually access the certificate.


[To be finished tater]



PB 12.5.2 Classic .Net assembly build error "C0352: Unknown error"

$
0
0

Hi everyone.

 

I am trying to create a .Net assembly in PB12.5.2 Classic. When I do this in a small test application it works well but when I try to create a .Net assembly target on our main application the build process returns with ther strange error C0352: Unknown error.

 

The application consists of approx 75 pbl's and we are using external functions and oleobjects etc. We use our own transaction object which is inherited from a base transaction object inherited from powerbuilder class "transaction".

 

Parallel to the .Net assembly target we have our normal (Classic) application target and it builds just fine.

 

Can anyone give me a hint to what I shall be looking for ? I have tried to find information about the limitations in a .Net assembly generated in powerbuilder 12.5.2 Classic but I haven't succeded.

 

I will be happy to provide more detailed information.

 

 

Best regards

 

Flemming


Thoughts regarding PB perception and community benefit

$
0
0

These are some things albeit little that I think if done would help cultivate the perception of PB outside the PB sphere and benefit the PB community overall.

 

1. Fix all the broken links on the PowerBuilder Developer Center landing page. Surely someone running this website is embarrassed.

2. There hasn't been a post in the "Document" section in months. One would think that with the first PB release in several years that some new WOW functionality would be touted or someone would have figured out something new to share or some PB engineer would want to explain the best way to implement a certain piece of functionality that isn't obvious to a regular person. You know like they used to do in the PBDJ.

3. No training videos in a year and most if not all were done by Bruce Armstrong who isn't an SAP employee. Come on guys. Surely some of the SAP resources assigned to PB can carve out some time to show something new and cool. Again there's a new release in the pipeline surely there's SOMETHING to show besides a shiny new box? I'd love to see Dave, Paul, Yakov and the other gurus at SAP posting a document, blog, video or whatever on here every now and then to help share the love. Or anybody for that matter. It's a community and there are some awesome developers out there with lots of wisdom to share. My guess is Bruce has gotten tired of toting the mail all by himself. Share the load brothers and sisters.

4. Bashing PB.Net is bashing PB. If you don't like the product that's your prerogative. Don't use it and move on. Use your powers for good not evil. When people read daily negative comments about PB.Net it hurts PB Classic by association. Non PBers don't know the difference. All they see is PB is blah blah blah. Like the saying goes: if you don't have anything good to say keep your mouth shut. I would add "please" to that.

5. Add a cool image to the subspace page for PB. If a subspace with 34 followers can have an image why can't ours? I'm just saying.

Capture.PNG

 

6. Contribute, Contribute, Contribute! If you figured something out that wasn't obvious share it with all of us.

7. A thank you to the folks both in and outside SAP that support the PB community. You are appreciated.

 

The intent of this post is to encourage participation. I hope it is taking that way.

Using ImageMagick from PowerBuilder

$
0
0

ImageMagick is a free open-source software package that allows you to convert image files between formats, resize images and perform other functions. It can be used from the command line or as a COM object using PowerBuilder's OLEObject functionality.

 

You can download the installer from here: http://www.imagemagick.org/script/binary-releases.php#windows

 

You must use one of the installers with the word "dynamic" in the description. I chose the Win32 installer because it offers a higher resolution than the Win64 Dynamic installer.

 

The command documentation for ImageMagick can be found here: http://www.imagemagick.org/script/command-line-tools.php

 

There are several commands that are supported by the COM interface.

 

compare: Compares two image files and returns information about the differences.

 

composite: Overlaps one image over another resulting in a third image file.

 

convert: Converts between image formats as well as resizing the image and other actions such as blur, crop, despeckle, and much more.

 

identify: Describes the format and characteristics of image files.

 

mogrify: Resizes the image and other actions such as blur, crop, despeckle, and much more. Mogrify overwrites the original image file, whereas, convert writes to a different image file.

 

montage: Creates a composite image by combining several separate images. The images are tiled on the composite image optionally adorned with a border, frame, image name, and more.

 

Here is an example that converts a JPG file to PNG:

 

OLEObject oMagick

String ls_origfile, ls_destfile

Integer li_rc

Any la_result


ls_origfile = "C:\PBSource\PB105\ImageMagick\Totoro.jpg"

ls_destfile = "C:\PBSource\PB105\ImageMagick\Totoro.png"

 

oMagick = Create OLEObject

 

li_rc = oMagick.ConnectToNewObject("ImageMagickObject.MagickImage")

If li_rc = 0 Then

   la_result = oMagick.Convert(ls_origfile, "-format", "png", ls_destfile)

   MessageBox("Convert", "Result: " + String(la_result))

Else

   MessageBox("ConnectToNewObject", "Failed: " + String(li_rc), StopSign!)

End If

 

oMagick.DisconnectObject()

 

Destroy oMagick


PowerBuilder 15 - OData Support!

$
0
0

PowerBuilder 15 is here!  Well, almost...  It's in a "closed" beta, which means that the download is only available to registered SAP customers and employees.  The SCN link above contains a link to the registration page, and SAP is working to migrate all the former Sybase customers' accounts, and provide them the necessary "S" user ids.  In the meantime, we've been given the go-ahead to blog all we want about PB15, and I couldn't be more excited!

 

There are some great new features being planned for PB15, including the following:

 

  • Updated support for the .NET Framework v4.5
  • MSS 2012
  • Oracle 12
  • Windows 8
  • OData Support
  • Dockable Windows
  • 32 and 64 bit deployment

 

This blog post will cover one of the items listed above - the new support for the OData protocol.  In the current beta, this support only exists in the PB.Net IDE, but I've been assured that it will be available in PB Classic by the time v15 goes into General Availability.

 

What is OData?

OData is emerging as the standard for data exchange across the web.  It's essentially a REST-based web service protocol that allows a client application to invoke backend resources over standard HTTP/s.  I know that sounds a lot like SOAP/XML, but there are some key differences between SOAP/XML and REST/OData.  With SOAP, the Web Sevices Definition Language (WSDL) file defines the methods and data structures that can be invoked from an HTTP client.  The WSDL specification for a service is VERY inflexible, and the calls must be structured exactly as specified or they fail. The response payloads are formatted as tightly-structured and verbose XML that must be parsed apart on the client side.  PowerBuilder has had support for SOAP web services for many years, both as a datawindow datasource, and as a non-visual web service proxy class.  PB15 now introduces support for the OData specification as a datawindow source.

 

OData is a relatively new standard, and it provides more dynamic capabilities for querying the backend data sources.  OData has been described as "ODBC for the Web", and that's a fairly accurate analogy.  I wrote a blog post several months ago that covered OData in fairly good detail, so I won't recreate that here.

 

Creating an OData datawindow

The first step in creating a PowerBuilder datawindow that accesses an OData endpoint, is to find a valid OData endpoint!  For this blog, I'll be using a public SAP Netweaver Gateway endpoint on the SAP Developer Center.  That URL is https://sapes1.sapdevcenter.com/sap/opu/odata/sap/ZGWSAMPLE_SRV/  Note: use of the SAP Developer Center does require user registration, which can be found here.

That URL is known as the "Service Root" in OData, and it provides a quick list of all the entities that are exposed through the OData endpoint.  Accessing an entity (essentially doing a "Select * from <entityName>") is as simple as adding the entityName to the end of the service root URL.  For example, to query the SalesOrderCollection entity, change the URL to https://sapes1.sapdevcenter.com/sap/opu/odata/sap/ZGWSAMPLE_SRV/SalesOrderCollection

To retrieve a specific SalesOrder, add its primary key value in parens after the entityname.  https://sapes1.sapdevcenter.com/sap/opu/odata/sap/ZGWSAMPLE_SRV/SalesOrderCollection('0500000001')

 

 

Step 2: Fire up PB.Net and open the Database Profiles dialog.  This is shown below, and you can clearly see the new profile "ODT OData"

 

Screen Shot 2013-12-20 at 10.48.13 AM.png

 

Step 3: Make sure "ODT OData" is the selected node, then click the "New..." button.  That opens the OData Profile Setup dialog.

Give the connection a name, and paste in the Service Root URL into the "URI" field.  Since this particular OData root requires authentication, I've selected "Supply Userid and Password", and filled those values in.  There's a "Test Connection" button on the Preview tabpage.

Click OK to save the new profile.

 

Screen Shot 2013-12-20 at 11.07.25 AM.png

 

Step 4:  Connect to the new datasource, and open the Database Painter (View > Database Painter).  The OData sources behave just like regular databases. Expand the "Tables" folder to see the exposed OData entities.  Drag a table over to the Object Layout pane to examine its structure.  Right-click the table, and select Edit Data > Grid to perform a retrieve and manipulate the data.  All of this is being done through HTTP calls to REST endpoints.

 

Screen Shot 2013-12-20 at 11.22.15 AM.png

 

Build a Datawindow

At this point, since the OData entities look and feel just like regular database tables, creating an actual datawindow should be basic, "PowerBuilder 101"-level stuff.  You'll need a Solution, and a Target, and a PBL (but these should have already been created if you've gotten this far).  The only new wrinkle will be the selection of the Data Source.  The third panel of the File > New > Datawindow dialog shows the new "OData Service" datasource:

 

Screen Shot 2013-12-20 at 11.28.55 AM.png

 

One note: the SQL creation wizard in the datawindow painter allows you to paint JOINs between OData entities, but I don't recommend taking advantage of that...  At this stage of the beta, restrict your use of OData to single-table queries.

 

From this point, the OData entity looks and behaves just like a traditional SQL table or view.  The $metadata document provides all the information about column names, data types, and associations to other entities.  Creating a datawindow from here is basic PB101 material...  I just created a simple tabular datawindow on one of the OData entities, with no retrieval arguments or other filters.

 

Coding the PowerScript

 

The final step is coding the PowerScript that makes the connection to the OData resource.  This can go anywhere in your code, but it's typically found in the application or window Open event scripts.  Here's what my window Open event looks like:

 

// Profile workflowdemo
SQLCA.DBMS = "ODT"
SQLCA.AutoCommit = False
SQLCA.DBParm = "ConnectString='URI=https://sapes1.sapdevcenter.com/sap/opu/odata/IWFND/RMTSAMPLEFLIGHT/;UID={your ID};PWD={your PW}'"

connect using SQLCA;

tab_1.tabpage_1.dw_1.SetTransObject( SQLCA )
tab_1.tabpage_1.dw_1.Retrieve()

 

You now have the full power of the datawindow at your disposal, including the Update() method.  This uses the same buffer architecture to generate HTTP PUTs for INSERT statements, POSTs for UPDATE statements, and DELETEs for DELETE statements.

 

Happy Testing!

-Paul-

PowerBuilder and Appeon Customers

$
0
0

Hi Everyone

 

If you have purchased Appeon from Sybase or SAP in the past, you probably received notification that Appeon would be EOL as of July 2015.  Please note that this is referring ONLY to SAP selling and supporting Appeon products.  

 

Appeon is still selling, supporting, and actively developing both Appeon for PowerBuilder Web and Mobile editions.

 

The notices you received were sent out inline with past practice, and they are done in a certain format that doesn't allow for extra narrative to let customers know details about the product.

 

As most PowerBuilder customers are aware, Appeon has continued to develop, sell, and provide training and support for their products, so please continue to support and use this product, finding all relevant information at their website.

 

Thanks very much

 

Sue

Upcoming PowerBuilder sessions at d-code Las Vegas

$
0
0

There are five sessions overall, although two are repeats of earlier sessions.

 

NumberTitlePresenterDayTimeSummary
DMM115SAP PowerBuilder 15 – The OverviewJohn Strano, SAPWed10:30 a.m. - 11:30 a.m.See the features of the long-awaited release of SAP PowerBuilder 15 in action! Updated support for the .NET Framework v4.5, MSS 2012, Windows 8, 32, and 64 bit deployment, and Dockable Windows. Learn how SAP PowerBuilder 15 can now interact with SAP HANA with its new OData DataWindow!
Fri08:00 a.m. - 09:00 a.m
DMM117SAP HANA and SAP PowerBuilder 15 – The Solution MixJohn Strano, SAPWed11:45 a.m. - 12:45 p.m.SAP PowerBuilder has been heralded as the most productive custom application development environment in the industry. Examine multiple architectures and avenues for having SAP PowerBuilder develop the presentation layer and business logic for retrieving, manipulating, transforming, and persisting data for custom solutions on the SAP HANA platform.
Fri09:15 a.m. - 10:15 a.m.
UXP206Enhance Existing SAP PowerBuilder Apps Through Mobile TechnologiesMatthew Balent, McKessonWed10:30 a.m. - 11:30 a.m.This session demonstrates techniques for adding imaging and barcode scanning capabilities from mobile devices into existing desktop applications. With the emphasis on a single generic toolset, see how a small footprint and generic component can make a big impact on the viability of your existing SAP PowerBuilder technology stack.

 

 

For more information, and to register for d-Code, see:

 

SAP TechEd d-code Las Vegas | October 20 - 24, 2014 | PowerBuilder Sessions

Viewing all 186 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>