SAP iXp Summit 2017

SAP’s Internship Experience Project (iXp) focuses on providing a best-in-class intern experience and assigning impactful projects in strategic areas of SAP’s business. This project is built based on the idea that through placing passionate people on the right teams, providing leadership and learning opportunities, and working on impactful projects, purpose is born.

My eyes widened at the sight of scrambled eggs served as part of our breakfast buffet, but little did I know, that was the just the beginning of the one and only, SAP iXp Summit 2017.

 

The summit was held at The Pinnacle Hotel Harbourfront— a truly stunning hotel in the heart of Downtown, Vancouver. The glimpse of sunshine in the middle of a gloomy November shone through the tall windows that filled the walls of the venue, and just like that, we kickstarted the summit with speakers and an applicational design thinking activity.

 

Along with the incredible Don Wakefield and Janet Wood, Kirsten Sutton— the Global Head of Engineering for SAP Jam spoke about the art of creating meaningful connections throughout our careers. This resonated with me because as an intern on the SAP Jam team, it was an honour to be able to pick Kirsten’s brain, and to my relief, I was thoroughly impressed and her panel exceeded my expectations. I left the panel with my mind bubbling with ideas, and a stronger understanding of why I, even as an intern, should make conscious efforts to broaden my network. Kelsy Trigg followed and gave a talk titled “Lessons from the Mountains”, where she spoke about her story of completing the Transalpine-Run— a 7 day trip to traverse the Alps. The journey was a tough one, but she what she took away from it and later on taught us, was well worth the journey. She put into perspective the behind the scenes of hardwork hiding in the corner of everyone’s success, and most importantly, she reminded us to celebrate every step of the way as we climb our own mountains.

 

We then wrapped up day 1 with a challenge to build a mini golf course. However, the golf course was to be made entirely of rationed nonperishable foods, which were later on donated to the Greater Vancouver Food Bank. Every team made up their own unique golf courses. Fom a journey to save the princess, to recreating the life of an intern with nothing more than canned food and some cardboard, I was in awe of the creativity that filled the room. I felt humbled to be standing amongst these brilliant students who were passionate about making a difference in the technology community. Day 1 of the summit left me feeling inspired, and I just couldn’t wait for what was to come.

 

Day 2 started off with a deep dive into SAP Leonardo (again, with a side of scrambled eggs). As an intern, it can be overwhelming to think about the hundreds of products that SAP builds and maintains. Therefore, it was helpful to be able to gradually gain an understanding of some of our core products by learning about each speaker’s role in the community, and the awesome solutions they were working on.

We then jumped into activities with folks from the Vancouver TheatreSports League. As someone who grew up watching their shows at Granville Island, I was ecstatic to be able to try my hand at some improv. Despite my excitement, I was nervous and every activity that we did pushed me comfortably out of my comfort zone. I was proud of myself for being able to live in the moment. I let go of the worries of being judged by others and I just had fun. But my favourite part about all this was how every activity tied into actions we could take in the work place to communicate with our co-workers more effectively, and with trust. At the end of the day, trusting that while you’ll do everything you can to help your co-workers, like actors in an improv act, you know that they too, will return the favour.

 

Lunch on the 19th floor with the most beautiful view of our city was then followed by breakout sessions, where we optionally attended the workshops that we were interested in. I chose a workshop on authenticity and gained insight on how to advance in my career, while always being true to myself. This was important to me and I was glad to be able to have an open discussion about it. I also attended a workshop by Doug Beleznay and Jason Cao— “Why Emotional Intelligence Matters to You”. They defined the differences between empathy and sympathy and why empathy matters. I self identify as an empathetic developer— it was great to be reassured about what I know, but also to discover some gaps which I could improve on.

 

Jessica, our fantastic iXp lead closed the summit with bittersweet goodbyes of the unforgettable 2 days, and I walked out while humming to the tune of “look around, look around at how lucky we are to be alive right now“. I’m grateful to be a part of SAP’s Internship Experience Project and to have had the opportunity to attend this summit. I’m excited to apply what I’ve learnt and most importantly, share what I’ve learnt with others so that together, we can continue pushing our industry forward! http://bit.ly/2Bwm6m7 #SAP #SAPCloud #AI

SAP SQL Anywhere におけるヒントを使用したSQL リクエストのカスタマイズ : 過去のブログより

このページは、以下の英語ページの抄訳です。最新の情報については、英語ページを参照してください。

https://blogs.sap.com/2014/03/26/customizing-sql-requests-with-hints/

この記事のオリジナルは、 Glenn Paulley がsybase.com に 2009 年 6 月に掲載したものです。その中で、Glenn は SQL Anywhere におけるヒントの使用によるクエリセマンティクスのカスタマイズについて解説しています。

