ThingWorx Edge Java SDK Edge Extensions > Example ETT Implementation
Example ETT Implementation
Any new ETS class must extend EdgeThingShape so that it can participate in the required life cycle of an ETS. Optionally, an ETS can use annotations to configure itself with the required metadata to participate in the life cycle of its parent Edge Thing Template (ETT).
Demonstrates composition rather than inheritance - object oriented design principle. Ongoing thing in platform. Edge development should mirror platform dev. So do things same way - object oriented. SEE https://thingworx.jira.com/wiki/spaces/Prod/pages/86507549/Java+Edge+Thing+Shape+Framework+Design+Specification
Creating an Edge Thing Template with Two Edge Thing Shapes
The following example shows an Edge Thing Template that will reference two Edge Thing Shapes. The ETT represents a Thing that is the model for a warehouse that stores an inventory of items. It is composed of an address ETS and an inventory ETS.
package com.thingworx.sdk.edgethingshapes.demos.simple;

import com.thingworx.communications.client.ConnectedThingClient;
import com.thingworx.communications.client.things.EdgeThingTemplate;
import com.thingworx.communications.client.things.exceptions.
InvalidAnnotationArgumentException;
import com.thingworx.metadata.annotations.ThingworxEdgeThingShapeDefinition;
import com.thingworx.metadata.annotations.ThingworxEdgeThingShapeDefinitions;
import com.thingworx.metadata.annotations.ThingworxPropertyDefinition;
import com.thingworx.metadata.annotations.ThingworxPropertyDefinitions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ThingworxPropertyDefinitions(properties = {
@ThingworxPropertyDefinition(name = "instanceName",
description = "Instance Name", category = "",
baseType = "STRING", aspects = {"isReadOnly:false", "defaultValue:unknown"})
})
@ThingworxEdgeThingShapeDefinitions(shapes = {
@ThingworxEdgeThingShapeDefinition(className =
"com.thingworx.sdk.edgethingshapes.demos.simple.AddressEdgeShape",
name = "AddressEdgeShape"),
@ThingworxEdgeThingShapeDefinition(className =
"com.thingworx.sdk.edgethingshapes.demos.simple.InventoryEdgeShape",
name = "InventoryEdgeShape"),

})
public class WarehouseEdgeTemplate extends EdgeThingTemplate {
private static final Logger LOG = LoggerFactory.getLogger(WarehouseEdgeTemplate.class);

public WarehouseEdgeTemplate(String name, String description, ConnectedThingClient client) throws
InvalidAnnotationArgumentException {
super(name, description, client);
}

}
Above you can see that this ETT is composed of the AddressEdgeShape and the InventoryEdgeShape. Here, the full class names of the shapes are listed.
The name attribute that is used in this example is not required because the className attribute should be used when the name is not given. Use the name attribute in cases where the ETS is used more than once within the same ETT.
Creating the AddressEdgeShape
In the following example, the AddressEdgeShape is defined. This shape establishes properties for a name and an address and could be reused to add this functionality to any template in the future.
package com.thingworx.sdk.edgethingshapes.demos.simple;

import com.thingworx.communications.client.things.EdgeThingShape;
import com.thingworx.communications.client.things.EdgeThingTemplate;
import com.thingworx.metadata.annotations.ThingworxPropertyDefinition;
import com.thingworx.metadata.annotations.ThingworxPropertyDefinitions;
import com.thingworx.metadata.annotations.ThingworxServiceDefinition;
import com.thingworx.metadata.annotations.ThingworxServiceParameter;
import com.thingworx.metadata.annotations.ThingworxServiceResult;
import com.thingworx.types.constants.CommonPropertyNames;

/**
* This class represents reusable functionality which establishes the
* most common properties used to store an address.
* It also provides a service which composes a salutation line for an
* email to this address.
* This class is intended to be used as a simple example of an Edge Thing Shape.
*/
@ThingworxPropertyDefinitions(properties = {
@ThingworxPropertyDefinition(name = "category", description = "",
category = "Address ETS", baseType = "STRING",
aspects = {"isReadOnly:false" }),
@ThingworxPropertyDefinition(name = "firstName", description = "",
category = "Address ETS", baseType = "STRING",
aspects = {"isReadOnly:false" }),
@ThingworxPropertyDefinition(name = "lastName", description = "",
category = "Address ETS", baseType = "STRING",
aspects = {"isReadOnly:false" }),
@ThingworxPropertyDefinition(name = "address", description = "",
category = "Address ETS", baseType = "STRING",
aspects = {"isReadOnly:false" }),
@ThingworxPropertyDefinition(name = "city", description = "",
category = "Address ETS", baseType = "STRING",
aspects = {"isReadOnly:false" }),
@ThingworxPropertyDefinition(name = "state", description = "",
category = "Address ETS", baseType = "STRING",
aspects = {"isReadOnly:false" }),
@ThingworxPropertyDefinition(name = "zip", description = "",
category = "Address ETS", baseType = "STRING",
aspects = {"isReadOnly:false" }),
@ThingworxPropertyDefinition(name = "yearsAtLocation", description = "",
category = "Address ETS", baseType = "NUMBER",
aspects = {"isReadOnly:false" })
})
public class AddressEdgeShape extends EdgeThingShape {

public AddressEdgeShape(EdgeThingTemplate thingInstance, String identifier,
boolean usesNamespace) {
super(thingInstance, identifier,usesNamespace);
}

/**
* Creates a standard salutation line for use in an email.
* @param title should contain Mr, Ms, Mrs or Dr
* @return valid salutation sentence
*/
@ThingworxServiceDefinition( name="generateSalutation", description=
"Generates a salutation phrase for an email")
@ThingworxServiceResult( name = CommonPropertyNames.PROP_RESULT,
description="Formatted Salutation", baseType="STRING" )
public String generateSalutation(@ThingworxServiceParameter( name="title",
description="Ms,Mrs,Dr or Mr", baseType="STRING" ) String title){
return "Dear "+ title+ " "+getPropertyAsString("firstName")+" "+getPropertyAsString("lastName");
}
}
Creating the InventoryEdgeShape
Finally, the following example defines the inventory shape. This shape adds an InfoTable property to store inventory and a service to add new inventory items. It also uses annotations to define the Data Shape used for the inventory InfoTable.
package com.thingworx.sdk.edgethingshapes.demos.simple;

