apache / dubbo-admin
Showing 61 of 82 files from the diff.

@@ -0,0 +1,26 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.destination;
19 +
20 +
21 +
public class TcpKeepalive {
22 +
    private int probes;
23 +
    private int time;
24 +
    private int interval;
25 +
26 +
}

@@ -0,0 +1,63 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.virtualservice;
19 +
20 +
21 +
import org.apache.dubbo.admin.model.store.mesh.virtualservice.match.StringMatch;
22 +
23 +
import java.util.List;
24 +
25 +
26 +
public class DubboRoute {
27 +
    private String name;
28 +
    private List<StringMatch> services;
29 +
    private List<DubboRouteDetail> routedetail;
30 +
31 +
    public String getName() {
32 +
        return name;
33 +
    }
34 +
35 +
    public void setName(String name) {
36 +
        this.name = name;
37 +
    }
38 +
39 +
    public List<StringMatch> getServices() {
40 +
        return services;
41 +
    }
42 +
43 +
    public void setServices(List<StringMatch> services) {
44 +
        this.services = services;
45 +
    }
46 +
47 +
    public List<DubboRouteDetail> getRoutedetail() {
48 +
        return routedetail;
49 +
    }
50 +
51 +
    public void setRoutedetail(List<DubboRouteDetail> routedetail) {
52 +
        this.routedetail = routedetail;
53 +
    }
54 +
55 +
    @Override
56 +
    public String toString() {
57 +
        return "DubboRoute{" +
58 +
                "name='" + name + '\'' +
59 +
                ", services=" + services +
60 +
                ", routedetail=" + routedetail +
61 +
                '}';
62 +
    }
63 +
}

@@ -0,0 +1,32 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.dto;
19 +
20 +
public class MeshRouteDTO extends BaseDTO{
21 +
22 +
    private String meshRule;
23 +
24 +
    public String getMeshRule() {
25 +
        return meshRule;
26 +
    }
27 +
28 +
    public void setMeshRule(String meshRule) {
29 +
        this.meshRule = meshRule;
30 +
    }
31 +
32 +
}

@@ -0,0 +1,131 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.virtualservice;
19 +
20 +
21 +
import org.apache.dubbo.admin.model.store.mesh.virtualservice.match.DoubleMatch;
22 +
import org.apache.dubbo.admin.model.store.mesh.virtualservice.match.DubboAttachmentMatch;
23 +
import org.apache.dubbo.admin.model.store.mesh.virtualservice.match.DubboMethodMatch;
24 +
import org.apache.dubbo.admin.model.store.mesh.virtualservice.match.StringMatch;
25 +
26 +
import java.util.Map;
27 +
28 +
29 +
public class DubboMatchRequest {
30 +
    private String name;
31 +
    private DubboMethodMatch method;
32 +
    private Map<String, String> sourceLabels;
33 +
    private DubboAttachmentMatch attachments;
34 +
    private Map<String, StringMatch> headers;
35 +
    private DoubleMatch threshold;
36 +
37 +
    public String getName() {
38 +
        return name;
39 +
    }
40 +
41 +
    public void setName(String name) {
42 +
        this.name = name;
43 +
    }
44 +
45 +
    public DubboMethodMatch getMethod() {
46 +
        return method;
47 +
    }
48 +
49 +
    public void setMethod(DubboMethodMatch method) {
50 +
        this.method = method;
51 +
    }
52 +
53 +
    public Map<String, String> getSourceLabels() {
54 +
        return sourceLabels;
55 +
    }
56 +
57 +
    public void setSourceLabels(Map<String, String> sourceLabels) {
58 +
        this.sourceLabels = sourceLabels;
59 +
    }
60 +
61 +
    public DubboAttachmentMatch getAttachments() {
62 +
        return attachments;
63 +
    }
64 +
65 +
    public void setAttachments(DubboAttachmentMatch attachments) {
66 +
        this.attachments = attachments;
67 +
    }
68 +
69 +
    public Map<String, StringMatch> getHeaders() {
70 +
        return headers;
71 +
    }
72 +
73 +
    public void setHeaders(Map<String, StringMatch> headers) {
74 +
        this.headers = headers;
75 +
    }
76 +
77 +
    public DoubleMatch getThreshold() {
78 +
        return threshold;
79 +
    }
80 +
81 +
    public void setThreshold(DoubleMatch threshold) {
82 +
        this.threshold = threshold;
83 +
    }
84 +
85 +
86 +
    public static boolean isMatch(DubboMatchRequest dubboMatchRequest,
87 +
                                  String methodName, String[] parameterTypeList, Object[] parameters,
88 +
                                  Map<String, String> sourceLabels,
89 +
                                  Map<String, String> eagleeyeContext, Map<String, String> dubboContext,
90 +
                                  Map<String, String> headers
91 +
    ) {
92 +
        if (dubboMatchRequest.getMethod() != null) {
93 +
            if (!DubboMethodMatch.isMatch(dubboMatchRequest.getMethod(), methodName, parameterTypeList, parameters)) {
94 +
                return false;
95 +
            }
96 +
        }
97 +
98 +
        if (dubboMatchRequest.getSourceLabels() != null) {
99 +
            for (Map.Entry<String, String> entry : dubboMatchRequest.getSourceLabels().entrySet()) {
100 +
                String value = sourceLabels.get(entry.getKey());
101 +
                if (value == null || !entry.getValue().equals(value)) {
102 +
                    return false;
103 +
                }
104 +
            }
105 +
        }
106 +
107 +
        if (dubboMatchRequest.getAttachments() != null) {
108 +
            if (!DubboAttachmentMatch.isMatch(dubboMatchRequest.getAttachments(),eagleeyeContext,dubboContext)){
109 +
                return false;
110 +
            }
111 +
        }
112 +
113 +
        //TODO headers
114 +
115 +
116 +
        return true;
117 +
118 +
    }
119 +
120 +
    @Override
121 +
    public String toString() {
122 +
        return "DubboMatchRequest{" +
123 +
                "name='" + name + '\'' +
124 +
                ", method=" + method +
125 +
                ", sourceLabels=" + sourceLabels +
126 +
                ", attachments=" + attachments +
127 +
                ", headers=" + headers +
128 +
                ", threshold=" + threshold +
129 +
                '}';
130 +
    }
131 +
}

@@ -17,8 +17,10 @@
Loading
17 17
package org.apache.dubbo.admin.controller;
18 18
19 19
import org.apache.dubbo.admin.annotation.Authority;
20 +
import org.apache.dubbo.admin.authentication.LoginAuthentication;
20 21
21 22
import org.apache.commons.lang3.StringUtils;
23 +
import org.apache.dubbo.common.extension.ExtensionLoader;
22 24
import org.springframework.beans.factory.annotation.Value;
23 25
import org.springframework.scheduling.annotation.Scheduled;
24 26
import org.springframework.web.bind.annotation.RequestMapping;
@@ -29,8 +31,10 @@
Loading
29 31
import org.springframework.web.context.request.ServletRequestAttributes;
30 32
31 33
import javax.servlet.http.HttpServletRequest;
34 +
import java.util.Iterator;
32 35
import java.util.Map;
33 36
import java.util.Objects;
37 +
import java.util.Set;
34 38
import java.util.UUID;
35 39
import java.util.concurrent.ConcurrentHashMap;
36 40
@@ -49,15 +53,26 @@
Loading
49 53
    private long sessionTimeoutMilli;
50 54
51 55
    @RequestMapping(value = "/login", method = RequestMethod.GET)
52 -
    public String login(@RequestParam String userName, @RequestParam String password) {
53 -
        if (StringUtils.isBlank(rootUserName) || (rootUserName.equals(userName) && rootUserPassword.equals(password))) {
54 -
            UUID uuid = UUID.randomUUID();
55 -
            String token = uuid.toString();
56 -
            User user = new User();
57 -
            user.setUserName(userName);
58 -
            user.setLastUpdateTime(System.currentTimeMillis());
59 -
            tokenMap.put(token, user);
60 -
            return token;
56 +
    public String login(HttpServletRequest httpServletRequest, @RequestParam String userName, @RequestParam String password) {
57 +
        ExtensionLoader<LoginAuthentication> extensionLoader = ExtensionLoader.getExtensionLoader(LoginAuthentication.class);
58 +
        Set<LoginAuthentication> supportedExtensionInstances = extensionLoader.getSupportedExtensionInstances();
59 +
        Iterator<LoginAuthentication> iterator = supportedExtensionInstances.iterator();
60 +
        boolean flag = true;
61 +
        if (iterator == null) {
62 +
            if (StringUtils.isBlank(rootUserName) || (rootUserName.equals(userName) && rootUserPassword.equals(password))) {
63 +
                return creatToken(rootUserName);
64 +
            }
65 +
        }
66 +
        while (iterator.hasNext()) {
67 +
            LoginAuthentication loginAuthentication = iterator.next();
68 +
            boolean b = loginAuthentication.authentication(httpServletRequest, userName, password);
69 +
            flag = b & flag;
70 +
            if (flag == false) {
71 +
                break;
72 +
            }
73 +
        }
74 +
        if (flag) {
75 +
            return creatToken(userName);
61 76
        }
62 77
        return null;
63 78
    }
@@ -97,4 +112,13 @@
Loading
97 112
        }
98 113
    }
99 114
115 +
    public String creatToken(String userName) {
116 +
        UUID uuid = UUID.randomUUID();
117 +
        String token = uuid.toString();
118 +
        User user = new User();
119 +
        user.setUserName(userName);
120 +
        user.setLastUpdateTime(System.currentTimeMillis());
121 +
        tokenMap.put(token, user);
122 +
        return token;
123 +
    }
100 124
}

@@ -0,0 +1,76 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.virtualservice.match;
19 +
20 +
import java.util.Map;
21 +
22 +
23 +
public class DubboAttachmentMatch {
24 +
    private Map<String, StringMatch> eagleeyecontext;
25 +
    private Map<String, StringMatch> dubbocontext;
26 +
27 +
    public Map<String, StringMatch> getEagleeyecontext() {
28 +
        return eagleeyecontext;
29 +
    }
30 +
31 +
    public void setEagleeyecontext(Map<String, StringMatch> eagleeyecontext) {
32 +
        this.eagleeyecontext = eagleeyecontext;
33 +
    }
34 +
35 +
    public Map<String, StringMatch> getDubbocontext() {
36 +
        return dubbocontext;
37 +
    }
38 +
39 +
    public void setDubbocontext(Map<String, StringMatch> dubbocontext) {
40 +
        this.dubbocontext = dubbocontext;
41 +
    }
42 +
43 +
    public static boolean isMatch(DubboAttachmentMatch dubboAttachmentMatch, Map<String, String> eagleeyeContext, Map<String, String> dubboContext) {
44 +
        if (dubboAttachmentMatch.getDubbocontext() != null) {
45 +
            for (Map.Entry<String, StringMatch> stringStringMatchEntry : dubboAttachmentMatch.getDubbocontext().entrySet()) {
46 +
                String key = stringStringMatchEntry.getKey();
47 +
                StringMatch stringMatch = stringStringMatchEntry.getValue();
48 +
49 +
                String dubboContextValue = dubboContext.get(key);
50 +
                if (dubboContextValue == null) {
51 +
                    return false;
52 +
                }
53 +
                if (!StringMatch.isMatch(stringMatch, dubboContextValue)) {
54 +
                    return false;
55 +
                }
56 +
            }
57 +
        }
58 +
59 +
        if (dubboAttachmentMatch.getEagleeyecontext() != null) {
60 +
            for (Map.Entry<String, StringMatch> stringStringMatchEntry : dubboAttachmentMatch.getEagleeyecontext().entrySet()) {
61 +
                String key = stringStringMatchEntry.getKey();
62 +
                StringMatch stringMatch = stringStringMatchEntry.getValue();
63 +
64 +
                String eagleeyeContextValue = eagleeyeContext.get(key);
65 +
                if (eagleeyeContextValue == null) {
66 +
                    return false;
67 +
                }
68 +
                if (!StringMatch.isMatch(stringMatch, eagleeyeContextValue)) {
69 +
                    return false;
70 +
                }
71 +
            }
72 +
        }
73 +
74 +
        return true;
75 +
    }
76 +
}

