레이블이 SOAP인 게시물을 표시합니다. 모든 게시물 표시
레이블이 SOAP인 게시물을 표시합니다. 모든 게시물 표시

2008년 11월 4일 화요일

[soap] asmx 와 soap::lite 사용

#!/usr/bin/perl -w use strict;

use SOAP::Lite 'trace', 'debug';

my $server = SOAP::Lite
    ->uri('http://ws.robstones-services.co.uk/External')    
    ->proxy('http://ws.robstones-services.co.uk/external.asmx');

my $returned = $server ->getCallList({ 'Username' => 'RobsUser', 'Password' => 'RobsPassword' });

foreach my $type ($returned->valueof('//getCallListResult/string'))
{
    next unless ($type); ## ignore any undefs
    print "$type\n";
 }

2007년 8월 10일 금요일

Representational State Transfer(REST)

SOA를 구현하기 위한 많은 표준이 제시되고 있지만 크게 SOAP, XML-RPC, REST로 진영이 나누어 져있다고 보면 무방할 것이다.

REST란 대규모 네트워크 시스템을 위한 아키텍처로 2000년 Roy Fielding의 박사 학위 논문에서 처음 제안되었다. REST는 원래 웹과 같은 대규모 네트워크 시스템을 위한 원칙들의 모음을 말하는 것이지만, 요즘에는 XML과 HTTP를 사용하는 단순한 웹 기반 인터페이스(즉, REST의 원칙을 따르는 Web Services)를 지칭하기도 한다.

최근엔 많은 Open-Api가 만들어지고 있으며 사용의 편리성때문에 SOAP계열보다는 REST로 무게의 추가 기운 느낌이다.

간단하게 REST계열의 특징을 보면 REST는 HTTP프로토콜을 사용하며 초창기의 WEB과 동일한 룰을 가지고 있다고 보면 된다.

  - 상태를 유지하지 않는 클라이언트/서버 구조를 가진다.

  - 작고 어디에서나 적용되는 인터페이스를 가진다. (e.g., GET, POST, PUT, DELETE)

  - 모든 자원은 URI를 이용하여 유일하게 지칭될 수 있다.

  - 자원들의 표현(Representation)들이 URI을 통해 서로 연결되어 있다.


이와 같은 특징으로 인해 웹 서버와 웹 클라이언트의 종류에 상관없이 URI만 알면 HTTP GET과 같은 인터페이스를 이용하여 간단히 해당 자원에 접근할 수 있다.

 

오늘날 대부분의 웹 어플리케이션들은 사용자 인증 또는 상태 정보를 유지하기 위해 쿠키 또는 HttpSession 등을 사용하고 있는데 이것은 REST의 원칙에 명백히 위배되는 방식이다. 또, 웹 서버상의 데이터를 조회하는 것은 물론이고 변경이나 삭제 심지어는 생성을 위해서도 GET method를 사용하는 경우도 매우 많은 것이 사실이다. (서버 사이드의 변경을 유발하는 요청에 대해서는 POST를 사용하는 것이 바람직하며, ActiveResource 에서는 생성을 위해서는 PUT, 삭제를 위해서는 DELETE를 사용한다.)


보통 PERL이나 PHP로 프로그램을 할때, GET $URL, POST $URL등을 사용하지만 표준엔 DELETE도 있다. 사용해 본적 없는데..지워지면 큰일이게..
 

하지만 현실적으로 여러 사용자에 대한 동적인 정보를 다루는 웹사이트를 쿠키나 세션없이 개발하는 것은 쉬운 일이 아니다. 또 PUT과 DELETE 같은 method는 HTTP 스펙에는 존재하지만 실제 이를 지원하는 브라우저는 많지 않다. (참고로 XMLHttpRequest 에서는 PUT과 DELETE를 지원한다. ? Using REST with Ajax )

 