特定の状況においては、ヒントは非常に便利になりえますが、ほとんどの場合、SQL Anywhere のクエリのオプティマイゼーションとクエリの実行においては、クエリとDMLの性能の実行を実現するために全てのコンテキストを考慮して「正しいこと」をする、というとてつもない仕事を行っているということに留意することが重要です。

SQL クエリの正確なセマンティクスに影響を与えるために使用できるメカニズム、特に、特定の SQL 文の結果への同時トランザクションの影響を隔離する(あるいは晒す)ためのものはたくさんあります。このようなメカニズムの 1 つが、使用されるカーソルのタイプです。

例を挙げると、INSENSITIVE カーソルは、同時アップデートの影響からクエリを隔離し、同じトランザクションからであっても、その結果の最初の FETCH より前に、OPEN 時の SQL クエリの全結果セットを実体化します。

一方、SQL Anywhere の KEYSET-DRIVEN (または SCROLL・value-sensitive) カーソルは、それらのローがアプリケーションによってFETCHされたものであると記憶し、同じ結果のローが再FETCH され、同時アップデート(または削除)される場合には、アプリケーションに警告(エラー)を返します。

他のメカニズムとして、SQL 文で使用されている分離レベルがあります。

SERIALIZABLEより低い ANSI SQL 分離レベルには、明らかに同時実行性を改善する利点があります。

しかしながら、同時更新やそれら間の相互作用が理由で、クエリ実行中にエラーが発生するリスクがあります。

他のセマンティックの効果のうち、テーブルヒントの使用は、クエリあるいはテーブルベースでさえセマンティックの変更の指定が可能です。

もともと、私は SQL クエリのヒントの使用は好きではありません。なぜならば、「クエリオプティマイザーに最適なアクセスプランを選択させなければならない」という強い偏見があるからです。

しかしながら、多くの場合において、クエリまたはテーブルヒントは、特にロックの動作を細かく制御するのに、非常に便利です。

SELECT FOR UPDATE

テーブルヒントの話をする前に、FOR UPDATE 構文で指定された文レベルの 2 つの同時実行性制御ヒントについて述べたいと思います。

FOR UPDATE句の基本は、明示的に更新可能なカーソルを宣言します。しかしながら、分離レベル0 と 1 のロックでは、現在の行以外ロックは取得されていないので、その他のローは他の接続による修正や削除がオープンに行えます。

これらのローのその後の更新の可否を確認するには、2つのオプションがあります。

* FOR UPDATE BY LOCK. を指定します。これは、アプリケーションでFETCHされているので、各ローで INTENT ローロックの取得が発生します。INTENT ロックは、他の接続がローを読むことを許可しますが、他の接続はそれの INTENT または WRITE ロックを取得することはできません。INTENT ロックは、COMMIT/ROLLBACKまで保たれる長期のロックです。
* FOR UPDATE BY TIMESTAMP または FOR UPDATE BY VALUES。を指定します。この場合、SQL Anywhereは、他の接続によって特定のローが替えられた、または削除されたという通知を有効化するため、楽観的同時実行制御の形式としてKEYSET-DRIVEN カーソルの使用を強要します。

テーブルヒント

Microsoft SQL Serverのような他のシステムと同様に、SQL Anywhere では追加の WITH 句を使うことでテーブルヒントをサポートしています。以下に demo.db サンプルデータベースを使用した例を挙げます。 SELECT * FROM CUSTOMERS WITH ( NOLOCK )

NOLOCKテーブルヒントは、サーバーが Customers テーブルに分離レベル0でアクセスさせます。テーブルヒントは、ベースまたはグローバル共有 temp テーブルにのみ適用されることに留意してください。ビューまたはプロキシテーブルで使用される場合、ヒントは無視されます。以下が SQL Anywhere 11.0.1 サーバーでサポートされているテーブルヒントのリストです。

* NOLOCK http://bit.ly/2oD71w9 #SAP #SAPCloud #AI

Image upload & retrieve through Spring RESTful Web Service in SAP Cloud Platform

1. Introduction 

This blog is about the image upload and retrieval approach in SAP cloud platform through Spring based restful services, The image can be profile pics or some some thumbnail, which end users or client need to store in database along with the user information. So, instead of storing in UI application as folder structure or by any other mechanism, using this way we can store the images in the form of binary object in database along with the other information, Which we can retrieve while fetching the other information Like we have requirement that we have products thumbnail needs to upload real time along with the other product information and also customer can upload new thumbnail images, So instead of storing in the UI folder or server, we can upload the same in the database and use it whenever needs to retrieve along with the product details. It will be stored as blob object or clob object form in database.

