package org.fluxtream.core.domain;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Lob;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import org.fluxtream.core.Configuration;
import org.fluxtream.core.aspects.FlxLogger;
import org.fluxtream.core.connectors.Connector;
import com.google.gson.annotations.Expose;
import org.hibernate.annotations.Index;
import org.hibernate.annotations.Type;
import org.springframework.util.SerializationUtils;
@Entity(name="ApiKey")
@NamedQueries ( {
@NamedQuery( name="apiKeys.byConnector",
query="SELECT apiKey FROM ApiKey apiKey WHERE apiKey.api=?"),
@NamedQuery( name="apiKeys.delete.all",
query="DELETE FROM ApiKey apiKey WHERE apiKey.guestId=?"),
@NamedQuery( name="apiKeys.all",
query="SELECT apiKey FROM ApiKey apiKey WHERE apiKey.guestId=?"),
@NamedQuery( name="apiKey.count.byApi",
query="SELECT COUNT(apiKey) FROM ApiKey apiKey WHERE apiKey.api=?"),
@NamedQuery( name="apiKey.byApi",
query="SELECT apiKey FROM ApiKey apiKey WHERE apiKey.guestId=? AND apiKey.api=? ORDER BY apiKey.id DESC"),
@NamedQuery( name="apiKeys.all.byApi",
query="SELECT apiKey FROM ApiKey apiKey WHERE apiKey.api=?"),
@NamedQuery( name="apiKey.byAttribute",
query="SELECT apiKey FROM ApiKey apiKey JOIN apiKey.attributes attr WHERE attr.attributeKey=? AND attr.attributeValue=?")
})
public class ApiKey extends AbstractEntity {
transient FlxLogger logger = FlxLogger.getLogger(ApiKey.class);
public enum Status {
STATUS_UP, STATUS_PERMANENT_FAILURE, STATUS_TRANSIENT_FAILURE, STATUS_OVER_RATE_LIMIT
}
public static class PermanentFailReason {
public final static String NEEDS_REAUTH = "NEEDS_REAUTH";
public final static String AUTH_REVOKED = "AUTH_REVOKED";
public final static String CLIENT_ERROR = "CLIENT_ERROR";
public final static String SERVER_EXCEPTION = "SERVER_EXCEPTION";
public final static String MANUAL_INTERVENTION = "MANUAL_INTERVENTION";
public final static String UNKNOWN = "UNKNOWN";
public final static String DIVIDER = " ";
public static String clientError(final int code) {
return new StringBuffer(CLIENT_ERROR).append(DIVIDER).append(code).toString();
}
public static String clientError(final int code, String message) {
StringBuffer sb = new StringBuffer(CLIENT_ERROR).append(DIVIDER).append(code);
if (message!=null)
sb.append(DIVIDER).append(message);
return sb.toString();
}
public static String unknownReason(String message) {
return new StringBuffer(UNKNOWN).append(DIVIDER).append(message).toString();
}
}
@Expose
@Index(name="guestId_index")
private long guestId;
@Type(type="yes_no")
public boolean synching;
@Expose
@Index(name="api_index")
private int api;
@OneToMany(mappedBy="apiKey", orphanRemoval = true, fetch=FetchType.EAGER, cascade=CascadeType.ALL)
List<ApiKeyAttribute> attributes = new ArrayList<ApiKeyAttribute>();
public Status status;
@Lob
public String stackTrace;
public String reason;
@Lob
private byte[] settingsStorage;
@Lob
private byte[] defaultSettingsStorage;
public void setGuestId(long guestId) {
this.guestId = guestId;
}
public long getGuestId() {
return guestId;
}
public void setSettings(Object o) {
settingsStorage = SerializationUtils.serialize(o);
}
public void setDefaultSettings(Object o) {
defaultSettingsStorage = SerializationUtils.serialize(o);
}
public Object getSettings() {
try {
return SerializationUtils.deserialize(settingsStorage);
} catch (Throwable e) {
// let's be robust against class changes
return null;
}
}
public Object getDefaultSettings() {
try {
return SerializationUtils.deserialize(defaultSettingsStorage);
} catch (Throwable e) {
// let's be robust against class changes
return null;
}
}
public void setAttribute(ApiKeyAttribute attr) {
attr.apiKey = this;
List<ApiKeyAttribute> toRemove = new ArrayList<ApiKeyAttribute>();
for (ApiKeyAttribute attribute : attributes) {
if (attribute.attributeKey==null) {
logger.warn("null attributeKey for ApiKey: " + guestId + "/" + api);
toRemove.add(attribute);
continue;
}
if (attribute.attributeKey.equals(attr.attributeKey))
toRemove.add(attribute);
}
for (ApiKeyAttribute attribute : toRemove) {
attribute.apiKey = null;
attributes.remove(attribute);
}
attributes.add(attr);
}
private ApiKeyAttribute getAttribute(String key) {
for (ApiKeyAttribute attr : attributes) {
if (attr.attributeKey!=null&&attr.attributeKey.equals(key))
return attr;
}
return null;
}
public String getAttributeValue(String key, Configuration env) {
ApiKeyAttribute attribute = getAttribute(key);
if (attribute!=null) {
String attValue = env.decrypt(attribute.attributeValue);
return attValue;
}
return null;
}
public Map<String,String> getAttributes(Configuration env) {
Map<String,String> atts = new HashMap<String, String>();
if (attributes==null) return atts;
for (ApiKeyAttribute attribute : attributes) {
String attValue = env.decrypt(attribute.attributeValue);
atts.put(attribute.attributeKey, attValue);
}
return atts;
}
public void removeAttribute(String key) {
ApiKeyAttribute attribute = getAttribute(key);
if (attribute==null) return;
attribute.attributeKey = null;
attributes.remove(attribute);
}
public boolean equals(Object o) {
if (! (o instanceof ApiKey))
return false;
ApiKey key = (ApiKey) o;
return key.guestId == guestId
&& key.api == api;
}
public String toString() {
return getConnector().getName();
}
public Connector getConnector() {
return Connector.fromValue(api);
}
public void setConnector(final Connector connector) {
this.api = connector.value();
}
public Status getStatus() {
return status;
}
public String getReason() {
return reason;
}
}