/* * 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.entity.impl; import static com.globo.galeb.verticles.ConfVerticleDictionary.CONF_STARTER_CONF; import static com.globo.galeb.verticles.ConfVerticleDictionary.CONF_ROOT_ROUTER; import java.util.Collection; import java.util.HashSet; import java.util.Set; import org.vertx.java.core.json.JsonArray; import org.vertx.java.core.json.JsonObject; import org.vertx.java.platform.Verticle; import com.globo.galeb.bus.ICallbackQueueAction; import com.globo.galeb.bus.MessageToMap; import com.globo.galeb.bus.MessageToMapBuilder; import com.globo.galeb.criteria.impl.HostHeaderCriterion; import com.globo.galeb.entity.EntitiesMap; import com.globo.galeb.entity.Entity; import com.globo.galeb.entity.IJsonable; import com.globo.galeb.entity.impl.backend.Backend; import com.globo.galeb.entity.impl.backend.BackendPool; import com.globo.galeb.entity.impl.backend.BackendPools; import com.globo.galeb.entity.impl.backend.IBackend; import com.globo.galeb.entity.impl.frontend.Rule; import com.globo.galeb.entity.impl.frontend.Virtualhost; import com.globo.galeb.verticles.ConfVerticleDictionary; /** * Class Farm. * * @author: See AUTHORS file. * @version: 1.0.0, Oct 23, 2014. */ public class Farm extends EntitiesMap<Virtualhost> implements ICallbackQueueAction { /** The Constant FARM_MAP. */ public static final String FARM_MAP = "farm"; /** The Constant FARM_BACKENDS_FIELDNAME. */ public static final String FARM_BACKENDPOOLS_FIELDNAME = "backendpools"; /** The Constant FARM_VIRTUALHOSTS_FIELDNAME. */ public static final String FARM_VIRTUALHOSTS_FIELDNAME = "virtualhosts"; /** The Constant FARM_VERSION_FIELDNAME. */ public static final String FARM_VERSION_FIELDNAME = "version"; /** The Constant REQUEST_TIMEOUT_FIELDNAME. */ public static final String REQUEST_TIMEOUT_FIELDNAME = "requestTimeOut"; /** The verticle. */ private final Verticle verticle; /** The version. */ private Long version = 0L; /** The backend pools. */ private EntitiesMap<BackendPool> backendPools = new BackendPools(BackendPools.class.getSimpleName()); /** The messageToMapBuilder instance */ private MessageToMapBuilder messageToMapBuilder = new MessageToMapBuilder(); /** * Instantiates a new farm. * * @param verticle the verticle */ public Farm(final Verticle verticle) { super("farm"); setFarm(this); this.verticle = verticle; } /** * Prepare backend pools. * * @return the farm */ private Farm prepareBackendPools() { backendPools.setFarm(farm) .setLogger(logger) .setPlataform(plataform) .setQueueService(queueService) .setStaticConf(staticConf) .setCounter(counter); return this; } /* (non-Javadoc) * @see com.globo.galeb.entity.Entity#start() */ @Override public void start() { prepareBackendPools(); registerQueueAction(); properties.mergeIn(staticConf.getObject(ConfVerticleDictionary.CONF_STARTER_CONF, new JsonObject())); setCriterion(new HostHeaderCriterion<Virtualhost>().setLog(logger)); } /** * Gets the version. * * @return the version */ public Long getVersion() { return version; } /* (non-Javadoc) * @see com.globo.galeb.core.bus.ICallbackQueueAction#setVersion(long) */ @Override public void setVersion(long version) { this.version = version; String infoMessage = String.format("Version changed to %d", version); if (verticle!=null) { logger.info(infoMessage); } else { System.out.println(infoMessage); } } /** * Gets the verticle id. * * @return the verticle id */ public String getVerticleId() { return (verticle!=null) ? verticle.toString() : ""; } /* (non-Javadoc) * @see com.globo.galeb.core.Entity#toJson() */ @Override public JsonObject toJson() { super.toJson(); idObj.putNumber(FARM_VERSION_FIELDNAME, version); idObj.putArray(FARM_VIRTUALHOSTS_FIELDNAME, getEntitiesJson()); idObj.putArray(FARM_BACKENDPOOLS_FIELDNAME, getBackendPoolJson()); String keyVirtualhosts = ""; String keyBackendPools = ""; String keyRules = ""; String keyBackends = ""; for (Virtualhost virtualhost: getEntities().values()) { keyVirtualhosts += "+"+virtualhost.getHash(); for (Rule rule: virtualhost.getEntities().values()) { keyRules += "+"+rule.getHash(); } } for (BackendPool backendPool: getBackendPools().getEntities().values()) { keyBackendPools += "+"+backendPool.getHash(); for (IBackend backend: backendPool.getEntities().values()) { keyBackends += "+"+((Entity) backend).getHash(); } } String key = "farm"+keyVirtualhosts+keyBackendPools+keyRules+keyBackends; prepareHash(key); return idObj; } /* (non-Javadoc) * @see com.globo.galeb.core.bus.ICallbackQueueAction#addToMap(java.lang.String) */ @Override public boolean addToMap(String message) { @SuppressWarnings("rawtypes") MessageToMap messageToMap = messageToMapBuilder.setFarm(this).getMessageToMap(message); if (properties.containsField(CONF_STARTER_CONF)) { JsonObject starterConf = properties.getObject(CONF_STARTER_CONF); if (starterConf.containsField(CONF_ROOT_ROUTER)) { JsonObject staticConf = starterConf.getObject(CONF_ROOT_ROUTER); return messageToMap.staticConf(staticConf.encode()).add(); } } return messageToMap.add(); } /* (non-Javadoc) * @see com.globo.galeb.core.bus.ICallbackQueueAction#delFromMap(java.lang.String) */ @Override public boolean delFromMap(String message) { return messageToMapBuilder.setFarm(this).getMessageToMap(message).del(); } /** * Register queue action. */ private void registerQueueAction() { queueService.registerQueueAdd(verticle, this); queueService.registerQueueDel(verticle, this); queueService.registerQueueVersion(verticle, this); } /** * Collection to json. * * @param clazz the clazz * @param collection the collection * @return the string */ private String collectionToJson(String clazz, final Collection<?> collection) { if ("".equals(clazz)||collection==null) { return "{}"; } String arrayName = clazz.toLowerCase()+"s"; JsonArray jsonArray = new JsonArray(); for (Object obj: collection) { if (obj instanceof IJsonable) { IJsonable entity = (IJsonable)obj; jsonArray.add(entity.toJson()); } else { return "{}"; } } return new JsonObject().putArray(arrayName, jsonArray).encodePrettily(); } /** * Gets the backend pools. * * @return the backend pools */ public EntitiesMap<BackendPool> getBackendPools() { return backendPools; } /** * Adds the backend pool. * * @param backendPool the backend pool */ public void addBackendPool(JsonObject backendPool) { BackendPool backendPoolInstance = new BackendPool(backendPool); backendPools.addEntity(backendPoolInstance); } /** * Removes the backend pool. * * @param backendPoolId the backend pool id */ public void removeBackendPool(String backendPoolId) { backendPools.removeEntity(new BackendPool(backendPoolId)); } /** * Clear backend pools map. */ public void clearBackendPools() { backendPools.clearEntities(); } /** * Gets the backend pool by id. * * @param id the id * @return the backend pool by id */ public BackendPool getBackendPoolById(String id) { return backendPools.getEntityById(id); } /** * Gets the backend pool json. * * @return the backend pool json */ public JsonArray getBackendPoolJson() { return getBackendPools().getEntitiesJson(); } /** * Gets the backend pool json. * * @param id the id * @return the backend pool json */ public String getBackendPoolJson(String id) { if ("".equals(id)||id==null) { return new JsonObject().putArray(FARM_BACKENDPOOLS_FIELDNAME, getBackendPools().getEntitiesJson()).encodePrettily(); } BackendPool backendPool = getBackendPoolById(id); if (backendPool!=null) { return backendPool.toJson().encodePrettily(); } return "{}"; } /** * Gets the virtualhost json. * * @return the virtualhost json */ public JsonArray getVirtualhostJson() { return new JsonArray(getVirtualhostJson("")); } /** * Gets the virtualhost json. * * @param id the id * @return the virtualhost json */ public String getVirtualhostJson(String id) { if ("".equals(id)||id==null) { return new JsonObject().putArray(FARM_VIRTUALHOSTS_FIELDNAME, getEntitiesJson()).encodePrettily(); } Virtualhost virtualhost = getEntityById(id); if (virtualhost!=null) { return virtualhost.toJson().encodePrettily(); } return "{}"; } /** * Gets the rule json. * * @return the rule json */ public JsonArray getRuleJson() { return new JsonArray(getRuleJson("")); } /** * Gets the rules. * * @return the rules */ public Set<Rule> getRules() { Set<Rule> rules = new HashSet<>(); for (Virtualhost virtualhost: getEntities().values()) { rules.addAll(virtualhost.getEntities().values()); } return rules; } /** * Gets the rule json. * * @param id the id * @return the rule json */ public String getRuleJson(String id) { if ("".equals(id)||id==null) { return collectionToJson(Rule.class.getSimpleName(), getRules()); } for (Virtualhost virtualhost : getEntities().values()) { Rule rule = virtualhost.getEntityById(id); if (rule!=null) { return rule.toJson().encodePrettily(); } } return "{}"; } /** * Gets the backends. * * @return the backends */ public Set<IBackend> getBackends() { Set<IBackend> backends = new HashSet<>(); for (BackendPool backendpool: backendPools.getEntities().values()) { backends.addAll(backendpool.getEntities().values()); } return backends; } /** * Gets the backend json. * * @return the backend json */ public JsonArray getBackendJson() { return new JsonArray(getBackendJson("")); } /** * Gets the backend json. * * @param id the id * @return the backend json */ public String getBackendJson(String id) { if ("".equals(id)||id==null) { return collectionToJson(Backend.class.getSimpleName(), getBackends()); } for (BackendPool backendPool : getBackendPools().getEntities().values()) { IBackend backend = backendPool.getEntityById(id); if (backend!=null) { return backend.toJson().encodePrettily(); } } return "{}"; } }