ABAP 和 Java 的 destination 和 JNDI

Netweaver 里使用事务码 SM59 创建 Destination:
Java
新建一个 destination:
测试代码:
try { Context ctx = new InitialContext(); ConnectivityConfiguration configuration = (ConnectivityConfiguration) ctx.lookup("java:comp/env/connectivityConfiguration");
DestinationConfiguration destConfiguration = configuration.getConfiguration(destinationName);
if (destConfiguration == null) { response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, String.format("Destination %s is not found. Hint:" + " Make sure to have the destination configured.", destinationName)); return; }
// Get the destination URL String value = destConfiguration.getProperty("URL"); URL url = new URL(value + "xml?origins=Walldorf&destinations=Paris");
String proxyType = destConfiguration.getProperty("ProxyType"); Proxy proxy = getProxy(proxyType);
urlConnection = (HttpURLConnection) url.openConnection(proxy);
injectHeader(urlConnection, proxyType);
// Copy content from the incoming response to the outgoing response InputStream instream = urlConnection.getInputStream(); OutputStream outstream = response.getOutputStream(); copyStream(instream, outstream); } catch (Exception e) { // Connectivity operation failed String errorMessage = "Connectivity operation failed with reason: " + e.getMessage() + ". See " + "logs for details. Hint: Make sure to have an HTTP proxy configured in your " + "local environment in case your environment uses " + "an HTTP proxy for the outbound Internet " + "communication."; LOGGER.error("Connectivity operation failed", e); response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, errorMessage); }
通过 JNDI 获得 destination 配置的 url:
以 Internet Service http://maps.googleapis.com/maps/api/distancematrix/xml?origins=Walldorf&destinations=Berlin为例,
在浏览器里访问这个 url,得到输出:从 Walldorf 到 Berlin 的距离。
如何让一个部署到 SAP 云平台的 Java 应用也能访问到该 internet service 呢?
首先在 SAP 云平台里创建一个 destination,维护 service 的 end point:
在 Java 代码里使用 SAP 云平台里创建的 destination:
然后使用 JNDI service 读取 destination 里配置的 url:
部署到 SAP 云平台之后,在 Eclipse 里看到 preview 结果:
SAP 云平台 Cockpit 显示如下:
浏览器访问如下:
web.xml:
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<!-- Main sample servlet mapped to / so that the integration test harness can detect readiness (generic for all samples) --> <servlet> <servlet-name>ConnectivityServlet</servlet-name> <servlet-class>com.sap.cloud.sample.connectivity.ConnectivityServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ConnectivityServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
<!-- Declare the JNDI lookup of destination --> <resource-ref> <res-ref-name>connectivityConfiguration</res-ref-name> <res-type>com.sap.core.connectivity.api.configuration.ConnectivityConfiguration</res-type> </resource-ref></web-app>
package com.sap.cloud.sample.connectivity;
import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.InetSocketAddress;import java.net.Proxy;import java.net.URL;
import javax.annotation.Resource;import javax.naming.Context;import javax.naming.InitialContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import com.sap.cloud.account.TenantContext;import com.sap.core.connectivity.api.configuration.ConnectivityConfiguration;import com.sap.core.connectivity.api.configuration.DestinationConfiguration;
public class ConnectivityServlet extends HttpServlet { @Resource private TenantContext tenantContext;
private static final long serialVersionUID = 1L; private static final int COPY_CONTENT_BUFFER_SIZE = 1024; private static final Logger LOGGER = LoggerFactory.getLogger(ConnectivityServlet.class);
private static final String ON_PREMISE_PROXY = "OnPremise";
@Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpURLConnection urlConnection = null; String destinationName = request.getParameter("destname");
if (destinationName == null) { destinationName = "google_map"; } try { Context ctx = new InitialContext(); ConnectivityConfiguration configuration = (ConnectivityConfiguration) ctx.lookup("java:comp/env/connectivityConfiguration");
DestinationConfiguration destConfiguration = configuration.getConfiguration(destinationName);
if (destConfiguration == null) { response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, String.format("Destination %s is not found. Hint:" + " Make sure to have the destination configured.", destinationName)); return; }
String value = destConfiguration.getProperty("URL"); URL url = new URL(value + "xml?origins=Walldorf&destinations=Paris");
String proxyType = destConfiguration.getProperty("ProxyType"); Proxy proxy = getProxy(proxyType);
urlConnection = (HttpURLConnection) url.openConnection(proxy);
injectHeader(urlConnection, proxyType);
InputStream instream = urlConnection.getInputStream(); OutputStream outstream = response.getOutputStream(); copyStream(instream, outstream); } catch (Exception e) { String errorMessage = "Connectivity operation failed with reason: " + e.getMessage() + ". See " + "logs for details. Hint: Make sure to have an HTTP proxy configured in your " + "local environment in case your environment uses " + "an HTTP proxy for the outbound Internet " + "communication."; LOGGER.error("Connectivity operation failed", e); response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, errorMessage); } }
private Proxy getProxy(String proxyType) { Proxy proxy = Proxy.NO_PROXY; String proxyHost = null; String proxyPort = null;
if (ON_PREMISE_PROXY.equals(proxyType)) { // Get proxy for on-premise destinations proxyHost = System.getenv("HC_OP_HTTP_PROXY_HOST"); proxyPort = System.getenv("HC_OP_HTTP_PROXY_PORT"); } else { // Get proxy for internet destinations proxyHost = System.getProperty("https.proxyHost"); proxyPort = System.getProperty("https.proxyPort"); }
if (proxyPort != null && proxyHost != null) { int proxyPortNumber = Integer.parseInt(proxyPort); proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPortNumber)); }
return proxy; }
private void injectHeader(HttpURLConnection urlConnection, String proxyType) { if (ON_PREMISE_PROXY.equals(proxyType)) { // Insert header for on-premise connectivity with the consumer account name urlConnection.setRequestProperty("SAP-Connectivity-ConsumerAccount", tenantContext.getTenant().getAccount().getId()); } }
private void copyStream(InputStream inStream, OutputStream outStream) throws IOException { byte[] buffer = new byte[COPY_CONTENT_BUFFER_SIZE]; int len; while ((len = inStream.read(buffer)) != -1) { outStream.write(buffer, 0, len); } }}
首先在 SAP 云平台里创建一个 destination,维护 service 的 end point:
然后打开 SAP 云平台的 WebIDE,创建一个新的文件夹和新的 HTML5 Application Descriptor:
将下列内容粘贴到 neo-app.json 去:
{ "welcomeFile": "index.html", "routes": [ { "path": "/resources", "target": { "type": "service", "name": "sapui5", "entryPath": "/resources" }, "description": "SAPUI5 Resources" }, { "path": "/test-resources", "target": { "type": "service", "name": "sapui5", "entryPath": "/test-resources" }, "description": "SAPUI5 Test Resources" }, { "path": "/distance", "target": { "type": "destination", "name": "google_map" }, "description": "Google map" } ]}
新建一个 index.html, 输入以下内容:
<a href="distance/xml?origins=Walldorf&destinations=Paris">
Distance from Walldorf to Paris:</a>
测试该应用,点击超链接:
会发现第一步创建的 destination 已经生效了。
打开 SAP 云平台上的 SAP HANA Web-Based Development Workbench 超链接:
遇到错误信息:403 - Forbidden - The server refused to fulfill the request.
solution
打开 SAP HANA Cockpit, 选择 OK:
添加下列权限:
sap.hana.admin.roles::Administrator
sap.hana.ide.roles::TraceViewer
sap.hana.ide.roles::SecurityAdmin
之后即可打开。
版权声明: 本文为 InfoQ 作者【Jerry Wang】的原创文章。
原文链接:【http://xie.infoq.cn/article/870c9b39085890a0245597c3d】。文章转载请联系作者。
Jerry Wang
个人微信公众号:汪子熙 2017.12.03 加入
SAP成都研究院开发专家,SAP社区导师,SAP中国技术大使。











评论