diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/impl/OwnerServiceImpl.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/impl/OwnerServiceImpl.java
deleted file mode 100644
index 38be229..0000000
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/impl/OwnerServiceImpl.java
+++ /dev/null
@@ -1,159 +0,0 @@
-///*
-// * Licensed to the Apache Software Foundation (ASF) under one or more
-// * contributor license agreements.  See the NOTICE file distributed with
-// * this work for additional information regarding copyright ownership.
-// * The ASF licenses this file to You under the Apache License, Version 2.0
-// * (the "License"); you may not use this file except in compliance with
-// * the License.  You may obtain a copy of the License at
-// *
-// *     http://www.apache.org/licenses/LICENSE-2.0
-// *
-// * Unless required by applicable law or agreed to in writing, software
-// * distributed under the License is distributed on an "AS IS" BASIS,
-// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// * See the License for the specific language governing permissions and
-// * limitations under the License.
-// */
-//package org.apache.dubbo.admin.service.impl;
-//
-//import org.apache.dubbo.common.Constants;
-//import org.apache.dubbo.common.utils.StringUtils;
-//import org.apache.dubbo.admin.service.OverrideService;
-//import org.apache.dubbo.admin.service.OwnerService;
-//import org.apache.dubbo.admin.service.ProviderService;
-//import org.apache.dubbo.admin.model.domain.Override;
-//import org.apache.dubbo.admin.model.domain.Owner;
-//import org.apache.dubbo.admin.model.domain.Provider;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.stereotype.Component;
-//
-//import java.util.ArrayList;
-//import java.util.HashMap;
-//import java.util.List;
-//import java.util.Map;
-//
-//@Component
-//public class OwnerServiceImpl extends AbstractService implements OwnerService {
-//
-//    @Autowired
-//    ProviderService providerService;
-//
-//    @Autowired
-//    OverrideService overrideService;
-//
-//    public List<String> findAllServiceNames() {
-//        // TODO Auto-generated method stub
-//        return null;
-//    }
-//
-//    public List<String> findServiceNamesByUsername(String username) {
-//        // TODO Auto-generated method stub
-//        return null;
-//    }
-//
-//    public List<String> findUsernamesByServiceName(String serviceName) {
-//        // TODO Auto-generated method stub
-//        return null;
-//    }
-//
-//    public List<Owner> findByService(String serviceName) {
-//        List<Provider> pList = providerService.findByService(serviceName);
-//        List<Override> cList = overrideService.findByServiceAndAddress(serviceName, Constants.ANYHOST_VALUE);
-//        return toOverrideLiset(pList, cList);
-//    }
-//
-//    public List<Owner> findAll() {
-//        List<Provider> pList = providerService.findAll();
-//        List<Override> cList = overrideService.findAll();
-//        return toOverrideLiset(pList, cList);
-//    }
-//
-//    public Owner findById(String id) {
-//
-//        return null;
-//    }
-//
-//    private List<Owner> toOverrideLiset(List<Provider> pList, List<Override> cList) {
-//        Map<String, Owner> oList = new HashMap<String, Owner>();
-//        for (Provider p : pList) {
-//            if (p.getUsername() != null) {
-//                for (String username : Constants.COMMA_SPLIT_PATTERN.split(p.getUsername())) {
-//                    Owner o = new Owner();
-//                    o.setService(p.getService());
-//                    o.setUsername(username);
-//                    oList.put(o.getService() + "/" + o.getUsername(), o);
-//                }
-//            }
-//        }
-//        for (Override c : cList) {
-//            Map<String, String> params = StringUtils.parseQueryString(c.getParams());
-//            String usernames = params.get("owner");
-//            if (usernames != null && usernames.length() > 0) {
-//                for (String username : Constants.COMMA_SPLIT_PATTERN.split(usernames)) {
-//                    Owner o = new Owner();
-//                    o.setService(c.getService());
-//                    o.setUsername(username);
-//                    oList.put(o.getService() + "/" + o.getUsername(), o);
-//                }
-//            }
-//        }
-//        return new ArrayList<Owner>(oList.values());
-//    }
-//
-//    public void saveOwner(Owner owner) {
-//        List<Override> overrides = overrideService.findByServiceAndAddress(owner.getService(), Constants.ANYHOST_VALUE);
-//        if (overrides == null || overrides.size() == 0) {
-//            Override override = new Override();
-//            override.setAddress(Constants.ANYHOST_VALUE);
-//            override.setService(owner.getService());
-//            override.setEnabled(true);
-//            override.setParams("owner=" + owner.getUsername());
-//            overrideService.saveOverride(override);
-//        } else {
-//            for (Override override : overrides) {
-//                Map<String, String> params = StringUtils.parseQueryString(override.getParams());
-//                String usernames = params.get("owner");
-//                if (usernames == null || usernames.length() == 0) {
-//                    usernames = owner.getUsername();
-//                } else {
-//                    usernames = usernames + "," + owner.getUsername();
-//                }
-//                params.put("owner", usernames);
-//                override.setParams(StringUtils.toQueryString(params));
-//                overrideService.updateOverride(override);
-//            }
-//        }
-//    }
-//
-//    public void deleteOwner(Owner owner) {
-//        List<Override> overrides = overrideService.findByServiceAndAddress(owner.getService(), Constants.ANYHOST_VALUE);
-//        if (overrides == null || overrides.size() == 0) {
-//            Override override = new Override();
-//            override.setAddress(Constants.ANYHOST_VALUE);
-//            override.setService(owner.getService());
-//            override.setEnabled(true);
-//            override.setParams("owner=" + owner.getUsername());
-//            overrideService.saveOverride(override);
-//        } else {
-//            for (Override override : overrides) {
-//                Map<String, String> params = StringUtils.parseQueryString(override.getParams());
-//                String usernames = params.get("owner");
-//                if (usernames != null && usernames.length() > 0) {
-//                    if (usernames.equals(owner.getUsername())) {
-//                        params.remove("owner");
-//                    } else {
-//                        usernames = usernames.replace(owner.getUsername() + ",", "").replace("," + owner.getUsername(), "");
-//                        params.put("owner", usernames);
-//                    }
-//                    if (params.size() > 0) {
-//                        override.setParams(StringUtils.toQueryString(params));
-//                        overrideService.updateOverride(override);
-//                    } else {
-//                        overrideService.deleteOverride(override.getHash());
-//                    }
-//                }
-//            }
-//        }
-//    }
-//
-//}
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/impl/ProviderServiceImpl.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/impl/ProviderServiceImpl.java
index 10a4fe4..084746f 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/impl/ProviderServiceImpl.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/impl/ProviderServiceImpl.java
@@ -61,168 +61,12 @@
         registry.register(url);
     }
 