@@ -0,0 +1,105 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.virtualservice.match;
19 +
20 +
21 +
public class StringMatch {
22 +
    private String exact;
23 +
    private String prefix;
24 +
    private String regex;
25 +
    private String noempty;
26 +
    private String empty;
27 +
28 +
29 +
    public String getExact() {
30 +
        return exact;
31 +
    }
32 +
33 +
    public void setExact(String exact) {
34 +
        this.exact = exact;
35 +
    }
36 +
37 +
    public String getPrefix() {
38 +
        return prefix;
39 +
    }
40 +
41 +
    public void setPrefix(String prefix) {
42 +
        this.prefix = prefix;
43 +
    }
44 +
45 +
    public String getRegex() {
46 +
        return regex;
47 +
    }
48 +
49 +
    public void setRegex(String regex) {
50 +
        this.regex = regex;
51 +
    }
52 +
53 +
    public String getNoempty() {
54 +
        return noempty;
55 +
    }
56 +
57 +
    public void setNoempty(String noempty) {
58 +
        this.noempty = noempty;
59 +
    }
60 +
61 +
    public String getEmpty() {
62 +
        return empty;
63 +
    }
64 +
65 +
    public void setEmpty(String empty) {
66 +
        this.empty = empty;
67 +
    }
68 +
69 +
70 +
    public static boolean isMatch(StringMatch stringMatch, String input) {
71 +
        if (stringMatch.getExact() != null && input != null) {
72 +
            if (input.equals(stringMatch.getExact())) {
73 +
                return true;
74 +
            }
75 +
        } else if (stringMatch.getPrefix() != null && input != null) {
76 +
            if (input.startsWith(stringMatch.getPrefix())) {
77 +
                return true;
78 +
            }
79 +
        } else if (stringMatch.getRegex() != null && input != null) {
80 +
            if (input.matches(stringMatch.getRegex())) {
81 +
                return true;
82 +
            }
83 +
        } else if (stringMatch.getEmpty() != null) {
84 +
            return input == null || "".equals(input);
85 +
        } else if (stringMatch.getNoempty() != null) {
86 +
            return input != null && input.length() > 0;
87 +
        } else {
88 +
            return false;
89 +
        }
90 +
91 +
        return false;
92 +
    }
93 +
94 +
95 +
    @Override
96 +
    public String toString() {
97 +
        return "StringMatch{" +
98 +
                "exact='" + exact + '\'' +
99 +
                ", prefix='" + prefix + '\'' +
100 +
                ", regex='" + regex + '\'' +
101 +
                ", noempty='" + noempty + '\'' +
102 +
                ", empty='" + empty + '\'' +
103 +
                '}';
104 +
    }
105 +
}

@@ -0,0 +1,50 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.registry.mapping;
19 +
20 +
import org.apache.dubbo.common.URL;
21 +
import org.apache.dubbo.registry.client.ServiceDiscovery;
22 +
import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
23 +
24 +
import java.util.ArrayList;
25 +
import java.util.HashMap;
26 +
import java.util.List;
27 +
import java.util.Map;
28 +
import java.util.Set;
29 +
30 +
public class AdminServiceInstancesChangedListener extends ServiceInstancesChangedListener {
31 +
32 +
    private AddressChangeListener addressChangeListener;
33 +
34 +
    private Map<String, Object> oldServiceUrls;
35 +
36 +
    public AdminServiceInstancesChangedListener(Set<String> serviceNames, ServiceDiscovery serviceDiscovery, AddressChangeListener addressChangeListener) {
37 +
        super(serviceNames, serviceDiscovery);
38 +
        this.addressChangeListener = addressChangeListener;
39 +
        oldServiceUrls = new HashMap<>();
40 +
    }
41 +
42 +
    protected void notifyAddressChanged() {
43 +
        oldServiceUrls.keySet().stream()
44 +
                .filter(protocolServiceKey -> !serviceUrls.containsKey(protocolServiceKey))
45 +
                .forEach(protocolServiceKey -> addressChangeListener.notifyAddressChanged(protocolServiceKey, new ArrayList<>()));
46 +
        serviceUrls.forEach((protocolServiceKey, urls) -> addressChangeListener.notifyAddressChanged(protocolServiceKey, (List<URL>) urls));
47 +
48 +
        oldServiceUrls = serviceUrls;
49 +
    }
50 +
}

@@ -0,0 +1,128 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.virtualservice.match;
19 +
20 +
import java.util.List;
21 +
import java.util.Map;
22 +
23 +
24 +
public class DubboMethodMatch {
25 +
    private StringMatch name_match;
26 +
    private Integer argc;
27 +
    private List<DubboMethodArg> args;
28 +
    private List<StringMatch> argp;
29 +
    private Map<String, StringMatch> headers;
30 +
31 +
    public StringMatch getName_match() {
32 +
        return name_match;
33 +
    }
34 +
35 +
    public void setName_match(StringMatch name_match) {
36 +
        this.name_match = name_match;
37 +
    }
38 +
39 +
    public Integer getArgc() {
40 +
        return argc;
41 +
    }
42 +
43 +
    public void setArgc(Integer argc) {
44 +
        this.argc = argc;
45 +
    }
46 +
47 +
    public List<DubboMethodArg> getArgs() {
48 +
        return args;
49 +
    }
50 +
51 +
    public void setArgs(List<DubboMethodArg> args) {
52 +
        this.args = args;
53 +
    }
54 +
55 +
    public List<StringMatch> getArgp() {
56 +
        return argp;
57 +
    }
58 +
59 +
    public void setArgp(List<StringMatch> argp) {
60 +
        this.argp = argp;
61 +
    }
62 +
63 +
    public Map<String, StringMatch> getHeaders() {
64 +
        return headers;
65 +
    }
66 +
67 +
    public void setHeaders(Map<String, StringMatch> headers) {
68 +
        this.headers = headers;
69 +
    }
70 +
71 +
    public static boolean isMatch(DubboMethodMatch dubboMethodMatch, String methodName, String[] parameterTypeList, Object[] parameters) {
72 +
        StringMatch nameMatch = dubboMethodMatch.getName_match();
73 +
        if (nameMatch != null && !StringMatch.isMatch(nameMatch, methodName)) {
74 +
            return false;
75 +
        }
76 +
77 +
        Integer argc = dubboMethodMatch.getArgc();
78 +
        if (argc != null &&
79 +
                ((argc != 0 && (parameters == null || parameters.length == 0)) || (argc != parameters.length))) {
80 +
            return false;
81 +
        }
82 +
        List<StringMatch> argp = dubboMethodMatch.getArgp();
83 +
        if (argp != null) {
84 +
            if (((parameterTypeList == null || parameterTypeList.length == 0) && argp.size() > 0)
85 +
                    || (argp.size() != parameterTypeList.length)) {
86 +
                return false;
87 +
            }
88 +
89 +
            for (int index = 0; index < argp.size(); index++) {
90 +
                if (!StringMatch.isMatch(argp.get(index), parameterTypeList[index])) {
91 +
                    return false;
92 +
                }
93 +
            }
94 +
        }
95 +
96 +
        List<DubboMethodArg> args = dubboMethodMatch.getArgs();
97 +
98 +
        if (args != null && args.size() > 0) {
99 +
            if (parameters == null || parameters.length == 0) {
100 +
                return false;
101 +
            }
102 +
103 +
            for (DubboMethodArg dubboMethodArg : args) {
104 +
                int index = dubboMethodArg.getIndex();
105 +
                if (index >= parameters.length) {
106 +
                    throw new IndexOutOfBoundsException("DubboMethodArg index >= parameters.length");
107 +
                }
108 +
                if (!DubboMethodArg.isMatch(dubboMethodArg, parameters[index])) {
109 +
                    return false;
110 +
                }
111 +
            }
112 +
        }
113 +
114 +
        return true;
115 +
    }
116 +
117 +
    @Override
118 +
    public String toString() {
119 +
        return "DubboMethodMatch{" +
120 +
                "name_match=" + name_match +
121 +
                ", argc=" + argc +
122 +
                ", args=" + args +
123 +
                ", argp=" + argp +
124 +
                ", headers=" + headers +
125 +
                '}';
126 +
    }
127 +
}
128 +

@@ -18,7 +18,6 @@
Loading
18 18
19 19
import org.apache.dubbo.admin.registry.config.GovernanceConfiguration;
20 20
import org.apache.dubbo.admin.registry.metadata.MetaDataCollector;
21 -
import org.apache.dubbo.admin.service.RegistryServerSync;
22 21
import org.apache.dubbo.common.URL;
23 22
import org.apache.dubbo.common.logger.Logger;
24 23
import org.apache.dubbo.common.logger.LoggerFactory;
@@ -42,10 +41,10 @@
Loading
42 41
    protected MetaDataCollector metaDataCollector;
43 42
44 43
    @Autowired
45 -
    private RegistryServerSync sync;
44 +
    private InterfaceRegistryCache interfaceRegistryCache;
46 45
47 -
    public ConcurrentMap<String, ConcurrentMap<String, Map<String, URL>>> getRegistryCache() {
48 -
        return sync.getRegistryCache();
46 +
    public ConcurrentMap<String, ConcurrentMap<String, Map<String, URL>>> getInterfaceRegistryCache() {
47 +
        return interfaceRegistryCache.getRegistryCache();
49 48
    }
50 49
51 50
}

@@ -0,0 +1,108 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.domain;
19 +
20 +
import java.util.ArrayList;
21 +
import java.util.Arrays;
22 +
import java.util.Collections;
23 +
import java.util.List;
24 +
import java.util.Objects;
25 +
26 +
/**
27 +
 * copy from {@link org.apache.dubbo.metadata.definition.model.MethodDefinition} compatible 2.x version
28 +
 */
29 +
public class MethodDefinition {
30 +
31 +
    private String name;
32 +
    private String[] parameterTypes;
33 +
    private String returnType;
34 +
    private List<TypeDefinition> parameters;
35 +
    private List<String> annotations;
36 +
37 +
    public MethodDefinition() {
38 +
    }
39 +
40 +
    public String getName() {
41 +
        return this.name;
42 +
    }
43 +
44 +
    public List<TypeDefinition> getParameters() {
45 +
        if (this.parameters == null) {
46 +
            this.parameters = new ArrayList();
47 +
        }
48 +
49 +
        return this.parameters;
50 +
    }
51 +
52 +
    public String[] getParameterTypes() {
53 +
        return this.parameterTypes;
54 +
    }
55 +
56 +
    public String getReturnType() {
57 +
        return this.returnType;
58 +
    }
59 +
60 +
    public void setName(String name) {
61 +
        this.name = name;
62 +
    }
63 +
64 +
    public void setParameters(List<TypeDefinition> parameters) {
65 +
        this.parameters = parameters;
66 +
    }
67 +
68 +
    public void setParameterTypes(String[] parameterTypes) {
69 +
        this.parameterTypes = TypeDefinition.formatTypes(parameterTypes);
70 +
    }
71 +
72 +
    public void setReturnType(String returnType) {
73 +
        this.returnType = TypeDefinition.formatType(returnType);
74 +
    }
75 +
76 +
    public List<String> getAnnotations() {
77 +
        if (this.annotations == null) {
78 +
            this.annotations = Collections.emptyList();
79 +
        }
80 +
81 +
        return this.annotations;
82 +
    }
83 +
84 +
    public void setAnnotations(List<String> annotations) {
85 +
        this.annotations = annotations;
86 +
    }
87 +
88 +
    public String toString() {
89 +
        return "MethodDefinition [name=" + this.name + ", parameterTypes=" + Arrays.toString(this.parameterTypes) + ", returnType=" + this.returnType + "]";
90 +
    }
91 +
92 +
    public boolean equals(Object o) {
93 +
        if (this == o) {
94 +
            return true;
95 +
        } else if (!(o instanceof MethodDefinition)) {
96 +
            return false;
97 +
        } else {
98 +
            MethodDefinition that = (MethodDefinition) o;
99 +
            return Objects.equals(this.getName(), that.getName()) && Arrays.equals(this.getParameterTypes(), that.getParameterTypes()) && Objects.equals(this.getReturnType(), that.getReturnType()) && Objects.equals(this.getParameters(), that.getParameters());
100 +
        }
101 +
    }
102 +
103 +
    public int hashCode() {
104 +
        int result = Objects.hash(new Object[]{this.getName(), this.getReturnType(), this.getParameters()});
105 +
        result = 31 * result + Arrays.hashCode(this.getParameterTypes());
106 +
        return result;
107 +
    }
108 +
}

