You are on page 1of 23

openSAP Introduction to Software Development on SAP HANA

This document contains a transcript of an openSAP video lecture. It is provided without claim of reliability. If in doubt, refer to the original recording on https://open.sap.com/.

WEEK 5, UNIT 1 00:00:13 Welcome to week five, unit one: Server-Side JavaScript. In the previous week, we saw how we can use the generic OData service generation framework for the creation of REST-based services and how they're also consumed from the user interface. Now this OData framework is very nice in that its easy to use and with a simple service definition document we can have a running service in a matter of seconds, but it does have a few limitations. Currently in HANA 1.0 SP5, only read operations are supported so if you want to create, update, or delete data, you need another option. Also, you can only do OData services. So what if you want a custom body format? What if you want some custom validation logic before you fire into reading of your view or your table? In all of these situations we have another option, to be able to programmatically create services on our own. Thats what were going to talk about all this week: using JavaScript as a programming language for implementing REST-based services, where JavaScript is the primary programming language used in the XS Engine, in the Extended Application Services. So lets review for just a moment the primary development model in SAP HANA Extended Application Services. We see various parts of this overall development model and weve talked about many of them already. But the overall rules that we have seen: One that the UI client rendering is completely done in the client side so theres no server-side UI framework. We simply have REST-based services that expose data and logic to the client side. All the event handling is done inside the client side and then browser code, as we have seen, either the UI elements were provided SAPUI5 or JavaScript running on the client side is used to consume these services and then inject the data into the page. On the server side, our programming language for all procedural logic is JavaScript. We have seen how we can use SQLScript as the main programming language for data-intensive logic down in the database. But it is designedalthough it has some imperative logic featuresit is primary designed for data-intensive operations. On the other hand, JavaScript is well suited to more imperative logic so having validation is also well suited for the creation of services and control flow logic. But yet all of the development artifacts, whether its our user interface, our server-side JavaScript, our OData definitions, the underlying data-intensive logic, even the definition of the catalog artifacts that exist in the database, they're all stored in the SAP HANA Repository.

00:00:41

00:00:53

00:01:30

00:01:47

00:02:22

00:02:46

00:03:22

So lets talk a little bit more on what were going to focus on this week, which is the serverside JavaScript. So server-side JavaScript is very well suited to lightweight procedural logic. We choose JavaScript for a couple of reasons. First of all, the execution of JavaScript is relatively fast. I might not have wanted to say that a few years ago, but weve seen a lot of improvements in the compilation in execution of JavaScript and this largely comes because we now see competition in amongst the browsers. And that competition between Chrome and Firefox and Internet Explorer has caused all the browsers to improve the execution speed of their JavaScript. Because we see JavaScript being the main component for the execution in HTML5based applications. Added to this, SAP did not write our own JavaScript virtual machine. It would have been kind of silly, considering there is already so many good open source options. So we decided to use the Mozilla SpiderMonkey virtual machine, thats the JavaScript virtual machine that runs within Firefox. Now this virtual machine is well suited to our needs. It allowed us to extend the virtual machine and add in things like the HANA native data types, and we could also add our own APIs to the virtual machine as well. Well talk more about those APIs in just a moment. But because we choose an open source JavaScript VM, we can quickly adapt improvements that the open source community makes to that VM. That largely means that as newer versions of Firefox come out and the JavaScript encryption is improved in those versions of the browser, we can fairly quickly adapt those improvements into the server-side JavaScript execution engine inside of HANA Extended Application Services. This also means that we're open, not just because we're using an open source VM but because JavaScript is a very open, very widely known programming language. This also lends us to being able to reuse existing JavaScript code, so we're able to execute standard ECMA-compliant JavaScript. And as long as that JavaScript doesnt assume that its running in a Web browser and try to do something specific with the client, like try to access the DOM, the document object model, something that wouldnt exist on the server side. As long as your code doesnt try to do any of those things, its going to execute serverside JavaScript inside HANA Extended Application Services as well. So that means that you can take existing open source libraries and you can take existing content that you find on the Internet, lots of JavaScript examples out there, and you can very quickly and easily integrate them into the server-side execution environment. It also means that you have one language to learn and use for both the client-side and the server-side development. So with HTML5, even if youre not using SAPUI,5 just about all the other major HTML5 environments, development environments, youre going to need to know some JavaScript. To do modern Web development you have to be well versed in JavaScript. Theres really no avoiding it. That means youre already going to have to go out and learn JavaScript, you're going to have to have developers who are familiar with JavaScript. You might as well continue to leverage that knowledge and use the same programming language on the server side.

00:03:34

00:03:58

00:04:15

00:04:36

00:04:58

00:05:28

00:05:37

00:06:12

00:06:29

00:06:51

Page 2

Copyright/Trademark

00:07:10

We also find that theres widespread knowledge of JavaScript. Most any student coming out of university with a programming degree these days will have some experience doing JavaScript already. Very commonly used programming language because its so widely used in the Web. A recent survey that looked at all public perforce and gift hub repositories found that JavaScript was the most commonly used language in all those open repositories. And there is tons of information available. Information on the Internet for free, there are good books that are out there, its incredibly simple to find educational materials on JavaScript even if you arent already familiar with the programming language, and its really quite easy to learn. And then finally, JavaScript lends itself well to rapid development. Theres no long compile or build cycles. You dont have to do a nightly build or anything like that. You can write your JavaScript code, save it, activate it, and it is immediately executable. Therefore it lends itself well to test-driven and iterative development; you can make a few changes to your code, activate it immediately, test those changes, and then maybe go back and continue adding to the code. And that's a model we want to follow inside of SAP to support rapid and agile development. So a little bit about the server-side JavaScript code itself. We have some HANA native application-specific APIs. Therefore when you write the server side JavaScript, it is going to be largely very specific to HANA, very specific to HANA Extended Application Services. This is where you write all the control flow between the client and the HANA sever. Youll notice that our primary APIs are to give us access to the HTTP request and the HTTP response object. We have direct access to those objects we can read data directly from them so we can we can read our HTTP headers. We can write directly into the response body. We can set response headers so we have a lot of control. So that also means that we have a lot of responsibility for properly formatting the body and setting the correct headers and those sorts of things. So there isnt a lot of programmatic framework where things are provided for you. If you want that then we have the generic OData services, but once you choose to use the server-side JavaScript you have this really low level of control. Now the JavaScript artifacts are stored in the content repository like all the other developmental artifacts that we have seen so far. And the developmental process for creating them and then committing them and activating them is largely the same as everything up to this point. Now we do have a dedicated server side JavaScript or XSJS editor and debugger. And we created a dedicated editor. What we really did was we took the standard Eclipse JavaScript editor and then we we're just able to subclass it and add some features to it. We wanted to be able to display all of our added APIs in the class overview in a project. We

00:07:21

00:07:39

00:07:59

00:08:13

00:08:23 00:08:33

00:08:55