2. Prerequisite Activities

The prerequisites in two part, the 1st part would be the SAP UI5 app and in the 2nd part backend services along with the database can be covered.

PART-1: UI5 APP

* Create SAPUI5 app:

The UI5 app explained  here is being used to upload and fetch the image and to explain through UI, how images feature can be used in UI5 by using the FileUploader control.

In any UI5 application includes 5 files namely

* html
* js – route to given JS view
* controller.js – server call for data manipulation
* view.xml – View logic and SAP UI5 controls
* xs-app.json – application routing from UI to backend services

As mentioned above the code will be shown below along with the web project snapshots

Index.html

Component.js

Controller.controller.js

View.view.xml

xs-app.json

The above file can be part of one web folder basically in the resource folder and the xs-app.json file be part of the main project which will be used to route the request of server for uploading and retrieving of the images or thumbnails images. You can check the details project structure and files being used in the application in the github account. The apps can be deployed in SAP cloud foundry platform as the mentioned app is being developed and evaluated in SAP cloud foundry account.

PART-2: Java Services & Database

* Create and build JPA Project: You can refer my previous log series regarding project setup  blog series.
* Get dependent Library:

In addition to the existing api added in previous blogs pom.xml, following api must be added

  commons-fileupload commons-fileupload 1.3.1

Here we need to use this jar as the file upload is of multipart and for that we need to use this API to upload image as multipart data type.

3. Configuration and Implementation

3.1 Configure persistence.xml in JPA model: Refer to my previous blog series log series for this section.

3.1.1 Configure resource.xml in JPA model: Refer to my previous blog series for this section

4. Adding the spring-servlet.xml file under WEB-INF folder: Refer to my previous blog series for this section.

Along with the above-mentioned content in spring-servlet following code needs to be added in spring-servlet.xml

As shown in the above snapshot that the minimum & maximum upload sizes are defined. Beyond that, will throws an exception.

4.1. Spring-servlet has to be included in web.xml file, code snippet has to added : Refer to my previous blog series for this section.

4.2. Now create class where using JPAEntitymanager establish a connection, basically to connect to database. @RestController @RequestMapping(“/v1/internal”) public class ImageMgmtService { final static Logger LOGGER = LoggerFactory.getLogger(ImageMgmtServiceImpl.class); private ImageMgmtServiceImpl imageServiceImpl = new ImageMgmtServiceImpl(); EntityManagerFactory emf ; @InitBinder public void initBinder(WebDataBinder dataBinder){ dataBinder.setDisallowedFields(); } @PersistenceUnit public void setEntityManagerFactory(EntityManagerFactory emf) { this.emf = emf; } @RequestMapping(value = “/uploadImage”, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity getuploadImage(@RequestParam(“file”) MultipartFile file, @RequestParam(“file-data”) String data) throws JSONException { JSONObject obj = new JSONObject(data); Integer mappingGuid = (Integer) obj.get(“mapping_Guid”); return imageServiceImpl.uploadImage(file, mappingGuid , emf); } @RequestMapping(value = “/fetchImage/{guid}”, method = RequestMethod.GET) public ResponseEntity fetchImage(@PathVariable(“guid”) String mappingGuid ) { return imageServiceImpl.fetchImage(mappingGuid, emf);} }

As shown above the image object accepted in the requestParam as multipart data. public class ImageMgmtServiceImpl { final static Logger LOGGER = LoggerFactory.getLogger(ImageMgmtServiceImpl.class); HttpStatus statusCode = null; EntityManagerFactory emf; public ResponseEntity uploadImage(MultipartFile file, Integer mappingGUID, EntityManagerFactory emf) { this.emf = emf; return doUploadImage(file, mappingGUID); } private ResponseEntity doUploadImage(MultipartFile file, Integer mappingGuid) { EntityManager em = this.emf.createEntityManager(); HttpHeaders httpHeaders = new HttpHeaders(); ImageManagementServiceResponse response = null; try { String EVENT_IDENTFIER = “com.sap.sample::IMAGE_MANAGEMENT.IMAGE_STORE”; String eventIdentificationCall = “INSERT INTO “” + EVENT_IDENTFIER + “” VALUES (?,?,?)”; em.getTransaction().begin(); Query query = em.createNativeQuery(eventIdentificationCall); query.setParameter(1, mappingGuid); query.setParameter(2, file.getContentType()); query.setParameter(3, file.getBytes()); int records = query.executeUpdate(); LOGGER.info(“The image has been uploaded” + records); em.getTransaction().commit(); response = new ImageManagementServiceResponse(); response.setGuid(mappingGuid + “”); response.setLevel(“1”); response.setSuccess(true); return new ResponseEntity(response, httpHeaders, HttpStatus.OK); } catch (Exception ex) { if ((em != null) && (em.isOpen() == true)) { em.close(); } response = new ImageManagementServiceResponse(); response.setGuid(mappingGuid + “”); response.setLevel(“0”); response.setSuccess(false); response.setReasonType(0); response.setReasonDescription(“Image cannot be uploaded”); LOGGER.error(“tenantName: ” + “,Upload image failed : ” + ex.getMessage()); return new ResponseEntity(response, httpHeaders, HttpStatus.OK); } finally { if (em != null) { em.close(); } } } public ResponseEntity fetchImage(String guid, EntityManagerFactory emf) { return doFetchImage(guid, emf); } private ResponseEntity doFetchImage(String guid, EntityManagerFactory emf) { EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); try { String fetchCall = “com.sap.sample::IMAGE_MANAGEMENT.IMAGE_STORE”; String eventIdentificationCall = “SELECT * FROM “” + fetchCall + “” WHERE IMAGE_ID = ?”; Query query = em.createNativeQuery(eventIdentificationCall, ImageOutput.class); query.setParameter(1, guid); ImageOutput imo = (ImageOutput) query.getSingleResult(); byte[] image = imo.getImageBinary(); HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.add(“Content-Type”, imo.getImageMime()); httpHeaders.add(“Cache-Control”, “max-age=259200”); em.getTransaction().commit(); return new ResponseEntity(image, httpHeaders, HttpStatus.OK); } catch (Exception ex) { try { File file = new File(getClass().getClassLoader().getResource(“default-image.png”).getFile()); HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.add(“Content-Type”, “image/png”); byte[] image = IOUtils.toByteArray(new FileInputStream(file)); LOGGER.error(“tenantName: ” + “,Upload fetch failed : ” + ex.getMessage()); return new ResponseEntity(image, httpHeaders, HttpStatus.OK); } catch (Exception e) { HttpHeaders httpHeaders = new HttpHeaders(); LOGGER.error(“tenantName: ” + “,Upload fetch failed : ” + ex.getMessage()); return new ResponseEntity(httpHeaders, HttpStatus.BAD_REQUEST); } } } }