웹은 수많은 행위자들이 상호작용하는 시스템 중 가장 성공한 예이다. 그러므로 유사한 시스템에서 REST모델은 가치 있는 프레임워크를 제공해 줄 수 있다.REST와 가장 비교되는 모델은 Remote Procedure Call(RPC)모델 이다. RPC모델은 로컬 프로그래밍 모델의 함수 호출 형식을 네트워크 시스템에 적용시킨 것이다. REST의 성공과 DCOM, CORBA, RMI와 같은 기존 RPC모델의 실패는 REST가 큰 스케일의 네트워크 시스템에 적합하다는 것을 의미한다.

 

그러나 모든 웹 application들이 Stateless 와 Uniform Interface 라는 특성을 충분히 따르기에는 현실적인 어려움이 많으므로 당분간은 순수한 REST가 일반적인 웹 개발의 패러다임으로 자리잡지는 못할 것으로 보인다.

  

그런데 최근 관심이 높아지고 있는 분야들인 Open API, Ajax, Rails 와 같은 곳에서 REST라는 용어를 자주 접하게 되는 것은 반가운 현상이다.
REST를 사용하게 되면 어떻게 보면 서버쪽에 요청을 자주 할것 같지만 사실은 어떻게 디자인 하는가의 문제이다. XML로 전체 데이터를 받은 후 CLIENT의 메모리와 프로세서 파워를 사용해 이리저리 조합해 보여주고, DATA는 Ajax를 사용하여 Server와 Sync한다면 훨씬 훌륭한 구조가 될 수 있다.

 

 

Amazone, eBay, Yahoo 와 같은 주요 웹 업체들은 대부분 REST 방식의 OPEN API를 제공하고 있으며 ( Amazone 이 제공하는 SOAP, REST 두 가지 방식의 API 중에서 REST API 의 사용율이 85%라는 정보도 소개 된 바 있다.) 최근에 Google 이 기존의 SOAP 방식 API의 지원을 중단 하면서 Ajax를 이용한 API를 새로 제공하기 시작한 것도 눈여겨 볼만한 대목이다



2007년 6월 14일 목요일

XML-RPC와 SOAP Web Service

XML-RPC is a protocol that allows programs of different languages on different machines to easily talk to each other. By sending a well-defined XML document over unadorned HTTP, a client program can make a remote procedure call to a server. The server processes the request and wraps its response in another well-defined XML document that is sent back to the client over that same HTTP connection.

XML-RPC는 이종 머신상의 이종 언어들이 각자 쉽게 데이터를 주고 받을 수 있게 도와주는 일종의 프로토콜이다. 잘 정의된 XML문서를 HTTP를 통해 보내고 클라이언트는 서버의 프로시져를 호출 할 수 있다. 서버는 클라이언트의 요청에 대해 마찬가지로 잘 정의된 XML문서로 답변한다.

 

Because procedure requests and responses are all in XML, each end of the RPC connection need not be written in the same language or even for the same platforms

프로시져의 호출과 답변이 XML 이루어 지기 때문에 같은 환경과 언어가 필요하지 않다.

 

Clients code to an agreed-upon API that a Web service listener implements. Either side of the API fence can change without affecting the other side. In this way, Web services in general, and XML-RPC in particular, can help break down the Berlin Wall of incompatible OS platforms and make language-agnostic software network components.

클라이언트의 서비스Api 지원한다. Xml-RPC Web Service 일반적인 방법은 Web Service이고 XML-RPC 특별한 방법이다.

 

Although less famous than its younger sibling SOAP, XML-RPC is a simple and easy tool that can help you integrate even the most uncommunicative of systems

서비스보다 유명하진 않지만 XML-RPC 통신할 없는 시스템조차도 관리할 있는 쉬운 방법이다.

 

Where SOAP is a generalized, object-oriented, messaging protocol that is designed to carry arbitrary XML payloads across any network protocol, XML-RPC is a simple procedural protocol designed only to make remote function calls

SOAP 서비스는 XML 전송하기 위한 객체 지향의 네트워크 프로토콜인데 반해 XML-RPC 단순 리모트 펑션을 부르기 위한 방법 하나이다.

 