@@ -18,6 +18,8 @@
Loading
18 18
19 19
import org.apache.dubbo.admin.model.domain.Consumer;
20 20
import org.apache.dubbo.admin.model.domain.Provider;
21 +
import org.apache.dubbo.admin.model.domain.RegistrySource;
22 +
import org.apache.dubbo.common.BaseServiceMetadata;
21 23
import org.apache.dubbo.common.URL;
22 24
23 25
import java.util.ArrayList;
@@ -48,7 +50,10 @@
Loading
48 50
49 51
        Provider p = new Provider();
50 52
        p.setHash(id);
51 -
        p.setService(url.getServiceKey());
53 +
        String group = url.getUrlParam().getParameter(Constants.GROUP_KEY);
54 +
        String version = url.getUrlParam().getParameter(Constants.VERSION_KEY);
55 +
        String service = BaseServiceMetadata.buildServiceKey(url.getServiceInterface(), group, version);
56 +
        p.setService(service);
52 57
        p.setAddress(url.getAddress());
53 58
        p.setApplication(url.getParameter(Constants.APPLICATION_KEY));
54 59
        p.setUrl(url.toIdentityString());
@@ -58,6 +63,7 @@
Loading
58 63
        p.setEnabled(url.getParameter(Constants.ENABLED_KEY, true));
59 64
        p.setWeight(url.getParameter(Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT));
60 65
        p.setUsername(url.getParameter("owner"));
66 +
        p.setRegistrySource(RegistrySource.INTERFACE);
61 67
62 68
        return p;
63 69
    }
@@ -83,7 +89,10 @@
Loading
83 89
84 90
        Consumer c = new Consumer();
85 91
        c.setHash(id);
86 -
        c.setService(url.getServiceKey());
92 +
        String group = url.getUrlParam().getParameter(Constants.GROUP_KEY);
93 +
        String version = url.getUrlParam().getParameter(Constants.VERSION_KEY);
94 +
        String service = BaseServiceMetadata.buildServiceKey(url.getServiceInterface(), group, version);
95 +
        c.setService(service);
87 96
        c.setAddress(url.getHost());
88 97
        c.setApplication(url.getParameter(Constants.APPLICATION_KEY));
89 98
        c.setParameters(url.toParameterString());

@@ -0,0 +1,51 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.service.impl;
19 +
20 +
import org.apache.dubbo.admin.service.RegistryCache;
21 +
import org.apache.dubbo.common.URL;
22 +
23 +
import org.springframework.stereotype.Component;
24 +
25 +
import java.util.Map;
26 +
import java.util.concurrent.ConcurrentHashMap;
27 +
import java.util.concurrent.ConcurrentMap;
28 +
29 +
/**
30 +
 * interface registry url cache
31 +
 * key --> category,value --> ConcurrentMap<serviceKey, Map<hash, URL>>
32 +
 */
33 +
@Component
34 +
public class InterfaceRegistryCache implements RegistryCache<String, ConcurrentMap<String, Map<String, URL>>> {
35 +
36 +
    private final ConcurrentMap<String, ConcurrentMap<String, Map<String, URL>>> registryCache = new ConcurrentHashMap<>();
37 +
38 +
    @Override
39 +
    public void put(String key, ConcurrentMap<String, Map<String, URL>> value) {
40 +
        registryCache.put(key, value);
41 +
    }
42 +
43 +
    @Override
44 +
    public ConcurrentMap<String, Map<String, URL>> get(String key) {
45 +
        return registryCache.get(key);
46 +
    }
47 +
48 +
    public ConcurrentMap<String, ConcurrentMap<String, Map<String, URL>>> getRegistryCache() {
49 +
        return registryCache;
50 +
    }
51 +
}

@@ -79,7 +79,8 @@
Loading
79 79
    public static final String METRICS_PROTOCOL = "metrics.protocol";
80 80
    public static final Set<String> CONFIGS = new HashSet<>();
81 81
    public static final String COLON = ":";
82 -
82 +
    public static final String MESH_RULE_SUFFIX = ".MESHAPPRULE";
83 +
    public static final String DEFAULT_MAPPING_GROUP = "mapping";
83 84
    static {
84 85
        CONFIGS.add(WEIGHT);
85 86
        CONFIGS.add(BALANCING);

@@ -17,15 +17,17 @@
Loading
17 17
18 18
package org.apache.dubbo.admin.model.dto;
19 19
20 +
import org.apache.dubbo.admin.model.domain.RegistrySource;
20 21
import org.apache.commons.lang3.StringUtils;
21 22
22 23
import java.util.Objects;
23 24
24 -
public class ServiceDTO implements Comparable<ServiceDTO>{
25 +
public class ServiceDTO implements Comparable<ServiceDTO> {
25 26
    private String service;
26 27
    private String appName;
27 28
    private String group;
28 29
    private String version;
30 +
    private RegistrySource registrySource;
29 31
30 32
    public String getService() {
31 33
        return service;
@@ -59,6 +61,14 @@
Loading
59 61
        this.version = version;
60 62
    }
61 63
64 +
    public RegistrySource getRegistrySource() {
65 +
        return registrySource;
66 +
    }
67 +
68 +
    public void setRegistrySource(RegistrySource registrySource) {
69 +
        this.registrySource = registrySource;
70 +
    }
71 +
62 72
    @Override
63 73
    public int compareTo(ServiceDTO o) {
64 74
        int result = StringUtils.trimToEmpty(appName).compareTo(StringUtils.trimToEmpty(o.getAppName()));
@@ -70,6 +80,9 @@
Loading
70 80
            if (result == 0) {
71 81
                result = StringUtils.trimToEmpty(version).compareTo(StringUtils.trimToEmpty(o.getVersion()));
72 82
            }
83 +
            if (result == 0) {
84 +
                result = registrySource.compareTo(o.registrySource);
85 +
            }
73 86
        }
74 87
        return result;
75 88
    }
@@ -84,11 +97,11 @@
Loading
84 97
        }
85 98
        ServiceDTO that = (ServiceDTO) o;
86 99
        return Objects.equals(service, that.service) && Objects.equals(appName, that.appName) && Objects
87 -
            .equals(group, that.group) && Objects.equals(version, that.version);
100 +
                .equals(group, that.group) && Objects.equals(version, that.version) && Objects.equals(registrySource, that.registrySource);
88 101
    }
89 102
90 103
    @Override
91 104
    public int hashCode() {
92 -
        return Objects.hash(service, appName, group, version);
105 +
        return Objects.hash(service, appName, group, version, registrySource);
93 106
    }
94 107
}