As above mentioned in snapshot that there are two method, first method is used to store the image as binary object into the database. Second method is used to fetch the image from database.

Along with the above class there is POJO class is set as response object to return the response of BLOB object in the byte [] array format, as shown below public class ImageManagementServiceResponse { private byte[] image; private String level; private String guid; private Boolean success; private Integer reasonType; private String reasonDescription; private Object data; // setter and getter method needs to be generated here }

In the above code base, we have class, the service and the service Implementation class. In service class the upload image or files can be read and then in the implementation class, the actual business logic is mentioned to upload and retrieve of the images.

5. Entity class addition for the JPA implementations

As shown below the JPA class for persistence @Entity @Table(name=“”com.sap.sample::IMAGE_MANAGEMENT.IMAGE_STORE””) public class ImageStorage implements Serializable{ private static final long serialVersionUID = 4829386985899147977L; @Id @Column(name=“IMAGE_ID”) private String imageId = null; @Lob @Column(name = “IMAGE_BINARY”) private byte[] imageBinary = null; @Column(name = “IMAGE_MIME_TYPE”) private String imageMimeType = null; public String getImageId() { return imageId; } public void setImageId(String imageId) { this.imageId = imageId; } public String getImageMimeType() { return imageMimeType; } public void setImageMimeType(String imageMimeType) { this.imageMimeType = imageMimeType; } public static long getSerialversionuid() { return serialVersionUID; } public byte[] getImageBinary() { return imageBinary; } public void setImageBinary(byte[] imageBinary) { this.imageBinary = imageBinary; }

This implementation will deal with any type of binary content, It can be doc, pdf etc. The Entity class needs to be added into the persistence.xml file. The annotation @Lob has to added for the column which mapped to byte [] columns as it bind with the binary content.

6. Database design

As shown above the IMAGE_BINARY fields stores the image object in the blob format. The above database field might change based on the requirement. In my case I have tried to show only for the image content save as blob object, it can be added for any number of fields and any type of content that can be stored as binary content.

7. Conclusion

This blog is about implementation of binary content and retrieval through Spring MVC from database, Of course there is a documentation and numerous materials about image processing or storing using spring MVC in the database, Here I have explained about the end to end integration from UI to back-end, along with the database binding mechanism. It’s an attempt for persisting binary object in db. With the above approach, we can implement how to store any image content in the form of binary or blob object into database. http://bit.ly/2oDT3dL #SAP #SAPCloud #AI