CPAN의 RPC::XML 모듈을 사용한다.

 

결론: SOAP Web Service와 XML-RPC는 다름 ㅋㅋㅋㅋ

데이터를 전송하는 복잡한 행동 보다는 서버의 프로시져를 단순히 CALL해서 사용할 때 사용한다.

두 개의 프로토콜을 적절히 조합해서 사용하면 최상의 결과를 얻을 수 있음

2007년 5월 14일 월요일

soap client sample #1

<?
// date: 2007.5.14 - jk
require_once('SOAP/Client.php');

// soapclient 생성
$soapclient = new SOAP_Client( "http://[domain]/service/service.cgi" );

// parameter
$parameters = array ( "name1"=>"test1", "name2"=>"test2" );

// namespace는 server의 모듈을 의미한다
$soapoptions = array('namespace' => 'urn:Demo', 'trace' => 0);

echo $soapclient->call( "hi", $parameters, $soapoptions);

?>
~               

결과
hi test1
hi test2

별거 아니지만 일단 테스트가 된다...server는 perl의고 client는 php인 case였음 ㅋㅋ

PEAR - PHP Extension and Application Repository 설치함

PERL의 CPAN처럼 Reusable한 module들을 설치 할 수 있는 util인듯

url: http://pear.php.net/index.php

여기서 SOAP Client관련 모듈을 다운 받아 개발 하려 한다.


PEAR Installer 설치 on Linux
In PHP 5.0.0+, the PHP CLI binary is php.exe
#
#  > php -r "readfile('http://pear.php.net/go-pear');" > go-pear
#  > php go-pear


# 설치 완료 화면
The 'pear' command is now at your service at /usr/local/php/bin/pear

** The 'pear' command is not currently in your PATH, so you need to
** use '/usr/local/php/bin/pear' until you have added
** '/usr/local/php/bin' to your PATH environment variable.

Run it without parameters to see the available actions, try 'pear list'
to see what packages are installed, or 'pear help' for help.

For more information about PEAR, see:

  http://pear.php.net/faq.php
  http://cvs.php.net/co.php/pearweb/doc/pear_package_manager.txt?p=1
  http://pear.php.net/manual/

Thanks for using go-pear!

TEST
pear install  SOAP

2007년 5월 11일 금요일

SOAP::Data, SOAP::SOM 을 사용해 structured 정보 전달

#### Demo.pm 소스
use SOAP::Lite;

package Demo;
 
  #===============================
  # object Acess
  #
  ....

  # SOAP으로 데이터를 만들어 봄
  sub someMethod3
  {
        # $elem1 = SOAP::Data->name('item' => 123)->type('SomeObject');
        # $elem2 = SOAP::Data->name('item' => 456)->type('SomeObject');

        # 흠 SomeObject는 뭐지?
        $elem1 = SOAP::Data->name('id' => 123);
        $elem2 = SOAP::Data->name('name' => "test 입니다");

        push(@array,$elem1);
        push(@array,$elem2);

        $data = SOAP::Data->name("infos" =>
                \SOAP::Data->value( @array )   
        );
       
        return $data;
  }
  ....

  #===============================
  # 클라이언트 소스
  #
  #!perl -w
   use SOAP::Lite;
   use Data::Dumper;

   use SOAP::Lite +autodispatch =>
         uri => 'http://[Server]/Demo',
         proxy => 'http://[Server]/service/service.cgi';

  my $obj = Demo->new(90);
  $som = SOAP::SOM->new;
  $som = $obj->someMethod3();

  print Dumper( $som );

2007년 5월 10일 목요일

SOAP::Serializer

SOAP::Serializer
 data를 XML로 만들어 주는 역할을 수행
 $serialize = SOAP::Serializer->new( );
 