00:09:11

00:09:22

00:09:34

00:09:48

00:10:12

00:10:25

Page 3

Copyright/Trademark

wanted to be able to add code completion for our APIs. And we wanted syntax highlighting that didnt just have the standard JavaScript syntax highlighting, but also had some of our additional features. 00:10:50 And then we wanted a debugger. We wanted this even though its JavaScript and in JavaScript you generally think about executing on the client side and then therefore being difficult to debug because its running inside of the Web browser. Well this is executing on the server. It should be just as simple as any other programming language to set a breakpoint, run your Web page that calls to the HTTP service, and the Web browser stops and the clips debugger comes up and you have full debugging capabilities. And thats exactly what we have introduced in HANA 1.0 SP5 for the server-side JavaScript. Now there are several APIs, and this is the code that we have added to the JavaScript VM and largely it allows you to interact with various pieces of SAP HANA or the Extended Application Services runtime itself. Now the important thing here, the APIs are not written in JavaScript. They are actually written in C but we can expose them to the JavaScript programming model and they look like they're JavaScript functions. So its really kind of nice. You get the ease of use of it being as simple as calling it another JavaScript function, but at the same time these are implemented in very powerful multithreaded C environment. So these APIs, only the SAP HANA development team can create them. If a customer or partner wants to create any reusable code, they would use JavaScript and well see in a second how you would create reusable functions. But SAP is able to create these powerful reusable functions and then expose them as JavaScript functions and these are the functions that we will use to access the database to send SQL commands down to the database and get results sets back. We have an API that represents the results set in such a way that the data doesnt have to be transformed from the HANA native data types. Its not until really you cast some of that data into a JavaScript variable that it finally has to be transformed. And this is one of the powerful benefits of using HANA Extended Application Services is that the application server layer understands the HANA native data types can store and process the HANA native data types. And with these APIs, we basically have the ability to expose data to the outside world to form updates, inserts, delete data...basically anything that you can do with SQL cluster procedures we can do all that via the database API. We also have the request API, and that's what gives us access to the HTTP request and the response object. And in the screenshot you see some additional APIs that will be coming in HANA 1.0 SP6. So we're adding an API for outbound connectivity, so you will be able to consume RESTbased services or really consume anything over HTTP or HTTPS.

00:11:28

00:11:46

00:11:58

00:12:15

00:12:33

00:12:58

00:13:04

00:13:16

00:13:33

00:13:40

Page 4

Copyright/Trademark

00:13:59

And a repository API. So we've seen how from the studio we can check things in and out and activate them, but we also want that all to be programmatically exposed to server-side JavaScript as well. And well continue with this approach of the HANA team taking HANA functionality and exposing it to the JavaScript programming model through the form of these built-in APIs. And then finally we also have the concept of creating server-side JavaScript libraries, or XSJS lib files. This is when you want to create some reusable code. You have a function that does something you want to use in more than one application, then you put it in this XSJS lib file and no matter where it is in the content repository it can be shared with all other projects. Basically we have the syntax $import and we give the package path pointing to where this XSJS lib lives, and then we give the name of the XSJS library. And then we're able to call functions that exist inside that library, either by using this full pass $ and then the full package path name of the library, and then .name of the function, or you can even, as youll see in the source code examples in subsequent units, you can even declare like a shortcut name for that so you dont have to repeat the whole path each time you call a function. And this is a great way to reuse existing open source examples, open source code, and third-party JavaScript code. I personally use this, Ive gone out to the Internet and found some great JavaScript samples. Using some the other day to do some decode encode from Base64, there was an example of creating a zip file, zipped content and compressing content. These were open source and just example JavaScript code. We were able to just cut and paste the code from the online repository or the Web page that it came from and put it in an XSJS lib, and then its perfectly functional inside the server-side JavaScript as well. This is also a great way if you have repetitive tasks like handling of forms or conversion of day time strings or parsing URLs that you could put in one of these XSJS libraries, and its a nice way of reusing this code so youre not cutting and pasting it into each of your applications. I did this one the other day. I needed a little function that would add a day or add any arbitrary amount of time to a time stamp, and I needed that in two or three applications. I didnt want to cut and paste the code. It was only three or four lines of code but it was still better to put it into a reusable function in one of this server-side JavaScript libraries and then its easily reusable for multiple applications. So you see with the syntax how we can import these libraries into other XSJS applications and then its very easy to call functions from that reusable library. So in this unit we have given you your first introduction to the concept of server-side JavaScript talked a little bit about how the architecture works, the APIs that are available, and how we can create reusable libraries. In the subsequent units well go into the system and well start creating some example code. Well show you what the development environment looks like, how we then consume these services from the client-side JavaScript of SAPUI5, and then finally how we can debug our server-side JavaScript code.

00:14:11

00:14:24

00:14:54

00:15:31

00:16:21

00:16:41

00:16:55

00:17:07

00:17:20

00:17:36

Page 5

Copyright/Trademark

WEEK 5, UNIT 2 00:00:13 This is week five, unit two: Creating an XSJS Service. So in the previous unit we saw a lot of fundamental concepts about server-side JavaScript and how it can be used , when it can be used, and just a little about the syntax. In this unit were going to go into the system and were going to create our first simple server-side JavaScript service. This will be mostly focused on just working with the APIs and development environment. Were not going to create something that is fabulously powerful, but is a simple example to get us started. In the subsequent units well have more complex examples. So first of all well use the HANA studio. And we do have a file new wizard for the server-side JavaScript. We have one for creating the source file which is an executable server-side JavaScript service end point, and we have a separate wizard XS JavaScript library file, thats for creating the reusable libraries that we spoke about at the end of the previous unit. So this will create the .xsjs source file and this is where we can put all of our application logic. We then commit and activate it just like all the other development artifacts that weve worked with so far. And then, of course, youll have a service end point thats reachable via HTTP or HTTPS. We can then write a user interface on top of that, well see that as well in a subsequent unit. We can also just go out to the Web browser and directly test our service end point. In this example were going to keep it really simple, were going to have a service that takes in two parameters, two numbers, and were going to multiply them together and then put the results into the body of the response object. Now, not that you would ever have to come back to the server to be able to do multiplication, its certainly something you could do on the client side, but I intentionally wanted to choose a very simple example to start with so that you can focus on things like: How can we get URL parameters out of the request project? How do we write into the response body? How can we handle error situations? without really having to get deep into a lot of Java syntax or any complex calculations or anything like that on the Java server side. You notice here were also not interacting with the database yet so in this example were simply going to use the request and response APIs and in a later example well show you how to interact with the database. Obviously, most times when you have a server-side JavaScript service, youre going to be doing something with the database. Otherwise why would it be running on SAP HANA? The end result is well have one function to perform the multiplication, and theres various variables well have in there to hold the two numbers that well bring in. The answer to the multiplication, a variable to hold our commandbecause also from the URL parameter well pass in which command we want. This way we can have a single service endpoint that does multiple things and for our test well start off with one that does multiplication and then were going to add additional functions to it in subsequent units. Finally we have the body. This is where we can build up the content we want to inject into the response body. Anything that goes into the HTTP response body will be displayed by the Web browser. Well see this when we test our service in the Web browser. So at this point lets go back over to the HANA studio, Im in my SAP HANA dDvelopment perspective. Im going to switch to the Project Explorer and of course I have the project that