@@ -0,0 +1,233 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.common.util;
19 +
20 +
import org.apache.dubbo.admin.model.domain.MethodMetadata;
21 +
import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
22 +
import org.apache.dubbo.metadata.definition.model.MethodDefinition;
23 +
import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
24 +
import org.apache.dubbo.metadata.definition.model.TypeDefinition;
25 +
26 +
import org.apache.commons.lang3.StringUtils;
27 +
28 +
import java.util.ArrayList;
29 +
import java.util.Collections;
30 +
import java.util.HashMap;
31 +
import java.util.List;
32 +
import java.util.Map;
33 +
import java.util.regex.Matcher;
34 +
import java.util.regex.Pattern;
35 +
36 +
public class ServiceTestV3Util {
37 +
    private static Pattern COLLECTION_PATTERN = Pattern.compile("^java\\.util\\..*(Set|List|Queue|Collection|Deque)(<.*>)*$");
38 +
    private static Pattern MAP_PATTERN = Pattern.compile("^java\\.util\\..*Map.*(<.*>)*$");
39 +
40 +
    public static boolean sameMethod(MethodDefinition m, String methodSig) {
41 +
        String name = m.getName();
42 +
        String[] parameters = m.getParameterTypes();
43 +
        StringBuilder sb = new StringBuilder();
44 +
        sb.append(name).append("~");
45 +
        for (String parameter : parameters) {
46 +
            sb.append(parameter).append(";");
47 +
        }
48 +
        String sig = StringUtils.removeEnd(sb.toString(), ";");
49 +
        return sig.equals(methodSig);
50 +
    }
51 +
52 +
    public static MethodMetadata generateMethodMeta(FullServiceDefinition serviceDefinition, MethodDefinition methodDefinition) {
53 +
        MethodMetadata methodMetadata = new MethodMetadata();
54 +
        String[] parameterTypes = methodDefinition.getParameterTypes();
55 +
        String returnType = methodDefinition.getReturnType();
56 +
        String signature = methodDefinition.getName() + "~" + String.join(";", parameterTypes);
57 +
        methodMetadata.setSignature(signature);
58 +
        methodMetadata.setReturnType(returnType);
59 +
        List<Object> parameters = generateParameterTypes(parameterTypes, serviceDefinition);
60 +
        methodMetadata.setParameterTypes(parameters);
61 +
        return methodMetadata;
62 +
    }
63 +
64 +
    private static boolean isPrimitiveType(TypeDefinition td) {
65 +
        String type = td.getType();
66 +
        return isPrimitiveType(type);
67 +
    }
68 +
69 +
    private static boolean isPrimitiveType(String type) {
70 +
        return type.equals("byte") || type.equals("java.lang.Byte") ||
71 +
                type.equals("short") || type.equals("java.lang.Short") ||
72 +
                type.equals("int") || type.equals("java.lang.Integer") ||
73 +
                type.equals("long") || type.equals("java.lang.Long") ||
74 +
                type.equals("float") || type.equals("java.lang.Float") ||
75 +
                type.equals("double") || type.equals("java.lang.Double") ||
76 +
                type.equals("boolean") || type.equals("java.lang.Boolean") ||
77 +
                type.equals("void") || type.equals("java.lang.Void") ||
78 +
                type.equals("java.lang.String") ||
79 +
                type.equals("java.util.Date") ||
80 +
                type.equals("java.lang.Object");
81 +
    }
82 +
83 +
    private static List<Object> generateParameterTypes(String[] parameterTypes, ServiceDefinition serviceDefinition) {
84 +
        List<Object> parameters = new ArrayList<>();
85 +
        for (String type : parameterTypes) {
86 +
            Object result = generateType(serviceDefinition, type);
87 +
            parameters.add(result);
88 +
        }
89 +
        return parameters;
90 +
    }
91 +
92 +
    private static TypeDefinition findTypeDefinition(ServiceDefinition serviceDefinition, String type) {
93 +
        return serviceDefinition.getTypes().stream()
94 +
                .filter(t -> t.getType().equals(type))
95 +
                .findFirst().orElse(new TypeDefinition(type));
96 +
    }
97 +
98 +
    private static void generateComplexType(ServiceDefinition sd, TypeDefinition td, Map<String, Object> holder) {
99 +
        td.getProperties().forEach((name, type) -> {
100 +
            if (isPrimitiveType(type)) {
101 +
                holder.put(name, generatePrimitiveType(type));
102 +
            } else {
103 +
                generateEnclosedType(holder, name, sd, type);
104 +
            }
105 +
        });
106 +
    }
107 +
108 +
    private static Object generateComplexType(ServiceDefinition sd, TypeDefinition td) {
109 +
        Map<String, Object> holder = new HashMap<>();
110 +
        generateComplexType(sd, td, holder);
111 +
        return holder;
112 +
    }
113 +
114 +
    private static boolean isMap(TypeDefinition td) {
115 +
        String type = StringUtils.substringBefore(td.getType(), "<");
116 +
        Matcher matcher = MAP_PATTERN.matcher(type);
117 +
        return matcher.matches();
118 +
    }
119 +
120 +
    private static boolean isCollection(TypeDefinition td) {
121 +
        String type = StringUtils.substringBefore(td.getType(), "<");
122 +
        Matcher matcher = COLLECTION_PATTERN.matcher(type);
123 +
        return matcher.matches();
124 +
    }
125 +
126 +
    private static boolean isArray(TypeDefinition td) {
127 +
        return StringUtils.endsWith(td.getType(), "[]");
128 +
    }
129 +
130 +
    private static Object generatePrimitiveType(TypeDefinition td) {
131 +
        return generatePrimitiveType(td.getType());
132 +
    }
133 +
134 +
    private static Object generatePrimitiveType(String type) {
135 +
        switch (type) {
136 +
            case "byte":
137 +
            case "java.lang.Byte":
138 +
            case "short":
139 +
            case "java.lang.Short":
140 +
            case "int":
141 +
            case "java.lang.Integer":
142 +
            case "long":
143 +
            case "java.lang.Long":
144 +
                return 0;
145 +
            case "float":
146 +
            case "java.lang.Float":
147 +
            case "double":
148 +
            case "java.lang.Double":
149 +
                return 0.0;
150 +
            case "boolean":
151 +
            case "java.lang.Boolean":
152 +
                return true;
153 +
            case "void":
154 +
            case "java.lang.Void":
155 +
                return null;
156 +
            case "java.lang.String":
157 +
                return "";
158 +
            case "java.lang.Object":
159 +
                return Collections.emptyMap();
160 +
            case "java.util.Date":
161 +
                return System.currentTimeMillis();
162 +
            default:
163 +
                return Collections.emptyMap();
164 +
        }
165 +
    }
166 +
167 +
    private static Object generateType(ServiceDefinition sd, String type) {
168 +
        TypeDefinition td = findTypeDefinition(sd, type);
169 +
        return generateType(sd, td);
170 +
    }
171 +
172 +
    private static Object generateType(ServiceDefinition sd, TypeDefinition td) {
173 +
        if (isPrimitiveType(td)) {
174 +
            return generatePrimitiveType(td);
175 +
        } else if (isMap(td)) {
176 +
            return generateMapType(sd, td);
177 +
        } else if (isArray(td)) {
178 +
            return generateArrayType(sd, td);
179 +
        } else if (isCollection(td)) {
180 +
            return generateCollectionType(sd, td);
181 +
        } else {
182 +
            return generateComplexType(sd, td);
183 +
        }
184 +
    }
185 +
186 +
    private static Object generateMapType(ServiceDefinition sd, TypeDefinition td) {
187 +
        String keyType = StringUtils.substringAfter(td.getType(), "<");
188 +
        keyType = StringUtils.substringBefore(keyType, ",");
189 +
        keyType = StringUtils.strip(keyType);
190 +
191 +
        Map<Object, Object> map = new HashMap<>();
192 +
        Object key = generateType(sd, keyType);
193 +
        String valueType = StringUtils.substringAfter(td.getType(), ",");
194 +
        valueType = StringUtils.substringBefore(valueType, ">");
195 +
        valueType = StringUtils.strip(valueType);
196 +
        valueType = StringUtils.isNotEmpty(valueType) ? valueType : "java.lang.Object";
197 +
        Object value = generateType(sd, valueType);
198 +
        map.put(key, value);
199 +
        return map;
200 +
    }
201 +
202 +
    private static Object generateCollectionType(ServiceDefinition sd, TypeDefinition td) {
203 +
        String type = StringUtils.substringAfter(td.getType(), "<");
204 +
        type = StringUtils.substringBefore(type, ">");
205 +
        if (StringUtils.isEmpty(type)) {
206 +
            // if type is null return empty collection
207 +
            return new Object[]{};
208 +
        }
209 +
        return new Object[]{generateType(sd, type)};
210 +
211 +
    }
212 +
213 +
    private static Object generateArrayType(ServiceDefinition sd, TypeDefinition td) {
214 +
        String type = StringUtils.substringBeforeLast(td.getType(), "[]");
215 +
        return new Object[]{generateType(sd, type)};
216 +
    }
217 +
218 +
    private static void generateEnclosedType(Map<String, Object> holder, String key, ServiceDefinition sd, String type) {
219 +
        if (isPrimitiveType(type)) {
220 +
            holder.put(key, generateType(sd, type));
221 +
        } else {
222 +
            TypeDefinition td = findTypeDefinition(sd, type);
223 +
            if (td.getProperties() == null || td.getProperties().size() == 0) {
224 +
                holder.put(key, generateType(sd, td));
225 +
            } else {
226 +
                Map<String, Object> enclosedMap = new HashMap<>();
227 +
                holder.put(key, enclosedMap);
228 +
                generateComplexType(sd, td, enclosedMap);
229 +
            }
230 +
231 +
        }
232 +
    }
233 +
}

@@ -0,0 +1,63 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.virtualservice;
19 +
20 +
21 +
import org.apache.dubbo.admin.model.store.mesh.virtualservice.destination.DubboRouteDestination;
22 +
23 +
import java.util.List;
24 +
25 +
26 +
public class DubboRouteDetail {
27 +
    private String name;
28 +
    private List<DubboMatchRequest> match;
29 +
    private List<DubboRouteDestination> route;
30 +
31 +
    public String getName() {
32 +
        return name;
33 +
    }
34 +
35 +
    public void setName(String name) {
36 +
        this.name = name;
37 +
    }
38 +
39 +
    public List<DubboMatchRequest> getMatch() {
40 +
        return match;
41 +
    }
42 +
43 +
    public void setMatch(List<DubboMatchRequest> match) {
44 +
        this.match = match;
45 +
    }
46 +
47 +
    public List<DubboRouteDestination> getRoute() {
48 +
        return route;
49 +
    }
50 +
51 +
    public void setRoute(List<DubboRouteDestination> route) {
52 +
        this.route = route;
53 +
    }
54 +
55 +
    @Override
56 +
    public String toString() {
57 +
        return "DubboRouteDetail{" +
58 +
                "name='" + name + '\'' +
59 +
                ", match=" + match +
60 +
                ", route=" + route +
61 +
                '}';
62 +
    }
63 +
}

@@ -0,0 +1,93 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.registry.mapping.impl;
19 +
20 +
import org.apache.dubbo.admin.common.util.Constants;
21 +
import org.apache.dubbo.admin.registry.mapping.ServiceMapping;
22 +
import org.apache.dubbo.common.URL;
23 +
import org.apache.dubbo.common.utils.CollectionUtils;
24 +
import org.apache.dubbo.common.utils.ConcurrentHashSet;
25 +
import org.apache.dubbo.metadata.MappingChangedEvent;
26 +
import org.apache.dubbo.metadata.MappingListener;
27 +
import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
28 +
import org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter;
29 +
30 +
import java.util.List;
31 +
import java.util.Set;
32 +
33 +
import static org.apache.dubbo.metadata.ServiceNameMapping.getAppNames;
34 +
35 +
36 +
public class ZookeeperServiceMapping implements ServiceMapping {
37 +
38 +
    private ZookeeperClient zkClient;
39 +
40 +
    private final static String MAPPING_PATH = Constants.PATH_SEPARATOR + Constants.DEFAULT_ROOT + Constants.PATH_SEPARATOR + Constants.DEFAULT_MAPPING_GROUP;
41 +
42 +
    private final Set<MappingListener> listeners = new ConcurrentHashSet<>();
43 +
44 +
    private final Set<String> anyServices = new ConcurrentHashSet<>();
45 +
46 +
    @Override
47 +
    public void init(URL url) {
48 +
        ZookeeperTransporter zookeeperTransporter = ZookeeperTransporter.getExtension();
49 +
        zkClient = zookeeperTransporter.connect(url);
50 +
        listenerAll();
51 +
    }
52 +
53 +
    @Override
54 +
    public void listenerAll() {
55 +
        zkClient.create(MAPPING_PATH, false);
56 +
        List<String> services = zkClient.addChildListener(MAPPING_PATH, (path, currentChildList) -> {
57 +
            for (String child : currentChildList) {
58 +
                if (anyServices.add(child)) {
59 +
                    notifyMappingChangedEvent(child);
60 +
                }
61 +
            }
62 +
        });
63 +
        if (CollectionUtils.isNotEmpty(services)) {
64 +
            for (String service : services) {
65 +
                if (anyServices.add(service)) {
66 +
                    notifyMappingChangedEvent(service);
67 +
                }
68 +
            }
69 +
        }
70 +
    }
71 +
72 +
    private void notifyMappingChangedEvent(String service) {
73 +
        if (service.equals(Constants.CONFIGURATORS_CATEGORY) || service.equals(Constants.CONSUMERS_CATEGORY)
74 +
                || service.equals(Constants.PROVIDERS_CATEGORY) || service.equals(Constants.ROUTERS_CATEGORY)) {
75 +
            return;
76 +
        }
77 +
        String servicePath = MAPPING_PATH + Constants.PATH_SEPARATOR + service;
78 +
        String content = zkClient.getContent(servicePath);
79 +
        if (content != null) {
80 +
            Set<String> apps = getAppNames(content);
81 +
            MappingChangedEvent event = new MappingChangedEvent(service, apps);
82 +
            for (MappingListener listener : listeners) {
83 +
                listener.onEvent(event);
84 +
            }
85 +
        }
86 +
    }
87 +
88 +
    @Override
89 +
    public void addMappingListener(MappingListener listener) {
90 +
        listeners.add(listener);
91 +
    }
92 +
93 +
}

@@ -0,0 +1,22 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.destination;
19 +
20 +
21 +
public class ConnectionPoolSettings {
22 +
}

@@ -0,0 +1,22 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.virtualservice.match;
19 +
20 +
21 +
public class ListBoolMatch {
22 +
}

@@ -0,0 +1,41 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.destination;
19 +
20 +
21 +
import org.apache.dubbo.admin.model.store.mesh.BaseRule;
22 +
23 +
public class DestinationRule extends BaseRule {
24 +
    private DestinationRuleSpec spec;
25 +
26 +
    public DestinationRuleSpec getSpec() {
27 +
        return spec;
28 +
    }
29 +
30 +
    public void setSpec(DestinationRuleSpec spec) {
31 +
        this.spec = spec;
32 +
    }
33 +
34 +
    @Override
35 +
    public String toString() {
36 +
        return "DestinationRule{" +
37 +
                "base=" + super.toString() +
38 +
                ", spec=" + spec +
39 +
                '}';
40 +
    }
41 +
}