메서드 설명
 $serialize = SOAP::Serializer->new( );
 
 envelope(method, data arguments)
 $serialize->envelope(fault => $fault_obj);
  입력된 값을 envelope data로 만들어 줌
 context
 $serialize->context->packager();
  SOAP::Serializer로 만들어진 data를 access가능 하도록 만들어 줌
 
 $serial->soapversion('1.2');
  SOAP의 Version정의
 
 $serial->xmlschema($xml_schema_1999);
 
custom data type
 serialrize는 MyModule::MyPackage가 정의되어 있는지 확인한 후 $foo를 SOAP::Data의 형태로 만들어 준다.

 $foo = MyModule::MyPackage->new;
 my $client = SOAP::Lite
  ->uri($NS)
  ->proxy($HOST);
 $som = $client->someMethod(SOAP::Data->name("foo" => $foo));

흠 사용자 정의 타입 만들기가 의외로 어렵네...어쩐다.

SOAP::SOM Soap return을 functionally 하게 access할 수 있게 해 준다.

SOAP::SOM   
    Web Service의 SOAP Response의 값을 access하는것이 가능함
   
    $som = SOAP::SOM->new;
    my $client = SOAP::Lite
        ->readable(1)
        ->uri($NS)
        ->proxy($HOST)
    $som = $client->someMethod();
   
    위의 예제에서 여기에서 $som은 SOAP::SOM 타입 이였음 dump떠보면 알 수 있겠네..
   
    잠시 dump 예제
    ------------------------------------------
    $VAR1 = bless( {
                 '_name' => 'sign',
                 '_signature' => [],
                 '_value' => [
                               'Aries'
                             ],
                 '_attr' => {}
               }, 'SOAP::Data' );
              
    타입이 'SOAP::Data'라고 분명히 나온다.
    ------------------------------------------
   
    XML data를 바로 사용가능하게 함
    $som = SOAP::SOM->new($message_as_xml);

몇몇 메서드 들   
    match(path)
    $som->match('/Envelope/Body/[1]');
    SOAP의 Body는 Envelope attribute가 시작임


    $envelope = $som->envelope;
        몰 가져오지?
   
    $ns = $som->namespaceof('[1]');
        네임 스페이스
       
    $body = $som->body;
   
   
예제 1 ( xpath와 비슷한 방식 ? )
    <Envelope>
      <Body>
        <fooResponse>
          <bar>abcd</bar>
        </fooResponse>
      </Body>
    </Envelope>
   
   
    my $soap = SOAP::Lite
        ->uri($SOME_NS)
        ->proxy($SOME_HOST);
    my $som = $soap->foo();
    print $som->valueof('//fooResponse/bar');
   
   
예제 2 ( attribute를 찾는 방식 )
    <Envelope>
      <Body>
        <c2fResponse>
          <convertedTemp test="foo">98.6</convertedTemp>
        </c2fResponse>
      </Body>
    </Envelope>
   
    print "The attribute is: " .
      $som->dataof('//c2fResponse/convertedTemp')->attr->{'test'};
   
   
예제 3 ( iterate 방식 )
    <Envelope>
      <Body>
        <catalog>
          <product>
            <title>Programming Web Service with Perl</title>
            <price>$29.95</price>
          </product>
          <product>
            <title>Perl Cookbook</title>
            <price>$49.95</price>
          </product>
        </catalog>
      </Body>
    </Envelope>
   
   
    for my $t ($som->valueof('//catalog/product')) {
      print $t->{title} . " - " . $t->{price} . "\n";
    }
   
예제 4 ( array의 array 처리 )
    $xml = <<END_XML;
    <foo>
      <person>
        <foo>123</foo>
        <foo>456</foo>
      </person>
      <person>
        <foo>789</foo>
        <foo>012</foo>
      </person>
    </foo>
    END_XML

    #
    # 앗 왜 여기서는 Deserializer를 사용했지?
    # $som = SOAP::SOM->new($xml); 과의 차이점은 무얼까?
    #
    my $som = SOAP::Deserializer->deserialize($xml);
    my $i = 0;
    foreach my $a ($som->dataof("//person/*")) {
        $i++;
        my $j = 0;
        foreach my $b ($som->dataof("//person/[$i]/*")) {
            $j++;
            # do something
        }
    }

