Integration of SAP with the Google App Engine

Recently I though how I could integrate an SAP System which tends to be in a closed firewall where no access it granded from the outsite. The solution is actually quite easy. You can easily send our HTTP requests from SAP. So you could send out some data from SAP and / or request a status via HTTP from the outsite system.

This blog entry demonstrates how to send out emails from the Google App Engine via a ABAP report. Here is the ABAP report. Your have to replace the “your-appid” with your application id on the Google App Engine.

*&---------------------------------------------------------------------*
*& Report  Z_CALL_GOOGLEAPPENGINE
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  Z_CALL_GOOGLEAPPENGINE.

DATA: client        TYPE REF TO if_http_client,
      host          TYPE string VALUE 'your-appid.appspot.com',
      proxy_host    TYPE string VALUE 'proxy',
      service       TYPE string VALUE '80',
      proxy_service TYPE string VALUE '8080',
      path          TYPE string,
      errortext     TYPE string,
      subrc         TYPE sysubrc,
      response_data TYPE xstring,
      request_data  TYPE xstring,
      txt           TYPE string,
      code          TYPE i,
      reason        TYPE string.

PARAMETERS: s_name(12) TYPE c.
PARAMETERS: s_email(20) TYPE c.
PARAMETERS: s_desc(30) TYPE c.


CONCATENATE '/feedback?name=' s_name '&description='  s_desc  '&email='  s_email into path.

cl_http_client=>create(
  EXPORTING
    host               = host    " Logical destination (specified in function call)
    service            = service    " Port Number
    proxy_host         = proxy_host    " Logical destination (specified in function call)
    proxy_service      = proxy_service    " Port Number
    scheme             = cl_http_client=>schemetype_http    " HTTP/HTTPS
  IMPORTING
    client             = client    " HTTP Client Abstraction
  EXCEPTIONS
    argument_not_found = 1
    plugin_not_active  = 2
    internal_error     = 3
    OTHERS             = 4
        ).
IF SY-SUBRC <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*            WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.


* Set HTTP method GET (optional, also used when the request contains no body)
*client->request->set_method( if_http_request=>co_request_method_get ).

*client->request->set_version( if_http_request=>co_protocol_version_1_1 ).


* Set request URI (/<path>[?<querystring>])
cl_http_utility=>set_request_uri(
  request = client->request
  uri     = path ).

*client->request->get_raw_message(
*  RECEIVING
*    data = request_data    " HTTP message
*  EXCEPTIONS
*    OTHERS = 1
*).
*IF sy-subrc <> 0.
*  WRITE: / 'Error printing the request'.
*ELSE.
*  MOVE request_data TO txt.
*  WRITE: / 'Request: ', request_data.
*  WRITE: / txt.
*ENDIF.

* Send the request
client->send(
  EXCEPTIONS
    http_communication_failure = 1
    http_invalid_state         = 2
    http_processing_failed     = 3
    http_invalid_timeout       = 4
    OTHERS                     = 5
).

IF sy-subrc <> 0.
  client->get_last_error(
    IMPORTING
      code    = subrc    " Return Value, Return Value After ABAP Statements
      message = errortext    " Error Message
    EXCEPTIONS
      OTHERS  = 1
  ).
  IF sy-subrc <> 0.
    WRITE: / 'Communication error. Cannot get last error'.
  ELSE.
    WRITE: / 'Communication error( send ), Code: ', subrc, ' Message: ', errortext.
  ENDIF.
  EXIT.
ENDIF.

* Receive the response
client->receive(
  EXCEPTIONS
    http_communication_failure = 1
    http_invalid_state         = 2
    http_processing_failed     = 3
    OTHERS                     = 4
).
IF sy-subrc <> 0.
  client->get_last_error(
    IMPORTING
      code    = subrc    " Return Value, Return Value After ABAP Statements
      message = errortext    " Error Message
    EXCEPTIONS
      OTHERS  = 1
  ).
  IF sy-subrc <> 0.
    WRITE: / 'Communication error (receive). Cannot get last error'.
  ELSE.
    WRITE: / 'Communication error(send), Code: ', subrc, ' Message: ', errortext.
  ENDIF.
  EXIT.
ENDIF.

client->response->get_status(
  IMPORTING
    code   = code    " HTTP status code
    reason = reason    " HTTP status description
  EXCEPTIONS
    OTHERS = 1
).

WRITE: / 'Response Status Code: ', code, reason.

client->response->get_cdata(
  RECEIVING
    data = txt    " Character data
  EXCEPTIONS
    OTHERS = 1
).

IF sy-subrc <> 0.
  WRITE: / 'Error printing the response'.
ELSE.
*  MOVE request_data TO txt.
*  DATA: conv TYPE REF TO cl_abap_conv_in_ce.
*  conv = cl_abap_conv_in_ce=>create( input = request_data ).
*  conv->read( IMPORTING data = txt ).
*  WRITE: / 'Response: ', response_data.
  WRITE: / txt.
ENDIF.

* Close the connection at the end
client->close(
  EXCEPTIONS
    http_invalid_state = 1
    OTHERS             = 2
).
IF sy-subrc <> 0.
  WRITE: / 'Error on closing the http connection: ', sy-subrc.
ELSE.
  WRITE: / 'Connection closed'.
ENDIF.

The receiving servlet just extract the in the doGet method the information and uses it to send our an email. Here is the servlet code.

package de.vogella.gae.feedback;

import java.io.IOException;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class FeedbackServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		String name = req.getParameter("name");
		String description = req.getParameter("description");
		String email = req.getParameter("email");
		Properties props = new Properties();
		Session session = Session.getDefaultInstance(props, null);

		String msgBody = description;
		try {
			Message msg = new MimeMessage(session);
			msg.setFrom(new InternetAddress("Your_Admin_Email@googlemail.com",
					"Your Name"));
			msg.addRecipient(Message.RecipientType.TO, new InternetAddress(
					email, name));
			msg.setSubject("Feedback");
			msg.setText(msgBody);
			Transport.send(msg);

		} catch (Exception e) {
			resp.setContentType("text/plain");
			resp.getWriter().println("Something went wrong. Please try again.");
			throw new RuntimeException(e);
		}

		resp.setContentType("text/plain");
		resp.getWriter().println(
				"Thank you for your feedback. An Email has been send out.");
	}
}

You find more information about App Engine in my Google App Engine Tutorial. You should also follow me on Twitter.

About Lars Vogel

Lars Vogel is the founder and CEO of the vogella GmbH and works as Eclipse and Android consultant, trainer and book author. He is a regular speaker at international conferences, He is the primary author of vogella.com. With more than one million visitors per month this website is one of the central sources for Java, Eclipse and Android programming information.
This entry was posted in Web and tagged . Bookmark the permalink.