1.2.9. Webサービスの公開

WSDLを公開したり、レジストリサービスにWebサービスを登録することによって、Webサービスを公開する方法について説明します。

1.2.9.1. WSDLの公開

Webサービスを公開する上でまず初めにやることは、インタフェースの公開、つまりWSDLの公開です。
ランタイムのWSDL公開機能
Webサービス作成ウィザードを利用してRPCのWebサービスを作成した場合、Webサービスの配備を行うと自動的にWSDLが公開されるようになっています。これは、JAX-RPC仕様に定められた機能であり、ランタイムにあらかじめ組み込まれている機能によって実現されています。このWSDLのURLは次のようになります。
http://WebサービスのURL/?wsdl
ファイルを公開する
SOAPメッセージを直接処理するWebサービスを作成した場合や、相手によってWSDLを使い分けるなどの目的で公開するWSDLを厳密に管理したい場合は、WSDLファイルをWebサーバやWebコンテナなどに置くことによって公開してください。

1.2.9.2. レジストリサービスにWebサービスを登録

UDDIレジストリなどのWebサービスが登録されているレジストリサービスに、自分で作成し公開するWebサービスを登録する方法について説明します。
JAXRインタフェースを利用する
JAXRは、UDDI、ebXMLなどのレジストリサービスに対して、同じインタフェースを用いてWebサービスの登録をすることができます。ここでは、JAXRインタフェースを用いてUDDI 2.0対応レジストリに登録を行う「JAXR_Publish」サンプルについて説明します。プロパティや登録内容などに使用する各値は、それぞれプロパティファイルから取得します。
//フィールドではコネクションを宣言します。
Connection connection = null; 
//登録を実行するmainメソッドです。
public static void main(String[] args) {
  //プロパティファイルの設定内容を取得します。
  ResourceBundle bundle = ResourceBundle.getBundle("com.nec.webotx.webservice.sample.JAXRSample");
  //検索用URLを取得します。
  String queryURL = bundle.getString("query.url");
  //登録用URLを取得します。
  String publishURL = bundle.getString("publish.url");
  //ユーザ名を取得します。
  String username = bundle.getString("registry.username");
  //パスワードを取得します。
  String password = bundle.getString("registry.password");

  JAXRPublishSample sample = new JAXRPublishSample();
  //コネクションを張ります。
  sample.makeConnection(queryURL,publishURL);
  //登録を実行します。
  sample.executePublish(username,password);
}

//コネクションを張るためのメソッドです。
public void makeConnection(String queryURL, String publishURL) {
  //プロパティファイルの設定内容を取得します。
  ResourceBundle bundle = ResourceBundle.getBundle("com.nec.webotx.webservice.sample.JAXRSample");
  //Factoryクラスを設定します。
  String factoryClass = "com.sun.xml.registry.uddi.ConnectionFactoryImpl";
  //各種プロパティ値の設定
  Properties props = new Properties();
  props.setProperty("javax.xml.registry.queryManagerURL",queryURL); //検索用URL
  props.setProperty("javax.xml.registry.lifeCycleManagerURL",publishURL); /登録用URL
  props.setProperty("javax.xml.registry.factoryClass",factoryClass); //ファクトリクラス
  String uuidString = bundle.getString("postal.uuidString");
  props.setProperty("javax.xml.registry.postalAddressScheme",uuidString); //住所
  props.setProperty("javax.xml.registry.semanticEquivalences", 
      "urn:uuid:PostalAddressAttributes/StreetNumber," +
      "urn:" + uuidString + "/MyStreetNumber|" +
      "urn:uuid:PostalAddressAttributes/City," +
      "urn:" + uuidString + "/MyCity|" +
      "urn:uuid:PostalAddressAttributes/State," +
      "urn:" + uuidString + "/MyState|" +
      "urn:uuid:PostalAddressAttributes/Country," +
      "urn:"+ uuidString + "/MyCountry");

  //実際にコネクションを張ります。
  try {
    ConnectionFactory cf = ConnectionFactory.newInstance();
    cf.setProperties(props);
    connection = cf.createConnection();
  } catch (Exception e) {
    e.printStackTrace();
  }
}