SOAP::Data 여러가지 타입의 data를 만들어 내기 위해 사용함

여러 타입의 SOAP Data를 만들어 내는데 사용한다.

    $elem1 = SOAP::Data->new(name => 'idx', value => 5);
    $elem2 = SOAP::Data->name('idx' => 5);
    $elem3 = SOAP::Data->name('idx')->value(5);
  
    위의 3개의 예제는 모두 같은 값이다.
   
    <foo>
      <bar>123</bar>
    </foo>
   
    의 구현을 위해서는 아래의 예제를 사용하면 된다.
   
    SOAP::Data->name('foo' => \SOAP::Data->value(
        SOAP::Data->name('bar' => '123')));
       
 Array 예제
    $elem1 = SOAP::Data->name('item' => 123)->type('SomeObject');
    $elem2 = SOAP::Data->name('item' => 456)->type('SomeObject');
    push(@array,$elem1);
    push(@array,$elem2);

    my $client = SOAP::Lite
        ->readable(1)
        ->uri($NS)
        ->proxy($HOST);

    $temp_elements = SOAP::Data
        ->name("CallDetails" => \SOAP::Data->value(
              SOAP::Data->name("elem1" => 'foo'),
              SOAP::Data->name("elem2" => 'baz'),
              SOAP::Data->name("someArray" => \SOAP::Data->value(
                  SOAP::Data->name("someArrayItem" => @array)
                            ->type("SomeObject"))
                       )->type("ArrayOf_SomeObject") ))

        ->type("SomeObject");

    $response = $client->someMethod($temp_elements);
   
    결과물 확인
    <?xml version="1.0" encoding="UTF-8"?>
    <SOAP-ENV:Envelope
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
        xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:namesp2="http://namespaces.soaplite.com/perl"
        SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      <SOAP-ENV:Body>
        <namesp1:someMethod xmlns:namesp1="urn:TemperatureService">
          <CallDetails xsi:type="namesp2:SomeObject">
            <elem1 xsi:type="xsd:string">foo</elem1>
            <elem2 xsi:type="xsd:string">baz</elem2>
            <someArray xsi:type="namesp2:ArrayOf_SomeObject">
              <item xsi:type="namesp2:SomeObject">123</bar>
              <item xsi:type="namesp2:SomeObject">456</bar>
            </someArray>
          </CallDetails>
        </namesp1:test>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>

XML 자체로 Data를 만들어 낼 수도 있음
    $xml_content = "<foo><bar>123</bar></foo>";
    $elem = SOAP::Data->type('xml' => $xml_content);

SOAP Data type

Data Types 
Scalars
Booleans, Integers, Doubles, Strings

Vectors
Arrays, Associative Arrays ("hashes"), Objects, Mixed

2007년 5월 9일 수요일

CGI::XMLApplication -- Object Oriented Interface for CGI Script Applications

PERL로 SOAP구현을 공부하다 나온 라이브러리

샘플
use CGI::XMLApplication;

  $script = new CGI::XMLApplication;
  $script->setStylesheetPath( "the/path/to/the/stylesheets" );

  # either this for simple scripts
  $script->run();
  # or if you need more control ...
  $script->run(%context_hash); # or a context object

설명
PERL 프로그래머에게 XML/XSLT를 function으로 만들수 있는 기능 제공한다.
 XML::LibXML/ XML::LibXSLT 의 강력한 기능을 사용할 수 있게 해준다.

코드 레벨의 프로젝트 관리가 가능하도록 해준다네? 어떻게 해준다는거지?
웹 어플리케이션을 여러개의 간단한 파트로 나눌 수 있게 해준다라..대부분의 코드들을 심플한 상태로 둘 수 있고 XMLApplication이 이들을 안정적으로 유지시켜 준다.

