This tutorial demonstrates how to use Grimoires Java API to write a simple program to publish and discover a service to a Grimoires registry.
In this tutorial, we use the example in Grimoires tutorial. It publishes the BLAST service from the DNA Data Bank of Japan (DDBJ). The service is described using WSDL as the description language. The WSDL file is located at http://xml.nig.ac.jp/wsdl/Blast.wsdl. We assume the BLAST service is deploy at http://xml.nig.ac.jp/xddbj/Blast.
In this tutorial, we will also publish the service's WSDL file, and attach a piece of metadata to a message part inside the WSDL description. The metadata describes the semantic type, i.e., a DNA sequence, of the message part, which is syntactically a string. Finally, we discover the message part based on the metadata. Given the message part, we can further discover which operation this message part belongs to, which WSDL description the operation belongs to, and which service has implemented the WSDL description. Following these steps, a service can be discovered by its metadata.
This example program is also available in the "GShell/src" directory. To run them, make sure that all Java libraries under the "GShell/lib" directory and GShell classes under the "GShell/build/classes" directory are put into your CLASSPATH. It is assumed your Grimoires registry is deployed at http://fantasio.ecs.soton.ac.uk:8080/grimoires.
java uk.ac.soton.ecs.grimoires.shell.APITutorialExample http://fantasio.ecs.soton.ac.uk:8080/grimoires
On the screen, you will see:
====Publish a business==== Business key: c758196c-0f03-4d74-bbc1-19e1c3343483 ====Publish a service==== Service key: 5b3529c3-6635-4fc5-9ba2-7f37963d7176 ====Find a service==== Service name: Blast Service key: 5b3529c3-6635-4fc5-9ba2-7f37963d7176 Business key: c758196c-0f03-4d74-bbc1-19e1c3343483 Service description: A DDBJWeb Service Access point in binding template: http://xml.nig.ac.jp/xddbj/Blast tModel: http://xml.nig.ac.jp/wsdl/Blast.wsdl ====Publish WSDL==== WSDL key: bdeb81e1-ba19-4b32-b757-c0c3e717387b ====Publish metadata==== Metadata key: 0da51ebb-f7fc-4d68-bc8b-edf54cc5cc63 ====Inquire metadata==== Found a message part with this metedata (http://www.grimoires.org/SemanticType, DNA_Sequence) Message namespacehttp://www.themindelectric.com/wsdl/Blast/ Message namesearchParam0In Message part nameparam
Before we publish or discover a service, we need to set up stubs, which are in charge of serializing/deserializing Java objects to/from SOAP messages, and sending receiving SOAP messages to/from Grimoires.
private static void setUpStubs(String grimoiresURL) throws Exception {
if (!grimoiresURL.endsWith("/")) {
grimoiresURL = grimoiresURL + "/";
}
String publishEndpoint = grimoiresURL + "services/publish";
String inquireEndpoint = grimoiresURL + "services/inquire";
// Set up UDDI publish stub
uk.ac.soton.ecs.grimoires.server.impl.uddiv2.publication.GrimoiresLocator publishLocator =
new uk.ac.soton.ecs.grimoires.server.impl.uddiv2.publication.GrimoiresLocator();
publishLocator.setpublishEndpointAddress(publishEndpoint);
publish = publishLocator.getpublish();
// Set up UDDI inquire stub
uk.ac.soton.ecs.grimoires.server.impl.uddiv2.inquiry.GrimoiresLocator inquireLocator =
new uk.ac.soton.ecs.grimoires.server.impl.uddiv2.inquiry.GrimoiresLocator();
inquireLocator.setinquireEndpointAddress(inquireEndpoint);
inquire = inquireLocator.getinquire();
// Set up other stubs ...... }
To set up a stub, we firstly create an instance of GrimoiresLocator, which represents a locator for the Grimoires service. We then set the correct Grimoires service endpoint address in the locator. Finally, we get the service interface from the locator.
We will publish a business called "DDBJ", which has a description of "DNA Data Bank of Japan". A business is the UDDI's terminology for an organization.
private static void publishBusienss() throws Exception {
System.out.println("====Publish a business====");
// Prepare the save_business request
Save_business request = new Save_business();
request.setAuthInfo("AUTHINFO");
BusinessEntity[] businessEntities = new BusinessEntity[1];
businessEntities[0] = new BusinessEntity();
businessEntities[0].setName(new Name[] {
new Name("DDBJ")
});
businessEntities[0].setDescription(new Description[] {
new Description("DNA Data Bank of Japan")
});
request.setBusinessEntity(businessEntities);
// Send the request and get a response
BusinessDetail response = publish.save_business(request);
// Process the response
businessKey = response.getBusinessEntity(0).getBusinessKey();
System.out.println("Business key: " + businessKey);
}
In the above code, we create an instance of the Save_business class, which is
the corresponding Java class for the save_business SOAP message. We set up the
Save_business instance properly. Then it is passed as an argument to the
save_business method of the Publish interface. The save_business method returns
a BusinessDetail object, which is deserialized from the response SOAP message.private static void publishService() throws Exception {
System.out.println("====Publish a service====");
// Prepare the save_service request
Save_service request = new Save_service(
"AUTHINFO",
new BusinessService[] {new BusinessService(
new Name[] {new Name("Blast")},
new Description[] {new Description("A DDBJ Web Service")},
new BindingTemplates(
new BindingTemplate[] {
new BindingTemplate(
null,
new AccessPoint("http://xml.nig.ac.jp/xddbj/Blast"),
null, //HostingRedirector hostingRedirector,
new TModelInstanceDetails(
new TModelInstanceInfo[] {
new TModelInstanceInfo(
null, //Description[] description,
new InstanceDetails(
null,
new OverviewDoc(null, "http://xml.nig.ac.jp/wsdl/Blast.wsdl"),
null),
null
)
}
),
null, //java.lang.String serviceKey,
null //java.lang.String bindingKey
)
}
),
null, //CategoryBag categoryBag,
null, //java.lang.String serviceKey,
businessKey
)},
"2.0"
);
// Send the request and get a response
ServiceDetail response = publish.save_service(request);
// Process the response
serviceKey = response.getBusinessService(0).getServiceKey();
System.out.println("Service key: " + serviceKey);
}
In the above code, we firstly construct a Save_service instance, then pass it to
the save_service method of the Publish interface.We will inquire a service called "Blast", and get its detailed information.
private static void discoveryService() throws Exception {
System.out.println("====Find a service====");
// Prepare the find_service request
Find_service request = new Find_service(null, //FindQualifiers findQualifiers,
new Name[] { new Name("Blast") }, null, //CategoryBag categoryBag,
null, //TModelBag tModelBag,
"2.0", 100, //int maxRows,
null //java.lang.String businessKey
);
// Send the request and get a reponse
ServiceList response = inquire.find_service(request);
// Process the find_service response and prepare the get_servicedetail request
ServiceInfo[] info = response.getServiceInfos().getServiceInfo();
if (info == null)
return;
String[] keys = new String[info.length];
for (int i = 0; i < info.length; i++) {
keys[i] = info[i].getServiceKey();
}
Get_serviceDetail request2 = new Get_serviceDetail(keys, "2.0");
// Send the get_servicedetail request
ServiceDetail response2 = inquire.get_serviceDetail(request2);
// Process the response
BusinessService services[] = response2.getBusinessService();
System.out.println("Service name: " + services[0].getName(0).get_value());
System.out.println("Service key: " + services[0].getServiceKey());
System.out.println("Business key: " + services[0].getBusinessKey());
System.out.println("Service description: " + services[0].getDescription(0).get_value());
BindingTemplate bt = services[0].getBindingTemplates().getBindingTemplate(0);
System.out.println("Access point in binding template: " + bt.getAccessPoint().get_value());
System.out.println("tModel: " + bt.getTModelInstanceDetails()
.getTModelInstanceInfo(0).getInstanceDetails()
.getOverviewDoc().getOverviewURL());
}
In the above code, we firstly construct a Find_service instance, and pass it to the find_service method of the Inquire interface. The returned ServiceList instance contains the key of the service whose name matches "Blast". We then construct a Get_serviceDetail object which contains the service key we have got, and pass it to the get_serviceDetail method of the Inquire interface. The get_serviceDetail method returns the detail service information corresponding to the given service key.
We will publish the service's WSDL file, which is at http://xml.nig.ac.jp/wsdl/Blast.wsdl.
private static void publishWSDL() throws Exception {
System.out.println("====Publish WSDL====");
String wsdlKey = wsdl.addWSDLFile("http://xml.nig.ac.jp/wsdl/Blast.wsdl");
System.out.println("WSDL key: " + wsdlKey);
}
We will publish a piece of metadata, which describes the semantic type of a message part in the previously published WSDL file. The message part is syntactically a string, and is semantically a DNA sequence.
private static void publishMetadata() throws Exception {
System.out.println("====Publish metadata====");
// set up entity to be annotated
MessagePartReference msgRef = new MessagePartReference(
"http://www.themindelectric.com/wsdl/Blast/", "searchParam0In", "param");
EntityReference enRef = new EntityReference();
enRef.setMessagePartReference(msgRef);
enRef.setEntityType(new URI("http://www.grimoires.org/metadata.xsd#messagePartReference"));
// set up metadata
MetadataValue mv = new MetadataValue();
mv.setStringValue("DNA_Sequence");
Metadata md = new Metadata();
md.setMetadataType(new URI("http://www.grimoires.org/SemanticType"));
md.setMetadataValue(mv);
// attonation
MetadataInfo info = publishMetadata.addMetadataToEntity(new AddMetadataToEntity(enRef, md));
System.out.println("Metadata key: " + info.getMetadataKey());
}
In the above code, we attach a metadata to a message part. The metadata is of the type "http://www.grimoires.org/SemanticType", and has the value "DNA_Sequence". The message part has the name "param", and it belongs to the message "http://www.themindelectric.com/wsdl/Blast#searchParam0In".
We will find the message part with the specified metadata.
private static void inquireMetadata() throws Exception {
System.out.println("====Inquire metadata====");
// Prepare request message
MetadataQuery mq = new MetadataQuery();
mq.setMetadataType(new URI("http://www.grimoires.org/SemanticType"));
MetadataValue mv = new MetadataValue();
mv.setStringValue("DNA_Sequence");
mq.setMetadataValue(mv);
Find_entityByMetadata find = new Find_entityByMetadata(
new MetadataQueryBag(
new MetadataQuery[] {
mq
}));
// Send request and get response
EntityReferenceList enRefList = inquireMetadata.find_entityByMetadata(find);
// Process the response
EntityReference enRef = enRefList.getEntityReference(0);
if (enRef.getEntityType().toString()
.equals("http://www.grimoires.org/metadata.xsd#messagePartReference")) {
System.out.println("Found a message part with this metedata" +
"\n(http://www.grimoires.org/SemanticType, DNA_Sequence)");
MessagePartReference msgRef = enRef.getMessagePartReference();
System.out.println("Message namespace" + msgRef.getMessageNamespace());
System.out.println("Message name" + msgRef.getMessageName());
System.out.println("Message part name" + msgRef.getMessagePartName());
}
}
In the above code, we inquire for a message part attached with a metadata that is of the type "http://www.grimoires.org/SemanticType", and has the value "DNA_Sequence".