Home

WebSphere eXtreme Scale Tutorials


  1. ObjectQuery tutorial
  2. Entity manager tutorial
  3. Configure Java SE security
  4. Run WXS clients and servers in the Liberty profile
  5. Use the xscmd tool to monitor
  6. Integrate WXS security in a mixed environment with an external authenticator
  7. Run WXS bundles in the OSGi framework
  8. Update the service rankings


ObjectQuery tutorial - step 1

With the following steps, we can continue to develop a local, in-memory ObjectGrid that stores order information for an online retail store using the ObjectMap APIs. You define a schema for the map and run a query against the map.

  1. Create an ObjectGrid with a map schema.

    Create an ObjectGrid with one map schema for the map, then insert an object into the cache and later retrieve it using a simple query.

    OrderBean.java
    
    
    public class OrderBean implements Serializable {
        String orderNumber;
        java.util.Date date;
        String customerName;
        String itemName;
        int quantity;
        double price;}

  2. Define the primary key.

    The previous code shows an OrderBean object. This object implements the java.io.Serializable interface because all objects in the cache must (by default) be Serializable.

    The orderNumber attribute is the primary key of the object. The following example program can be run in stand-alone mode. You should follow this tutorial in an Eclipse Java project that has the objectgrid.jar file added to the class path.

    Application.java
    
    
    package querytutorial.basic.step1;
    
    import java.util.Iterator;
    
    import com.ibm.websphere.objectgrid.ObjectGrid;
    import com.ibm.websphere.objectgrid.ObjectGridManagerFactory;
    import com.ibm.websphere.objectgrid.ObjectMap;
    import com.ibm.websphere.objectgrid.Session;
    import com.ibm.websphere.objectgrid.config.QueryConfig;
    import com.ibm.websphere.objectgrid.config.QueryMapping;
    import com.ibm.websphere.objectgrid.query.ObjectQuery;
    
    public class Application {
    
        static public void main(String [] args) throws Exception
        {
            ObjectGrid og = ObjectGridManagerFactory.getObjectGridManager().createObjectGrid();
            og.defineMap("Order");
    
            // Define the schema
            QueryConfig queryCfg = new QueryConfig();
            queryCfg.addQueryMapping(new QueryMapping("Order", OrderBean.class.getName(), 
         "orderNumber", QueryMapping.FIELD_ACCESS));
            og.setQueryConfig(queryCfg);
    
            Session s = og.getSession();
            ObjectMap orderMap = s.getMap("Order");
    
            s.begin();
            OrderBean o = new OrderBean();
            o.customerName = "John Smith";
            o.date = new java.util.Date(System.currentTimeMillis());
            o.itemName = "Widget";
            o.orderNumber = "1";
            o.price = 99.99;
            o.quantity = 1;
            orderMap.put(o.orderNumber, o);
            s.commit();
    
            s.begin();
            ObjectQuery query = s.createObjectQuery("SELECT o FROM Order o WHERE o.itemName='Widget'");
            Iterator result = query.getResultIterator();
            o = (OrderBean) result.next();
            System.out.println("Found order for customer: " + o.customerName);
            s.commit();
     // Close the session (optional in Version 7.1.1 and later) for improved performance
     s.close();}}

    This eXtreme Scale application first initializes a local ObjectGrid with an automatically generated name. Next, the application creates a BackingMap and a QueryConfig that defines what Java type is associated with the map, the name of the field that is the primary key for the map, and how to access the data in the object. You then obtain a Session to get the ObjectMap instance and insert an OrderBean object into the map in a transaction.

    After the data is committed into the cache, we can use ObjectQuery to find the OrderBean using any of the persistent fields in the class. Persistent fields are those that do not have the transient modifier. Because you did not define any indexes on the BackingMap, ObjectQuery must scan each object in the map using Java reflection.


ObjectQuery tutorial - step 2

With the following steps, we can continue to create an ObjectGrid with one map and an index, along with a schema for the map. Then we can insert an object into the cache and later retrieve it using a simple query.

Be sure that you have completed ObjectQuery tutorial - step 1 before proceeding with this step of the tutorial.

Schema and index

Application.java


// Create an index
    HashIndex idx= new HashIndex();
    idx.setName("theItemName");
    idx.setAttributeName("itemName");
    idx.setRangeIndex(true);
    idx.setFieldAccessAttribute(true);
    orderBMap.addMapIndexPlugin(idx);}

The index must be a com.ibm.websphere.objectgrid.plugins.index.HashIndex instance with the following settings:

When a query runs that filters on the itemName field, the query engine automatically uses the defined index. Using the index allows the query to run much faster and a map scan is not needed. The next step demonstrates how an index can be used to optimize the query.

Next step

Previous topic: ObjectQuery tutorial - step 1

Next topic: ObjectQuery tutorial - step 3


ObjectQuery tutorial - step 3

With the following step, we can create an ObjectGrid with two maps and a schema for the maps with a relationship, then insert objects into the cache and later retrieve them using a simple query.

Be sure you have completed ObjectQuery tutorial - step 2 prior to proceeding with this step.

In this example, there are two maps, each with a single Java type mapped to it. The Order map has OrderBean objects and the Customer map has CustomerBean objects in it.

Define maps with a relationship.

OrderBean.java


public class OrderBean implements Serializable {
    String orderNumber;
    java.util.Date date;
    String customerId;
    String itemName;
    int quantity;
    double price;}
The OrderBean no longer has the customerName in it. Instead, it has the customerId, which is the primary key for the CustomerBean object and the Customer map.

CustomerBean.java


public class CustomerBean implements Serializable{
    private static final long serialVersionUID = 1L;
    String id;
    String firstName;
    String surname;
    String address;
    String phoneNumber;}

The relationship between the two types or Maps follows:

Application.java

public class Application {

    static public void main(String [] args)
        throws Exception
    {
        ObjectGrid og = ObjectGridManagerFactory.getObjectGridManager().createObjectGrid();
        og.defineMap("Order");
        og.defineMap("Customer");

        // Define the schema
        QueryConfig queryCfg = new QueryConfig();
        queryCfg.addQueryMapping(new QueryMapping(
            "Order", OrderBean.class.getName(), "orderNumber", QueryMapping.FIELD_ACCESS));
        queryCfg.addQueryMapping(new QueryMapping(
            "Customer", CustomerBean.class.getName(), "id", QueryMapping.FIELD_ACCESS));
        queryCfg.addQueryRelationship(new QueryRelationship(
             OrderBean.class.getName(), CustomerBean.class.getName(), "customerId", null));
        og.setQueryConfig(queryCfg);

        Session s = og.getSession();
        ObjectMap orderMap = s.getMap("Order");
        ObjectMap custMap = s.getMap("Customer");

        s.begin();
        CustomerBean cust = new CustomerBean();
        cust.address = "Main Street";
        cust.firstName = "John";
        cust.surname = "Smith";
        cust.id = "C001";
        cust.phoneNumber = "5555551212";
        custMap.insert(cust.id, cust);

        OrderBean o = new OrderBean();
        o.customerId = cust.id;
        o.date = new java.util.Date();
        o.itemName = "Widget";
        o.orderNumber = "1";
        o.price = 99.99;
        o.quantity = 1;
        orderMap.insert(o.orderNumber, o);
        s.commit();

        s.begin();
        ObjectQuery query = s.createObjectQuery(
            "SELECT c FROM Order o JOIN o.customerId as c WHERE o.itemName='Widget'");
        Iterator result = query.getResultIterator();
        cust = (CustomerBean) result.next();
        System.out.println("Found order for customer: " + cust.firstName + " " + cust.surname);
 s.commit();
   // Close the session (optional in Version 7.1.1 and later) for improved performance
 s.close();   
    }}

The equivalent XML in the ObjectGrid deployment descriptor follows:

<?xml version="1.0" encoding="UTF-8"?>
<objectGridConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ibm.com/ws/objectgrid/config ../objectGrid.xsd"
xmlns="http://ibm.com/ws/objectgrid/config">
  <objectGrids>
    <objectGrid name="CompanyGrid">
      <backingMap name="Order"/>
      <backingMap name="Customer"/>

      <querySchema>
         <mapSchemas>
           <mapSchema
             mapName="Order"
             valueClass="com.mycompany.OrderBean"
             primaryKeyField="orderNumber"
             accessType="FIELD"/>
           <mapSchema
             mapName="Customer"
             valueClass="com.mycompany.CustomerBean"
             primaryKeyField="id"
             accessType="FIELD"/>
         </mapSchemas>
         <relationships>
           <relationship
             source="com.mycompany.OrderBean"
             target="com.mycompany.CustomerBean"
             relationField="customerId"/>
         </relationships>
      </querySchema>
    </objectGrid>
  </objectGrids>
</objectGridConfig>


ObjectQuery tutorial - step 4

The following step shows how to create an ObjectGrid with four maps and a schema for the maps. Some of the maps maintain a one-to-one (unidirectional) and one-to-many (bidirectional) relationship. After creating the maps, we can then run the sample Application.java program to insert objects into the cache and run queries to retrieve these objects.

Be sure to have completed ObjectQuery tutorial - step 3 prior to continuing with the current step.

You are required to create four JAVA classes. These are the maps for the ObjectGrid:

Figure 1. Order Schema. An Order schema has a one-to-one relationship with Customer and a one-to-many relationship with OrderLine. The OrderLine map has a one-to-one relationship with Item and includes the quantity ordered.

After creating these JAVA classes with these relationships, we can then run the sample Application.java program. This program lets you insert objects into the cache and retrieve these using several queries.

  1. Create the following JAVA classes:

    OrderBean.java
    
    public class OrderBean implements Serializable {
       String orderNumber;
       java.util.Date date;
       String customerId;
       String itemName;
       List<Integer> orderLines;}
        
    OrderLineBean.java
    
    public class OrderLineBean implements Serializable {
      int lineNumber;
      int quantity;
      String orderNumber;
      String itemId;}

    CustomerBean.java
    
    public class CustomerBean implements Serializable{
      String id;
      String firstName;
      String surname;
      String address;
      String phoneNumber;}
    ItemBean.java
    
    public class ItemBean implements Serializable {
      String id;  
      String description;  
      long quantityOnHand;  
      double price;}

  2. After creating the classes, we can run the sample Application.java:
    Application.java
    
    
      public class Application static public void main(String [] args)throws Exception
            // Configure programatically
         objectGrid og = ObjectGridManagerFactory.getObjectGridManager().createObjectGrid();
            og.defineMap("Order");
            og.defineMap("Customer");
            og.defineMap("OrderLine");
            og.defineMap("Item");
    
            // Define the schema
            QueryConfig queryCfg = new QueryConfig();
            queryCfg.addQueryMapping(new QueryMapping("Order", OrderBean.class.getName(), "orderNumber", QueryMapping.FIELD_ACCESS));
            queryCfg.addQueryMapping(new QueryMapping("Customer", CustomerBean.class.getName(), "id", QueryMapping.FIELD_ACCESS));
            queryCfg.addQueryMapping(new QueryMapping("OrderLine", OrderLineBean.class.getName(), "lineNumber", QueryMapping.FIELD_ACCESS));
            queryCfg.addQueryMapping(new QueryMapping("Item", ItemBean.class.getName(), "id", QueryMapping.FIELD_ACCESS));
            queryCfg.addQueryRelationship(new QueryRelationship(OrderBean.class.getName(), CustomerBean.class.getName(), "customerId", null));
            queryCfg.addQueryRelationship(new QueryRelationship(OrderBean.class.getName(), OrderLineBean.class.getName(), 
        "orderLines", "lineNumber"));
            queryCfg.addQueryRelationship(new QueryRelationship(OrderLineBean.class.getName(), ItemBean.class.getName(), "itemId", null));
            og.setQueryConfig(queryCfg);
    
            // Get session and maps;
            Session s = og.getSession();
            ObjectMap orderMap = s.getMap("Order");
            ObjectMap custMap = s.getMap("Customer");
            ObjectMap itemMap = s.getMap("Item");
            ObjectMap orderLineMap = s.getMap("OrderLine");
    
            // Add data 
            s.begin();
            CustomerBean aCustomer = new CustomerBean();
            aCustomer.address = "Main Street";
            aCustomer.firstName = "John";
            aCustomer.surname = "Smith";
            aCustomer.id = "C001";
            aCustomer.phoneNumber = "5555551212";
            custMap.insert(aCustomer.id, aCustomer);
    
            // Insert an order with a reference to the customer, but without any OrderLines yet.
            // Because we are using CopyMode.COPY_ON_READ_AND_COMMIT, the         // insert won't be copied into the backing map until commit time, so
            // the reference is still good.
        
        OrderBean anOrder = new OrderBean();
        anOrder.customerId = aCustomer.id;
        anOrder.date = new java.util.Date();
        anOrder.itemName = "Widget";
        anOrder.orderNumber = "1";
        anOrder.orderLines = new ArrayList();
        orderMap.insert(anOrder.orderNumber, anOrder);
                
            ItemBean anItem = new ItemBean();
            anItem.id = "AC0001";
            anItem.description = ">Description of widget";
            anItem.quantityOnHand = 100;
            anItem.price = 1000.0;
            itemMap.insert(anItem.id, anItem);
    
        // Create the OrderLines and add the reference to the Order
            OrderLineBean anOrderLine = new OrderLineBean();
            anOrderLine.lineNumber = 99;
            anOrderLine.itemId = anItem.id;
            anOrderLine.orderNumber = anOrder.orderNumber;
            anOrderLine.quantity = 500;
            orderLineMap.insert(anOrderLine.lineNumber, anOrderLine);
            anOrder.orderLines.add(Integer.valueOf(anOrderLine.lineNumber));
    
        anOrderLine = new OrderLineBean();
            anOrderLine.lineNumber = 100;
            anOrderLine.itemId = anItem.id;
            anOrderLine.orderNumber = anOrder.orderNumber;
            anOrderLine.quantity = 501;
            orderLineMap.insert(anOrderLine.lineNumber, anOrderLine);
            anOrder.orderLines.add(Integer.valueOf(anOrderLine.lineNumber));
            s.commit();
    
        s.begin();
            // Find all customers who have ordered a specific item.
            ObjectQuery query = s.createObjectQuery("SELECT c FROM Order o JOIN o.customerId as c WHERE o.itemName='Widget'");
            Iterator result = query.getResultIterator();
            aCustomer = (CustomerBean) result.next();
            System.out.println("Found order for customer: " + aCustomer.firstName + " " + aCustomer.surname);
            s.commit();
    
        s.begin();
            // Find all OrderLines for customer C001.
            // The query joins are expressed on the foreign keys.
            query = s.createObjectQuery("SELECT ol FROM Order o JOIN o.customerId as c JOIN o.orderLines as ol WHERE c.id='C001'");
            result = query.getResultIterator();
            System.out.println("Found OrderLines:");
            while(result.hasNext()) {
                anOrderLine = (OrderLineBean) result.next();
                System.out.println(anOrderLine.lineNumber + ", qty=" + anOrderLine.quantity);
            }
     // Close the session (optional in Version 7.1.1 and later) for improved performance
     s.close();   
       }}

  3. Use the XML configuration below (in the ObjectGrid deployment descriptor) is equivalent to the programmatic approach above.
    <?xml version="1.0" encoding="UTF-8"?><objectGridConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://ibm.com/ws/objectgrid/config
    ../objectGrid.xsd"xmlns="http://ibm.com/ws/objectgrid/config">
    <objectGrids>
      <objectGrid name="CompanyGrid">
      <backingMap name="Order"/>
      <backingMap name="Customer"/>
      <backingMap name="OrderLine"/>
      <backingMap name="Item"/>
    
    <querySchema>
     <mapSchemas>
      <mapSchema
      mapName="Order"
      valueClass="com.mycompany.OrderBean"
      primaryKeyField="orderNumber"
      accessType="FIELD"/>
      <mapSchema
      mapName="Customer"
      valueClass="com.mycompany.CustomerBean"
      primaryKeyField="id"
      accessType="FIELD"/>
      <mapSchema
      mapName="OrderLine"
      valueClass="com.mycompany.OrderLineBean"
      primaryKeyField="
      lineNumber"
      accessType="FIELD"/>
      <mapSchema
      mapName="Item"
      valueClass="com.mycompany.ItemBean"
      primaryKeyField="id"
      accessType="FIELD"/>
      </mapSchemas>
    
    <relationships>
     <relationship
      source="com.mycompany.OrderBean"
      target="com.mycompany.CustomerBean"
      relationField="customerId"/>
     <relationship
      source="com.mycompany.OrderBean"
      target="com.mycompany.OrderLineBean"
      relationField="orderLines"
      invRelationField="lineNumber"/>
     <relationship
      source="com.mycompany.OrderLineBean"
      target="com.mycompany.ItemBean"
      relationField="itemId"/>
        </relationships>
       </querySchema>
      </objectGrid>
     </objectGrids>
    </objectGridConfig>

Previous topic: ObjectQuery tutorial - step 3


Tutorial: Entity manager tutorial

The tutorial for the entity manager shows you how to use WXS to store order information on a Web site. We can create a simple Java Platform, Standard Edition 5 application that uses an in-memory, local eXtreme Scale. The entities use Java SE 5 annotations and generics.

Ensure that you have met the following requirements before you begin the tutorial:


Entity manager tutorial: Creating an entity class

Create a local ObjectGrid with one entity by creating an Entity class, registering the entity type, and storing an entity instance into the cache.

  1. Create the Order object. To identify the object as an ObjectGrid entity, add the @Entity annotation. When you add this annotation, all serializable attributes in the object are automatically persisted in eXtreme Scale, unless you use annotations on the attributes to override the attributes. The orderNumber attribute is annotated with

    @Id to indicate that this attribute is the primary key. An example of an Order object follows:

    Order.java
    
    @Entity
    public class Order
    {
        @Id String orderNumber;
        Date date;
        String customerName;
        String itemName;
        int quantity;
        double price;}

  2. Run the eXtreme Scale Hello World application to demonstrate the entity operations. The following example program can be issued in stand-alone mode to demonstrate the entity operations. Use this program in an Eclipse Java project that has the objectgrid.jar file added to the class path. An example of a simple Hello world application that uses eXtreme Scale follows:
    Application.java
    
    package emtutorial.basic.step1;
    
    import com.ibm.websphere.objectgrid.ObjectGrid;
    import com.ibm.websphere.objectgrid.ObjectGridManagerFactory;
    import com.ibm.websphere.objectgrid.Session;
    import com.ibm.websphere.objectgrid.em.EntityManager;
    
    public class Application {
    
        static public void main(String [] args)
            throws Exception
        {
            ObjectGrid og = 
        ObjectGridManagerFactory.getObjectGridManager().createObjectGrid();
            og.registerEntities(new Class[] {Order.class});
    
            Session s = og.getSession();
            EntityManager em = s.getEntityManager();
    
            em.getTransaction().begin();
    
            Order o = new Order();
            o.customerName = "John Smith";
            o.date = new java.util.Date(System.currentTimeMillis());
            o.itemName = "Widget";
            o.orderNumber = "1";
            o.price = 99.99;
            o.quantity = 1;
    
            em.persist(o);
            em.getTransaction().commit();
    
            em.getTransaction().begin();
            o = (Order)em.find(Order.class, "1");
            System.out.println("Found order for customer: " + o.customerName);
            em.getTransaction().commit();
        }}
    This example application performs the following operations:

    1. Initializes a local eXtreme Scale with an automatically generated name.

    2. Registers the entity classes with the application using the registerEntities API, although using the registerEntities API is not always necessary.

    3. Retrieve a Session and a reference to the entity manager for the Session.

    4. Associates each eXtreme Scale Session with a single EntityManager and EntityTransaction. The EntityManager is now used.

    5. The registerEntities method creates a BackingMap object that is called Order, and associates the metadata for the Order object with the BackingMap object. This metadata includes the key and non-key attributes, along with the attribute types and names.

    6. A transaction starts and creates an Order instance. The transaction is populated with some values. The transaction is then persisted using the EntityManager.persist method, which identifies the entity as waiting to be included in the associated map.

    7. The transaction is then committed, and the entity is included in the ObjectMap instance.

    8. Another transaction is made, and the Order object is retrieved using the key 1. The type cast on the EntityManager.find method is necessary. The Java SE 5 capability is not used to ensure that the objectgrid.jar file works on a Java SE Version 5 and later Java virtual machine.

Next topic: Entity manager tutorial: Forming entity relationships


Entity manager tutorial: Forming entity relationships

Create a simple relationship between entities by creating two entity classes with a relationship, registering the entities with the ObjectGrid, and storing the entity instances into the cache.

  1. Create the customer entity, which is used to store customer details independently from the Order object. An example of the customer entity follows:
    Customer.java
    @Entity
    public class Customer
    {
        @Id String id;
        String firstName;
        String surname;
        String address;
        String phoneNumber;}
    This class includes information about the customer such as name, address, and phone number.

  2. Create the Order object, which is similar to the Order object in the Entity manager tutorial: Creating an entity class topic. An example of the order object follows:
    Order.java
    
    @Entity
    public class Order
    {
        @Id String orderNumber;
        Date date;
        @ManyToOne(cascade=CascadeType.PERSIST) Customer customer;
        String itemName;
        int quantity;
        double price;}
    In this example, a reference to a Customer object replaces the customerName attribute. The reference has an annotation that indicates a many-to-one relationship. A many-to-one relationship indicates that each order has one customer, but multiple orders might reference the same customer. The cascade annotation modifier indicates that if the entity manager persists the Order object, it must also persist the Customer object. If you choose to not set the cascade persist option, which is the default option, manually persist the Customer object with the Order object.

  3. Use the entities, define the maps for the ObjectGrid instance. Each map is defined for a specific entity, and one entity is named Order and the other is named Customer. The following example application illustrates how to store and retrieve a customer order:
    Application.java
    
    public class Application {
        static public void main(String [] args)
            throws Exception
        {
            ObjectGrid og = 
         ObjectGridManagerFactory.getObjectGridManager().createObjectGrid();
            og.registerEntities(new Class[] {Order.class});
    
            Session s = og.getSession();
            EntityManager em = s.getEntityManager();
    
            em.getTransaction().begin();
    
            Customer cust = new Customer();
            cust.address = "Main Street";
            cust.firstName = "John";
            cust.surname = "Smith";
            cust.id = "C001";
            cust.phoneNumber = "5555551212";
    
            Order o = new Order();
            o.customer = cust;
            o.date = new java.util.Date();
            o.itemName = "Widget";
            o.orderNumber = "1";
            o.price = 99.99;
            o.quantity = 1;
    
            em.persist(o);
            em.getTransaction().commit();
    
            em.getTransaction().begin();
            o = (Order)em.find(Order.class, "1");
            System.out.println("Found order for customer: " 
         + o.customer.firstName + " " + o.customer.surname);
            em.getTransaction().commit();
     // Close the session (optional in Version 7.1.1 and later) for improved performance
     s.close();
        }}
    This application is similar to the example application that is in the previous step. In the preceding example, only a single class Order is registered. WXS detects and automatically includes the reference to the Customer entity, and a Customer instance for John Smith is created and referenced from the new Order object. As a result, the new customer is automatically persisted, because the relationship between two orders includes the cascade modifier, which requires that each object be persisted. When the Order object is found, the entity manager automatically finds the associated Customer object and inserts a reference to the object.

Previous topic: Entity manager tutorial: Creating an entity class

Next topic: Entity manager tutorial: Order Entity Schema