이 모듈을 기존의 CGI모듈을 확장해 준다. 물론 모든 기존의 CGI모듈을 여전히 사용이 가능하다. ..좋구만...CGI모듈의 확장판이었구나. 그래서 SOAP에서 사용됐던것 같음

흠 결과물의 layout을 읽기 좋게 만들어 주는 효과도 있다네.
그래서 setStylesheetPath가 있나 보네.

flow도 있군...참조 http://search.cpan.org/~phish/CGI-XMLApplication-1.1.3/XMLApplication.pm

어떻게 Event를 catch하는가?

클라이언트
    <!-- SOME HTML CODE -->
    <input type="submit" name="dummy" value="whatever" />
    <!-- SOME MORE HTML :) -->


어플리케이션
 # Application Module
package myApp;

use CGI::XMLApplication;
@ISA = qw(CGI::XMLApplication);

sub registerEvents { qw( dummy ); } # list of event names

# ...

sub event_dummy {
     my ( $self, $context ) = @_;

     # your event code goes here

     return 0;
}

cgi 스크립트들은 submit버튼을 통해 event가 발새되고 한다.
많은경우 쿼리 스트링을 통해 event를 발생시키기 쉽지 않다, 이런경우 XMLApplication은 event_init() 를 사용해 스페셜 event를 전송 할 수 있다(예를들면 application error와 같은), 이 작업은 sendEvent() function을 사용해 구현이 가능하다. 하지만 반듯이 regist된 function만을 사용할 수 있다.

method registerEvents
method run

Event System

XMLApplication은 두가지 부분으로 구성되어 있다. 1) 서버로 부터 스크립트 실행하는 부분 2) 어플리케이션 모듈이 스크립트로 부터 불려져 로드되는 부분

CGI::XMLApplication 두가지 타입의 이벤트 핸들러가 있다.  아 띠...모뇽~
implicit events
registerEvents를 사용해 이름이나 필요치 않은 이벤트 들을 정의?

Common to all applications and explicit events
차이가 뭐지?

package myApp;
  use CGI::XMLApplication;
  @ISA = qw(CGI::XMLApplication);

  sub registerEvents { qw( missing ... ) ; }

  # event_init is an implicit event
  sub event_init {
     my ( $self, $context ) = @_;
     if ( not ( defined $self->param( $paraname ) && length $self->param( $paramname ) ) ){
        # the parameter is not correctly filled
        $self->sendEvent( 'missing' );
     }
     else {

    ... some more initialization ...

     }
     return 0;
  }

  ... more code ...

  # event_missing is an explicit event.
  sub event_missing {
     my ( $self , $context ) = @_;

     ... your error handling code goes ...

     return -4 if $panic;  # just for illustration
     return 0;
  }

솔직히 &missing하는거랑 차이가 뭔지 모르겠네..쓰바..

Implicit Events

the XML Serialization











2007년 5월 8일 화요일

2/3 두 개의 파일 비교 webservice , cgi 파일

#!/usr/bin/perl -w
use strict;
use SOAP::Lite;
 ...
my $soap = SOAP::Lite
  -> uri('http://my.host.tld/WebSemDiff')
  -> proxy('http://my.host.tld/cgi-bin/semdiff.cgi')
  -> on_fault( \&fatal_error );

my $result = $soap->compare( $file1, $file2 )->result;

print "Comparing $f1 and $f2...\n";

if ( defined $result and scalar( @{$result} ) == 0 ) {
    print "Files are semantically identical\n";
    exit;
}

foreach my $diff ( @{$result} ) {
print $diff->{context} . ' ' .
      $diff->{startline} . ' - '  .
      $diff->{endline} . ' '  .
      $diff->{message} .
      "\n";

}
#================
#


# auto dispatch를 사용한 version
#

use SOAP::Lite +autodispatch => uri => 'http://my.host.tld/WebSemDiff', proxy =>'http://my.host.tld/cgi-bin/semdiff.cgi', on_fault => \&fatal_error ; my $result = SOAP->compare( $file1, $file2 ); print "Comparing $f1 and $f2...\n";