00:00:37

00:00:55

00:01:22

00:01:59

00:02:15

00:02:53

00:03:17

00:03:47

00:04:06

Page 6

Copyright/Trademark

weve been working on all along. Now Im going to add to the services folder. This is where Ive already created our XS OData service. Now were going to extend it and add some server-side JavaScript services as well. So from this package Ill say New>Other and then I can come down here and under SAP HANA Development we see the various wizards we have, similar to much earlier when we created the role via one of the wizards. 00:04:48 We have a dedicated wizard here for the XS JavaScript source file. I just say Next. Youll notice that I already put a file name in here but it has the .xsjs file extension already on the end of it. Well just say Example1. It doesnt really matter what I name the service other than that this will be part of the URL that we call later. Say Finish and this opens in the XSJS editor. And you remember early on when we created our project, we created an XS project. And part of the reason we did that is so we can get these JavaScript resources. These JavaScript resources show us what ECMA3 basic features we have in the JavaScript language. You wont find all of this in SAPs documentation. In our online documentation, we only document the APIs which we add to the JavaScript VM. There are lots of standard capabilities built into the JavaScript VM being able to do math, being able to do text manipulation, and so forth. All these APIs are available here. We can see information about them. We can even drill-in to them and well see the interface for these functions, so thats the standard. In our built-in library, these are additional features that we see here, here we have Math, complex math functions, Number, Object, Regular Expressions built into the language itself. These are also all coming from the standard JavaScript VM. Lets go back to our example, at this point Im going to cut and paste in my code and then well talk about it. You notice that I get nice code syntax formatting here, it helps with the readability of the code. Now what we usually do with our server-side JavaScript is that we have to list all of our functions first, but the block of code at the end of all our functions list, thats where the program execution comes in. So when a web browser will access this Example1.xsjs, the processing will start here. The first thing that were going to do is were going to use the API. All our APIs start with the dollar sign, so $.request. So were going to access the HTTP request object. and then were using the parameters objects, were saying those are any url parameters that were passed in. Were saying get the parameter named CMD. So this is where from a programming standpoint there is no set definition of parameters, unlike OData where the OData specification decides what the parameter name should be. You as the developer have to decide which parameters you expect and then correspondingly use the same parameter names when you call the service. In this case, Ive decided I want a parameter named cmd and thats where Im going to pass in which operation I want to perform. I then go into a case on that cmd or whatever value that Ive pulled out of that URL parameter and when its multiplied, Im going to branch into this function to perform multiply. If I pass something thats completely invalid, if I didnt pass multiply into cmd, then Im going to set the response. status and we have some built-in constants to be able to tell it thats the code for error, thats HTTP500, status code 500, and then the response. setBody will put

00:05:17

00:05:48

00:06:27

00:06:54

00:07:30

00:08:04

00:08:22

00:08:44

Page 7

Copyright/Trademark

content directly back in the body. So Im going to say Invalid Command and take whatever was passed back in and put it back in to that error message. 00:09:17 Now in the performMultiply, this is going to be relatively simple, were going to get the URL parameter named num1. Were going to get the url parameter num2. Were going to multiply them both together and put the results in answer. And then answer would be a numeric at this point, but we want to cast it into this body, which is a string, so were going to say answer.toString. And then the body will be set into the response body and if we got this far and everything is okay. Well use net.http. OK, so itll be HTTP status code 200 will go back to the client. So lets go ahead and save our service and we will activate it. So at the time of activation, if I have any syntax errors thats when it would tell me. If I were to come here and put in something thats syntactically incorrectalready I have a warning here that Im missing a semicolon. But lets go ahead and try and activate this. This should produce a nice hard error here. There we are. It let me know that I have errors, do I want to activate anyway? I can see the results of the syntax check. It expected a semicolon, instead its all body. Line 8 position 27, so I know exactly where my problem is. So I can go ahead (of course, I put that line in, knowing it was bad, to demonstrate what the syntax errors look like) and correct it, reactivate, and now everythings okay. So with that, once its activated, I have an executable service. I can go to the Web browser. I'll just open another tab here, go to my package path, which would be workshop.sessiona.00/services. But now I just put in Example1.xsjs. Ill put a question mark so I can start putting in my URL parameters, so cmd= multiply&num1=5&num2=10. I run my service and I get 50 back. No formatting because we arent putting any HTML tags in the body, were just putting that raw data, that answer.toString, so were converting the numeric value to a string, putting that string directly in the body. Therefore the browser gets that response so it does its best to display it exactly as we told it to. So once again, services, although we can test them from a Web browser, its not something we give to our end users to be able to run. This isnt how they would run the service. The service gets embedded into a larger overall user interface. Lets maybe make a mistake here. Lets change the command to a command we havent yet implemented multiply2. And well go ahead and run this and youll see, now I get my error code I get Invalid Command: multiply2. And if I were to go ahead and turn on the developer tools, and Ill refresh that, you see that I get a 500 Internal Server Error. So if I was calling this service say, via Ajax, as well do in the user interface, well be able to test the HTTP response status and right away we know weve got a 500, I go into some sort of error condition. If I correct this then it works correctly and I get a 200. So this has been a very simple example, but hopefully it's let you focus on how the mechanics of how we create a server-side JavaScript and what the basic program flow is. In the subsequent units, we will certainly get into more complex examples. Well interact with the database, well have some reusable libraries, and then well consume the service in the user interface.

00:09:41

00:11:02

00:11:25

00:12:14

00:12:41

00:12:57

00:13:45

Page 8

Copyright/Trademark