Entity manager tutorial: Order Entity Schema

Create four entity classes by using both single and bidirectional relationships, ordered lists, and foreign key relationships. The EntityManager APIs are used to persist and find the entities. Building on the Order and Customer entities that are in the previous parts of the tutorial, this tutorial step adds two more entities: the Item and OrderLine entities.

Figure 1. Order Entity Schema. An Order entity has a reference to one customer and zero or more OrderLines. Each OrderLine entity has a reference to a single item and includes the quantity ordered.

  1. Create the customer entity, which is similar to the previous examples.
    Customer.java
    @Entity
    public class Customer
    {
        @Id String id;
        String firstName;
        String surname;
        String address;
        String phoneNumber;}

  2. Create the Item entity, which holds information about a product that is included in the store's inventory, such as the product description, quantity, and price.
    Item.java
    @Entity
    public class Item
    {
        @Id String id;
        String description;
        long quantityOnHand;
        double price;}

  3. Create the OrderLine entity. Each Order has zero or more OrderLines, which identify the quantity of each item in the order. The key for the OrderLine is a compound key that consists of the Order that owns the OrderLine and an integer that assigns the order line a number. Add the cascade persist modifier to every relationship on your entities.
    OrderLine.java
    @Entity
    public class OrderLine
    {
        @Id @ManyToOne(cascade=CascadeType.PERSIST) Order order;
        @Id int lineNumber;
        @OneToOne(cascade=CascadeType.PERSIST) Item item;
        int quantity;
        double price;}

  4. Create the final Order Object, which has a reference to the Customer for the order and a collection of OrderLine objects.
    Order.java
    @Entity
    public class Order
    {
        @Id String orderNumber;
        java.util.Date date;
        @ManyToOne(cascade=CascadeType.PERSIST) Customer customer;
        @OneToMany(cascade=CascadeType.ALL, mappedBy="order") 
       @OrderBy("lineNumber") List<OrderLine> lines; } 

    The cascade ALL is used as the modifier for lines. This modifier signals the EntityManager to cascade both the PERSIST operation and the REMOVE operation. For example, if the Order entity is persisted or removed, then all OrderLine entities are also persisted or removed.

    If an OrderLine entity is removed from the lines list in the Order object, the reference is then broken. However, the OrderLine entity is not removed from the cache. You must use the EntityManager remove API to remove entities from the cache. The REMOVE operation is not used on the customer entity or the item entity from OrderLine. As a result, the customer entity remains even though the order or item is removed when the OrderLine is removed.

    The mappedBy modifier indicates an inverse relationship with the target entity. The modifier identifies which attribute in the target entity references the source entity, and the owning side of a one-to-one or many-to-many relationship. Typically, we can omit the modifier. However, an error is displayed to indicate that it must be specified if WXS cannot discover it automatically. An OrderLine entity that contains two of type Order attributes in a many-to-one relationship typically causes the error.

    The @OrderBy annotation specifies the order in which each OrderLine entity should be in the lines list. If the annotation is not specified, then the lines display in an arbitrary order. Although the lines are added to the Order entity by issuing ArrayList, which preserves the order, the EntityManager does not necessarily recognize the order. When you issue the find method to retrieve the Order object from the cache, the list object is not an ArrayList object.

  5. Create the application. The following example illustrates the final Order object, which has a reference to the Customer for the order and a collection of OrderLine objects.

    1. Find the Items to order, which then become Managed entities.

    2. Create the OrderLine and attach it to each Item.

    3. Create the Order and associate it with each OrderLine and the customer.

    4. Persist the order, which automatically persists each OrderLine.

    5. Commit the transaction, which detaches each entity and synchronizes the state of the entities with the cache.

    6. Print the order information. The OrderLine entities are automatically sorted by the OrderLine ID.

    Application.java
    
    static public void main(String [] args)
            throws Exception
        {
            ...
    
            // Add some items to our inventory.
            em.getTransaction().begin();
            createItems(em);
            em.getTransaction().commit();
    
            // Create a new customer with the items in his cart.
            em.getTransaction().begin();
            Customer cust = createCustomer();
            em.persist(cust);
    
            // Create a new order and add an order line for each item.
            // Each line item is automatically persisted since the 
        // Cascade=ALL option is set.
            Order order = createOrderFromItems(em, cust, "ORDER_1", 
         new String[]{"1", "2"}, new int[]{1,3});
            em.persist(order);
            em.getTransaction().commit();
    
            // Print the order summary
            em.getTransaction().begin();
            order = (Order)em.find(Order.class, "ORDER_1");
            System.out.println(printOrderSummary(order));
            em.getTransaction().commit();
        }
    
        public static Customer createCustomer() {
            Customer cust = new Customer();
            cust.address = "Main Street";
            cust.firstName = "John";
            cust.surname = "Smith";
            cust.id = "C001";
            cust.phoneNumber = "5555551212";
            return cust;
        }
    
        public static void createItems(EntityManager em) {
            Item item1 = new Item();
            item1.id = "1";
            item1.price = 9.99;
            item1.description = "Widget 1";
            item1.quantityOnHand = 4000;
            em.persist(item1);
    
            Item item2 = new Item();
            item2.id = "2";
            item2.price = 15.99;
            item2.description = "Widget 2";
            item2.quantityOnHand = 225;
            em.persist(item2);
    
        }
    
        public static Order createOrderFromItems(EntityManager em, 
       Customer cust, String orderId, String[] itemIds, int[] qty) {
    
            Item[] items = getItems(em, itemIds);
    
            Order order = new Order();
            order.customer = cust;
            order.date = new java.util.Date();
            order.orderNumber = orderId;
            order.lines = new ArrayList<OrderLine>(items.length);          
        for(int i=0;i<items.length;i++){
          OrderLine line = new OrderLine();
                line.lineNumber = i+1;
                line.item = items[i];
                line.price = line.item.price;
                line.quantity = qty[i];
                line.order = order;
                order.lines.add(line);
            }
            return order;
        }
    
        public static Item[] getItems(EntityManager em, String[] itemIds) {
            Item[] items = new Item[itemIds.length];
            for(int i=0;i<items.length;i++){
        items[i] = (Item) em.find(Item.class, itemIds[i]);
            }
            return items;
        }
    The next step is to delete an entity. The EntityManager interface has a remove method that marks an object as deleted. The application should remove the entity from any relationship collections before calling the remove method. Edit the references and issue the remove method, or em.remove(object), as a final step.

Previous topic: Entity manager tutorial: Forming entity relationships

Next topic: Entity manager tutorial: Updating entries


Entity manager tutorial: Updating entries

To change an entity, we can find the instance, update the instance and any referenced entities, and commit the transaction.

Update entries. The following example demonstrates how to find the Order instance, change it and any referenced entities, and commit the transaction.

public static void updateCustomerOrder(EntityManager em) {
    em.getTransaction().begin();
    Order order = (Order) em.find(Order.class, "ORDER_1");
    processDiscount(order, 10);
    Customer cust = order.customer;
    cust.phoneNumber = "5075551234";
    em.getTransaction().commit();        }
   
public static void processDiscount(Order order, double discountPct) {
    for(OrderLine line : order.lines) {
        line.price = line.price * ((100-discountPct)/100);
    }}
Flushing the transaction synchronizes all managed entities with the cache. When a transaction is committed, a flush automatically occurs. In this case, the Order becomes a managed entity. Any entities that are referenced from the Order, Customer, and OrderLine also become managed entities. When the transaction is flushed, each of the entities are checked to determine if they have been modified. Those that are modified are updated in the cache. After the transaction completes, by either being committed or rolled back, the entities become detached and any changes that are made in the entities are not reflected in the cache.

Previous topic: Entity manager tutorial: Order Entity Schema

Next topic: Entity manager tutorial: Updating and removing entries with an index


Entity manager tutorial: Updating and removing entries with an index

Use an index to find, update, and remove entities.

Update and remove entities by using an index. Use an index to find, update, and remove entities.

In the following examples, the Order entity class is updated to use the @Index annotation. The @Index annotation signalsWXS to create a range index for an attribute. The name of the index is the same name as the name of the attribute and is always a MapRangeIndex index type.

Order.java
@Entity
public class Order
{
    @Id String orderNumber;
    @Index java.util.Date date;
    @OneToOne(cascade=CascadeType.PERSIST) Customer customer;
    @OneToMany(cascade=CascadeType.ALL, mappedBy="order") 
    @OrderBy("lineNumber") List<OrderLine> lines;  } 
The following example demonstrates how to cancel all orders that are submitted within the last minute. Find the order by using an index, add the items in the order back into the inventory, and remove the order and the associated line items from the system.
public static void cancelOrdersUsingIndex(Session s) 
  throws ObjectGridException {
    // Cancel all orders that were submitted 1 minute ago
    java.util.Date cancelTime = new 
   java.util.Date(System.currentTimeMillis() - 60000);
    EntityManager em = s.getEntityManager();
    em.getTransaction().begin();
    MapRangeIndex dateIndex = (MapRangeIndex) 
   s.getMap("Order").getIndex("date");
    Iterator<Tuple> orderKeys = dateIndex.findGreaterEqual(cancelTime);     
  while(orderKeys.hasNext()) {         
   Tuple orderKey = orderKeys.next();         
   // Find the Order so we can remove it.         
   Order curOrder = (Order) em.find(Order.class, orderKey);         
   // Verify that the order was not updated by someone else.         
   if(curOrder != null && curOrder.date.getTime() >= cancelTime.getTime()) {
    for(OrderLine line : curOrder.lines) {                 
     // Add the item back to the inventory.                 
     line.item.quantityOnHand += line.quantity;                 
     line.quantity = 0;             
    }             
   em.remove(curOrder);         
   }     
  }     
 em.getTransaction().commit(); }

Previous topic: Entity manager tutorial: Updating entries

Next topic: Entity manager tutorial: Updating and removing entries by using a query


Entity manager tutorial: Updating and removing entries by using a query

We can update and remove entities by using a query.

Update and remove entities by using a query.

Order.java
@Entity
public class Order
{
    @Id String orderNumber;
    @Index java.util.Date date;
    @OneToOne(cascade=CascadeType.PERSIST) Customer customer;
    @OneToMany(cascade=CascadeType.ALL, mappedBy="order") 
   @OrderBy("lineNumber") List<OrderLine> lines;  } 
