|
|
![]() | ||||||||
|
7월의 Technology Day 제 2회 자바 유저 그룹 세미나
|
||
이번 호 테크팁에서는, » SSL로 JAX-WS 기반 웹 서비스 이용하기 » 웹 서비스 애플리케이션에서 문서 처리하기 에 대해 다룹니다. 이 팁들은 Java EE 5의 오픈소스 구현(GlassFish)을 이용하여 개발되었으며, GlassFish 프로젝트 페이지에서 GlassFish를 다운로드 받으실 수 있습니다. -샘플 아카이브 다운로드 받기- SSL로 JAX-WS 기반 웹 서비스 이용하기 웹 서비스 애플리케이션에서 문서 처리하기 | ||
| SSL로 JAX-WS 기반 웹 서비스 이용하기 | ||
글쓴이 Shing Wai Chan Java EE 5에서는 JAX-WS에 기반을 둔 웹 서비스를 EJB 엔드포인트나 서블릿 엔드포인트로 구현할 수 있다. EJB 엔드포인트로 구현된 JAX-WS 기반 웹 서비스의 예는 테크 팁 EJB 3.0을 이용하여 웹 서비스 개발하기에서 찾아볼 수 있으며, 서블릿 엔드포인트로 구현된 JAX-WS 기반 웹 서비스에 대한 예는 테크 팁 JAX-WS를 이용하여 웹 서비스 개발하기에 나와 있다. 웹 서비스 구현 방식과 관계없이, 웹 서비스를 이용하는 경우를 포함한 대부분의 엔터프라이즈 애플리케이션은 반드시 안전한 환경에서 실행되어야 한다. TSL(Transport Layer Security)/SSL(Secure Sockets Layer)은 인증, 메시지 무결성 및 비밀 유지를 위해 사용할 수 있는 point-to-point 보안 전송 메커니즘으로, 이 TLS/SSL (본 팁에서는 간단히 ‘SSL’로 표기)은 대부분의 엔터프라이즈 애플리케이션 환경의 보안 요구사항을 충족할 뿐 아니라 실제로 널리 채택되어 사용되고 있다. 본 테크 팁은 SSL로 실행되는 JAX-WS 기반 웹 서비스를 구성하는 방법과 애플리케이션 클라이언트에서의 웹 서비스 액세스 방법을 다룬다. 첨부된 예제 패키지에서는 SSL을 이용하여 JAX-WS 웹 서비스에 액세스하는 자바 클라이언트를 예시하고 있다. 이와 더불어 EJB 및 서블릿 엔드포인트로 구현되는 웹 서비스의 예제가 제공되며, 예제는 GlassFish라고 불리는 Java EE 5의 오픈 소스 레퍼런스 구현을 사용한다. GlassFish는 GlassFish 커뮤니티 다운로드 페이지에서 다운로드할 수 있다. 웹 서비스 엔드포인트를 위한 클래스 작성 먼저 웹 서비스를 위한 자바 클래스를 작성해 보기로 하자. SSL은 웹 서비스 엔드포인트의 자바 코드에 영향을 미치지 않으며, SSL을 이용하거나 이용하지 않는 웹 서비스 모두에 동일한 코드가 적용된다. Java EE 5에서는 주석을 이용하여 손쉽게 JAX-WS 웹 서비스를 구성할 수 있다. 다음은 EJB 엔드포인트로 구현된 웹 서비스의 예제이다. package ejbws;
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;
@Stateless
@WebService
public class HelloEjb {
@Resource WebServiceContext wsContext;
public String hello(String msg) {
return "Ejb WS: " + wsContext.getUserPrincipal()
+ ": " + msg;
}
}
The 다음은 동일한 웹 서비스가 서블릿 엔드포인트로 구현된 예제이다. package servletws;
import javax.annotation.Resource;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;
@WebService
public class HelloServlet {
@Resource WebServiceContext wsContext;
public String hello(String msg) {
return "Servlet WS: " + wsContext.getUserPrincipal()
+ ": " + msg;
}
}
배포 서술자에 보안 정보 명시 EJB 엔드포인트로 구현된 웹 서비스에서 SSL을 이용하려면 벤더별 배포 서술자(본 팁의 경우에는 SSL을 통한 보안 통신에 있어서 중요 사항 중 한 가지는 서버 인증, 즉 서버의 아이덴티티를 클라이언트에 확인시키는 일이다. 또 중요한 측면은 바로 클라이언트 인증인데, 이 경우에는 서버가 클라이언트의 아이덴티티를 확인하게 된다. SSL에서는 서버 인증이나 서버와 클라이언트가 결합된 인증이 허용된다(클라이언트 인증만은 허용되지 않음). 본 팁에서는 서버와 클라이언트가 결합된 인증에 대해 ‘상호 인증’이라는 용어를 사용하기로 한다. (단, 타 문서에서는 상호 인증이 다른 의미로 사용될 수 있다는 점에 유의할 것. 예를 들어, 어떤 문서에서는 클라이언트 인증이 상호 인증과 동의어로 사용되기도 한다.) SSL 서버 인증을 인에이블하려면 <ejb>
<ejb-name>HelloEjb</ejb-name>
<webservice-endpoint>
<port-component-name>HelloEjb</port-component-name>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</webservice-endpoint>
</ejb>
<security-constraint>
<web-resource-collection>
<web-resource-name>Secure Area</web-resource-name>
<url-pattern>/HelloServletService/HelloServlet
</url-pattern>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>EMPLOYEE</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
GlassFish에서 WSDL 파일은 SSL나 SSL 상호 인증을 통해 엔드포인트의 SSL에 의해 보호된다. SSL 상호 인증의 경우에는 <ejb>
<ejb-name>HelloEjb</ejb-name>
<webservice-endpoint>
<port-component-name>HelloEjb</port-component-name>
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm>certificate</realm>
</login-config>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</webservice-endpoint>
</ejb>
<security-constraint>
<web-resource-collection>
<web-resource-name>Secure Area</web-resource-name>
<url-pattern>/HelloServletService/HelloServlet
</url-pattern>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
</role-name>EMPLOYEE</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>certificate</realm-name>
</login-config>
클라이언트 프로그램에는 배포 서술자가 필요하지 않다. 웹 서비스 애플리케이션의 패키징 및 배포 SSL을 이용하는 웹 서비스 애플리케이션의 패키징 및 배포는 SSL을 이용하지 않는 웹 서비스 애플리케이션의 경우와 동일하다. 하지만, 웹 서비스가 엔터프라이즈 아카이브(즉, 클라이언트 작성 웹 서비스를 배포한 후에는 클라이언트 프로그램으로 액세스할 수 있다. SSL을 이용하는 웹 서비스 애플리케이션을 위한 클라이언트 프로그램은 SSL을 이용하지 않는 경우와 사실상 동일하다. 주된 차이점은 인터넷 프로토콜로 HTTP를 사용하는 대신 HTTPS를 사용해야 한다는 사실이다. 클라이언트에서 @WebServiceRef(wsdlLocation=
"https://serverName:8181/HelloEjbService/HelloEjb?WSDL")
private static HelloEjbService helloEjbService;
이어서 웹 서비스에 대한 포트에 액세스하여 웹 서비스를 호출할 수 있다. HelloEjb helloEjbPort = helloEjbService.getHelloEjbPort();
helloEjbPort.hello("Hello World");
클라이언트 측 artifacts는 HTTPS를 통해 WSDL 파일에 액세스함으로써 생성되는데, 이를 위해서는 환경 변수 서버의 truststore 파일과 그 비밀번호를 명시하기 위한 여러 가지 방법들이 있는데, 예를 들어 다음과 같이 <exec executable="wsimport">
<env key="VMARGS"
value="-Djavax.net.ssl.trustStore=${truststore.location}
-Djavax.net.ssl.trustStorePassword=${ssl.password}"/>
<arg line="-keep -d ${client.build}
https://serverName:8181/HelloEjbService/HelloEjb?WSDL"/>
</exec>
클라이언트 Truststore 및 Keystore 설정 서버를 위한 truststore 파일 외에 클라이언트를 위한 truststore 파일도 필요하다. 클라이언트는 truststore 내의 인증서들과 대조하여 서버 인증서를 검증하는데, SSL을 이용한 안전한 접속이 이루어지려면 클라이언트 측 truststore가 서버 인증서를 신뢰해야 한다. SSL 상호 인증을 위해서는 서버 측 truststore 역시 클라이언트 인증서를 신뢰해야 한다. 또한 서버 측 truststore를 수정할 경우에는 서버를 재시작해야 한다(이로써 새 인증서를 사용할 수 있게 된다). 생산 증명은 공동 인증 기관(CA, Certificate Authority)에서 승인하기 때문에 생산 환경에서는 상기 과정이 필요치 않을 수 있다. GlassFish 빌드에는 몇 가지의 공동 루트CA에 대한 인증서가 포함되어 있다. SSL 상호 인증의 경우에는 클라이언트 keystore(클라이언트의 키와 인증서가 포함된 파일)에 자체 키를 제공해야 하고, keystore는 JDK 5.0에 포함된 키와 인증서 관리 유틸리티인 keytool을 이용하여 생성할 수 있다. 클라이언트 실행 SSL을 통해 웹 서비스에 액세스하는 클라이언트를 실행하기에 앞서 먼저 환경 변수 -Djavax.net.ssl.trustStore=${truststore.location}
-Djavax.net.ssl.trustStorePassword=${ssl.password}
SSL 상호 인증의 경우에는 -Djavax.net.ssl.trustStore=${truststore.location}
-Djavax.net.ssl.trustStorePassword=${ssl.password}
-Djavax.net.ssl.keyStore =${keystore.location}
-Djavax.net.ssl.keyStorePassword=${ssl.password}
예제 코드 실행하기 본 팁에 첨부된 예제 코드를 실행하려면 다음 단계를 수행한다.
글쓴이 소개 Shing Wai Chan은 Sun Java Application Server 및 Java EE SDK 개발 팀의 고참 멤버로서 보안, 주석, CMP, B2B 및 B2C와 관련한 개발 프로젝트에 전념하고 있다. 맨위로 | ||
| 웹 서비스 애플리케이션에서 문서 처리하기 | ||
글쓴이 Deep Singh Java EE는 XML 문서 처리를 위한 다양한 기술을 제공하며, 이러한 기술에는JAXB(Java Architecture for XML Binding), StAX(Streaming API for XML), DOM(Document Object Model) API 등이 포함된다. 본 테크 팁에서는 이 기술들을 서로 비교하고, 예제 애플리케이션에서의 사용 실례를 살펴보도록 한다. JAXB JAXB 기술은 XML 스키마를 Java 오브젝트에 바인드하는 방법을 제공함으로써 개발자들이 각자의 자바 애플리케이션에서 손쉽게 데이터를 처리할 수 있도록 해준다. JAXB API는 XML 문서를 자바 오브젝트에 unmarshal하고 자바 오브젝트를 XML 문서에 marshal하는 메소드를 제공한다. JAXB에 관한 자세한 내용은 테크 팁 JAXB 2.0에 새로 추가된 기능을 참조하기 바란다. JAXB를 사용하는 데 따른 중요한 이점은 스키마(또는 dtd)를 컴파일하여 자바 컨텐트 트리를 생성한 다음 플레인 자바 오브젝트로 작업할 수 있다는 점이다. JAXB의 경우에는 복잡한 스키마가 수반되는데, 소규모의 컨텐트만으로 작업하고자 하는 경우에는 그다지 적합하지는 않다. StAX StAX는 XML 문서를 처리하기 위한 스트리밍 API로, XML 문서를 읽고 쓰는 event-driven ‘pull’ 파서라 할 수 있다. StAX에 관한 자세한 내용은 테크 팁 Sun Java Streaming XML Parser 소개를 참조할 것. StAX의 양방향 특성, 작은 메모리 풋프린트, 낮은 프로세서 요구사항 등은 JAXB나 DOM과 같은 API보다 더 유리한 점으로 작용한다. StAX는 대규모 문서에서 작은 양의 정보를 추출하는 데 특히 효과적이다. 반면에 StAX를 이용하는 데 따른 주된 단점은 문서의 뷰가 협소하다는 점인데, 따라서 사용자는 XML 문서를 읽기에 앞서 어떤 처리 작업을 수행할지 알고 있어야 한다. 또 다른 단점은 복잡한 스키마를 따르는 XML 문서를 리턴할 경우 StAX를 사용하기가 어렵다는 점이다. DOM DOM은 프로그램이 XML 문서의 내용을 동적으로 업데이트할 수 있게 해주는 플랫폼/언어 중립형 API이다. DOM에 관한 자세한 내용은 테크 팁 Using the Document Object Model(영문)을 참조할 것. DOM은 전체 XML 문서의 in-memory 오브젝트 표현을 생성하는데, 이는 문서의 내용을 파싱, 네비게이트, 업데이트하는 데 엄청난 유연성을 제공해 준다. DOM의 단점은 메모리 요구사항이 높고 보다 강력한 처리 능력이 필요하다는 점이다. 예제 애플리케이션: JAXB, StAX, DOM의 비교 본 팁에는 예제 아카이브가 첨부되어 있으며, 이 예제 아카이브는 JAXB, StAX, DOM을 사용하여 웹 서비스에 대한 인풋으로 패스되는 XML 문서를 처리하는 과정을 예시한다. 예제 애플리케이션에서는 신용카드 인증에 대해 다루고 있다. 애플리케이션 클라이언트 코드는 웹 서비스를 호출하여 고객이 제시한 신용카드를 통한 결제를 인증하고, 클라이언트는 XML 문서에 포함된 신용카드 및 카드 소지자 정보를 웹 서비스에 전송한다. 또한 클라이언트는 JAXB, StAX, DOM을 사용하여 XML 문서를 처리할 수 있다. 예제는 이 세 가지 기술을 모두 사용한 XML 문서 처리 예시를 다루고 있다. 본 섹션에서는 예제 애플리케이션을 설치하고 실행하는 방법을 설명한다. 환경 설정하기 예제는 GlassFish라고 불리는 Java EE 5의 오픈 소스 레퍼런스 구현을 사용한다. GlassFish를 아직 구하지 못했다면 GlassFish 커뮤니티 다운로드 페이지에서 다운로드한다. 예제를 구축하고 실행하려면 JDK 5.0(J2SE 5.0 다운로드 페이지에서 다운로드할 수 있다)과 Apache Ant 1.6.5(GlassFish 번들에 포함되어 있으며, Windows의 경우에는 예제 애플리케이션 설치하기 예제 패키지를 다운로드하여 압축을 푼다. 예제를 위한 루트 디렉토리는 웹 서비스 구축하기 예제에서는 WSDL 파일을 이용하여 웹 서비스를 구축하는데, 이를 수행하기 위한 단계는 다음과 같다.
XML 스키마를 기반으로 WSDL 파일을 생성한다 WSDL 파일은 예제 패키지에 포함되어 있으며, WSDL 파일 스키마 파일 WSDL 파일이 임포트하는 두 개의 스키마 파일은 <element name="AuthorizationRequest"
type="tns:AuthorizationRequest"/>
<element name="authorizePaymentSTAX" type="xsd:string"/>
<element name="authorizePaymentDOM">
<complexType>
<sequence>
<any maxOccurs="1"/>
</sequence>
</complexType>
</element>
타입 값
portable artifact 생성 예제에서는 <target name="generate-server" depends="prepare">
<wsimport
...
wsdl="${server.wsdl}">
<binding dir="${confdir}"
includes="${server.config}"/>
</wsimport>
</target>
위에 언급한 artifacts가 생성된 후에는 javac 컴파일러를 사용하여 컴파일을 수행한다. 예제에서는 타깃 이름이 엔드포인트 구현 클래스 작성 예제에서 제공되는 엔드포인트 구현 클래스인 다음은 JAXB를 사용하는 메소드이다. public AuthorizationStatus authorizePaymentJAXB(
AuthorizationRequest parameters) throws
com.sun.techtip.cardservice.service.CardServiceException {
try {
CreditCard card = parameters.getCreditCard();
CardUser user = parameters.getCardUser();
// For sake of simplicity, read only limited
// information about credit card and credit card user
String cardNumber = card.getCardNumber();
String lastName = user.getLname();
// Emulate charge authorization
dao.authorizeCharge(cardNumber, lastName);
// Create and populate authorization status object
ObjectFactory of = new ObjectFactory();
AuthorizationStatus status =
of.createAuthorizationStatus();
status.setAuthorizationToken(dao.authorizationToken);
...
return status;
이 메소드는 JAXB가 생성한 오브젝트를 파라미터로 수신하며, 관련 JAXB 오브젝트 다음은 StAX를 사용하여 동일한 인증 태스크를 수행하는 메소드이다. 메소드에 패스되는 파라미터는 String 오브젝트(실제로는 XML 문서)이다. public String authorizePaymentSTAX(String parameters) throws
CardServiceException {
try {
// Create the StAX reader to read the XML document
StringReader strReader = new StringReader(parameters);
XMLInputFactory staxFactory =
XMLInputFactory.newInstance();
staxFactory.setProperty(
XMLInputFactory.IS_VALIDATING, Boolean.FALSE);
XMLStreamReader xmlReader =
staxFactory.createXMLStreamReader(strReader);
StAX 파서는 // For sake of simplicity, we read only limited information
// about credit card and credit card user
String cardNumber= null;
String lastName = null;
while (xmlReader.hasNext()) {
if (xmlReader.isStartElement()) {
String sName = xmlReader.getLocalName();
if (sName.equals("cardNumber")) {
cardNumber = xmlReader.getElementText();
}
if (sName.equals("lname")) {
lastName = xmlReader.getElementText();
}
}
xmlReader.next();
}
xmlReader.close();
애플리케이션의 비즈니스 로직이 카드에 대한 대금 청구를 인증하고, 그런 다음 메소드가 응답 XML 문서를 생성한다. 아래 코드의 경우, // Emulate charge authorization
dao.authorizeCharge(cardNumber, lastName);
// Create response XML document
StringWriter strWr = new StringWriter();
XMLStreamWriter resvStatusWr =
XMLOutputFactory.newInstance().createXMLStreamWriter(strWr);
resvStatusWr.writeStartDocument();
resvStatusWr.writeStartElement(
"ns0", "AuthorizationStatus", "urn:CardService");
resvStatusWr.writeStartElement(
"ns0", "authorizationToken", "urn:CardService");
resvStatusWr.writeCharacters(dao.authorizationToken);
resvStatusWr.writeEndElement();
...
resvStatusWr.writeEndDocument();
return strWr.toString();
다음은 DOM을 사용하는 메소드인데, 메소드에 대한 파라미터는 클라이언트가 전송하는 XML 문서의 루트 엘리먼트를 제공한다. 메소드는 이를 이용하여 문서를 파싱하고 신용카드와 그 사용자에 관한 필요한 정보를 수집한다. public AuthorizeStatusDOM authorizePaymentDOM(
AuthorizePaymentDOM parameters) throws
CardServiceException {
try {
Element element = (Element)parameters.getAny();
// For sake of simplicity, we read only limited
// information about credit card and credit card user
Node cardNode = (
element.getElementsByTagName("cardNumber")).item(0);
String cardNumber =
cardNode.getFirstChild().getNodeValue();
Node lnameNode =
(element.getElementsByTagName("fname")).item(0);
String lastName =
lnameNode.getFirstChild().getNodeValue();
전과 마찬가지로, 메소드는 애플리케이션의 비즈니스 로직을 호출하여 카드 대금 청구를 인증하고, 이어서 // Emulate charge authorization
dao.authorizeCharge(cardNumber, lastName);
SOAPFactory sf = SOAPFactory.newInstance();
SOAPElement root = sf.createElement(
"AuthorizationStatus","ns0","urn:CardService");
SOAPElement token = sf.createElement("authorizationToken");
token.addTextNode(dao.authorizationToken);
root.addChildElement(token);
...
ObjectFactory of = new ObjectFactory();
AuthorizeStatusDOM status = of.createAuthorizeStatusDOM();
status.setAny(root);
return status;
웹 서비스를 컴파일하고 WAR 파일로 패키징하여 배포 앞서 클라이언트 구축 다음은 웹 서비스 클라이언트를 구축하기 위한 단계들이다.
클라이언트 클래스 작성 예제 패키지에는 독립형 웹 서비스 클라이언트 다음은 JAXB를 이용하여 서비스를 호출하는 클라이언트 내의 메소드이다. JAXB public void testAuthorizePaymentJAXB(
String authrequestXMLfile) throws Exception {
try {
// Get the unmarshaller to convert XML into Object
JAXBContext jc =
JAXBContext.newInstance("creditcard");
Unmarshaller u = jc.createUnmarshaller();
// Unmarshal the XML document into authorization
// request object
JAXBElement cardAuthorizationElement =
(JAXBElement)u.unmarshal(
new FileInputStream(authrequestXMLfile));
AuthorizationRequest cardAuthorizationRequest =
(AuthorizationRequest)
cardAuthorizationElement.getValue();
// Make web service call
AuthorizationStatus reply =
stubC.authorizePaymentJAXB(cardAuthorizationRequest);
서비스로부터의 응답이 JAXB 인증 상태 오브젝트라는 점에 유의할 것. 또한, 클라이언트는 XML 문서를 사용하는 대신 관련 JAXB 오브젝트를 파퓰레이트한 다음 서비스를 호출할 수도 있는데, 이런 방법은 다음은 StAX를 이용하여 서비스를 호출하는 클라이언트 내의 메소드이다. 이 메소드는 XML 문서를 String 오브젝트의 형태로 서비스에 패스하는데, 서비스로부터의 응답 역시 String이다. public void testAuthorizePaymentSTAX(
String authrequestXMLfile) throws Exception {
// Read XML document into a string
String authRequest =
readStringFromFileRaw(authrequestXMLfile);
try {
// Make web service call
String reply =
stubC.authorizePaymentSTAX(authRequest);
끝으로, DOM을 사용하여 웹 서비스를 호출하는 클라이언트 내의 메소드이다. 유틸리티 메소드 public void testAuthorizePaymentDOM(String authrequestXMLfile)
throws Exception {
// Get document root element
Element authRequest =
createElementMessage(authrequestXMLfile);
try {
// Populate authorization request object
ObjectFactory of = new ObjectFactory();
AuthorizePaymentDOM msg =
of.createAuthorizePaymentDOM();
msg.setAny(authRequest);
// Make web service call
AuthorizeStatusDOM reply =
stubC.authorizePaymentDOM(msg);
portable artifact 생성 서버 상의 WSDL을 사용하여 클라이언트 측 portable artifacts를 생성한다. 예제에서는 타깃 예제 실행하기 예제를 실행하려면 다음 단계를 수행한다.
글쓴이 소개 Deep Singh은 썬 마이크로시스템즈 Java Performance Engineering 그룹의 스태프 멤버로 활동하고 있다. 맨위로 | ||
| 개발자 지원 | ||
Java EE에 관한 프로그래밍의 조언이 필요하신가요? 그렇다면 개발자 전문 지원 서비스(http://developers.sun.com/services/expertassistance/ 영문)를 활용해 보세요. 맨위로 | ||
| 이 문서에 사용된 코드/정보에 대한 라이센스는 license terms 페이지에서 확인하실 수 있습니다. JavaEE 테크팁 아카이브 http://kr.sun.com/developers/j2ee/techtip.html SKDN(Sun Korea Developers Network)에서 J2EE/J2SE 테크팁, 이벤트 안내, 뉴스 등 좀 더 많은 정보를 확인하실 수 있습니다. ⓒ 2006 Sun Microsystems, Inc. All rights reserved. 썬의 등록상표에 대한 자세한 내용은 다음 페이지를 참조하시기 바랍니다. http://kr.sun.com/suntrademarks 뉴스레터 수신정보 변경을 원하시면 SKDN@sun.com로 메일을 보내주시기 바랍니다. 135-798, 서울 강남구 삼성동 159-1 무역센터 아셈타워 15-16층 한국 썬마이크로시스템즈(주) Sun Microsystems, 4150 Network Circle, USCA22-106, Santa Clara, CA 95054 U.S.A. |