/* * Copyright (c) 2014 Globo.com - ATeam * All rights reserved. * * This source is subject to the Apache License, Version 2.0. * Please see the LICENSE file for more information. * * Authors: See AUTHORS file * * 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 com.globo.galeb.criteria.impl; import static com.globo.galeb.consistenthash.HashAlgorithm.HashType.*; import java.util.ArrayList; import java.util.List; import java.util.Map; import com.globo.galeb.consistenthash.ConsistentHash; import com.globo.galeb.consistenthash.HashAlgorithm; import com.globo.galeb.criteria.ICriterion; import com.globo.galeb.logger.SafeLogger; import com.globo.galeb.request.RequestData; import org.vertx.java.core.json.JsonObject; /** * Class IPHashCriterion. * * @author See AUTHORS file. * @version 1.0.0, Nov 9, 2014. * @param <T> the generic type */ public class IPHashCriterion<T> implements ICriterion<T> { /** The Constant DEFAULT_HASH_ALGORITHM. */ public static final String DEFAULT_HASH_ALGORITHM = SIP24.toString(); /** The Constant HASH_ALGORITHM_FIELDNAME. */ public static final String HASH_ALGORITHM_FIELDNAME = "hashAlgorithm"; /** The log. */ @SuppressWarnings("unused") private SafeLogger log = null; /** The collection. */ private List<T> collection = new ArrayList<T>(); /** The request data. */ private RequestData requestData = new RequestData(); /** The consistent hash. */ private ConsistentHash<T> consistentHash = null; /** The hash type. */ private String hashType = ""; /** The source ip. */ private String sourceIp = ""; /* (non-Javadoc) * @see com.globo.galeb.criteria.ICriterion#setLog(org.vertx.java.core.logging.Logger) */ @Override public ICriterion<T> setLog(final SafeLogger logger) { log = logger; return this; } /* (non-Javadoc) * @see com.globo.galeb.criteria.ICriterion#given(java.util.Map) */ @Override public ICriterion<T> given(final Map<String, T> map) { if (map!=null) { int lastCollectionSize = collection.size(); this.collection = new ArrayList<T>(map.values()); if (collection.size()!=lastCollectionSize) { consistentHash = null; } } return this; } /* (non-Javadoc) * @see com.globo.galeb.criteria.ICriterion#when(java.lang.Object) */ @Override public ICriterion<T> when(final Object param) { if (param instanceof RequestData) { requestData = (RequestData) param; JsonObject requestDataProperties = ((RequestData) param).getProperties(); String lastHashType = hashType; this.hashType = requestDataProperties.getString(HASH_ALGORITHM_FIELDNAME, DEFAULT_HASH_ALGORITHM); if (!hashType.equals(lastHashType)) { consistentHash = null; } this.sourceIp = requestData.getRemoteAddress(); } return this; } /* (non-Javadoc) * @see com.globo.galeb.criteria.ICriterion#thenGetResult() */ @Override public T thenGetResult() { if (collection.isEmpty() || "".equals(sourceIp)) { return null; } int numberOfReplicas = 1; if (consistentHash == null) { consistentHash = new ConsistentHash<T>(new HashAlgorithm(hashType), numberOfReplicas, collection); } return consistentHash.get(sourceIp); } /* (non-Javadoc) * @see com.globo.galeb.criteria.ICriterion#action(com.globo.galeb.criteria.ICriterion.CriterionAction) */ @Override public ICriterion<T> action(ICriterion.CriterionAction criterionAction) { return this; } }