001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.camel.impl.cloud;
018
019import java.util.ArrayList;
020import java.util.Collection;
021import java.util.Collections;
022import java.util.List;
023import java.util.Map;
024import java.util.Objects;
025import java.util.stream.Collectors;
026
027import org.apache.camel.cloud.ServiceDefinition;
028import org.apache.camel.util.ObjectHelper;
029import org.apache.camel.util.StringHelper;
030
031/**
032 * A static list of known servers Camel Service Call EIP.
033 */
034public class StaticServiceDiscovery extends DefaultServiceDiscovery {
035    private final List<ServiceDefinition> services;
036
037    public StaticServiceDiscovery() {
038        this.services = new ArrayList<>();
039    }
040
041    public StaticServiceDiscovery(List<ServiceDefinition> servers) {
042        this.services = new ArrayList<>(servers);
043    }
044
045    /**
046     * Set the servers.
047     *
048     * @param servers server in the format: [service@]host:port.
049     */
050    public void setServers(List<String> servers) {
051        this.services.clear();
052        servers.forEach(this::addServer);
053    }
054
055    public void addServers(String serviceName, List<String> servers) {
056        for (String server : servers) {
057            String host = StringHelper.before(server, ":");
058            String port = StringHelper.after(server, ":");
059
060            if (ObjectHelper.isNotEmpty(host) && ObjectHelper.isNotEmpty(port)) {
061                addServer(serviceName, host, Integer.valueOf(port));
062            }
063        }
064    }
065
066    /**
067     * Set the servers.
068     *
069     * @param servers servers separated by comma in the format: [service@]host:port,[service@]host2:port,[service@]host3:port and so on.
070     */
071    public void setServers(String servers) {
072        this.services.clear();
073        addServer(servers);
074    }
075
076    /**
077     * Add a server to the known list of servers.
078     */
079    public void addServer(ServiceDefinition server) {
080        services.add(server);
081    }
082
083    /**
084     * Add a server to the known list of servers.
085     * @param serverString servers separated by comma in the format: [service@]host:port,[service@]host2:port,[service@]host3:port and so on.
086     */
087    public void addServer(String serverString) {
088        String[] parts = serverString.split(",");
089        for (String part : parts) {
090            String service = StringHelper.before(part, "@");
091            if (service != null) {
092                part = StringHelper.after(part, "@");
093            }
094            String host = StringHelper.before(part, ":");
095            String port = StringHelper.after(part, ":");
096
097            if (ObjectHelper.isNotEmpty(host) && ObjectHelper.isNotEmpty(port)) {
098                addServer(service, host, Integer.valueOf(port));
099            }
100        }
101    }
102
103    /**
104     * Add a server to the known list of servers.
105     */
106    public void addServer(String host, int port) {
107        addServer(null, host, port, null);
108    }
109
110    /**
111     * Add a server to the known list of servers.
112     */
113    public void addServer(String name, String host, int port) {
114        addServer(name, host, port, null);
115    }
116
117    /**
118     * Add a server to the known list of servers.
119     */
120    public void addServer(String name, String host, int port, Map<String, String> meta) {
121        services.add(new DefaultServiceDefinition(name, host, port, meta));
122    }
123
124    /**
125     * Remove an existing server from the list of known servers.
126     */
127    public void removeServer(String host, int port) {
128        services.removeIf(
129            s -> Objects.equals(host, s.getHost()) && port == s.getPort()
130        );
131    }
132
133    /**
134     * Remove an existing server from the list of known servers.
135     */
136    public void removeServer(String name, String host, int port) {
137        services.removeIf(
138            s -> Objects.equals(name, s.getName()) && Objects.equals(host, s.getHost()) && port == s.getPort()
139        );
140    }
141
142    @Override
143    public List<ServiceDefinition> getServices(String name) {
144        return Collections.unmodifiableList(
145            services.stream()
146                .filter(s -> Objects.isNull(s.getName()) || Objects.equals(name, s.getName()))
147                .collect(Collectors.toList())
148        );
149    }
150
151    // *************************************************************************
152    // Helpers
153    // *************************************************************************
154
155    public static StaticServiceDiscovery forServices(Collection<ServiceDefinition> definitions) {
156        StaticServiceDiscovery discovery = new StaticServiceDiscovery();
157        for (ServiceDefinition definition: definitions) {
158            discovery.addServer(definition);
159        }
160
161        return discovery;
162    }
163
164    public static StaticServiceDiscovery forServices(ServiceDefinition... definitions) {
165        StaticServiceDiscovery discovery = new StaticServiceDiscovery();
166        for (ServiceDefinition definition: definitions) {
167            discovery.addServer(definition);
168        }
169
170        return discovery;
171    }
172}