From 1b6d1647e8b4f20279027c70a526614f99d38de0 Mon Sep 17 00:00:00 2001
From: Carolyn Beeton <cbeeton@nortel.com>
Date: Mon, 12 Jan 2009 12:12:03 -0500
Subject: [PATCH] XECS-845 extend authrules.xml with dial rule type to enable Emergency Notification

---
 .../neoconf/etc/sipxproxy/sipXproxy-config.vm      |    3 +
 .../sipxconfig/admin/dialplan/DialingRule.java     |    4 +
 .../sipxconfig/admin/dialplan/EmergencyRule.java   |    5 ++
 .../sipxconfig/admin/dialplan/IDialingRule.java    |    6 ++
 .../admin/dialplan/config/AuthRules.java           |    6 +-
 .../admin/dialplan/config/RulesXmlFile.java        |   16 +++++
 .../admin/dialplan/config/AuthRulesTest.java       |   69 +++++++++++++++++++-
 .../config/authrules-internal-target-perm.test.xml |    2 +-
 .../sipxconfig/service/expected-proxy-config       |    3 +
 9 files changed, 109 insertions(+), 5 deletions(-)

diff --git a/sipXconfig/neoconf/etc/sipxproxy/sipXproxy-config.vm b/sipXconfig/neoconf/etc/sipxproxy/sipXproxy-config.vm
index ee71bda..cdb5dfb 100644
--- a/sipXconfig/neoconf/etc/sipxproxy/sipXproxy-config.vm
+++ b/sipXconfig/neoconf/etc/sipxproxy/sipXproxy-config.vm
@@ -35,3 +35,6 @@ SIPX_PROXY.400_authrules.IDENTITY_VALIDITY_SECONDS : 300
 SIPX_PROXY_HOOK_LIBRARY.700_fromalias : @sipxpbx.lib.dir@/authplugins/libCallerAlias.so
 
 SIPX_PROXY_HOOK_LIBRARY.900_ntap : @sipxpbx.lib.dir@/authplugins/libNatTraversalAgent.so
+
+SIPX_PROXY_HOOK_LIBRARY.990_emergnotif: @sipxpbx.lib.dir@/authplugins/libEmergencyNotify.so
+SIPX_PROXY.990_emergnotif.EMERGRULES  : @sipxpbx.conf.dir@/authrules.xml
diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/DialingRule.java b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/DialingRule.java
index 3dfd958..8fb78a9 100644
--- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/DialingRule.java
+++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/DialingRule.java
@@ -84,6 +84,10 @@ public abstract class DialingRule extends BeanWithId implements DataCollectionIt
         m_name = name;
     }
 
+    public String getRuleType() {
+        return null;
+    }
+
     public List<Gateway> getGateways() {
         return m_gateways;
     }
diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/EmergencyRule.java b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/EmergencyRule.java
index 061be81..4a89ec6 100644
--- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/EmergencyRule.java
+++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/EmergencyRule.java
@@ -72,6 +72,11 @@ public class EmergencyRule extends DialingRule {
         return DialingRuleType.EMERGENCY;
     }
 
+    @Override
+    public String getRuleType() {
+        return "Emergency";
+    }
+
     /**
      * External rule - added to mappingrules.xml
      */
diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/IDialingRule.java b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/IDialingRule.java
index 316a259..db0587b 100644
--- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/IDialingRule.java
+++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/IDialingRule.java
@@ -43,6 +43,12 @@ public interface IDialingRule {
 
     public abstract Integer getId();
 
+    /**
+     * Returns the xml tag to be used for this rule type in authrules.xml.
+     * Unless over-written for a specific rule type, returns empty string and is not added to authrules.xml.
+     */
+    public abstract String getRuleType();
+
     public abstract boolean isInternal();
 
     /**
diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/config/AuthRules.java b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/config/AuthRules.java
index 8b463b3..de875a7 100644
--- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/config/AuthRules.java
+++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/config/AuthRules.java
@@ -57,6 +57,7 @@ public class AuthRules extends RulesXmlFile {
     private static final String USER_MATCH = "userMatch";
     private static final String HOST_PATTERN = "hostPattern";
     private static final String HOST_MATCH = "hostMatch";
+    private static final String RULE_TYPE = "ruleType";
 
     private Document m_doc;
     private Set<Gateway> m_gateways;
@@ -84,8 +85,9 @@ public class AuthRules extends RulesXmlFile {
             m_gateways.add(gateway);
             String host = gateway.getGatewayAddress();
             Element hostMatch = mappings.addElement(HOST_MATCH);
-            addRuleNameComment(hostMatch, rule);
+            addRuleName(hostMatch, rule);
             addRuleDescription(hostMatch, rule);
+            addRuleType(hostMatch, rule);
             Element hostPattern = hostMatch.addElement(HOST_PATTERN);
             hostPattern.setText(host);
             addPermissions(rule, hostMatch, permissions, gateway);
@@ -93,7 +95,7 @@ public class AuthRules extends RulesXmlFile {
         // if we have no gateways we still need to generate entries for "source" permission rules
         if (gateways.isEmpty() && !rule.isTargetPermission() && !permissions.isEmpty()) {
             Element hostMatch = mappings.addElement(HOST_MATCH);
-            addRuleNameComment(hostMatch, rule);
+            addRuleName(hostMatch, rule);
             addRuleDescription(hostMatch, rule);
 
             Element domainElement = hostMatch.addElement(HOST_PATTERN);
diff --git a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/config/RulesXmlFile.java b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/config/RulesXmlFile.java
index 7f9fbdb..ddf61fc 100644
--- a/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/config/RulesXmlFile.java
+++ b/sipXconfig/neoconf/src/org/sipfoundry/sipxconfig/admin/dialplan/config/RulesXmlFile.java
@@ -79,6 +79,22 @@ public abstract class RulesXmlFile extends XmlFile {
         }
     }
 
+    protected void addRuleName(Element userMatch, IDialingRule rule) {
+        String nameText = rule.getName();
+        if (!StringUtils.isBlank(nameText)) {
+            Element name = userMatch.addElement("name");
+            name.setText(nameText);
+        }
+    }
+
+    protected void addRuleType(Element userMatch, IDialingRule rule) {
+        String typeText = rule.getRuleType();
+        if (!StringUtils.isBlank(typeText)) {
+            Element ruleType = userMatch.addElement("ruleType");
+            ruleType.setText(typeText);
+        }
+    }
+
     protected void addRuleNameComment(Element hostMatch, IDialingRule rule) {
         String nameText = rule.getName();
         if (!StringUtils.isBlank(nameText)) {
diff --git a/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/admin/dialplan/config/AuthRulesTest.java b/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/admin/dialplan/config/AuthRulesTest.java
index ae142d1..24b2c30 100644
--- a/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/admin/dialplan/config/AuthRulesTest.java
+++ b/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/admin/dialplan/config/AuthRulesTest.java
@@ -31,6 +31,7 @@ import org.sipfoundry.sipxconfig.admin.dialplan.CallDigits;
 import org.sipfoundry.sipxconfig.admin.dialplan.CallPattern;
 import org.sipfoundry.sipxconfig.admin.dialplan.CustomDialingRule;
 import org.sipfoundry.sipxconfig.admin.dialplan.DialPattern;
+import org.sipfoundry.sipxconfig.admin.dialplan.DialingRuleType;
 import org.sipfoundry.sipxconfig.admin.dialplan.IDialingRule;
 import org.sipfoundry.sipxconfig.domain.Domain;
 import org.sipfoundry.sipxconfig.domain.DomainManager;
@@ -73,8 +74,12 @@ public class AuthRulesTest {
 
         IMocksControl control = EasyMock.createControl();
         IDialingRule rule = control.createMock(IDialingRule.class);
+        rule.getName();
+        control.andReturn("test rule");
         rule.getDescription();
         control.andReturn("test rule description");
+        rule.getRuleType();
+        control.andReturn(null);
         rule.getTransformedPatterns(gateway);
         control.andReturn(new String[] {
             "555", "666", "777"
@@ -85,8 +90,6 @@ public class AuthRulesTest {
         }));
         rule.getGateways();
         control.andReturn(gateways);
-        rule.getName();
-        control.andReturn("testrule");
         control.replay();
 
         MockAuthRules authRules = new MockAuthRules();
@@ -97,6 +100,7 @@ public class AuthRulesTest {
         Document document = authRules.getDocument();
         String domDoc = XmlUnitHelper.asString(document);
 
+        XMLAssert.assertXpathEvaluatesTo("test rule", "/mappings/hostMatch/name", domDoc);
         XMLAssert.assertXpathEvaluatesTo("test rule description", "/mappings/hostMatch/description", domDoc);
         XMLAssert.assertXpathEvaluatesTo(gateway.getGatewayAddress(), "/mappings/hostMatch/hostPattern",
                 domDoc);
@@ -133,6 +137,8 @@ public class AuthRulesTest {
         control.andReturn("testrule").times(gateways.length);
         rule.getDescription();
         control.andReturn(null).times(gateways.length);
+        rule.getRuleType();
+        control.andReturn(null).times(gateways.length);
         for (int i = 0; i < gateways.length; i++) {
             rule.getTransformedPatterns(gateways[i]);
             String prefix = gateways[i].getPrefix();
@@ -199,6 +205,8 @@ public class AuthRulesTest {
         control.andReturn("testrule").times(gateways.length);
         rule.getDescription();
         control.andReturn(null).times(gateways.length);
+        rule.getRuleType();
+        control.andReturn(null).times(gateways.length);
         for (int i = 0; i < gateways.length; i++) {
             rule.getTransformedPatterns(gateways[i]);
             control.andReturn(new String[] {
@@ -237,6 +245,63 @@ public class AuthRulesTest {
     }
 
     @Test
+    public void testGenerateEmergencyRule() throws Exception {
+        Gateway[] gateways = new Gateway[GATEWAYS_LEN];
+        for (int i = 0; i < gateways.length; i++) {
+            gateways[i] = new Gateway();
+            gateways[i].setUniqueId();
+            gateways[i].setAddress("10.1.2." + i);
+        }
+
+        IMocksControl control = EasyMock.createControl();
+        IDialingRule rule = control.createMock(IDialingRule.class);
+        rule.getName();
+        control.andReturn("test emerg rule").times(gateways.length);
+        rule.getDescription();
+        control.andReturn("test emerg rule description").times(gateways.length);
+        rule.getRuleType();
+        control.andReturn("Emergency").times(gateways.length);
+        for (int i = 0; i < gateways.length; i++) {
+            rule.getTransformedPatterns(gateways[i]);
+            control.andReturn(new String[] {
+                "911", "9911", "sos"
+            });
+        }
+        rule.getPermissionNames();
+        control.andReturn(Arrays.asList(new String[] {}));
+        rule.getGateways();
+        control.andReturn(Arrays.asList(gateways));
+        control.replay();
+
+        MockAuthRules authRules = new MockAuthRules();
+        authRules.begin();
+        authRules.generate(rule);
+        authRules.end();
+
+        Document document = authRules.getDocument();
+        String domDoc = XmlUnitHelper.asString(document);
+
+        String hostMatchFormat = "/mappings/hostMatch[%d]/";
+        for (int i = 0; i < gateways.length; i++) {
+            String hostMatch = String.format(hostMatchFormat, i + 1);
+            XMLAssert.assertXpathEvaluatesTo(gateways[i].getGatewayAddress(), hostMatch + "hostPattern",
+                    domDoc);
+            XMLAssert.assertXpathEvaluatesTo("test emerg rule", "/mappings/hostMatch/name", domDoc);
+            XMLAssert.assertXpathEvaluatesTo("test emerg rule description", "/mappings/hostMatch/description", domDoc);
+            XMLAssert.assertXpathEvaluatesTo("Emergency", "/mappings/hostMatch/ruleType", domDoc);
+            XMLAssert.assertXpathEvaluatesTo("911", hostMatch + "userMatch/userPattern", domDoc);
+            XMLAssert.assertXpathEvaluatesTo("9911", hostMatch + "userMatch/userPattern[2]", domDoc);
+            XMLAssert.assertXpathEvaluatesTo("sos", hostMatch + "userMatch/userPattern[3]", domDoc);
+            XMLAssert.assertXpathEvaluatesTo("", hostMatch + "/userMatch/permissionMatch", domDoc);
+        }
+
+        // check if generate no access has been called properly
+        Assert.assertEquals(GATEWAYS_LEN, authRules.uniqueGateways);
+
+        control.verify();
+    }
+
+    @Test
     public void testGenerateNoAccessRule() throws Exception {
         Gateway[] gateways = new Gateway[GATEWAYS_LEN];
         for (int i = 0; i < gateways.length; i++) {
diff --git a/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/admin/dialplan/config/authrules-internal-target-perm.test.xml b/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/admin/dialplan/config/authrules-internal-target-perm.test.xml
index 6ea7bf6..62af160 100644
--- a/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/admin/dialplan/config/authrules-internal-target-perm.test.xml
+++ b/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/admin/dialplan/config/authrules-internal-target-perm.test.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <mappings xmlns="http://www.sipfoundry.org/sipX/schema/xml/urlauth-00-00">
   <hostMatch>
-    <!--test-->
+    <name>test</name>
     <description>Calls to internal extensions</description>
     <hostPattern>example.org</hostPattern>
     <hostPattern>sipx.example.org</hostPattern>
diff --git a/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/service/expected-proxy-config b/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/service/expected-proxy-config
index 03ed1ce..dfdf481 100644
--- a/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/service/expected-proxy-config
+++ b/sipXconfig/neoconf/test/org/sipfoundry/sipxconfig/service/expected-proxy-config
@@ -35,3 +35,6 @@ SIPX_PROXY.400_authrules.IDENTITY_VALIDITY_SECONDS : 300
 SIPX_PROXY_HOOK_LIBRARY.700_fromalias : @sipxpbx.lib.dir@/authplugins/libCallerAlias.so
 
 SIPX_PROXY_HOOK_LIBRARY.900_ntap : @sipxpbx.lib.dir@/authplugins/libNatTraversalAgent.so
+
+SIPX_PROXY_HOOK_LIBRARY.990_emergnotif: @sipxpbx.lib.dir@/authplugins/libEmergencyNotify.so
+SIPX_PROXY.990_emergnotif.EMERGRULES  : @sipxpbx.conf.dir@/authrules.xml
-- 
1.5.4.3