WEEK 5, UNIT 3 00:00:13 This is week five, unit three: Extending the XSJS Service. In this unit were going to take the XSJS service we built in the previous unit and then were going to add some more functionality to it. Were going to be able to access the database and then were going to take the data thats returned from the database, loop over it and format it, and create a text tabdelimited response body. 00:00:39 This also shows us how we can differentiate from the OData database services. In the case of the OData services, we can only return JSON or Atom XML format. Sometimes you might need a custom body format or to return binary content thats stored in the content repository. These are the kinds of things that server-side JavaScript can do for you. 00:01:03 At the end, we want the service to have an additional operation that will allow us to take our partner data and format it as text tab-delimited, so we can send it out as a file attachment and it will look like an Excel file that opens when we click on a link. This shows two things, not just the custom body format that I mentioned previously, but also with server-side JavaScript we have complete control over the HTTP headers. 00:01:34 Were able to set the proper HTTP headers so that this will not look like the main response body that will be displayed in the Web browser, but instead it will show that its a file attachment and the browser will treat it appropriately and therefore prompt us to open or save the file. And if we say Open, then it will open in Microsoft Excel. 00:01:55 The other thing that were going to introduce in this exercise is some reusable libraries. So I have already prepared a server-side JavaScript library that contains some processing for issuing error messages. So well see how we can use that inside our application and Ill even go into this library and have a look at the coding inside of it. 00:02:22 So well add a new function called downloadExcel. It will be responsible for retrieving the data from the database tables and views and then formatting that into text tab-delimited and then setting the proper headers so it will display in the Web browser as a file download with the Excel type. 00:02:42 In order to do that, well have to loop over the result set and concatenate together a string and put in the proper formatting as we pull the various pieces of data out of the record set and put it into that text tab-delimited string. 00:02:59 Well also have to set the custom HTTP headers, and so well have to set the contentType to tell it that this is Excel. Thats what the browser uses to know which application on the client side to open the content with. And well have to set the Content-Disposition header so we can say that this is an attachment and set the file name. 00:03:23 And then finally well also see how we can perform SQL queries. We have a JDBC or ODBClike syntax for executing SQL statements. We have a query object that we build up, make a connection to the database, do a prepared statement from that query, and then we execute the query. 00:03:46 Now its important to note that even though the syntax is like JDBC or ODBC, the execution is still quite different. So everything we told you earlier about the closeness of the extended application services to the SAP HANA database, thats all still true. Just because we use syntax that looks like JDBC/ODBC doesnt mean that the data has to be transformed or its been sent across the network or anything like that.

Page 9

Copyright/Trademark

00:04:13 We simply wanted the programming interface to look familiar to developers. In reality the SQL statement is being preprocessed inside the XS Engine and theres some direct communication to the index server going on. Very efficient processing of this query, very efficient processing of the results set that comes back. 00:04:32 Youll notice that when we execute the query, were putting it back into an object, this rs object. That is a special API weve added to the JavaScript VM to represent results sets, to represent data thats being returned from the database. As long as the data stays in that results set, it stays in its HANA-native data type format. 00:04:53 Once again, no data transformations have to take place as the data is returned to the application server. Lets go into the system now and lets extend our example. So lets pull this back up again to refresh what we had in the previous unit. Our processing comes in at this point. We look at our URL parameters and get the action we want to perform from the cmd. In this case, we only have the one, which was multiply. We branch into our performMultiply function and we very quickly do our multiplication of two import parameters and put them into the body. 00:05:33 So lets go back over here, let me add two things right away. Let me first add this import statement, so $.import. And then I give it the package path and the file name. So Im saying import from SAP.hana.democontent.epm.services. So here I have SAP.hana.democontent.epm, so this is the project that thats in and I said services and then I said messages, so that's this messages.xsjslib, thats the content that were pulling in. 00:06:11 So well now have access to all the functions in here, the escape and the getMessage functions. And like I said earlier, we can call those functions by specifying this whole long string here. We can also create almost like an alias for this path, so Im going to say var MESSAGES and MESSAGES=$.sap.hana.democontent.epm.services.messages. 00:06:38 Now we have easy access to call those functions via the shorter name of MESSAGES. And Ill actually use that right away. Lets rewrite this error handling, so lets and change this error handling. The status is the same, but now in the set body well call MESSAGES.get Message and well pass a message class and a message number and any variables we want to parse into that message. 00:07:13 What this allows us to do is do language-independent error message processing. So instead of hard coding the text in here Im going to have this reusable function called getMessage that will go to the database and will look up the error message for this message class and this message number, for the current logon language. 00:07:32 If no message exists for that logon language, then itll fall back to English and then itll take the resulting error message and itll parse in any parameters that we have here. So lets see how this is done, well bring up this messages.xsjslib. Inside here we expect messageClass, messageNumber, and up to four parameters that can be parsed into the error message. 00:07:59 Then well use another API that we havent seen yet, $.session. So this is where we can get information about the user session. Im going to use this to get the current language and just to be safe; Im just going to get the first two characters of the language. Next Ill get a connection to the database. Now with the getConnection, youll notice that I dont have to specify any connection string.

Page 10

Copyright/Trademark

00:08:25 In JDBC/ODBC you would, of course, have to specify something which would tell you what server to connect to, what port, what user name and password to use. Well XSJS knows that its living inside of HANA therefore when I say getConnection, it knows the database already and theres no functionality to do a getConnection to a foreign database. At least, thats not functionality we have yet. 00:08:48 The only reason we even really have this API getConnection is we can pass in a parameter here and that parameter would be the name of a SQL CC entry. The idea of a SQL CC entry is maybe you want an anonymous service, so I dont want the user to have to authenticate to my service. Thats fine, we can do that. You can go into your .XSaccess file and you can say authentication:null and then itll run as an anonymous service. It will not prompt for our user name and password. 00:09:23 But when you get in your code, we can execute JavaScript code but as soon as you try and go to the database, that will fail. You always have to have a user associated with your connection. The SQL CC is a tool you can set up and put a user name and password in this tool and save it with a unique ID. And in this getConnection you simply specify the SQL CC ID and that user name and password will be used automatically. 00:09:54 That avoids us having to hard code user name and password into our program code. I dont have an anonymous service, its using my user authentication on the Web browser so its going to run as my database user thats logged in. I don't need to specify anything in the getConnection. Next I have my SELECT statement. So Im selecting Description from table messages and youll notice here in the WHERE clause, Im saying message class=?, message number=?, and language=?. 00:10:28 So this is a parameterized query and you want to follow this pattern any time that you have WHERE conditions, particularly if the values for those WHERE conditions are coming from the client side or coming from outside the service. We want to protect against something called SQL injection. Thats where someone could maliciously call our service and force additional content into the parameters. 00:10:53 So you could imagine if maybe they would try to say here MessageClass= and we pass in a value and we just directly can concatenate that value in from outside. Someone might have maliciously overloaded that and said MessageClass=123 AND MessageClass= something else and be able to get access to more data than we intended them to have access to. 00:11:20 Well if we use the question mark and the parameterized query statement, then when we do the prepareStatement, we can take the prepareStatement and set those values in. So Ill say setString 1, meaning the first question mark, replace it with the value messageClass, and when I use the set functions of the prepared statement the system will automatically do a type check for me to make sure that the data coming in matches the data type of the parameter of the WHERE condition that Im matching it up to. 00:11:57 Well also safe encode the content thats coming in to make sure you cant add on additional information, like add on more WHERE conditions, like an AND or OR condition or something like that. So it protects you against SQL injection and as long as you use these prepareStatement set functions, youll be pretty safe against SQL injection. 00:12:22 If you just concatenate these values directly into the string, well, then youre vulnerable to SQL injection. So then well say executeQuery. We get a record set back. Now record sets, we always use a WHILE loop over record sets. We want to process it one record at a time.

