实现集群过滤器

发送反馈


集群过滤器的实现和配置分如下3个步骤:
  1. 实现 com.supermap.services.cluster.client.spi.ClusterServiceFilter 接口
  2. 声明过滤器
  3. 打 Jar 包

实现 com.supermap.services.cluster.client.spi.ClusterServiceFilter 接口

创建 com.supermap.sample.ImageBoundsFilter 类(实现 ClusterServiceFilter 接口)实现一个名为根据 bbox 参数来选择集群节点的类(即集群节点过滤器)。

代码如下:

package com.supermap.sample;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import com.supermap.services.cluster.ServiceInfo;
import com.supermap.services.cluster.client.spi.ClusterServiceFilter;
import com.supermap.services.components.spi.ClusterServiceFilterType;
@ClusterServiceFilterType(componentType = "Map", interfaceType = "WMS")
public class ImageBoundsFilter implements ClusterServiceFilter {
    /**
    * 实现 com.supermap.services.cluster.client.spi.ClusterServiceFilter 中的方法,该方法会被集群服务调用以决定一个服务是否可用于处理特定请求。
    */
    public boolean filter(ServiceInfo serviceInfo, HttpServletRequest request) {
        if(serviceInfo != null) {
            // 过滤掉不是 WMS 和 Map 组件类型的服务
            if(!"WMS".equalsIgnoreCase(serviceInfo.protocol) || !"Map".equalsIgnoreCase(serviceInfo.type) ) {
                return true;
            }
        }
        //从请求中获取 bbox 参数
        String requestBBox = getBBox(request);
        if (requestBBox == null) {
            //bbox 参数为 null,则这个 filter 不适用于这个请求,返回 ClusterServiceFilter.NEUTRAL
            return true;
        }
        if (serviceInfo.address == null) {
            return true;
        }
        //判断当前请求中要求的 bbox 是否在配置的范围内,并且对应的服务器信息地址端口为指定端口
        if(isContain(requestBBox, new double[]{-180,-90,0,90}) && serviceInfo.address.indexOf("8091") != -1) {
            return false;
        }
        if(isContain(requestBBox, new double[]{0,-90,180,90}) && serviceInfo.address.indexOf("8092") != -1) {
            return false;
        }    
        return true;
    }
    private boolean isContain(String requestBBox, double[] bounds) {
        double[] requested = split(requestBBox);
        return requested[0] >= bounds[0] && requested[1] >= bounds[1] && requested[2] <= bounds[2] && requested[3] <= bounds[3];
    }
    private String getBBox(HttpServletRequest request) {
        Enumeration names = request.getParameterNames();
        while (names.hasMoreElements()) {
            String name = (String) names.nextElement();
            if ("BBOX".equalsIgnoreCase(name)) {
                return request.getParameter(name);
            }
        }
        return null;
    }
    private double[] split(String bbox) {
        String[] tmp = bbox.split(",");
        double[] result = new double[4];
        for (int i = 0; i < 4; i++) {
            result[i] = Double.parseDouble(tmp[i]);
        }
        return result;
    }
}

声明过滤器

新建一个名为 SuperMapClusterClient.properties 的文件,进行必要的配置。该文件需要放到指定目录(META-INF/extensions/cluster/filters)下,该文件的内容如下:

implementation=com.supermap.sample.ImageBoundsFilter

该文件中配置声明了对于自定义 WMS 集群功能的过滤器,集群服务会读取这个配置文件并构造对应的实例对象。

打 Jar 包

将以上代码编译之后,将 ImageBoundsFilter.class 及过滤器的声明文件(SuperMapClusterClient.properties)打成 Jar 包,如 clusterfilter.jar。将 clusterfilter.jar 放置到集群服务器(此例中即8090端口上的 iServer 服务)的 SuperMap iServer Web 应用下,即 %SuperMap iServer_HOME%webapps\iserver\WEB-INF\lib 目录下。