-//    public void enableProvider(String id) {
-//        if (id == null) {
-//            throw new IllegalStateException("no provider id");
-//        }
-//
-//        Provider oldProvider = findProvider(id);
-//
-//        if (oldProvider == null) {
-//            throw new IllegalStateException("Provider was changed!");
-//        }
-//        if (oldProvider.isDynamic()) {
-//            // Make sure we only have one override configured disable property.
-//            if (!oldProvider.isEnabled()) {
-//                Override override = new Override();
-//                override.setAddress(oldProvider.getAddress());
-//                override.setService(oldProvider.getService());
-//                override.setEnabled(true);
-//                override.setParams(Constants.DISABLED_KEY + "=false");
-//                overrideService.saveOverride(override);
-//                return;
-//            }
-//            List<Override> oList = overrideService.findByServiceAndAddress(oldProvider.getService(), oldProvider.getAddress());
-//
-//            for (Override o : oList) {
-//                Map<String, String> params = StringUtils.parseQueryString(o.getParams());
-//                if (params.containsKey(Constants.DISABLED_KEY)) {
-//                    if (params.get(Constants.DISABLED_KEY).equals("true")) {
-//                        overrideService.deleteOverride(o.getHash());
-//                    }
-//                }
-//            }
-//        } else {
-//            oldProvider.setEnabled(true);
-//            updateProvider(oldProvider);
-//        }
-//    }
 
     @Override
     public String getProviderMetaData(MetadataIdentifier providerIdentifier) {
         return metaDataCollector.getProviderMetaData(providerIdentifier);
     }
 