Page 11

Copyright/Trademark

We can only do forward processing for a record set. Once Ive gone forward, once Ive read the next record, I can never go backward. 00:12:53 Theres no .previous or anything like that. You can think of it almost like a destructive read, if you will. The idea is if you need random access to the record set, you need to read a specific record, you loop through until you find that record. If you need to be able to go back and read a previous record youd actually have to have two record set objects. So it just means performing the query twice. Because its an in-memory database, and we have efficient data transfer we can do things like that and it doesnt come at a high cost. 00:13:26 So all were doing here is were saying get rs.next, so thats going to get us the first record. And then were going to get a string parameter out of there, so get the first value, which is just the text because we said SELECT description. So the getNString(1) there is going to get the first field thats in the record set, which was only one, its a description. Put it in our message text. If the message text is blank then we can assume that there was no record in the database for whatever language we were logged in as or maybe that was a record, but somebody hasnt maintained any text for it. Either way we wanted to try going to English instead. 00:14:10 So you notice what we do here is we just switch the language to English. And this is another advantage to using the prepareStatement. I dont have to re-prepare the statement. I can use the same prepareStatement, just reset the values into it, and then perform the query again. This can lead to much more efficient processing particularly if youre firing the same query over and over again inside of a loop. 00:14:32 Although if youre going to do a large number of operations like that we also have the idea of batching. So you can do a special type of prepareStatement that is set as a batch, add a bunch of operations to that batch and then instead of execute query you have instead execute batch. And when you use the execute batch it will send all the requests to the database as a bundle. 00:14:56 The database can process them in a parallel fashion and return the results back to the application server. In this case, were just going to re-execute the query and this time were going to get the string value back, even if it was blank at this point were going to just have to issue a blank error message to the user. 00:15:14 Well close our record set. Well close our prepareStatement. And now we do our concatenation. Remember we had four parameters that are passed in that we might want to replace in the string, and we just set this rule that if inside the text of the error message we just use an &1, &2, &3, and &4 to be placeholders for values that might be passed in. 00:15:37 So in this case were going to say replace &1 with whatever p1toString is and we do escaping on it. This is to make sure that were taking a parameter thats passed in from the user interface that once again, somebody doesnt do something malicious. Somebody could potentially pass say, JavaScript or HTML or a hyperlink that says, Youve committed an error, click here that could redirect them to a malicious site, a phishing Web site. 00:16:11 We want to protect against that sort of thing so we want to safe encode anything that came in, so basically replacing the HTML tags so that theyll show up as comments instead of being interpreted by the Web browser. So this is the other nice thing about having a reusable library is that we can build in things like automatic escaping and then we dont have to do that every place in our code.

Page 12

Copyright/Trademark

00:16:34 So for instance now we have our MESSAGES.getMessage and now we have the safe encoding of this aCmd, so whatever value is being passed in via this cmd user parameter. So lets get the rest of our code. We want to add an additional case statement for Excel, for our download to Excel, and now lets add our function. 00:17:02 That processes our download to Excel. There we are, lets walk through what this is doing. So were building our query similar to what we did in our messages.xsjslib. Were going to retrieve the top 25,000 records. Simply for the purpose of the demonstration I didnt want to download too much data to Excel, you wouldnt necessarily want to send millions of records to Excel. I guess you could get more sophisticated here and have various filters and WHERE conditions passed in. 00:17:39 Once again, this is a demonstration. Lets focus more on the formatting of the data and how were passing it down and not really on how Im giving the data. But Im getting 25,000 records, choosing the fields that I want from the purchaseOrderHeaderExt view, and Im ordering them by purchase order ID. 00:18:00 Now Im using the trace statement here. This is another API. If Im having problems with the program, if trace is activated and I go into the system configuration and Id set the trace level for the XS Engine to debug, then whatevers the query string will be written into the trace log and I could then observe that. So even without debugging, if something was going wrong I could see, well, is it my query thats wrong? 00:18:30 Now this is a hard-coded query. It has no parameters coming into it, so maybe thats not all that valuable, but sometimes its nice to have these trace statements in and theres other trace levels that you can set as well, information, warning, error, and so forth. So I get my connection to the database, prepare my statement with my query, and then Ill execute that query. 00:18:55 So in the body now I want to build column headers. And I want those column headers to be language-independent as well. So Im actually reusing my messages and this time Im not getting error messages, Im just getting a plain text block with the column headers that I want. Im going to concatenate those altogether and just make them text tab-delimited, so the \t in JavaScript is the way we insert a tab. 00:19:21 Then Im going to loop over my record set and want to concatenate it together, so Im just going to take each of the fields here and concatenate them separated by the tab, at the end, a carriage return, the \n. I do have some error handling, so this entire block is inside of a try block so if anything goes wrong then Im going to go in here, Im going to catch the error, and then all Im really doing is taking that error message and Im outputting it in the body. 00:19:49 But I am setting the internal server error as well. So if something would be wrong with the database connection, my authorizations, maybe one of my data types was cast wrong here or something like that, it would all be caught by this error exception handling. If there were no errors then I can go ahead and set the string into the body. Ill set the content type. This is how the browser will know that this is Excel. 00:20:14 Ill set a custom header, the Content-Disposition header, and that will let the browser know that this going to come down as a file attachment and what the file name should be. And then this other header, access-control-allow-origin, this is for cross-site scripting. This would allow this service to be callable if the Web page was running on a different server than what the

Page 13

Copyright/Trademark

service is running on. 00:20:39 Now Im going to consume this later in SAPUI5. The UI5 is running on the same server, so I would not need this control allow origin but if I were say, to call this from a mobile device and I had HTML running in the hybrid container from the SAP mobile platform, then that would be a cross-domain access. 00:21:02 Or if I had a Web page or a .NET Web page running on a .NET server and it was going to consume the service, then Im going to have a different URL for the Web server than I have for the service. And once again I would have cross-site access and I would need this additional line in the header to set that. 00:21:20 That completes our service, so lets go ahead and save it. And we will reactivate it and now we can go to the Web browser and lets re-run our test. Lets put in our package path and now instead of multiply we will say Excel and I think I did, capital E, so Excel. Ill just make my browser a little larger there. And you notice that the file attachment comes down. We have the open option here so Ill go ahead and open that. 00:22:07 And then Microsoft Excel will open and Im just getting that warning because its text tabdelimited and now I have my data down here opened in Excel. And youll notice that weve even got some nice formatting here, like on the Created At, we get this nice long name. Its taken the time stamp and re-formatted it, and that came from the if we go back to the studio...that came from the automatic processing when we said getDate. It didnt just take the raw date format and insert it. It really turned it into its string representation so we get some of this automatic type casting and formatting applied when we pull the data out of the record set and basically put it back into a JavaScript variable, in this case concatenating it into a JavaScript variable. 00:23:01 So in this unit weve seen a more complex example, weve seen how to use re-usable libraries, how to connect to the database, and the benefits of having this lower-level access to be able to write custom body formats into the HTTP response as well as set the HTTP headers.

