/*
* 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;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.vertx.java.core.json.JsonObject;
import com.globo.galeb.bus.IQueueService;
import com.globo.galeb.bus.NullQueueService;
import com.globo.galeb.consistenthash.HashAlgorithm;
import com.globo.galeb.consistenthash.HashAlgorithm.HashType;
import com.globo.galeb.entity.impl.Farm;
import com.globo.galeb.logger.SafeLogger;
import com.globo.galeb.metrics.CounterConsoleOut;
import com.globo.galeb.metrics.ICounter;
import com.globo.galeb.server.Server;
/**
* Class Entity.
*
* @author: See AUTHORS file.
* @version: 1.0.0, Oct 23, 2014.
*/
public abstract class Entity implements IJsonable, Comparable<Entity> {
/** The primary key */
protected int pk = -1;
/** The id. */
protected String id = "";
/** The parent id. */
protected String parentId = "";
/** The created at. */
protected final Long createdAt = System.currentTimeMillis();
/** The modified at. */
protected Long modifiedAt = System.currentTimeMillis();
/** The properties. */
protected JsonObject properties = new JsonObject();
/** The id obj. */
protected final JsonObject idObj = new JsonObject();
/** The entity type. */
protected String entityType = this.getClass().getSimpleName().toLowerCase();
/** The plataform */
protected Object plataform = null;
/** The farm instance */
protected Farm farm = null;
/** The queue service */
protected IQueueService queueService = new NullQueueService();
/** The Logger */
protected SafeLogger logger = null;
/** The static conf. */
protected JsonObject staticConf = new JsonObject();
/** The counter. */
protected ICounter counter = new CounterConsoleOut();
/** The entity status */
protected StatusType status = StatusType.CREATED;
/** The hash. */
protected String hash = "";
/**
* Instantiates a new entity.
*/
protected Entity() {
this(UNDEF);
}
/**
* Instantiates a new entity.
*
* @param id the string id
*/
protected Entity(String id) {
this(new JsonObject().putString(ID_FIELDNAME, id));
}
/**
* Instantiates a new entity.
*
* @param pk the int pk
*/
protected Entity(int pk) {
this(new JsonObject().putNumber(PK_FIELDNAME, pk));
}
/**
* Instantiates a new entity.
*
* @param json the json
*/
protected Entity(JsonObject json) {
this.pk = json.getInteger(PK_FIELDNAME, -1);
this.id = json.getString(ID_FIELDNAME, UNDEF);
this.parentId = json.getString(PARENT_ID_FIELDNAME, "");
this.properties.mergeIn(json.getObject(PROPERTIES_FIELDNAME, new JsonObject()));
idObj.mergeIn(json);
}
/**
* Gets the pk.
*
* @return the pk
*/
public int getPK() {
return pk;
}
/**
* Gets the id.
*
* @return the id
*/
public String getId() {
return id;
}
/**
* Gets the parent id.
*
* @return the parent id
*/
public String getParentId() {
return parentId;
}
/**
* Gets the properties.
*
* @return the properties
*/
public JsonObject getProperties() {
return properties;
}
/**
* Gets the plataform.
*
* @return the plataform
*/
public Object getPlataform() {
return plataform;
}
/**
* Sets the plataform.
*
* @param plataform plataform instance
* @return this
*/
public Entity setPlataform(final Object plataform) {
this.plataform = plataform;
updateModifiedTimestamp();
return this;
}
/**
* Gets the farm.
*
* @return the farm
*/
public Farm getFarm() {
return farm;
}
/**
* Sets the farm.
*
* @param farm the farm
* @return this
*/
public Entity setFarm(final Farm farm) {
this.farm = farm;
return this;
}
/**
* Sets the queue service.
*
* @param queueService the queue service
* @return this
*/
public Entity setQueueService(final IQueueService queueService) {
this.queueService = queueService;
updateModifiedTimestamp();
return this;
}
/**
* Sets the logger instance.
*
* @param logger2 the logger instance
* @return this
*/
public Entity setLogger(final SafeLogger aLogger) {
this.logger = aLogger;
return this;
}
/**
* Gets the logger.
*
* @return the logger
*/
public SafeLogger getLogger() {
return logger;
}
/**
* Sets the static conf.
*
* @param staticConf the static conf
* @return this
*/
public Entity setStaticConf(JsonObject staticConf) {
this.staticConf = staticConf.copy();
return this;
}
/**
* Sets the counter.
*
* @param counter the counter
* @return this
*/
public Entity setCounter(final ICounter counter) {
this.counter = counter;
return this;
}
/**
* Gets the status.
*
* @return the status
*/
public StatusType getStatus() {
return status;
}
/**
* Sets the status.
*
* @param status the status
* @return the entity
*/
public Entity setStatus(StatusType status) {
this.status = status;
return this;
}
/**
* Gets the entity type.
*
* @return the entity type
*/
public String getEntityType() {
return entityType;
}
/**
* Gets the hash.
*
* @return the hash
*/
public String getHash() {
toJson();
return hash;
}
/**
* Update modified timestamp.
*/
protected void updateModifiedTimestamp() {
modifiedAt = System.currentTimeMillis();
}
/**
* Reset and Update properties.
*
* @param json the json with new properties
*/
public void resetAndUpdateProperties(JsonObject json) {
this.properties = json;
}
/**
* Merge new properties.
*
* @param json the json with properties to merge
*/
public void mergeNewProperties(JsonObject json) {
this.properties.mergeIn(json);
}
/**
* Gets the or create json property.
*
* @param fieldName the field name
* @param defaultData the default data
* @return the or create json property
*/
public Object getOrCreateProperty(String fieldName, Object defaultData) {
if (!properties.containsField(fieldName)) {
properties.putValue(fieldName, defaultData);
updateModifiedTimestamp();
}
return properties.getField(fieldName);
}
/**
* Prepare json.
*
* @return this
*/
protected Entity prepareJson() {
idObj.putNumber(PK_FIELDNAME, pk);
idObj.putString(ID_FIELDNAME, id);
if (!"".equals(parentId)) {
idObj.putString(Entity.PARENT_ID_FIELDNAME, parentId);
}
idObj.putString(STATUS_FIELDNAME, status.toString());
idObj.putObject(LINKS_FIELDNAME, new JsonObject()
.putString(LINKS_REL_FIELDNAME, "self")
.putString(LINKS_HREF_FIELDNAME,
String.format("http://%s/%s/%d", Server.getHttpServerName(), entityType, pk))
);
idObj.putNumber(CREATED_AT_FIELDNAME, createdAt);
idObj.putNumber(MODIFIED_AT_FIELDNAME, modifiedAt);
idObj.putObject(PROPERTIES_FIELDNAME, properties);
return this;
}
/* (non-Javadoc)
* @see com.globo.galeb.core.IJsonable#toJson()
*/
@Override
public JsonObject toJson() {
prepareJson();
sortProperties();
prepareHash(id+parentId+properties.encode());
return idObj;
}
/**
* Prepare hash.
*
* @param key the key
*/
protected void prepareHash(String key) {
String result = key.replaceAll("[ \n\t]", "");
this.hash = new HashAlgorithm(HashType.SIP24).hash(result).asString();
idObj.putString(IJsonable.HASH_FIELDNAME, hash);
}
/**
* Sort properties.
*/
protected void sortProperties() {
List<String> propertiesFieldList = new ArrayList<>();
propertiesFieldList.addAll(properties.getFieldNames());
Collections.sort(propertiesFieldList);
JsonObject jsonTemp = new JsonObject();
for (String fieldName: propertiesFieldList) {
jsonTemp.putValue(fieldName, properties.getField(fieldName));
}
properties = jsonTemp.copy();
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.id;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (obj==null || !(obj instanceof Entity)) {
return false;
}
return this.id.equals(obj.toString());
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return this.id.hashCode();
}
/**
* Start entity.
*/
public void start() {
//
}
/* (non-Javadoc)
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
@Override
public int compareTo(Entity entity) {
this.id.compareTo(entity.id);
return 0;
}
}