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.Collections; 020import java.util.HashMap; 021import java.util.Map; 022import java.util.Objects; 023import java.util.stream.Stream; 024 025import org.apache.camel.cloud.ServiceDefinition; 026import org.apache.camel.cloud.ServiceHealth; 027import org.apache.camel.util.CollectionHelper; 028import org.apache.camel.util.ObjectHelper; 029import org.apache.camel.util.StringHelper; 030 031public class DefaultServiceDefinition implements ServiceDefinition { 032 private static final ServiceHealth DEFAULT_SERVICE_HEALTH = new DefaultServiceHealth(); 033 034 private final String id; 035 private final String name; 036 private final String host; 037 private final int port; 038 private final Map<String, String> meta; 039 private final ServiceHealth health; 040 041 public DefaultServiceDefinition(String name, String host, int port) { 042 this(null, name, host, port, Collections.emptyMap(), DEFAULT_SERVICE_HEALTH); 043 } 044 045 public DefaultServiceDefinition(String id, String name, String host, int port) { 046 this(id, name, host, port, Collections.emptyMap(), DEFAULT_SERVICE_HEALTH); 047 } 048 049 public DefaultServiceDefinition(String name, String host, int port, ServiceHealth health) { 050 this(null, name, host, port, Collections.emptyMap(), health); 051 } 052 053 public DefaultServiceDefinition(String id, String name, String host, int port, ServiceHealth health) { 054 this(id, name, host, port, Collections.emptyMap(), health); 055 } 056 057 public DefaultServiceDefinition(String name, String host, int port, Map<String, String> meta) { 058 this(null, name, host, port, meta, DEFAULT_SERVICE_HEALTH); 059 } 060 061 public DefaultServiceDefinition(String id, String name, String host, int port, Map<String, String> meta) { 062 this(id, name, host, port, meta, DEFAULT_SERVICE_HEALTH); 063 } 064 065 public DefaultServiceDefinition(String name, String host, int port, Map<String, String> meta, ServiceHealth health) { 066 this(null, name, host, port, meta, health); 067 } 068 069 public DefaultServiceDefinition(String id, String name, String host, int port, Map<String, String> meta, ServiceHealth health) { 070 this.id = id; 071 this.name = name; 072 this.host = host; 073 this.port = port; 074 this.meta = CollectionHelper.unmodifiableMap(meta); 075 this.health = ObjectHelper.supplyIfEmpty(health, () -> DEFAULT_SERVICE_HEALTH); 076 } 077 078 @Override 079 public String getId() { 080 return id; 081 } 082 083 @Override 084 public String getName() { 085 return name; 086 } 087 088 @Override 089 public String getHost() { 090 return host; 091 } 092 093 @Override 094 public int getPort() { 095 return port; 096 } 097 098 @Override 099 public ServiceHealth getHealth() { 100 return health; 101 } 102 103 @Override 104 public Map<String, String> getMetadata() { 105 return this.meta; 106 } 107 108 @Override 109 public String toString() { 110 return "DefaultServiceDefinition[" + id + "]"; 111 } 112 113 @Override 114 public boolean equals(Object o) { 115 if (this == o) { 116 return true; 117 } 118 if (o == null || getClass() != o.getClass()) { 119 return false; 120 } 121 122 DefaultServiceDefinition that = (DefaultServiceDefinition) o; 123 return getPort() == that.getPort() 124 && Objects.equals(getId(), that.getId()) 125 && Objects.equals(getName(), that.getName()) 126 && Objects.equals(getHost(), that.getHost()); 127 } 128 129 @Override 130 public int hashCode() { 131 return Objects.hash(getId(), getName(), getHost(), getPort()); 132 } 133 134 // *************************** 135 // Builder 136 // *************************** 137 138 public static Stream<? extends ServiceDefinition> parse(String serverString) { 139 return Stream.of(serverString.split(",")) 140 .map(part -> { 141 String serviceId = null; 142 String serviceName = StringHelper.before(part, "@"); 143 144 if (serviceName != null) { 145 serviceId = StringHelper.before(serviceName, "/"); 146 serviceName = StringHelper.after(serviceName, "/"); 147 148 if (serviceName == null) { 149 serviceName = StringHelper.before(part, "@"); 150 } 151 152 part = StringHelper.after(part, "@"); 153 } 154 155 String serviceHost = StringHelper.before(part, ":"); 156 String servicePort = StringHelper.after(part, ":"); 157 158 if (ObjectHelper.isNotEmpty(serviceHost) && ObjectHelper.isNotEmpty(servicePort)) { 159 return new DefaultServiceDefinition(serviceId, serviceName, serviceHost, Integer.valueOf(servicePort)); 160 } 161 162 return null; 163 } 164 ).filter(Objects::nonNull); 165 } 166 167 public static Builder builder() { 168 return new Builder(); 169 } 170 171 /** 172 * Fluent builder to construct ServiceDefinition. 173 */ 174 public static class Builder { 175 private String id; 176 private String name; 177 private String host; 178 private Integer port; 179 private Map<String, String> meta; 180 private ServiceHealth health; 181 182 public Builder from(ServiceDefinition source) { 183 withId(source.getId()); 184 withName(source.getName()); 185 withHost(source.getHost()); 186 withPort(source.getPort()); 187 withMeta(source.getMetadata()); 188 withHealth(source.getHealth()); 189 190 return this; 191 } 192 193 public Builder from(Map<String, String> properties) { 194 ObjectHelper.ifNotEmpty(properties.get(ServiceDefinition.SERVICE_META_ID), this::withId); 195 ObjectHelper.ifNotEmpty(properties.get(ServiceDefinition.SERVICE_META_NAME), this::withName); 196 ObjectHelper.ifNotEmpty(properties.get(ServiceDefinition.SERVICE_META_HOST), this::withHost); 197 ObjectHelper.ifNotEmpty(properties.get(ServiceDefinition.SERVICE_META_PORT), this::withPort); 198 199 for (Map.Entry<String, String> entry : properties.entrySet()) { 200 if (!entry.getKey().startsWith(ServiceDefinition.SERVICE_META_PREFIX)) { 201 continue; 202 } 203 204 addMeta(entry.getKey(), entry.getValue()); 205 } 206 207 return this; 208 } 209 210 public Builder withId(String id) { 211 this.id = id; 212 return this; 213 } 214 215 public String id() { 216 return id; 217 } 218 219 public Builder withName(String name) { 220 this.name = name; 221 return this; 222 } 223 224 public String name() { 225 return name; 226 } 227 228 public Builder withHost(String host) { 229 this.host = host; 230 return this; 231 } 232 233 public String host() { 234 return host; 235 } 236 237 public Builder withPort(Integer port) { 238 this.port = port; 239 return this; 240 } 241 242 public Builder withPort(String port) { 243 if (port != null) { 244 withPort(Integer.parseInt(port)); 245 } 246 247 return this; 248 } 249 250 public Integer port() { 251 return port; 252 } 253 254 public Builder withMeta(Map<String, String> meta) { 255 this.meta = new HashMap<>(meta); 256 return this; 257 } 258 259 public Builder addMeta(String key, String val) { 260 if (this.meta == null) { 261 this.meta = new HashMap<>(); 262 } 263 264 this.meta.put(key, val); 265 266 return this; 267 } 268 269 public Builder addAllMeta(Map<String, String> meta) { 270 if (this.meta == null) { 271 this.meta = new HashMap<>(); 272 } 273 274 this.meta.putAll(meta); 275 276 return this; 277 } 278 279 public Map<String, String> meta() { 280 return meta; 281 } 282 283 public Builder withHealth(ServiceHealth health) { 284 this.health = health; 285 286 return this; 287 } 288 289 public ServiceHealth health() { 290 return health; 291 } 292 293 public ServiceDefinition build() { 294 return new DefaultServiceDefinition(id, name, host, port != null ? port : -1, meta, health); 295 } 296 } 297}