diff --git a/gateways/Gateways.md b/gateways/Gateways.md index ea5f3896..e9a8b9e1 100644 --- a/gateways/Gateways.md +++ b/gateways/Gateways.md @@ -16,6 +16,8 @@ A fjåge Gateway connects to a fjåge master container and sends/receives messag - `action: send` : parse and process the messsage as per the Gateway logic. - `action: shutdown` : close and stop the Gateway +All gateway agents should use names prefixed with `gateway-`. + ### `Gateway()` :: String hostname, Int port, (String settings) -> Gateway - Creates a gateway connecting to a specified master container specified by the arguments. diff --git a/gateways/c/src/fjage.c b/gateways/c/src/fjage.c index d15a3583..92b0832f 100644 --- a/gateways/c/src/fjage.c +++ b/gateways/c/src/fjage.c @@ -550,7 +550,7 @@ fjage_gw_t fjage_tcp_open(const char* hostname, int port) { fgw->intr = 0; #endif char s[64]; - sprintf(s, "CGateway-%08x", rand()); + sprintf(s, "gateway-%08x", rand()); fgw->aid = fjage_aid_create(s); fgw->head = 0; update_watch(fgw); diff --git a/gateways/js/src/fjage.js b/gateways/js/src/fjage.js index edc775ba..aeb159a3 100644 --- a/gateways/js/src/fjage.js +++ b/gateways/js/src/fjage.js @@ -356,7 +356,7 @@ export class Gateway { this.queue = []; // incoming message queue this.connected = false; // connection status this.debug = false; // debug info to be logged to console? - this.aid = new AgentID((isBrowser ? 'WebGW-' : 'NodeGW-')+_guid(4)); // gateway agent name + this.aid = new AgentID('gateway-'+_guid(4)); // gateway agent name this.connector = this._createConnector(url); this._addGWCache(this); } diff --git a/gateways/python/fjagepy/__init__.py b/gateways/python/fjagepy/__init__.py index c66ec69d..b67f98c1 100644 --- a/gateways/python/fjagepy/__init__.py +++ b/gateways/python/fjagepy/__init__.py @@ -555,7 +555,7 @@ def __init__(self, hostname, port=1100): self.logger = _log.getLogger('org.arl.fjage') self.cancel = False try: - self.aid = AgentID("PythonGW-" + str(_uuid.uuid4()), owner=self) + self.aid = AgentID("gateway-" + str(_uuid.uuid4()), owner=self) self.q = list() self.subscriptions = list() self.pending = dict() diff --git a/src/main/groovy/org/arl/fjage/shell/BaseGroovyScript.groovy b/src/main/groovy/org/arl/fjage/shell/BaseGroovyScript.groovy index ef6097bc..21737409 100644 --- a/src/main/groovy/org/arl/fjage/shell/BaseGroovyScript.groovy +++ b/src/main/groovy/org/arl/fjage/shell/BaseGroovyScript.groovy @@ -103,9 +103,10 @@ abstract class BaseGroovyScript extends Script { /** * Lists all the agents. * + * @param all true to list all agents, false to hide special agents. * @return a string representation of all agents. */ - String ps() { + String ps(boolean all=false) { Binding binding = getBinding() if (binding.hasVariable('__agent__')) { Agent a = binding.getVariable('__agent__') @@ -114,6 +115,7 @@ abstract class BaseGroovyScript extends Script { StringBuffer s = new StringBuffer() boolean first = true for (AgentID aid: agentIDs) { + if (!all && aid.name.contains('-')) continue // hide gateways and other special agents if (!first) s.append('\n') s.append(aid) if (aid.type == null) s.append(': REMOTE') diff --git a/src/main/java/org/arl/fjage/Container.java b/src/main/java/org/arl/fjage/Container.java index 6f030c00..8ccde170 100644 --- a/src/main/java/org/arl/fjage/Container.java +++ b/src/main/java/org/arl/fjage/Container.java @@ -14,6 +14,7 @@ import java.lang.reflect.*; import java.util.*; import java.util.concurrent.*; +import java.util.regex.*; import java.util.logging.Logger; /** @@ -38,6 +39,8 @@ public class Container { //////////// Private attributes + private static final Pattern NAME_PATTERN = Pattern.compile("^[a-zA-Z_][a-zA-Z0-9_]*$"); + protected String name; protected Platform platform; protected Map agents = new ConcurrentHashMap(); @@ -189,6 +192,14 @@ public boolean getAutoClone() { /** * Adds an agent to the container. + *

+ * Agent names should only contain alphanumeric characters and underscores. + * The first character should not be a digit. Names with special characters + * such as '-', '.', '@', etc are considered reserved and should be avoided. + *

+ * While agent names inconsistent with this guideline may not be rejected + * today, they may not work well on all platforms. In future, we may enforce + * this guideline more strictly. * * @param name name of the agent. * @param agent the agent object. @@ -199,6 +210,8 @@ public AgentID add(String name, Agent agent) { log.warning("Undefined agent name"); return null; } + Matcher matcher = NAME_PATTERN.matcher(name); + if (!matcher.matches()) log.warning("Agent name "+name+" does not meet naming guidelines and may be disallowed in future"); AgentID aid = new AgentID(name); aid.setType(agent.getClass().getName()); if (isDuplicate(aid)) { @@ -227,7 +240,7 @@ public AgentID add(String name, Agent agent) { * @return an agent id if successful, null on failure. */ public AgentID add(Agent agent) { - return add(agent.getClass().getName()+"@"+agent.hashCode(), agent); + return add(agent.getClass().getSimpleName()+"_"+agent.hashCode(), agent); } /** diff --git a/src/main/java/org/arl/fjage/remote/Gateway.java b/src/main/java/org/arl/fjage/remote/Gateway.java index e8449769..c6c03065 100644 --- a/src/main/java/org/arl/fjage/remote/Gateway.java +++ b/src/main/java/org/arl/fjage/remote/Gateway.java @@ -177,7 +177,7 @@ public boolean authenticate(String creds) { * @return agent ID */ public AgentID getAgentID() { - return new AgentID("JavaGateway-"+hashCode()); + return new AgentID("gateway-"+hashCode()); } /**