Underscore in topic name leads to invalid nodes creation in zk.
When topic is created via Hermes API and it contains underscore in the name, for example `topic_v1` then node with the same name is created in zk. However when messages are published on that topic then counters are reported in zk under `topic.v1/metrics/published` node. The problem is that when metrics are reported to zk, then underscore is converted to dot and new empty topic node is created. This leads to invalid structures creation in zk and prevents me from listing all subscriptions via /query/subscriptions endpoint because `Unable to read data from path` is thrown.

diff --git a/hermes-common/src/main/java/pl/allegro/tech/hermes/common/metric/counter/zookeeper/ZookeeperCounterReporter.java b/hermes-common/src/main/java/pl/allegro/tech/hermes/common/metric/counter/zookeeper/ZookeeperCounterReporter.java
index db9f7945..76dbcfad 100644
--- a/hermes-common/src/main/java/pl/allegro/tech/hermes/common/metric/counter/zookeeper/ZookeeperCounterReporter.java
+++ b/hermes-common/src/main/java/pl/allegro/tech/hermes/common/metric/counter/zookeeper/ZookeeperCounterReporter.java
@@ -93,7 +93,7 @@ public class ZookeeperCounterReporter extends ScheduledReporter {
         TopicName topicName = fromQualifiedName(qualifiedTopicName);
         return new TopicName(
                 escapeMetricsReplacementChar(topicName.getGroupName()),
-                escapeMetricsReplacementChar(topicName.getName())
+                topicName.getName()
         );
     }
 