@@ -19,7 +19,6 @@
Loading
19 19
20 20
import org.apache.dubbo.admin.model.domain.Consumer;
21 21
import org.apache.dubbo.admin.model.domain.Provider;
22 -
import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
23 22
24 23
import java.util.List;
25 24
@@ -30,7 +29,7 @@
Loading
30 29
    private String service;
31 30
    private String application;
32 31
33 -
    FullServiceDefinition metadata;
32 +
    Object metadata;
34 33
35 34
    public String getService() {
36 35
        return service;
@@ -64,11 +63,11 @@
Loading
64 63
        this.consumers = consumers;
65 64
    }
66 65
67 -
    public FullServiceDefinition getMetadata() {
66 +
    public Object getMetadata() {
68 67
        return metadata;
69 68
    }
70 69
71 -
    public void setMetadata(FullServiceDefinition metadata) {
70 +
    public void setMetadata(Object metadata) {
72 71
        this.metadata = metadata;
73 72
    }
74 73
}

@@ -0,0 +1,50 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.destination;
19 +
20 +
import java.util.Map;
21 +
22 +
23 +
public class Subset {
24 +
    private String name;
25 +
    private Map<String, String> labels;
26 +
27 +
    public String getName() {
28 +
        return name;
29 +
    }
30 +
31 +
    public void setName(String name) {
32 +
        this.name = name;
33 +
    }
34 +
35 +
    public Map<String, String> getLabels() {
36 +
        return labels;
37 +
    }
38 +
39 +
    public void setLabels(Map<String, String> labels) {
40 +
        this.labels = labels;
41 +
    }
42 +
43 +
    @Override
44 +
    public String toString() {
45 +
        return "Subset{" +
46 +
                "name='" + name + '\'' +
47 +
                ", labels=" + labels +
48 +
                '}';
49 +
    }
50 +
}

@@ -0,0 +1,90 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.service.impl;
19 +
20 +
import org.apache.dubbo.admin.common.util.Constants;
21 +
import org.apache.dubbo.admin.common.util.ConvertUtil;
22 +
import org.apache.dubbo.admin.common.util.YamlParser;
23 +
import org.apache.dubbo.admin.model.dto.MeshRouteDTO;
24 +
import org.apache.dubbo.admin.model.store.mesh.destination.DestinationRule;
25 +
import org.apache.dubbo.admin.model.store.mesh.virtualservice.VirtualServiceRule;
26 +
import org.apache.dubbo.admin.service.MeshRouteService;
27 +
28 +
import org.springframework.stereotype.Service;
29 +
30 +
import java.util.Map;
31 +
32 +
33 +
@Service
34 +
public class MeshRouteServiceImpl extends AbstractService implements MeshRouteService {
35 +
36 +
    @Override
37 +
    public boolean createMeshRule(MeshRouteDTO meshRoute) {
38 +
        String routeRule = meshRoute.getMeshRule();
39 +
        checkMeshRule(routeRule);
40 +
        String id = ConvertUtil.getIdFromDTO(meshRoute);
41 +
        String path = getPath(id);
42 +
        dynamicConfiguration.setConfig(path, routeRule);
43 +
        return true;
44 +
    }
45 +
46 +
    @Override
47 +
    public boolean updateMeshRule(MeshRouteDTO meshRoute) {
48 +
        String id = ConvertUtil.getIdFromDTO(meshRoute);
49 +
        String path = getPath(id);
50 +
        checkMeshRule(meshRoute.getMeshRule());
51 +
        dynamicConfiguration.setConfig(path, meshRoute.getMeshRule());
52 +
        return true;
53 +
    }
54 +
55 +
    private void checkMeshRule(String meshRule) {
56 +
        Iterable<Object> objectIterable = YamlParser.loadAll(meshRule);
57 +
        for (Object result : objectIterable) {
58 +
            Map resultMap = (Map) result;
59 +
            if ("DestinationRule".equals(resultMap.get("kind"))) {
60 +
                YamlParser.loadObject(YamlParser.dumpObject(result), DestinationRule.class);
61 +
            } else if ("VirtualService".equals(resultMap.get("kind"))) {
62 +
                YamlParser.loadObject(YamlParser.dumpObject(result), VirtualServiceRule.class);
63 +
            }
64 +
        }
65 +
    }
66 +
67 +
    @Override
68 +
    public boolean deleteMeshRule(String id) {
69 +
        String path = getPath(id);
70 +
        return dynamicConfiguration.deleteConfig(path);
71 +
    }
72 +
73 +
    @Override
74 +
    public MeshRouteDTO findMeshRoute(String id) {
75 +
        String path = getPath(id);
76 +
        String rule = dynamicConfiguration.getConfig(path);
77 +
        if (rule == null) {
78 +
            return null;
79 +
        }
80 +
        MeshRouteDTO meshRoute = new MeshRouteDTO();
81 +
        meshRoute.setApplication(id);
82 +
        meshRoute.setMeshRule(rule);
83 +
        return meshRoute;
84 +
    }
85 +
86 +
    private String getPath(String id) {
87 +
        return Constants.CONFIG_KEY + Constants.PATH_SEPARATOR + id + Constants.MESH_RULE_SUFFIX;
88 +
    }
89 +
90 +
}

@@ -0,0 +1,48 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.service;
19 +
20 +
import java.util.function.Function;
21 +
22 +
/**
23 +
 * cache registry url
24 +
 */
25 +
public interface RegistryCache<K, V> {
26 +
27 +
    /**
28 +
     * put cache
29 +
     *
30 +
     * @param key   key
31 +
     * @param value value
32 +
     */
33 +
    void put(K key, V value);
34 +
35 +
    /**
36 +
     * get cache
37 +
     *
38 +
     * @param key key
39 +
     * @return value
40 +
     */
41 +
    V get(K key);
42 +
43 +
44 +
    default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
45 +
        return null;
46 +
    }
47 +
48 +
}

@@ -0,0 +1,60 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh;
19 +
20 +
import java.util.Map;
21 +
22 +
23 +
public class BaseRule {
24 +
    private String apiVersion;
25 +
    private String kind;
26 +
    private Map<String,String> metadata;
27 +
28 +
    public String getApiVersion() {
29 +
        return apiVersion;
30 +
    }
31 +
32 +
    public void setApiVersion(String apiVersion) {
33 +
        this.apiVersion = apiVersion;
34 +
    }
35 +
36 +
    public String getKind() {
37 +
        return kind;
38 +
    }
39 +
40 +
    public void setKind(String kind) {
41 +
        this.kind = kind;
42 +
    }
43 +
44 +
    public Map<String, String> getMetadata() {
45 +
        return metadata;
46 +
    }
47 +
48 +
    public void setMetadata(Map<String, String> metadata) {
49 +
        this.metadata = metadata;
50 +
    }
51 +
52 +
    @Override
53 +
    public String toString() {
54 +
        return "BaseRule{" +
55 +
                "apiVersion='" + apiVersion + '\'' +
56 +
                ", kind='" + kind + '\'' +
57 +
                ", metadata=" + metadata +
58 +
                '}';
59 +
    }
60 +
}

@@ -19,6 +19,8 @@
Loading
19 19
import org.apache.dubbo.admin.common.util.CoderUtil;
20 20
import org.apache.dubbo.admin.common.util.Constants;
21 21
import org.apache.dubbo.admin.common.util.Tool;
22 +
import org.apache.dubbo.admin.service.impl.InterfaceRegistryCache;
23 +
import org.apache.dubbo.common.BaseServiceMetadata;
22 24
import org.apache.dubbo.common.URL;
23 25
import org.apache.dubbo.common.logger.Logger;
24 26
import org.apache.dubbo.common.logger.LoggerFactory;
@@ -69,13 +71,11 @@
Loading
69 71
     * ConcurrentMap<category, ConcurrentMap<servicename, Map<MD5, URL>>>
70 72
     * registryCache
71 73
     */
72 -
    private final ConcurrentMap<String, ConcurrentMap<String, Map<String, URL>>> registryCache = new ConcurrentHashMap<>();
73 74
    @Autowired
74 75
    private Registry registry;
75 76
76 -
    public ConcurrentMap<String, ConcurrentMap<String, Map<String, URL>>> getRegistryCache() {
77 -
        return registryCache;
78 -
    }
77 +
    @Autowired
78 +
    private InterfaceRegistryCache interfaceRegistryCache;
79 79
80 80
    @EventListener(classes = ApplicationReadyEvent.class)