1/3 두 개의 파일 비교 web service

# 모듈 작성 부분
package WebSemDiff;

use strict;
use CGI::XMLApplication;
use XML::SemanticDiff;
use XML::LibXML::SAX::Builder;
use XML::Generator::PerlData;

use vars qw( @ISA );
@ISA = qw( CGI::XMLApplication );


# 메서드 추가 부분
sub selectStylesheet {
    my ( $self, $context ) = @_;
    my $style = $context->{style} || 'default';
    my $style_path = '/www/site/stylesheets/';
    return $style_path . 'semdiff_' . $style . '.xsl';
}

# XML::LibXML::Document object의 확장

sub getDOM {
    my ( $self, $context ) = @_;
    return $context->{domtree};
}

#
sub getXSLParameter {
    my $self = shift;
    return $self->Vars;
}


# event registration and event callbacks
sub registerEvents {
    return qw( semdiff_result );
}

sub event_semdiff_result {
    my ( $self, $context ) = @_;
    my ( $file1, $file2, $error );
    my $fh1 = $self->upload('file1');
    my $fh2 = $self->upload('file2');
    $context->{style} = 'result';


    if ( defined( $fh1 ) and defined( $fh2 ) ) {
        local $/ = undef;
        $file1 = <$fh1>
        $file2 = <$fh2>;

    eval {
            $context->{domtree} = $self->compare_as_dom( $file1, $file2 );
        };

        if ( $@ ) {
            $error = $@;
        }
    }
    else {
        $error = 'You must select two XML files to compare and wait for them to finish uploading';
    }

    if ( $error ) {
        $context->{domtree} =  $self->dom_from_data( {  error => $error } );
    }
   

    unless ( defined( $context->{domtree} )) {
        my $msg = "Files are semantically identical.";
        $context->{domtree} =  $self->dom_from_data( {  message => $msg } );
    }
}



sub compare {
    my $self = shift;
    my ( $xmlstring1, $xmlstring2 ) = @_;
    my $diff = XML::SemanticDiff->new( keeplinenums => 1 );
    my @results = $diff->compare( $xmlstring1, $xmlstring2 );
    return \@results;
}

2007년 5월 7일 월요일