-//    public void disableProvider(String id) {
-//        if (id == null) {
-//            throw new IllegalStateException("no provider id");
-//        }
-//
-//        Provider oldProvider = findProvider(id);
-//        if (oldProvider == null) {
-//            throw new IllegalStateException("Provider was changed!");
-//        }
-//
-//        if (oldProvider.isDynamic()) {
-//            // Make sure we only have one override configured disable property.
-//            if (oldProvider.isEnabled()) {
-//                Override override = new Override();
-//                override.setAddress(oldProvider.getAddress());
-//                override.setService(oldProvider.getService());
-//                override.setEnabled(true);
-//                override.setParams(Constants.DISABLED_KEY + "=true");
-//                overrideService.saveOverride(override);
-//                return;
-//            }
-//            List<Override> oList = overrideService.findByServiceAndAddress(oldProvider.getService(), oldProvider.getAddress());
-//
-//            for (Override o : oList) {
-//                Map<String, String> params = StringUtils.parseQueryString(o.getParams());
-//                if (params.containsKey(Constants.DISABLED_KEY)) {
-//                    if (params.get(Constants.DISABLED_KEY).equals("false")) {
-//                        overrideService.deleteOverride(o.getHash());
-//                    }
-//                }
-//            }
-//        } else {
-//            oldProvider.setEnabled(false);
-//            updateProvider(oldProvider);
-//        }
-//
-//    }
-
-//    public void doublingProvider(String id) {
-//        setWeight(id, 2F);
-//    }
-//
-//    public void halvingProvider(String id) {
-//        setWeight(id, 0.5F);
-//    }
-
-//    public void setWeight(String id, float factor) {
-//        if (id == null) {
-//            throw new IllegalStateException("no provider id");
-//        }
-//        Provider oldProvider = findProvider(id);
-//        if (oldProvider == null) {
-//            throw new IllegalStateException("Provider was changed!");
-//        }
-//        Map<String, String> map = StringUtils.parseQueryString(oldProvider.getParameters());
-//        String weight = map.get(Constants.WEIGHT_KEY);
-//        if (oldProvider.isDynamic()) {
-//            // Make sure we only have one override configured disable property.
-//            List<Override> overrides = overrideService.findByServiceAndAddress(oldProvider.getService(), oldProvider.getAddress());
-//            if (overrides == null || overrides.size() == 0) {
-//                int value = getWeight(weight, factor);
-//                if (value != Constants.DEFAULT_WEIGHT) {
-//                    Override override = new Override();
-//                    override.setAddress(oldProvider.getAddress());
-//                    override.setService(oldProvider.getService());
-//                    override.setEnabled(true);
-//                    override.setParams(Constants.WEIGHT_KEY + "=" + String.valueOf(value));
-//                    overrideService.saveOverride(override);
-//                }
-//            } else {
-//                for (Override override : overrides) {
-//                    Map<String, String> params = StringUtils.parseQueryString(override.getParams());
-//                    String overrideWeight = params.get(Constants.WEIGHT_KEY);
-//                    if (overrideWeight == null || overrideWeight.length() == 0) {
-//                        overrideWeight = weight;
-//                    }
-//                    int value = getWeight(overrideWeight, factor);
-//                    if (value == getWeight(weight, 1)) {
-//                        params.remove(Constants.WEIGHT_KEY);
-//                    } else {
-//                        params.put(Constants.WEIGHT_KEY, String.valueOf(value));
-//                    }
-//                    if (params.size() > 0) {
-//                        override.setParams(StringUtils.toQueryString(params));
-//                        overrideService.updateOverride(override);
-//                    } else {
-//                        overrideService.deleteOverride(override.getHash());
-//                    }
-//                }
-//            }
-//        } else {
-//            int value = getWeight(weight, factor);
-//            if (value == Constants.DEFAULT_WEIGHT) {
-//                map.remove(Constants.WEIGHT_KEY);
-//            } else {
-//                map.put(Constants.WEIGHT_KEY, String.valueOf(value));
-//            }
-//            oldProvider.setParameters(StringUtils.toQueryString(map));
-//            updateProvider(oldProvider);
-//        }
-//    }
-
-    private int getWeight(String value, float factor) {
-        int weight = 100;
-        if (value != null && value.length() > 0) {
-            weight = Integer.parseInt(value);
-        }
-        weight = (int) (weight * factor);
-        if (weight < 1){
-            weight = 1;
-        }
-        if (weight == 2){
-            weight = 3;
-        }
-
-        if (weight == 24){
-            weight = 25;
-        }
-        return weight;
-    }
 
     @Override
     public void deleteStaticProvider(String id) {