81 81
    public void startSubscribe() {
@@ -98,16 +98,19 @@
Loading
98 98
        final Map<String, Map<String, Map<String, URL>>> categories = new HashMap<>();
99 99
        String interfaceName = null;
100 100
        for (URL url : urls) {
101 -
            String category = url.getParameter(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY);
101 +
            String category = url.getUrlParam().getParameter(Constants.CATEGORY_KEY);
102 +
            if (category == null) {
103 +
                category = Constants.PROVIDERS_CATEGORY;
104 +
            }
102 105
            // NOTE: group and version in empty protocol is *
103 106
            if (Constants.EMPTY_PROTOCOL.equalsIgnoreCase(url.getProtocol())) {
104 -
                ConcurrentMap<String, Map<String, URL>> services = registryCache.get(category);
107 +
                ConcurrentMap<String, Map<String, URL>> services = interfaceRegistryCache.get(category);
105 108
                if (services != null) {
106 -
                    String group = url.getParameter(Constants.GROUP_KEY);
107 -
                    String version = url.getParameter(Constants.VERSION_KEY);
109 +
                    String group = url.getUrlParam().getParameter(Constants.GROUP_KEY);
110 +
                    String version = url.getUrlParam().getParameter(Constants.VERSION_KEY);
108 111
                    // NOTE: group and version in empty protocol is *
109 112
                    if (!Constants.ANY_VALUE.equals(group) && !Constants.ANY_VALUE.equals(version)) {
110 -
                        services.remove(url.getServiceKey());
113 +
                        services.remove(url.getServiceInterface());
111 114
                    } else {
112 115
                        for (Map.Entry<String, Map<String, URL>> serviceEntry : services.entrySet()) {
113 116
                            String service = serviceEntry.getKey();
@@ -128,7 +131,9 @@
Loading
128 131
                    services = new HashMap<>();
129 132
                    categories.put(category, services);
130 133
                }
131 -
                String service = url.getServiceKey();
134 +
                String group = url.getUrlParam().getParameter(Constants.GROUP_KEY);
135 +
                String version = url.getUrlParam().getParameter(Constants.VERSION_KEY);
136 +
                String service = BaseServiceMetadata.buildServiceKey(url.getServiceInterface(), group, version);
132 137
                Map<String, URL> ids = services.get(service);
133 138
                if (ids == null) {
134 139
                    ids = new HashMap<>();
@@ -150,10 +155,10 @@
Loading
150 155
        }
151 156
        for (Map.Entry<String, Map<String, Map<String, URL>>> categoryEntry : categories.entrySet()) {
152 157
            String category = categoryEntry.getKey();
153 -
            ConcurrentMap<String, Map<String, URL>> services = registryCache.get(category);
158 +
            ConcurrentMap<String, Map<String, URL>> services = interfaceRegistryCache.get(category);
154 159
            if (services == null) {
155 160
                services = new ConcurrentHashMap<String, Map<String, URL>>();
156 -
                registryCache.put(category, services);
161 +
                interfaceRegistryCache.put(category, services);
157 162
            } else {// Fix map can not be cleared when service is unregistered: when a unique “group/service:version” service is unregistered, but we still have the same services with different version or group, so empty protocols can not be invoked.
158 163
                Set<String> keys = new HashSet<String>(services.keySet());
159 164
                for (String key : keys) {

@@ -0,0 +1,50 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.virtualservice;
19 +
20 +
import java.util.List;
21 +
22 +
23 +
public class VirtualServiceSpec {
24 +
    private List<String> hosts;
25 +
    private List<DubboRoute> dubbo;
26 +
27 +
    public List<String> getHosts() {
28 +
        return hosts;
29 +
    }
30 +
31 +
    public void setHosts(List<String> hosts) {
32 +
        this.hosts = hosts;
33 +
    }
34 +
35 +
    public List<DubboRoute> getDubbo() {
36 +
        return dubbo;
37 +
    }
38 +
39 +
    public void setDubbo(List<DubboRoute> dubbo) {
40 +
        this.dubbo = dubbo;
41 +
    }
42 +
43 +
    @Override
44 +
    public String toString() {
45 +
        return "VirtualServiceSpec{" +
46 +
                "hosts=" + hosts +
47 +
                ", dubbo=" + dubbo +
48 +
                '}';
49 +
    }
50 +
}

@@ -0,0 +1,41 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.virtualservice;
19 +
20 +
21 +
import org.apache.dubbo.admin.model.store.mesh.BaseRule;
22 +
23 +
public class VirtualServiceRule extends BaseRule {
24 +
    private VirtualServiceSpec spec;
25 +
26 +
    public VirtualServiceSpec getSpec() {
27 +
        return spec;
28 +
    }
29 +
30 +
    public void setSpec(VirtualServiceSpec spec) {
31 +
        this.spec = spec;
32 +
    }
33 +
34 +
    @Override
35 +
    public String toString() {
36 +
        return "VirtualServiceRule{" +
37 +
                "base=" + super.toString() +
38 +
                ", spec=" + spec +
39 +
                '}';
40 +
    }
41 +
}

@@ -0,0 +1,41 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.domain;
19 +
20 +
import java.util.Map;
21 +
22 +
/**
23 +
 * copy from {@link org.apache.dubbo.metadata.definition.model.FullServiceDefinition} compatible 2.x version
24 +
 */
25 +
public class FullServiceDefinition extends ServiceDefinition {
26 +
    private Map<String, String> parameters;
27 +
28 +
    public Map<String, String> getParameters() {
29 +
        return parameters;
30 +
    }
31 +
32 +
    public void setParameters(Map<String, String> parameters) {
33 +
        this.parameters = parameters;
34 +
    }
35 +
36 +
    public String toString() {
37 +
        return "FullServiceDefinition{" +
38 +
                "parameters=" + parameters +
39 +
                "} " + super.toString();
40 +
    }
41 +
}

@@ -0,0 +1,43 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.virtualservice.match;
19 +
20 +
import java.util.List;
21 +
22 +
23 +
public class ListDoubleMatch {
24 +
    private List<DoubleMatch> oneof;
25 +
26 +
    public List<DoubleMatch> getOneof() {
27 +
        return oneof;
28 +
    }
29 +
30 +
    public void setOneof(List<DoubleMatch> oneof) {
31 +
        this.oneof = oneof;
32 +
    }
33 +
34 +
    public static boolean isMatch(ListDoubleMatch listDoubleMatch, Double input) {
35 +
36 +
        for (DoubleMatch doubleMatch : listDoubleMatch.getOneof()) {
37 +
            if (DoubleMatch.isMatch(doubleMatch, input)) {
38 +
                return true;
39 +
            }
40 +
        }
41 +
        return false;
42 +
    }
43 +
}

@@ -0,0 +1,40 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.destination;
19 +
20 +
21 +
import org.apache.dubbo.admin.model.store.mesh.destination.loadbalance.LoadBalancerSettings;
22 +
23 +
public class TrafficPolicy {
24 +
    private LoadBalancerSettings loadBalancer;
25 +
26 +
    public LoadBalancerSettings getLoadBalancer() {
27 +
        return loadBalancer;
28 +
    }
29 +
30 +
    public void setLoadBalancer(LoadBalancerSettings loadBalancer) {
31 +
        this.loadBalancer = loadBalancer;
32 +
    }
33 +
34 +
    @Override
35 +
    public String toString() {
36 +
        return "TrafficPolicy{" +
37 +
                "loadBalancer=" + loadBalancer +
38 +
                '}';
39 +
    }
40 +
}

@@ -0,0 +1,40 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.virtualservice.destination;
19 +
20 +
21 +
public class DubboRouteDestination {
22 +
    private DubboDestination destination;
23 +
    private int weight;
24 +
25 +
    public DubboDestination getDestination() {
26 +
        return destination;
27 +
    }
28 +
29 +
    public void setDestination(DubboDestination destination) {
30 +
        this.destination = destination;
31 +
    }
32 +
33 +
    public int getWeight() {
34 +
        return weight;
35 +
    }
36 +
37 +
    public void setWeight(int weight) {
38 +
        this.weight = weight;
39 +
    }
40 +
}

@@ -0,0 +1,155 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.service.impl;
19 +
20 +
import org.apache.dubbo.admin.common.util.Constants;
21 +
import org.apache.dubbo.admin.model.domain.Provider;
22 +
import org.apache.dubbo.admin.model.domain.RegistrySource;
23 +
import org.apache.dubbo.common.utils.CollectionUtils;
24 +
import org.apache.dubbo.metadata.MetadataInfo;
25 +
import org.apache.dubbo.registry.client.InstanceAddressURL;
26 +
import org.apache.dubbo.registry.client.ServiceInstance;
27 +
28 +
import com.google.common.collect.Lists;
29 +
import com.google.common.collect.Sets;
30 +
import org.springframework.stereotype.Component;
31 +
32 +
import java.util.List;
33 +
import java.util.Map;
34 +
import java.util.Set;
35 +
import java.util.concurrent.ConcurrentMap;
36 +
import java.util.stream.Collectors;
37 +
38 +
@Component
39 +
public class InstanceRegistryQueryHelper {
40 +
41 +
    private final InstanceRegistryCache instanceRegistryCache;
42 +
43 +
    public InstanceRegistryQueryHelper(InstanceRegistryCache instanceRegistryCache) {
44 +
        this.instanceRegistryCache = instanceRegistryCache;
45 +
    }
46 +
47 +
48 +
    public Set<String> findServices() {
49 +
        Set<String> services = Sets.newHashSet();
50 +
        ConcurrentMap<String, Map<String, List<InstanceAddressURL>>> appInterfaceMap = instanceRegistryCache.get(Constants.PROVIDERS_CATEGORY);
51 +
        if (appInterfaceMap == null) {
52 +
            return services;
53 +
        }
54 +
        appInterfaceMap.values().forEach(serviceUrlMap ->
55 +
                serviceUrlMap.forEach((service, urls) -> {
56 +
                    if (CollectionUtils.isNotEmpty(urls)) {
57 +
                        services.add(service);
58 +
                    }
59 +
                }));
60 +
        return services;
61 +
    }
62 +
63 +
    public Set<String> findApplications() {
64 +
        ConcurrentMap<String, Map<String, List<InstanceAddressURL>>> appInterfaceMap = instanceRegistryCache.get(Constants.PROVIDERS_CATEGORY);
65 +
        if (appInterfaceMap == null) {
66 +
            return Sets.newHashSet();
67 +
        }
68 +
        return Sets.newHashSet(appInterfaceMap.keySet());
69 +
    }
70 +
71 +
    public List<Provider> findByService(String serviceName) {
72 +
        ConcurrentMap<String, Map<String, List<InstanceAddressURL>>> appInterfaceMap = instanceRegistryCache.get(Constants.PROVIDERS_CATEGORY);
73 +
        if (appInterfaceMap == null) {
74 +
            return Lists.newArrayList();
75 +
        }
76 +
        List<InstanceAddressURL> providerUrls = Lists.newArrayList();
77 +
        appInterfaceMap.values().forEach(serviceUrlMap ->
78 +
                serviceUrlMap.forEach((service, urls) -> {
79 +
                    if (CollectionUtils.isNotEmpty(urls) && service.equals(serviceName)) {
80 +
                        providerUrls.addAll(urls);
81 +
                    }
82 +
                }));
83 +
        return urlsToProviderList(providerUrls).stream()
84 +
                .filter(provider -> provider.getService().equals(serviceName))
85 +
                .collect(Collectors.toList());
86 +
    }
87 +
88 +
    public List<Provider> findByAddress(String providerAddress) {
89 +
        ConcurrentMap<String, Map<String, List<InstanceAddressURL>>> appInterfaceMap = instanceRegistryCache.get(Constants.PROVIDERS_CATEGORY);
90 +
        if (appInterfaceMap == null) {
91 +
            return Lists.newArrayList();
92 +
        }
93 +
        List<InstanceAddressURL> providerUrls = Lists.newArrayList();
94 +
        appInterfaceMap.values().forEach(serviceUrlMap ->
95 +
                serviceUrlMap.forEach((service, urls) -> {
96 +
                    if (CollectionUtils.isNotEmpty(urls)) {
97 +
                        urls.forEach(url -> {
98 +
                            if ((url.getInstance().getHost().equals(providerAddress))) {
99 +
                                providerUrls.add(url);
100 +
                            }
101 +
                        });
102 +
                    }
103 +
                }));
104 +
        return urlsToProviderList(providerUrls);
105 +
    }
106 +
107 +
    public List<Provider> findByApplication(String application) {
108 +
        ConcurrentMap<String, Map<String, List<InstanceAddressURL>>> appInterfaceMap = instanceRegistryCache.get(Constants.PROVIDERS_CATEGORY);
109 +
        if (appInterfaceMap == null || appInterfaceMap.get(application) == null) {
110 +
            return Lists.newArrayList();
111 +
        }
112 +
        List<InstanceAddressURL> providerUrls = Lists.newArrayList();
113 +
        appInterfaceMap.get(application).forEach((service, urls) -> providerUrls.addAll(urls));
114 +
        return urlsToProviderList(providerUrls);
115 +
    }
116 +
117 +
    public String findVersionInApplication(String application) {
118 +
        ConcurrentMap<String, Map<String, List<InstanceAddressURL>>> appInterfaceMap = instanceRegistryCache.get(Constants.PROVIDERS_CATEGORY);
119 +
        if (appInterfaceMap == null || appInterfaceMap.get(application) == null) {
120 +
            return null;
121 +
        }
122 +
        Map<String, List<InstanceAddressURL>> urlsMap = appInterfaceMap.get(application);
123 +
        for (Map.Entry<String, List<InstanceAddressURL>> entry : urlsMap.entrySet()) {
124 +
            List<InstanceAddressURL> urls = entry.getValue();
125 +
            if (CollectionUtils.isNotEmpty(urls)) {
126 +
                return urls.get(0).getParameter(Constants.SPECIFICATION_VERSION_KEY, "3.0.0");
127 +
            }
128 +
        }
129 +
        return null;
130 +
    }
131 +
132 +
    private List<Provider> urlsToProviderList(List<InstanceAddressURL> urls) {
133 +
        List<Provider> providers = Lists.newArrayList();
134 +
        urls.stream().distinct().forEach(url -> {
135 +
            ServiceInstance instance = url.getInstance();
136 +
            MetadataInfo metadataInfo = url.getMetadataInfo();
137 +
138 +
            metadataInfo.getServices().forEach((serviceKey, serviceInfo) -> {
139 +
                Provider p = new Provider();
140 +
                String service = serviceInfo.getServiceKey();
141 +
                p.setService(service);
142 +
                p.setAddress(url.getAddress());
143 +
                p.setApplication(instance.getServiceName());
144 +
                p.setUrl(url.toParameterString());
145 +
                p.setDynamic(url.getParameter("dynamic", true));
146 +
                p.setEnabled(url.getParameter(Constants.ENABLED_KEY, true));
147 +
                p.setWeight(url.getParameter(Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT));
148 +
                p.setUsername(url.getParameter("owner"));
149 +
                p.setRegistrySource(RegistrySource.INSTANCE);
150 +
                providers.add(p);
151 +
            });
152 +
        });
153 +
        return providers;
154 +
    }
155 +
}

@@ -0,0 +1,26 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.destination.loadbalance;
19 +
20 +
21 +
public enum SimpleLB {
22 +
    ROUND_ROBIN,
23 +
    LEAST_CONN,
24 +
    RANDOM,
25 +
    PASSTHROUGH
26 +
}

@@ -0,0 +1,161 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.domain;
19 +
20 +
import org.apache.dubbo.common.utils.StringUtils;
21 +
22 +
import com.google.gson.annotations.SerializedName;
23 +
24 +
import java.io.Serializable;
25 +
import java.util.ArrayList;
26 +
import java.util.HashMap;
27 +
import java.util.List;
28 +
import java.util.Map;
29 +
import java.util.Objects;
30 +
31 +
32 +
/**
33 +
 * copy from {@link org.apache.dubbo.metadata.definition.model.TypeDefinition} compatible 2.x version
34 +
 */
35 +
public class TypeDefinition implements Serializable {
36 +
    private String id;
37 +
    private String type;
38 +
    @SerializedName("items")
39 +
    private List<TypeDefinition> items;
40 +
    @SerializedName("enum")
41 +
    private List<String> enums;
42 +
    private String $ref;
43 +
    private Map<String, TypeDefinition> properties;
44 +
    private String typeBuilderName;
45 +
46 +
    public TypeDefinition() {
47 +
    }
48 +
49 +
    public TypeDefinition(String type) {
50 +
        this.setType(type);
51 +
    }
52 +
53 +
    public static String[] formatTypes(String[] types) {
54 +
        String[] newTypes = new String[types.length];
55 +
56 +
        for (int i = 0; i < types.length; ++i) {
57 +
            newTypes[i] = formatType(types[i]);
58 +
        }
59 +
60 +
        return newTypes;
61 +
    }
62 +
63 +
    public static String formatType(String type) {
64 +
        return isGenericType(type) ? formatGenericType(type) : type;
65 +
    }
66 +
67 +
    private static String formatGenericType(String type) {
68 +
        return StringUtils.replace(type, ", ", ",");
69 +
    }
70 +
71 +
    private static boolean isGenericType(String type) {
72 +
        return type.contains("<") && type.contains(">");
73 +
    }
74 +
75 +
    public String get$ref() {
76 +
        return this.$ref;
77 +
    }
78 +
79 +
    public List<String> getEnums() {
80 +
        if (this.enums == null) {
81 +
            this.enums = new ArrayList();
82 +
        }
83 +
84 +
        return this.enums;
85 +
    }
86 +
87 +
    public String getId() {
88 +
        return this.id;
89 +
    }
90 +
91 +
    public List<TypeDefinition> getItems() {
92 +
        if (this.items == null) {
93 +
            this.items = new ArrayList();
94 +
        }
95 +
96 +
        return this.items;
97 +
    }
98 +
99 +
    public Map<String, TypeDefinition> getProperties() {
100 +
        if (this.properties == null) {
101 +
            this.properties = new HashMap();
102 +
        }
103 +
104 +
        return this.properties;
105 +
    }
106 +
107 +
    public String getType() {
108 +
        return this.type;
109 +
    }
110 +
111 +
    public String getTypeBuilderName() {
112 +
        return this.typeBuilderName;
113 +
    }
114 +
115 +
    public void set$ref(String $ref) {
116 +
        this.$ref = $ref;
117 +
    }
118 +
119 +
    public void setEnums(List<String> enums) {
120 +
        this.enums = enums;
121 +
    }
122 +
123 +
    public void setId(String id) {
124 +
        this.id = id;
125 +
    }
126 +
127 +
    public void setItems(List<TypeDefinition> items) {
128 +
        this.items = items;
129 +
    }
130 +
131 +
    public void setProperties(Map<String, TypeDefinition> properties) {
132 +
        this.properties = properties;
133 +
    }
134 +
135 +
    public void setType(String type) {
136 +
        this.type = formatType(type);
137 +
    }
138 +
139 +
    public void setTypeBuilderName(String typeBuilderName) {
140 +
        this.typeBuilderName = typeBuilderName;
141 +
    }
142 +
143 +
    public String toString() {
144 +
        return "TypeDefinition [id=" + this.id + ", type=" + this.type + ", properties=" + this.properties + ", $ref=" + this.$ref + "]";
145 +
    }
146 +
147 +
    public boolean equals(Object o) {
148 +
        if (this == o) {
149 +
            return true;
150 +
        } else if (!(o instanceof TypeDefinition)) {
151 +
            return false;
152 +
        } else {
153 +
            TypeDefinition that = (TypeDefinition) o;
154 +
            return Objects.equals(this.getId(), that.getId()) && Objects.equals(this.getType(), that.getType()) && Objects.equals(this.getItems(), that.getItems()) && Objects.equals(this.getEnums(), that.getEnums()) && Objects.equals(this.get$ref(), that.get$ref()) && Objects.equals(this.getProperties(), that.getProperties());
155 +
        }
156 +
    }
157 +
158 +
    public int hashCode() {
159 +
        return Objects.hash(new Object[]{this.getId(), this.getType(), this.getItems(), this.getEnums(), this.get$ref(), this.getProperties()});
160 +
    }
161 +
}

@@ -60,6 +60,8 @@
Loading
60 60
61 61
    private List<Override> overrides;
62 62
63 +
    private RegistrySource registrySource;
64 +
63 65
    public Provider() {
64 66
    }
65 67
@@ -181,6 +183,14 @@
Loading
181 183
        this.overrides = overrides;
182 184
    }
183 185
186 +
    public RegistrySource getRegistrySource() {
187 +
        return registrySource;
188 +
    }
189 +
190 +
    public void setRegistrySource(RegistrySource registrySource) {
191 +
        this.registrySource = registrySource;
192 +
    }
193 +
184 194
    public URL toUrl() {
185 195
        Map<String, String> serviceName2Map = ConvertUtil.serviceName2Map(getService());
186 196
        /*if(!serviceName2Map.containsKey(Constants.INTERFACE_KEY)) {

@@ -21,14 +21,21 @@
Loading
21 21
import org.apache.dubbo.admin.common.exception.ConfigurationException;
22 22
import org.apache.dubbo.admin.common.util.Constants;
23 23
import org.apache.dubbo.admin.registry.config.GovernanceConfiguration;
24 +
import org.apache.dubbo.admin.registry.mapping.ServiceMapping;
25 +
import org.apache.dubbo.admin.registry.mapping.impl.NoOpServiceMapping;
24 26
import org.apache.dubbo.admin.registry.metadata.MetaDataCollector;
25 27
import org.apache.dubbo.admin.registry.metadata.impl.NoOpMetadataCollector;
26 28
import org.apache.dubbo.common.URL;
27 29
import org.apache.dubbo.common.extension.ExtensionLoader;
28 30
import org.apache.dubbo.common.logger.Logger;
29 31
import org.apache.dubbo.common.logger.LoggerFactory;
32 +
import org.apache.dubbo.metadata.MappingListener;
30 33
import org.apache.dubbo.registry.Registry;
31 34
import org.apache.dubbo.registry.RegistryFactory;
35 +
import org.apache.dubbo.registry.RegistryService;
36 +
import org.apache.dubbo.registry.client.ServiceDiscovery;
37 +
import org.apache.dubbo.registry.client.ServiceDiscoveryFactory;
38 +
import org.springframework.beans.factory.annotation.Autowired;
32 39
import org.springframework.beans.factory.annotation.Value;
33 40
import org.springframework.context.annotation.Bean;
34 41
import org.springframework.context.annotation.Configuration;
@@ -37,6 +44,7 @@
Loading
37 44
import java.util.Arrays;
38 45
39 46
import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
47 +
import static org.apache.dubbo.registry.client.ServiceDiscoveryFactory.getExtension;
40 48
41 49
@Configuration
42 50
public class ConfigCenter {
@@ -85,7 +93,8 @@
Loading
85 93
    private URL registryUrl;
86 94
    private URL metadataUrl;
87 95
88 -
96 +
    @Autowired
97 +
    private MappingListener mappingListener;
89 98
90 99
    /*
91 100
     * generate dynamic configuration client
@@ -130,7 +139,7 @@
Loading
130 139
    /*
131 140
     * generate registry client
132 141
     */
133 -
    @Bean
142 +
    @Bean("dubboRegistry")
134 143
    @DependsOn("governanceConfiguration")
135 144
    Registry getRegistry() {
136 145
        Registry registry = null;
@@ -148,7 +157,7 @@
Loading
148 157
    /*
149 158
     * generate metadata client
150 159
     */
151 -
    @Bean
160 +
    @Bean("metaDataCollector")
152 161
    @DependsOn("governanceConfiguration")
153 162
    MetaDataCollector getMetadataCollector() {
154 163
        MetaDataCollector metaDataCollector = new NoOpMetadataCollector();
@@ -168,6 +177,30 @@
Loading
168 177
        return metaDataCollector;
169 178
    }
170 179
180 +
181 +
    @Bean(destroyMethod = "destroy")
182 +
    @DependsOn("dubboRegistry")
183 +
    ServiceDiscovery getServiceDiscoveryRegistry() throws Exception {
184 +
        URL registryURL = registryUrl.setPath(RegistryService.class.getName());
185 +
        ServiceDiscoveryFactory factory = getExtension(registryURL);
186 +
        ServiceDiscovery serviceDiscovery = factory.getServiceDiscovery(registryURL);
187 +
        serviceDiscovery.initialize(registryURL);
188 +
        return serviceDiscovery;
189 +
    }
190 +
191 +
    @Bean
192 +
    @DependsOn("metaDataCollector")
193 +
    ServiceMapping getServiceMapping() {
194 +
        ServiceMapping serviceMapping = new NoOpServiceMapping();
195 +
        if (metadataUrl == null) {
196 +
            return serviceMapping;
197 +
        }
198 +
        serviceMapping = ExtensionLoader.getExtensionLoader(ServiceMapping.class).getExtension(metadataUrl.getProtocol());
199 +
        serviceMapping.addMappingListener(mappingListener);
200 +
        serviceMapping.init(metadataUrl);
201 +
        return serviceMapping;
202 +
    }
203 +
  
171 204
    public static String removerConfigKey(String properties) {
172 205
        String[] split = properties.split("=");
173 206
        String[] address = new String[split.length - 1];

@@ -0,0 +1,48 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.destination.loadbalance;
19 +
20 +
21 +
public class LoadBalancerSettings {
22 +
    private SimpleLB simple;
23 +
    private ConsistentHashLB consistentHash;
24 +
25 +
    public SimpleLB getSimple() {
26 +
        return simple;
27 +
    }
28 +
29 +
    public void setSimple(SimpleLB simple) {
30 +
        this.simple = simple;
31 +
    }
32 +
33 +
    public ConsistentHashLB getConsistentHash() {
34 +
        return consistentHash;
35 +
    }
36 +
37 +
    public void setConsistentHash(ConsistentHashLB consistentHash) {
38 +
        this.consistentHash = consistentHash;
39 +
    }
40 +
41 +
    @Override
42 +
    public String toString() {
43 +
        return "LoadBalancerSettings{" +
44 +
                "simple=" + simple +
45 +
                ", consistentHash=" + consistentHash +
46 +
                '}';
47 +
    }
48 +
}

@@ -0,0 +1,53 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.virtualservice.match;
19 +
20 +
21 +
public class DoubleRangeMatch {
22 +
    private Double start;
23 +
    private Double end;
24 +
25 +
    public Double getStart() {
26 +
        return start;
27 +
    }
28 +
29 +
    public void setStart(Double start) {
30 +
        this.start = start;
31 +
    }
32 +
33 +
    public Double getEnd() {
34 +
        return end;
35 +
    }
36 +
37 +
    public void setEnd(Double end) {
38 +
        this.end = end;
39 +
    }
40 +
41 +
42 +
    public static boolean isMatch(DoubleRangeMatch doubleRangeMatch, Double input) {
43 +
        if (doubleRangeMatch.getStart() != null && doubleRangeMatch.getEnd() != null) {
44 +
            return input.compareTo(doubleRangeMatch.getStart()) >= 0 && input.compareTo(doubleRangeMatch.getEnd()) < 0;
45 +
        } else if (doubleRangeMatch.getStart() != null) {
46 +
            return input.compareTo(doubleRangeMatch.getStart()) >= 0;
47 +
        } else if (doubleRangeMatch.getEnd() != null) {
48 +
            return input.compareTo(doubleRangeMatch.getEnd()) < 0;
49 +
        } else {
50 +
            return false;
51 +
        }
52 +
    }
53 +
}

@@ -0,0 +1,131 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.registry.mapping;
19 +
20 +
import org.apache.dubbo.admin.common.util.Constants;
21 +
import org.apache.dubbo.admin.service.impl.InstanceRegistryCache;
22 +
import org.apache.dubbo.common.URL;
23 +
import org.apache.dubbo.common.utils.CollectionUtils;
24 +
import org.apache.dubbo.common.utils.NetUtils;
25 +
import org.apache.dubbo.metadata.MappingChangedEvent;
26 +
import org.apache.dubbo.metadata.MappingListener;
27 +
import org.apache.dubbo.registry.client.InstanceAddressURL;
28 +
import org.apache.dubbo.registry.client.ServiceDiscovery;
29 +
import org.apache.dubbo.registry.client.ServiceInstance;
30 +
import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
31 +
import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
32 +
33 +
import com.google.common.collect.Sets;
34 +
import org.springframework.stereotype.Component;
35 +
36 +
import java.util.List;
37 +
import java.util.Map;
38 +
import java.util.Set;
39 +
import java.util.concurrent.ConcurrentHashMap;
40 +
import java.util.concurrent.ConcurrentMap;
41 +
import java.util.stream.Collectors;
42 +
43 +
@Component
44 +
public class AdminMappingListener implements MappingListener {
45 +
46 +
    private static final URL CONSUMER_URL = new URL(Constants.ADMIN_PROTOCOL, NetUtils.getLocalHost(), 0, "",
47 +
            Constants.INTERFACE_KEY, Constants.ANY_VALUE,
48 +
            Constants.GROUP_KEY, Constants.ANY_VALUE,
49 +
            Constants.VERSION_KEY, Constants.ANY_VALUE,
50 +
            Constants.CLASSIFIER_KEY, Constants.ANY_VALUE,
51 +
            Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY + ","
52 +
            + Constants.CONSUMERS_CATEGORY + ","
53 +
            + Constants.ROUTERS_CATEGORY + ","
54 +
            + Constants.CONFIGURATORS_CATEGORY,
55 +
            Constants.ENABLED_KEY, Constants.ANY_VALUE,
56 +
            Constants.CHECK_KEY, String.valueOf(false));
57 +
58 +
    /* app - listener */
59 +
    private final Map<String, ServiceInstancesChangedListener> serviceListeners = new ConcurrentHashMap<>();
60 +
61 +
    private final ServiceDiscovery serviceDiscovery;
62 +
63 +
    private final InstanceRegistryCache instanceRegistryCache;
64 +
65 +
    public AdminMappingListener(ServiceDiscovery serviceDiscovery, InstanceRegistryCache instanceRegistryCache) {
66 +
        this.serviceDiscovery = serviceDiscovery;
67 +
        this.instanceRegistryCache = instanceRegistryCache;
68 +
    }
69 +
70 +
    @Override
71 +
    public void onEvent(MappingChangedEvent event) {
72 +
        Set<String> apps = event.getApps();
73 +
        if (CollectionUtils.isEmpty(apps)) {
74 +
            return;
75 +
        }
76 +
        for (String serviceName : apps) {
77 +
            ServiceInstancesChangedListener serviceInstancesChangedListener = serviceListeners.get(serviceName);
78 +
            if (serviceInstancesChangedListener == null) {
79 +
                synchronized (this) {
80 +
                    serviceInstancesChangedListener = serviceListeners.get(serviceName);
81 +
                    if (serviceInstancesChangedListener == null) {
82 +
                        AddressChangeListener addressChangeListener = new DefaultAddressChangeListener(serviceName, instanceRegistryCache);
83 +
                        serviceInstancesChangedListener = new AdminServiceInstancesChangedListener(Sets.newHashSet(serviceName), serviceDiscovery, addressChangeListener);
84 +
                        serviceInstancesChangedListener.setUrl(CONSUMER_URL);
85 +
                        List<ServiceInstance> serviceInstances = serviceDiscovery.getInstances(serviceName);
86 +
                        if (CollectionUtils.isNotEmpty(serviceInstances)) {
87 +
                            serviceInstancesChangedListener.onEvent(new ServiceInstancesChangedEvent(serviceName, serviceInstances));
88 +
                        }
89 +
                        serviceListeners.put(serviceName, serviceInstancesChangedListener);
90 +
                        serviceInstancesChangedListener.setUrl(CONSUMER_URL);
91 +
                        serviceDiscovery.addServiceInstancesChangedListener(serviceInstancesChangedListener);
92 +
                    }
93 +
                }
94 +
            }
95 +
        }
96 +
    }
97 +
98 +
    private static class DefaultAddressChangeListener implements AddressChangeListener {
99 +
100 +
        private String serviceName;
101 +
102 +
        private InstanceRegistryCache instanceRegistryCache;
103 +
104 +
        public DefaultAddressChangeListener(String serviceName, InstanceRegistryCache instanceRegistryCache) {
105 +
            this.serviceName = serviceName;
106 +
            this.instanceRegistryCache = instanceRegistryCache;
107 +
        }
108 +
109 +
        @Override
110 +
        public void notifyAddressChanged(String protocolServiceKey, List<URL> urls) {
111 +
            String serviceKey = removeProtocol(protocolServiceKey);
112 +
            ConcurrentMap<String, Map<String, List<InstanceAddressURL>>> appServiceMap = instanceRegistryCache.computeIfAbsent(Constants.PROVIDERS_CATEGORY, key -> new ConcurrentHashMap<>());
113 +
            Map<String, List<InstanceAddressURL>> serviceMap = appServiceMap.computeIfAbsent(serviceName, key -> new ConcurrentHashMap<>());
114 +
            if (CollectionUtils.isEmpty(urls)) {
115 +
                serviceMap.remove(serviceKey);
116 +
            } else {
117 +
                List<InstanceAddressURL> instanceAddressUrls = urls.stream().map(url -> (InstanceAddressURL) url).collect(Collectors.toList());
118 +
                serviceMap.put(serviceKey, instanceAddressUrls);
119 +
            }
120 +
        }
121 +
122 +
        private String removeProtocol(String protocolServiceKey) {
123 +
            int index = protocolServiceKey.lastIndexOf(":");
124 +
            if (index == -1) {
125 +
                return protocolServiceKey;
126 +
            }
127 +
            return protocolServiceKey.substring(0, index);
128 +
        }
129 +
    }
130 +
131 +
}

@@ -0,0 +1,44 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.virtualservice.match;
19 +
20 +
import java.util.List;
21 +
22 +
23 +
public class ListStringMatch {
24 +
    private List<StringMatch> oneof;
25 +
26 +
    public List<StringMatch> getOneof() {
27 +
        return oneof;
28 +
    }
29 +
30 +
    public void setOneof(List<StringMatch> oneof) {
31 +
        this.oneof = oneof;
32 +
    }
33 +
34 +
35 +
    public static boolean isMatch(ListStringMatch listStringMatch, String input) {
36 +
37 +
        for (StringMatch stringMatch : listStringMatch.getOneof()) {
38 +
            if (StringMatch.isMatch(stringMatch, input)) {
39 +
                return true;
40 +
            }
41 +
        }
42 +
        return false;
43 +
    }
44 +
}

@@ -0,0 +1,63 @@
Loading
1 +
/*
2 +
 * Licensed to the Apache Software Foundation (ASF) under one or more
3 +
 * contributor license agreements.  See the NOTICE file distributed with
4 +
 * this work for additional information regarding copyright ownership.
5 +
 * The ASF licenses this file to You under the Apache License, Version 2.0
6 +
 * (the "License"); you may not use this file except in compliance with
7 +
 * the License.  You may obtain a copy of the License at
8 +
 *
9 +
 *     http://www.apache.org/licenses/LICENSE-2.0
10 +
 *
11 +
 * Unless required by applicable law or agreed to in writing, software
12 +
 * distributed under the License is distributed on an "AS IS" BASIS,
13 +
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +
 * See the License for the specific language governing permissions and
15 +
 * limitations under the License.
16 +
 */
17 +
18 +
package org.apache.dubbo.admin.model.store.mesh.virtualservice.match;
19 +
20 +
21 +
public class DoubleMatch {
22 +
    private Double exact;
23 +
    private DoubleRangeMatch range;
24 +
    private Double mod;
25 +
26 +
    public Double getExact() {
27 +
        return exact;
28 +
    }
29 +
30 +
    public void setExact(Double exact) {
31 +
        this.exact = exact;
32 +
    }
33 +
34 +
    public DoubleRangeMatch getRange() {
35 +
        return range;
36 +
    }
37 +
38 +
    public void setRange(DoubleRangeMatch range) {
39 +
        this.range = range;
40 +
    }
41 +
42 +
    public Double getMod() {
43 +
        return mod;
44 +
    }
45 +
46 +
    public void setMod(Double mod) {
47 +
        this.mod = mod;
48 +
    }
49 +
50 +
51 +
    public static boolean isMatch(DoubleMatch doubleMatch, Double input) {
52 +
        if (doubleMatch.getExact() != null && doubleMatch.getMod() == null) {
53 +
            return input.equals(doubleMatch.getExact());
54 +
        } else if (doubleMatch.getRange() != null) {
55 +
            return DoubleRangeMatch.isMatch(doubleMatch.getRange(), input);
56 +
        } else if (doubleMatch.getExact() != null && doubleMatch.getMod() != null) {
57 +
            Double result = input % doubleMatch.getMod();
58 +
            return result.equals(doubleMatch.getExact());
59 +
        }
60 +
61 +
        return false;
62 +
    }
63 +
}

@@ -19,10 +19,10 @@
Loading
19 19
20 20
import org.apache.commons.lang3.StringUtils;
21 21
import org.apache.dubbo.admin.model.domain.MethodMetadata;
22 -
import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
23 -
import org.apache.dubbo.metadata.definition.model.MethodDefinition;
24 -
import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
25 -
import org.apache.dubbo.metadata.definition.model.TypeDefinition;
22 +
import org.apache.dubbo.admin.model.domain.FullServiceDefinition;
23 +
import org.apache.dubbo.admin.model.domain.MethodDefinition;
24 +
import org.apache.dubbo.admin.model.domain.ServiceDefinition;
25 +
import org.apache.dubbo.admin.model.domain.TypeDefinition;
26 26
27 27
import java.util.ArrayList;
28 28
import java.util.Collections;
@@ -180,10 +180,7 @@
Loading
180 180
        keyType = StringUtils.strip(keyType);
181 181
182 182
        Map<Object, Object> map = new HashMap<>();
183 -
        // 生成 key 默认值
184 183
        Object key = generateType(sd, keyType);
185 -
186 -