import com.thingworx.communications.client.things.EdgeThingShape;
import com.thingworx.communications.client.things.EdgeThingTemplate;
import com.thingworx.metadata.DataShapeDefinition;
import com.thingworx.metadata.annotations.ThingworxDataShapeDefinition;
import com.thingworx.metadata.annotations.ThingworxDataShapeDefinitions;
import com.thingworx.metadata.annotations.ThingworxFieldDefinition;
import com.thingworx.metadata.annotations.ThingworxPropertyDefinition;
import com.thingworx.metadata.annotations.ThingworxPropertyDefinitions;
import com.thingworx.metadata.annotations.ThingworxServiceDefinition;
import com.thingworx.metadata.annotations.ThingworxServiceParameter;
import com.thingworx.metadata.annotations.ThingworxServiceResult;
import com.thingworx.types.InfoTable;
import com.thingworx.types.collections.ValueCollection;
import com.thingworx.types.constants.CommonPropertyNames;
import com.thingworx.types.primitives.InfoTablePrimitive;
import com.thingworx.types.primitives.NumberPrimitive;
import com.thingworx.types.primitives.StringPrimitive;
import org.slf4j.LoggerFactory;

/**
* This class establishes and maintains the inventory of a business.
* It creates an inventory list, exposes it as a property, and
* creates a service to add new products to the inventory.
* This class is intended to be used as a simple example of an
* Edge Thing Shape.
*/
@ThingworxPropertyDefinitions(properties = {
@ThingworxPropertyDefinition(name = "inventory", description = "",
category = "Inventory ETS", baseType = "INFOTABLE",
aspects = {"isReadOnly:false" }),
})
@ThingworxDataShapeDefinitions(dataShapes = {
@ThingworxDataShapeDefinition(name = "inventoryItem",fields={
@ThingworxFieldDefinition(name = "price",baseType = "NUMBER"),
@ThingworxFieldDefinition(name = "description",baseType = "STRING")
})
})
public class InventoryEdgeShape extends EdgeThingShape {

private static final org.slf4j.Logger LOG = LoggerFactory.getLogger (InventoryEdgeShape.class);

public InventoryEdgeShape(EdgeThingTemplate thingInstance,
String identifier,boolean usesNamespace) {
super(thingInstance, identifier,usesNamespace);
}

/**
* Adds a new product to the inventory
*
* @param description a description of this item
* @param price the cost of this item
*/
@ThingworxServiceDefinition( name="addProduct",
description="Adds A product to the Inventory")
@ThingworxServiceResult( name = CommonPropertyNames.PROP_RESULT,
description="Nothing", baseType="NOTHING" )
public void addProduct(
@ThingworxServiceParameter( name="description", description=
"Description of Inventory Item",baseType="STRING" )
String description,

@ThingworxServiceParameter( name="price",
description="Price of Inventory Item",
baseType="NUMBER" ) Double price
){
InfoTablePrimitive inventoryTable =
(InfoTablePrimitive) getProperty("inventory").getValue();
DataShapeDefinition dd = getDataShapeDefinition("inventoryItem");
InfoTable inventoryTableVal = inventoryTable.getValue();
inventoryTableVal.setDataShape(dd);

ValueCollection vc = new ValueCollection();
vc.put("description",new StringPrimitive(description));
vc.put("price",new NumberPrimitive(price));
inventoryTableVal.addRow(vc);

try {
getThingInstance().setPropertyValue("inventory",
new InfoTablePrimitive(inventoryTableVal));
} catch (Exception e) {
e.printStackTrace();
}

}

/**
* Returns the entire inventory as an InfoTable
* @return current inventory
*/
@ThingworxServiceDefinition( name="currentInventory",
description="displays the Inventory")
@ThingworxServiceResult( name = CommonPropertyNames.PROP_RESULT,
description="The inventory", baseType="INFOTABLE" )
public InfoTable currentInventory( ){
InfoTablePrimitive inventoryTable = (InfoTablePrimitive)
getProperty("inventory").getValue();
InfoTable inventoryTableVal = inventoryTable.getValue();
return inventoryTableVal;
}

}
Was this helpful?