The order entity class is the same as it is in the previous example. The class still provides the @Index annotation, because the query string uses the date to find the entity. The query engine uses indices when they can be used.
public static void cancelOrdersUsingQuery(Session s) {
        // Cancel all orders that were submitted 1 minute ago
        java.util.Date cancelTime = new java.util.Date(System.currentTimeMillis() - 60000);
        EntityManager em = s.getEntityManager();
        em.getTransaction().begin();
        
        // Create a query that will find the order based on date.  Since
        // we have an index defined on the order date, the query 
    // will automatically use it.
        Query query = em.createQuery("SELECT order FROM Order order 
     WHERE order.date >= ?1");
        query.setParameter(1, cancelTime);
        Iterator<Order> orderIterator = query.getResultIterator();         
    while(orderIterator.hasNext()) {             
     Order order = orderIterator.next();             
     // Verify that the order wasn't updated by someone else.             
     // Since the query used an index, there was no lock on the row.             
     if(order != null && order.date.getTime() >= cancelTime.getTime()) {                 
       for(OrderLine line : order.lines) {                     
        // Add the item back to the inventory.                     
        line.item.quantityOnHand += line.quantity;                     
        line.quantity = 0;                 
       }                 
       em.remove(order);             
     }         
   }         
  em.getTransaction().commit();              }
Like the previous example, the cancelOrdersUsingQuery method intends to cancel all orders that were submitted in the past minute. To cancel the order, you find the order using a query, add the items in the order back into the inventory, and remove the order and associated line items from the system.

Previous topic: Entity manager tutorial: Updating and removing entries with an index


Tutorial: Configuring Java SE security

With the following tutorial, we can create a distributed eXtreme Scale environment in a Java Platform, Standard Edition environment.

Ensure that we are familiar with the basics of a distributed eXtreme Scale configuration.

Use this tutorial when you have installed eXtreme Scale in a stand-alone environment. Each step in the tutorial builds on the previous one. Follow each of the steps to secure a distributed eXtreme Scale and develop a simple Java SE application to access the secured eXtreme Scale.

Begin tutorial


Java SE security tutorial - Step 1

In order to work with the rest of the tutorial, you need to create and package a simple Java program and two XML files. These set of files defines a simple ObjectGrid configuration with one ObjectGrid instance named

accounting and a customer map. The SimpleDP.xml file features a deployment policy of one map set configured with one partition and zero minimum required replicas.

  1. In a command line window, go to the wxs_home directory.

  2. Create a directory called applib.

  3. Ensure your development environment contains the ogclient.jar file in the classpath.

  4. Create and compile the following SimpleApp.java class:
    SimpleApp.java
    // This sample program is provided AS IS and may be used, executed, copied and modified 
    // without royalty payment by customer 
    // (a) for its own instruction and study, 
    // (b) to develop applications designed to run with an IBM WebSphere product, 
    // either for customer's own internal use or for redistribution by customer, as part of such an 
    // application, in customer's own products.
    // Licensed Materials - Property of IBM
    // 5724-J34 (C) COPYRIGHT International Business Machines Corp. 2007-2009
    package com.ibm.websphere.objectgrid.security.sample.guide;
    
    import com.ibm.websphere.objectgrid.ClientClusterContext;
    import com.ibm.websphere.objectgrid.ObjectGrid;
    import com.ibm.websphere.objectgrid.ObjectGridManager;
    import com.ibm.websphere.objectgrid.ObjectGridManagerFactory;
    import com.ibm.websphere.objectgrid.ObjectMap;
    import com.ibm.websphere.objectgrid.Session;
    
    public class SimpleApp {
    
        public static void main(String[] args) throws Exception {
    
            SimpleApp app = new SimpleApp();
            app.run(args);
        }
    
        /**
         * read and write the map 
         * @throws Exception
         */
        protected void run(String[] args) throws Exception {
            ObjectGrid og = getObjectGrid(args);
    
            Session session = og.getSession();
    
            ObjectMap customerMap = session.getMap("customer");
    
            String customer = (String) customerMap.get("0001");
    
            if (customer == null) {
                customerMap.insert("0001", "fName lName");
            } else {
                customerMap.update("0001", "fName lName");
            }
            customer = (String) customerMap.get("0001");
     // Close the session (optional in Version 7.1.1 and later) for improved performance     
     session.close(); 
            System.out.println("The customer name for ID 0001 is " + customer);
        }
    
        /**
         * Get the ObjectGrid      * @return an ObjectGrid instance      * @throws Exception
         */
        protected ObjectGrid getObjectGrid(String[] args) throws Exception {
            ObjectGridManager ogManager = ObjectGridManagerFactory.getObjectGridManager();
    
            // Create an ObjectGrid 
            ClientClusterContext ccContext = ogManager.connect("localhost:2809", null, null);
            ObjectGrid og = ogManager.getObjectGrid(ccContext, "accounting");
    
            return og;
    
        }}

  5. Compile the package with this file and name the JAR sec_sample.jar.

  6. Go to the wxs_home directory, and create a directory called xml

  7. In thewxs_home /xml directory, create the following configuration files:
    SimpleApp.xml
    
    <?xml version="1.0" encoding="UTF-8"?>
    <objectGridConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://ibm.com/ws/objectgrid/config ../objectGrid.xsd" 
     xmlns="http://ibm.com/ws/objectgrid/config">
        <objectGrids>
            <objectGrid name="accounting">
                <backingMap name="customer" readOnly="false" copyKey="true"/>
            </objectGrid>
        </objectGrids>
    </objectGridConfig>

    The following XML file configures the deployment environment.

    SimpleDP.xml
    
    <?xml version="1.0" encoding="UTF-8"?>
    <deploymentPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://ibm.com/ws/objectgrid/deploymentPolicy ../deploymentPolicy.xsd"
     xmlns="http://ibm.com/ws/objectgrid/deploymentPolicy">
    
     <objectgridDeployment objectgridName="accounting">
      <mapSet name="mapSet1" numberOfPartitions="1" minSyncReplicas="0" maxSyncReplicas="2" 
       maxAsyncReplicas="1">
       <map ref="customer"/>
      </mapSet>
     </objectgridDeployment>
    </deploymentPolicy>

These files create a simple ObjectGrid configuration with one ObjectGrid an

accounting instance and a customer map.


Java SE security tutorial - Step 2

Before we can verify that the SimpleApp.java sample runs, you need to start a catalog server and a container server. After starting these services successfully, we can then launch the client and run the sample. Additional security features are added incrementally in the steps of the tutorial to increase the amount of integrated security that is available.

To successfully complete this step of the tutorial, you should have access to the following files:

You should have created these files in Java SE security tutorial - Step 1 of this tutorial.

You should also know how to:

  1. In a command line window, go to the wxs_home /bin directory and start the catalog service.

  2. Start a container service named c0:

      ./startOgServer.sh c0 -objectGridFile ../xml/SimpleApp.xml -deploymentPolicyFile ../xml/SimpleDP.xml -catalogServiceEndPoints localhost:2809
      ./startXsServer.sh c0 -objectGridFile ../xml/SimpleApp.xml -deploymentPolicyFile ../xml/SimpleDP.xml -catalogServiceEndPoints localhost:2809

  3. After the catalog server and container server have been started, run the sec_sample.jar sample as follows:

      java -classpath ../lib/objectgrid.jar:../applib/sec_sample.jar com.ibm.websphere.objectgrid.security.sample.guide.SimpleApp

    The output of the sample is: The customer name for ID 0001 is fName lName The getObjectGrid method in this class obtains an ObjectGrid, and the run method reads a record from the customer map and updates the value in the accounting grid.

  4. Verify the size of the "customer" map inserted into the "accounting" grid, by issuing the xscmd command utility as follows:

      ./xscmd.sh -c showMapSizes -g accounting -ms mapSet1

  5. Stop a container server named c0 with one of the following scripts:

    If the server stopped successfully, then you will see the following message:

    CWOBJ2512I: ObjectGrid server c0 stopped.

  6. Stop the catalog server with one of the following scripts:

      ./stopOgServer.sh catalogServer -catalogServiceEndPoints localhost:2809
      ./stopXsServer.sh catalogServer -catalogServiceEndPoints localhost:2809

    If the server stopped successfully, then you will see the following message:

    CWOBJ2512I: ObjectGrid server catalogServer stopped.


Java SE security tutorial - Step 3

The rest of the tutorial demonstrates how to enable client authentication before connecting to a WXS server. To prepare for the next step of this tutorial, you need to package the SecureSimpleApp.java program into a JAR and create a set of configuration files, which include a security.xml file, and two JAAS configuration files. The security.xml file lets you write authentication into the environment, and the JAAS configuration files provide the authentication mechanism when connecting to the server.

  1. In a command line window, go to the wxs_home /applib directory you created in Java SE security tutorial - Step 1 .

  2. Create and compile the following SecureSimpleApp.java class:

    In the following example, some lines of code are continued on the next line for publication purposes.

    SecureSimpleApp.java
    package com.ibm.websphere.objectgrid.security.sample.guide;
    
    import com.ibm.websphere.objectgrid.ClientClusterContext;
    import com.ibm.websphere.objectgrid.ObjectGrid;
    import com.ibm.websphere.objectgrid.ObjectGridManager;
    import com.ibm.websphere.objectgrid.ObjectGridManagerFactory;
    import com.ibm.websphere.objectgrid.security.config.ClientSecurityConfiguration;
    import com.ibm.websphere.objectgrid.security.config.ClientSecurityConfigurationFactory;
    import com.ibm.websphere.objectgrid.security.plugins.CredentialGenerator;
    import com.ibm.websphere.objectgrid.security.plugins.builtins.UserPasswordCredentialGenerator;
    
    public class SecureSimpleApp extends SimpleApp {
    
        public static void main(String[] args) throws Exception {
    
            SecureSimpleApp app = new SecureSimpleApp();
            app.run(args);
        }
    
        /**
         * Get the ObjectGrid      * @return an ObjectGrid instance      * @throws Exception
         */
        protected ObjectGrid getObjectGrid(String[] args) throws Exception {
            ObjectGridManager ogManager = ObjectGridManagerFactory.getObjectGridManager();
            ogManager.setTraceFileName("logs/client.log");
            ogManager.setTraceSpecification("ObjectGrid*=all=enabled:ORBRas=all=enabled");
    
            // Creates a ClientSecurityConfiguration object using the specified file         
            ClientSecurityConfiguration clientSC = ClientSecurityConfigurationFactory
                    .getClientSecurityConfiguration(args[0]);
            
            // Creates a CredentialGenerator using the passed-in user and password.
            CredentialGenerator credGen = new UserPasswordCredentialGenerator(args[1], args[2]);
            clientSC.setCredentialGenerator(credGen);
            
            // Create an ObjectGrid by connecting to the catalog server 
            ClientClusterContext ccContext = ogManager.connect("localhost:2809", clientSC, null);
            ObjectGrid og = ogManager.getObjectGrid(ccContext, "accounting");
    
            return og;
    
        }}

  3. Ensure your development environment contains the ogclient.jar file in the classpath. For more information, see the Programming Guide.

  4. Compile the package with these files and name the JAR sec_sample.jar.

  5. Change to the wxs_home directory.

  6. Create a directory called security.

  7. Create a configuration file called security.xml. Server security properties are specified in this file. These properties are common for both catalog servers and container servers.
    security.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <securityConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://ibm.com/ws/objectgrid/config/security ../objectGridSecurity.xsd"
     xmlns="http://ibm.com/ws/objectgrid/config/security">
    
     <security securityEnabled="true" loginSessionExpirationTime="300" >
            
            <authenticator className ="com.ibm.websphere.objectgrid.security.plugins.builtins.KeyStoreLoginAuthenticator">
            </authenticator>
        </security>
     
    </securityConfig>

Building on the previous step, the following topic shows how to implement client authentication in a distributed eXtreme Scale environment.

Be sure that you have completed Java SE security tutorial - Step 3 . You need to have created and complied the SecureSimpleApp.java sample into a sec_sample.jar file, and created a configuration file called security.xml.

With client authentication enabled, a client is authenticated before connecting to the eXtreme Scale server. This section demonstrates how client authentication can be done in a WXS server environment, using the sample SecureSimpleApp.java.

Client credential

The SecureSimpleApp.java sample uses the following two plug-in implementations to obtain client credentials:

com.ibm.websphere.objectgrid.security.plugins.builtins.UserPasswordCredential
com.ibm.websphere.objectgrid.security.plugins.builtins.UserPasswordCredentialGenerator 

Server authenticator

The example uses a WXS built-in implementation: KeyStoreLoginAuthenticator, which is for testing and sample purposes (a keystore is a simple user registry and should not be used for production).

  1. In a command line window, go to the wxs_home directory.

  2. Change to the wxs_home /security directory you had created in Java SE security tutorial - Step 3 .

  3. Create a JAAS configuration file that enforces a method of authentication to the server, og_jaas.config. The KeyStoreLoginAuthenticator referenced in the security.xml file uses a keystore by using the JAAS login module "KeyStoreLogin". The keystore can be configured as an option to the KeyStoreLoginModule class.
    og_jaas.config
    KeyStoreLogin{
    com.ibm.websphere.objectgrid.security.plugins.builtins.KeyStoreLoginModule required
         keyStoreFile="../security/sampleKS.jks" debug = true;};

  4. Change to the java_home /bin directory and run the keytool.

  5. Change to the wxs_home /security directory, and create two users, "manager" and "cashier" with their own passwords.

    1. Use the keytool to create a user "manager" with password "manager1" in the keystore sampleKS.jks.

      • keytool -genkey -v -keystore sampleKS.jks -storepass sampleKS1 \
        -alias manager -keypass manager1 \
        -dname CN=manager,O=acme,OU=OGSample -validity 10000

      • keytool -genkey -v -keystore sampleKS.jks -storepass sampleKS1 ^
        -alias manager -keypass manager1 ^
        -dname CN=manager,O=acme,OU=OGSample -validity 10000

    2. Use the keytool to create a user "cashier" with password "cashier1" in the keystore sampleKS.jks.

      • keytool -genkey -v -keystore sampleKS.jks -storepass sampleKS1 \
        -alias cashier -keypass cashier1 \
        -dname CN=cashier,O=acme,OU=OGSample -validity 10000

      • keytool -genkey -v -keystore sampleKS.jks -storepass sampleKS1 ^
        -alias cashier -keypass cashier1 ^
        -dname CN=cashier,O=acme,OU=OGSample -validity 10000

  6. Make a copy of the sampleClient.properties file located in wxs_home/properties directory to wxs_home/security/client.properties

    • cp ../properties/sampleClient.properties client.properties

    • copy ..\properties\sampleClient.properties client.properties

  7. In the wxs_home/security directory, save it as client.properties

    Make the following changes to the client.properties file:

    1. securityEnabled: Set securityEnabled to true (default value) enables the client security, which includes authentication.

    2. credentialAuthentication: Set credentialAuthentication to Supported (default value), which means the client supports credential authentication.

    3. transportType: Set transportType to TCP/IP, which means no SSL will be used.

  8. Copy the sampleServer.properties file into the wxs_home/security directory and save it as server.properties.

    • cp ../properties/sampleServer.properties server.properties

    • copy ..\properties\sampleServer.properties server.properties

    Make the following changes in the server.properties file:

    1. securityEnabled: Set the securityEnabled attribute to true.

    2. transportType: Set transportType attribute to TCP/IP, which means no SSL is used.

    3. secureTokenManagerType: Set secureTokenManagerType attribute to none to not configure the secure token manager.

  9. Go to the wxs_home/bin directory and depending on your platform, issue one of the following commands to start a catalog server. You need to issue the-clusterFile and -serverProps command line options to pass in security properties:

    • ./startOgServer.sh catalogServer -clusterSecurityFile ../security/security.xml
      -serverProps ../security/server.properties -jvmArgs
      -Djava.security.auth.login.config="../security/og_jaas.config"

    • ./startXsServer.sh catalogServer -clusterSecurityFile ../security/security.xml
      -serverProps ../security/server.properties -jvmArgs
      -Djava.security.auth.login.config="../security/og_jaas.config"

  10. Start a container server named c0 with one of the following scripts. The server property file is passed by issuing -serverProps.

      • ./startOgServer.sh c0 -objectgridFile ../xml/SimpleApp.xml
        -deploymentPolicyFile ../xml/SimpleDP.xml
        -catalogServiceEndPoints localhost:2809
        -serverProps ../security/server.properties
        -jvmArgs -Djava.security.auth.login.config="../security/og_jaas.config"

      • ./startXsServer.sh c0 -objectgridFile ../xml/SimpleApp.xml
        -deploymentPolicyFile ../xml/SimpleDP.xml
        -catalogServiceEndPoints localhost:2809
        -serverProps ../security/server.properties
        -jvmArgs -Djava.security.auth.login.config="../security/og_jaas.config"

  11. After the catalog server and container server have been started, run the sec_sample.jar sample as follows:

    • java -classpath ../lib/objectgrid.jar:../applib/sec_sample.jar
        com.ibm.websphere.objectgrid.security.sample.guide.SecureSimpleApp
        ../security/client.properties manager manager1

    • java -classpath ..\lib\objectgrid.jar;..\applib\sec_sample.jar
        com.ibm.websphere.objectgrid.security.sample.guide.SecureSimpleApp
        ..\security\client.properties manager manager1

    Use a colon (:) for the classpath separator instead of a semicolon (;) as in the previous example.

    After you issue the class, the following output results:

    The customer name for ID 0001 is fName lName.

  12. Verify the size of the "customer" map inserted into the "accounting" grid, by issuing the xscmd command utility as follows:

      ./xscmd.sh -c showMapSizes -g accounting -m customer -username manager -password manager1

  13. Optional: To stop the container or catalog servers, you can use the stopOgServer or stopXsServer command. However you need to provide a security configuration file. The sample client property file defines the following two properties to generate a userID/password credential (manager/manager1).
    credentialGeneratorClass=com.ibm.websphere.objectgrid.security.plugins.builtins.UserPasswordCredentialGenerator 
    credentialGeneratorProps=manager manager1

    Stop the container c0 with the following command.

      ./stopOgServer.sh c0 -catalogServiceEndPoints localhost:2809 -clientSecurityFile ../security/client.properties
      ./stopXsServer.sh c0 -catalogServiceEndPoints localhost:2809 -clientSecurityFile ../security/client.properties

    If you do not provide the -clientSecurityFile option, you will see an exception with the following message.

    >> SERVER (id=39132c79, host=9.10.86.47) TRACE START:

    >> org.omg.CORBA.NO_PERMISSION: Server requires credential authentication but there is no security context from the client. This usually happens when the client does not pass a credential the server.

    vmcid: 0x0

    minor code: 0

    completed: No

    We can also shut down the catalog server using the following command. However, if we want to continue trying the next step tutorial, we can let the catalog server stay running.

      ./stopOgServer.sh catalogServer -catalogServiceEndPoints localhost:2809 -clientSecurityFile ../security/client.properties
      ./stopXsServer.sh -catalogServiceEndPoints localhost:2809 -clientSecurityFile ../security/client.properties

    If you do shutdown the catalog server, you will see the following output.

    CWOBJ2512I: ObjectGrid server catalogServer stopped

    Now, you have successfully made your system partially secure by enabling authentication. You configured the server to plug in the user registry, configured the client to provide client credentials, and changed the client property file and cluster XML file to enable authentication.

    If you provide an invalidate password, you see an exception stating that the user name or password is not correct.

    Next step of tutorial

After authenticating a client, as in the previous step, we can give security privileges through eXtreme Scale authorization mechanisms.

Be sure to have completed Java SE security tutorial - Step 4 prior to proceeding with this task.

The previous step of this tutorial demonstrated how to enable authentication in a WXS grid. As a result, no unauthenticated client can connect to your server and submit requests to your system. However, every authenticated client has the same permission or privileges to the server, such as reading, writing, or deleting data that is stored in the ObjectGrid maps. Clients can also issue any type of query. This section demonstrates how to use eXtreme Scale authorization to give various authenticated users varying privileges.

Similar to many other systems, eXtreme Scale adopts a permission-based authorization mechanism. WXS has different permission categories that are represented by different permission classes. This topic features MapPermission.

In WXS, the com.ibm.websphere.objectgrid.security.MapPermission class represents permissions to the eXtreme Scale resources, specifically the methods of ObjectMap or JavaMap interfaces. WXS defines the following permission strings to access the methods of ObjectMap and JavaMap:

The authorization occurs when a client calls a method of ObjectMap or JavaMap. The eXtreme Scale runtime environment checks different map permissions for different methods. If the required permissions are not granted to the client, an AccessControlException results.

This tutorial demonstrates how to use Java Authentication and Authorization Service (JAAS) authorization to grant authorization map accesses for different users.

  1. Enable eXtreme Scale authorization. To enable authorization on the ObjectGrid, you need to set the securityEnabled attribute to true for that particular ObjectGrid in the XML file. Enabling security on the ObjectGrid means that we are enabling authorization. Use the following commands to create a new ObjectGrid XML file with security enabled.

    1. Navigate to the xml directory.
      cd objectgridRoot/xml

    2. Copy the SimpleApp.xml file to the SecureSimpleApp.xml file.

      • cp SimpleApp.xml SecureSimpleApp.xml

      • copy SimpleApp.xml SecureSimpleApp.xml

    3. Open the SecureSimpleApp.xml file and add

      securityEnabled="true" on the ObjectGrid level as the following XML shows:

      <?xml version="1.0" encoding="UTF-8"?>
      <objectGridConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
          xsi:schemaLocation="http://ibm.com/ws/objectgrid/config ../objectGrid.xsd" 
         xmlns="http://ibm.com/ws/objectgrid/config">
          <objectGrids>
              <objectGrid name="accounting" securityEnabled="true">
                  <backingMap name="customer" readOnly="false" copyKey="true"/>
              </objectGrid>
          </objectGrids>
      </objectGridConfig>

  2. Define the authorization policy.

    In the previous client authentication topic, you created the users, cashier and manager, in the keystore. In this example, the user "cashier" only has read permissions to all the maps, and the user "manager" has all permissions. JAAS authorization is used in this example. Create a JAAS authorization policy file to grant permissions to principals. Create the following og_auth.policy file in the objectgridRoot/security directory:

    og_auth.policy
    grant codebase "http://www.ibm.com/com/ibm/ws/objectgrid/security/PrivilegedAction"
        principal javax.security.auth.x500.X500Principal "CN=cashier,O=acme,OU=OGSample" {
        permission com.ibm.websphere.objectgrid.security.MapPermission "accounting.*", "read";};
    
    grant codebase "http://www.ibm.com/com/ibm/ws/objectgrid/security/PrivilegedAction"
        principal javax.security.auth.x500.X500Principal "CN=manager,O=acme,OU=OGSample" {
        permission com.ibm.websphere.objectgrid.security.MapPermission "accounting.*", "all";};
    Note:

    • The codebase "http://www.ibm.com/com/ibm/ws/objectgridRoot/security/PrivilegedAction" is a specially-reserved URL for ObjectGrid. All ObjectGrid permissions granted to principals should use this special code base.

    • The first grant statement grants "read" map permission to principal "CN=cashier,O=acme,OU=OGSample", so the cashier has only map read permission to all the maps in the ObjectGrid accounting.

    • The second grant statement grants "all" map permission to principal "CN=manager,O=acme,OU=OGSample", so the manager has all permissions to maps in the ObjectGrid accounting.

    Now we can launch a server with an authorization policy. The JAAS authorization policy file can be set using the standard -D property: -Djava.security.policy=../security/og_auth.policy

  3. Run the application.

    After you create the above files, we can run the application.

    Use the following commands to start the catalog server.

    1. Navigate to the bin directory: cd objectgridRoot/bin

    2. Start the catalog server.

        ./startOgServer.sh catalogServer -clusterSecurityFile ../security/security.xml -serverProps ../security/server.properties -jvmArgs -Djava.security.auth.login.config="../security/og_jaas.config"
        ./startXsServer.sh catalogServer -clusterSecurityFile ../security/security.xml -serverProps ../security/server.properties -jvmArgs -Djava.security.auth.login.config="../security/og_jaas.config"

      The security.xml and server.properties files were created in the previous step of this tutorial.

    3. We can then start a secure container server using the following script. Run the following script from the bin directory:

      • ./startOgServer.sh c0 -objectGridFile ../xml/SecureSimpleApp.xml 
        -deploymentPolicyFile ../xml/SimpleDP.xml 
        -catalogServiceEndPoints localhost:2809 
        -serverProps ../security/server.properties 
        -jvmArgs -Djava.security.auth.login.config="../security/og_jaas.config" 
        -Djava.security.policy="../security/og_auth.policy"
        ./startXsServer.sh c0 -objectGridFile ../xml/SecureSimpleApp.xml 
        -deploymentPolicyFile ../xml/SimpleDP.xml 
        -catalogServiceEndPoints localhost:2809 
        -serverProps ../security/server.properties 
        -jvmArgs -Djava.security.auth.login.config="../security/og_jaas.config" 
        -Djava.security.policy="../security/og_auth.policy"

    Notice the following differences from the previous container server start command:

    • Use the SecureSimpleApp.xml file instead of the SimpleApp.xml file.

    • Add another -Djava.security.policy argument to set the JAAS authorization policy file to the container server process.

    Use the same command as in the previous step of the tutorial:

    1. Navigate to the bin directory.

      • java -classpath ../lib/objectgrid.jar:../applib/sec_sample.jar com.ibm.websphere.objectgrid.security.sample.guide.SecureSimpleApp 
        ../security/client.properties manager manager1

      • java -classpath ..\lib\objectgrid.jar;..\applib\sec_sample.jar com.ibm.websphere.objectgrid.security.sample.guide.SecureSimpleApp
         ..\security\client.properties manager manager1

    2. Because user "manager" has all permissions to maps in the accounting ObjectGrid, the application runs properly.

      Now, instead of using user "manager", use user "cashier" to launch the client application.

    3. Navigate to the bin directory.

      • java -classpath ../lib/objectgrid.jar:../applib/sec_sample.jar com.ibm.ws.objectgrid.security.sample.guide.SecureSimpleApp 
        ../security/client.properties cashier cashier1

      • java -classpath ..\lib\objectgrid.jar;..\applib\sec_sample.jar com.ibm.ws.objectgrid.security.sample.guide.SecureSimpleApp 
        ..\security\client.properties cashier cashier1

    The following exception results:

    In the following example, some lines of code are continued on the next line for publication purposes.

    Exception in thread "P=387313:O=0:CT" com.ibm.websphere.objectgrid.TransactionException: 
    rolling back transaction, see caused by exception
     at com.ibm.ws.objectgrid.SessionImpl.rollbackPMapChanges(SessionImpl.java:1422)
      at com.ibm.ws.objectgrid.SessionImpl.commit(SessionImpl.java:1149)
      at com.ibm.ws.objectgrid.SessionImpl.mapPostInvoke(SessionImpl.java:2260)
      at com.ibm.ws.objectgrid.ObjectMapImpl.update(ObjectMapImpl.java:1062)
      at com.ibm.ws.objectgrid.security.sample.guide.SimpleApp.run(SimpleApp.java:42)
     at com.ibm.ws.objectgrid.security.sample.guide.SecureSimpleApp.main(SecureSimpleApp.java:27)
    Caused by: com.ibm.websphere.objectgrid.ClientServerTransactionCallbackException: 
       Client Services - received exception from remote server:
         com.ibm.websphere.objectgrid.TransactionException: transaction rolled back, 
       see caused by Throwable
            at com.ibm.ws.objectgrid.client.RemoteTransactionCallbackImpl.processReadWriteResponse(
                RemoteTransactionCallbackImpl.java:1399)
            at com.ibm.ws.objectgrid.client.RemoteTransactionCallbackImpl.processReadWriteRequestAndResponse(
                RemoteTransactionCallbackImpl.java:2333)
            at com.ibm.ws.objectgrid.client.RemoteTransactionCallbackImpl.commit(RemoteTransactionCallbackImpl.java:557)
            at com.ibm.ws.objectgrid.SessionImpl.commit(SessionImpl.java:1079)
            ... 4 more
    Caused by: com.ibm.websphere.objectgrid.TransactionException: transaction rolled back, see caused by Throwable
            at com.ibm.ws.objectgrid.ServerCoreEventProcessor.processLogSequence(ServerCoreEventProcessor.java:1133)
            at com.ibm.ws.objectgrid.ServerCoreEventProcessor.processReadWriteTransactionRequest
         (ServerCoreEventProcessor.java:910)
            at com.ibm.ws.objectgrid.ServerCoreEventProcessor.processClientServerRequest(ServerCoreEventProcessor.java:1285)
    
            at com.ibm.ws.objectgrid.ShardImpl.processMessage(ShardImpl.java:515)
            at com.ibm.ws.objectgrid.partition.IDLShardPOA._invoke(IDLShardPOA.java:154)
            at com.ibm.CORBA.poa.POAServerDelegate.dispatchToServant(POAServerDelegate.java:396)
            at com.ibm.CORBA.poa.POAServerDelegate.internalDispatch(POAServerDelegate.java:331)
            at com.ibm.CORBA.poa.POAServerDelegate.dispatch(POAServerDelegate.java:253)
            at com.ibm.rmi.iiop.ORB.process(ORB.java:503)
            at com.ibm.CORBA.iiop.ORB.process(ORB.java:1553)
            at com.ibm.rmi.iiop.Connection.respondTo(Connection.java:2680)
            at com.ibm.rmi.iiop.Connection.doWork(Connection.java:2554)
            at com.ibm.rmi.iiop.WorkUnitImpl.doWork(WorkUnitImpl.java:62)
            at com.ibm.rmi.iiop.WorkerThread.run(ThreadPoolImpl.java:202)
            at java.lang.Thread.run(Thread.java:803)
    Caused by: java.security.AccessControlException: Access denied (
       com.ibm.websphere.objectgrid.security.MapPermission accounting.customer write)
            at java.security.AccessControlContext.checkPermission(AccessControlContext.java:155)
            at com.ibm.ws.objectgrid.security.MapPermissionCheckAction.run(MapPermissionCheckAction.java:141)
            at java.security.AccessController.doPrivileged(AccessController.java:275)
            at javax.security.auth.Subject.doAsPrivileged(Subject.java:727)
            at com.ibm.ws.objectgrid.security.MapAuthorizer$1.run(MapAuthorizer.java:76)
            at java.security.AccessController.doPrivileged(AccessController.java:242)
            at com.ibm.ws.objectgrid.security.MapAuthorizer.check(MapAuthorizer.java:66)
            at com.ibm.ws.objectgrid.security.SecuredObjectMapImpl.checkMapAuthorization(SecuredObjectMapImpl.java:429)
            at com.ibm.ws.objectgrid.security.SecuredObjectMapImpl.update(SecuredObjectMapImpl.java:490)
            at com.ibm.ws.objectgrid.SessionImpl.processLogSequence(SessionImpl.java:1913)
            at com.ibm.ws.objectgrid.SessionImpl.processLogSequence(SessionImpl.java:1805)
            at com.ibm.ws.objectgrid.ServerCoreEventProcessor.processLogSequence(ServerCoreEventProcessor.java:1011)
            ... 14 more

    This exception occurs because the user "cashier" does not have write permission, so it cannot update the map customer.

    Now your system supports authorization. We can define authorization policies to grant different permissions to different users.

Complete the next step of the tutorial. See Java SE security tutorial - Step 6 .

The following step explains how we can enable a security layer for communication between your environment's endpoints.

Be sure you have completed Java SE security tutorial - Step 5 prior to proceeding with this task.

The eXtreme Scale topology supports both Transport Layer Security/Secure Sockets Layer (TLS/SSL) for secure communication between ObjectGrid endpoints (client, container servers, and catalog servers). This step of the tutorial builds upon the previous steps to enable transport security.

  1. Create TLS/SSL keys and keystores

    In order to enable transport security, you must create a keystore and trust store. This exercise only creates one key and trust-store pair. These stores are used for ObjectGrid clients, container servers, and catalog servers, and are created with the JDK keytool.

    • Create a private key in the keystore

      keytool -genkey -alias ogsample -keystore key.jks -storetype JKS -keyalg rsa -dname "CN=ogsample, OU=OGSample, O=acme, L=Your City, S=Your State, C=Your Country" -storepass ogpass -keypass ogpass -validity 3650

      Using this command, a keystore key.jks is created with a key "ogsample" stored in it. This keystore key.jks will be used as the SSL keystore.

    • Export the public certificate

      keytool -export -alias ogsample -keystore key.jks -file temp.key -storepass ogpass

      Using this command, the public certificate of key "ogsample" is extracted and stored in the file temp.key.

    • Import the client's public certificate to the trust store

      keytool -import -noprompt -alias ogsamplepublic -keystore trust.jks -file temp.key -storepass ogpass

      Using this command, the public certificate was added to keystore trust.jks. This trust.jks is used as the SSL trust store.

  2. Configure ObjectGrid property files

    In this step, configure the ObjectGrid property files to enable transport security.

    First, copy the key.jks and trust.jks files into the objectgridRoot/security directory.

    Set the following properties in the client.properties and server.properties file.

    transportType=SSL-Required
    
    alias=ogsample
    contextProvider=IBMJSSE2
    protocol=SSL
    keyStoreType=JKS
    keyStore=../security/key.jks
    keyStorePassword=ogpass
    trustStoreType=JKS
    trustStore=../security/trust.jks
    trustStorePassword=ogpass

    transportType: The value of transportType is set to "SSL-Required", which means the transport requires SSL. So all the ObjectGrid endpoints (clients, catalog servers, and container servers) should have SSL configuration set and all transport communication will be encrypted.

    The other properties are used to set the SSL configurations. See Transport layer security and secure sockets layer for a detailed explanation. Make sure you follow the instructions in this topic to update your orb.properties file.

    Make sure you follow this page to update your orb.properties file.

    In the server.properties file, add an additional property clientAuthentication and set it to false. On the server side, you do not need to trust the client.

    clientAuthentication=false

  3. Run the application

    The commands are the same as the commands in the Java SE security tutorial - Step 3 topic.

    Use the following commands to start a catalog server.

    1. Navigate to the bin directory: cd objectgridRoot/bin

    2. Start the catalog server:

        ./startOgServer.sh catalogServer -clusterSecurityFile ../security/security.xml 
        -serverProps ../security/server.properties -JMXServicePort 11001 
        -jvmArgs -Djava.security.auth.login.config="../security/og_jaas.config"
        ./startXsServer.sh catalogServer -clusterSecurityFile ../security/security.xml 
        -serverProps ../security/server.properties -JMXServicePort 11001 
        -jvmArgs -Djava.security.auth.login.config="../security/og_jaas.config"

      The security.xml and server.properties files were created in the Java SE security tutorial - Step 2 page.

      Use the -JMXServicePort option to explicitly specify the JMX port for the server. This option is required to use the xscmd utility.

      Run a secure ObjectGrid container server:

    3. Navigate to the bin directory again: cd objectgridRoot/bin

      • ./startOgServer.sh c0 -objectGridFile ../xml/SecureSimpleApp.xml 
        -deploymentPolicyFile ../xml/SimpleDP.xml -catalogServiceEndPoints 
        localhost:2809 -serverProps ../security/server.properties 
        -JMXServicePort 11002 -jvmArgs 
        -Djava.security.auth.login.config="../security/og_jaas.config" 
        -Djava.security.policy="../security/og_auth.policy"

      • ./startXsServer.sh c0 -objectGridFile ../xml/SecureSimpleApp.xml 
        -deploymentPolicyFile ../xml/SimpleDP.xml -catalogServiceEndPoints 
        localhost:2809 -serverProps ../security/server.properties 
        -JMXServicePort 11002 -jvmArgs 
        -Djava.security.auth.login.config="../security/og_jaas.config" 
        -Djava.security.policy="../security/og_auth.policy"

    Notice the following differences from the previous container server start command:

    • Use the SecureSimpleApp.xml instead of SimpleApp.xml files.

    • Add another -Djava.security.policy to set the JAAS authorization policy file to the container server process.

    Run the following command for client authentication:

    1. cd objectgridRoot/bin

      • javaHome/java -classpath ../lib/objectgrid.jar:../applib/sec_sample.jar 
        com.ibm.websphere.objectgrid.security.sample.guide.SecureSimpleApp 
        ../security/client.properties manager manager1

      • javaHome\java -classpath ..\lib\objectgrid.jar;..\applib\sec_sample.jar 
        com.ibm.websphere.objectgrid.security.sample.guide.SecureSimpleApp 
        ..\security\client.properties manager manager1

    2. Because user "manager" has permission to all the maps in the accounting ObjectGrid, the application runs successfully.

    Use the xscmd utility to show the map sizes of the "accounting" grid.

    • Navigate to the directory objectgridRoot/bin.

    • Use the xscmd command to show the map sizes:

      • ./xscmd.sh -c showMapsizes -g accounting -m customer -prot SSL 
        -ts ../security/trust.jks -tsp ogpass -tst jks 
        -user manager -pwd manager1 -ks ../security/key.jks -ksp ogpass -kst JKS 
        -cxpv IBMJSSE2 -tt SSL-Required
        

      Notice we specify the JMX port of the catalog service using -p 11001 here.

      You see the following output.

      This administrative utility is provided as a sample only and is not to 
      be considered a fully supported component of the WXS product.
      Connecting to Catalog service  at localhost:1099
      *********** Displaying Results for Grid - accounting, MapSet - customer ***********
      *** Listing Maps for c0 ***
      Map Name: customer Partition #: 0 Map Size: 1 Shard Type: Primary
      Server Total: 1
      Total Domain Count: 1

    Running the application with an incorrect keystore

    If your truststore does not contain the public certificate of the private key in the keystore, an exception that the key cannot be trusted occurs.

    To show this exception, create another keystore key2.jks.

    keytool -genkey -alias ogsample -keystore key2.jks -storetype JKS -keyalg rsa -dname "CN=ogsample, OU=Your Organizational Unit, O=Your Organization, L=Your City, S=Your State, C=Your Country" -storepass ogpass -keypass ogpass -validity 3650

    Then modify the server.properties file to make the keyStore point to this new keystore key2.jks:

    keyStore=../security/key2.jks

    Run the following command to start the catalog server:

    1. Navigate to bin: cd objectgridRoot/bin

    2. Start the catalog server:

      • ./startOgServer.sh c0 -objectGridFile ../xml/SecureSimpleApp.xml 
        -deploymentPolicyFile ../xml/SimpleDP.xml -catalogServiceEndPoints localhost:2809 
        -serverProps ../security/server.properties -jvmArgs 
        -Djava.security.auth.login.config="../security/og_jaas.config" 
        -Djava.security.policy="../security/og_auth.policy"

      • ./startXsServer.sh c0 -objectGridFile ../xml/SecureSimpleApp.xml 
        -deploymentPolicyFile ../xml/SimpleDP.xml -catalogServiceEndPoints localhost:2809 
        -serverProps ../security/server.properties -jvmArgs 
        -Djava.security.auth.login.config="../security/og_jaas.config" 
        -Djava.security.policy="../security/og_auth.policy"

      You see the following exception:

      Caused by: com.ibm.websphere.objectgrid.ObjectGridRPCException:
          com.ibm.websphere.objectgrid.ObjectGridRuntimeException:
              SSL connection fails and plain socket cannot be used.

      Finally, change the server.properties file back to use the key.jks file.




Tutorial: Run eXtreme Scale clients and servers in the Liberty profile

We can run WXS as a client in the Liberty profile that WebSphere Application Server (WAS) provides.

In this tutorial, we can expect to complete the following learning objectives:

The Liberty profile is a highly composable, fast-to-start, dynamic application server runtime environment.

You install the Liberty profile when you install WXS with WAS Version 8.5. Because the Liberty profile does not include a Java runtime environment (JRE), you have to install a JRE provided by either Oracle or IBM.

For more information about supported Java environments and locations, see Minimum supported Java levels in the WAS Information Center.

This server supports two models of application deployment:

The Liberty profile supports a subset of the following parts of the full WAS programming model:

Associated services such as transactions and security are only supported as far as is required by these application types and by JPA.

Features are the units of capability by which you control the pieces of the runtime environment that are loaded into a particular server. The Liberty profile includes the following main features:

We can work with the runtime environment directly, or using the WAS Developer Tools for Eclipse.

On distributed platforms, the Liberty profile provides both a development and an operations environment. On the Mac, it provides a development environment.

On z/OS systems, the Liberty profile provides an operations environment. We can work natively with this environment using the MVS. console. For application development, consider using the Eclipse-based developer tools on a separate distributed system, on Mac OS, or in a Linux shell on z/OS.


Run the Liberty profile with a third-party JRE

When you use a JRE that Oracle provides, special considerations must be taken to run WXS with the Liberty profile.

Classloader deadlock

You might experience a classloader deadlock which has been worked around using the following JVM_ARGS settings. If you experience a deadlock in BundleLoader logic, add the following arguments:
export JVM_ARGS="$JVM_ARGS -XX:+UnlockDiagnosticVMOptions -XX:+UnsyncloadClass"

IBM ORB

WXS requires that you use the IBM ORB, which is included in a WAS installation, but not in the Liberty profile. Set the endorsed directories using the Java system property, java.endorsed.dirs, to add the directory containing the IBM ORB JAR files. The IBM ORB JAR files are included in the eXtreme Scale installation in the wlp\wxs\lib\endorsed directory.


Module 1: Install the Liberty profile

Install WAS Version 8.5 to obtain the Liberty profile.

To install the Liberty profile, use Installation Manager to install WAS Version 8.5 with WXS, or we can install the Liberty profile by running a provided JAR file. We can download and install the Liberty profile application-serving environment and included JAR file from the WASdev community downloads page .


Module 2: Create a web application server in the Liberty profile

Create a server directory and server.xml file to develop the server definition for the Liberty profile.

To complete this module, install the Liberty profile.


Lesson 2.1: Define a server to run in the Liberty profile

Create a server directory and server definition file to run in the Liberty profile.

To create the server definition for the web application server, enter the following command from your bin directory:

wlp home/bin/server create your_server_name

To verify that you created the server definition file, search for the XML file in the following directory: wlp_home/usr/servers/your_server_name.

We can find server.xml under your server definition, and open the file in an editor. A commented feature manager stanza exists in the server.xml. In the next module, you will add the web feature to this stanza of the server definition.


Module 3: Add the Liberty web feature to the Liberty profile

Add the web feature to your server definition to identify web-based applications and add functions, such as session replication.

To complete this module, you must complete the following modules first


Lesson 3.1: Define a web application to run in the Liberty profile

Define the web feature to your server definition to enable application functions, such as session replication.

The web feature is deprecated. Use the webApp feature when we want to replicate HTTP session data for fault tolerance.

The webApp feature has meta type properties that we can set on the xsWebApp element of server.xml.

Add the following web feature to the Liberty profile server.xml file. The web feature includes the client feature; however, it does not include the server feature. You likely want to separate your web applications from the data grids. For example, you have one Liberty profile server for your web applications and a different Liberty profile server for hosting the data grid.

<featureManager>
<feature>eXtremeScale_web-1.0</feature>
</featureManager>

Your web applications can now persist its session data in a WXS grid.

See the following example of a server.xml file, which contains the web feature that you use when you connect to the data grid remotely.

<server description="Airport Entry eXtremeScale Getting Started Client Web Server">
<!-- 
 This sample program is provided AS IS and may be used, executed, copied and modified
 without royalty payment by customer
 (a) for its own instruction and study,
 (b) to develop applications designed to run with an IBM WebSphere product,
 either for customer's own internal use or for redistribution by customer, as part of such an
 application, in customer's own products.
 Licensed Materials - Property of IBM
 5724-X67, 5655-V66 (C) COPYRIGHT International Business Machines Corp. 2012
-->
    <!-- Enable features -->
    <featureManager>
        <feature>servlet-3.0</feature>
        <feature>jsp-2.2</feature>
        <feature>eXtremeScale.web-1.1</feature>
    </featureManager>

    <httpEndpoint id="defaultHttpEndpoint"
        host="*"
        httpPort="${default.http.port}"
        httpsPort="${default.https.port}" />

     <xsWebAppV85 objectGridType="REMOTE" objectGridName="session" catalogHostPort="remoteHost:2809" securityEnabled="false" /> 
  
</server>


Module 4: Configure clients to use client APIs in the Liberty profile

We can configure your WXS clients to run in the Liberty profile.

To complete this module, you must complete the following modules first:


Lesson 4.1: Configure the Liberty profile to run with WXS clients

Use the WXS client feature to run the Liberty profile with WXS clients.

This configuration provides only the client functionality. In this application, the server function runs in another process. Adding the client feature allows the application to access the eXtreme Scale APIs and connect to a remote grid. This client configuration provides a single process that includes what you need to unit test a web application using a WXS data grid. When you add the client feature, it starts a catalog server and a container server when the configuration is deployed into the grid directory. In addition, after you add the client feature, the application can write to the eXtreme Scale APIs.

  1. Add the client feature to the Liberty server. Add the following code to the Liberty server:
    <server description="eXtreme Scale Container Server">
    
    <featureManager>
    <feature>eXtremeScale.client-1.1</feature>
    </featureManager>
    
    
    </server>

  2. (Optional) Alternatively, we can use the eXtreme Scale server feature to reference the client configuration. When you add the following server configuration, the client functionality is automatically included:
    <server description="eXtreme Scale Container Server">
    
    <featureManager>
    <feature>eXtremeScale.server-1.1</feature>
    </featureManager>
    
    
    </server>

  3. (Optional) To configure security for your clients, then use the client.xml file to specify the path to the server properties file, which contains all of the security settings.

You configured the Liberty profile by adding the client feature to the Liberty server.


Module 5: Run the data grid inside the Liberty profile

After you add the client and server configurations to the Liberty profile, we can run WXS in the Liberty profile.

To complete this module, you must complete the following modules in this tutorial:


Lesson 5.1: Configure eXtreme Scale servers to use the Liberty profile

To run the data grid in a Liberty profile, add the server feature to configure WXS servers that use Liberty profile configuration files.

  1. Configure a catalog server with default settings using the following attributes in server.xml, which tells eXtreme Scale to create and start a catalog server:
    <server description="eXtreme Scale Catalog Server with default settings">
    
        <!-- Enable features -->
        <featureManager>
            <feature>eXtremeScale.server-1.1</feature>
        </featureManager>
    
        <xsServer isCatalog="true" listenerPort="${com.ibm.ws.xs.server.listenerPort}" />
    
        <logging traceSpecification="*=info" maxFileSize="200" maxFiles="10" />
    
    </server>

    Notice that the listenerPort element is referenced in the server.xml; however, you configure this value in the bootstrap.properties file. It can be useful to separate elements such as port numbers out of server.xml so that multiple processes that run with an identical configuration can share server.xml, but still have unique settings.

  2. Configure the listenerPort attribute in the bootstrap.properties file.

    In the previous example, tracing is specified in the Liberty profile configuration, and the listenerPort attribute specifies a variable. This variable is configured in the bootstrap.properties file in the server configuration directory, wlp_install_root/usr/server/serverName. See the following example of the bootstrap.properties file:

    # Licensed Materials - Property of IBM
    #
    # "Restricted Materials of IBM"
    #
    # Copyright IBM Corp. 2011 All Rights Reserved.
    #
    # disclosure restricted by GSA ADP Schedule Contract with
    # IBM Corp.
    #
    # ----------------------------------------------------------------
    #
    # port for the OSGi console # osgi.console=5678
    
    com.ibm.ws.xs.server.listenerPort=2809

    In this example, the osgi.console port is commented out, which means that the Liberty profile listens on the specified port for telnet clients to connect to an OSGi console. This behavior is useful for diagnosing OSGi-related errors.

  3. Configure server.xml using the same configuration that you might use for a stand-alone server configuration. In server.xml, specify the file path to the properties file in a serverProps attribute inside the com.ibm.ws.xs.server.config element. See the following example from server.xml:
    <server>
    ...
    <com.ibm.ws.xs.server.config ... serverProps="/path/to/myServerProps.properties" ... />
    </server>

    Restriction: The Liberty configuration model has restrictions in the way properties are specified. Therefore, if you require the following properties, specify them in the server properties file:

    foreignDomain.endpoints
    Names of catalog service domains to which we want to link in the multimaster replication topology.
    xioChannel.xioContainerTCPNonSecure.Port
    Specifies the unsecured listener port number of eXtremeIO on the server. If you do not set the value, an ephemeral port is used. This property is used only when the transportType property is set to TCP/IP. xioChannel.xioContainerTCPSecure.Port.

    Some properties that were formerly configurable in a stand-alone environment must be configured with the Liberty profile configuration instead of the eXtreme Scale configuration mechanisms.

    • Logging and tracing settings must be specified with the logging element in server.xml, rather than being specified in the eXtreme Scale server properties file or com.ibm.ws.xs.server.config element. For more information, see Liberty profile: Trace and logging in the WAS Information Center.

    • The working directory, like logging and tracing, is a server-wide setting, and therefore, they must be specified in a server-wide way.

    If the previous settings are specified incorrectly, eXtreme Scale logs a warning message, which indicates that the settings are ignored.

  4. (Optional) To configure security with your servers, then use server.xml to specify the path to the server properties file, which contains all of the security settings. When WXS is deployed in a WAS environment, we can simplify the authentication flow and transport layer security configuration from WAS.

Your eXtreme Scale servers are ready to run in the Liberty profile.


Lesson 5.2: Configuring a Liberty profile web application server to use eXtreme Scale for session replication

We can configure a web application server so that when the web server receives an HTTP request for session replication, the request is forwarded to the Liberty profile.

The Liberty profile does not include session replication. However, if you use WXS with the Liberty profile, then we can replicate sessions. Therefore, if a server fails, then application users do not lose session data.

When you add the webapp feature to the server definition and configure the session manager, we can use session replication in your eXtreme Scale applications that run in the Liberty profile.

Your eXtreme Scale applications that run in the Liberty profile are enabled for session replication.




Tutorial: Integrate WXS security with WAS

This tutorial demonstrates how to secure a WXS server deployment in a WAS environment.

The learning objectives for this tutorial follow:

In this tutorial, you integrate WXS security with WAS. First, you configure authentication with a simple web application that uses authenticated user credentials from the current thread to connect to the ObjectGrid. Then, you investigate the encryption of data that is transferred between the client and server with transport layer security. To give users varying levels of permissions, we can configure Java Authentication and Authorization Service (JAAS). After completing the configuration, we can use the xscmd utility to monitor your data grids and maps.

This tutorial assumes that all of your WXS clients, container servers, and catalog servers are deployed in the WAS environment.


System requirements and topology

This tutorial uses four WAS application servers and one dmgr to demonstrate the sample.

A basic understanding of the following items is helpful before you start this tutorial:

WAS: Securing applications and their environment


Module 1: Prepare WAS

Before you start the tutorial to integrate with WXS, you must create a basic security configuration in WAS.

For this less we will...


Lesson 1.1: Understand the topology and get the tutorial files

To prepare your environment for the tutorial, you must configure WAS security. You configure administration and application security using internal file-based federated repositories as a user account registry.

This lesson guides you through the sample topology and applications used to in the tutorial. To begin running the tutorial, you must download the applications and place the configuration files in the correct locations for your environment. We can download the sample application from the WXS wiki .


WAS sample topology

This tutorial guides you through creating four WAS application servers to demonstrate using the sample applications with security enabled. These application servers are grouped into two clusters, each with two servers:

In this deployment topology, the s1 and s2 application servers are the client servers that access data that is being stored in the data grid. The xs1 and xs2 servers are the container servers that host the data grid.

The catalog server is deployed in the deployment manager process by default. This tutorial uses the default behavior. Hosting the catalog server in the dmgr is not a recommended practice in a production environment. In a production environment, you should create a catalog service domain to define where catalog servers start. See Creating catalog service domains in WAS for more information.

Alternative configuration: We can host all of the application servers in a single cluster, such as in the appCluster cluster. With this configuration, all of the servers in the cluster are both clients and container servers. This tutorial uses two clusters to distinguish between the application servers that are hosting the clients and container servers.

Figure 1. Tutorial topology


Applications

In this tutorial, we are using two applications and one shared library file:


Get the tutorial files

  1. Download the WASSecurity.zip and security.zip files. We can download the sample application from the WXS wiki .

  2. Extract the WASSecurity.zip file to a directory for viewing the binary and source artifacts, for example the /wxs_samples/ directory. This directory is referred to as samples_home for the remainder of the tutorial. For a description of the contents of the WASSecurity.zip file and how to load the source into your Eclipse workspace, see the README.txt file in the package.

  3. Extract the security.zip file to the samples_home directory. The security.zip file contains the following security configuration files used in this tutorial:

    • catServer2.props
    • server2.props
    • client2.props
    • securityWAS2.xml
    • xsAuth2.props


About the configuration files

The objectGrid.xml and objectGridDeployment.xml files create the data grids and maps that store the application data.

These configuration files must be named objectGrid.xml and objectGridDeployment.xml. When the application server starts, eXtreme Scale detects these files in the META-INF directory of the EJB and web modules. If these files are found, it assumed that the JVM acts as a container server for the defined data grids in the configuration files.

objectGrid.xml file

The objectGrid.xml file defined one ObjectGrid named

Grid. The Grid data grid has one map, the Map1 map, that stores the employee profile for the application.

<?xml version="1.0" encoding="UTF-8"?>
<objectGridConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://ibm.com/ws/objectgrid/config ../objectGrid.xsd"
 xmlns="http://ibm.com/ws/objectgrid/config">

 <objectGrids>
        <objectGrid name="Grid" txTimeout="15">
            <backingMap name="Map1" />
        </objectGrid>
    </objectGrids>

</objectGridConfig>

objectGridDeployment.xml file

The objectGridDeployment.xml file specifies how to deploy the Grid data grid. When the grid is deployed, it has five partitions and one synchronous replica.

<?xml version="1.0" encoding="UTF-8"?>

<deploymentPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://ibm.com/ws/objectgrid/deploymentPolicy ../deploymentPolicy.xsd"
 xmlns="http://ibm.com/ws/objectgrid/deploymentPolicy">

    <objectgridDeployment objectgridName="Grid">
        <mapSet name="mapSet" numberOfPartitions="5" minSyncReplicas="0" maxSyncReplicas="1" >
            <map ref="Map1"/>
        </mapSet>
    </objectgridDeployment>

</deploymentPolicy>


Lesson 1.2: Configure the WAS environment

To prepare your environment for the tutorial, you must configure WAS security. Enable administration and application security using internal file-based federated repositories as a user account registry. Then, we can create server clusters to host the client application and container servers.

The following steps were written using WAS Version 7.0. However, we can also apply the concepts apply to earlier versions of WAS.


Configure WAS security

  1. Configure WAS security.

    1. In the WAS administrative console, click Security > Global Security.
    2. Select Federated repositories as the Available realm definition. Click Set as current.
    3. Click Configure.. to go to the Federated repositories panel.
    4. Enter the Primary administrative user name, for example,

      admin. Click Apply.

    5. When prompted, enter the administrative user password and click OK. Save your changes.
    6. On the Global Security page, verify that Federated repositories setting is set to the current user account registry.
    7. Select the following items: Enable administrative security, Enable application security, and Use Java 2 security to restrict application access to local resources. Click Apply and save your changes.
    8. Restart the dmgr and any running application servers.

    The WAS administrative security is enabled using the internal file-based federated repositories as the user account registry.

  2. Create two user groups: adminGroup and operatorGroup.

    1. Click Users and groups > Manage groups > Create...
    2. Type

      adminGroup as the group name. Enter

      Administration group as the description. Click Create.

    3. Click Create alike. Type

      operatorGroup as the group name. Enter

      Operator group as the description. Click Create.

    4. Click Close.

  3. Create users

    admin1 and

    operator1.

    1. Click Users and groups > Manage users > Create...
    2. Create a user called

      admin1 with the first name

      Joe and last name

      Doe with the password

      admin1. Click Create.

    3. Create a second user. Click Create alike to create a a user called

      operator1 with the first name

      Jane and last name

      Doe with the password

      operator1. Click Create. Click Close.

  4. Add users to the user groups. Add the admin1 user to the adminGroup and the operator1 user to the operatorGroup.

    1. Click Users and groups > Manage users.
    2. Search for users to add to groups. Click Search.. and set the search for value to an asterisk (*) to display all the users.
    3. From the search result, click the admin1 user, and click the Groups tab. Click Add to add the group.
    4. Search the groups to find the available groups. Click the adminGroup and click Add.
    5. Repeat these steps to add the operator1 user to the operatorGroup user group.

  5. Save your changes, log out of the administrative console, and restart the dmgr and node agent to enable the security settings.

You enabled security and created users and user groups have administrative and operator access to your WAS configuration.


Create server clusters

Create two server clusters in your WAS configuration: The appCluster cluster to host the sample application for the tutorial and the xsCluster cluster to host the data grid.

  1. In the WAS administrative console, open the clusters panel. Click Servers > Clusters > WebSphere application server clusters > New.
  2. Type

    appCluster as the cluster name, leave the Prefer local option selected, and click Next.

  3. Create servers in the cluster. Create a server named

    s1, keeping the default options. Add an additional cluster member named

    s2.

  4. Complete the remaining steps in the wizard to create the cluster. Save the changes.
  5. Repeat these steps to create the xsCluster cluster. This cluster has two servers, named

    xs1 and

    xs2.


Module 2: Configure WXS to use WAS Authentication plug-ins

After you have created the WAS configuration, we can integrate WXS authentication with WAS.

When a WXS client connects to a container server that requires authentication, the client must provide a credential generator represented by the com.ibm.websphere.objectgrid.security.plugins.CredentialGenerator interface. A credential generator is a factory to create a client credential. A client credential can be: a user name and password pair, a Kerberos ticket, a client certificate, or client identification data in any format that the client and server agree upon. See the Credential API documentation for more details. In this sample, the WXS client is the EmployeeManagment web application that is deployed in the appCluster cluster. The client credential is a WebSphere security token that represents the web user identity.

With the lessons in this module, you learn how to:


Lesson 2.1: Configure client server security

The client properties file indicates the CredentialGenerator implementation class to use.

Configure the client properties file with the -Dobjectgrid.client.props JVM property. The file name specified for this property is an absolute file path, such as samples_home /security/client2.props. See Client properties file for more information about the client properties file.

Module 2: Configure WXS to use WAS Authentication plug-ins

Credential API documentation


Client properties file contents

This example uses WAS security tokens as the client credential. The client2.props file is in the samples_home /security directory. The client2.props file includes the following settings:

securityEnabled

When set to true, indicates that the client must send available security information to the server.

credentialAuthentication

When set to Supported, indicates that the client supports credential authentication.

credentialGeneratorClass

Indicates the com.ibm.websphere.objectgrid.security.plugins.builtins.WSTokenCredentialGenerator class so the client retrieves the security tokens from the thread. See Security integration with WAS for more information about how security tokens are retrieved.


Setting the client properties file using Java virtual machine (JVM) properties

In the administrative console, complete the following steps to both the s1 and

s2 servers in the appCluster cluster. If we are using a different topology, complete the following steps to all of the application servers to which the EmployeeManagement application is deployed.

  1. Servers > WebSphere application servers > server_name > Java and Process Management > Process definition > Java Virtual Machine.

  2. Create the following generic JVM property to set the location of the client properties file:
    -Dobjectgrid.client.props=samples_home /security/client2.props

  3. Click OK and save your changes.


Lesson 2.2: Configure catalog server security

A catalog server contains two different levels of security information: The security properties that are common to all the WXS servers, including the catalog service and container servers, and the security properties that are specific to the catalog server.

The security properties that are common to the catalog servers and container servers are configured in the security XML descriptor file. An example of common properties is the authenticator configuration, which represents the user registry and authentication mechanism. See Security descriptor XML file for more information about the security properties.

To configure the security XML descriptor file, create a -Dobjectgrid.cluster.security.xml.url property in the Java virtual machine (JVM) argument. The file name specified for this property is in an URL format, such as file:///samples_home /security/securityWAS2.xml.

Module 2: Configure WXS to use WAS Authentication plug-ins


securityWAS2.xml file

In this tutorial, the securityWAS2.xml file is in the samples_home /security directory. The content of the securityWAS2.xml file with the comments removed follows:

<securityConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://ibm.com/ws/objectgrid/config/security ../objectGridSecurity.xsd"
 xmlns="http://ibm.com/ws/objectgrid/config/security">

 <security securityEnabled="true">
  <authenticator
 className="com.ibm.websphere.objectgrid.security.plugins.builtins.WSTokenAuthenticator">
  </authenticator>
 </security>
</securityConfig>
The following properties are defined in the securityWAS2.xml file:

securityEnabled

The securityEnabled property is set to true, which indicates to the catalog server that the WXS global security is enabled.

authenticator

The authenticator is configured as the com.ibm.websphere.objectgrid.security.plugins.builtins.WSTokenAuthenticator class. With this built-in implementation of the Authenticator plug-in, the WXS server can convert the security tokens to a Subject object. See Security integration with WAS for more information about how the security tokens are converted.


catServer2.props file

The server property file stores the server-specific properties, which include the server-specific security properties. See Server properties file for more information. We can configure the server property file with the -Dobjectgrid.server.props property in the JVM argument. Specify the file name value for this property is an absolute path, such as samples_home /security/catServer2.props. For this tutorial, a catServer2.props file is included in the samples_home /security directory. The content of the catServer2.props file with comments removed follows:

securityEnabled

The securityEnabled property is set to true to indicate that this catalog server is a secure server.

credentialAuthentication

The credentialAuthentication property is set to Required, so any client that is connecting to the server is required to provide a credential.

secureTokenManagerType

The secureTokenManagerType is set to none to indicate that the authentication secret is not encrypted when joining the existing servers.

authenticationSecret

The authenticationSecret property is set to ObjectGridfalse Secret. This secret string is used to join the eXtreme Scale server cluster. When a server joins the data grid, it is challenged to present the secret string. If the secret string of the joining server matches the string in the catalog server, the joining server is accepted. If the string does not match, the join request is rejected.

transportType

The transportType property is set to TCP/IP initially. Later in the tutorial, transport security is enabled.


Setting the server properties file with JVM properties

Set the server properties file on the dmgr server. If we are using a different topology than the topology for this tutorial, set the server properties file on all of the application servers that we are using to host container servers.

  1. Open the Java virtual machine configuration for the server. In the administrative console, click System administration > Deployment manager > Java and Process Management > Process definition > Java Virtual Machine.

  2. Add the following generic JVM arguments:
    -Dobjectgrid.cluster.security.xml.url=file:///samples_home /security/securityWAS2.xml 
    -Dobjectgrid.server.props=samples_home /security/catServer2.props

  3. Click OK and save your changes.


Lesson 2.3: Configure container server security

When a container server connects to the catalog service, the container server gets all the security configurations that are configured in the Object Grid Security XML file, such as authenticator configuration, the login session timeout value, and other configuration information. A container server also has its own server-specific security properties in the server property file.

Configure the server property file with the -Dobjectgrid.server.props Java virtual machine (JVM) property. The file name for this property is an absolute file path, such as samples_home /security/server2.props.

In this tutorial, the container servers are hosted in the xs1 and

xs2 servers in the xsCluster cluster.


server2.props file

The server2.props file is in the samples_home/security directory under the WASSecurity directory. The properties that are defined in the server2.props file follow:

securityEnabled

The securityEnabled property is set to true to indicate that this container server is a secure server.

credentialAuthentication

The credentialAuthentication property is set to Required, so any client that is connecting to the server is required to provide a credential.

secureTokenManagerType

The secureTokenManagerType is set to none to indicate that the authentication secret is not encrypted when joining the existing servers.

authenticationSecret

The authenticationSecret property is set to ObjectGridfalse Secret. This secret string is used to join the eXtreme Scale server cluster. When a server joins the data grid, it is challenged to present the secret string. If the secret string of the joining server matches the string in the catalog server, the joining server is accepted. If the string does not match, the join request is rejected.


Setting the server properties file with JVM properties

Set the server properties file on the xs1 and xs2 servers. If we are not using the topology for this tutorial, set the server properties file on all of the application servers that we are using to host container servers.

  1. Open the Java virtual machine page for the server. Servers > Application servers > server_name > Java and Process Management > Process definition > Java Virtual Machine

  2. Add the generic JVM arguments:
    -Dobjectgrid.server.props=samples_home /security/server2.props

  3. Click OK and save your changes.


Lesson 2.4: Install and run the sample

After authentication is configured, we can install and run the sample application.


Create a shared library for the EmployeeData.jar file

  1. In the WAS administrative console, open the Shared Libraries page. Click Environment > Shared libraries.

  2. Choose the cell scope.

  3. Create the shared library. Click New. Enter

    EmployeeManagementLIB as the Name. Enter the path to the EmployeeData.jar in the classpath, for example, samples_home /WASSecurity/EmployeeData.jar.

  4. Click Apply.


Installing the sample

  1. Install the EmployeeManagement.ear file.

    1. To begin the installation, click Applications > New application > New Enterprise Application. Choose the detailed path for installing the application.

    2. On the Map modules to servers step, specify the appCluster cluster to install the EmployeeManagementWeb module.

    3. On the Map shared libraries step, select the EmployeeManagementWeb module.

    4. Click Reference shared libraries. Select the EmployeeManagementLIB library.

    5. Map the webUser role to All Authenticated in Application's Realm.

    6. Click OK.

    The clients run in the s1 and

    s2 servers in this cluster.

  2. Install the sample XSDeployment.ear file.

    1. To begin the installation, click Applications > New application > New Enterprise Application. Choose the detailed path for installing the application.

    2. On the Map modules to servers step, specify the xsCluster cluster to install the XSDeploymentWeb web module.

    3. On the Map shared libraries step, select the XSDeploymentWeb module.

    4. Click Reference shared libraries. Select the EmployeeManagementLIB library.

    5. Click OK.

    The xs1 and

    xs2 servers in this cluster host the container servers.

  3. Restart the dmgr. When the deployment manager starts, the catalog server also starts. If you look at the SystemOut.log file of the dmgr, we can see the following message that indicates that the eXtreme Scale server properties file is loaded.
    CWOBJ0913I: Server property files have been loaded: 
    /wxs_samples/security/catServer2.props.

  4. Restart the xsCluster cluster. When the xsCluster starts, the XSDeployment application starts, and a container server is started on the xs1 and xs2 servers respectively. If you look at the SystemOut.log file of the xs1 and xs2 servers, the following message that indicates the server properties file is loaded is displayed:
    CWOBJ0913I: Server property files have been loaded: 
    /wxs_samples/security/server2.props.

  5. Restart the appClusters cluster. When the cluster appCluster starts, the EmployeeManagement application also starts. If you look at the SystemOut.log file of the s1 and s2 servers, we can see the following message that indicates that the client properties file is loaded.
    CWOBJ0924I: The client property file {0} has been loaded.

    We can ignore the warning messages regarding the authenticationRetryCount, transportType, and clientCertificateAuthentication properties. The default values are be used because the values were not specified in the properties file. If we are using  WXS Version 7.0, the English-only CWOBJ9000I message displays to indicate that the client property file has been loaded. If you do not see the expected message, verify that you configured the -Dobjectgrid.server.props or -Dobjectgrid.client.props property in the JVM argument. If you do have the properties configured, make sure the dash (-) is a UTF character.


Run the sample application

  1. Run the management.jsp file. In a web browser, access

    http://<your_servername>:<port>/EmployeeManagementWeb/management.jsp. For example, you might use the following URL:

    http://localhost:9080/EmployeeManagementWeb/management.jsp.

  2. Provide authentication to the application. Enter the credentials of the user that you mapped to the webUser role. By default, this user role is mapped to all authenticated users. Type

    admin1 as your user ID and

    admin1 as your password. A page to display, add, update, and delete employees displays.

  3. Display employees. Click Display an Employee. Enter

    emp1@acme.com as the email address, and click Submit. A message displays that the employee cannot be found.

  4. Add an employee. click Add an Employee. Enter

    emp1@acme.com as the email address, enter

    Joe as the first name, and

    Doe as the last name. Click Submit. A message displays that an employee with the emp1@acme.com address has been added.

  5. Display the new employee. Click Display an Employee. Enter

    emp1@acme.com as the email address with empty fields for the first and last names, and click Submit. A message displays that the employee has been found, and the correct names are displayed in the first name and last name fields.

  6. Delete the employee. Click Delete an employee. Enter

    emp1@acme.com and click Submit. A message is displayed that the employee has been deleted.


Module 3: Configure transport security

Configure transport security to secure data transfer between the clients and servers in the configuration.

In the previous module in the tutorial, you enabled WXS authentication. With authentication, any application that tries to connect to the WXS server is required to provide a credential. Therefore, no unauthenticated client can connect to the WXS server. The clients must be an authenticated application running in a WAS cell.

With the configuration up to this module, the data transfer between the clients in the appCluster cluster and servers in the xsCluster cluster is not encrypted. This configuration might be acceptable if your WAS clusters are installed on servers behind a firewall. However, in some scenarios, non-encrypted traffic is not accepted for some reasons even though the topology is protected by firewall. For example, a government policy might enforce encrypted traffic. WXS supports Transport Layer Security/Secure Sockets Layer (TLS/SSL) for secure communication between ObjectGrid endpoints, which include client servers, container servers, and catalog servers.

In this sample deployment, the eXtreme Scale clients and container servers are all running in the WAS environment. Client or server properties are not necessary to configure the SSL settings because the eXtreme Scale transport security is managed by the Application Server Common Secure Interoperability Protocol Version 2 (CSIV2) transport settings. WXS servers use the same Object Request Broker (ORB) instance as the application servers in which they run. Specify all the SSL settings for client and container servers in the WAS configuration using these CSIv2 transport settings. The catalog server has its own proprietary transport paths that do not use Internet Inter-ORB Protocol (IIOP) or Remote Method Invocation (RMI). Because of these proprietary transport paths, the catalog server cannot be managed by the WAS CSIV2 transport settings. Therefore, configure the SSL properties in the server properties file for the catalog server.

This step of the tutorial builds upon the previous modules. Complete the previous modules in this tutorial before you configure transport security.


Lesson 3.1: Configure CSIv2 inbound and outbound transport

To configure Transport Layer Security/Secure Sockets Layer (TLS/SSL) for the server transport, set the Common Secure Interoperability Protocol Version 2 (CSIv2) inbound transport and CSIv2 outbound transport to SSL-Required for all the WAS servers that host clients, catalog servers, and container servers.

In the tutorial example topology, set these properties for the, s1, s2, xs1, and xs2 application servers. The following steps configure the inbound and outbound transports for all the servers in the configuration.

Set the inbound and outbound transports in the administrative console. Make sure that administrative security is enabled.

Use centrally managed endpoint security settings, or we can configure SSL repositories. See Common Secure Interoperability Version 2 transport inbound settings for more information.


Lesson 3.2: Add SSL properties to the catalog server properties file

The catalog server has its own proprietary transport paths that cannot be managed by the WAS Common Secure Interoperability Protocol Version 2 (CSIV2) transport settings. Therefore, you must configure the SSL properties in the server properties file for the catalog server.

To configure catalog server security, additional steps are necessary because the catalog server has its own proprietary transport paths. These transport paths cannot be managed by the Application Server CSIV2 transport settings.

  1. Edit the SSL properties in the catServer2.props file. To configure catalog server security, uncomment the following SSL properties in the catalog server properties file. For this tutorial, the catalog server properties are in the catServer2.props file. Update the keyStore and trustStore properties to refer to the proper location in your environment.
    #alias=default
    #contextProvider=IBMJSSE2
    #protocol=SSL
    #keyStoreType=PKCS12
    #keyStore=/<WAS_HOME>/IBM/WebSphere/AppServer/profiles/<DMGR_NAME>/config/
    cells/<CELL_NAME>/nodes/<NODE_NAME>/key.p12 
    #keyStorePassword=WebAS
    #trustStoreType=PKCS12
    #trustStore=/<WAS_HOME>/IBM/WebSphere/AppServer/profiles/<DMGR_NAME>/config/
    cells/<CELL_NAME>/nodes/<NODE_NAME>/trust.p12
    #trustStorePassword=WebAS
    #clientAuthentication=false
    

    The catServer2.props file is using the default WAS node level keystore and truststore. If we are deploying a more complex deployment environment, you must choose the correct keystore and truststore. In some cases, you must create a keystore and truststore and import the keys from keystores from the other servers. Notice that the WebAS string is the default password of the WAS keystore and truststore.

  2. In the catServer2.props file, update the value of the transportType property. For previous steps of the tutorial, the value was set to TCP/IP. Change the value to SSL-Required.

  3. Restart the dmgr to activate the changes to the catalog server security settings.


Lesson 3.3: Run the sample

Restart all the servers and run the sample application again. You should be able to run through the steps without any problems.

See Lesson 2.4: Install and run the sample for more information about running and installing the sample application.


Module 4: Use Java Authentication and Authorization Service (JAAS) authorization in WAS

Now configured authentication for clients, we can further configure authentication to give different users varying permissions. For example, an operator user might only be able to view data, while an administrator user can perform all operations.

After authenticating a client, as in the previous module in this tutorial, we can give security privileges through eXtreme Scale authorization mechanisms. The previous module of this tutorial demonstrated how to enable authentication for a data grid using integration with WAS. As a result, no unauthenticated client can connect to the eXtreme Scale servers or submit requests to your system. However, every authenticated client has the same permission or privileges to the server, such as reading, writing, or deleting data that is stored in the ObjectGrid maps. Clients can also issue any type of query.

This part of the tutorial demonstrates how to use eXtreme Scale authorization to give authenticated users varying privileges. WXS uses a permission-based authorization mechanism. We can assign different permission categories that are represented by different permission classes. This module features the MapPermission class.

In WXS, the com.ibm.websphere.objectgrid.security.MapPermission class represents permissions to the eXtreme Scale resources, specifically the methods of the ObjectMap or JavaMap interfaces. WXS defines the following permission strings to access the methods of ObjectMap and JavaMap:

read Grant permission to read the data from the map.
write Grant permission to update the data in the map.
insert Grant permission to insert the data into the map.
remove Grant permission to remove the data from the map.
invalidate Grant permission to invalidate the data from the map.
all Grant all permissions to read, write, insert, remote, and invalidate.

The authorization occurs when a WXS client uses a data access API, such as the ObjectMap,JavaMap, or EntityManager APIs. The run time checks corresponding map permissions when the method is called. If the required permissions are not granted to the client, an AccessControlException exception results. This tutorial demonstrates how to use Java Authentication and Authorization Service (JAAS) authorization to grant authorization map access for different users.

After completing the lessons in this module, you know how to:

Complete the prior modules in this tutorial before configuring authentication.


Lesson 4.1: Enable WXS authorization

To enable authorization in WXS, enable security on a specific ObjectGrid.

To enable authorization on the ObjectGrid, you must set the securityEnabled attribute to true for that particular ObjectGrid in the XML file. For this tutorial, we can either use the XSDeployment_sec.ear file in the samples_home /WASSecurity directory, which has already has security set in the objectGrid.xml file, or we can edit the existing objectGrid.xml file to enable security. This lesson demonstrates how to edit the file to enable security.

  1. Extract the files in the XSDeployment.ear file, and then unzip the XSDeploymentWeb.war file.

  2. Open the objectGrid.xml file and set the securityEnabled attribute to true on the ObjectGrid level. See an example of this attribute in the following example:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <objectGridConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://ibm.com/ws/objectgrid/config ../objectGrid.xsd"
     xmlns="http://ibm.com/ws/objectgrid/config">
    
        <objectGrids>
            <objectGrid name="Grid" securityEnabled="true">
                <backingMap name="Map1" />
            </objectGrid>
        </objectGrids>
    
    </objectGridConfig>
    If you have multiple ObjectGrids defined, then set this attribute on each data grid.

  3. Repackage the XSDeploymentWeb.war and XSDeployment.ear files to include your changes. Name the file XSDeployment_sec.ear so you do not overwrite the original package.

  4. Uninstall the existing XSDeployment application and install the XSDeployment_sec.ear file. See Lesson 2.4: Install and run the sample for more information about deploying applications.


Lesson 4.2: Enable user-based authorization

In the authentication module of this tutorial, you created two users: 

operator1 and

admin1. We can assign varying permissions to these users with Java Authentication and Authorization Service (JAAS) authorization.


Defining the Java Authentication and Authorization Service (JAAS) authorization policy using user principals

We can assign permissions to the users that you previously created. Assign the operator1 user read permissions only to all maps. Assign the admin1 user all permissions. Use the JAAS authorization policy file to grant permissions to principals.

Edit the JAAS authorization file. The xsAuth2.policy file is in the samples_home /security directory:

grant codebase http://www.ibm.com/com/ibm/ws/objectgrid/security/PrivilegedAction
Principal com.ibm.ws.security.common.auth.WSPrincipalImpl "defaultWIMFileBasedRealm/operator1" {
    permission com.ibm.websphere.objectgrid.security.MapPermission "Grid.Map1", "read";};

grant codebase http://www.ibm.com/com/ibm/ws/objectgrid/security/PrivilegedAction
Principal com.ibm.ws.security.common.auth.WSPrincipalImpl "defaultWIMFileBasedRealm/admin1" {
    permission com.ibm.websphere.objectgrid.security.MapPermission "Grid.Map1", "all";};
In this file, the http://www.ibm.com/com/ibm/ws/objectgrid/security/PrivilegedAction codebase is a specially reserved URL for ObjectGrid. All ObjectGrid permissions that are granted to principals should use this special code base. The following permissions are assigned in this file:


Setting the JAAS authorization policy file using JVM properties

Use the following steps to set JVM properties for the xs1 and xs2 servers, which are in the xsCluster cluster. If we are using a topology that is different from the sample topology used in this tutorial, set the file on all of your container servers.

  1. In the administrative console, click Servers > Application servers > server_name > Java and Process Management > Process definition > Java Virtual Machine.

  2. Add the following generic JVM arguments:
    -Djava.security.policy=samples_home /security/xsAuth2.policy

  3. Click OK and save your changes.


Run the sample application to test authorization

Use the sample application to test the authorization settings. The administrator user continues to have all permissions in the Map1 map, including displaying and adding employees. The operator user should only be able to view employees because that user was assigned read permission only.

  1. Restart all of the application servers running container servers.

  2. Open the EmployeeManagementWeb application. In a web browser, open

    http://<host>:<port>/EmployeeManagermentWeb/management.jsp.

  3. Log in to the application as an administrator. Use the user name

    admin1 and password

    admin1.

  4. Attempt to display an employee. Click Display an Employee and search for the authemp1@acme.com email address. A message displays that the user cannot be found.

  5. Add an employee. Click Add an Employee. Add the email

    authemp1@acme.com, the first name

    Joe, and the last name

    Doe. Click Submit. A message displays that the employee has been added.

  6. Log in as the operator user. Open a second Web browser window and open

    http://<host>:<port>/EmployeeManagermentWeb/management.jsp. Use the user name

    operator1 and password

    operator1.

  7. Attempt to display an employee. Click Display an Employee and search for the authemp1@acme.com email address. The employee is displayed.

  8. Add an employee. Click Add an Employee. Add the email

    authemp2@acme.com, the first name

    Joe, and the last name

    Doe. Click Submit. The following message displays:

    An exception occurs when Add the employee. See below for detailed exception messages.
    The following exception is in the exception chain:
    java.security.AccessControlException: Access denied 
    (com.ibm.websphere.objectgrid.security.MapPermission Grid.Map1 insert)
    This message displays because the operator1 user does not have permission to insert data into the Map1 map.

If we are running with a version of WAS that is earlier than Version 7.0.0.11, you might see a java.lang.StackOverflowError error on the container server. This error is caused by a problem with the IBM Developer Kit. The problem is fixed in the IBM Developer Kit that is shipped with WAS Version 7.0.0.11 and later.


Lesson 4.3: Configure group-based authorization

In the previous lesson, you assigned individual user-based authorization with user principals in the Java Authentication and Authorization Service. (JAAS) authorization policy. However, when you have hundreds or thousands of users, use group-based authorization, which authorizes access based on groups instead of individual users.

Unfortunately, the Subject object that is authenticated from the WAS only contains a user principal. This object does not contain a group principal. We can add a custom login module to populate the group principal into the Subject object.

For this tutorial, the custom login module is named com.ibm.websphere.samples.objectgrid.security.lm.WASAddGroupLoginModule. The module is in the groupLM.jar file. Place this JAR file in the WAS-INSTALL/lib/ext directory.

The WASAddGroupLoginModule retrieves the public group credential from the WAS subject and creates a Group principal, com.ibm.websphere.samples.objectgrid.security.WSGroupPrincipal, to represent the group. This group principal can then be used for group authorization. The groups are defined in the xsAuthGroup2.policy file:

grant codebase "http://www.ibm.com/com/ibm/ws/objectgrid/security/PrivilegedAction"
principal com.ibm.websphere.sample.xs.security.WSGroupPrincipal 
  "defaultWIMFileBasedRealm/cn=operatorGroup,o=defaultWIMFileBasedRealm" {
    permission com.ibm.websphere.objectgrid.security.MapPermission "Grid.Map1", "read";};

grant codebase "http://www.ibm.com/com/ibm/ws/objectgrid/security/PrivilegedAction"
principal com.ibm.websphere.sample.xs.security.WSGroupPrincipal 
 "defaultWIMFileBasedRealm/cn=adminGroup,o=defaultWIMFileBasedRealm" {
    permission com.ibm.websphere.objectgrid.security.MapPermission "Grid.Map1", "all";};
The principal name is the WSGroupPrincipal, which represents the group.


Adding the custom login module

The custom login module must be added to each of the following system login module entries: If we are using Lightweight Third Party Authentication (LTPA), add the entry to the RMI_INBOUND login modules. LTPA is the default authentication mechanism for WAS Version 7.0. For a WAS Network Deployment configuration, you only need to configure the LTPA authentication mechanism configuration entries.

Use the following steps to configure the supplied com.ibm.websphere.samples.objectgrid.security.lm.WASAddGroupLoginModule login module:

  1. In the administrative console, click Security > Global Security > Java Authentication and Authorization Service > System logins > login_module_name > JAAS login modules > New.

  2. Enter the class name as

    com.ibm.websphere.sample.xs.security.lm.WASAddGroupLoginModule.

  3. Optional: Add a property

    debug and set the value to true.

  4. Click Apply to add the new module to the login module list.


Setting the JAAS Authorization Policy file using JVM Properties

In the administrative console, perform the following steps to xs1 and xs2 servers in the xsCluster. If a different deployment topology is used, perform the following steps to the application servers that host the container servers.

  1. In the administrative console, click Servers > Application servers > server_name > Java and Process management > Process definition > JVM

  2. Enter the following Generic JVM arguments or replace the -Djava.security.policy entry with the following text:
    -Djava.security.policy=samples_home /security/xsAuthGroup2.policy

  3. Click OK and save your changes.


Testing group authorization with the sample application

We can test that group authorization is configured by the login module with the sample application.

  1. Restart the container servers. For this tutorial, the container servers are the xs1 and xs2 servers.

  2. Log in to the sample application. In a web browser, open

    http://<host>:<port>/EmployeeManagementWeb/management.jsp and login with the user name

    admin1 and password

    admin1.

  3. Display an employee. Click Display an Employee and search for the authemp2@acme.com email address. A message displays that the user cannot be found.

  4. Add an employee. Click Add an Employee. Add the email

    authemp2@acme.com, the first name

    Joe, and the last name

    Doe. Click Submit. A message displays that the employee has been added.

  5. Log in as the operator user. Open a second web browser window and open the following URL:

    http://<host>:<port>/EmployeeManagermentWeb/management.jsp. Use the user name

    operator1 and password

    operator1.

  6. Attempt to display an employee. Click Display an Employee and search for the authemp2@acme.com email address. The employee is displayed.

  7. Add an employee. Click Add an Employee. Add the email

    authemp3@acme.com, the first name

    Joe, and the last name

    Doe. Click Submit. The following message displays:

    An exception occurs when Add the employee. See below for detailed exception messages.
    The following exception is in the exception chain:
    java.security.AccessControlException: Access denied 
    (com.ibm.websphere.objectgrid.security.MapPermission Grid.Map1 insert)
    This message displays because the operator user does not have permission to insert data into the Map1 map.


Module 5: Use the xscmd tool to monitor data grids and maps

Use the xscmd tool to show the primary data grids and map sizes of the Grid data grid. The xscmd tool uses the MBean to query all of the data grid artifacts, such as primary shards, replica shards, container servers, map sizes, and so on.

In this tutorial, the container and catalog servers are running in WAS application servers. The WXS run time registers the Managed Beans (MBean) with the MBean server that is created by the WAS run time. The security used by the xscmd tool is provided by the WAS MBean security. Therefore, WXS specific security configuration is not necessary.

To list the placement of the primary shards.

Before we can view the output, we are prompted to log in with your WAS ID and password.


Tutorial: Integrate WXS security in a mixed environment with an external authenticator

This tutorial demonstrates how to secure WXS servers that are partially deployed in a WAS environment.

In the deployment for this tutorial, the container servers are deployed in WAS. The catalog server is deployed as stand-alone server, and is started in a Java Standard Edition (Java SE) environment.

Because the catalog server is not deployed in WAS, we cannot use the WAS Authentication plug-ins. In this tutorial, a different authenticator is required for catalog server authentication. You configure a keystore authenticator to authenticate the clients.


Introduction: Security in a mixed environment

In this tutorial, you integrate WXS security in a mixed environment. The container servers run within WAS, and the catalog service runs in stand-alone mode. Because the catalog server is in stand-alone mode, configure an external authenticator.

If both your container servers and catalog server are running within WAS, we can use the WAS Authentication plug-ins or an external authenticator.

Developers and administrators that are interested in the security integration between WXS and WAS and configuring external authenticators.


System requirements

This tutorial uses four WAS application servers and one dmgr to demonstrate the sample.


Prerequisites

A basic understanding of the following items is helpful before you start this tutorial:


Module 1: Prepare the mixed WAS and stand-alone environment

Before you start the tutorial, you must create a basic topology that includes container servers that run within WAS. In this tutorial, the catalog servers run in stand-alone mode.


Lesson 1.1: Understand the topology and get the tutorial files

To prepare your environment for the tutorial, you must configure the catalog and container servers for the topology.

This lesson guides you through the sample topology and applications used to in the tutorial. To begin running the tutorial, you must download the applications and place the configuration files in the correct locations for your environment. We can download the sample application from the WXS wiki .


Topology

In this tutorial, you create the following clusters in the WAS cell:

In this deployment topology, the s1 and s2 application servers are the client servers that access data that is being stored in the data grid. The xs1 and xs2 servers are the container servers that host the data grid.

Alternative configuration: We can host all of the application servers in a single cluster, such as in the appCluster cluster. With this configuration, all of the servers in the cluster are both clients and container servers. This tutorial uses two clusters to distinguish between the application servers that are hosting the clients and container servers.

In this tutorial, you configure a catalog service domain that consists of a remote server that is not in the WAS cell. This configuration is not the default, which results in the catalog servers running on the dmgr and other processes in the WAS cell. See Creating catalog service domains in WAS for more information about creating a catalog service domain that consists of remote servers.

Figure 1. Tutorial topology


Applications

In this tutorial, we are using two applications and one shared library file:


Get the tutorial files

  1. Download the WASSecurity.zip and security_extauth.zip files from the WXS wiki .

  2. Extract the WASSecurity.zip file to a directory for viewing the binary and source artifacts, for example a wxs_samples/ directory. This directory is referred to as samples_home for the remainder of the tutorial. Refer to the README.txt file in the package for a description of the contents and how to load the source into your Eclipse workspace. The following ObjectGrid configuration files are in the META-INF directory:

    • objectGrid.xml
    • objectGridDeployment.xml

  3. Create a directory to store the property files that are used to secure this environment. For example, you might create the /opt/wxs/security directory.

  4. Extract the security_extauth.zip file to samples_home . The security_extauth.zip file contains the following security configuration files used in this tutorial:. These configuration files follow:

    • catServer3.props
    • server3.props
    • client3.props
    • security3.xml
    • xsAuth3.props
    • xsjaas3.config
    • sampleKS3.jks


About the configuration files

The objectGrid.xml and objectGridDeployment.xml files create the data grids and maps that store the application data.

These configuration files must be named objectGrid.xml and objectGridDeployment.xml. When the application server starts, eXtreme Scale detects these files in the META-INF directory of the EJB and web modules. If these files are found, it assumed that the JVM acts as a container server for the defined data grids in the configuration files.

objectGrid.xml file

The objectGrid.xml file defined one ObjectGrid named

Grid. The Grid data grid has one map, the Map1 map, that stores the employee profile for the application.

<?xml version="1.0" encoding="UTF-8"?>
<objectGridConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://ibm.com/ws/objectgrid/config ../objectGrid.xsd"
 xmlns="http://ibm.com/ws/objectgrid/config">

 <objectGrids>
        <objectGrid name="Grid" txTimeout="15">
            <backingMap name="Map1" />
        </objectGrid>
    </objectGrids>

</objectGridConfig>

objectGridDeployment.xml file

The objectGridDeployment.xml file specifies how to deploy the Grid data grid. When the grid is deployed, it has five partitions and one synchronous replica.

<?xml version="1.0" encoding="UTF-8"?>

<deploymentPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://ibm.com/ws/objectgrid/deploymentPolicy ../deploymentPolicy.xsd"
 xmlns="http://ibm.com/ws/objectgrid/deploymentPolicy">

    <objectgridDeployment objectgridName="Grid">
        <mapSet name="mapSet" numberOfPartitions="5" minSyncReplicas="0" maxSyncReplicas="1" >
            <map ref="Map1"/>
        </mapSet>
    </objectgridDeployment>

</deploymentPolicy>


Lesson 1.2: Configure the WAS environment

To prepare your environment for the tutorial, you must configure WAS security. Enable administration and application security using internal file-based federated repositories as a user account registry. Then, we can create server clusters to host the client application and container servers. You also must create and start the catalog servers.

The following steps were written using WAS Version 7.0. However, we can also apply the concepts apply to earlier versions of WAS.


Configure WAS security

Create and augment profiles for the dmgr and nodes with WXS. See Installing WXS or WXS client with WAS for more information.

Configure WAS security.

  1. In the WAS administrative console, click Security > Global Security.
  2. Select Federated repositories as the Available realm definition. Click Set as current.
  3. Click Configure.. to go to the Federated repositories panel.
  4. Enter the Primary administrative user name, for example,

    admin. Click Apply.

  5. When prompted, enter the administrative user password and click OK. Save your changes.
  6. On the Global Security page, verify that Federated repositories setting is set to the current user account registry.
  7. Select the following items: Enable administrative security, Enable application security, and Use Java 2 security to restrict application access to local resources. Click Apply and save your changes.
  8. Restart the dmgr and any running application servers.

The WAS administrative security is enabled using the internal file-based federated repositories as the user account registry.


Create server clusters

Create two server clusters in your WAS configuration: The appCluster cluster to host the sample application for the tutorial and the xsCluster cluster to host the data grid.

  1. In the WAS administrative console, open the clusters panel. Click Servers > Clusters > WebSphere application server clusters > New.
  2. Type

    appCluster as the cluster name, leave the Prefer local option selected, and click Next.

  3. Create servers in the cluster. Create a server named

    s1, keeping the default options. Add an additional cluster member named

    s2.

  4. Complete the remaining steps in the wizard to create the cluster. Save the changes.
  5. Repeat these steps to create the xsCluster cluster. This cluster has two servers, named

    xs1 and

    xs2.


Create a catalog service domain

After configuring the server cluster and security, you must define where catalog servers start.

Define a catalog service domain in WXS

  1. In the WAS administrative console, click System administration > WXS > Catalog service domains.
  2. Create the catalog service domain. Click New. Create the catalog service domain with the name

    catalogService1, and enable the catalog service domain as the default.

  3. Add remote servers to the catalog service domain. Select Remote server. Provide the host name where the catalog server is running. Use the listener port value of

    16809 for this example.

  4. Click OK and save your changes.


Module 2: Configure WXS authentication in a mixed environment

By configuring authentication, we can reliably determine the identity of the requester. WXS supports both client-to-server and server-to-server authentication.

Authentication flow

Figure 1. Authentication flow

The previous diagram shows two application servers. The first application server hosts the web application, which is also a WXS client. The second application server hosts a container server. The catalog server is running in a stand-alone JVM instead of WAS.

The arrows marked with numbers in the diagram indicate the authentication flow:

  1. An enterprise application user accesses the web browser, and logs in to the first application server with a user name and password. The first application server sends the client user name and password to the security infrastructure to authenticate to the user registry. This user registry is a keystore. As a result, the security information is stored on the WAS thread.
  2. The JavaServer Pages (JSP) file acts as a WXS client to retrieve the security information from the client property file. The JSP application that is acting as the WXS client sends the WXS client security credential along with the request to the catalog server. Sending the security credential with the request is considered a runAs model. In a runAs model, the web browser client runs as a WXS client to access the data stored in the container server. The client uses a Java virtual machine (JVM)-wide client credential to connect to the WXS servers. Using the runAs model is like connecting to a database with a data source level user ID and password.
  3. The catalog server receives the WXS client credential, which includes the WAS security tokens. Then, the catalog server calls the authenticator plug-in to authenticate the client credential. The authenticator connects to the external user registry and sends the client credential to the user registry for authentication.
  4. The client sends the user ID and password to the container server that is hosted in the application server.
  5. The container service, hosted in the application server, receives the WXS client credential, which is the user id and password pair. Then, the container server calls the authenticator plug-in to authenticate the client credential. The authenticator connects to the keystore user registry and sends the client credential to the user registry for authentication


Lesson 2.1: Configure WXS client security

You configure the client properties with a properties file. The client properties file indicates the CredentialGenerator implementation class to use.


Client properties file contents

The tutorial uses WAS security tokens for the client credential. The samples_home/security_extauth directory contains the client3.props file.

The client3.props file includes the following settings:

securityEnabled

Enables WXS client security. The value is set to true to indicate that the client must send available security information to the server.

credentialAuthentication

Client credential authentication support. The value is set to Supported to indicate that the client supports credential authentication.

credentialGeneratorClass

Name of the class that implements the com.ibm.websphere.objectgrid.security.plugins.CredentialGenerator interface. The value is set to the com.ibm.websphere.objectgrid.security.plugins.builtins. UserPasswordCredentialGenerator class so that the client retrieves the security information from the UserPasswordCredentialGenerator class.

credentialGeneratorProps

Specifies the user name and password: manager manager1. The user name is manager, and the password is manager1. We can also use the FilePasswordEncoder.bat|sh command to encode this property using an exclusive or (xor) algorithm.


Setting the client properties file using Java virtual machine (JVM) properties

In the administrative console, complete the following steps to both the s1 and s2 servers in the appCluster cluster. If we are using a different topology, complete the following steps to all of the application servers to which the EmployeeManagement application is deployed.

  1. Servers > WebSphere application servers > server_name > Java and Process Management > Process definition > Java Virtual Machine.

  2. Create the following generic JVM property to set the location of the client properties file:
    -Dobjectgrid.client.props=samples_home/security_extauth/client3.props

  3. Click OK and save your changes.


Lesson 2.2: Configure catalog server security

A catalog server contains two different levels of security information: The first level contains the security properties that are common to all the WXS servers, including the catalog service and container servers. The second level contains the security properties that are specific to the catalog server.

The security properties that are common to the catalog servers and container servers are configured in the security XML descriptor file. An example of common properties is the authenticator configuration, which represents the user registry and authentication mechanism. See Security descriptor XML file for more information about the security properties.

To configure the security XML descriptor file in a Java SE environment, use a -clusterSecurityFile option when we run the startOgServer or startXsServer command. Specify a value in a file format, such as samples_home /security_extauth/security3.xml.


security3.xml file

In this tutorial, the security3.xml file is in the samples_home /security_extauth directory. The content of the security3.xml file with the comments removed follows:

<securityConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://ibm.com/ws/objectgrid/config/security ../objectGridSecurity.xsd"
 xmlns="http://ibm.com/ws/objectgrid/config/security">

 <security securityEnabled="true">
  <authenticator
 className="com.ibm.websphere.objectgrid.security.plugins.builtins.KeyStoreLoginAuthenticator">
  </authenticator>
 </security>
</securityConfig>
The following properties are defined in the security3.xml file:

securityEnabled

The securityEnabled property is set to true, which indicates to the catalog server that the WXS global security is enabled.

authenticator

The authenticator is configured as the com.ibm.websphere.objectgrid.security.plugins.builtins.KeyStoreLoginAuthenticator class. With this built-in implementation of the Authenticator plug-in, the user ID and password is passed to verify that it is configured in the keystore file. The KeyStoreLoginAuthenticator class uses a KeyStoreLogin login module alias, so a Java Authentication and Authorization Service (JAAS) login configuration is required.


catServer3.props file

The server property file stores the server-specific properties, which include the server-specific security properties. See Server properties file for more information. Use -serverProps option to specify the catalog server property when we run the startOgServer or startXsServer command. For this tutorial, a catServer3.props file is in the c directory. The content of the catServer3.props file with the comments removed follows:

securityEnabled=true
credentialAuthentication=Required
transportType=TCP/IP
secureTokenManagerType=none
authenticationSecret=ObjectGridfalse Secret

securityEnabled

The securityEnabled property is set to true to indicate that this catalog server is a secure server.

credentialAuthentication

The credentialAuthentication property is set to Required, so any client that is connecting to the server is required to provide a credential. Iin the client property file, the credentialAuthentication value is set to Supported, so the server receives the credentials that are sent by the client.

secureTokenManagerType

The secureTokenManagerType is set to none to indicate that the authentication secret is not encrypted when joining the existing servers.

authenticationSecret

The authenticationSecret property is set to ObjectGridfalse Secret. This secret string is used to join the eXtreme Scale server cluster. When a server joins the data grid, it is challenged to present the secret string. If the secret string of the joining server matches the string in the catalog server, the joining server is accepted. If the string does not match, the join request is rejected.

transportType

The transportType property is set to TCP/IP initially. Later in the tutorial, transport security is enabled.


xsjaas3.config file

Because the KeyStoreLoginAuthenticator implementation uses a login module, configure the login model with a JAAS authentication login configuration file. The contents of the xsjaas3.config file follows:

KeyStoreLogin{
com.ibm.websphere.objectgrid.security.plugins.builtins.KeyStoreLoginModule required
     keyStoreFile="samples_home /security_extauth/sampleKS3.jks" debug = true;};
If you used a location for samples_home other than /wxs_samples/, you need to update the location of the keyStoreFile. This login configuration indicates that the com.ibm.websphere.objectgrid.security.plugins.builtins.KeyStoreLoginModule module is used as the login module. The keystore file is set to the sampleKS3.jks file.

The sampleKS3.jks sample keystore file stores two user IDs and the passwords: manager/manager1 and cashier/cashier1.

Use the following keytool commands to create this keystore:


Start the catalog server with security enabled

To start the catalog server, issue the startOgServer or startXsServer command with the -clusterFile and -serverProps parameters to pass in the security properties.

Use a stand-alone installation of WXS to run the catalog server. When using the stand-alone installation image, use the IBM SDK. Use the SDK that is included with WAS by setting the JAVA_HOME variable to point to the IBM SDK. For example, set JAVA_HOME=was_root/IBM/WebSphere/AppServer/java/

  1. Go to the bin directory.
    cd wxs_home /bin

  2. Run the startOgServer or startXsServer command.

    ./startOgServer.sh cs1 -listenerPort 16809 -JMXServicePort 16099 -catalogServiceEndPoints
    cs1:[HOST_NAME]:16601:16602 -clusterSecurityFile samples_home /security_extauth/security3.xml
    -serverProps samples_home /security_extauth/catServer3.props -jvmArgs 
    -Djava.security.auth.login.config="samples_home /security_extauth/xsjaas3.config"
    ./startXsServer.sh cs1 -listenerPort 16809 -JMXServicePort 16099 -catalogServiceEndPoints
    cs1:[HOST_NAME]:16601:16602 -clusterSecurityFile samples_home /security_extauth/security3.xml
    -serverProps samples_home /security_extauth/catServer3.props -jvmArgs 
    -Djava.security.auth.login.config="samples_home /security_extauth/xsjaas3.config"

After we run the startOgServer or startXsServer command, a secure server starts with listener port 16809, client port 16601, peer port 16602, and JMX port 16099. If a port conflict exists, change the port number to an unused port number.


Stop a catalog server that has security enabled

Use the stopOgServer or stopXsServer command to stop the catalog server.

  1. Go to the bin directory.
    cd wxs_home /bin

  2. Run the stopOgServer or stopXsServer command.
      stopOgServer.sh cs1 -catalogServiceEndPoints localhost:16809 -clientSecurityFile samples_home /security_extauth/client3.props
      stopXsServer.sh cs1 -catalogServiceEndPoints localhost:16809 -clientSecurityFile samples_home /security_extauth/client3.props


Lesson 2.3: Configure container server security

When a container server connects to the catalog service, the container server gets all the security configurations that are configured in the Object Grid Security XML file. The ObjectGrid Security XML file defines authenticator configuration, the login session timeout value, and other configuration information. A container server also has its own server-specific security properties in the server property file.

Configure the server property file with the -Dobjectgrid.server.props JVM property. The file name specified for this property is an absolute file path, such as samples_home /security_extauth/server3.props.

In this tutorial, the container servers are hosted in the xs1 and

xs2 servers in the xsCluster cluster.


server3.props file

The server3.props file is in the samples_home/security_extauth/ directory. The content of the server3.props file follows:

securityEnabled=true
credentialAuthentication=Required
secureTokenManagerType=none
authenticationSecret=ObjectGridfalse Secret

securityEnabled

The securityEnabled property is set to true to indicate that this container server is a secure server.

credentialAuthentication

The credentialAuthentication property is set to Required, so any client that is connecting to the server is required to provide a credential. In the client property file, the credentialAuthentication property is set to Supported, so the server receives the credential that is sent by the client.

secureTokenManagerType

The secureTokenManagerType is set to none to indicate that the authentication secret is not encrypted when joining the existing servers.

authenticationSecret

The authenticationSecret property is set to ObjectGridfalse Secret. This secret string is used to join the eXtreme Scale server cluster. When a server joins the data grid, it is challenged to present the secret string. If the secret string of the joining server matches the string in the catalog server, the joining server is accepted. If the string does not match, the join request is rejected.


Setting the server properties file with JVM properties

Set the server properties file on the xs1 and xs2 servers. If we are not using the topology for this tutorial, set the server properties file on all of the application servers that we are using to host container servers.

  1. Open the Java virtual machine page for the server. Servers > WebSphere application servers > server_name > Java and Process Management > Process definition > Java Virtual Machine.

  2. Add the generic JVM argument:
    -Dobjectgrid.server.props=samples_home /security_extauth/server3.props

  3. Click OK and save your changes.


Adding the custom login module

The container server uses the same KeyStoreAuthenticator implementation as the catalog server. The KeyStoreAuthenticator implementation uses a KeyStoreLogin login module alias, so you must add a custom login module to the application login model entries.

  1. In the WAS administrative console, click Security > Global security > Java Authentication and Authorization Service.
  2. Click Application logins.
  3. Click New, add an alias

    KeyStoreLogin. Click Apply.

  4. Under JAAS login modules, click New.
  5. Enter

    com.ibm.websphere.objectgrid.security.plugins.builtins.KeyStoreLoginModule as the module class name, and choose SUFFICIENT as the authentication strategy. Click Apply.

  6. Add the keyStoreFile custom property with value samples_home /security_extauth/sampleKS.jks.
  7. Optional: Add the debug custom property with value true.
  8. Save the configuration.


Lesson 2.4: Install and run the sample

After authentication is configured, we can install and run the sample application.


Create a shared library for the EmployeeData.jar file

  1. In the WAS administrative console, open the Shared Libraries page. Click Environment > Shared libraries.
  2. Choose the cell scope.
  3. Create the shared library. Click New. Enter

    EmployeeManagementLIB as the Name. Enter the path to the EmployeeData.jar in the classpath, for example, samples_home /WASSecurity/EmployeeData.jar.

  4. Click Apply.


Installing the sample

  1. Install the EmployeeManagement_extauth.ear file under the samples_home /security_extauth directory.

    The EmployeeManagement_extauth.ear file is different from the samples_home /WASSecurity/EmployeeManagement.ear file. The manner in which the ObjectGrid session is retrieved has been updated to use the credential that is cached in the client property file in the EmployeeManagement_extauth.ear application. See the comments in the com.ibm.websphere.sample.xs.DataAccessor class in the samples_home /WASSecurity/EmployeeManagementWeb project to see the code that was updated for this change.

    1. To begin the installation, click Applications > New application > New Enterprise Application. Choose the detailed path for installing the application.
    2. On the Map modules to servers step, specify the appCluster cluster to install the EmployeeManagementWeb module.
    3. On the Map shared libraries step, select the EmployeeManagementWeb module.
    4. Click Reference shared libraries. Select the EmployeeManagementLIB library.
    5. Map the webUser role to All Authenticated in Application's Realm.
    6. Click OK.

    The clients run in the s1 and

    s2 servers in this cluster.

  2. Install the sample XSDeployment.ear file that is in the samples_home /WASSecurity directory.

    1. To begin the installation, click Applications > New application > New Enterprise Application. Choose the detailed path for installing the application.
    2. On the Map modules to servers step, specify the xsCluster cluster to install the XSDeploymentWeb web module.
    3. On the Map shared libraries step, select the XSDeploymentWeb module.
    4. Click Reference shared libraries. Select the EmployeeManagementLIB library.
    5. Click OK.

    The xs1 and

    xs2 servers in this cluster host the container servers.

  3. Verify that the catalog server is started.

  4. Restart the xsCluster cluster. When the xsCluster starts, the XSDeployment application starts, and a container server is started on the xs1 and xs2 servers respectively. If you look at the SystemOut.log file of the xs1 and xs2 servers, the following message that indicates the server properties file is loaded is displayed:
    CWOBJ0913I: Server property files have been loaded: 
    samples_home/security_extauth/server3.props.

  5. Restart the appClusters cluster. When the cluster appCluster starts, the EmployeeManagement application also starts. If you look at the SystemOut.log file of the s1 and s2 servers, we can see the following message that indicates that the client properties file is loaded.
    CWOBJ0924I: The client property file {0} has been loaded.
    If we are using  WXS Version 7.0, the English-only CWOBJ9000I message displays to indicate that the client property file has been loaded. If you do not see the expected message, verify that you configured the -Dobjectgrid.server.props or -Dobjectgrid.client.props property in the JVM argument. If you do have the properties configured, make sure the dash (-) is a UTF character.


Run the sample application

  1. Run the management.jsp file. In a web browser, access

    http://<your_servername>:<port>/EmployeeManagementWeb/management.jsp. For example, you might use the following URL:

    http://localhost:9080/EmployeeManagementWeb/management.jsp.

  2. Provide authentication to the application. Enter the credentials of the user that you mapped to the webUser role. By default, this user role is mapped to all authenticated users. Type any valid user name and password, such as the administrative user name and password. A page to display, add, update, and delete employees displays.
  3. Display employees. Click Display an Employee. Enter

    emp1@acme.com as the email address, and click Submit. A message displays that the employee cannot be found.

  4. Add an employee. click Add an Employee. Enter

    emp1@acme.com as the email address, enter

    Joe as the given name, and

    Doe as the surname. Click Submit. A message displays that an employee with the emp1@acme.com address has been added.

  5. Display the new employee. Click Display an Employee. Enter

    emp1@acme.com as the email address with empty fields for the first and surnames, and click Submit. A message displays that the employee has been found, and the correct names are displayed in the given name and surname fields.

  6. Delete the employee. Click Delete an employee. Enter

    emp1@acme.com and click Submit. A message is displayed that the employee has been deleted.

Because the catalog server transport type is set to TCP/IP, verify that the server s1 and s2 outbound transport setting is not set to SSL-Required. Otherwise, an exception occurs. If you look at the system out file of the catalog server, logs/cs1/SystemOut.log file, the following debug output to indicates the key store authentication:

SystemOut     O [KeyStoreLoginModule] initialize: Successfully loaded key store
SystemOut     O [KeyStoreLoginModule] login: entry
SystemOut     O [KeyStoreLoginModule] login: user entered user name: manager
SystemOut     O   Print out the certificates: 
...


Module 3: Configure transport security

Configure transport security to secure data transfer between the clients and servers in the configuration.

In the previous module in the tutorial, you enabled WXS authentication. With authentication, any application that tries to connect to the WXS server is required to provide a credential. Therefore, no unauthenticated client can connect to the WXS server. The clients must be an authenticated application running in a WAS cell.

With the configuration up to this module, the data transfer between the clients in the appCluster cluster and servers in the xsCluster cluster is not encrypted. This configuration might be acceptable if your WAS clusters are installed on servers behind a firewall. However, in some scenarios, non-encrypted traffic is not accepted for some reasons even though the topology is protected by firewall. For example, a government policy might enforce encrypted traffic. WXS supports Transport Layer Security/Secure Sockets Layer (TLS/SSL) for secure communication between ObjectGrid endpoints, which include client servers, container servers, and catalog servers.

In this sample deployment, the eXtreme Scale clients and container servers are all running in the WAS environment. Client or server properties are not necessary to configure the SSL settings because the eXtreme Scale transport security is managed by the Application Server Common Secure Interoperability Protocol Version 2 (CSIV2) transport settings. WXS servers use the same Object Request Broker (ORB) instance as the application servers in which they run. Specify all the SSL settings for client and container servers in the WAS configuration using these CSIv2 transport settings. Configure the SSL properties in the server properties file for the catalog server.


Prerequisites

This step of the tutorial builds upon the previous modules. Complete the previous modules in this tutorial before you configure transport security.


Lesson 3.2: Add SSL properties to the catalog server properties file

The catalog server is running outside of WAS, so configure the SSL properties in the server properties file.

The other reason to configure the SSL properties in the server properties file is because the catalog server has its own proprietary transport paths that cannot be managed by the WAS Common Secure Interoperability Protocol Version 2 (CSIV2) transport settings. Therefore, you must configure the SSL properties in the server properties file for the catalog server.


SSL properties in the catServer3.props file

alias=default
contextProvider=IBMJSSE2
protocol=SSL
keyStoreType=PKCS12
keyStore=/was_root/IBM/WebSphere/AppServer/profiles/
<deployment_manager_name>/config/cells/<cell_name>/nodes/
<node_name>/key.p12 
keyStorePassword=WebAS
trustStoreType=PKCS12
trustStore=/was_root/IBM/WebSphere/AppServer/profiles/
<deployment_manager_name>/config/cells/<cell_name>/nodes/
<node_name>/trust.p12
trustStorePassword=WebAS
clientAuthentication=false
The catServer3.props file is using the default WAS node level keystore and truststore. If we are deploying a more complex deployment environment, you must choose the correct keystore and truststore. In some cases, you must create a keystore and truststore and import the keys from keystores from the other servers. Notice that the WebAS string is the default password of the WAS keystore and truststore. See Default self-signed certificate configuration for more details.

These entries are already included in the samples_home /security_extauth/catServer3.props file as comments. We can uncomment the entries and make the appropriate updates for the installation to the was_root, <deployment_manager_name>, <cell_name>, and <node_name> variables.

After configuring the SSL properties, change the transportType property value from

TCP/IP to SSL-Required.


SSL properties in the client3.props file

Also configure the SSL properties in the client3.props file because this file is used when you stop the catalog server that is running outside of WAS.

These properties have no effect on the client servers running in WAS because they are using the WAS Common Security Interoperability Protocol Version 2 (CSIV2) transport settings. However, when you stop the catalog server you must provide a client properties file on the stopOgServer command. Set the following properties in the <SAMPLES_HOME>/security_extauth/client3.props file to match the values specified above in the catServer3.props file:

#contextProvider=IBMJSSE2 
#protocol=SSL 
#keyStoreType=PKCS12 
#keyStore=/was_root/IBM/WebSphere/AppServer/profiles/
<deployment_manager_name>/config/cells/<cell_name>/nodes/
<node_name>/key.p12  
#keyStorePassword=WebAS 
#trustStoreType=PKCS12 
#trustStore=/was_root/IBM/WebSphere/AppServer/profiles/
<deployment_manager_name>/config/cells/<cell_name>/nodes/
<node_name>/trust.p12 
#trustStorePassword=WebAS
As with the catServer3.props file, we can use the comments that are already provided in the samples_home /security_extauth/client3.props file with appropriate updates to was_root, <deployment_manager_name>, <cell_name>, and <node_name> variables to match your environment.


Lesson 3.3: Run the sample

Restart all the servers and run the sample application again. You should be able to run through the steps without any problems.

See Lesson 2.4: Install and run the sample for more information about running and installing the sample application.


Module 4: Use Java Authentication and Authorization Service (JAAS) authorization in WAS

Now configured authentication for clients, we can further configure authorization to give different users varying permissions. For example, an "operator" user might only be able to view data, while a "manager" user can perform all operations.

After authenticating a client, as in the previous module in this tutorial, we can give security privileges through eXtreme Scale authorization mechanisms. The previous module of this tutorial demonstrated how to enable authentication for a data grid using integration with WAS. As a result, no unauthenticated client can connect to the eXtreme Scale servers or submit requests to your system. However, every authenticated client has the same permission or privileges to the server, such as reading, writing, or deleting data that is stored in the ObjectGrid maps. Clients can also issue any type of query.

This part of the tutorial demonstrates how to use eXtreme Scale authorization to give authenticated users varying privileges. WXS uses a permission-based authorization mechanism. We can assign different permission categories that are represented by different permission classes. This module features the MapPermission class.

In WXS, the com.ibm.websphere.objectgrid.security.MapPermission class represents permissions to the eXtreme Scale resources, specifically the methods of the ObjectMap or JavaMap interfaces. WXS defines the following permission strings to access the methods of ObjectMap and JavaMap:

The authorization occurs when a WXS client uses a data access API, such as the ObjectMap,JavaMap, or EntityManager APIs. The run time checks corresponding map permissions when the method is called. If the required permissions are not granted to the client, an AccessControlException exception results. This tutorial demonstrates how to use Java Authentication and Authorization Service (JAAS) authorization to grant authorization map access for different users.


Lession 4.1: Enable WXS authorization

To enable authorization in WXS, enable security on a specific ObjectGrid.

To enable authorization on the ObjectGrid, you must set the securityEnabled attribute to true for that particular ObjectGrid in the XML file. For this tutorial, we can either use the XSDeployment_sec.ear file from the samples_home /WASSecurity directory, which has already has security set in the objectGrid.xml file, or we can edit the existing objectGrid.xml file to enable security. This lesson demonstrates how to edit the file to enable security.

  1. Optional: Extract the files in the XSDeployment.ear file, and then unzip the XSDeploymentWeb.war file.

  2. Optional: Open the objectGrid.xml file and set the securityEnabled attribute to true on the ObjectGrid level. See an example of this attribute in the following example:
    <objectGridConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://ibm.com/ws/objectgrid/config ../objectGrid.xsd"
     xmlns="http://ibm.com/ws/objectgrid/config">
    
        <objectGrids>
            <objectGrid name="Grid" txTimeout="15" securityEnabled="true">
                   <backingMap name="Map1" />
            </objectGrid>
        </objectGrids>
    
    </objectGridConfig>
    If you have multiple ObjectGrids defined, then set this attribute on each grid.

  3. Optional: Repackage the XSDeploymentWeb.war and XSDeployment.ear files to include your changes.

  4. Required: Uninstall the XSDeployment.ear file and then install the updated XSDeployment.ear. We can either use the file you modified in the previous steps, or we can install the XSDeployment_sec.ear file that is provided in the samples_home /WASSecurity directory. See Lesson 2.4: Install and run the sample for more information about installing the application.

  5. Restart all of the application servers to enable WXS authorization.


Lesson 4.2: Enable user-based authorization

In the authentication module of this tutorial, you created two users: 

operator and

manager. We can assign varying permissions to these users with Java Authentication and Authorization Service (JAAS) authorization.


Defining the Java Authentication and Authorization Service (JAAS) authorization policy using user principals

We can assign permissions to the users that you previously created. Assign the operator user only read permissions to all maps. Assign the manager user all permissions. Use the JAAS authorization policy file to grant permissions to principals.

Edit the JAAS authorization file. The xsAuth3.policy file is in the samples_home /security_extauth directory.

grant codebase "http://www.ibm.com/com/ibm/ws/objectgrid/security/PrivilegedAction"
    principal javax.security.auth.x500.X500Principal
    "CN=operator,O=acme,OU=OGSample" {
    permission com.ibm.websphere.objectgrid.security.MapPermission "Grid.Map1", "read";};

grant codebase "http://www.ibm.com/com/ibm/ws/objectgrid/security/PrivilegedAction"
    principal javax.security.auth.x500.X500Principal
    "CN=manager,O=acme,OU=OGSample" {
    permission com.ibm.websphere.objectgrid.security.MapPermission "Grid.Map1", "all";};
In this file, the http://www.ibm.com/com/ibm/ws/objectgrid/security/PrivilegedAction codebase is a specially reserved URL for ObjectGrid. All ObjectGrid permissions that are granted to principals should use this special code base. The following permissions are assigned in this file:


Setting the JAAS authorization policy file using JVM properties

Use the following steps to set JVM properties for the xs1 and xs2 servers, which are in the xsCluster cluster. If we are using a topology that is different from the sample topology used in this tutorial, set the file on all of your container servers.

  1. In the administrative console, click Servers > Application servers > server_name > Java and process management > Process definition > JVM.

  2. Add the following generic JVM arguments:
    -Djava.security.policy=samples_home /security_extauth/xsAuth3.policy

  3. Click OK and save your changes.


Run the sample application to test authorization

Use the sample application to test the authorization settings. The manager user continues to have all permissions in the Map1 map, including displaying and adding employees. The operator user should only be able to view employees because that user was assigned read permission only.

  1. Restart all of the application servers running container servers. For this tutorial, restart the xs1 and

    xs2 servers.

  2. Open the EmployeeManagementWeb application. In a web browser, open

    http://<host>:<port>/EmployeeManagermentWeb/management.jsp.

  3. Log in to the application using any valid user name and password.

  4. Attempt to display an employee. Click Display an Employee and search for the authemp1@acme.com email address. A message displays that the user cannot be found.

  5. Add an employee. Click Add an Employee. Add the email

    authemp1@acme.com, the given name

    Joe, and the surname

    Doe. Click Submit. A message displays that the employee has been added.

  6. Edit the samples_home /security_extauth/client3.props file. Change the value of credentialGeneratorProps property from

    manager manager1 to operator operator1. After you edit the file, the servlet uses user name "operator" and password "operator1" to authenticate to the WXS servers.

  7. Restart the appCluster cluster to pick up the changes in the samples_home /security_extauth/client3.props file.

  8. Attempt to display an employee. Click Display an Employee and search for the authemp1@acme.com email address. The employee is displayed.

  9. Add an employee. Click Add an Employee. Add the email

    authemp2@acme.com, the given name

    Joe, and the surname

    Doe. Click Submit. The following message displays:

    An exception occurs when Add the employee. See below for detailed exception messages.
    The detailed exception text follows:
    java.security.AccessControlException: Access denied 
    (com.ibm.websphere.objectgrid.security.MapPermission Grid.Map1 insert)
    This message displays because the operator user does not have permission to insert data into the Map1 map.

If we are running with a version of WAS that is earlier than Version 7.0.0.11, you might see a java.lang.StackOverflowError error on the container server. This error is caused by a problem with the IBM Developer Kit. The problem is fixed in the IBM Developer Kit that is shipped with WAS Version 7.0.0.11 and later.


Module 5: Use the xscmd utility to monitor data grids and maps

Use the xscmd utility to show the primary data grids and map sizes of the Grid data grid. The xscmd tool uses the MBean to query all of the data grid artifacts, such as primary shards, replica shards, container servers, map sizes, and other data.

In this tutorial, the catalog server is running as a stand-alone Java SE server. The container servers are running in WAS application servers.

For the catalog server, a MBean server is created in the stand-alone Java virtual machine (JVM). When you use the xscmd tool on the catalog server, WXS security is used.

For the container servers, the WXS run time registers the Managed Beans (MBean) with the MBean server that is created by the WAS run time. The security used by the xscmd tool is provided by the WAS MBean security.

  1. cd DMGR_PROFILE/bin

  2. Run the xscmd tool. Use the -c showPlacement -st P parameters...

    xscmd.sh -c showPlacement -cep localhost:16099 -g Grid -ms mapSet -sf P 
    -user manager -pwd manager1 

    If you use the following command to access the data grid, you might also be authorized to perform administrative actions, such as listAllJMXAddresses:

    ./xscmd.sh -user <user> -password <password> <other_parameters>
    If this operation works for this user, then any xscmd operation might also be performed by the same user. The user name and password are passed to the catalog server for authentication.

  3. View the command results.
    *** Showing all primaries for grid - Grid & mapset - mapSet
    Partition Container Host Server
    0 myCell02\myNode04\xs2_C-1 myhost.mycompany.com myCell02\myNode04\xs2
    1 myCell02\myNode04\xs2_C-1 myhost.mycompany.com myCell02\myNode04\xs2
    2 myCell02\myNode04\xs2_C-1 myhost.mycompany.com myCell02\myNode04\xs2
    3 myCell02\myNode04\xs2_C-1 myhost.mycompany.com myCell02\myNode04\xs2
    4 myCell02\myNode04\xs2_C-1 myhost.mycompany.com myCell02\myNode04\xs2

  4. Run the xscmd tool. Use the -c showMapSizes parameter...

    xscmd.sh -c showMapSizes -cep localhost:16099 -g Grid -ms mapSet  -user manager -pwd manager1
    The user name and password are passed to the catalog server for authentication. After we run the command, we are prompted for the WAS user ID and password to authenticate to WAS. You must provide this login information because the -c showMapSizes option gets the map size from each container server, which requires the WAS security.

  5. Optional: We can change the PROFILE/properties/sas.client.props file to run the command without the user ID and password being required. Change the com.ibm.CORBA.loginSource property from

    prompt to properties and then provide the user ID and password. An example of the properties in the PROFILE/properties/sas.client.props file follows:

    com.ibm.CORBA.loginSource=properties
    # RMI/IIOP user identity
    com.ibm.CORBA.loginUserid=Admin
    com.ibm.CORBA.loginPassword=xxxxxx

  6. Optional: If we are using the xscmd command on a WXS stand-alone installation, then add the following options:

    • If we are using WXS security:
      -user
      -pwd
    • If we are using WXS security with custom credential generation:
      -user
      -pwd
      -cgc
      -cgp
    • If SSL is enabled:
      -tt
      -cxpv
      -prot
      -ks
      -ksp
      -kst
      -ts
      -tsp
      -tst

    If WXS security and SSL are both enabled, then both set of parameters are required.


Tutorial: Running eXtreme Scale bundles in the OSGi framework

The OSGi sample builds on the Google Protocol Buffers serializer samples. When you complete this set of lessons, you will have run the serializer sample plug-ins in the OSGi framework.

This sample demonstrates the OSGi bundles. The serializer plug-in is incidental and is not required. The OSGi sample is available on the WXS samples gallery . You must download the sample, and extract it into the wxs_home/samples directory. The root directory for the OSGi sample is...

The command examples in this tutorial assume that we are running on the UNIX operating system. Adjust the command example to run on a Windows operating system. After completing the lessons in this tutorial, you will understand the OSGi sample concepts and know how to complete the following objectives:

In this tutorial you start a WXS server in the OSGi framework, start a WXS container, and wire the sample plug-ins with WXS runtime environment.

After completing the lessons in this tutorial you will understand the OSGi sample concepts and know how to complete the following objectives:


System requirements


Prerequisites

To complete this tutorial, you must download the sample, and extracted it into the wxs_home/samples directory. The root directory for the OSGi sample is wxs_home/samples/OSGiProto.


Expected results

When you complete this tutorial, you will have installed the sample bundles and run a WXS client to insert data into the grid. We can also expect to query and update those sample bundles using the dynamic capabilities that the OSGi container provides.


Module 1: Preparing to install and configure eXtreme Scale server bundles

Complete this module to explore OSGi sample bundles and examine configuration files that you use to configure the eXtreme Scale server.


Objectives

After completing the lessons in this module, you will understand the concepts and know how to complete the following objectives:


Lesson 1.1: Understand the OSGi sample bundles

Complete this lesson to locate and explore the bundles that are provided in the OSGi sample.


OSGi sample bundles

Other than the bundles that are configured in the config.ini file, which is shown in the topic about setting up the Eclipse Equinox environment, the following additional bundles are used in the OSGi sample:

objectgrid.jar

The WXS server runtime bundle. This bundle is located in the wxs_home/lib directory.

com.google.protobuf_2.4.0a.jar

The Google Protocol Buffers, version 2.4.0a bundle. This bundle is located in the wxs_sample_osgi_root/lib directory.

ProtoBufSamplePlugins-1.0.0.jar

Version 1.0.0 of the user plug-in bundle with sample ObjectGridEventListener and MapSerializerPlugin plug-in implementations. This bundle is located in the wxs_sample_osgi_root/lib directory. The services are configured with service ranking 1.

This version uses the standard Blueprint XML to configure the eXtreme Scale plug-in services. The service class is a user-implemented class for WXS interface, com.ibm.websphere.objectgrid.plugins.osgi.PluginServiceFactory. The user-implemented class creates a bean for each request and works similar to a prototype-scoped bean.

ProtoBufSamplePlugins-2.0.0.jar

Version 2.0.0 of the user plug-in bundle with sample ObjectGridEventListener and MapSerializerPlugin plug-in implementations. This bundle is located in the wxs_sample_osgi_root/lib directory. The services are configured with service ranking 2.

This version uses the standard Blueprint XML to configure the eXtreme Scale plug-in services. The service class is using a WXS, built-in class, com.ibm.websphere.objectgrid.plugins.osgi.PluginServiceFactoryImpl, which uses the BlueprintContainer service. Using the standard Blueprint XML configuration, the beans can be configured either as a prototype scope or singleton scope. The bean is not configured as a shard scope.

ProtoBufSamplePlugins-Gemini-3.0.0.jar

Version 3.0.0 of the user plug-in bundle with sample ObjectGridEventListener and MapSerializerPlugin plug-in implementations. This bundle is located in the wxs_sample_osgi_root/lib directory. The services are configured with service ranking 3.

This version uses the Eclipse Gemini-specific Blueprint XML to configure the eXtreme Scale plug-in services. The service class is using a WXS built-in class, com.ibm.websphere.objectgrid.plugins.osgi.PluginServiceFactoryImpl, which uses the BlueprintContainer service. The way to configure a shard scope bean is using a Gemini-specific approach. This version configures the myShardListener bean as a shard scope bean by providing {http://www.ibm.com/schema/objectgrid}shard as the scope value, and configuring a dummy attribute so that the custom scope is recognized by Gemini. This is due to the following Eclipse issue: https://bugs.eclipse.org/bugs/show_bug.cgi?id=348776

ProtoBufSamplePlugins-Aries-4.0.0.jar

Version 4.0.0 of the user plug-in bundle with sample ObjectGridEventListener and MapSerializerPlugin plug-in implementations. This bundle is located in the wxs_sample_osgi_root/lib directory. The services are configured with service ranking 4.

This version uses standard Blueprint XML to configure the eXtreme Scale plug-in services. The service class is using a WXS, built-in class, com.ibm.websphere.objectgrid.plugins.osgi.PluginServiceFactoryImpl, which uses the BlueprintContainer service. Using the standard Blueprint XML configuration, the beans can be configured using a custom scope. This version configures the myShardListenerbean as a shard scoped bean by providing {http://www.ibm.com/schema/objectgrid}shard as the scope value.

ProtoBufSamplePlugins-Activator-5.0.0.jar

Version 5.0.0 of the user plug-in bundle with sample ObjectGridEventListener and MapSerializerPlugin plug-in implementations. This bundle is located in the wxs_sample_osgi_root/lib directory. The services are configured with service ranking 5.

This version does not use Blueprint container at all. In this version, the services are registered using OSGi service registration. The service class is a user-implemented class for the WXS interface, com.ibm.websphere.objectgrid.plugins.osgi.PluginServiceFactory. The user-implemented class creates a bean for each request. It works similar to a prototype-scoped bean.


Lesson 1.2: Understand the OSGi configuration files

The OSGi sample includes configuration files that you use to start and configure the WXS grid and server.


OSGi configuration files

In this lesson, you will explore the following configuration files that are included with the OSGI sample:

collocated.server.properties

A server configuration is required to start a server. When the eXtreme Scale server bundle is started, it does not start a server. It waits for the configuration PID, com.ibm.websphere.xs.server, to be created with a server property file. This server property file specifies the server name, port number, and other server properties.

In most cases, you create a configuration to set the server property file. In rare cases, you might want only to start a server, with every property set to a default value. In that case, we can create a configuration called com.ibm.websphere.xs.server with value set to default.

The OSGi sample server properties file starts a single catalog. This sample property file starts a single catalog service and a container server in the OSGi framework process. eXtreme Scale clients connect to port 2809 and JMX clients connect to port 1099. The content of the sample server property file is:

serverName=collocatedServer
isCatalog=true
catalogClusterEndPoints=collocatedServer:localhost:6601:6602
traceSpec=ObjectGridOSGi=all=enabled
traceFile=logs/trace.log
listenerPort=2809
JMXServicePort=1099

protoBufObjectGrid.xml

The sample protoBufObjectGrid.xml ObjectGrid descriptor XML file contains the following content, with comments removed.

<objectGridConfig 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://ibm.com/ws/objectgrid/config ../objectGrid.xsd"
    xmlns="http://ibm.com/ws/objectgrid/config">

    <objectGrids>
        <objectGrid name="Grid" txTimeout="15">

            <bean id="ObjectGridEventListener"
                osgiService="myShardListener"/>

            <backingMap name="Map" readOnly="false"
                lockStrategy="PESSIMISTIC" lockTimeout="5" 
                copyMode="COPY_TO_BYTES"
                pluginCollectionRef="serializer"/>
                
        </objectGrid>
    </objectGrids>

    <backingMapPluginCollections>
        <backingMapPluginCollection id="serializer">
            <bean id="MapSerializerPlugin"
                osgiService="myProtoBufSerializer"/>"/>
        </backingMapPluginCollection>
    </backingMapPluginCollections>
 </objectGridConfig>

There are two plug-ins configured in this ObjectGrid descriptor XML file:

ObjectGridEventListener

The shard-level plug-in. For each ObjectGrid instance, there is an instance of ObjectGridEventListener. It is configured to use the OSGi service myShardListener. That means when the grid is created, the ObjectGridEventListener plug-in uses the OSGi service myShardListener with the highest service ranking available.

MapSerializerPlugin

The map-level plug-in. For the backing map namedMap, there is a MapSerializerPlugin plug-in configured. It is configured to use the OSGI service myProtoBufSerializer. That means when the map is created, the MapSerializerPlugin plug-in uses the service, myProtoBufSerializer, with the highest ranked service ranking available.

protoBufDeployment.xml

The deployment descriptor XML file describes the deployment policy for the grid named Grid, which uses five partitions. See the following code example of the XML file:

<deploymentPolicy 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ibm.com/ws/objectgrid/deploymentPolicy ../deploymentPolicy.xsd"
 xmlns="http://ibm.com/ws/objectgrid/deploymentPolicy">

  <objectgridDeployment objectgridName="Grid">
    <mapSet name="MapSet" numberOfPartitions="5">
      <map ref="Map"/>
    </mapSet>
  </objectgridDeployment>
</deploymentPolicy>

blueprint.xml

As an alternative to using the collocated.server.properties file in conjunction with configuration PID, com.ibm.websphere.xs.server, we can include the ObjectGrid XML and deployment XML files in an OSGi bundle, along with a Blueprint XML file as shown in the following example:

<blueprint 
   xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
       xmlns:objectgrid="http://www.ibm.com/schema/objectgrid"
       default-activation="lazy">
    
    <objectgrid:server id="server" isCatalog="true"
                name="server"
                tracespec="ObjectGridOSGi=all=enabled"
                tracefile="C:/Temp/logs/trace.log"
                workingDirectory="C:/Temp/working"
                jmxport="1099">
        <objectgrid:catalog host="localhost" port="2809"/>
    </objectgrid:server>
  
    <objectgrid:container id="container" 
  objectgridxml="/META-INF/objectgrid.xml" 
       deploymentxml="/META-INF/deployment.xml" 
  server="server"/>
</blueprint>


Module 2: Installing and starting eXtreme Scale bundles in the OSGi framework

Use the lessons in this module to install the eXtreme Scale server bundle into the OSGi container, and start the WXS server.

Starting the server in the OSGi framework does not mean that your OSGi bundles are ready to run. Configure the server properties and containers so that the OSGi bundles that you install are recognized and can run correctly.

After completing the lessons in this module, you will understand the concepts and know how to complete the following tasks:


Prerequisites

To complete this module, the following tasks are required before you begin:

Also prepare to access the following files to complete the lessons in this module:

We can expect to install and start the following bundles:


Lesson 2.1: Start the console and install the eXtreme Scale server bundle

In this lesson, you use the Equinox OSGi console to install the WXS server bundle.

  1. Use the following command to start the Equinox OSGi console:
    cd equinox_root 
    java -jar plugins\org.eclipse.osgi_3.6.1.R36x_v20100806.jar -console

  2. After the OSGi console is started, issue the ss command in the console, and the following bundles are started:

    If you completed the task, Installing eXtreme Scale bundles, then the bundle has already been activated. If the bundle is started, then stop the bundle before you complete this step.

     Eclipse Gemini output: 
    osgi> ss
    Framework is launched.
    id State Bundle
    0 ACTIVE org.eclipse.osgi_3.6.1.R36x_v20100806
    1 ACTIVE org.eclipse.osgi.services_3.2.100.v20100503
    2 ACTIVE org.eclipse.osgi.util_3.2.100.v20100503
    3 ACTIVE org.eclipse.equinox.cm_1.0.200.v20100520
    4 ACTIVE com.springsource.org.apache.commons.logging_1.1.1
    5 ACTIVE com.springsource.org.aopalliance_1.0.0
    6 ACTIVE org.springframework.aop_3.0.5.RELEASE
    7 ACTIVE org.springframework.asm_3.0.5.RELEASE
    8 ACTIVE org.springframework.beans_3.0.5.RELEASE
    9 ACTIVE org.springframework.context_3.0.5.RELEASE
    10 ACTIVE org.springframework.core_3.0.5.RELEASE
    11 ACTIVE org.springframework.expression_3.0.5.RELEASE
    12 ACTIVE org.apache.felix.fileinstall_3.0.2
    13 ACTIVE net.luminis.cmc_0.2.5
    14 ACTIVE org.eclipse.gemini.blueprint.core_1.0.0.RELEASE
    15 ACTIVE org.eclipse.gemini.blueprint.extender_1.0.0.RELEASE
    16 ACTIVE org.eclipse.gemini.blueprint.io_1.0.0.RELEASE
     Apache Aries output: 
    osgi> ss
    Framework is launched.
    id State Bundle
    0 ACTIVE org.eclipse.osgi_3.6.1.R36x_v20100806
    1 ACTIVE org.eclipse.osgi.services_3.2.100.v20100503
    2 ACTIVE org.eclipse.osgi.util_3.2.100.v20100503
    3 ACTIVE org.eclipse.equinox.cm_1.0.200.v20100520
    4 ACTIVE org.ops4j.pax.logging.pax-logging-api_1.6.3
    5 ACTIVE org.ops4j.pax.logging.pax-logging-service_1.6.3
    6 ACTIVE org.objectweb.asm.all_3.3.0
    7 ACTIVE org.apache.aries.blueprint_0.3.2.SNAPSHOT
    8 ACTIVE org.apache.aries.util_0.4.0.SNAPSHOT
    9 ACTIVE org.apache.aries.proxy_0.4.0.SNAPSHOT
    10 ACTIVE org.apache.felix.fileinstall_3.0.2
    11 ACTIVE net.luminis.cmc_0.2.5

  3. Install the objectgrid.jar bundle. To start a server in the Java virtual machine (JVM), you need to install a WXS server bundle. This eXtreme Scale server bundle can start a server and create containers. Use the following command to install the objectgrid.jar file:
    osgi> install file:///wxs_home/lib/objectgrid.jar
    See the following example:
    osgi> install file:///opt/wxs/ObjectGrid/lib/objectgrid.jar
    Equinox displays its bundle ID; for example:
    Bundle id is 19

    Remember: Your bundle ID might be different. The file path must be an absolute URL to the bundle path. Relative paths are not supported.


Lesson 2.2: Customize and configure the eXtreme Scale server

Use this lesson to customize and add the server properties to the WXS server.

  1. Edit the wxs_sample_osgi_root/projects/server/properties/collocated.server.properties file.

    1. Change the traceFile property to equinox_root/logs/trace.log.

  2. Save the file.

  3. Enter the following lines of code in the OSGI console to create the server configuration from the file. The following example is displayed on multiple lines for publication purposes.
    osgi> cm create com.ibm.websphere.xs.server
    osgi> cm put com.ibm.websphere.xs.server objectgrid.server.props wxs_sample_osgi_root/projects/server/properties/collocated.server.properties

  4. To view the configuration, run the following command:
    osgi> cm get com.ibm.websphere.xs.server
    Configuration for service (pid) "com.ibm.websphere.xs.server"
    (bundle location = null)
    key                      value
    ----                     ----
    objectgrid.server.props  wxs_sample_osgi_root/projects/server/properties/collocated.server.properties
    service.pid              com.ibm.websphere.xs.server


Lesson 2.3: Configure the eXtreme Scale container

Complete this lesson to configure a container, which includes the WXS ObjectGrid descriptor XML file and ObjectGrid deployment XML file. These files include the configuration for the grid and its topology.

To create a container, first create a configuration service using the managed service factory process identification number (PID), com.ibm.websphere.xs.container. The service configuration is a managed service factory, so we can create multiple service PIDs from the factory PID. Then, to start the container service, set the objectgridFile and deploymentPolicyFile PIDs to each service PID.

Complete the following steps to customize and add the server properties to the OSGi framework:

  1. In the OSGI console, enter the following command to create the container from the file:
    osgi> cm createf com.ibm.websphere.xs.container
    PID: com.ibm.websphere.xs.container-1291179621421-0

  2. Enter the following commands to bind the newly created PID to the ObjectGrid XML files.

    Remember: The PID number will be different from what is included in this example.

    osgi> cm put com.ibm.websphere.xs.container-1291179621421-0 objectgridFile wxs_sample_osgi_root/projects/server/META-INF/protoBufObjectgrid.xml
    
    osgi> cm put com.ibm.websphere.xs.container-1291179621421-0 deploymentPolicyFile wxs_sample_osgi_root/projects/server/META-INF/protoBufDeployment.xml

  3. Use the following command to display the configuration:
    osgi> cm get com.ibm.websphere.xs.container-1291760127968-0
    Configuration for service (pid) "com.ibm.websphere.xs.container-1291760127968-0"
    (bundle location = null)
    
    key                    value
    ------                 ------
    deploymentPolicyFile   /opt/wxs/ObjectGrid/samples/OSGiProto/server/META-INF/protoBufDeployment.xml
    objectgridFile         /opt/wxs/ObjectGrid/samples/OSGiProto/server/META-INF/protoBufObjectgrid.xml
    service.factoryPid     com.ibm.websphere.xs.container
    service.pid            com.ibm.websphere.xs.container-1291760127968-0


Lesson 2.4: Install the Google Protocol Buffers and sample plug-in bundles

Complete this tutorial to install the protobuf-java-2.4.0a-bundle.jar bundle and the ProtoBufSamplePlugins-1.0.0.jar plug-in bundle using the Equinox OSGi console.


Install the Google Protocol Buffers plug-in

Complete the following steps to install the Google Protocol Buffers plug-in.

In the OSGI console, enter the following command to install the plug-in:

osgi> install file:///wxs_sample_osgi_root/lib/com.google.protobuf_2.4.0a.jar
The following output is displayed:
Bundle ID is 21


Sample plug-in bundles overview

The OSGi sample includes five sample bundles that include eXtreme Scale plug-ins, including a custom ObjectGridEventListener and MapSerializerPlugin plug-in. The MapSerializerPlugin plug-in uses the Google Protocol Buffers sample and messages provided by the MapSerializerPlugin sample.

The following bundles are located in wxs_sample_osgi_root/lib directory: ProtoBufSamplePlugins-1.0.0.jar and the ProtoBufSamplePlugins-2.0.0.jar.

The blueprint.xml file has the following content with comments removed:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
 <bean id="myShardListener" class="com.ibm.websphere.samples.xs.proto.osgi.MyShardListenerFactory"/>
 <service ref="myShardListener" interface="com.ibm.websphere.objectgrid.plugins.osgi.PluginServiceFactory" ranking="1">
 </service>

 <bean id="myProtoBufSerializer" class="com.ibm.websphere.samples.xs.proto.osgi.ProtoMapSerializerFactory">
  <property name="keyType" value="com.ibm.websphere.samples.xs.serializer.app.proto.DataObjects1$OrderKey" />
  <property name="valueType" value="com.ibm.websphere.samples.xs.serializer.app.proto.DataObjects1$Order" />
 </bean>

 <service ref="myProtoBufSerializer" interface="com.ibm.websphere.objectgrid.plugins.osgi.PluginServiceFactory"
  ranking="1">
 </service>
</blueprint>

The Blueprint XML file exports two services, myShardListener and myProtoBufSerializer. These two services are referenced in the protoBufObjectgrid.xml file.


Install the sample plug-in bundle

Complete the following steps to install the ProtoBufSamplePlugins-1.0.0.jar bundle.

Run the following command in the Equinox OSGi console to install the ProtoBufSamplePlugins-1.0.0.jar plugin bundle:

osgi> install file:///wxs_sample_osgi_root/lib/ProtoBufSamplePlugins-1.0.0.jar
The following output is displayed:
Bundle ID is 22


Lesson 2.5: Start the OSGi bundles

The WXS server is packaged as an OSGi server bundle. Complete this lesson to install the eXtreme Scale server bundle as well as other OSGi bundles installed.

  1. Run the ss command to view the IDs for each bundle.
    osgi> ss
    
    Framework is launched.
    
    id State Bundle
    0 ACTIVE org.eclipse.osgi_3.6.1.R36x_v20100806
    1 ACTIVE org.eclipse.osgi.services_3.2.100.v20100503
    2 ACTIVE org.eclipse.osgi.util_3.2.100.v20100503
    3 ACTIVE org.eclipse.equinox.cm_1.0.200.v20100520
    4 ACTIVE com.springsource.org.apache.commons.logging_1.1.1
    5 ACTIVE com.springsource.org.aopalliance_1.0.0
    6 ACTIVE org.springframework.aop_3.0.5.RELEASE
    7 ACTIVE org.springframework.asm_3.0.5.RELEASE
    8 ACTIVE org.springframework.beans_3.0.5.RELEASE
    9 ACTIVE org.springframework.context_3.0.5.RELEASE
    10 ACTIVE org.springframework.core_3.0.5.RELEASE
    11 ACTIVE org.springframework.expression_3.0.5.RELEASE
    12 ACTIVE org.apache.felix.fileinstall_3.0.2
    13 ACTIVE net.luminis.cmc_0.2.5
    15 ACTIVE org.eclipse.gemini.blueprint.core_1.0.0.RELEASE
    16 ACTIVE org.eclipse.gemini.blueprint.extender_1.0.0.RELEASE
    17 ACTIVE org.eclipse.gemini.blueprint.io_1.0.0.RELEASE
    19 RESOLVED com.ibm.websphere.xs.server_7.1.1
    21 RESOLVED Google_ProtoBuf_2.4.0
    22 RESOLVED ProtoBufPlugins_1.0.0

  2. Start each bundle installed. Start the bundles in a specific order. See the order of the bundle IDs from the previous example.

    1. Start the sample plug-in bundle, ProtoBufPlugins_1.0.0. Run the following command in the Equinox OSGi console to start the bundle. In this example, the bundle ID of the sample plug-in is 22.
      osgi> start 22
    2. Start the Google Protocol Buffers bundle, Google_ProtoBuf_2.4.0. Run the following command in the Equinox OSGi console to start the bundle. In this example, the bundle ID of the Google Protocol Buffers plug-in is 21.
      osgi> start 21
    3. Start the server bundle, com.ibm.websphere.xs.server_7.1.1. Run the following command in the OSGi console to start the server. In this example, the bundle ID of the eXtreme Scale server bundle is 19.
      osgi> start 19

After you start the server, the MyShardListener event listener is started and ready to insert or update records. We can see the following output on the OSGi console to confirm that the plug-in bundle has started successfully:

SystemOut O MyShardListener@1253853884(version=1.0.0) order
com.ibm.websphere.samples.xs.serializer.proto.DataObjects1$Order$Builder
@1aba1aba(22) inserted


Module 3: Running the eXtreme Scale sample client

The WXS server is now running in an OSGi environment. Complete the steps in this module to run an WXS client that inserts data into the grid.

Learning objectives

After completing the lessons in this module you will know how to complete the following tasks:


Prerequisites

Complete Module 2: Installing and starting eXtreme Scale bundles in the OSGi framework .


Lesson 3.1: Set up Eclipse to run the client and build the samples

Complete this lesson to import the Eclipse project that you will use to run the client and build the sample plug-ins.

The sample includes a Java SE client program that connects to the grid and inserts and retrieves data from it. It also includes projects that we can use to build and redeploy the OSGi bundles.

The provided project has been tested with Eclipse 3.x and later, and requires only the standard Java development project perspective. Complete the following steps to set up of your WXS development environment.

  1. Open Eclipse to a new or existing workspace.

  2. From the File menu, select Import.

  3. Expand the General folder. Select Existing Projects into Workspace, and click Next.

  4. In the Select root directory field, type or browse to the wxs_sample_osgi_root directory. Click Finish. Several new projects are displayed in your workspace. Build errors will be fixed by defining two user libraries. Complete the next steps to define the user libraries.

  5. From the Window menu, select Preferences.

  6. Expand the Java > Build Path branch, and select User Libraries.

  7. Define the eXtreme Scale user library.

    1. Click New.
    2. Type

      eXtremeScale in the User Library Name field, and click OK.

    3. Select the new user library, and click Add JARs.

      1. Browse and select the objectgrid.jar file from the wxs_install_root/lib directory. Click OK.
      2. To include API documentation for the ObjectGrid APIs, select the API documentation location for the objectgrid.jar file that you added in the previous step. Click Edit.
      3. In the location path box for the API documentation, select the Javadoc.zip file that is included in the following directory: wxs_install_root/docs/javadoc.zip.

  8. Define the Google Protocol Buffers user library.

    1. Click New.
    2. Type

      com.google.protobuf in the User Library Name field, and click OK.

    3. Select the new user library, and click Add JARs.

      1. Browse and select the com.google.protobuf_2.4.0.a.jar file from the wxs_sample_osgi_root/lib directory. Click OK.


Lesson 3.2: Start a client and insert data into the grid

Complete this lesson to start a non-OSGi client and run a client application.

The Java client application is com.ibm.websphere.samples.xs.proto.client.Client. The Eclipse project, wxs.sample.osgi.protobuf.client, contains the Java client application. The main class file is com.ibm.websphere.samples.xs.proto.client.Client.

This client uses a client override, ObjectGrid descriptor XML file to override the OSGi configuration, so that the client can run in a non-OSGi environment. See the following content of the file with comments and headers removed.

<objectGridConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://ibm.com/ws/objectgrid/config ../objectGrid.xsd"
    xmlns="http://ibm.com/ws/objectgrid/config">

    <objectGrids>
        <objectGrid name="Grid" txTimeout="15">
            <bean id="ObjectGridEventListener" className="" osgiService=""/>
            <backingMap name="Map" readOnly="false"
                lockStrategy="PESSIMISTIC" lockTimeout="5" 
                copyMode="COPY_TO_BYTES" pluginCollectionRef="serializer"/>
                
        </objectGrid>
    </objectGrids>

    <backingMapPluginCollections>
        <backingMapPluginCollection id="serializer">
                 
   <bean id="MapSerializer"   
   className="com.ibm.websphere.samples.xs.serializer.proto.ProtoMapSerializer" 
       osgiService="">
    <property name="keyType" type="java.lang.String" 
        value="com.ibm.websphere.samples.xs.serializer.proto.DataObjects2$OrderKey" />
          <property name="valueType" type="java.lang.String" 
              value="com.ibm.websphere.samples.xs.serializer.proto.DataObjects2$Order" />
   </bean>
  </backingMapPluginCollection>
    </backingMapPluginCollections>
</objectGridConfig>

Click Run As > Java Application to run the client application.

When we run the application, the following message is displayed. The message indicates that an order was inserted:

order
com.ibm.websphere.samples.xs.serializer.proto.DataObjects1$Order$Builder@5d165d16(5000000) inserted


Module 4: Querying and upgrading the sample bundle

Complete the lessons in this module to use the xscmd command to query the service ranking of the sample bundle, upgrade it to a new service ranking, and verify the new service ranking.


Objectives

After completing the lessons in this module you will know how to complete the tasks:


Prerequisites

Complete Module 3: Running the eXtreme Scale sample client


Lesson 4.1: Query service rankings

Complete this lesson to query current service rankings as well as those service rankings that are available for upgrade.


Lesson 4.2: Determine whether specific service rankings are available

Complete this lesson to determine whether specific service rankings are available for the service names that you specify.

  1. Enter the following command to determine whether the service named myShardListener, with service ranking 2 and service named myProtoBufSerializer, with service ranking 2 are available. The service ranking list is passed in using -sr option.

    To determine whether the services are available:

    cd wxs_home/bin
    ./xscmd.sh -c osgiCheck -sr "myShardListener;2,myProtoBufSerializer;2" 
    

    The following output is displayed:

    CWXSI0040I: The command osgiCheck has completed successfully.

  2. Enter the following command to determine whether the service named myShardListener, with service ranking 2 and the service named myProtoBufSerializer, with service ranking 3 are available.

    1. Switch to the following directory:
      cd wxs_home/bin
    2. Enter the following command to determine whether the services are available:
      ./xscmd.sh -c osgiCheck -sr "myShardListener;2,myProtoBufSerializer;3" 
      The following output is displayed:
      Server           OSGi Service         Unavailable Rankings
      ------           ------------         --------------------
      collocatedServer myProtoBufSerializer          3


Lesson 4.3: Update the service rankings

Complete this lesson to update current service rankings that you queried.

  1. Update the service rankings of the services, myShardListener and myProtoBufSerializer, to service ranking 2. The service ranking list is passed in using -sr option.

    1. Switch to the following directory:
      cd wxs_home/bin

    2. Enter the following command to update the service rankings:
      ./xscmd.sh -c osgiUpdate -g Grid -ms MapSet -sr "myShardListener;2,myProtoBufSerializer;2" 
      The following output is displayed:
      Update succeeded for the following service rankings:
      Service              Ranking
      -------              -------
      myProtoBufSerializer 2
      myShardListener      2
      
      CWXSI0040I: The command osgiUpdate has completed successfully.
      The following output is displayed on the OSGi console:
      SystemOut O MyShardListener@326505334(version=2.0.0) order
      com.ibm.websphere.samples.xs.serializer.proto.DataObjects2$Order$Builder@
      22342234(34) updated
      Notice that the MyShardListener service is now version 2.0.0, which has service ranking 2.

  2. Run the xscmd command to query the current service ranking for all services used by the ObjectGrid named Grid and the map set named MapSet.

    1. Switch to the following directory:
      cd wxs_home/bin
    2. Enter the following command to query the service rankings for all services used by Grid and MapSet:
      ./xscmd.sh -c osgiCurrent -g Grid -ms MapSet 
      The following output is displayed:
      OSGi Service Name    Current Ranking ObjectGrid Name MapSet Name Server Name
      -----------------    --------------- --------------- ----------- -----------
      myProtoBufSerializer 2               Grid            MapSet      collocatedServer
      myShardListener      2               Grid            MapSet      collocatedServer
      
      CWXSI0040I: The command osgiCurrent has completed successfully.