Summary: Overview of GigaSpaces in-memory data grid - how to create a data grid, connect to it, and interact with it.
OverviewThis section covers the main APIs of GigaSpaces XAP. It explains how to:
Classpath Settings for Development and RuntimeTo compile and run code that interacts with the Space from within the IDE, you should include all the JARs under the <GigaSapces root>/lib/required directory in your build path:
If you run your Space client as a Processing Unit within the GigaSpaces runtime environment, GigaSpaces classes and interfaces are part of the JVM's classpath by default. If you run in standalone mode (from within your IDE or non-GigaSpaces JVM), you should include the above thirteen JARs in your classpath.
Space Cluster SchemasA Space is identified by its name, and is comprised of one or more Space instances, which form the Space cluster. The Space instances interact with one another, based on the Space topology defined for the Space. The topology is defined using a cluster schema, and the following schemas are provided out-of-the-box:
The Space cluster is typically accessed from a remote JVM. Alternatively, applications that are collocated on the same JVM with a Space instance can access that instance locally without being exposed to the other instances (this is useful for implementing SBA applications). Instantiating a SpaceThe Space can be instantiated in a number of ways: The first way, you deploy a Space onto the GigaSpaces Service Grid infrastructure (using the management GUI, the CLI or the administration and monitoring API). Deploying a Space onto the Service Grid InfrastructureThe service grid infrastructure is composed of one or more GigaSpaces Containers (GSCs) and at least one GigaSpaces Manager (GSM). When deploying onto the service grid, the deployment tool you use connects to the GSM and instructs it to provision Space instances to the running GSCs, based on the deployment details (Space topology, number of instances, etc.). Deploying a Space Using the Management UI1. Start the GigaSpaces Agent by running <GigaSpaces root>/bin/gs-agent.sh(bat) on the machines on which you would like to deploy the clustered space.
Sync-Replicated
A-Sync-Replicated Partitioned without backups Partitioned with one backup 5. Click Deploy. Deploying a Space Using the CLI1. Start the GigaSpaces Agent by running <GigaSpaces root>/bin/gs-agent.sh(bat) on the machines on which you would like to deploy the clustered space. gs deploy-space -cluster [schema=<cluster schema>] total_members=<number of instances>[,<number of backups>] <Space name> Examples: gs deploy-space -cluster schema=sync_replicated total_members=2 mySpace A-sync-replicated cluster with 2 nodes: gs deploy-space -cluster schema=async_replicated total_members=2 mySpace Partitioned cluster with 2 nodes and a backup for each node: gs deploy-space -cluster schema=partitioned-sync2backup total_members=2,1 mySpace To see the full list of options available with this command, refer to this page. Deploying a Space Using the Administration APIAdmin admin = new AdminFactory().addGroup("myGroup").createAdmin(); ProcessingUnit processingUnit = admin.getGridServiceManagers(). deploy(new SpaceDeployment("mySpace").numberOfInstances(2).numberOfBackups(1)); //wait for the instances to start Space Space = processingUnit.waitForSpace(); Space.waitFor(4); Refer to the admin API documentation for more details. Creating and Deploying a Processing Unit onto the Service Grid InfrastructureBy using processing units, you can deploy full-blown applications onto the service grid, and leverage on the Space's messaging and code execution capabilities, such as remoting and task execution. This allows you to execute the business logic close to the Space instance for the best possible performance. A processing unit can define an embedded Space in the processing unit's pu.xml file. The pu.xml file is, in effect a Spring XML configuration file, and you simply define the Space using GigaSpaces namespace extensions, or using plain Spring format. Here is an example: <os-core:space id="space" url="/./mySpace"/>
This defines an embedded Space within the processing unit. The fact that the Space is embedded is determined by the url property. As you can see below, a URL that starts with the jini:// prefix, indicates that a connection to a remote Space is created, not an embedded Space. <os-sla:sla cluster-schema="partitioned-sync2backup" number-of-instances="2" number-of-backups="1"/>
Refer to this page for more details on how to configure the Space component, and to this page for more details about the SLA definitions. Creating the Space via SpringIf you would like to create a Space within your own Spring application, and do not wish to deploy it as a processing unit onto the GigaSpaces service grid, you can create an embedded Space instance within the application's JVM much the same way you would do in a regular processing unit configuration. The main difference with this approach is that when deploying on to the service grid, the GSM automatically starts the right amount of Space instances for you, and assigns the instance ID to each of the instances. <os-core:space id="space" url="/./mySpace?total_members=2&id=1"/>
Creating the Space ProgrammaticallyThe last option is to create the Space Programmatically from within a plain Java application. Note that this option has the same limitation as creating the Space in your standalone Spring application, namely you have to start each of the instances separately and provide the instance ID to each of the started Space instances. Here is an example of starting the first instance of a sync-replicated Space with 10 instances: ClusterInfo clusterInfo = new ClusterInfo("sync-replicated", 1, null, 10, null); IJSpace space = new UrlSpaceConfigurer("/./mySpace").clusterInfo(clusterInfo).space(); Refer to this page for more details on how to configure the Space component programmatically (click the Code tabs in all of the examples). Accessing the SpaceThe handle to the Space is represented by the low level IJSpace interface. When creating the Space in one of the above ways (programmatically, via Spring or within a processing unit), you get a handle to the local Space instance within your JVM.
Spring Configuration (NameSpace)
<os-core:space id="space" url="jini://*/*/mySpace" />
Spring Configuration (Plain) <bean id="space" class="org.openSpaces.core.Space.UrlSpaceFactoryBean"> <property name="url" value="jini:/*/*/mySpace" /> </bean> Java Code IJSpace space = new UrlSpaceConfigurer("jini://*/*/mySpace").space(); Although you can access the Space directly via the IJSpace interface (which was the mainstream approach until version 6.0), it is much more recommended to access the Space via one of the higher level APIs, namely the org.openSpaces.core.GigaSpace interface, the Map API, or the JDBC API. The most recommended API is the GigaSpaces interface. It is the closest to the older IJSpace interface, but is different since it supports Java 5 generics, declarative Spring transactions and task execution over the Space. They support 4 basic "verbs" of this model, namely read, write, take and notify (see below for more details).
Interacting with the Space Using the GigaSpace InterfaceThe rest of this page describes the GigaSpace interface, and how to perform basic data access operations with which to access the Space. If you are interested in the Map API, refer to the following pages: For details about the JDBC API, refer to this page. Basic Data Access Space OperationsThe GigaSpace interface supports a number of Space operations:
As per the JavaSpaces model, when you read an object from the Space, you can specify a timeout for the read operation. This means that the calling code can block until a certain object is written to the Space, which allows for much more sophisticated communication patterns that use the Space as a collaborative work area between multiple Space clients.
Creating a GigaSpace InstanceCreating a GigaSpace instance is done by wrapping an existing IJSpace instance, or by providing details about the Space you would like to connect to. This can be done programmatically, or via Spring. Here is an example:
Spring Configuration (NameSpace)
<os-core:space id="space" url="jini://*/*/mySpace" /> <os-core:giga-Space id="gigaSpace" space="space"/> Spring Configuration (Plain) <bean id="space" class="org.openSpaces.core.Space.UrlSpaceFactoryBean"> <property name="url" value="jini:/*/*/mySpace" /> </bean> <bean id="gigaSpace" class="org.openSpaces.core.GigaSpaceFactoryBean"> <property name="Space" ref="space" /> </bean> Java Code - Option 1 IJSpace space = new UrlSpaceConfigurer("jini://*/*/mySpace").space(); GigaSpace gigaSpace = new GigaSpaceConfigurer(space).gigaSpace(); Java Code - Option 2 GigaSpace gigaSpace = new GigaSpaceConfigurer(new UrlSpaceConfigurer("jini://*/*/mySpace")).gigaSpace(); Once you have access to a GigaSpace instance, you can start operating on the Space, namely write objects to it, and read and take objects from it.
POJOs as Data ObjectsAs mentioned earlier, one of the differences between the GigaSpace interface and the classic net.jini.Space.JavaSpace interface, is its support for POJOs as Space entries. The JavaSpace interface is rather intrusive and forces objects that are written to the Space to implement the net.jini.core.entry.Entry interface, and mark any field to be stored on the Space as public. In terms of preconditions, your POJO classes need to follow the JavaBeans conventions, i.e. have a no-argument constructor, and declare a getter and setter to every field you want saved on the Space. Also, they cannot implement the net.jini.core.entry.Entry interface (there shouldn't be any reason to do that anyway, since it is an empty tagging interface). The POJO class does not have to implement java.io.Serializable, but its properties must. The reason for this, is that the POJOs fields are extracted when written to the Space, and stored in a special tuple format that enables the Space to index and analyze them more easily. Therefore the actual POJO is not sent over the network, but rather its properties. Providing Metadata to the Space about the POJO ClassWhen writing POJOs to the Space, you can provide some metadata about the POJO's class to the space, using Java 5 annotations, or an XML configuration. This overview uses annotation to provide metadata. For a complete reference to POJO annotations and XML configuration, refer to this page.
Here is a sample POJO class: @SpaceClass public class Person { private Integer id; private String name; private String lastName; private Integer age; ... public Person() {} @SpaceId(autoGenerate=false) @SpaceRouting public Integer getId() { return id;} public void setId(Integer id) { this.id = id; } @SpaceProperty(index=BASIC) public Long getLastName() { return lastName; } public void setLastName(String type) { this.lastName = lastName; } ... } Space OperationsWriting Objects to the SpaceIn order to write or update objects in the Space, you should use the write method of the GigaSpace interface. The write method is used to write objects if these are introduced for the first time, or update them if these already exist in the space. In order to override these default semantics, you can use the overloaded write methods which accept update modifiers such as UpdateModifiers.UPDATE_ONLY. Person person = new Person(); person.setName("foo"); person.setLastName("bar"); person.setAge(25); gigaSpace.write(person); The GigaSpace interface also supports writing objects in batches. The corresponding methods for this are named writeMultiple, and are mainly used to batch operations over a single network call in case you write to a remote space. Reading Objects from the SpaceThe read methods are used to retrieve objects from the Space. The read method returns a copy of the matching object to the client. To read more than one object, you should use the readMultiple methods of the GigaSpace interface. To define the criteria for the operation, all of these methods accept either a template object, or an SQLQuery instance. A template object is an example object of the class you would like to read. For an object in the space to match the template, each of the non-null properties in the template must match its values for these properties. // readById Integer id = ...//get the id Integer routing = ...//get the routing value (not mandatory, but more efficient) Person result1 = gigaSpace.readById(Person.class, id, routing); //second argument determines routing // readByIds Integer[] ids = new Integer[] { ... // object ids Integer[] routingKeys = new Integer[] { ... // get the routing keys values (not mandatory, but more efficient) ReadByIdsResult<Person> result = gigaSpace.readByIds(Person.class, ids, routingKeys); for (Person person : result) { // ... } //template matching Person template = new Person(); template.setFirstName("foo"); template.setLastName(null);//means any value Person result2 = gigaSpace.read(template) ; // read by template //50 is the maximum number of results to retrieve Person[] multipleResults = gigaSpace.readMultiple(template, 50); //SQLQuery SQLQuery<Person> query = new SQLQuery<Person>("(name = ?) AND (age>? AND age<?)"); template.setParameters("foo" , 25 , 30); // returns all Person objects whose name is 'foo' and age between 25-30 (non-inclusive) Person[] multipleResults2 = gigaSpace.readMultiple(query, 50); Note that you can specify a timeout for the read operations. This causes the calling code to block until a result becomes becomes available (or until the specified number of results is available in the case of readMultiple). Taking Objects from the SpaceThe take methods have similar method signatures as the read methods. The main difference is that take removes the object from the Space, in addition to returning a copy of it to the client. // takeById Integer id = ...//get the id Integer routing = ...//get the routing value (not mandatory, but more efficient) Person result1 = gigaSpace.takeById(Person.class, id, routing); // takeByIds Integer[] ids = new Integer[] { ... // object ids Integer[] routingKeys = new Integer[] { ... // get the routing keys values (not mandatory, but more efficient) TakeByIdsResult<Person> result = gigaSpace.takeByIds(Person.class, ids, routingKeys); for (Person person : result) { // ... } //template matching Person template = new Person(); template.setFirstName("foo"); template.setLastName(null);//means any value Person result2 = gigaSpace.take(template) ; // take by template //50 is the maximum number of results to take Person[] multipleResults = gigaSpace.takeMultiple(template, 50); //SQLQuery SQLQuery<Person> query = new SQLQuery<Person>("(name = ?) AND (age>? AND age<?)"); template.setParameters("foo" , 25 , 30); // returns all Person objects whose name is 'foo' and age between 25-30 (non-inclusive) Person[] multipleResults2 = gigaSpace.takeMultiple(query, 50); Ordering of ResultsThe Space matches the stored object with the template to return a result. Matched objects are stored in the Space and returned from it in no particular order. However you can use FIFO ordering or the ORDER BY statement to control the ordering. |
![]() |
GigaSpaces.com - Legal Notice - 3rd Party Licenses - Site Map - API Docs - Forum - Downloads - Blog - White Papers - Contact Tech Writing - Gen. by Atlassian Confluence |