Array passing simple example

    #======================================
   #  auto dispatching client - 2007.5.3 - jkryu
   #  이 것은 클라이언트
   print "==============\n";
   print "auto dispatching \n";

   use SOAP::Lite +autodispatch =>
     uri => 'http://host/Demo',
     proxy => 'http://host/service/service.cgi';

   # array passing simple case
   # 2007.5.7
   @a = ("aa", "bb", "cc", "dd", "ee");

   my $obj = Demo->new(90);
   $result = $obj->hi( @a );
   print $result;

   #======================================
   #  auto dispatching server - 2007.5.3 - jkryu
   #  서버
   #!/usr/bin/perl -w

  use SOAP::Transport::HTTP;
  use Demo;

  SOAP::Transport::HTTP::CGI
    -> dispatch_to('Demo')
    -> handle;

    #======================================
   #  auto dispatching server - 2007.5.3 - jkryu
   #
   package Demo;

  sub hi {
        my ($class, @a) = @_;
        my $result;

        for ( $i=0; $i <= $#a; $i++ )
        {
                $result .= "hi " . $a[$i] . "\n";
        }

        # return "HI $a \n";
        return $result;
  }

  #===============================
  # object Acess
  #
  sub new {
      my $self = shift;
      my $class = ref($self) || $self;
      bless {_temperature => shift} => $class;
  }  

-----------  결과 ---------------
$ perl client.pl  
hi 123
==============
auto dispatching
hi aa
hi bb
hi cc
hi dd
hi ee

Handling Lists, Structure, Objects ...

'Treat the result of SOAP call as variable of specified type' 으로 처리 함으로써 다양한 type의 결과물을 passing할 수 있다.

Client
#!perl -w
  use SOAP::Lite;
  my $result = SOAP::Lite
        -> uri('urn:xmethodsServicesManager')
        -> proxy('http://www.xmethods.net/soap/servlet/rpcrouter')
        -> getAllSOAPServices();
  if ($result->fault) {
    print $result->faultcode, " ", $result->faultstring, "\n";
  } else {
    # reference to array of structs is returned
    my @listings = @{$result->result};
    # @listings is the array of structs
    foreach my $listing (@listings) {
      print "-----------------------------------------\n";
      # print description for every listing
      foreach my $key (keys %{$listing}) {
        print $key, ": ", $listing->{$key} || '', "\n";
      }        
    }
  }


# 아 놔~~ 서버가 없쟎아. 썩을

2007년 5월 3일 목요일

SOAP DATA TYPE

PERL은 type이 없지만 SOAP의 경우 타입이 존재한다.

my $var = SOAP::Data->type(string => 123);

my $var = SOAP::Data->type('string')->name(myvar => 123);
my $var = SOAP::Data->type('string')->name('myvar')->value(123);

You may always get/set the value of this variable with the value() method:

  $var->value(321);            # set new value
  my $realvalue = $var->value; # store it in variable


좋구만..허나 내가 알고 싶은건 data set을 전달하는 방법인데?

왜 없지? 흠흠..

SOAP Server Module Dispatch

case 1. Static external
SOAP::Transport::HTTP::CGI  
    -> dispatch_to('Demo')    
    -> handle;

설명 : Demo는 @INC내에 있어야 하며 해당 서버는 Demo 클래스만을 dispatch할 수 있다.

Case 2. Dynamic

      SOAP::Transport::HTTP::CGI
    -> dispatch_to('/home/soaplite/modules')
    -> handle;

설명: 모듈이 저장된 디렉터리를 설정함으로써 모듈 디렉터리 내부의 클래스들을 사용할 수 있다.

Case 3. Mixed
     SOAP::Transport::HTTP::CGI
     -> dispatch_to('/home/soaplite/modules', 'Demo', 'Demo1', 'Demo2')
     -> handle;
설명: 디렉터리와 특정 모듈을 모두 사용할 수 있다.


2007년 5월 2일 수요일

[SOAP] 간단한 Server / Client 예제 작성 중

URL: http://guide.soaplite.com/#item_uri

Web Service에 대한 대략적 study와 병행해서 실제 perl의 SOAP::Lite를 사용하여  Web Service를 작성해 보고자 한다.

#============================
# business module
# date: 2007.5.2
#
package Demo;

  sub hi {
        my ($class, $a) = @_;

        return "HI $a \n";
  }

  sub bye {
    return "goodbye, cruel world";
  }

  #===============================
  # object Acess
  #
  sub new {
      my $self = shift;
      my $class = ref($self) || $self;
      bless {_temperature => shift} => $class;
  }
  sub as_fahrenheit {
      return shift->{_temperature};
  }
  sub as_celsius {
      return 5/9*(shift->{_temperature}-32);
  }
1;

#================================
# service.cgi
# date: 2007.5.2
#!/usr/bin/perl -w

  use SOAP::Transport::HTTP;
  use Demo;

  SOAP::Transport::HTTP::CGI
    -> dispatch_to('Demo')
    -> handle;


#================================
# client.pl
# date: 2007.5.2
#!perl -w
  use SOAP::Lite;
    # -> uri('http://www.ezadmin.co.kr')
  # uri는 class의 위치?
  print SOAP::Lite
    -> uri('http://[domain]/Demo')
    -> proxy('http://[domain]/service.cgi')
    -> hi( "123" )
    -> result;


결과
$ perl client.pl
HI 123

쩝 이 단순한 결과를 얻기 위해 하루종일 이렇게 저렇게 해보다니..ㅠ.ㅠ 내일은 autodispatch 에 대해서 작업할 예정