Copypackage com.cisco.pxgrid.samples.ise;
import java.io.IOException;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.websocket.Session;
import org.apache.commons.cli.ParseException;
import org.glassfish.tyrus.client.ClientManager;
import org.glassfish.tyrus.client.ClientProperties;
import org.glassfish.tyrus.client.SslEngineConfigurator;
import org.glassfish.tyrus.client.auth.Credentials;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.cisco.pxgrid.samples.ise.model.AccountState;
import com.cisco.pxgrid.samples.ise.model.Service;
import com.cisco.pxgrid.samples.ise.model.ServiceRegisterResponse;
import com.google.gson.Gson;
/**
* Demonstrate how to create a custom service that publishes data
*
* The flow of the application is as follows:
* 1. Parse arguments for configurations
* 2. Activate Account. This will then require ISE Admin to approve this new node.
* 3. pxGrid ServiceRegister to register the new custom service
* 4. Schedule periodic pxGrid ServiceReregister to signify the service is still alive
* 5. pxGrid ServiceLookup for ISE pubsub service
* 6. pxGrid get AccessSecret for the ISE pubsub node
* 7. Establish WebSocket connection with the ISE pubsub node
* 8. Establish STOMP connection for pubsub messaging
* 9. Schedule periodic publish of data
* 10. Wait for keyboard input for stopping the application
*/
public class ContextInPublishing {
private static Logger logger = LoggerFactory.getLogger(ContextInPublishing.class);
public static void main(String[] args) throws Exception {
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
// Parse arguments
SampleConfiguration config = new SampleConfiguration();
try {
config.parse(args);
} catch (ParseException e) {
config.printHelp("CustomServiceProvider");
System.exit(1);
}
// AccountActivate
PxgridControl control = new PxgridControl(config);
while (control.accountActivate() != AccountState.ENABLED) {
Thread.sleep(60000);
}
logger.info("pxGrid controller version={}", control.getControllerVersion());
// pxGrid ServiceRegister
Map<String, String> sessionProperties = new HashMap<>();
sessionProperties.put("wsPubsubService", "com.cisco.ise.pubsub");
sessionProperties.put("assetTopic", "/topic/com.cisco.endpoint.asset");
ServiceRegisterResponse response = control.serviceRegister("com.cisco.endpoint.asset", sessionProperties);
String registrationId = response.getId();
long reregisterTimeMillis = response.getReregisterTimeMillis();
// Schedule pxGrid ServiceReregister
executor.scheduleWithFixedDelay(() -> {
try {
control.serviceReregister(registrationId);
} catch (IOException e) {
logger.error("Reregister failure");
}
}, reregisterTimeMillis, reregisterTimeMillis, TimeUnit.MILLISECONDS);
// pxGrid ServiceLookup for pubsub service
Service[] services = control.serviceLookup("com.cisco.ise.pubsub");
if (services.length == 0) {
logger.info("Pubsub service unavailabe");
return;
}
// Use first service
Service wsPubsubService = services[0];
String wsURL = wsPubsubService.getProperties().get("wsUrl");
logger.info("wsUrl={}", wsURL);
// pxGrid AccessSecret
String secret = control.getAccessSecret(wsPubsubService.getNodeName());
// Setup WebSocket client
ClientManager client = ClientManager.createClient();
SslEngineConfigurator sslEngineConfigurator = new SslEngineConfigurator(config.getSSLContext());
client.getProperties().put(ClientProperties.SSL_ENGINE_CONFIGURATOR, sslEngineConfigurator);
client.getProperties().put(ClientProperties.CREDENTIALS,
new Credentials(config.getNodeName(), secret.getBytes()));
// WebSocket connect
StompPubsubClientEndpoint endpoint = new StompPubsubClientEndpoint();
URI uri = new URI(wsURL);
Session session = client.connectToServer(endpoint, uri);
// STOMP connect
endpoint.connect(uri.getHost());
Asset asset = new Asset();
asset.setAssetId("1");
asset.setAssetName("pxGrid2-PC");
asset.setAssetIpAddress("10.0.0.21");
asset.setAssetMacAddress("00:0C:29:C1:7B:2C");
asset.setAssetHwRevision("5.6");
asset.setAssetProtocol("CIP");
AssetConnectedLink[] assetConnectedLinks = new AssetConnectedLink[1];
AssetConnectedLink link = new AssetConnectedLink();
link.setKey("indattr1");
link.setValue("1");
assetConnectedLinks[0] = link;
// Define the number of custom attributes
AssetCustomAttribute[] assetCustomAttributes = new AssetCustomAttribute[3];
// Add each custom attribute to each object. Here it is for the DeviceType customAttribute.
AssetCustomAttribute deviceTypeattr = new AssetCustomAttribute();
deviceTypeattr.setKey("DeviceType");
deviceTypeattr.setValue("1");
assetCustomAttributes[0] = deviceTypeattr;
// Add the seconds custom attribute to each object. Here it is for the Score customAttribute.
AssetCustomAttribute scoreAttr = new AssetCustomAttribute();
scoreAttr.setKey("Score");
scoreAttr.setValue("10");
assetCustomAttributes[1] = scoreAttr;
// Add the seconds custom attribute to each object. Here it is for the Manufacturer customAttribute
AssetCustomAttribute manufacturerAttr = new AssetCustomAttribute();
manufacturerAttr.setKey("Manufacturer");
manufacturerAttr.setValue("Apple");
assetCustomAttributes[2] = manufacturerAttr;
// Finally add all the three custom attributes using a single array to the asset object which is sent to the pxGrid topic
asset.setAssetCustomAttributes(assetCustomAttributes);
/** If there is a need to add another attribute (for example, SoftwareType), first increase the array size by replacing the following command mentioned in the definition of custom attributes earlier:
* AssetCustomAttribute[] assetCustomAttributes = new AssetCustomAttribute[3];
* with
* AssetCustomAttribute[] assetCustomAttributes = new AssetCustomAttribute[4];
*
* Now add the new customAttribute to the array using the following commands. Here it is for the Software customAttribute.
* AssetCustomAttribute softwareAttr = new AssetCustomAttribute();
* softwareAttr.setKey(“SoftwareAttribute”);
* softwareAttr.setValue("Apple");
* assetCustomAttributes[3] = softwareAttr;
*/
AssetOperation assetOperation = new AssetOperation();
assetOperation.setAsset(asset);
assetOperation.setOpType("UPDATE");
Gson gson = new Gson();
String data = gson.toJson(assetOperation);
// STOMP send periodically
executor.scheduleWithFixedDelay(() -> {
try {
endpoint.publish("/topic/com.cisco.endpoint.asset", data.getBytes() );
} catch (IOException e) {
logger.error("Publish failure");
}
}, 0, 5, TimeUnit.SECONDS);
SampleHelper.prompt("press <enter> to disconnect...");
// pxGrid ServerUnregister
control.unregisterService(registrationId);
// Stop executor
executor.shutdown();
executor.awaitTermination(5, TimeUnit.SECONDS);
// STOMP disconnect
endpoint.disconnect("ID-123");
// Wait for disconnect receipt
Thread.sleep(3000);
// Websocket close
session.close();
}
private static class Asset {
private String assetId;
private String assetName;
private String assetIpAddress;
private String assetMacAddress;
private String assetVendor;
private String assetProductId;
private String assetSerialNumber;
private String assetDeviceType;
private String assetSwRevision;
private String assetHwRevision;
private String assetProtocol;
private AssetCustomAttribute assetCustomAttributes[];
private AssetConnectedLink assetConnectedLinks[];
public void setAssetId(String assetId) {
this.assetId = assetId;
}
public void setAssetName(String assetName) {
this.assetName = assetName;
}
public void setAssetIpAddress(String assetIpAddress) {
this.assetIpAddress = assetIpAddress;
}
public void setAssetMacAddress(String assetMacAddress) {
this.assetMacAddress = assetMacAddress;
}
public void setAssetVendor(String assetVendor) {
this.assetVendor = assetVendor;
}
public void setAssetProductId(String assetProductId) {
this.assetProductId = assetProductId;
}
public void setAssetSerialNumber(String assetSerialNumber) {
this.assetSerialNumber = assetSerialNumber;
}
public void setAssetDeviceType(String assetDeviceType) {
this.assetDeviceType = assetDeviceType;
}
public void setAssetSwRevision(String assetSwRevision) {
this.assetSwRevision = assetSwRevision;
}
public void setAssetHwRevision(String assetHwRevision) {
this.assetHwRevision = assetHwRevision;
}
public void setAssetProtocol(String assetProtocol) {
this.assetProtocol = assetProtocol;
}
public void setAssetCustomAttributes(AssetCustomAttribute[] assetCustomAttributes) {
this.assetCustomAttributes = assetCustomAttributes;
}
public void setAssetConnectedLinks(AssetConnectedLink[] assetConnectedLinks) {
this.assetConnectedLinks = assetConnectedLinks;
}
}
private static class AssetOperation {
private Asset asset;
private String opType;
public void setAsset(Asset asset) {
this.asset = asset;
}
public void setOpType(String opType) {
this.opType = opType;
}
}
private static class AssetCustomAttribute {
private String key;
private String value;
public void setKey(String key) {
this.key = key;
}
public void setValue(String value) {
this.value = value;
}
}
private static class AssetConnectedLink {
private String key;
private String value;
public void setKey(String key) {
this.key = key;
}
public void setValue(String value) {
this.value = value;
}
}
}