Page 14

Copyright/Trademark

WEEK 5, UNIT 4 00:00:13 This is week five, unit four: Calling XSJS from the User Interface. So far this week weve seen the basics on how to create server-side JavaScript-based REST services. In this unit we want to build a user interface using SAPUI5 that will consume these services. Were actually going to take that very first simple service that we had that took two input parameters and multiply them together and display the result. So lets take a build a user interface for that. That means well have a fairly simple user interface that has two input fields. Well use the live change event on those input fields so that every time I type something into them, every character will trigger a call to the server asynchronous, execute the server side JavaScript and display the results in the screen. Well also format those results so that the numeric value is formatted correctly according to the users logon locale. To do this well take our existing SAPUI5 project from the previous weeks. Well extend it and add a new view to it. And well copy the HTML file that is the bootstrap. Well just make a couple of changes to that bootstrap file to point to the new view and then most of our logic will be in the view and the controller. Unlike our previous exercises where we didnt use the controller, this time we will use the controller because SAPUI5 doesnt necessarily have a built-in event that knows how to call our custom service, so we wouldnt expect it to. So this is a nice contrast to our OData UI where we had an SAPUI5 control and of course, it knew how to call standard OData services. The table control could be bound to it. This time we have to custom code the event handler, which is not all that difficult to do, and youll see how we use the jQuery.ajax to asynchronously call to the server and execute our service. And that will really be the focus of what we code on the client side. Well build a URL that points to our service with the proper command and multiply and the two import parameters parsed into that URL, and then well call jQuery.ajax to that URL and if the call is successful it will branch into the onCompleteMultiply function. And if its not successful then well go to the onErrorCall. Let's switch over to the system and well have our Example1.xsjs service that were going to call. Lets go to our user interface: Project, which remember, is embedded inside of our larger project and well tell it that we want a new view. Itll launch the wizard for this and well call this xsjsTest, say Finish, and well see now inside our exercise UI weve got a new XSJS controller and a new view. We just need to copy the HTML file so now we have our xsjsTest.html. Inside here we just need to make a little change so we can change the ID. Like I said earlier, that isnt absolutely necessary, but I like to do it to keep my IDs consistent with the name of the objects they represent. But here well change the name of the controller, xsjsTest, so our HTML file is good. Now if we go to our view...once again, Im just going to cut and paste the code because you do not want to watch me type, no fun in that. We come here to the createContent. Thats where we do all of our rendering. And lets talk about what weve just put in here. First of all, I want a panel. A panel is just a grouping UI element. It has a nice expand/collapse capability and well have the ability to set some text in

00:00:35

00:00:48

00:01:12

00:01:33

00:02:01

00:02:27

00:02:57

00:03:18

00:04:05

00:04:27

Page 15

Copyright/Trademark

the description of the panel. 00:04:48 Well set some other properties. Well set the AreaDesign to Fill, the BorderDesign to Box. These are all cosmetic features/cosmetic properties that were setting of the panel. Then inside the panel we create a layout. Layout is how inner UI elements will be arranged. Were going to use the Matrix layout but there are other layouts available depending upon whether you want a flow-based organization of the inner UI elements. Im just saying Matrix auto, and then it will evenly position based on the number of columns that I have in here. So I add the layout to my panel, but then inside the layout itself Im going to want to render a TextField for val1 and val2, and then a TextView to show the results. A TextView for the equals sign and a TextView for the multiply sign. Now Ill take the text fields, the actual input fields, and I want to attach an event to them. So Im going to say, attach the liveChange event. And this is where Im going to use the controller because Im going to say, any time the liveChange event occurs on this field, trigger the onLiveChageV1 function inside my controller object. oController represents my controller, which right now is empty but were going to have to add these functions to it. And then the same thing with the second field. It just goes to a different live change event. Well say Layout>Create row. So this is the order that all the UI elements be rendered in. And then we return the panel and it gets rendered into the page. So thats our user interface, so now lets bring up our controller. So once again, lets cut and paste here, back to my controller. These are all standard event handlers in the controller so onInit, BeforeRendering, AfterRendering, onExit. So if you want to implement the standard event handlers that are controlled by the SAPUI5 framework, you can. In our case, we really just need our onLiveChangeV1 and onLiveChangeV2. In these cases were going to build up the URL. I just need to adjust this because I named my service Example1. Im building up to say cmd=multiply. Im taking num1= ...and I want to escape this so its properly escaped for putting into a URL. Then I say Event.getParameters( ).liveValue, so whichever UI element triggered the event we have to use the .liveValue to get the currently typed value. We cant just go and read the value in the UI element. The event is actually occurring before the value is put back into the screen. But then for the field that it isnt being typed into we can just say getValue. Thats why we needed two different event handlers, to be able to trigger this differently for the two different fields. All were doing here is saying now num1 is getValue whereas num2 is the Event.getParameters( ).liveValue. Once we have our URL pointing to our service then we use standard jQuery.ajax. This is what we were talking about earlier, a couple of weeks ago, when we first introduced SAPUI5 and we said SAPUI5 is based upon jQuery, and anytime that jQuery had some functionality that was sufficient we just use it, theres no reason to replace it with anything SAP-specific. Therefore to make an asynchronous javaScript request, an AJAX request, we simply use jQuery.ajax. We give it the URL, its a GET method, we expect JSON to be returned. Its really just standard text but it really doesnt matter and then, if its just successfulin other

00:05:26

00:05:50

00:06:21

00:06:50

00:07:11

00:07:52

00:08:12

00:08:34

00:09:00

Page 16

Copyright/Trademark