public void executePublish(String username, String password) {
  RegistryService rs = null;
  BusinessLifeCycleManager blcm = null;
  BusinessQueryManager bqm = null;
  ResourceBundle bundle = ResourceBundle.getBundle("com.nec.webotx.webservice.sample.JAXRSample");
  try {
    rs = connection.getRegistryService();
    blcm = rs.getBusinessLifeCycleManager();
    bqm = rs.getBusinessQueryManager();
    //login
    PasswordAuthentication passwdAuth = new PasswordAuthentication(username,password.toCharArray());
    Set creds = new HashSet();
    creds.add(passwdAuth);
    connection.setCredentials(creds);

    // executePublishメソッドのつづき

    /*
    * Conceptを登録します。Concept とは UDDI では tModel になります。
    */

    //Conceptオブジェクトを生成します。
    Concept specConcept = blcm.createConcept(null,bundle.getString("concept.name"),"");
    //Conceptについての説明を追加します。
    InternationalString is = blcm.createInternationalString(bundle.getString("concept.description"));
    specConcept.setDescription(is);
    //WSDLの参照先を追加します。
    ExternalLink wsdlLink = blcm.createExternalLink(bundle.getString("link.uri"),bundle.getString("link.description"));
    specConcept.addExternalLink(wsdlLink);
    String schemeName = "uddi-org:types";
    ClassificationScheme uddiOrgTypes = bqm.findClassificationSchemeByName(null,schemeName);
    Classification wsdlSpecClassification = blcm.createClassification(uddiOrgTypes,"wsdlSpec","wsdlSpec");
    specConcept.addClassification(wsdlSpecClassification);
    Collection concepts = new ArrayList();
    concepts.add(specConcept);
    //登録を実行します。
    BulkResponse response = blcm.saveConcepts(concepts);
    Collection exceptions = response.getExceptions();
    javax.xml.registry.infomodel.KeyconcKey = null;
    String uuidString = null;
    if (exceptions == null) {
      //レスポンスから登録時に割り振られたConceptのIDを取得し、保持します。
      Collection keys =response.getCollection();
      Iterator keyIter = keys.iterator();
      if (keyIter.hasNext()) {
        concKey = (javax.xml.registry.infomodel.Key)keyIter.next();
        //IDを取得し、保持する。
        uuidString = concKey.getId();
        System.out.println("save conceptsuccessful");
      }
    } else {
      Iterator excIter =exceptions.iterator();
      Exception exception = null;
      while (excIter.hasNext()) {
        exception = (Exception) excIter.next();
        System.err.println("Exception on save: " + exception.toString());
      }
    }
    //executePublishメソッドのつづき

    /*
    * Organizationを登録します。
    */

    //Organizationオブジェクトを生成します。このオブジェクトに
    //登録内容を追加していきます。
    //生成時には、企業などの機構名を追加します。
    Organization org = blcm.createOrganization(bundle.getString("org.name"));
    //この機構についての説明を追加します。
    InternationalString s = blcm.createInternationalString(bundle.getString("org.description"));
    org.setDescription(s);

    //連絡先の担当者名や役職を追加します。
    User primaryContact = blcm.createUser();
    PersonName pName = blcm.createPersonName(bundle.getString("person.name"));
    primaryContact.setPersonName(pName);

    //連絡先となる電話番号を追加します。
    TelephoneNumber tNum = blcm.createTelephoneNumber();
    tNum.setNumber(bundle.getString("phone.number"));
    Collection phoneNums = new ArrayList();
    phoneNums.add(tNum);
    primaryContact.setTelephoneNumbers(phoneNums);

    //住所を追加します。
    PostalAddress address = blcm.createPostalAddress(
        bundle.getString("postal.address1"),
        bundle.getString("postal.address2"),
        bundle.getString("postal.address3"),
        bundle.getString("postal.address4"),
        bundle.getString("postal.address5"),
        bundle.getString("postal.address6"),
        bundle.getString("postal.address7"));
    Collection postalAddresses = new ArrayList();
    postalAddresses.add(address);
    primaryContact.setPostalAddresses(postalAddresses);

    //e-mailアドレスを追加します。
    EmailAddress emailAddress = blcm.createEmailAddress(bundle.getString("email.address"));
    Collection emailAddresses= new ArrayList();
    emailAddresses.add(emailAddress);
    primaryContact.setEmailAddresses(emailAddresses);

    //Organizationに追加します。
    org.setPrimaryContact(primaryContact);

    //企業の分類を追加します。
    ClassificationScheme cScheme = blcm.createClassificationScheme(
        blcm.createInternationalString(bundle.getString("classification.scheme")),
        blcm.createInternationalString(""));
    javax.xml.registry.infomodel.Key cKey =
        (javax.xml.registry.infomodel.Key)blcm.createKey(bundle.getString("schema.key"));
    cScheme.setKey(cKey);
    Classification classification = blcm.createClassification(cScheme,
        bundle.getString("classification.name"),
        bundle.getString("classification.value"));
    org.addClassification(classification);

    ClassificationScheme Scheme1 = blcm.createClassificationScheme(
        blcm.createInternationalString(bundle.getString("classification.scheme1")),
        blcm.createInternationalString(""));
    javax.xml.registry.infomodel.Key cKey1 =
        (javax.xml.registry.infomodel.Key)blcm.createKey(bundle.getString("schema.key1"));
    cScheme1.setKey(cKey1);
    classification = blcm.createClassification(cScheme,
        bundle.getString("classification.name1"),
        bundle.getString("classification.value1"));
    org.addClassification(classification);

    //企業の識別情報を追加します。
    ClassificationScheme cScheme2 = blcm.createClassificationScheme(
        blcm.createInternationalString(bundle.getString("classification.scheme2")),
        blcm.createInternationalString());
    javax.xml.registry.infomodel.Key cKey2 =
        (javax.xml.registry.infomodel.Key)blcm.createKey(bundle.getString("schema.key2"));
    cScheme2.setKey(cKey2);

    ExternalIdentifier ei = blcm.createExternalIdentifier(cScheme2,
        bundle.getString("classification.name2"),
        bundle.getString("classification.value2"));
    org.addExternalIdentifier(ei);

    //サービスの情報を追加していきます。
    Collection services = new ArrayList();
    //サービス名を追加します。
    Service service = blcm.createService(bundle.getString("service.name"));
    //サービスについての説明を追加します。
    service.setDescription(blcm.createInternationalString(bundle.getString("service.description")));

    //サービスを利用するための技術的な情報についての説明を追加します。
    Collection serviceBindings = new ArrayList();
    ServiceBinding binding = blcm.createServiceBinding();
    is = blcm.createInternationalString(bundle.getString("svcbinding.description"));
    binding.setDescription(is);

    //架空のサービスエンドポイントURLの登録を可能にします。
    binding.setValidateURI(false);
    //サービスエンドポイントURLを追加します。
    binding.setAccessURI(bundle.getString("svcbinding.accessURI"));

    //tModelの参照先を追加します。このメソッドの最初に登録したConceptをレジストリから
    //取得します。
    Collection namePatterns = new ArrayList();
    namePatterns.add(bundle.getString("concept.name"));
    //検索を実行します。検索条件には、登録したConcept名を使用します。
    BulkResponse br = bqm.findConcepts(null,namePatterns, null, null,null);
    //取得したConceptとIDを照らし合わせ、登録したConceptと同じIDかどうか
    //確認します。
    Collection specConcepts = br.getCollection();
    Iterator iter = specConcepts.iterator();
    Concept retConcept = null;
    if (!iter.hasNext()) {
      System.out.println("No WSDL specification concepts found");
    } else {
      while(iter.hasNext()) {
        Concept testConcept = (Concept) iter.next();
        String testId = testConcept.getKey().getId();
        //IDが一致したConceptを一旦、保持します。
        if(testId.equals(uuidString)) {
          retConcept= testConcept;
          System.out.println("findconcept Successful");
        }
      }
      //ConceptからtModelの参照先を取得し、Organizationに追加します。
      if (retConcept != null) {
        Collection links =retConcept.getExternalLinks();
        if (links.size() > 0) {
          ExternalLinklink = (ExternalLink)links.iterator().next();
        }
        SpecificationLink specLink = blcm.createSpecificationLink();
        specLink.setSpecificationObject(retConcept);
        binding.addSpecificationLink(specLink);
      }
      serviceBindings.add(binding);
      service.addServiceBindings(serviceBindings);
      services.add(service);
      //Organizationに追加します。
      org.addServices(services);

      //登録を実行します。
      Collection orgs = newArrayList();
      orgs.add(org);
      BulkResponse response2 = blcm.saveOrganizations(orgs);
      //レスポンスに例外が含まれているかチェックします。例外がなければ
      //"Successful"と表示して終了します。例外がある場合は、その内容を
      //表示します。
      Collection exceptions = response2.getExceptions();
      if(exceptions == null) {
        System.out.println("Successful");
      } else {
        Iterator excIter = exceptions.iterator();
        Exception exception = null;
        while(excIter.hasNext()) {
          exception = (Exception) excIter.next();
          System.err.println(exception.toString());
        }
      }
    }
  } catch (Exception e) {
    e.printStackTrace();
  } finally {
    //最後にレジストリへのコネクションをクローズします。
    if(connection != null) {
      try {
        connection.close();
      } catch(JAXRException je) {
      }
    }
  }
}
UDDI 3.0対応レジストリに登録する
UDDI 3.0 対応レジストリに登録する方法については、「WebOTX UDDI Registry アプリケーション開発ガイド」を参照してください。