diff --git a/hermes-common/src/test/java/pl/allegro/tech/hermes/common/metric/counter/zookeeper/ZookeeperCounterReporterTest.java b/hermes-common/src/test/java/pl/allegro/tech/hermes/common/metric/counter/zookeeper/ZookeeperCounterReporterTest.java
index 5821b227..e3488e59 100644
--- a/hermes-common/src/test/java/pl/allegro/tech/hermes/common/metric/counter/zookeeper/ZookeeperCounterReporterTest.java
+++ b/hermes-common/src/test/java/pl/allegro/tech/hermes/common/metric/counter/zookeeper/ZookeeperCounterReporterTest.java
@@ -37,23 +37,23 @@ public class ZookeeperCounterReporterTest {
     public static final SortedMap<String, Gauge> EMPTY_GAUGES = null;
     public static final String GROUP_NAME_UNDERSCORE = "pl_allegro_tech_skylab";
     public static final String GROUP_NAME = "pl.allegro.tech.skylab";
-    public static final String TOPIC_NAME = "topic1";
+    public static final String TOPIC_NAME_UNDERSCORE = "topic_1";
     public static final String SUBSCRIPTION_NAME_UNDERSCORE = "subscription_name";
     public static final String SUBSCRIPTION_NAME = "subscription.name";
-    public static final TopicName QUALIFIED_TOPIC_NAME = new TopicName(GROUP_NAME, TOPIC_NAME);
+    public static final TopicName QUALIFIED_TOPIC_NAME = new TopicName(GROUP_NAME, TOPIC_NAME_UNDERSCORE);
     public static final long COUNT = 100L;
     public static final String GRAPHITE_PREFIX = "tech.hermes";
 
     private static PathsCompiler pathsCompiler = new PathsCompiler("localhost.domain");
 
-    public static final String METRIC_NAME_FOR_PUBLISHED = pathsCompiler.compile(PUBLISHED,
-            pathContext().withGroup(GROUP_NAME_UNDERSCORE).withTopic(TOPIC_NAME).build());
+    public static final String METRIC_NAME_FOR_PUBLISHED = pathsCompiler.compile(PUBLISHED, pathContext()
+            .withGroup(GROUP_NAME_UNDERSCORE).withTopic(TOPIC_NAME_UNDERSCORE).build());
 
-    public static final String METRIC_NAME_FOR_DELIVERED = pathsCompiler.compile(DELIVERED,
-            pathContext().withGroup(GROUP_NAME_UNDERSCORE).withTopic(TOPIC_NAME).withSubscription(SUBSCRIPTION_NAME_UNDERSCORE).build());
+    public static final String METRIC_NAME_FOR_DELIVERED = pathsCompiler.compile(DELIVERED, pathContext()
+            .withGroup(GROUP_NAME_UNDERSCORE).withTopic(TOPIC_NAME_UNDERSCORE).withSubscription(SUBSCRIPTION_NAME_UNDERSCORE).build());
 
-    public static final String METRIC_NAME_FOR_DISCARDED = pathsCompiler.compile(DISCARDED,
-            pathContext().withGroup(GROUP_NAME_UNDERSCORE).withTopic(TOPIC_NAME).withSubscription(SUBSCRIPTION_NAME_UNDERSCORE).build());
+    public static final String METRIC_NAME_FOR_DISCARDED = pathsCompiler.compile(DISCARDED, pathContext()
+            .withGroup(GROUP_NAME_UNDERSCORE).withTopic(TOPIC_NAME_UNDERSCORE).withSubscription(SUBSCRIPTION_NAME_UNDERSCORE).build());
 
     @Mock
     private CounterStorage counterStorage;
diff --git a/hermes-console/static/partials/modal/editGroup.html b/hermes-console/static/partials/modal/editGroup.html
index 8927db9b..c2c084cf 100644
--- a/hermes-console/static/partials/modal/editGroup.html
+++ b/hermes-console/static/partials/modal/editGroup.html
@@ -14,7 +14,8 @@
             <div class="form-group {{groupForm.groupName.$valid ? '' : 'has-error'}}">
                 <label for="groupName" class="col-md-3 control-label">Name</label>
                 <div class="col-md-9">
-                    <input class="form-control" id="groupName" required name="groupName" placeholder="group name" ng-model="group.groupName" ng-disabled="operation === 'EDIT'"/>
+                    <input class="form-control" id="groupName" required name="groupName" placeholder="group name"
+                           ng-model="group.groupName" ng-disabled="operation === 'EDIT'" ng-pattern="/^[a-zA-Z0-9.-]+$/"/>
                 </div>
             </div>
         </form>
diff --git a/integration/src/integration/java/pl/allegro/tech/hermes/integration/MetricsTest.java b/integration/src/integration/java/pl/allegro/tech/hermes/integration/MetricsTest.java
index 2cc6958e..3d92c543 100644
--- a/integration/src/integration/java/pl/allegro/tech/hermes/integration/MetricsTest.java
+++ b/integration/src/integration/java/pl/allegro/tech/hermes/integration/MetricsTest.java
@@ -43,18 +43,18 @@ public class MetricsTest extends IntegrationTest {
     @Test
     public void shouldIncreaseTopicMetricsAfterMessageHasBeenPublished() {
         // given
-        Topic topic = operations.buildTopic("topicMetricsGroup", "topic");
+        Topic topic = operations.buildTopic("pl.group", "topic_metrics");
         operations.createSubscription(topic, "subscription", HTTP_ENDPOINT_URL);
-        graphiteEndpoint.returnMetricForTopic("topicMetricsGroup", "topic", 10, 15);
+        graphiteEndpoint.returnMetricForTopic("pl_group", "topic_metrics", 10, 15);
 
         remoteService.expectMessages(TestMessage.simple().body());
-        assertThat(publisher.publish("topicMetricsGroup.topic", TestMessage.simple().body()).getStatus())
+        assertThat(publisher.publish("pl.group.topic_metrics", TestMessage.simple().body()).getStatus())
                 .isEqualTo(CREATED.getStatusCode());
         remoteService.waitUntilReceived();
 
         wait.until(() -> {
             // when
-            TopicMetrics metrics = management.topic().getMetrics("topicMetricsGroup.topic");
+            TopicMetrics metrics = management.topic().getMetrics("pl.group.topic_metrics");
 
             // then
             assertThat(metrics.getRate()).isEqualTo("10");
@@ -67,18 +67,18 @@ public class MetricsTest extends IntegrationTest {
     @Test
     public void shouldIncreaseSubscriptionDeliveredMetricsAfterMessageDelivered() {
         // given
-        Topic topic = operations.buildTopic("subscriptionMetricsGroup", "topic");
+        Topic topic = operations.buildTopic("pl.group", "topic");
         operations.createSubscription(topic, "subscription", HTTP_ENDPOINT_URL);
-        graphiteEndpoint.returnMetricForSubscription("subscriptionMetricsGroup", "topic", "subscription", 15);
+        graphiteEndpoint.returnMetricForSubscription("pl_group", "topic", "subscription", 15);
 
         remoteService.expectMessages(TestMessage.simple().body());
-        assertThat(publisher.publish("subscriptionMetricsGroup.topic", TestMessage.simple().body()).getStatus())
+        assertThat(publisher.publish("pl.group.topic", TestMessage.simple().body()).getStatus())
                 .isEqualTo(CREATED.getStatusCode());
         remoteService.waitUntilReceived();
 
         wait.until(() -> {
             // when
-            SubscriptionMetrics metrics = management.subscription().getMetrics("subscriptionMetricsGroup.topic", "subscription");
+            SubscriptionMetrics metrics = management.subscription().getMetrics("pl.group.topic", "subscription");
 
             // then
             assertThat(metrics.getRate()).isEqualTo("15");
['hermes-console/static/partials/modal/editGroup.html', 'integration/src/integration/java/pl/allegro/tech/hermes/integration/MetricsTest.java', 'hermes-common/src/main/java/pl/allegro/tech/hermes/common/metric/counter/zookeeper/ZookeeperCounterReporter.java', 'hermes-common/src/test/java/pl/allegro/tech/hermes/common/metric/counter/zookeeper/ZookeeperCounterReporterTest.java']