words, if the HTTP status code is 200then branch to onCompleteMultiply. If we get any sort of error code back then we go to onErrorCall. 00:09:28 And the nice thing about this is that it then releases processing. The browsers open and available for the user to go on working. If this service takes a couple of seconds to process it doesnt lock the Web browser. Theres no wait clock or anything like that. But of course the service wont take a couple of seconds to process, its going to process very quickly. If we had an error, we would branch down to the onErrorCall and the jQuery.ajax will build some additional parameters in here. Its going to pass this jqXHR, which is going to have information about the error message, textStatus and the errorThrown. So these are all things that the jQuery.Ajax will extract out of the response object for us. Here Im just calling the SAPUI5 MessageBox.show, and Im putting whatever error message came back in the body into the screen. In the onCompleteMultiply, if everything worked correctly, well take the result so we can say sap.ui.getCore( ).byId(result). So this is how we access any UI element thats already rendered on the screen. This oResult will be the UI element; the sap.ui.getCore is a core API of SAPUI5 and is a helper to be able to give us a JavaScript object for a particular UI element on the screen. Were then able to say if(myTxt==undefined, then that meant there was some sort of error that wasnt caught. We really didnt get any result back because myTxt will have the textual body of the response object in it and therefore as long as thats not undefined, well put the result back into the oResults. If it is undefined, then well go ahead and just put it back into the result that will let the user know that basically something went wrong, and it will replace the current value thats there. If it was good, then we go ahead and use jQuery.ajax.require, so were going to load an additional library at this point, the SAPUI5 core number formatter. And then were going to use this number formatter to say that this is an integer instance, that the maximum number of digits is 12, that grouping is enabled. Therefore, using those settings and the jQuery formatter will also look up our locale, will properly format that number, putting in commas and decimal points and things like that. Once its been formatted, we can take that text, format it, and put it back in the screen using the oResults.setText. So at this point lets go ahead and save both of these objects. I do the Save all and now in our UI we can activate our HTML, our controller, and our view. Its activating all three objects. Theyre all active so now I can go back to the user interface here, workshop.sessiona.00/ui/Exercises_UI/WebContent/xsjsTest.html. So we see our panel being rendered. Thats the title, the title is here with the blue line and the little notch that lets us expand and contract it. And if I begin typing, already you see that Im getting some values here. Its actually executing the service here, every time I type. Now I havent put a value in the other side so any number times 00, as soon as I put a number in there, then we start to see it coming out. You notice the formatting automatically being applied. And every time that Im typing...just to show you this Ill turn on the developer tools and youll see each request going across the network. The number gets increasingly large so you see the request being fired. If I put in a non-numeric field Im not catching that on the server. Remember our logic was very simplistic.

00:09:49

00:10:18

00:11:04

00:11:42

00:12:31

00:12:52

00:13:28

00:13:56

Page 17

Copyright/Trademark

00:14:27

I really, probably, should have some logic to do some type checking on the server to make sure Im not trying to multiply a character field with a numeric field. Im getting a Not Defined error because I didnt catch it on the server side, but you do at least see the error status and then I get my pop-up so Im going into my onErrorCall and I get my dialog here, so this is a nice SAPUI5 dialog error message. Now, the message itself is not very nice but once again, thats because I didnt have very good handling on the server side to throw a proper error message when that occurred. But I can recover gracefully and now Im back to multiplying. So in this unit weve seen how we can build an SAPUI5 user interface that will consume our custom XSJS services. Weve seen how jQuery is used to call these services using asynchronous JavaScript. And hopefully you have a much better idea of the end-to-end process of both using XSJS to create these services, but also how theyre consumed in the user interface.

00:14:55

00:15:11

Page 18

Copyright/Trademark

WEEK 5, UNIT 5 00:00:00 Welcome to week five unit five: debugging server-side JavaScript. Any good development environment of course needs good debugging tools. 00:00:10 We've already seen in SAP HANA Native Development the SQLScript debugger, and in this unit we will see the interactive debugger for server-side JavaScript. 00:00:20 We will show you a little bit about the onetime prerequisites you have to do to set up JavaScript debugging in your system, 00:00:30 we will talk about some of the differences that have been made to the server-side JavaScript debugging in SP6, as opposed to when it was first introduced in SP5, 00:00:40 and we will show you some demos of how you can perform debugging both from the SAP HANA studio tools as well as the new Web-based IDE. 00:00:51 So let's talk about the administrative setup you have to do to be able to enable debugging of server-side JavaScript in HANA. 00:00:59 A lot has changed from SP5 to SP6 in the area of debugging of server-side JavaScript. In SP5 we had to not only enable the debugger, but we had to list the specific port that it ran on. 00:01:14 Well now, in SP6 we use Web sockets and therefore we debug over the http port. 00:01:21 So we no longer have to specify a separate port. This also means that you can keep the debugger enabled, and it's not nearly as much of a security risk as it was in SP5. 00:01:33 In SP5 we debugged basically as an un-authenticated super user. Therefore we said you should really only turn on debugging on nonproductive systems and for a very brief amount of time just while youre debugging, and then immediately turn it back off. 00:01:53 And you should also protect that port at the firewall level. Well now because we're debugging with Web sockets, we authenticate the user so that the user running the application will be the one that's debugging it. 00:02:06 And that that means that we can more safely keep the debugger enabled, and it also means that we need a special authorization on our user ID to be able to debug. 00:02:17 And thats what we see here in this slide, in the configuration under the xsengine / ini section you need to have a section for debugger, and then you need to add the parameter enabled, and it need to be equal to true, 00:02:31 and then your user needs the new debugger role added to it. Now lets go into the system and Ill show you where each of these items are set up. 00:02:46 So here I am in the HANA studio and I will go to my system connection, Ill go to administration; and this the kind of thing your developer user may not be able to do in your system. 00:03:00 You may have to ask the system admin to do the initial debugger setup, the enablement, but this should likely now be a onetime type activity and you could, in your development system, at least, keep the debugging turned on. 00:03:13 So from the system information screen, we can go to Configuration and then xsengine.ini, and then we would open the debugger section, 00:03:31 or you might have to add it, - you might have to right mouse click here and say Add Section, and then you'd have this Debugger section and then we see Enabled and we have it marked as true. 00:03:44 So this system is able to do debugging, and then Ill come back over here; I want to look at my user ID as well, so I go to the Security tab and Ill look at my openSAP user. 00:03:47 Now I dont have this role directly assigned to my user. That's OK because we've actually created this workshop role that grants us all the necessary access to do all the activities in the
Page 19 Copyright/Trademark

workshop, 00:04:12 and when we drill into this workshop role youll notice that it actually has many roles assigned to it, many standard roles in some other ones that weve created, but it most importantly has this debugger role that our user will need in order to do debugging. 00:04:30 We then also need to create a debugger configuration. We want to do this once on our developer machine for each system that were connected to. 00:04:39 So this is very similar to creating the SQL script debugger configuration, but unlike the SQL script debugger configuration, we don't have to put in the exact object that were debugging or input parameters or anything like that. 00:04:54 Here we simply supply the system host name, the http port that your system is running on - and that will be 80 - and then the instance number of your system, and then you supply the username and password you want to debug under. 00:05:11 Now lets go into system and have a look at the creation of this debug configuration. So I'll come here to the Debug button, 00:05:23 and choose Debug Configurations you can see all the configuration types that we have listed here - and Im wanting to do server-side JavaScript, so Ill just say New 00:05:38 I can name this configuration, and then Ill give it my host name and then my port number - my instance that I'm running on is actually instance 50, so my http port will be 8050 - and then my username and password. 00:06:10 And then Ill say Apply. At this point we could go ahead and start debugging, but we haven't set any breakpoints yet: we'll see all that in a moment. For now, just go ahead and close out the debug configuration, and its ready for us as soon as we want to start debugging. 00:06:23 Once we start the debugger itself you'll see a screen just like the one in this presentation. This is the standard Eclipse debugger, and it has many configurable features. For instance, you can control whether you want to see the breakpoints, you want to view the variables, you want an outline of the source code block that your debugging within, 00:06:45 and we'll see all this in action in the system in just a moment. 00:06:51 Now when we debug inside server-side JavaScript code we can go to the xsjs editor, so we simply open one of our server-side JavaScript artifacts or an xsjs library file 00:07:05 and we set a breakpoint in the code or multiple breakpoints, and then we're ready to begin debugging. 00:07:13 When we start the debugger, it's going to ask us for a session ID. It will bring up a list of all the session IDs that are currently active in the system for your user ID. 00:07:24 Now the little trick I will show you for getting this session ID is basically you go to your Web browser, and you use some form of developer tools in the Web browser to be able to get the session ID, because it's displayed in a Web browser has a cookie. 00:07:39 So we'll see this session ID Cookie, we'll be able to match it up with one of the session IDs on the server, and then we'll be able to start debugging. 00:07:50 From that point well stop at our first breakpoint, well have the ability to look at the various variables and their values, to stop and start the debugger, pause, resume, skip ahead to another breakpoint - all the kinds of things youd expect in an interactive debugger. 00:08:09 So once weve stopped at a breakpoint, or if we want to enable a breakpoint we can do this quite simply, we can double-click in the little bar area in the left inside our editor, 00:08:22 that will toggle the breakpoint, or we can right mouse click in that same area and set the

Page 20

Copyright/Trademark

breakpoint as well. 00:08:29 And once the debugger is running we have the ability to go to the Variables tab, and we can find variables and a list of all the possible variables. 00:08:40 We also see our variable values, for instance here we have a query, and well look at the value thats in that query, and we even have the ability to change those variables during debug time. 00:08:52 And its often quite useful when debugging to change the values and see the impact that it has on the running program. 00:09:01 So let's go back to the HANA studio and see the debugger in action. So switch back over to the Project Explorer and go into the project we've been working in and to the Example1.xsjs service that we've built up so far 00:09:19 and its in this perform multiply function that I want to set some breakpoints and debug it. To set breakpoints you can simply double-click in the little left and bar next to the line numbers 00:09:36 or you can right mouse click and choose toggle breakpoint. Let's go ahead and set a couple of breakpoints. Were ready to debug. I can go and start the debugger, but like I said earlier the first thing it will ask you for is a session ID, 00:09:53 and we want to go ahead and look up that session ID in the browser. 00:10:03 So a couple of things I want to do here; I want to first turn on the developer tools, so: Tools>Developer Tools. Im doing this in Chrome. 00:10:14 Now I like the Chrome developer tools because they're built in; I don't need any additional addons or installations. Similar tools are available for all the other browsers, though. 00:10:28 So lets put in our path to the service: workshop session a, group 00, and services Example1.xsjs, and then the command Multiply, and my two input parameters num1 and num2. 00:11:06 There we are. Now I will go ahead and run that service and I see my results. 00:11:14 And if I click on that request and I look at the headers I can also see my session ID. 00:11:25 So here is this xsSessionID it begins B-F-D 830. I don't have to remember the whole thing, but this is what I'm going to have to choose when I start the debugger. 00:11:37 So now, if I come back to the studio, I go to the Debug tab, and Im going to go ahead and start the debugger for the configuration I created previously. 00:11:50 You notice it comes up and it asks me, or gives me a list of session IDs for my user, and if I look once again, I want session ID B-F-D 830, already I can see, theres that session. 00:12:09 This is the one I want to debug, so Ill select that. And the debugger is now running. Now I dont go immediately into the debugger. Its obviously not until I trigger another request from the client side that the debugger will start. 00:12:22 At this point I could go ahead and just do a refresh and now the debugger is running. You notice that the browser is waiting, its running, its made a request to the server and its sitting and waiting for the response. 00:12:34 The server has started execution of this XSJS service and it has stopped here on my first breakpoint. 00:12:41 Now at this point I can go ahead and step into, step over, so I can go to my next breakpoint, and we see already here that num1 and num2 have values. I can see that in my variables - 5 and 10 the two values that came in. 00:12:58 I can see that answer has a value of 50 and for instance here, I could change this value. I've clicked on it and changed it and this should change the output result.

Page 21

Copyright/Trademark

00:13:13 We can now step forward and the response is going to go back and in step return that exits completely out of the debugger and returns control to the desktop, 00:13:27 and there we see the answer 51, which is obviously not correct. 5 times 10 isn't 51 but we see the impact we've had via the debugger. 00:13:37 Now I want to show you one additional way to debug, and that's using the SAP HANA Webbased Development Workbench. 00:13:45 So instead of starting in the HANA studio, we do have browser-based development tools as well now in SP6: we can do our editing, and we can also do our debugging of our server-side JavaScript from here as well. 00:13:58 And it has one major advantage, is that because the tools are running in the browser as well, we don't have to go and look up that session ID. The browsers going to know that session ID and automatically use it to debug the session that were currently in. 00:14:15 So the processes is rather similar. I don't have to create a debug configuration here either, I would simply go to my XSJS Service that I want to debug, and I would go ahead and set my breakpoints, 00:14:38 and now I can say Execute in a new browser window, and it gets an invalid command there, that's OK. 00:14:48 I just wanted to do that to get the URL. I actually want to type the rest of the parameters on the URL, and I'll do that from a new browser tab. 00:15:01 So there's a our command Multiply, and youll notice its doing the same thing; its stopped, its waiting, and were now if we return to the Web browser-based Development tab, 00:15:16 you see that we have stopped on our breakpoint. And we have very similar tools and capabilities here; we see that I have the same Variable view, I can now, if I step forward a little bit. 00:15:34 Lets just go and step forward, and now I have my two values ten and five, if I continue to step forward Ill see the multiplication into answers - there we get the results - 50 00:15:51 and if I continue processing - Ill just go ahead and step out - and its finished processing, and we see our results coming back. So very much the same tooling experience, very similar at least to what we have in the HANA studio, 00:16:07 but a little simpler workflow, plus the advantage that you would not have to check out the project in order to set the breakpoints and things like that; you can do everything from the Web browser.

Page 22

Copyright/Trademark

www.sap.com

2013 SAP AG or an SAP affiliate company. All rights reserved. No part of this publication may be reproduced or transmitted in any form or for any purpose without the express permission of SAP AG. The information contained herein may be changed without prior notice. Some software products marketed by SAP AG and its distributors contain proprietary software components of other software vendors. National product specifications may vary. These materials are provided by SAP AG and its affiliated companies ("SAP Group") for informational purposes only, without representation or warranty of any kind, and SAP Group shall not be liable for errors or omissions with respect to the materials. The only warranties for SAP Group products and services are those that are set forth in the express warranty statements accompanying such products and services, if any. Nothing herein should be construed as constituting an additional warranty. SAP and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP AG in Germany and other countries. Please see http://www.sap.com/corporate-en/legal/copyright/index.epx for additional trademark information and notices.

You might also like