topic support none label cases (#107)

diff --git a/pkg/stringutil/string_util.go b/pkg/stringutil/string_util.go
index 6f01d14..0e0ab86 100644
--- a/pkg/stringutil/string_util.go
+++ b/pkg/stringutil/string_util.go
@@ -22,10 +22,15 @@
 	"strings"
 )
 
+const (
+	// LabelNone is the format string when the map is none
+	LabelNone = "none"
+)
+
 //FormatMap format map to string
 func FormatMap(m map[string]string) string {
 	if len(m) == 0 {
-		return "none"
+		return LabelNone
 	}
 	sb := strings.Builder{}
 	s := make([]string, 0, len(m))
diff --git a/pkg/util/util.go b/pkg/util/util.go
new file mode 100644
index 0000000..29eb39e
--- /dev/null
+++ b/pkg/util/util.go
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package util
+
+import "reflect"
+
+//IsEquivalentLabel compares whether two labels are equal.
+//In particular, if one is nil and another is an empty map, it return true
+func IsEquivalentLabel(x, y map[string]string) bool {
+	if len(x) == 0 && len(y) == 0 {
+		return true
+	}
+	return reflect.DeepEqual(x, y)
+}
diff --git a/pkg/util/util_test.go b/pkg/util/util_test.go
new file mode 100644
index 0000000..a98e0ed
--- /dev/null
+++ b/pkg/util/util_test.go
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package util_test
+
+import (
+	"testing"
+
+	"github.com/apache/servicecomb-kie/pkg/util"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestIsEquivalentLabel(t *testing.T) {
+	var m1 map[string]string
+	m2 := make(map[string]string)
+	m3 := map[string]string{
+		"foo": "bar",
+	}
+	m4 := map[string]string{
+		"foo": "bar",
+	}
+	m5 := map[string]string{
+		"bar": "foo",
+	}
+	assert.Equal(t, util.IsEquivalentLabel(m1, m1), true)
+	assert.Equal(t, util.IsEquivalentLabel(m1, m2), true)
+	assert.Equal(t, util.IsEquivalentLabel(m2, m3), false)
+	assert.Equal(t, util.IsEquivalentLabel(m3, m4), true)
+	assert.Equal(t, util.IsEquivalentLabel(m3, m5), false)
+}
diff --git a/server/pubsub/event_handler.go b/server/pubsub/event_handler.go
index 941e143..7b6ebca 100644
--- a/server/pubsub/event_handler.go
+++ b/server/pubsub/event_handler.go
@@ -49,7 +49,7 @@
 	topics.Range(func(key, value interface{}) bool { //range all topics
 		t, err := ParseTopicString(key.(string))
 		if err != nil {
-			openlogging.Error("can not parse topic:" + key.(string))
+			openlogging.Error("can not parse topic " + key.(string) + ": " + err.Error())
 			return true
 		}
 		if t.Match(ke) {
diff --git a/server/pubsub/struct.go b/server/pubsub/struct.go
index df67116..dd7d156 100644
--- a/server/pubsub/struct.go
+++ b/server/pubsub/struct.go
@@ -20,10 +20,11 @@
 import (
 	"encoding/json"
 	"errors"
-	"reflect"
 	"strings"
 
 	"github.com/apache/servicecomb-kie/pkg/common"
+	"github.com/apache/servicecomb-kie/pkg/stringutil"
+	"github.com/apache/servicecomb-kie/pkg/util"
 )
 
 // const
@@ -67,6 +68,9 @@
 	if err != nil {
 		return nil, err
 	}
+	if t.LabelsFormat == stringutil.LabelNone {
+		return t, nil
+	}
 	ls := strings.Split(t.LabelsFormat, "::")
 	if len(ls) != 0 {
 		for _, l := range ls {
@@ -81,6 +85,11 @@
 }
 
 //Match compare event with topic
+//If the match type is set to exact in long pulling request, only update request with exactly
+//the same label of pulling request will match the request and will trigger an immediate return.
+//
+//If the match type is not set, it will be matched when pulling request labels is equal to
+//update request labels or a subset of it.
 func (t *Topic) Match(event *KVChangeEvent) bool {
 	match := false
 	if t.Key != "" {
@@ -89,10 +98,13 @@
 		}
 	}
 	if t.MatchType == common.PatternExact {
-		if !reflect.DeepEqual(t.Labels, event.Labels) {
+		if !util.IsEquivalentLabel(t.Labels, event.Labels) {
 			return false
 		}
 	}
+	if len(t.Labels) == 0 {
+		return true
+	}
 	for k, v := range t.Labels {
 		if event.Labels[k] != v {
 			return false
diff --git a/server/service/mongo/kv/kv_service.go b/server/service/mongo/kv/kv_service.go
index f828caa..99a11c8 100644
--- a/server/service/mongo/kv/kv_service.go
+++ b/server/service/mongo/kv/kv_service.go
@@ -20,10 +20,10 @@
 import (
 	"context"
 	"errors"
-	"reflect"
 	"time"
 
 	"github.com/apache/servicecomb-kie/pkg/model"
+	"github.com/apache/servicecomb-kie/pkg/util"
 	"github.com/apache/servicecomb-kie/server/service"
 	"github.com/apache/servicecomb-kie/server/service/mongo/label"
 	"github.com/apache/servicecomb-kie/server/service/mongo/session"
@@ -180,7 +180,7 @@
 			return nil, err
 		}
 		if opts.ExactLabels {
-			if !reflect.DeepEqual(opts.Labels, curKV.Labels) {
+			if !util.IsEquivalentLabel(opts.Labels, curKV.Labels) {
 				continue
 			}
 		}